]>
git.saurik.com Git - apple/javascriptcore.git/blob - wtf/MathExtras.h
2 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 #ifndef WTF_MathExtras_h
27 #define WTF_MathExtras_h
33 #if PLATFORM(SOLARIS) && COMPILER(GCC)
49 const double piDouble
= 3.14159265358979323846;
50 const float piFloat
= 3.14159265358979323846f
;
52 const double piDouble
= M_PI
;
53 const float piFloat
= static_cast<float>(M_PI
);
57 const double piOverFourDouble
= 0.785398163397448309616;
58 const float piOverFourFloat
= 0.785398163397448309616f
;
60 const double piOverFourDouble
= M_PI_4
;
61 const float piOverFourFloat
= static_cast<float>(M_PI_4
);
64 #if PLATFORM(SOLARIS) && COMPILER(GCC)
67 inline bool isfinite(double x
) { return finite(x
) && !isnand(x
); }
70 inline bool isinf(double x
) { return !finite(x
) && !isnand(x
); }
73 inline bool signbit(double x
) { return x
< 0.0; } // FIXME: Wrong for negative 0.
80 inline bool isinf(double num
) { return !_finite(num
) && !_isnan(num
); }
81 inline bool isnan(double num
) { return !!_isnan(num
); }
82 inline long lround(double num
) { return static_cast<long>(num
> 0 ? num
+ 0.5 : ceil(num
- 0.5)); }
83 inline long lroundf(float num
) { return static_cast<long>(num
> 0 ? num
+ 0.5f
: ceilf(num
- 0.5f
)); }
84 inline double round(double num
) { return num
> 0 ? floor(num
+ 0.5) : ceil(num
- 0.5); }
85 inline float roundf(float num
) { return num
> 0 ? floorf(num
+ 0.5f
) : ceilf(num
- 0.5f
); }
86 inline bool signbit(double num
) { return _copysign(1.0, num
) < 0; }
87 inline double trunc(double num
) { return num
> 0 ? floor(num
) : ceil(num
); }
89 inline double nextafter(double x
, double y
) { return _nextafter(x
, y
); }
90 inline float nextafterf(float x
, float y
) { return x
> y
? x
- FLT_EPSILON
: x
+ FLT_EPSILON
; }
92 inline double copysign(double x
, double y
) { return _copysign(x
, y
); }
93 inline int isfinite(double x
) { return _finite(x
); }
95 // Work around a bug in Win, where atan2(+-infinity, +-infinity) yields NaN instead of specific values.
96 inline double wtf_atan2(double x
, double y
)
98 static double posInf
= std::numeric_limits
<double>::infinity();
99 static double negInf
= -std::numeric_limits
<double>::infinity();
100 static double nan
= std::numeric_limits
<double>::quiet_NaN();
104 if (x
== posInf
&& y
== posInf
)
105 result
= piOverFourDouble
;
106 else if (x
== posInf
&& y
== negInf
)
107 result
= 3 * piOverFourDouble
;
108 else if (x
== negInf
&& y
== posInf
)
109 result
= -piOverFourDouble
;
110 else if (x
== negInf
&& y
== negInf
)
111 result
= -3 * piOverFourDouble
;
113 result
= ::atan2(x
, y
);
118 // Work around a bug in the Microsoft CRT, where fmod(x, +-infinity) yields NaN instead of x.
119 inline double wtf_fmod(double x
, double y
) { return (!isinf(x
) && isinf(y
)) ? x
: fmod(x
, y
); }
121 // Work around a bug in the Microsoft CRT, where pow(NaN, 0) yields NaN instead of 1.
122 inline double wtf_pow(double x
, double y
) { return y
== 0 ? 1 : pow(x
, y
); }
124 #define atan2(x, y) wtf_atan2(x, y)
125 #define fmod(x, y) wtf_fmod(x, y)
126 #define pow(x, y) wtf_pow(x, y)
128 #if defined(_CRT_RAND_S)
129 // Initializes the random number generator.
130 inline void wtf_random_init()
132 // No need to initialize for rand_s.
135 // Returns a pseudo-random number in the range [0, 1).
136 inline double wtf_random()
141 return static_cast<double>(u
) / (static_cast<double>(UINT_MAX
) + 1.0);
143 #endif // _CRT_RAND_S
145 #endif // COMPILER(MSVC)
147 #if !COMPILER(MSVC) || !defined(_CRT_RAND_S)
149 // Initializes the random number generator.
150 inline void wtf_random_init()
152 srand(static_cast<unsigned>(time(0)));
155 // Returns a pseudo-random number in the range [0, 1).
156 inline double wtf_random()
158 return static_cast<double>(rand()) / (static_cast<double>(RAND_MAX
) + 1.0);
161 #endif // #if COMPILER(MSVC)
163 inline double deg2rad(double d
) { return d
* piDouble
/ 180.0; }
164 inline double rad2deg(double r
) { return r
* 180.0 / piDouble
; }
165 inline double deg2grad(double d
) { return d
* 400.0 / 360.0; }
166 inline double grad2deg(double g
) { return g
* 360.0 / 400.0; }
167 inline double rad2grad(double r
) { return r
* 200.0 / piDouble
; }
168 inline double grad2rad(double g
) { return g
* piDouble
/ 200.0; }
170 inline float deg2rad(float d
) { return d
* piFloat
/ 180.0f
; }
171 inline float rad2deg(float r
) { return r
* 180.0f
/ piFloat
; }
172 inline float deg2grad(float d
) { return d
* 400.0f
/ 360.0f
; }
173 inline float grad2deg(float g
) { return g
* 360.0f
/ 400.0f
; }
174 inline float rad2grad(float r
) { return r
* 200.0f
/ piFloat
; }
175 inline float grad2rad(float g
) { return g
* piFloat
/ 200.0f
; }
177 #endif // #ifndef WTF_MathExtras_h