/work/obj-fuzz/dist/include/nsMathUtils.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
2 | | /* vim: set ts=8 sts=2 et sw=2 tw=80: */ |
3 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
4 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
5 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
6 | | |
7 | | #ifndef nsMathUtils_h__ |
8 | | #define nsMathUtils_h__ |
9 | | |
10 | | #include "nscore.h" |
11 | | #include <cmath> |
12 | | #include <float.h> |
13 | | |
14 | | #if defined(XP_SOLARIS) |
15 | | #include <ieeefp.h> |
16 | | #endif |
17 | | |
18 | | /* |
19 | | * round |
20 | | */ |
21 | | inline double |
22 | | NS_round(double aNum) |
23 | 0 | { |
24 | 0 | return aNum >= 0.0 ? floor(aNum + 0.5) : ceil(aNum - 0.5); |
25 | 0 | } |
26 | | inline float |
27 | | NS_roundf(float aNum) |
28 | 0 | { |
29 | 0 | return aNum >= 0.0f ? floorf(aNum + 0.5f) : ceilf(aNum - 0.5f); |
30 | 0 | } |
31 | | inline int32_t |
32 | | NS_lround(double aNum) |
33 | 0 | { |
34 | 0 | return aNum >= 0.0 ? int32_t(aNum + 0.5) : int32_t(aNum - 0.5); |
35 | 0 | } |
36 | | |
37 | | /* NS_roundup30 rounds towards infinity for positive and */ |
38 | | /* negative numbers. */ |
39 | | |
40 | | #if defined(XP_WIN32) && defined(_M_IX86) && !defined(__GNUC__) && !defined(__clang__) |
41 | | inline int32_t NS_lroundup30(float x) |
42 | | { |
43 | | /* Code derived from Laurent de Soras' paper at */ |
44 | | /* http://ldesoras.free.fr/doc/articles/rounding_en.pdf */ |
45 | | |
46 | | /* Rounding up on Windows is expensive using the float to */ |
47 | | /* int conversion and the floor function. A faster */ |
48 | | /* approach is to use f87 rounding while assuming the */ |
49 | | /* default rounding mode of rounding to the nearest */ |
50 | | /* integer. This rounding mode, however, actually rounds */ |
51 | | /* to the nearest integer so we add the floating point */ |
52 | | /* number to itself and add our rounding factor before */ |
53 | | /* doing the conversion to an integer. We then do a right */ |
54 | | /* shift of one bit on the integer to divide by two. */ |
55 | | |
56 | | /* This routine doesn't handle numbers larger in magnitude */ |
57 | | /* than 2^30 but this is fine for NSToCoordRound because */ |
58 | | /* Coords are limited to 2^30 in magnitude. */ |
59 | | |
60 | | static const double round_to_nearest = 0.5f; |
61 | | int i; |
62 | | |
63 | | __asm { |
64 | | fld x ; load fp argument |
65 | | fadd st, st(0) ; double it |
66 | | fadd round_to_nearest ; add the rounding factor |
67 | | fistp dword ptr i ; convert the result to int |
68 | | } |
69 | | return i >> 1; /* divide by 2 */ |
70 | | } |
71 | | #endif /* XP_WIN32 && _M_IX86 && !__GNUC__ */ |
72 | | |
73 | | inline int32_t |
74 | | NS_lroundf(float aNum) |
75 | 0 | { |
76 | 0 | return aNum >= 0.0f ? int32_t(aNum + 0.5f) : int32_t(aNum - 0.5f); |
77 | 0 | } |
78 | | |
79 | | /* |
80 | | * hypot. We don't need a super accurate version of this, if a platform |
81 | | * turns up with none of the possibilities below it would be okay to fall |
82 | | * back to sqrt(x*x + y*y). |
83 | | */ |
84 | | inline double |
85 | | NS_hypot(double aNum1, double aNum2) |
86 | 0 | { |
87 | 0 | #ifdef __GNUC__ |
88 | 0 | return __builtin_hypot(aNum1, aNum2); |
89 | | #elif defined _WIN32 |
90 | | return _hypot(aNum1, aNum2); |
91 | | #else |
92 | | return hypot(aNum1, aNum2); |
93 | | #endif |
94 | | } |
95 | | |
96 | | /** |
97 | | * Check whether a floating point number is finite (not +/-infinity and not a |
98 | | * NaN value). |
99 | | */ |
100 | | inline bool |
101 | | NS_finite(double aNum) |
102 | 0 | { |
103 | 0 | #ifdef WIN32 |
104 | 0 | // NOTE: '!!' casts an int to bool without spamming MSVC warning C4800. |
105 | 0 | return !!_finite(aNum); |
106 | 0 | #else |
107 | 0 | return std::isfinite(aNum); |
108 | 0 | #endif |
109 | 0 | } |
110 | | |
111 | | /** |
112 | | * Returns the result of the modulo of x by y using a floored division. |
113 | | * fmod(x, y) is using a truncated division. |
114 | | * The main difference is that the result of this method will have the sign of |
115 | | * y while the result of fmod(x, y) will have the sign of x. |
116 | | */ |
117 | | inline double |
118 | | NS_floorModulo(double aNum1, double aNum2) |
119 | 0 | { |
120 | 0 | return (aNum1 - aNum2 * floor(aNum1 / aNum2)); |
121 | 0 | } |
122 | | |
123 | | #endif |