1 /* GTK - The GIMP Toolkit
2  * Copyright (C) 2011 Chun-wei Fan <fanc999@yahoo.com.tw>
3  *
4  * Author: Chun-wei Fan <fanc999@yahoo.com.tw>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #include "config.h"
21 
22 #include <math.h>
23 
24 /* Workaround for round() for non-GCC/non-C99 compilers */
25 #ifndef HAVE_ROUND
26 static inline double
round(double x)27 round (double x)
28 {
29   if (x >= 0)
30     return floor (x + 0.5);
31   else
32     return ceil (x - 0.5);
33 }
34 #endif
35 
36 /* Workaround for rint() for non-GCC/non-C99 compilers */
37 #ifndef HAVE_RINT
38 static inline double
rint(double x)39 rint (double x)
40 {
41   if (ceil (x + 0.5) == floor (x + 0.5))
42   {
43     int a;
44     a = (int) ceil (x);
45     if (a % 2 == 0)
46       return ceil (x);
47     else
48       return floor (x);
49   }
50   else
51   {
52     if (x >= 0)
53       return floor (x + 0.5);
54     else
55       return ceil (x - 0.5);
56   }
57 }
58 #endif
59 
60 #ifndef HAVE_NEARBYINT
61 /* Workaround for nearbyint() for non-GCC/non-C99 compilers */
62 /* This is quite similar to rint() in most respects */
63 
64 static inline double
nearbyint(double x)65 nearbyint (double x)
66 {
67   return floor (x + 0.5);
68 }
69 #endif
70 
71 #ifndef HAVE_DECL_ISINF
72 /* Unfortunately MSVC does not have finite()
73  * but it does have _finite() which is the same
74  * as finite() except when x is a NaN
75  */
76 static inline gboolean
isinf(double x)77 isinf (double x)
78 {
79   return (!_finite (x) && !_isnan (x));
80 }
81 #endif
82 
83 #ifndef INFINITY
84 /* define INFINITY for compilers that lack support for it */
85 # ifdef HUGE_VALF
86 #  define INFINITY HUGE_VALF
87 # else
88 #  define INFINITY (float)HUGE_VAL
89 # endif
90 #endif
91 
92 #ifndef HAVE_LOG2
93 /* Use a simple implementation for log2() for compilers that lack it */
94 static inline double
log2(double x)95 log2 (double x)
96 {
97   return log (x) / log (2.0);
98 }
99 #endif
100 
101 #ifndef HAVE_EXP2
102 /* Use a simple implementation for exp2() for compilers that lack it */
103 static inline double
exp2(double x)104 exp2 (double x)
105 {
106   return pow (2.0, x);
107 }
108 #endif
109 
110 #ifndef HAVE_TRUNC
111 static inline double
trunc(double x)112 trunc (double x)
113 {
114   return (x > 0 ? floor (x) : ceil (x));
115 }
116 #endif
117 
118 #ifndef HAVE_DECL_ISNAN
119 /* it seems of the supported compilers only
120  * MSVC does not have isnan(), but it does
121  * have _isnan() which does the same as isnan()
122  */
123 static inline gboolean
isnan(double x)124 isnan (double x)
125 {
126   return _isnan (x);
127 }
128 #endif
129 
130 #ifndef HAVE_FMIN
131 static inline double
fmin(double x,double y)132 fmin (double x, double y)
133 {
134   return x < y ? x : y;
135 }
136 #endif
137