1 // Copyright 2006-2008 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28 #include <stdlib.h>
29 #include <limits>
30
31 #include "cctest.h"
32 #include "double-conversion/diy-fp.h"
33 #include "double-conversion/utils.h"
34 #include "double-conversion/ieee.h"
35
36
37 using namespace double_conversion;
38
39
TEST(Uint64Conversions)40 TEST(Uint64Conversions) {
41 // Start by checking the byte-order.
42 uint64_t ordered = DOUBLE_CONVERSION_UINT64_2PART_C(0x01234567, 89ABCDEF);
43 CHECK_EQ(3512700564088504e-318, Double(ordered).value());
44
45 uint64_t min_double64 = DOUBLE_CONVERSION_UINT64_2PART_C(0x00000000, 00000001);
46 CHECK_EQ(5e-324, Double(min_double64).value());
47
48 uint64_t max_double64 = DOUBLE_CONVERSION_UINT64_2PART_C(0x7fefffff, ffffffff);
49 CHECK_EQ(1.7976931348623157e308, Double(max_double64).value());
50 }
51
52
TEST(Uint32Conversions)53 TEST(Uint32Conversions) {
54 // Start by checking the byte-order.
55 uint32_t ordered = 0x01234567;
56 CHECK_EQ(2.9988165487136453e-38f, Single(ordered).value());
57
58 uint32_t min_float32 = 0x00000001;
59 CHECK_EQ(1.4e-45f, Single(min_float32).value());
60
61 uint32_t max_float32 = 0x7f7fffff;
62 CHECK_EQ(3.4028234e38f, Single(max_float32).value());
63 }
64
65
TEST(Double_AsDiyFp)66 TEST(Double_AsDiyFp) {
67 uint64_t ordered = DOUBLE_CONVERSION_UINT64_2PART_C(0x01234567, 89ABCDEF);
68 DiyFp diy_fp = Double(ordered).AsDiyFp();
69 CHECK_EQ(0x12 - 0x3FF - 52, diy_fp.e());
70 // The 52 mantissa bits, plus the implicit 1 in bit 52 as a UINT64.
71 CHECK(DOUBLE_CONVERSION_UINT64_2PART_C(0x00134567, 89ABCDEF) == diy_fp.f()); // NOLINT
72
73 uint64_t min_double64 = DOUBLE_CONVERSION_UINT64_2PART_C(0x00000000, 00000001);
74 diy_fp = Double(min_double64).AsDiyFp();
75 CHECK_EQ(-0x3FF - 52 + 1, diy_fp.e());
76 // This is a denormal; so no hidden bit.
77 CHECK(1 == diy_fp.f()); // NOLINT
78
79 uint64_t max_double64 = DOUBLE_CONVERSION_UINT64_2PART_C(0x7fefffff, ffffffff);
80 diy_fp = Double(max_double64).AsDiyFp();
81 CHECK_EQ(0x7FE - 0x3FF - 52, diy_fp.e());
82 CHECK(DOUBLE_CONVERSION_UINT64_2PART_C(0x001fffff, ffffffff) == diy_fp.f()); // NOLINT
83 }
84
85
TEST(Single_AsDiyFp)86 TEST(Single_AsDiyFp) {
87 uint32_t ordered = 0x01234567;
88 DiyFp diy_fp = Single(ordered).AsDiyFp();
89 CHECK_EQ(0x2 - 0x7F - 23, diy_fp.e());
90 // The 23 mantissa bits, plus the implicit 1 in bit 24 as a uint32_t.
91 CHECK_EQ(0xA34567u, diy_fp.f());
92
93 uint32_t min_float32 = 0x00000001;
94 diy_fp = Single(min_float32).AsDiyFp();
95 CHECK_EQ(-0x7F - 23 + 1, diy_fp.e());
96 // This is a denormal; so no hidden bit.
97 CHECK_EQ(1u, diy_fp.f());
98
99 uint32_t max_float32 = 0x7f7fffff;
100 diy_fp = Single(max_float32).AsDiyFp();
101 CHECK_EQ(0xFE - 0x7F - 23, diy_fp.e());
102 CHECK_EQ(0x00ffffffu, diy_fp.f());
103 }
104
105
TEST(AsNormalizedDiyFp)106 TEST(AsNormalizedDiyFp) {
107 uint64_t ordered = DOUBLE_CONVERSION_UINT64_2PART_C(0x01234567, 89ABCDEF);
108 DiyFp diy_fp = Double(ordered).AsNormalizedDiyFp();
109 CHECK_EQ(0x12 - 0x3FF - 52 - 11, diy_fp.e());
110 CHECK((DOUBLE_CONVERSION_UINT64_2PART_C(0x00134567, 89ABCDEF) << 11) ==
111 diy_fp.f()); // NOLINT
112
113 uint64_t min_double64 = DOUBLE_CONVERSION_UINT64_2PART_C(0x00000000, 00000001);
114 diy_fp = Double(min_double64).AsNormalizedDiyFp();
115 CHECK_EQ(-0x3FF - 52 + 1 - 63, diy_fp.e());
116 // This is a denormal; so no hidden bit.
117 CHECK(DOUBLE_CONVERSION_UINT64_2PART_C(0x80000000, 00000000) == diy_fp.f()); // NOLINT
118
119 uint64_t max_double64 = DOUBLE_CONVERSION_UINT64_2PART_C(0x7fefffff, ffffffff);
120 diy_fp = Double(max_double64).AsNormalizedDiyFp();
121 CHECK_EQ(0x7FE - 0x3FF - 52 - 11, diy_fp.e());
122 CHECK((DOUBLE_CONVERSION_UINT64_2PART_C(0x001fffff, ffffffff) << 11) ==
123 diy_fp.f()); // NOLINT
124 }
125
126
TEST(Double_IsDenormal)127 TEST(Double_IsDenormal) {
128 uint64_t min_double64 = DOUBLE_CONVERSION_UINT64_2PART_C(0x00000000, 00000001);
129 CHECK(Double(min_double64).IsDenormal());
130 uint64_t bits = DOUBLE_CONVERSION_UINT64_2PART_C(0x000FFFFF, FFFFFFFF);
131 CHECK(Double(bits).IsDenormal());
132 bits = DOUBLE_CONVERSION_UINT64_2PART_C(0x00100000, 00000000);
133 CHECK(!Double(bits).IsDenormal());
134 }
135
136
TEST(Single_IsDenormal)137 TEST(Single_IsDenormal) {
138 uint32_t min_float32 = 0x00000001;
139 CHECK(Single(min_float32).IsDenormal());
140 uint32_t bits = 0x007FFFFF;
141 CHECK(Single(bits).IsDenormal());
142 bits = 0x00800000;
143 CHECK(!Single(bits).IsDenormal());
144 }
145
146
TEST(Double_IsSpecial)147 TEST(Double_IsSpecial) {
148 CHECK(Double(Double::Infinity()).IsSpecial());
149 CHECK(Double(-Double::Infinity()).IsSpecial());
150 CHECK(Double(Double::NaN()).IsSpecial());
151 uint64_t bits = DOUBLE_CONVERSION_UINT64_2PART_C(0xFFF12345, 00000000);
152 CHECK(Double(bits).IsSpecial());
153 // Denormals are not special:
154 CHECK(!Double(5e-324).IsSpecial());
155 CHECK(!Double(-5e-324).IsSpecial());
156 // And some random numbers:
157 CHECK(!Double(0.0).IsSpecial());
158 CHECK(!Double(-0.0).IsSpecial());
159 CHECK(!Double(1.0).IsSpecial());
160 CHECK(!Double(-1.0).IsSpecial());
161 CHECK(!Double(1000000.0).IsSpecial());
162 CHECK(!Double(-1000000.0).IsSpecial());
163 CHECK(!Double(1e23).IsSpecial());
164 CHECK(!Double(-1e23).IsSpecial());
165 CHECK(!Double(1.7976931348623157e308).IsSpecial());
166 CHECK(!Double(-1.7976931348623157e308).IsSpecial());
167 }
168
169
TEST(Single_IsSpecial)170 TEST(Single_IsSpecial) {
171 CHECK(Single(Single::Infinity()).IsSpecial());
172 CHECK(Single(-Single::Infinity()).IsSpecial());
173 CHECK(Single(Single::NaN()).IsSpecial());
174 uint32_t bits = 0xFFF12345;
175 CHECK(Single(bits).IsSpecial());
176 // Denormals are not special:
177 CHECK(!Single(1.4e-45f).IsSpecial());
178 CHECK(!Single(-1.4e-45f).IsSpecial());
179 // And some random numbers:
180 CHECK(!Single(0.0f).IsSpecial());
181 CHECK(!Single(-0.0f).IsSpecial());
182 CHECK(!Single(1.0f).IsSpecial());
183 CHECK(!Single(-1.0f).IsSpecial());
184 CHECK(!Single(1000000.0f).IsSpecial());
185 CHECK(!Single(-1000000.0f).IsSpecial());
186 CHECK(!Single(1e23f).IsSpecial());
187 CHECK(!Single(-1e23f).IsSpecial());
188 CHECK(!Single(1.18e-38f).IsSpecial());
189 CHECK(!Single(-1.18e-38f).IsSpecial());
190 }
191
192
TEST(Double_IsInfinite)193 TEST(Double_IsInfinite) {
194 CHECK(Double(Double::Infinity()).IsInfinite());
195 CHECK(Double(-Double::Infinity()).IsInfinite());
196 CHECK(!Double(Double::NaN()).IsInfinite());
197 CHECK(!Double(0.0).IsInfinite());
198 CHECK(!Double(-0.0).IsInfinite());
199 CHECK(!Double(1.0).IsInfinite());
200 CHECK(!Double(-1.0).IsInfinite());
201 uint64_t min_double64 = DOUBLE_CONVERSION_UINT64_2PART_C(0x00000000, 00000001);
202 CHECK(!Double(min_double64).IsInfinite());
203 }
204
205
TEST(Single_IsInfinite)206 TEST(Single_IsInfinite) {
207 CHECK(Single(Single::Infinity()).IsInfinite());
208 CHECK(Single(-Single::Infinity()).IsInfinite());
209 CHECK(!Single(Single::NaN()).IsInfinite());
210 CHECK(!Single(0.0f).IsInfinite());
211 CHECK(!Single(-0.0f).IsInfinite());
212 CHECK(!Single(1.0f).IsInfinite());
213 CHECK(!Single(-1.0f).IsInfinite());
214 uint32_t min_float32 = 0x00000001;
215 CHECK(!Single(min_float32).IsInfinite());
216 }
217
218
TEST(Double_IsNan)219 TEST(Double_IsNan) {
220 CHECK(Double(Double::NaN()).IsNan());
221 uint64_t other_nan = DOUBLE_CONVERSION_UINT64_2PART_C(0xFFFFFFFF, 00000001);
222 CHECK(Double(other_nan).IsNan());
223 CHECK(!Double(Double::Infinity()).IsNan());
224 CHECK(!Double(-Double::Infinity()).IsNan());
225 CHECK(!Double(0.0).IsNan());
226 CHECK(!Double(-0.0).IsNan());
227 CHECK(!Double(1.0).IsNan());
228 CHECK(!Double(-1.0).IsNan());
229 uint64_t min_double64 = DOUBLE_CONVERSION_UINT64_2PART_C(0x00000000, 00000001);
230 CHECK(!Double(min_double64).IsNan());
231 }
232
233
TEST(Single_IsNan)234 TEST(Single_IsNan) {
235 CHECK(Single(Single::NaN()).IsNan());
236 uint32_t other_nan = 0xFFFFF001;
237 CHECK(Single(other_nan).IsNan());
238 CHECK(!Single(Single::Infinity()).IsNan());
239 CHECK(!Single(-Single::Infinity()).IsNan());
240 CHECK(!Single(0.0f).IsNan());
241 CHECK(!Single(-0.0f).IsNan());
242 CHECK(!Single(1.0f).IsNan());
243 CHECK(!Single(-1.0f).IsNan());
244 uint32_t min_float32 = 0x00000001;
245 CHECK(!Single(min_float32).IsNan());
246 }
247
248
TEST(Double_Sign)249 TEST(Double_Sign) {
250 CHECK_EQ(1, Double(1.0).Sign());
251 CHECK_EQ(1, Double(Double::Infinity()).Sign());
252 CHECK_EQ(-1, Double(-Double::Infinity()).Sign());
253 CHECK_EQ(1, Double(0.0).Sign());
254 CHECK_EQ(-1, Double(-0.0).Sign());
255 uint64_t min_double64 = DOUBLE_CONVERSION_UINT64_2PART_C(0x00000000, 00000001);
256 CHECK_EQ(1, Double(min_double64).Sign());
257 }
258
259
TEST(Single_Sign)260 TEST(Single_Sign) {
261 CHECK_EQ(1, Single(1.0f).Sign());
262 CHECK_EQ(1, Single(Single::Infinity()).Sign());
263 CHECK_EQ(-1, Single(-Single::Infinity()).Sign());
264 CHECK_EQ(1, Single(0.0f).Sign());
265 CHECK_EQ(-1, Single(-0.0f).Sign());
266 uint32_t min_float32 = 0x00000001;
267 CHECK_EQ(1, Single(min_float32).Sign());
268 }
269
270
TEST(Double_NormalizedBoundaries)271 TEST(Double_NormalizedBoundaries) {
272 DiyFp boundary_plus;
273 DiyFp boundary_minus;
274 DiyFp diy_fp = Double(1.5).AsNormalizedDiyFp();
275 Double(1.5).NormalizedBoundaries(&boundary_minus, &boundary_plus);
276 CHECK_EQ(diy_fp.e(), boundary_minus.e());
277 CHECK_EQ(diy_fp.e(), boundary_plus.e());
278 // 1.5 does not have a significand of the form 2^p (for some p).
279 // Therefore its boundaries are at the same distance.
280 CHECK(diy_fp.f() - boundary_minus.f() == boundary_plus.f() - diy_fp.f());
281 CHECK((1 << 10) == diy_fp.f() - boundary_minus.f()); // NOLINT
282
283 diy_fp = Double(1.0).AsNormalizedDiyFp();
284 Double(1.0).NormalizedBoundaries(&boundary_minus, &boundary_plus);
285 CHECK_EQ(diy_fp.e(), boundary_minus.e());
286 CHECK_EQ(diy_fp.e(), boundary_plus.e());
287 // 1.0 does have a significand of the form 2^p (for some p).
288 // Therefore its lower boundary is twice as close as the upper boundary.
289 CHECK(boundary_plus.f() - diy_fp.f() > diy_fp.f() - boundary_minus.f());
290 CHECK((1 << 9) == diy_fp.f() - boundary_minus.f()); // NOLINT
291 CHECK((1 << 10) == boundary_plus.f() - diy_fp.f()); // NOLINT
292
293 uint64_t min_double64 = DOUBLE_CONVERSION_UINT64_2PART_C(0x00000000, 00000001);
294 diy_fp = Double(min_double64).AsNormalizedDiyFp();
295 Double(min_double64).NormalizedBoundaries(&boundary_minus, &boundary_plus);
296 CHECK_EQ(diy_fp.e(), boundary_minus.e());
297 CHECK_EQ(diy_fp.e(), boundary_plus.e());
298 // min-value does not have a significand of the form 2^p (for some p).
299 // Therefore its boundaries are at the same distance.
300 CHECK(diy_fp.f() - boundary_minus.f() == boundary_plus.f() - diy_fp.f());
301 // Denormals have their boundaries much closer.
302 CHECK((static_cast<uint64_t>(1) << 62) ==
303 diy_fp.f() - boundary_minus.f()); // NOLINT
304
305 uint64_t smallest_normal64 = DOUBLE_CONVERSION_UINT64_2PART_C(0x00100000, 00000000);
306 diy_fp = Double(smallest_normal64).AsNormalizedDiyFp();
307 Double(smallest_normal64).NormalizedBoundaries(&boundary_minus,
308 &boundary_plus);
309 CHECK_EQ(diy_fp.e(), boundary_minus.e());
310 CHECK_EQ(diy_fp.e(), boundary_plus.e());
311 // Even though the significand is of the form 2^p (for some p), its boundaries
312 // are at the same distance. (This is the only exception).
313 CHECK(diy_fp.f() - boundary_minus.f() == boundary_plus.f() - diy_fp.f());
314 CHECK((1 << 10) == diy_fp.f() - boundary_minus.f()); // NOLINT
315
316 uint64_t largest_denormal64 = DOUBLE_CONVERSION_UINT64_2PART_C(0x000FFFFF, FFFFFFFF);
317 diy_fp = Double(largest_denormal64).AsNormalizedDiyFp();
318 Double(largest_denormal64).NormalizedBoundaries(&boundary_minus,
319 &boundary_plus);
320 CHECK_EQ(diy_fp.e(), boundary_minus.e());
321 CHECK_EQ(diy_fp.e(), boundary_plus.e());
322 CHECK(diy_fp.f() - boundary_minus.f() == boundary_plus.f() - diy_fp.f());
323 CHECK((1 << 11) == diy_fp.f() - boundary_minus.f()); // NOLINT
324
325 uint64_t max_double64 = DOUBLE_CONVERSION_UINT64_2PART_C(0x7fefffff, ffffffff);
326 diy_fp = Double(max_double64).AsNormalizedDiyFp();
327 Double(max_double64).NormalizedBoundaries(&boundary_minus, &boundary_plus);
328 CHECK_EQ(diy_fp.e(), boundary_minus.e());
329 CHECK_EQ(diy_fp.e(), boundary_plus.e());
330 // max-value does not have a significand of the form 2^p (for some p).
331 // Therefore its boundaries are at the same distance.
332 CHECK(diy_fp.f() - boundary_minus.f() == boundary_plus.f() - diy_fp.f());
333 CHECK((1 << 10) == diy_fp.f() - boundary_minus.f()); // NOLINT
334 }
335
336
TEST(Single_NormalizedBoundaries)337 TEST(Single_NormalizedBoundaries) {
338 uint64_t kOne64 = 1;
339 DiyFp boundary_plus;
340 DiyFp boundary_minus;
341 DiyFp diy_fp = Single(1.5f).AsDiyFp();
342 diy_fp.Normalize();
343 Single(1.5f).NormalizedBoundaries(&boundary_minus, &boundary_plus);
344 CHECK_EQ(diy_fp.e(), boundary_minus.e());
345 CHECK_EQ(diy_fp.e(), boundary_plus.e());
346 // 1.5 does not have a significand of the form 2^p (for some p).
347 // Therefore its boundaries are at the same distance.
348 CHECK(diy_fp.f() - boundary_minus.f() == boundary_plus.f() - diy_fp.f());
349 // Normalization shifts the significand by 8 bits. Add 32 bits for the bigger
350 // data-type, and remove 1 because boundaries are at half a ULP.
351 CHECK((kOne64 << 39) == diy_fp.f() - boundary_minus.f());
352
353 diy_fp = Single(1.0f).AsDiyFp();
354 diy_fp.Normalize();
355 Single(1.0f).NormalizedBoundaries(&boundary_minus, &boundary_plus);
356 CHECK_EQ(diy_fp.e(), boundary_minus.e());
357 CHECK_EQ(diy_fp.e(), boundary_plus.e());
358 // 1.0 does have a significand of the form 2^p (for some p).
359 // Therefore its lower boundary is twice as close as the upper boundary.
360 CHECK(boundary_plus.f() - diy_fp.f() > diy_fp.f() - boundary_minus.f());
361 CHECK((kOne64 << 38) == diy_fp.f() - boundary_minus.f()); // NOLINT
362 CHECK((kOne64 << 39) == boundary_plus.f() - diy_fp.f()); // NOLINT
363
364 uint32_t min_float32 = 0x00000001;
365 diy_fp = Single(min_float32).AsDiyFp();
366 diy_fp.Normalize();
367 Single(min_float32).NormalizedBoundaries(&boundary_minus, &boundary_plus);
368 CHECK_EQ(diy_fp.e(), boundary_minus.e());
369 CHECK_EQ(diy_fp.e(), boundary_plus.e());
370 // min-value does not have a significand of the form 2^p (for some p).
371 // Therefore its boundaries are at the same distance.
372 CHECK(diy_fp.f() - boundary_minus.f() == boundary_plus.f() - diy_fp.f());
373 // Denormals have their boundaries much closer.
374 CHECK((kOne64 << 62) == diy_fp.f() - boundary_minus.f()); // NOLINT
375
376 uint32_t smallest_normal32 = 0x00800000;
377 diy_fp = Single(smallest_normal32).AsDiyFp();
378 diy_fp.Normalize();
379 Single(smallest_normal32).NormalizedBoundaries(&boundary_minus,
380 &boundary_plus);
381 CHECK_EQ(diy_fp.e(), boundary_minus.e());
382 CHECK_EQ(diy_fp.e(), boundary_plus.e());
383 // Even though the significand is of the form 2^p (for some p), its boundaries
384 // are at the same distance. (This is the only exception).
385 CHECK(diy_fp.f() - boundary_minus.f() == boundary_plus.f() - diy_fp.f());
386 CHECK((kOne64 << 39) == diy_fp.f() - boundary_minus.f()); // NOLINT
387
388 uint32_t largest_denormal32 = 0x007FFFFF;
389 diy_fp = Single(largest_denormal32).AsDiyFp();
390 diy_fp.Normalize();
391 Single(largest_denormal32).NormalizedBoundaries(&boundary_minus,
392 &boundary_plus);
393 CHECK_EQ(diy_fp.e(), boundary_minus.e());
394 CHECK_EQ(diy_fp.e(), boundary_plus.e());
395 CHECK(diy_fp.f() - boundary_minus.f() == boundary_plus.f() - diy_fp.f());
396 CHECK((kOne64 << 40) == diy_fp.f() - boundary_minus.f()); // NOLINT
397
398 uint32_t max_float32 = 0x7f7fffff;
399 diy_fp = Single(max_float32).AsDiyFp();
400 diy_fp.Normalize();
401 Single(max_float32).NormalizedBoundaries(&boundary_minus, &boundary_plus);
402 CHECK_EQ(diy_fp.e(), boundary_minus.e());
403 CHECK_EQ(diy_fp.e(), boundary_plus.e());
404 // max-value does not have a significand of the form 2^p (for some p).
405 // Therefore its boundaries are at the same distance.
406 CHECK(diy_fp.f() - boundary_minus.f() == boundary_plus.f() - diy_fp.f());
407 CHECK((kOne64 << 39) == diy_fp.f() - boundary_minus.f()); // NOLINT
408 }
409
410
TEST(NextDouble)411 TEST(NextDouble) {
412 CHECK_EQ(4e-324, Double(0.0).NextDouble());
413 CHECK_EQ(0.0, Double(-0.0).NextDouble());
414 CHECK_EQ(-0.0, Double(-4e-324).NextDouble());
415 CHECK(Double(Double(-0.0).NextDouble()).Sign() > 0);
416 CHECK(Double(Double(-4e-324).NextDouble()).Sign() < 0);
417 Double d0(-4e-324);
418 Double d1(d0.NextDouble());
419 Double d2(d1.NextDouble());
420 CHECK_EQ(-0.0, d1.value());
421 CHECK(d1.Sign() < 0);
422 CHECK_EQ(0.0, d2.value());
423 CHECK(d2.Sign() > 0);
424 CHECK_EQ(4e-324, d2.NextDouble());
425 CHECK_EQ(-1.7976931348623157e308, Double(-Double::Infinity()).NextDouble());
426 CHECK_EQ(Double::Infinity(),
427 Double(DOUBLE_CONVERSION_UINT64_2PART_C(0x7fefffff, ffffffff)).NextDouble());
428 }
429
430
TEST(PreviousDouble)431 TEST(PreviousDouble) {
432 CHECK_EQ(0.0, Double(4e-324).PreviousDouble());
433 CHECK_EQ(-0.0, Double(0.0).PreviousDouble());
434 CHECK(Double(Double(0.0).PreviousDouble()).Sign() < 0);
435 CHECK_EQ(-4e-324, Double(-0.0).PreviousDouble());
436 Double d0(4e-324);
437 Double d1(d0.PreviousDouble());
438 Double d2(d1.PreviousDouble());
439 CHECK_EQ(0.0, d1.value());
440 CHECK(d1.Sign() > 0);
441 CHECK_EQ(-0.0, d2.value());
442 CHECK(d2.Sign() < 0);
443 CHECK_EQ(-4e-324, d2.PreviousDouble());
444 CHECK_EQ(1.7976931348623157e308, Double(Double::Infinity()).PreviousDouble());
445 CHECK_EQ(-Double::Infinity(),
446 Double(DOUBLE_CONVERSION_UINT64_2PART_C(0xffefffff, ffffffff)).PreviousDouble());
447 }
448
TEST(SignalingNan)449 TEST(SignalingNan) {
450 Double nan(Double::NaN());
451 CHECK(nan.IsNan());
452 CHECK(nan.IsQuietNan());
453 CHECK(Double(std::numeric_limits<double>::quiet_NaN()).IsQuietNan());
454 CHECK(Double(std::numeric_limits<double>::signaling_NaN()).IsSignalingNan());
455 }
456
TEST(SignalingNanSingle)457 TEST(SignalingNanSingle) {
458 Single nan(Single::NaN());
459 CHECK(nan.IsNan());
460 CHECK(nan.IsQuietNan());
461 CHECK(Single(std::numeric_limits<float>::quiet_NaN()).IsQuietNan());
462 #ifndef _MSC_VER
463 // Visual studio has a bug for generating signaling NaNs:
464 // https://developercommunity.visualstudio.com/t/stdnumeric-limitssignaling-nan-returns-quiet-nan/155064
465 CHECK(Single(std::numeric_limits<float>::signaling_NaN()).IsSignalingNan());
466 #endif
467 }
468