]>
git.saurik.com Git - apple/javascriptcore.git/blob - wtf/MathExtras.h
9ea57fd771b54585ba3ef98ca530559936e21c5b
   2  * Copyright (C) 2006, 2007, 2008 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 inline long long llround(double num
) { return static_cast<long long>(num 
> 0 ? num 
+ 0.5 : ceil(num 
- 0.5)); } 
 102 inline long long llroundf(float num
) { return static_cast<long long>(num 
> 0 ? num 
+ 0.5f 
: ceil(num 
- 0.5f
)); } 
 103 inline long lround(double num
) { return static_cast<long>(num 
> 0 ? num 
+ 0.5 : ceil(num 
- 0.5)); } 
 104 inline long lroundf(float num
) { return static_cast<long>(num 
> 0 ? num 
+ 0.5f 
: ceilf(num 
- 0.5f
)); } 
 105 inline double round(double num
) { return num 
> 0 ? floor(num 
+ 0.5) : ceil(num 
- 0.5); } 
 106 inline float roundf(float num
) { return num 
> 0 ? floorf(num 
+ 0.5f
) : ceilf(num 
- 0.5f
); } 
 107 inline double trunc(double num
) { return num 
> 0 ? floor(num
) : ceil(num
); } 
 113 inline bool isinf(double num
) { return !_finite(num
) && !_isnan(num
); } 
 114 inline bool isnan(double num
) { return !!_isnan(num
); } 
 115 inline bool signbit(double num
) { return _copysign(1.0, num
) < 0; } 
 117 inline double nextafter(double x
, double y
) { return _nextafter(x
, y
); } 
 118 inline float nextafterf(float x
, float y
) { return x 
> y 
? x 
- FLT_EPSILON 
: x 
+ FLT_EPSILON
; } 
 120 inline double copysign(double x
, double y
) { return _copysign(x
, y
); } 
 121 inline int isfinite(double x
) { return _finite(x
); } 
 123 // Work around a bug in Win, where atan2(+-infinity, +-infinity) yields NaN instead of specific values. 
 124 inline double wtf_atan2(double x
, double y
) 
 126     double posInf 
= std::numeric_limits
<double>::infinity(); 
 127     double negInf 
= -std::numeric_limits
<double>::infinity(); 
 128     double nan 
= std::numeric_limits
<double>::quiet_NaN(); 
 132     if (x 
== posInf 
&& y 
== posInf
) 
 133         result 
= piOverFourDouble
; 
 134     else if (x 
== posInf 
&& y 
== negInf
) 
 135         result 
= 3 * piOverFourDouble
; 
 136     else if (x 
== negInf 
&& y 
== posInf
) 
 137         result 
= -piOverFourDouble
; 
 138     else if (x 
== negInf 
&& y 
== negInf
) 
 139         result 
= -3 * piOverFourDouble
; 
 141         result 
= ::atan2(x
, y
); 
 146 // Work around a bug in the Microsoft CRT, where fmod(x, +-infinity) yields NaN instead of x. 
 147 inline double wtf_fmod(double x
, double y
) { return (!isinf(x
) && isinf(y
)) ? x 
: fmod(x
, y
); } 
 149 // Work around a bug in the Microsoft CRT, where pow(NaN, 0) yields NaN instead of 1. 
 150 inline double wtf_pow(double x
, double y
) { return y 
== 0 ? 1 : pow(x
, y
); } 
 152 #define atan2(x, y) wtf_atan2(x, y) 
 153 #define fmod(x, y) wtf_fmod(x, y) 
 154 #define pow(x, y) wtf_pow(x, y) 
 156 #endif // COMPILER(MSVC) 
 158 inline double deg2rad(double d
)  { return d 
* piDouble 
/ 180.0; } 
 159 inline double rad2deg(double r
)  { return r 
* 180.0 / piDouble
; } 
 160 inline double deg2grad(double d
) { return d 
* 400.0 / 360.0; } 
 161 inline double grad2deg(double g
) { return g 
* 360.0 / 400.0; } 
 162 inline double turn2deg(double t
) { return t 
* 360.0; } 
 163 inline double deg2turn(double d
) { return d 
/ 360.0; } 
 164 inline double rad2grad(double r
) { return r 
* 200.0 / piDouble
; } 
 165 inline double grad2rad(double g
) { return g 
* piDouble 
/ 200.0; } 
 167 inline float deg2rad(float d
)  { return d 
* piFloat 
/ 180.0f
; } 
 168 inline float rad2deg(float r
)  { return r 
* 180.0f 
/ piFloat
; } 
 169 inline float deg2grad(float d
) { return d 
* 400.0f 
/ 360.0f
; } 
 170 inline float grad2deg(float g
) { return g 
* 360.0f 
/ 400.0f
; } 
 171 inline float turn2deg(float t
) { return t 
* 360.0f
; } 
 172 inline float deg2turn(float d
) { return d 
/ 360.0f
; } 
 173 inline float rad2grad(float r
) { return r 
* 200.0f 
/ piFloat
; } 
 174 inline float grad2rad(float g
) { return g 
* piFloat 
/ 200.0f
; } 
 176 #endif // #ifndef WTF_MathExtras_h