1 /* 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 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. 12 * 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. 24 */ 25 26 #ifndef WTF_MathExtras_h 27 #define WTF_MathExtras_h 28 29 #include "wtf/CPU.h" 30 #include "wtf/StdLibExtras.h" 31 #include <algorithm> 32 #include <cmath> 33 #include <float.h> 34 #include <limits> 35 #include <stdint.h> 36 #include <stdlib.h> 37 38 #if OS(SOLARIS) 39 #include <ieeefp.h> 40 #endif 41 42 #if OS(OPENBSD) 43 #include <sys/types.h> 44 #include <machine/ieee.h> 45 #endif 46 47 #ifndef M_PI 48 const double piDouble = 3.14159265358979323846; 49 const float piFloat = 3.14159265358979323846f; 50 #else 51 const double piDouble = M_PI; 52 const float piFloat = static_cast<float>(M_PI); 53 #endif 54 55 #ifndef M_PI_2 56 const double piOverTwoDouble = 1.57079632679489661923; 57 const float piOverTwoFloat = 1.57079632679489661923f; 58 #else 59 const double piOverTwoDouble = M_PI_2; 60 const float piOverTwoFloat = static_cast<float>(M_PI_2); 61 #endif 62 63 #ifndef M_PI_4 64 const double piOverFourDouble = 0.785398163397448309616; 65 const float piOverFourFloat = 0.785398163397448309616f; 66 #else 67 const double piOverFourDouble = M_PI_4; 68 const float piOverFourFloat = static_cast<float>(M_PI_4); 69 #endif 70 71 #if OS(DARWIN) 72 73 // Work around a bug in the Mac OS X libc where ceil(-0.1) return +0. 74 inline double wtf_ceil(double x) { return copysign(ceil(x), x); } 75 76 #define ceil(x) wtf_ceil(x) 77 78 #endif 79 80 #if OS(SOLARIS) 81 82 namespace std { 83 84 #ifndef isfinite 85 inline bool isfinite(double x) { return finite(x) && !isnand(x); } 86 #endif 87 #ifndef signbit 88 inline bool signbit(double x) { return copysign(1.0, x) < 0; } 89 #endif 90 #ifndef isinf 91 inline bool isinf(double x) { return !finite(x) && !isnand(x); } 92 #endif 93 94 } // namespace std 95 96 #endif 97 98 #if OS(OPENBSD) 99 100 namespace std { 101 102 #ifndef isfinite 103 inline bool isfinite(double x) { return finite(x); } 104 #endif 105 #ifndef signbit 106 inline bool signbit(double x) { struct ieee_double *p = (struct ieee_double *)&x; return p->dbl_sign; } 107 #endif 108 109 } // namespace std 110 111 #endif 112 113 #if COMPILER(MSVC) 114 115 // We must not do 'num + 0.5' or 'num - 0.5' because they can cause precision loss. 116 static double round(double num) 117 { 118 double integer = ceil(num); 119 if (num > 0) 120 return integer - num > 0.5 ? integer - 1.0 : integer; 121 return integer - num >= 0.5 ? integer - 1.0 : integer; 122 } 123 static float roundf(float num) 124 { 125 float integer = ceilf(num); 126 if (num > 0) 127 return integer - num > 0.5f ? integer - 1.0f : integer; 128 return integer - num >= 0.5f ? integer - 1.0f : integer; 129 } 130 inline long long llround(double num) { return static_cast<long long>(round(num)); } 131 inline long long llroundf(float num) { return static_cast<long long>(roundf(num)); } 132 inline long lround(double num) { return static_cast<long>(round(num)); } 133 inline long lroundf(float num) { return static_cast<long>(roundf(num)); } 134 inline double trunc(double num) { return num > 0 ? floor(num) : ceil(num); } 135 136 #endif 137 138 #if OS(ANDROID) || COMPILER(MSVC) 139 // ANDROID and MSVC's math.h does not currently supply log2 or log2f. 140 inline double log2(double num) 141 { 142 // This constant is roughly M_LN2, which is not provided by default on Windows and Android. 143 return log(num) / 0.693147180559945309417232121458176568; 144 } 145 146 inline float log2f(float num) 147 { 148 // This constant is roughly M_LN2, which is not provided by default on Windows and Android. 149 return logf(num) / 0.693147180559945309417232121458176568f; 150 } 151 #endif 152 153 #if COMPILER(MSVC) 154 155 namespace std { 156 157 inline bool isinf(double num) { return !_finite(num) && !_isnan(num); } 158 inline bool isnan(double num) { return !!_isnan(num); } 159 inline bool isfinite(double x) { return _finite(x); } 160 inline bool signbit(double num) { return _copysign(1.0, num) < 0; } 161 162 } // namespace std 163 164 inline double nextafter(double x, double y) { return _nextafter(x, y); } 165 inline float nextafterf(float x, float y) { return x > y ? x - FLT_EPSILON : x + FLT_EPSILON; } 166 167 inline double copysign(double x, double y) { return _copysign(x, y); } 168 169 // Work around a bug in Win, where atan2(+-infinity, +-infinity) yields NaN instead of specific values. 170 inline double wtf_atan2(double x, double y) 171 { 172 double posInf = std::numeric_limits<double>::infinity(); 173 double negInf = -std::numeric_limits<double>::infinity(); 174 double nan = std::numeric_limits<double>::quiet_NaN(); 175 176 double result = nan; 177 178 if (x == posInf && y == posInf) 179 result = piOverFourDouble; 180 else if (x == posInf && y == negInf) 181 result = 3 * piOverFourDouble; 182 else if (x == negInf && y == posInf) 183 result = -piOverFourDouble; 184 else if (x == negInf && y == negInf) 185 result = -3 * piOverFourDouble; 186 else 187 result = ::atan2(x, y); 188 189 return result; 190 } 191 192 // Work around a bug in the Microsoft CRT, where fmod(x, +-infinity) yields NaN instead of x. 193 inline double wtf_fmod(double x, double y) { return (!std::isinf(x) && std::isinf(y)) ? x : fmod(x, y); } 194 195 // Work around a bug in the Microsoft CRT, where pow(NaN, 0) yields NaN instead of 1. 196 inline double wtf_pow(double x, double y) { return y == 0 ? 1 : pow(x, y); } 197 198 #define atan2(x, y) wtf_atan2(x, y) 199 #define fmod(x, y) wtf_fmod(x, y) 200 #define pow(x, y) wtf_pow(x, y) 201 202 // MSVC's math functions do not bring lrint. 203 inline long int lrint(double flt) 204 { 205 int64_t intgr; 206 #if CPU(X86) 207 __asm { 208 fld flt 209 fistp intgr 210 }; 211 #else 212 ASSERT(std::isfinite(flt)); 213 double rounded = round(flt); 214 intgr = static_cast<int64_t>(rounded); 215 // If the fractional part is exactly 0.5, we need to check whether 216 // the rounded result is even. If it is not we need to add 1 to 217 // negative values and subtract one from positive values. 218 if ((fabs(intgr - flt) == 0.5) & intgr) 219 intgr -= ((intgr >> 62) | 1); // 1 with the sign of result, i.e. -1 or 1. 220 #endif 221 return static_cast<long int>(intgr); 222 } 223 224 #endif // COMPILER(MSVC) 225 226 inline double deg2rad(double d) { return d * piDouble / 180.0; } 227 inline double rad2deg(double r) { return r * 180.0 / piDouble; } 228 inline double deg2grad(double d) { return d * 400.0 / 360.0; } 229 inline double grad2deg(double g) { return g * 360.0 / 400.0; } 230 inline double turn2deg(double t) { return t * 360.0; } 231 inline double deg2turn(double d) { return d / 360.0; } 232 inline double rad2grad(double r) { return r * 200.0 / piDouble; } 233 inline double grad2rad(double g) { return g * piDouble / 200.0; } 234 235 inline float deg2rad(float d) { return d * piFloat / 180.0f; } 236 inline float rad2deg(float r) { return r * 180.0f / piFloat; } 237 inline float deg2grad(float d) { return d * 400.0f / 360.0f; } 238 inline float grad2deg(float g) { return g * 360.0f / 400.0f; } 239 inline float turn2deg(float t) { return t * 360.0f; } 240 inline float deg2turn(float d) { return d / 360.0f; } 241 inline float rad2grad(float r) { return r * 200.0f / piFloat; } 242 inline float grad2rad(float g) { return g * piFloat / 200.0f; } 243 244 // std::numeric_limits<T>::min() returns the smallest positive value for floating point types 245 template<typename T> inline T defaultMinimumForClamp() { return std::numeric_limits<T>::min(); } 246 template<> inline float defaultMinimumForClamp() { return -std::numeric_limits<float>::max(); } 247 template<> inline double defaultMinimumForClamp() { return -std::numeric_limits<double>::max(); } 248 template<typename T> inline T defaultMaximumForClamp() { return std::numeric_limits<T>::max(); } 249 250 template<typename T> inline T clampTo(double value, T min = defaultMinimumForClamp<T>(), T max = defaultMaximumForClamp<T>()) 251 { 252 if (value >= static_cast<double>(max)) 253 return max; 254 if (value <= static_cast<double>(min)) 255 return min; 256 return static_cast<T>(value); 257 } 258 template<> inline long long int clampTo(double, long long int, long long int); // clampTo does not support long long ints. 259 260 inline int clampToInteger(double value) 261 { 262 return clampTo<int>(value); 263 } 264 265 inline float clampToFloat(double value) 266 { 267 return clampTo<float>(value); 268 } 269 270 inline int clampToPositiveInteger(double value) 271 { 272 return clampTo<int>(value, 0); 273 } 274 275 inline int clampToInteger(float value) 276 { 277 return clampTo<int>(value); 278 } 279 280 inline int clampToInteger(unsigned x) 281 { 282 const unsigned intMax = static_cast<unsigned>(std::numeric_limits<int>::max()); 283 284 if (x >= intMax) 285 return std::numeric_limits<int>::max(); 286 return static_cast<int>(x); 287 } 288 289 inline bool isWithinIntRange(float x) 290 { 291 return x > static_cast<float>(std::numeric_limits<int>::min()) && x < static_cast<float>(std::numeric_limits<int>::max()); 292 } 293 294 #ifndef UINT64_C 295 #if COMPILER(MSVC) 296 #define UINT64_C(c) c ## ui64 297 #else 298 #define UINT64_C(c) c ## ull 299 #endif 300 #endif 301 302 // Calculate d % 2^{64}. 303 inline void doubleToInteger(double d, unsigned long long& value) 304 { 305 if (std::isnan(d) || std::isinf(d)) 306 value = 0; 307 else { 308 // -2^{64} < fmodValue < 2^{64}. 309 double fmodValue = fmod(trunc(d), std::numeric_limits<unsigned long long>::max() + 1.0); 310 if (fmodValue >= 0) { 311 // 0 <= fmodValue < 2^{64}. 312 // 0 <= value < 2^{64}. This cast causes no loss. 313 value = static_cast<unsigned long long>(fmodValue); 314 } else { 315 // -2^{64} < fmodValue < 0. 316 // 0 < fmodValueInUnsignedLongLong < 2^{64}. This cast causes no loss. 317 unsigned long long fmodValueInUnsignedLongLong = static_cast<unsigned long long>(-fmodValue); 318 // -1 < (std::numeric_limits<unsigned long long>::max() - fmodValueInUnsignedLongLong) < 2^{64} - 1. 319 // 0 < value < 2^{64}. 320 value = std::numeric_limits<unsigned long long>::max() - fmodValueInUnsignedLongLong + 1; 321 } 322 } 323 } 324 325 namespace WTF { 326 327 inline unsigned fastLog2(unsigned i) 328 { 329 unsigned log2 = 0; 330 if (i & (i - 1)) 331 log2 += 1; 332 if (i >> 16) 333 log2 += 16, i >>= 16; 334 if (i >> 8) 335 log2 += 8, i >>= 8; 336 if (i >> 4) 337 log2 += 4, i >>= 4; 338 if (i >> 2) 339 log2 += 2, i >>= 2; 340 if (i >> 1) 341 log2 += 1; 342 return log2; 343 } 344 345 } // namespace WTF 346 347 #endif // #ifndef WTF_MathExtras_h 348