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