1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/xpcom/ds/nsMathUtils.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,121 @@ 1.4 +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- 1.5 + * This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#ifndef nsMathUtils_h__ 1.10 +#define nsMathUtils_h__ 1.11 + 1.12 +#define _USE_MATH_DEFINES /* needed for M_ constants on Win32 */ 1.13 + 1.14 +#include "nscore.h" 1.15 +#include <cmath> 1.16 +#include <float.h> 1.17 + 1.18 +#ifdef SOLARIS 1.19 +#include <ieeefp.h> 1.20 +#endif 1.21 + 1.22 +/* 1.23 + * round 1.24 + */ 1.25 +inline NS_HIDDEN_(double) NS_round(double x) 1.26 +{ 1.27 + return x >= 0.0 ? floor(x + 0.5) : ceil(x - 0.5); 1.28 +} 1.29 +inline NS_HIDDEN_(float) NS_roundf(float x) 1.30 +{ 1.31 + return x >= 0.0f ? floorf(x + 0.5f) : ceilf(x - 0.5f); 1.32 +} 1.33 +inline NS_HIDDEN_(int32_t) NS_lround(double x) 1.34 +{ 1.35 + return x >= 0.0 ? int32_t(x + 0.5) : int32_t(x - 0.5); 1.36 +} 1.37 + 1.38 +/* NS_roundup30 rounds towards infinity for positive and */ 1.39 +/* negative numbers. */ 1.40 + 1.41 +#if defined(XP_WIN32) && defined(_M_IX86) && !defined(__GNUC__) 1.42 +inline NS_HIDDEN_(int32_t) NS_lroundup30(float x) 1.43 +{ 1.44 + /* Code derived from Laurent de Soras' paper at */ 1.45 + /* http://ldesoras.free.fr/doc/articles/rounding_en.pdf */ 1.46 + 1.47 + /* Rounding up on Windows is expensive using the float to */ 1.48 + /* int conversion and the floor function. A faster */ 1.49 + /* approach is to use f87 rounding while assuming the */ 1.50 + /* default rounding mode of rounding to the nearest */ 1.51 + /* integer. This rounding mode, however, actually rounds */ 1.52 + /* to the nearest integer so we add the floating point */ 1.53 + /* number to itself and add our rounding factor before */ 1.54 + /* doing the conversion to an integer. We then do a right */ 1.55 + /* shift of one bit on the integer to divide by two. */ 1.56 + 1.57 + /* This routine doesn't handle numbers larger in magnitude */ 1.58 + /* than 2^30 but this is fine for NSToCoordRound because */ 1.59 + /* Coords are limited to 2^30 in magnitude. */ 1.60 + 1.61 + static const double round_to_nearest = 0.5f; 1.62 + int i; 1.63 + 1.64 + __asm { 1.65 + fld x ; load fp argument 1.66 + fadd st, st(0) ; double it 1.67 + fadd round_to_nearest ; add the rounding factor 1.68 + fistp dword ptr i ; convert the result to int 1.69 + } 1.70 + return i >> 1; /* divide by 2 */ 1.71 +} 1.72 +#endif /* XP_WIN32 && _M_IX86 && !__GNUC__ */ 1.73 + 1.74 +inline NS_HIDDEN_(int32_t) NS_lroundf(float x) 1.75 +{ 1.76 + return x >= 0.0f ? int32_t(x + 0.5f) : int32_t(x - 0.5f); 1.77 +} 1.78 + 1.79 +/* 1.80 + * hypot. We don't need a super accurate version of this, if a platform 1.81 + * turns up with none of the possibilities below it would be okay to fall 1.82 + * back to sqrt(x*x + y*y). 1.83 + */ 1.84 +inline NS_HIDDEN_(double) NS_hypot(double x, double y) 1.85 +{ 1.86 +#ifdef __GNUC__ 1.87 + return __builtin_hypot(x, y); 1.88 +#elif defined _WIN32 1.89 + return _hypot(x, y); 1.90 +#else 1.91 + return hypot(x, y); 1.92 +#endif 1.93 +} 1.94 + 1.95 +/** 1.96 + * Check whether a floating point number is finite (not +/-infinity and not a 1.97 + * NaN value). 1.98 + */ 1.99 +inline NS_HIDDEN_(bool) NS_finite(double d) 1.100 +{ 1.101 +#ifdef WIN32 1.102 + // NOTE: '!!' casts an int to bool without spamming MSVC warning C4800. 1.103 + return !!_finite(d); 1.104 +#elif defined(XP_DARWIN) 1.105 + // Darwin has deprecated |finite| and recommends |isfinite|. The former is 1.106 + // not present in the iOS SDK. 1.107 + return std::isfinite(d); 1.108 +#else 1.109 + return finite(d); 1.110 +#endif 1.111 +} 1.112 + 1.113 +/** 1.114 + * Returns the result of the modulo of x by y using a floored division. 1.115 + * fmod(x, y) is using a truncated division. 1.116 + * The main difference is that the result of this method will have the sign of 1.117 + * y while the result of fmod(x, y) will have the sign of x. 1.118 + */ 1.119 +inline NS_HIDDEN_(double) NS_floorModulo(double x, double y) 1.120 +{ 1.121 + return (x - y * floor(x / y)); 1.122 +} 1.123 + 1.124 +#endif