|
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this file, |
|
4 * You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 #include "mozilla/FloatingPoint.h" |
|
7 |
|
8 #include <math.h> |
|
9 |
|
10 using mozilla::ExponentComponent; |
|
11 using mozilla::FloatingPoint; |
|
12 using mozilla::FuzzyEqualsAdditive; |
|
13 using mozilla::FuzzyEqualsMultiplicative; |
|
14 using mozilla::IsFinite; |
|
15 using mozilla::IsInfinite; |
|
16 using mozilla::IsNaN; |
|
17 using mozilla::IsNegative; |
|
18 using mozilla::IsNegativeZero; |
|
19 using mozilla::NegativeInfinity; |
|
20 using mozilla::NumberEqualsInt32; |
|
21 using mozilla::NumberIsInt32; |
|
22 using mozilla::NumbersAreIdentical; |
|
23 using mozilla::PositiveInfinity; |
|
24 using mozilla::SpecificNaN; |
|
25 using mozilla::UnspecifiedNaN; |
|
26 |
|
27 template<typename T> |
|
28 static void |
|
29 ShouldBeIdentical(T d1, T d2) |
|
30 { |
|
31 MOZ_RELEASE_ASSERT(NumbersAreIdentical(d1, d2)); |
|
32 MOZ_RELEASE_ASSERT(NumbersAreIdentical(d2, d1)); |
|
33 } |
|
34 |
|
35 template<typename T> |
|
36 static void |
|
37 ShouldNotBeIdentical(T d1, T d2) |
|
38 { |
|
39 MOZ_RELEASE_ASSERT(!NumbersAreIdentical(d1, d2)); |
|
40 MOZ_RELEASE_ASSERT(!NumbersAreIdentical(d2, d1)); |
|
41 } |
|
42 |
|
43 static void |
|
44 TestDoublesAreIdentical() |
|
45 { |
|
46 ShouldBeIdentical(+0.0, +0.0); |
|
47 ShouldBeIdentical(-0.0, -0.0); |
|
48 ShouldNotBeIdentical(+0.0, -0.0); |
|
49 |
|
50 ShouldBeIdentical(1.0, 1.0); |
|
51 ShouldNotBeIdentical(-1.0, 1.0); |
|
52 ShouldBeIdentical(4294967295.0, 4294967295.0); |
|
53 ShouldNotBeIdentical(-4294967295.0, 4294967295.0); |
|
54 ShouldBeIdentical(4294967296.0, 4294967296.0); |
|
55 ShouldBeIdentical(4294967297.0, 4294967297.0); |
|
56 ShouldBeIdentical(1e300, 1e300); |
|
57 |
|
58 ShouldBeIdentical(PositiveInfinity<double>(), PositiveInfinity<double>()); |
|
59 ShouldBeIdentical(NegativeInfinity<double>(), NegativeInfinity<double>()); |
|
60 ShouldNotBeIdentical(PositiveInfinity<double>(), NegativeInfinity<double>()); |
|
61 |
|
62 ShouldNotBeIdentical(-0.0, NegativeInfinity<double>()); |
|
63 ShouldNotBeIdentical(+0.0, NegativeInfinity<double>()); |
|
64 ShouldNotBeIdentical(1e300, NegativeInfinity<double>()); |
|
65 ShouldNotBeIdentical(3.141592654, NegativeInfinity<double>()); |
|
66 |
|
67 ShouldBeIdentical(UnspecifiedNaN<double>(), UnspecifiedNaN<double>()); |
|
68 ShouldBeIdentical(-UnspecifiedNaN<double>(), UnspecifiedNaN<double>()); |
|
69 ShouldBeIdentical(UnspecifiedNaN<double>(), -UnspecifiedNaN<double>()); |
|
70 |
|
71 ShouldBeIdentical(SpecificNaN<double>(0, 17), SpecificNaN<double>(0, 42)); |
|
72 ShouldBeIdentical(SpecificNaN<double>(1, 17), SpecificNaN<double>(1, 42)); |
|
73 ShouldBeIdentical(SpecificNaN<double>(0, 17), SpecificNaN<double>(1, 42)); |
|
74 ShouldBeIdentical(SpecificNaN<double>(1, 17), SpecificNaN<double>(0, 42)); |
|
75 |
|
76 const uint64_t Mask = 0xfffffffffffffULL; |
|
77 for (unsigned i = 0; i < 52; i++) { |
|
78 for (unsigned j = 0; j < 52; j++) { |
|
79 for (unsigned sign = 0; i < 2; i++) { |
|
80 ShouldBeIdentical(SpecificNaN<double>(0, 1ULL << i), SpecificNaN<double>(sign, 1ULL << j)); |
|
81 ShouldBeIdentical(SpecificNaN<double>(1, 1ULL << i), SpecificNaN<double>(sign, 1ULL << j)); |
|
82 |
|
83 ShouldBeIdentical(SpecificNaN<double>(0, Mask & ~(1ULL << i)), |
|
84 SpecificNaN<double>(sign, Mask & ~(1ULL << j))); |
|
85 ShouldBeIdentical(SpecificNaN<double>(1, Mask & ~(1ULL << i)), |
|
86 SpecificNaN<double>(sign, Mask & ~(1ULL << j))); |
|
87 } |
|
88 } |
|
89 } |
|
90 ShouldBeIdentical(SpecificNaN<double>(0, 17), SpecificNaN<double>(0, 0x8000000000000ULL)); |
|
91 ShouldBeIdentical(SpecificNaN<double>(0, 17), SpecificNaN<double>(0, 0x4000000000000ULL)); |
|
92 ShouldBeIdentical(SpecificNaN<double>(0, 17), SpecificNaN<double>(0, 0x2000000000000ULL)); |
|
93 ShouldBeIdentical(SpecificNaN<double>(0, 17), SpecificNaN<double>(0, 0x1000000000000ULL)); |
|
94 ShouldBeIdentical(SpecificNaN<double>(0, 17), SpecificNaN<double>(0, 0x0800000000000ULL)); |
|
95 ShouldBeIdentical(SpecificNaN<double>(0, 17), SpecificNaN<double>(0, 0x0400000000000ULL)); |
|
96 ShouldBeIdentical(SpecificNaN<double>(0, 17), SpecificNaN<double>(0, 0x0200000000000ULL)); |
|
97 ShouldBeIdentical(SpecificNaN<double>(0, 17), SpecificNaN<double>(0, 0x0100000000000ULL)); |
|
98 ShouldBeIdentical(SpecificNaN<double>(0, 17), SpecificNaN<double>(0, 0x0080000000000ULL)); |
|
99 ShouldBeIdentical(SpecificNaN<double>(0, 17), SpecificNaN<double>(0, 0x0040000000000ULL)); |
|
100 ShouldBeIdentical(SpecificNaN<double>(0, 17), SpecificNaN<double>(0, 0x0020000000000ULL)); |
|
101 ShouldBeIdentical(SpecificNaN<double>(0, 17), SpecificNaN<double>(0, 0x0010000000000ULL)); |
|
102 ShouldBeIdentical(SpecificNaN<double>(1, 17), SpecificNaN<double>(0, 0xff0ffffffffffULL)); |
|
103 ShouldBeIdentical(SpecificNaN<double>(1, 17), SpecificNaN<double>(0, 0xfffffffffff0fULL)); |
|
104 |
|
105 ShouldNotBeIdentical(UnspecifiedNaN<double>(), +0.0); |
|
106 ShouldNotBeIdentical(UnspecifiedNaN<double>(), -0.0); |
|
107 ShouldNotBeIdentical(UnspecifiedNaN<double>(), 1.0); |
|
108 ShouldNotBeIdentical(UnspecifiedNaN<double>(), -1.0); |
|
109 ShouldNotBeIdentical(UnspecifiedNaN<double>(), PositiveInfinity<double>()); |
|
110 ShouldNotBeIdentical(UnspecifiedNaN<double>(), NegativeInfinity<double>()); |
|
111 } |
|
112 |
|
113 static void |
|
114 TestFloatsAreIdentical() |
|
115 { |
|
116 ShouldBeIdentical(+0.0f, +0.0f); |
|
117 ShouldBeIdentical(-0.0f, -0.0f); |
|
118 ShouldNotBeIdentical(+0.0f, -0.0f); |
|
119 |
|
120 ShouldBeIdentical(1.0f, 1.0f); |
|
121 ShouldNotBeIdentical(-1.0f, 1.0f); |
|
122 ShouldBeIdentical(8388607.0f, 8388607.0f); |
|
123 ShouldNotBeIdentical(-8388607.0f, 8388607.0f); |
|
124 ShouldBeIdentical(8388608.0f, 8388608.0f); |
|
125 ShouldBeIdentical(8388609.0f, 8388609.0f); |
|
126 ShouldBeIdentical(1e36f, 1e36f); |
|
127 |
|
128 ShouldBeIdentical(PositiveInfinity<float>(), PositiveInfinity<float>()); |
|
129 ShouldBeIdentical(NegativeInfinity<float>(), NegativeInfinity<float>()); |
|
130 ShouldNotBeIdentical(PositiveInfinity<float>(), NegativeInfinity<float>()); |
|
131 |
|
132 ShouldNotBeIdentical(-0.0f, NegativeInfinity<float>()); |
|
133 ShouldNotBeIdentical(+0.0f, NegativeInfinity<float>()); |
|
134 ShouldNotBeIdentical(1e36f, NegativeInfinity<float>()); |
|
135 ShouldNotBeIdentical(3.141592654f, NegativeInfinity<float>()); |
|
136 |
|
137 ShouldBeIdentical(UnspecifiedNaN<float>(), UnspecifiedNaN<float>()); |
|
138 ShouldBeIdentical(-UnspecifiedNaN<float>(), UnspecifiedNaN<float>()); |
|
139 ShouldBeIdentical(UnspecifiedNaN<float>(), -UnspecifiedNaN<float>()); |
|
140 |
|
141 ShouldBeIdentical(SpecificNaN<float>(0, 17), SpecificNaN<float>(0, 42)); |
|
142 ShouldBeIdentical(SpecificNaN<float>(1, 17), SpecificNaN<float>(1, 42)); |
|
143 ShouldBeIdentical(SpecificNaN<float>(0, 17), SpecificNaN<float>(1, 42)); |
|
144 ShouldBeIdentical(SpecificNaN<float>(1, 17), SpecificNaN<float>(0, 42)); |
|
145 |
|
146 const uint32_t Mask = 0x7fffffUL; |
|
147 for (unsigned i = 0; i < 23; i++) { |
|
148 for (unsigned j = 0; j < 23; j++) { |
|
149 for (unsigned sign = 0; i < 2; i++) { |
|
150 ShouldBeIdentical(SpecificNaN<float>(0, 1UL << i), SpecificNaN<float>(sign, 1UL << j)); |
|
151 ShouldBeIdentical(SpecificNaN<float>(1, 1UL << i), SpecificNaN<float>(sign, 1UL << j)); |
|
152 |
|
153 ShouldBeIdentical(SpecificNaN<float>(0, Mask & ~(1UL << i)), |
|
154 SpecificNaN<float>(sign, Mask & ~(1UL << j))); |
|
155 ShouldBeIdentical(SpecificNaN<float>(1, Mask & ~(1UL << i)), |
|
156 SpecificNaN<float>(sign, Mask & ~(1UL << j))); |
|
157 } |
|
158 } |
|
159 } |
|
160 ShouldBeIdentical(SpecificNaN<float>(0, 17), SpecificNaN<float>(0, 0x700000)); |
|
161 ShouldBeIdentical(SpecificNaN<float>(0, 17), SpecificNaN<float>(0, 0x400000)); |
|
162 ShouldBeIdentical(SpecificNaN<float>(0, 17), SpecificNaN<float>(0, 0x200000)); |
|
163 ShouldBeIdentical(SpecificNaN<float>(0, 17), SpecificNaN<float>(0, 0x100000)); |
|
164 ShouldBeIdentical(SpecificNaN<float>(0, 17), SpecificNaN<float>(0, 0x080000)); |
|
165 ShouldBeIdentical(SpecificNaN<float>(0, 17), SpecificNaN<float>(0, 0x040000)); |
|
166 ShouldBeIdentical(SpecificNaN<float>(0, 17), SpecificNaN<float>(0, 0x020000)); |
|
167 ShouldBeIdentical(SpecificNaN<float>(0, 17), SpecificNaN<float>(0, 0x010000)); |
|
168 ShouldBeIdentical(SpecificNaN<float>(0, 17), SpecificNaN<float>(0, 0x008000)); |
|
169 ShouldBeIdentical(SpecificNaN<float>(0, 17), SpecificNaN<float>(0, 0x004000)); |
|
170 ShouldBeIdentical(SpecificNaN<float>(0, 17), SpecificNaN<float>(0, 0x002000)); |
|
171 ShouldBeIdentical(SpecificNaN<float>(0, 17), SpecificNaN<float>(0, 0x001000)); |
|
172 ShouldBeIdentical(SpecificNaN<float>(1, 17), SpecificNaN<float>(0, 0x7f0fff)); |
|
173 ShouldBeIdentical(SpecificNaN<float>(1, 17), SpecificNaN<float>(0, 0x7fff0f)); |
|
174 |
|
175 ShouldNotBeIdentical(UnspecifiedNaN<float>(), +0.0f); |
|
176 ShouldNotBeIdentical(UnspecifiedNaN<float>(), -0.0f); |
|
177 ShouldNotBeIdentical(UnspecifiedNaN<float>(), 1.0f); |
|
178 ShouldNotBeIdentical(UnspecifiedNaN<float>(), -1.0f); |
|
179 ShouldNotBeIdentical(UnspecifiedNaN<float>(), PositiveInfinity<float>()); |
|
180 ShouldNotBeIdentical(UnspecifiedNaN<float>(), NegativeInfinity<float>()); |
|
181 } |
|
182 |
|
183 static void |
|
184 TestAreIdentical() |
|
185 { |
|
186 TestDoublesAreIdentical(); |
|
187 TestFloatsAreIdentical(); |
|
188 } |
|
189 |
|
190 static void |
|
191 TestDoubleExponentComponent() |
|
192 { |
|
193 MOZ_RELEASE_ASSERT(ExponentComponent(0.0) == -int_fast16_t(FloatingPoint<double>::ExponentBias)); |
|
194 MOZ_RELEASE_ASSERT(ExponentComponent(-0.0) == -int_fast16_t(FloatingPoint<double>::ExponentBias)); |
|
195 MOZ_RELEASE_ASSERT(ExponentComponent(0.125) == -3); |
|
196 MOZ_RELEASE_ASSERT(ExponentComponent(0.5) == -1); |
|
197 MOZ_RELEASE_ASSERT(ExponentComponent(1.0) == 0); |
|
198 MOZ_RELEASE_ASSERT(ExponentComponent(1.5) == 0); |
|
199 MOZ_RELEASE_ASSERT(ExponentComponent(2.0) == 1); |
|
200 MOZ_RELEASE_ASSERT(ExponentComponent(7.0) == 2); |
|
201 MOZ_RELEASE_ASSERT(ExponentComponent(PositiveInfinity<double>()) == FloatingPoint<double>::ExponentBias + 1); |
|
202 MOZ_RELEASE_ASSERT(ExponentComponent(NegativeInfinity<double>()) == FloatingPoint<double>::ExponentBias + 1); |
|
203 MOZ_RELEASE_ASSERT(ExponentComponent(UnspecifiedNaN<double>()) == FloatingPoint<double>::ExponentBias + 1); |
|
204 } |
|
205 |
|
206 static void |
|
207 TestFloatExponentComponent() |
|
208 { |
|
209 MOZ_RELEASE_ASSERT(ExponentComponent(0.0f) == -int_fast16_t(FloatingPoint<float>::ExponentBias)); |
|
210 MOZ_RELEASE_ASSERT(ExponentComponent(-0.0f) == -int_fast16_t(FloatingPoint<float>::ExponentBias)); |
|
211 MOZ_RELEASE_ASSERT(ExponentComponent(0.125f) == -3); |
|
212 MOZ_RELEASE_ASSERT(ExponentComponent(0.5f) == -1); |
|
213 MOZ_RELEASE_ASSERT(ExponentComponent(1.0f) == 0); |
|
214 MOZ_RELEASE_ASSERT(ExponentComponent(1.5f) == 0); |
|
215 MOZ_RELEASE_ASSERT(ExponentComponent(2.0f) == 1); |
|
216 MOZ_RELEASE_ASSERT(ExponentComponent(7.0f) == 2); |
|
217 MOZ_RELEASE_ASSERT(ExponentComponent(PositiveInfinity<float>()) == FloatingPoint<float>::ExponentBias + 1); |
|
218 MOZ_RELEASE_ASSERT(ExponentComponent(NegativeInfinity<float>()) == FloatingPoint<float>::ExponentBias + 1); |
|
219 MOZ_RELEASE_ASSERT(ExponentComponent(UnspecifiedNaN<float>()) == FloatingPoint<float>::ExponentBias + 1); |
|
220 } |
|
221 |
|
222 static void |
|
223 TestExponentComponent() |
|
224 { |
|
225 TestDoubleExponentComponent(); |
|
226 TestFloatExponentComponent(); |
|
227 } |
|
228 |
|
229 static void |
|
230 TestDoublesPredicates() |
|
231 { |
|
232 MOZ_RELEASE_ASSERT(IsNaN(UnspecifiedNaN<double>())); |
|
233 MOZ_RELEASE_ASSERT(IsNaN(SpecificNaN<double>(1, 17)));; |
|
234 MOZ_RELEASE_ASSERT(IsNaN(SpecificNaN<double>(0, 0xfffffffffff0fULL))); |
|
235 MOZ_RELEASE_ASSERT(!IsNaN(0.0)); |
|
236 MOZ_RELEASE_ASSERT(!IsNaN(-0.0)); |
|
237 MOZ_RELEASE_ASSERT(!IsNaN(1.0)); |
|
238 MOZ_RELEASE_ASSERT(!IsNaN(PositiveInfinity<double>())); |
|
239 MOZ_RELEASE_ASSERT(!IsNaN(NegativeInfinity<double>())); |
|
240 |
|
241 MOZ_RELEASE_ASSERT(IsInfinite(PositiveInfinity<double>())); |
|
242 MOZ_RELEASE_ASSERT(IsInfinite(NegativeInfinity<double>())); |
|
243 MOZ_RELEASE_ASSERT(!IsInfinite(UnspecifiedNaN<double>())); |
|
244 MOZ_RELEASE_ASSERT(!IsInfinite(0.0)); |
|
245 MOZ_RELEASE_ASSERT(!IsInfinite(-0.0)); |
|
246 MOZ_RELEASE_ASSERT(!IsInfinite(1.0)); |
|
247 |
|
248 MOZ_RELEASE_ASSERT(!IsFinite(PositiveInfinity<double>())); |
|
249 MOZ_RELEASE_ASSERT(!IsFinite(NegativeInfinity<double>())); |
|
250 MOZ_RELEASE_ASSERT(!IsFinite(UnspecifiedNaN<double>())); |
|
251 MOZ_RELEASE_ASSERT(IsFinite(0.0)); |
|
252 MOZ_RELEASE_ASSERT(IsFinite(-0.0)); |
|
253 MOZ_RELEASE_ASSERT(IsFinite(1.0)); |
|
254 |
|
255 MOZ_RELEASE_ASSERT(!IsNegative(PositiveInfinity<double>())); |
|
256 MOZ_RELEASE_ASSERT(IsNegative(NegativeInfinity<double>())); |
|
257 MOZ_RELEASE_ASSERT(IsNegative(-0.0)); |
|
258 MOZ_RELEASE_ASSERT(!IsNegative(0.0)); |
|
259 MOZ_RELEASE_ASSERT(IsNegative(-1.0)); |
|
260 MOZ_RELEASE_ASSERT(!IsNegative(1.0)); |
|
261 |
|
262 MOZ_RELEASE_ASSERT(!IsNegativeZero(PositiveInfinity<double>())); |
|
263 MOZ_RELEASE_ASSERT(!IsNegativeZero(NegativeInfinity<double>())); |
|
264 MOZ_RELEASE_ASSERT(!IsNegativeZero(SpecificNaN<double>(1, 17)));; |
|
265 MOZ_RELEASE_ASSERT(!IsNegativeZero(SpecificNaN<double>(1, 0xfffffffffff0fULL))); |
|
266 MOZ_RELEASE_ASSERT(!IsNegativeZero(SpecificNaN<double>(0, 17)));; |
|
267 MOZ_RELEASE_ASSERT(!IsNegativeZero(SpecificNaN<double>(0, 0xfffffffffff0fULL))); |
|
268 MOZ_RELEASE_ASSERT(!IsNegativeZero(UnspecifiedNaN<double>())); |
|
269 MOZ_RELEASE_ASSERT(IsNegativeZero(-0.0)); |
|
270 MOZ_RELEASE_ASSERT(!IsNegativeZero(0.0)); |
|
271 MOZ_RELEASE_ASSERT(!IsNegativeZero(-1.0)); |
|
272 MOZ_RELEASE_ASSERT(!IsNegativeZero(1.0)); |
|
273 |
|
274 int32_t i; |
|
275 MOZ_RELEASE_ASSERT(NumberIsInt32(0.0, &i)); MOZ_RELEASE_ASSERT(i == 0); |
|
276 MOZ_RELEASE_ASSERT(!NumberIsInt32(-0.0, &i)); |
|
277 MOZ_RELEASE_ASSERT(NumberEqualsInt32(0.0, &i)); MOZ_RELEASE_ASSERT(i == 0); |
|
278 MOZ_RELEASE_ASSERT(NumberEqualsInt32(-0.0, &i)); MOZ_RELEASE_ASSERT(i == 0); |
|
279 MOZ_RELEASE_ASSERT(NumberIsInt32(double(INT32_MIN), &i)); MOZ_RELEASE_ASSERT(i == INT32_MIN); |
|
280 MOZ_RELEASE_ASSERT(NumberIsInt32(double(INT32_MAX), &i)); MOZ_RELEASE_ASSERT(i == INT32_MAX); |
|
281 MOZ_RELEASE_ASSERT(NumberEqualsInt32(double(INT32_MIN), &i)); MOZ_RELEASE_ASSERT(i == INT32_MIN); |
|
282 MOZ_RELEASE_ASSERT(NumberEqualsInt32(double(INT32_MAX), &i)); MOZ_RELEASE_ASSERT(i == INT32_MAX); |
|
283 MOZ_RELEASE_ASSERT(!NumberIsInt32(0.5, &i)); |
|
284 MOZ_RELEASE_ASSERT(!NumberIsInt32(double(INT32_MAX) + 0.1, &i)); |
|
285 MOZ_RELEASE_ASSERT(!NumberIsInt32(double(INT32_MIN) - 0.1, &i)); |
|
286 MOZ_RELEASE_ASSERT(!NumberIsInt32(NegativeInfinity<double>(), &i)); |
|
287 MOZ_RELEASE_ASSERT(!NumberIsInt32(PositiveInfinity<double>(), &i)); |
|
288 MOZ_RELEASE_ASSERT(!NumberIsInt32(UnspecifiedNaN<double>(), &i)); |
|
289 MOZ_RELEASE_ASSERT(!NumberEqualsInt32(0.5, &i)); |
|
290 MOZ_RELEASE_ASSERT(!NumberEqualsInt32(double(INT32_MAX) + 0.1, &i)); |
|
291 MOZ_RELEASE_ASSERT(!NumberEqualsInt32(double(INT32_MIN) - 0.1, &i)); |
|
292 MOZ_RELEASE_ASSERT(!NumberEqualsInt32(NegativeInfinity<double>(), &i)); |
|
293 MOZ_RELEASE_ASSERT(!NumberEqualsInt32(PositiveInfinity<double>(), &i)); |
|
294 MOZ_RELEASE_ASSERT(!NumberEqualsInt32(UnspecifiedNaN<double>(), &i)); |
|
295 } |
|
296 |
|
297 static void |
|
298 TestFloatsPredicates() |
|
299 { |
|
300 MOZ_RELEASE_ASSERT(IsNaN(UnspecifiedNaN<float>())); |
|
301 MOZ_RELEASE_ASSERT(IsNaN(SpecificNaN<float>(1, 17)));; |
|
302 MOZ_RELEASE_ASSERT(IsNaN(SpecificNaN<float>(0, 0x7fff0fUL))); |
|
303 MOZ_RELEASE_ASSERT(!IsNaN(0.0f)); |
|
304 MOZ_RELEASE_ASSERT(!IsNaN(-0.0f)); |
|
305 MOZ_RELEASE_ASSERT(!IsNaN(1.0f)); |
|
306 MOZ_RELEASE_ASSERT(!IsNaN(PositiveInfinity<float>())); |
|
307 MOZ_RELEASE_ASSERT(!IsNaN(NegativeInfinity<float>())); |
|
308 |
|
309 MOZ_RELEASE_ASSERT(IsInfinite(PositiveInfinity<float>())); |
|
310 MOZ_RELEASE_ASSERT(IsInfinite(NegativeInfinity<float>())); |
|
311 MOZ_RELEASE_ASSERT(!IsInfinite(UnspecifiedNaN<float>())); |
|
312 MOZ_RELEASE_ASSERT(!IsInfinite(0.0f)); |
|
313 MOZ_RELEASE_ASSERT(!IsInfinite(-0.0f)); |
|
314 MOZ_RELEASE_ASSERT(!IsInfinite(1.0f)); |
|
315 |
|
316 MOZ_RELEASE_ASSERT(!IsFinite(PositiveInfinity<float>())); |
|
317 MOZ_RELEASE_ASSERT(!IsFinite(NegativeInfinity<float>())); |
|
318 MOZ_RELEASE_ASSERT(!IsFinite(UnspecifiedNaN<float>())); |
|
319 MOZ_RELEASE_ASSERT(IsFinite(0.0f)); |
|
320 MOZ_RELEASE_ASSERT(IsFinite(-0.0f)); |
|
321 MOZ_RELEASE_ASSERT(IsFinite(1.0f)); |
|
322 |
|
323 MOZ_RELEASE_ASSERT(!IsNegative(PositiveInfinity<float>())); |
|
324 MOZ_RELEASE_ASSERT(IsNegative(NegativeInfinity<float>())); |
|
325 MOZ_RELEASE_ASSERT(IsNegative(-0.0f)); |
|
326 MOZ_RELEASE_ASSERT(!IsNegative(0.0f)); |
|
327 MOZ_RELEASE_ASSERT(IsNegative(-1.0f)); |
|
328 MOZ_RELEASE_ASSERT(!IsNegative(1.0f)); |
|
329 |
|
330 MOZ_RELEASE_ASSERT(!IsNegativeZero(PositiveInfinity<float>())); |
|
331 MOZ_RELEASE_ASSERT(!IsNegativeZero(NegativeInfinity<float>())); |
|
332 MOZ_RELEASE_ASSERT(!IsNegativeZero(SpecificNaN<float>(1, 17)));; |
|
333 MOZ_RELEASE_ASSERT(!IsNegativeZero(SpecificNaN<float>(1, 0x7fff0fUL))); |
|
334 MOZ_RELEASE_ASSERT(!IsNegativeZero(SpecificNaN<float>(0, 17)));; |
|
335 MOZ_RELEASE_ASSERT(!IsNegativeZero(SpecificNaN<float>(0, 0x7fff0fUL))); |
|
336 MOZ_RELEASE_ASSERT(!IsNegativeZero(UnspecifiedNaN<float>())); |
|
337 MOZ_RELEASE_ASSERT(IsNegativeZero(-0.0f)); |
|
338 MOZ_RELEASE_ASSERT(!IsNegativeZero(0.0f)); |
|
339 MOZ_RELEASE_ASSERT(!IsNegativeZero(-1.0f)); |
|
340 MOZ_RELEASE_ASSERT(!IsNegativeZero(1.0f)); |
|
341 |
|
342 int32_t i; |
|
343 const int32_t BIG = 2097151; |
|
344 MOZ_RELEASE_ASSERT(NumberIsInt32(0.0f, &i)); MOZ_RELEASE_ASSERT(i == 0); |
|
345 MOZ_RELEASE_ASSERT(!NumberIsInt32(-0.0f, &i)); |
|
346 MOZ_RELEASE_ASSERT(NumberEqualsInt32(0.0f, &i)); MOZ_RELEASE_ASSERT(i == 0); |
|
347 MOZ_RELEASE_ASSERT(NumberEqualsInt32(-0.0f, &i)); MOZ_RELEASE_ASSERT(i == 0); |
|
348 MOZ_RELEASE_ASSERT(NumberIsInt32(float(INT32_MIN), &i)); MOZ_RELEASE_ASSERT(i == INT32_MIN); |
|
349 MOZ_RELEASE_ASSERT(NumberIsInt32(float(BIG), &i)); MOZ_RELEASE_ASSERT(i == BIG); |
|
350 MOZ_RELEASE_ASSERT(NumberEqualsInt32(float(INT32_MIN), &i)); MOZ_RELEASE_ASSERT(i == INT32_MIN); |
|
351 MOZ_RELEASE_ASSERT(NumberEqualsInt32(float(BIG), &i)); MOZ_RELEASE_ASSERT(i == BIG); |
|
352 MOZ_RELEASE_ASSERT(!NumberIsInt32(0.5f, &i)); |
|
353 MOZ_RELEASE_ASSERT(!NumberIsInt32(float(BIG) + 0.1f, &i)); |
|
354 MOZ_RELEASE_ASSERT(!NumberIsInt32(NegativeInfinity<float>(), &i)); |
|
355 MOZ_RELEASE_ASSERT(!NumberIsInt32(PositiveInfinity<float>(), &i)); |
|
356 MOZ_RELEASE_ASSERT(!NumberIsInt32(UnspecifiedNaN<float>(), &i)); |
|
357 MOZ_RELEASE_ASSERT(!NumberEqualsInt32(0.5f, &i)); |
|
358 MOZ_RELEASE_ASSERT(!NumberEqualsInt32(float(BIG) + 0.1f, &i)); |
|
359 MOZ_RELEASE_ASSERT(!NumberEqualsInt32(NegativeInfinity<float>(), &i)); |
|
360 MOZ_RELEASE_ASSERT(!NumberEqualsInt32(PositiveInfinity<float>(), &i)); |
|
361 MOZ_RELEASE_ASSERT(!NumberEqualsInt32(UnspecifiedNaN<float>(), &i)); |
|
362 } |
|
363 |
|
364 static void |
|
365 TestPredicates() |
|
366 { |
|
367 TestFloatsPredicates(); |
|
368 TestDoublesPredicates(); |
|
369 } |
|
370 |
|
371 static void |
|
372 TestFloatsAreApproximatelyEqual() |
|
373 { |
|
374 float epsilon = mozilla::detail::FuzzyEqualsEpsilon<float>::value(); |
|
375 float lessThanEpsilon = epsilon / 2.0f; |
|
376 float moreThanEpsilon = epsilon * 2.0f; |
|
377 |
|
378 // Additive tests using the default epsilon |
|
379 // ... around 1.0 |
|
380 MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0f, 1.0f + lessThanEpsilon)); |
|
381 MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0f, 1.0f - lessThanEpsilon)); |
|
382 MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0f, 1.0f + epsilon)); |
|
383 MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0f, 1.0f - epsilon)); |
|
384 MOZ_RELEASE_ASSERT(!FuzzyEqualsAdditive(1.0f, 1.0f + moreThanEpsilon)); |
|
385 MOZ_RELEASE_ASSERT(!FuzzyEqualsAdditive(1.0f, 1.0f - moreThanEpsilon)); |
|
386 // ... around 1.0e2 (this is near the upper bound of the range where |
|
387 // adding moreThanEpsilon will still be representable and return false) |
|
388 MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0e2f, 1.0e2f + lessThanEpsilon)); |
|
389 MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0e2f, 1.0e2f + epsilon)); |
|
390 MOZ_RELEASE_ASSERT(!FuzzyEqualsAdditive(1.0e2f, 1.0e2f + moreThanEpsilon)); |
|
391 // ... around 1.0e-10 |
|
392 MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0e-10f, 1.0e-10f + lessThanEpsilon)); |
|
393 MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0e-10f, 1.0e-10f + epsilon)); |
|
394 MOZ_RELEASE_ASSERT(!FuzzyEqualsAdditive(1.0e-10f, 1.0e-10f + moreThanEpsilon)); |
|
395 // ... straddling 0 |
|
396 MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0e-6f, -1.0e-6f)); |
|
397 MOZ_RELEASE_ASSERT(!FuzzyEqualsAdditive(1.0e-5f, -1.0e-5f)); |
|
398 // Using a small epsilon |
|
399 MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0e-5f, 1.0e-5f + 1.0e-10f, 1.0e-9f)); |
|
400 MOZ_RELEASE_ASSERT(!FuzzyEqualsAdditive(1.0e-5f, 1.0e-5f + 1.0e-10f, 1.0e-11f)); |
|
401 // Using a big epsilon |
|
402 MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0e20f, 1.0e20f + 1.0e15f, 1.0e16f)); |
|
403 MOZ_RELEASE_ASSERT(!FuzzyEqualsAdditive(1.0e20f, 1.0e20f + 1.0e15f, 1.0e14f)); |
|
404 |
|
405 // Multiplicative tests using the default epsilon |
|
406 // ... around 1.0 |
|
407 MOZ_RELEASE_ASSERT(FuzzyEqualsMultiplicative(1.0f, 1.0f + lessThanEpsilon)); |
|
408 MOZ_RELEASE_ASSERT(FuzzyEqualsMultiplicative(1.0f, 1.0f - lessThanEpsilon)); |
|
409 MOZ_RELEASE_ASSERT(FuzzyEqualsMultiplicative(1.0f, 1.0f + epsilon)); |
|
410 MOZ_RELEASE_ASSERT(!FuzzyEqualsMultiplicative(1.0f, 1.0f - epsilon)); |
|
411 MOZ_RELEASE_ASSERT(!FuzzyEqualsMultiplicative(1.0f, 1.0f + moreThanEpsilon)); |
|
412 MOZ_RELEASE_ASSERT(!FuzzyEqualsMultiplicative(1.0f, 1.0f - moreThanEpsilon)); |
|
413 // ... around 1.0e10 |
|
414 MOZ_RELEASE_ASSERT(FuzzyEqualsMultiplicative(1.0e10f, 1.0e10f + (lessThanEpsilon * 1.0e10f))); |
|
415 MOZ_RELEASE_ASSERT(!FuzzyEqualsMultiplicative(1.0e10f, 1.0e10f + (moreThanEpsilon * 1.0e10f))); |
|
416 // ... around 1.0e-10 |
|
417 MOZ_RELEASE_ASSERT(FuzzyEqualsMultiplicative(1.0e-10f, 1.0e-10f + (lessThanEpsilon * 1.0e-10f))); |
|
418 MOZ_RELEASE_ASSERT(!FuzzyEqualsMultiplicative(1.0e-10f, 1.0e-10f + (moreThanEpsilon * 1.0e-10f))); |
|
419 // ... straddling 0 |
|
420 MOZ_RELEASE_ASSERT(!FuzzyEqualsMultiplicative(1.0e-6f, -1.0e-6f)); |
|
421 MOZ_RELEASE_ASSERT(FuzzyEqualsMultiplicative(1.0e-6f, -1.0e-6f, 1.0e2f)); |
|
422 // Using a small epsilon |
|
423 MOZ_RELEASE_ASSERT(FuzzyEqualsMultiplicative(1.0e-5f, 1.0e-5f + 1.0e-10f, 1.0e-4f)); |
|
424 MOZ_RELEASE_ASSERT(!FuzzyEqualsMultiplicative(1.0e-5f, 1.0e-5f + 1.0e-10f, 1.0e-5f)); |
|
425 // Using a big epsilon |
|
426 MOZ_RELEASE_ASSERT(FuzzyEqualsMultiplicative(1.0f, 2.0f, 1.0f)); |
|
427 MOZ_RELEASE_ASSERT(!FuzzyEqualsMultiplicative(1.0f, 2.0f, 0.1f)); |
|
428 |
|
429 // "real world case" |
|
430 float oneThird = 10.0f / 3.0f; |
|
431 MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(10.0f, 3.0f * oneThird)); |
|
432 MOZ_RELEASE_ASSERT(FuzzyEqualsMultiplicative(10.0f, 3.0f * oneThird)); |
|
433 // NaN check |
|
434 MOZ_RELEASE_ASSERT(!FuzzyEqualsAdditive(SpecificNaN<float>(1, 1), SpecificNaN<float>(1, 1))); |
|
435 MOZ_RELEASE_ASSERT(!FuzzyEqualsAdditive(SpecificNaN<float>(1, 2), SpecificNaN<float>(0, 8))); |
|
436 MOZ_RELEASE_ASSERT(!FuzzyEqualsMultiplicative(SpecificNaN<float>(1, 1), SpecificNaN<float>(1, 1))); |
|
437 MOZ_RELEASE_ASSERT(!FuzzyEqualsMultiplicative(SpecificNaN<float>(1, 2), SpecificNaN<float>(0, 200))); |
|
438 } |
|
439 |
|
440 static void |
|
441 TestDoublesAreApproximatelyEqual() |
|
442 { |
|
443 double epsilon = mozilla::detail::FuzzyEqualsEpsilon<double>::value(); |
|
444 double lessThanEpsilon = epsilon / 2.0; |
|
445 double moreThanEpsilon = epsilon * 2.0; |
|
446 |
|
447 // Additive tests using the default epsilon |
|
448 // ... around 1.0 |
|
449 MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0, 1.0 + lessThanEpsilon)); |
|
450 MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0, 1.0 - lessThanEpsilon)); |
|
451 MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0, 1.0 + epsilon)); |
|
452 MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0, 1.0 - epsilon)); |
|
453 MOZ_RELEASE_ASSERT(!FuzzyEqualsAdditive(1.0, 1.0 + moreThanEpsilon)); |
|
454 MOZ_RELEASE_ASSERT(!FuzzyEqualsAdditive(1.0, 1.0 - moreThanEpsilon)); |
|
455 // ... around 1.0e4 (this is near the upper bound of the range where |
|
456 // adding moreThanEpsilon will still be representable and return false) |
|
457 MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0e4, 1.0e4 + lessThanEpsilon)); |
|
458 MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0e4, 1.0e4 + epsilon)); |
|
459 MOZ_RELEASE_ASSERT(!FuzzyEqualsAdditive(1.0e4, 1.0e4 + moreThanEpsilon)); |
|
460 // ... around 1.0e-25 |
|
461 MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0e-25, 1.0e-25 + lessThanEpsilon)); |
|
462 MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0e-25, 1.0e-25 + epsilon)); |
|
463 MOZ_RELEASE_ASSERT(!FuzzyEqualsAdditive(1.0e-25, 1.0e-25 + moreThanEpsilon)); |
|
464 // ... straddling 0 |
|
465 MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0e-13, -1.0e-13)); |
|
466 MOZ_RELEASE_ASSERT(!FuzzyEqualsAdditive(1.0e-12, -1.0e-12)); |
|
467 // Using a small epsilon |
|
468 MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0e-15, 1.0e-15 + 1.0e-30, 1.0e-29)); |
|
469 MOZ_RELEASE_ASSERT(!FuzzyEqualsAdditive(1.0e-15, 1.0e-15 + 1.0e-30, 1.0e-31)); |
|
470 // Using a big epsilon |
|
471 MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(1.0e40, 1.0e40 + 1.0e25, 1.0e26)); |
|
472 MOZ_RELEASE_ASSERT(!FuzzyEqualsAdditive(1.0e40, 1.0e40 + 1.0e25, 1.0e24)); |
|
473 |
|
474 // Multiplicative tests using the default epsilon |
|
475 // ... around 1.0 |
|
476 MOZ_RELEASE_ASSERT(FuzzyEqualsMultiplicative(1.0, 1.0 + lessThanEpsilon)); |
|
477 MOZ_RELEASE_ASSERT(FuzzyEqualsMultiplicative(1.0, 1.0 - lessThanEpsilon)); |
|
478 MOZ_RELEASE_ASSERT(FuzzyEqualsMultiplicative(1.0, 1.0 + epsilon)); |
|
479 MOZ_RELEASE_ASSERT(!FuzzyEqualsMultiplicative(1.0, 1.0 - epsilon)); |
|
480 MOZ_RELEASE_ASSERT(!FuzzyEqualsMultiplicative(1.0, 1.0 + moreThanEpsilon)); |
|
481 MOZ_RELEASE_ASSERT(!FuzzyEqualsMultiplicative(1.0, 1.0 - moreThanEpsilon)); |
|
482 // ... around 1.0e30 |
|
483 MOZ_RELEASE_ASSERT(FuzzyEqualsMultiplicative(1.0e30, 1.0e30 + (lessThanEpsilon * 1.0e30))); |
|
484 MOZ_RELEASE_ASSERT(!FuzzyEqualsMultiplicative(1.0e30, 1.0e30 + (moreThanEpsilon * 1.0e30))); |
|
485 // ... around 1.0e-30 |
|
486 MOZ_RELEASE_ASSERT(FuzzyEqualsMultiplicative(1.0e-30, 1.0e-30 + (lessThanEpsilon * 1.0e-30))); |
|
487 MOZ_RELEASE_ASSERT(!FuzzyEqualsMultiplicative(1.0e-30, 1.0e-30 + (moreThanEpsilon * 1.0e-30))); |
|
488 // ... straddling 0 |
|
489 MOZ_RELEASE_ASSERT(!FuzzyEqualsMultiplicative(1.0e-6, -1.0e-6)); |
|
490 MOZ_RELEASE_ASSERT(FuzzyEqualsMultiplicative(1.0e-6, -1.0e-6, 1.0e2)); |
|
491 // Using a small epsilon |
|
492 MOZ_RELEASE_ASSERT(FuzzyEqualsMultiplicative(1.0e-15, 1.0e-15 + 1.0e-30, 1.0e-15)); |
|
493 MOZ_RELEASE_ASSERT(!FuzzyEqualsMultiplicative(1.0e-15, 1.0e-15 + 1.0e-30, 1.0e-16)); |
|
494 // Using a big epsilon |
|
495 MOZ_RELEASE_ASSERT(FuzzyEqualsMultiplicative(1.0e40, 2.0e40, 1.0)); |
|
496 MOZ_RELEASE_ASSERT(!FuzzyEqualsMultiplicative(1.0e40, 2.0e40, 0.1)); |
|
497 |
|
498 // "real world case" |
|
499 double oneThird = 10.0 / 3.0; |
|
500 MOZ_RELEASE_ASSERT(FuzzyEqualsAdditive(10.0, 3.0 * oneThird)); |
|
501 MOZ_RELEASE_ASSERT(FuzzyEqualsMultiplicative(10.0, 3.0 * oneThird)); |
|
502 // NaN check |
|
503 MOZ_RELEASE_ASSERT(!FuzzyEqualsAdditive(SpecificNaN<double>(1, 1), SpecificNaN<double>(1, 1))); |
|
504 MOZ_RELEASE_ASSERT(!FuzzyEqualsAdditive(SpecificNaN<double>(1, 2), SpecificNaN<double>(0, 8))); |
|
505 MOZ_RELEASE_ASSERT(!FuzzyEqualsMultiplicative(SpecificNaN<double>(1, 1), SpecificNaN<double>(1, 1))); |
|
506 MOZ_RELEASE_ASSERT(!FuzzyEqualsMultiplicative(SpecificNaN<double>(1, 2), SpecificNaN<double>(0, 200))); |
|
507 } |
|
508 |
|
509 static void |
|
510 TestAreApproximatelyEqual() |
|
511 { |
|
512 TestFloatsAreApproximatelyEqual(); |
|
513 TestDoublesAreApproximatelyEqual(); |
|
514 } |
|
515 |
|
516 int |
|
517 main() |
|
518 { |
|
519 TestAreIdentical(); |
|
520 TestExponentComponent(); |
|
521 TestPredicates(); |
|
522 TestAreApproximatelyEqual(); |
|
523 } |