Line data Source code
1 : // Copyright 2011 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 :
30 : #include "src/v8.h"
31 :
32 : #include "src/bignum-dtoa.h"
33 :
34 : #include "src/base/platform/platform.h"
35 : #include "src/double.h"
36 : #include "test/cctest/cctest.h"
37 : #include "test/cctest/gay-fixed.h"
38 : #include "test/cctest/gay-precision.h"
39 : #include "test/cctest/gay-shortest.h"
40 :
41 : namespace v8 {
42 : namespace internal {
43 : namespace test_bignum_dtoa {
44 :
45 : // Removes trailing '0' digits.
46 : // Can return the empty string if all digits are 0.
47 1000095 : static void TrimRepresentation(Vector<char> representation) {
48 : int len = StrLength(representation.start());
49 : int i;
50 1914790 : for (i = len - 1; i >= 0; --i) {
51 3507330 : if (representation[i] != '0') break;
52 : }
53 2000190 : representation[i + 1] = '\0';
54 1000095 : }
55 :
56 :
57 : static const int kBufferSize = 100;
58 :
59 :
60 26644 : TEST(BignumDtoaVariousDoubles) {
61 : char buffer_container[kBufferSize];
62 : Vector<char> buffer(buffer_container, kBufferSize);
63 : int length;
64 : int point;
65 :
66 5 : BignumDtoa(1.0, BIGNUM_DTOA_SHORTEST, 0, buffer, &length, &point);
67 5 : CHECK_EQ(0, strcmp("1", buffer.start()));
68 5 : CHECK_EQ(1, point);
69 :
70 5 : BignumDtoa(1.0, BIGNUM_DTOA_FIXED, 3, buffer, &length, &point);
71 5 : CHECK_GE(3, length - point);
72 5 : TrimRepresentation(buffer);
73 5 : CHECK_EQ(0, strcmp("1", buffer.start()));
74 5 : CHECK_EQ(1, point);
75 :
76 5 : BignumDtoa(1.0, BIGNUM_DTOA_PRECISION, 3, buffer, &length, &point);
77 5 : CHECK_GE(3, length);
78 5 : TrimRepresentation(buffer);
79 5 : CHECK_EQ(0, strcmp("1", buffer.start()));
80 5 : CHECK_EQ(1, point);
81 :
82 5 : BignumDtoa(1.5, BIGNUM_DTOA_SHORTEST, 0, buffer, &length, &point);
83 5 : CHECK_EQ(0, strcmp("15", buffer.start()));
84 5 : CHECK_EQ(1, point);
85 :
86 5 : BignumDtoa(1.5, BIGNUM_DTOA_FIXED, 10, buffer, &length, &point);
87 5 : CHECK_GE(10, length - point);
88 5 : TrimRepresentation(buffer);
89 5 : CHECK_EQ(0, strcmp("15", buffer.start()));
90 5 : CHECK_EQ(1, point);
91 :
92 5 : BignumDtoa(1.5, BIGNUM_DTOA_PRECISION, 10, buffer, &length, &point);
93 5 : CHECK_GE(10, length);
94 5 : TrimRepresentation(buffer);
95 5 : CHECK_EQ(0, strcmp("15", buffer.start()));
96 5 : CHECK_EQ(1, point);
97 :
98 : double min_double = 5e-324;
99 5 : BignumDtoa(min_double, BIGNUM_DTOA_SHORTEST, 0, buffer, &length, &point);
100 5 : CHECK_EQ(0, strcmp("5", buffer.start()));
101 5 : CHECK_EQ(-323, point);
102 :
103 5 : BignumDtoa(min_double, BIGNUM_DTOA_FIXED, 5, buffer, &length, &point);
104 5 : CHECK_GE(5, length - point);
105 5 : TrimRepresentation(buffer);
106 5 : CHECK_EQ(0, strcmp("", buffer.start()));
107 :
108 5 : BignumDtoa(min_double, BIGNUM_DTOA_PRECISION, 5, buffer, &length, &point);
109 5 : CHECK_GE(5, length);
110 5 : TrimRepresentation(buffer);
111 5 : CHECK_EQ(0, strcmp("49407", buffer.start()));
112 5 : CHECK_EQ(-323, point);
113 :
114 : double max_double = 1.7976931348623157e308;
115 5 : BignumDtoa(max_double, BIGNUM_DTOA_SHORTEST, 0, buffer, &length, &point);
116 5 : CHECK_EQ(0, strcmp("17976931348623157", buffer.start()));
117 5 : CHECK_EQ(309, point);
118 :
119 5 : BignumDtoa(max_double, BIGNUM_DTOA_PRECISION, 7, buffer, &length, &point);
120 5 : CHECK_GE(7, length);
121 5 : TrimRepresentation(buffer);
122 5 : CHECK_EQ(0, strcmp("1797693", buffer.start()));
123 5 : CHECK_EQ(309, point);
124 :
125 5 : BignumDtoa(4294967272.0, BIGNUM_DTOA_SHORTEST, 0, buffer, &length, &point);
126 5 : CHECK_EQ(0, strcmp("4294967272", buffer.start()));
127 5 : CHECK_EQ(10, point);
128 :
129 5 : BignumDtoa(4294967272.0, BIGNUM_DTOA_FIXED, 5, buffer, &length, &point);
130 5 : CHECK_EQ(0, strcmp("429496727200000", buffer.start()));
131 5 : CHECK_EQ(10, point);
132 :
133 :
134 5 : BignumDtoa(4294967272.0, BIGNUM_DTOA_PRECISION, 14, buffer, &length, &point);
135 5 : CHECK_GE(14, length);
136 5 : TrimRepresentation(buffer);
137 5 : CHECK_EQ(0, strcmp("4294967272", buffer.start()));
138 5 : CHECK_EQ(10, point);
139 :
140 : BignumDtoa(4.1855804968213567e298, BIGNUM_DTOA_SHORTEST, 0,
141 5 : buffer, &length, &point);
142 5 : CHECK_EQ(0, strcmp("4185580496821357", buffer.start()));
143 5 : CHECK_EQ(299, point);
144 :
145 : BignumDtoa(4.1855804968213567e298, BIGNUM_DTOA_PRECISION, 20,
146 5 : buffer, &length, &point);
147 5 : CHECK_GE(20, length);
148 5 : TrimRepresentation(buffer);
149 5 : CHECK_EQ(0, strcmp("41855804968213567225", buffer.start()));
150 5 : CHECK_EQ(299, point);
151 :
152 : BignumDtoa(5.5626846462680035e-309, BIGNUM_DTOA_SHORTEST, 0,
153 5 : buffer, &length, &point);
154 5 : CHECK_EQ(0, strcmp("5562684646268003", buffer.start()));
155 5 : CHECK_EQ(-308, point);
156 :
157 : BignumDtoa(5.5626846462680035e-309, BIGNUM_DTOA_PRECISION, 1,
158 5 : buffer, &length, &point);
159 5 : CHECK_GE(1, length);
160 5 : TrimRepresentation(buffer);
161 5 : CHECK_EQ(0, strcmp("6", buffer.start()));
162 5 : CHECK_EQ(-308, point);
163 :
164 : BignumDtoa(2147483648.0, BIGNUM_DTOA_SHORTEST, 0,
165 5 : buffer, &length, &point);
166 5 : CHECK_EQ(0, strcmp("2147483648", buffer.start()));
167 5 : CHECK_EQ(10, point);
168 :
169 :
170 : BignumDtoa(2147483648.0, BIGNUM_DTOA_FIXED, 2,
171 5 : buffer, &length, &point);
172 5 : CHECK_GE(2, length - point);
173 5 : TrimRepresentation(buffer);
174 5 : CHECK_EQ(0, strcmp("2147483648", buffer.start()));
175 5 : CHECK_EQ(10, point);
176 :
177 : BignumDtoa(2147483648.0, BIGNUM_DTOA_PRECISION, 5,
178 5 : buffer, &length, &point);
179 5 : CHECK_GE(5, length);
180 5 : TrimRepresentation(buffer);
181 5 : CHECK_EQ(0, strcmp("21475", buffer.start()));
182 5 : CHECK_EQ(10, point);
183 :
184 : BignumDtoa(3.5844466002796428e+298, BIGNUM_DTOA_SHORTEST, 0,
185 5 : buffer, &length, &point);
186 5 : CHECK_EQ(0, strcmp("35844466002796428", buffer.start()));
187 5 : CHECK_EQ(299, point);
188 :
189 : BignumDtoa(3.5844466002796428e+298, BIGNUM_DTOA_PRECISION, 10,
190 5 : buffer, &length, &point);
191 5 : CHECK_GE(10, length);
192 5 : TrimRepresentation(buffer);
193 5 : CHECK_EQ(0, strcmp("35844466", buffer.start()));
194 5 : CHECK_EQ(299, point);
195 :
196 : uint64_t smallest_normal64 = V8_2PART_UINT64_C(0x00100000, 00000000);
197 : double v = Double(smallest_normal64).value();
198 5 : BignumDtoa(v, BIGNUM_DTOA_SHORTEST, 0, buffer, &length, &point);
199 5 : CHECK_EQ(0, strcmp("22250738585072014", buffer.start()));
200 5 : CHECK_EQ(-307, point);
201 :
202 5 : BignumDtoa(v, BIGNUM_DTOA_PRECISION, 20, buffer, &length, &point);
203 5 : CHECK_GE(20, length);
204 5 : TrimRepresentation(buffer);
205 5 : CHECK_EQ(0, strcmp("22250738585072013831", buffer.start()));
206 5 : CHECK_EQ(-307, point);
207 :
208 : uint64_t largest_denormal64 = V8_2PART_UINT64_C(0x000FFFFF, FFFFFFFF);
209 : v = Double(largest_denormal64).value();
210 5 : BignumDtoa(v, BIGNUM_DTOA_SHORTEST, 0, buffer, &length, &point);
211 5 : CHECK_EQ(0, strcmp("2225073858507201", buffer.start()));
212 5 : CHECK_EQ(-307, point);
213 :
214 5 : BignumDtoa(v, BIGNUM_DTOA_PRECISION, 20, buffer, &length, &point);
215 5 : CHECK_GE(20, length);
216 5 : TrimRepresentation(buffer);
217 5 : CHECK_EQ(0, strcmp("2225073858507200889", buffer.start()));
218 5 : CHECK_EQ(-307, point);
219 :
220 : BignumDtoa(4128420500802942e-24, BIGNUM_DTOA_SHORTEST, 0,
221 5 : buffer, &length, &point);
222 5 : CHECK_EQ(0, strcmp("4128420500802942", buffer.start()));
223 5 : CHECK_EQ(-8, point);
224 :
225 : v = 3.9292015898194142585311918e-10;
226 5 : BignumDtoa(v, BIGNUM_DTOA_SHORTEST, 0, buffer, &length, &point);
227 5 : CHECK_EQ(0, strcmp("39292015898194143", buffer.start()));
228 :
229 : v = 4194304.0;
230 5 : BignumDtoa(v, BIGNUM_DTOA_FIXED, 5, buffer, &length, &point);
231 5 : CHECK_GE(5, length - point);
232 5 : TrimRepresentation(buffer);
233 5 : CHECK_EQ(0, strcmp("4194304", buffer.start()));
234 :
235 : v = 3.3161339052167390562200598e-237;
236 5 : BignumDtoa(v, BIGNUM_DTOA_PRECISION, 19, buffer, &length, &point);
237 5 : CHECK_GE(19, length);
238 5 : TrimRepresentation(buffer);
239 5 : CHECK_EQ(0, strcmp("3316133905216739056", buffer.start()));
240 5 : CHECK_EQ(-236, point);
241 :
242 : v = 7.9885183916008099497815232e+191;
243 5 : BignumDtoa(v, BIGNUM_DTOA_PRECISION, 4, buffer, &length, &point);
244 5 : CHECK_GE(4, length);
245 5 : TrimRepresentation(buffer);
246 5 : CHECK_EQ(0, strcmp("7989", buffer.start()));
247 5 : CHECK_EQ(192, point);
248 :
249 : v = 1.0000000000000012800000000e+17;
250 5 : BignumDtoa(v, BIGNUM_DTOA_FIXED, 1, buffer, &length, &point);
251 5 : CHECK_GE(1, length - point);
252 5 : TrimRepresentation(buffer);
253 5 : CHECK_EQ(0, strcmp("100000000000000128", buffer.start()));
254 5 : CHECK_EQ(18, point);
255 5 : }
256 :
257 :
258 26644 : TEST(BignumDtoaGayShortest) {
259 : char buffer_container[kBufferSize];
260 : Vector<char> buffer(buffer_container, kBufferSize);
261 : int length;
262 : int point;
263 :
264 : Vector<const PrecomputedShortest> precomputed =
265 5 : PrecomputedShortestRepresentations();
266 1000005 : for (int i = 0; i < precomputed.length(); ++i) {
267 1000000 : const PrecomputedShortest current_test = precomputed[i];
268 : double v = current_test.v;
269 500000 : BignumDtoa(v, BIGNUM_DTOA_SHORTEST, 0, buffer, &length, &point);
270 500000 : CHECK_EQ(current_test.decimal_point, point);
271 500000 : CHECK_EQ(0, strcmp(current_test.representation, buffer.start()));
272 : }
273 5 : }
274 :
275 :
276 26644 : TEST(BignumDtoaGayFixed) {
277 : char buffer_container[kBufferSize];
278 : Vector<char> buffer(buffer_container, kBufferSize);
279 : int length;
280 : int point;
281 :
282 : Vector<const PrecomputedFixed> precomputed =
283 5 : PrecomputedFixedRepresentations();
284 1000005 : for (int i = 0; i < precomputed.length(); ++i) {
285 1000000 : const PrecomputedFixed current_test = precomputed[i];
286 : double v = current_test.v;
287 : int number_digits = current_test.number_digits;
288 500000 : BignumDtoa(v, BIGNUM_DTOA_FIXED, number_digits, buffer, &length, &point);
289 500000 : CHECK_EQ(current_test.decimal_point, point);
290 500000 : CHECK_GE(number_digits, length - point);
291 500000 : TrimRepresentation(buffer);
292 500000 : CHECK_EQ(0, strcmp(current_test.representation, buffer.start()));
293 : }
294 5 : }
295 :
296 :
297 26644 : TEST(BignumDtoaGayPrecision) {
298 : char buffer_container[kBufferSize];
299 : Vector<char> buffer(buffer_container, kBufferSize);
300 : int length;
301 : int point;
302 :
303 : Vector<const PrecomputedPrecision> precomputed =
304 5 : PrecomputedPrecisionRepresentations();
305 1000005 : for (int i = 0; i < precomputed.length(); ++i) {
306 1000000 : const PrecomputedPrecision current_test = precomputed[i];
307 : double v = current_test.v;
308 : int number_digits = current_test.number_digits;
309 : BignumDtoa(v, BIGNUM_DTOA_PRECISION, number_digits,
310 500000 : buffer, &length, &point);
311 500000 : CHECK_EQ(current_test.decimal_point, point);
312 500000 : CHECK_GE(number_digits, length);
313 500000 : TrimRepresentation(buffer);
314 500000 : CHECK_EQ(0, strcmp(current_test.representation, buffer.start()));
315 : }
316 5 : }
317 :
318 : } // namespace test_bignum_dtoa
319 : } // namespace internal
320 79917 : } // namespace v8
|