OLD | NEW |
| (Empty) |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | |
2 | |
3 #include <stdlib.h> | |
4 | |
5 #include "v8.h" | |
6 | |
7 #include "platform.h" | |
8 #include "cctest.h" | |
9 #include "diy_fp.h" | |
10 #include "double.h" | |
11 | |
12 | |
13 using namespace v8::internal; | |
14 | |
15 | |
16 TEST(Uint64Conversions) { | |
17 // Start by checking the byte-order. | |
18 uint64_t ordered = V8_2PART_UINT64_C(0x01234567, 89ABCDEF); | |
19 CHECK_EQ(3512700564088504e-318, Double(ordered).value()); | |
20 | |
21 uint64_t min_double64 = V8_2PART_UINT64_C(0x00000000, 00000001); | |
22 CHECK_EQ(5e-324, Double(min_double64).value()); | |
23 | |
24 uint64_t max_double64 = V8_2PART_UINT64_C(0x7fefffff, ffffffff); | |
25 CHECK_EQ(1.7976931348623157e308, Double(max_double64).value()); | |
26 } | |
27 | |
28 TEST(AsDiyFp) { | |
29 uint64_t ordered = V8_2PART_UINT64_C(0x01234567, 89ABCDEF); | |
30 DiyFp diy_fp = Double(ordered).AsDiyFp(); | |
31 CHECK_EQ(0x12 - 0x3FF - 52, diy_fp.e()); | |
32 // The 52 mantissa bits, plus the implicit 1 in bit 52 as a UINT64. | |
33 CHECK(V8_2PART_UINT64_C(0x00134567, 89ABCDEF) == diy_fp.f()); // NOLINT | |
34 | |
35 uint64_t min_double64 = V8_2PART_UINT64_C(0x00000000, 00000001); | |
36 diy_fp = Double(min_double64).AsDiyFp(); | |
37 CHECK_EQ(-0x3FF - 52 + 1, diy_fp.e()); | |
38 // This is a denormal; so no hidden bit. | |
39 CHECK(1 == diy_fp.f()); // NOLINT | |
40 | |
41 uint64_t max_double64 = V8_2PART_UINT64_C(0x7fefffff, ffffffff); | |
42 diy_fp = Double(max_double64).AsDiyFp(); | |
43 CHECK_EQ(0x7FE - 0x3FF - 52, diy_fp.e()); | |
44 CHECK(V8_2PART_UINT64_C(0x001fffff, ffffffff) == diy_fp.f()); // NOLINT | |
45 } | |
46 | |
47 | |
48 TEST(AsNormalizedDiyFp) { | |
49 uint64_t ordered = V8_2PART_UINT64_C(0x01234567, 89ABCDEF); | |
50 DiyFp diy_fp = Double(ordered).AsNormalizedDiyFp(); | |
51 CHECK_EQ(0x12 - 0x3FF - 52 - 11, diy_fp.e()); | |
52 CHECK((V8_2PART_UINT64_C(0x00134567, 89ABCDEF) << 11) == | |
53 diy_fp.f()); // NOLINT | |
54 | |
55 uint64_t min_double64 = V8_2PART_UINT64_C(0x00000000, 00000001); | |
56 diy_fp = Double(min_double64).AsNormalizedDiyFp(); | |
57 CHECK_EQ(-0x3FF - 52 + 1 - 63, diy_fp.e()); | |
58 // This is a denormal; so no hidden bit. | |
59 CHECK(V8_2PART_UINT64_C(0x80000000, 00000000) == diy_fp.f()); // NOLINT | |
60 | |
61 uint64_t max_double64 = V8_2PART_UINT64_C(0x7fefffff, ffffffff); | |
62 diy_fp = Double(max_double64).AsNormalizedDiyFp(); | |
63 CHECK_EQ(0x7FE - 0x3FF - 52 - 11, diy_fp.e()); | |
64 CHECK((V8_2PART_UINT64_C(0x001fffff, ffffffff) << 11) == | |
65 diy_fp.f()); // NOLINT | |
66 } | |
67 | |
68 | |
69 TEST(IsDenormal) { | |
70 uint64_t min_double64 = V8_2PART_UINT64_C(0x00000000, 00000001); | |
71 CHECK(Double(min_double64).IsDenormal()); | |
72 uint64_t bits = V8_2PART_UINT64_C(0x000FFFFF, FFFFFFFF); | |
73 CHECK(Double(bits).IsDenormal()); | |
74 bits = V8_2PART_UINT64_C(0x00100000, 00000000); | |
75 CHECK(!Double(bits).IsDenormal()); | |
76 } | |
77 | |
78 | |
79 TEST(IsSpecial) { | |
80 CHECK(Double(V8_INFINITY).IsSpecial()); | |
81 CHECK(Double(-V8_INFINITY).IsSpecial()); | |
82 CHECK(Double(OS::nan_value()).IsSpecial()); | |
83 uint64_t bits = V8_2PART_UINT64_C(0xFFF12345, 00000000); | |
84 CHECK(Double(bits).IsSpecial()); | |
85 // Denormals are not special: | |
86 CHECK(!Double(5e-324).IsSpecial()); | |
87 CHECK(!Double(-5e-324).IsSpecial()); | |
88 // And some random numbers: | |
89 CHECK(!Double(0.0).IsSpecial()); | |
90 CHECK(!Double(-0.0).IsSpecial()); | |
91 CHECK(!Double(1.0).IsSpecial()); | |
92 CHECK(!Double(-1.0).IsSpecial()); | |
93 CHECK(!Double(1000000.0).IsSpecial()); | |
94 CHECK(!Double(-1000000.0).IsSpecial()); | |
95 CHECK(!Double(1e23).IsSpecial()); | |
96 CHECK(!Double(-1e23).IsSpecial()); | |
97 CHECK(!Double(1.7976931348623157e308).IsSpecial()); | |
98 CHECK(!Double(-1.7976931348623157e308).IsSpecial()); | |
99 } | |
100 | |
101 | |
102 TEST(IsInfinite) { | |
103 CHECK(Double(V8_INFINITY).IsInfinite()); | |
104 CHECK(Double(-V8_INFINITY).IsInfinite()); | |
105 CHECK(!Double(OS::nan_value()).IsInfinite()); | |
106 CHECK(!Double(0.0).IsInfinite()); | |
107 CHECK(!Double(-0.0).IsInfinite()); | |
108 CHECK(!Double(1.0).IsInfinite()); | |
109 CHECK(!Double(-1.0).IsInfinite()); | |
110 uint64_t min_double64 = V8_2PART_UINT64_C(0x00000000, 00000001); | |
111 CHECK(!Double(min_double64).IsInfinite()); | |
112 } | |
113 | |
114 | |
115 TEST(IsNan) { | |
116 CHECK(Double(OS::nan_value()).IsNan()); | |
117 uint64_t other_nan = V8_2PART_UINT64_C(0xFFFFFFFF, 00000001); | |
118 CHECK(Double(other_nan).IsNan()); | |
119 CHECK(!Double(V8_INFINITY).IsNan()); | |
120 CHECK(!Double(-V8_INFINITY).IsNan()); | |
121 CHECK(!Double(0.0).IsNan()); | |
122 CHECK(!Double(-0.0).IsNan()); | |
123 CHECK(!Double(1.0).IsNan()); | |
124 CHECK(!Double(-1.0).IsNan()); | |
125 uint64_t min_double64 = V8_2PART_UINT64_C(0x00000000, 00000001); | |
126 CHECK(!Double(min_double64).IsNan()); | |
127 } | |
128 | |
129 | |
130 TEST(Sign) { | |
131 CHECK_EQ(1, Double(1.0).Sign()); | |
132 CHECK_EQ(1, Double(V8_INFINITY).Sign()); | |
133 CHECK_EQ(-1, Double(-V8_INFINITY).Sign()); | |
134 CHECK_EQ(1, Double(0.0).Sign()); | |
135 CHECK_EQ(-1, Double(-0.0).Sign()); | |
136 uint64_t min_double64 = V8_2PART_UINT64_C(0x00000000, 00000001); | |
137 CHECK_EQ(1, Double(min_double64).Sign()); | |
138 } | |
139 | |
140 | |
141 TEST(NormalizedBoundaries) { | |
142 DiyFp boundary_plus; | |
143 DiyFp boundary_minus; | |
144 DiyFp diy_fp = Double(1.5).AsNormalizedDiyFp(); | |
145 Double(1.5).NormalizedBoundaries(&boundary_minus, &boundary_plus); | |
146 CHECK_EQ(diy_fp.e(), boundary_minus.e()); | |
147 CHECK_EQ(diy_fp.e(), boundary_plus.e()); | |
148 // 1.5 does not have a significand of the form 2^p (for some p). | |
149 // Therefore its boundaries are at the same distance. | |
150 CHECK(diy_fp.f() - boundary_minus.f() == boundary_plus.f() - diy_fp.f()); | |
151 CHECK((1 << 10) == diy_fp.f() - boundary_minus.f()); // NOLINT | |
152 | |
153 diy_fp = Double(1.0).AsNormalizedDiyFp(); | |
154 Double(1.0).NormalizedBoundaries(&boundary_minus, &boundary_plus); | |
155 CHECK_EQ(diy_fp.e(), boundary_minus.e()); | |
156 CHECK_EQ(diy_fp.e(), boundary_plus.e()); | |
157 // 1.0 does have a significand of the form 2^p (for some p). | |
158 // Therefore its lower boundary is twice as close as the upper boundary. | |
159 CHECK_GT(boundary_plus.f() - diy_fp.f(), diy_fp.f() - boundary_minus.f()); | |
160 CHECK((1 << 9) == diy_fp.f() - boundary_minus.f()); // NOLINT | |
161 CHECK((1 << 10) == boundary_plus.f() - diy_fp.f()); // NOLINT | |
162 | |
163 uint64_t min_double64 = V8_2PART_UINT64_C(0x00000000, 00000001); | |
164 diy_fp = Double(min_double64).AsNormalizedDiyFp(); | |
165 Double(min_double64).NormalizedBoundaries(&boundary_minus, &boundary_plus); | |
166 CHECK_EQ(diy_fp.e(), boundary_minus.e()); | |
167 CHECK_EQ(diy_fp.e(), boundary_plus.e()); | |
168 // min-value does not have a significand of the form 2^p (for some p). | |
169 // Therefore its boundaries are at the same distance. | |
170 CHECK(diy_fp.f() - boundary_minus.f() == boundary_plus.f() - diy_fp.f()); | |
171 // Denormals have their boundaries much closer. | |
172 CHECK((static_cast<uint64_t>(1) << 62) == | |
173 diy_fp.f() - boundary_minus.f()); // NOLINT | |
174 | |
175 uint64_t smallest_normal64 = V8_2PART_UINT64_C(0x00100000, 00000000); | |
176 diy_fp = Double(smallest_normal64).AsNormalizedDiyFp(); | |
177 Double(smallest_normal64).NormalizedBoundaries(&boundary_minus, | |
178 &boundary_plus); | |
179 CHECK_EQ(diy_fp.e(), boundary_minus.e()); | |
180 CHECK_EQ(diy_fp.e(), boundary_plus.e()); | |
181 // Even though the significand is of the form 2^p (for some p), its boundaries | |
182 // are at the same distance. (This is the only exception). | |
183 CHECK(diy_fp.f() - boundary_minus.f() == boundary_plus.f() - diy_fp.f()); | |
184 CHECK((1 << 10) == diy_fp.f() - boundary_minus.f()); // NOLINT | |
185 | |
186 uint64_t largest_denormal64 = V8_2PART_UINT64_C(0x000FFFFF, FFFFFFFF); | |
187 diy_fp = Double(largest_denormal64).AsNormalizedDiyFp(); | |
188 Double(largest_denormal64).NormalizedBoundaries(&boundary_minus, | |
189 &boundary_plus); | |
190 CHECK_EQ(diy_fp.e(), boundary_minus.e()); | |
191 CHECK_EQ(diy_fp.e(), boundary_plus.e()); | |
192 CHECK(diy_fp.f() - boundary_minus.f() == boundary_plus.f() - diy_fp.f()); | |
193 CHECK((1 << 11) == diy_fp.f() - boundary_minus.f()); // NOLINT | |
194 | |
195 uint64_t max_double64 = V8_2PART_UINT64_C(0x7fefffff, ffffffff); | |
196 diy_fp = Double(max_double64).AsNormalizedDiyFp(); | |
197 Double(max_double64).NormalizedBoundaries(&boundary_minus, &boundary_plus); | |
198 CHECK_EQ(diy_fp.e(), boundary_minus.e()); | |
199 CHECK_EQ(diy_fp.e(), boundary_plus.e()); | |
200 // max-value does not have a significand of the form 2^p (for some p). | |
201 // Therefore its boundaries are at the same distance. | |
202 CHECK(diy_fp.f() - boundary_minus.f() == boundary_plus.f() - diy_fp.f()); | |
203 CHECK((1 << 10) == diy_fp.f() - boundary_minus.f()); // NOLINT | |
204 } | |
OLD | NEW |