]>
git.saurik.com Git - apple/javascriptcore.git/blob - wtf/MathExtras.h
1f77b61364459a94cf509840a6548c4560c62eda
   2  * Copyright (C) 2006, 2007, 2008, 2009, 2010 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 
  38 #include <sys/types.h> 
  39 #include <machine/ieee.h> 
  50 const double piDouble 
= 3.14159265358979323846; 
  51 const float piFloat 
= 3.14159265358979323846f
; 
  53 const double piDouble 
= M_PI
; 
  54 const float piFloat 
= static_cast<float>(M_PI
); 
  58 const double piOverFourDouble 
= 0.785398163397448309616; 
  59 const float piOverFourFloat 
= 0.785398163397448309616f
; 
  61 const double piOverFourDouble 
= M_PI_4
; 
  62 const float piOverFourFloat 
= static_cast<float>(M_PI_4
); 
  67 // Work around a bug in the Mac OS X libc where ceil(-0.1) return +0. 
  68 inline double wtf_ceil(double x
) { return copysign(ceil(x
), x
); } 
  70 #define ceil(x) wtf_ceil(x) 
  77 inline bool isfinite(double x
) { return finite(x
) && !isnand(x
); } 
  80 inline bool isinf(double x
) { return !finite(x
) && !isnand(x
); } 
  83 inline bool signbit(double x
) { return x 
< 0.0; } // FIXME: Wrong for negative 0. 
  91 inline bool isfinite(double x
) { return finite(x
); } 
  94 inline bool signbit(double x
) { struct ieee_double 
*p 
= (struct ieee_double 
*)&x
; return p
->dbl_sign
; } 
  99 #if COMPILER(MSVC) || COMPILER(RVCT) 
 101 // We must not do 'num + 0.5' or 'num - 0.5' because they can cause precision loss. 
 102 static double round(double num
) 
 104     double integer 
= ceil(num
); 
 106         return integer 
- num 
> 0.5 ? integer 
- 1.0 : integer
; 
 107     return integer 
- num 
>= 0.5 ? integer 
- 1.0 : integer
; 
 109 static float roundf(float num
) 
 111     float integer 
= ceilf(num
); 
 113         return integer 
- num 
> 0.5f 
? integer 
- 1.0f 
: integer
; 
 114     return integer 
- num 
>= 0.5f 
? integer 
- 1.0f 
: integer
; 
 116 inline long long llround(double num
) { return static_cast<long long>(round(num
)); } 
 117 inline long long llroundf(float num
) { return static_cast<long long>(roundf(num
)); } 
 118 inline long lround(double num
) { return static_cast<long>(round(num
)); } 
 119 inline long lroundf(float num
) { return static_cast<long>(roundf(num
)); } 
 120 inline double trunc(double num
) { return num 
> 0 ? floor(num
) : ceil(num
); } 
 125 // The 64bit version of abs() is already defined in stdlib.h which comes with VC10 
 126 #if COMPILER(MSVC9_OR_LOWER) 
 127 inline long long abs(long long num
) { return _abs64(num
); } 
 130 inline bool isinf(double num
) { return !_finite(num
) && !_isnan(num
); } 
 131 inline bool isnan(double num
) { return !!_isnan(num
); } 
 132 inline bool signbit(double num
) { return _copysign(1.0, num
) < 0; } 
 134 inline double nextafter(double x
, double y
) { return _nextafter(x
, y
); } 
 135 inline float nextafterf(float x
, float y
) { return x 
> y 
? x 
- FLT_EPSILON 
: x 
+ FLT_EPSILON
; } 
 137 inline double copysign(double x
, double y
) { return _copysign(x
, y
); } 
 138 inline int isfinite(double x
) { return _finite(x
); } 
 140 // Work around a bug in Win, where atan2(+-infinity, +-infinity) yields NaN instead of specific values. 
 141 inline double wtf_atan2(double x
, double y
) 
 143     double posInf 
= std::numeric_limits
<double>::infinity(); 
 144     double negInf 
= -std::numeric_limits
<double>::infinity(); 
 145     double nan 
= std::numeric_limits
<double>::quiet_NaN(); 
 149     if (x 
== posInf 
&& y 
== posInf
) 
 150         result 
= piOverFourDouble
; 
 151     else if (x 
== posInf 
&& y 
== negInf
) 
 152         result 
= 3 * piOverFourDouble
; 
 153     else if (x 
== negInf 
&& y 
== posInf
) 
 154         result 
= -piOverFourDouble
; 
 155     else if (x 
== negInf 
&& y 
== negInf
) 
 156         result 
= -3 * piOverFourDouble
; 
 158         result 
= ::atan2(x
, y
); 
 163 // Work around a bug in the Microsoft CRT, where fmod(x, +-infinity) yields NaN instead of x. 
 164 inline double wtf_fmod(double x
, double y
) { return (!isinf(x
) && isinf(y
)) ? x 
: fmod(x
, y
); } 
 166 // Work around a bug in the Microsoft CRT, where pow(NaN, 0) yields NaN instead of 1. 
 167 inline double wtf_pow(double x
, double y
) { return y 
== 0 ? 1 : pow(x
, y
); } 
 169 #define atan2(x, y) wtf_atan2(x, y) 
 170 #define fmod(x, y) wtf_fmod(x, y) 
 171 #define pow(x, y) wtf_pow(x, y) 
 173 #endif // COMPILER(MSVC) 
 175 inline double deg2rad(double d
)  { return d 
* piDouble 
/ 180.0; } 
 176 inline double rad2deg(double r
)  { return r 
* 180.0 / piDouble
; } 
 177 inline double deg2grad(double d
) { return d 
* 400.0 / 360.0; } 
 178 inline double grad2deg(double g
) { return g 
* 360.0 / 400.0; } 
 179 inline double turn2deg(double t
) { return t 
* 360.0; } 
 180 inline double deg2turn(double d
) { return d 
/ 360.0; } 
 181 inline double rad2grad(double r
) { return r 
* 200.0 / piDouble
; } 
 182 inline double grad2rad(double g
) { return g 
* piDouble 
/ 200.0; } 
 184 inline float deg2rad(float d
)  { return d 
* piFloat 
/ 180.0f
; } 
 185 inline float rad2deg(float r
)  { return r 
* 180.0f 
/ piFloat
; } 
 186 inline float deg2grad(float d
) { return d 
* 400.0f 
/ 360.0f
; } 
 187 inline float grad2deg(float g
) { return g 
* 360.0f 
/ 400.0f
; } 
 188 inline float turn2deg(float t
) { return t 
* 360.0f
; } 
 189 inline float deg2turn(float d
) { return d 
/ 360.0f
; } 
 190 inline float rad2grad(float r
) { return r 
* 200.0f 
/ piFloat
; } 
 191 inline float grad2rad(float g
) { return g 
* piFloat 
/ 200.0f
; } 
 193 #if !COMPILER(MSVC) && !COMPILER(WINSCW) && !(COMPILER(RVCT) && OS(SYMBIAN)) 
 200 #endif // #ifndef WTF_MathExtras_h