1 // Copyright 2010 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
31 #include "cctest.h"
32 #include "double-conversion/fixed-dtoa.h"
33 #include "gay-fixed.h"
34 #include "double-conversion/ieee.h"
35 #include "double-conversion/utils.h"
36
37 using namespace double_conversion;
38
39 static const int kBufferSize = 500;
40
TEST(FastFixedVariousDoubles)41 TEST(FastFixedVariousDoubles) {
42 char buffer_container[kBufferSize];
43 Vector<char> buffer(buffer_container, kBufferSize);
44 int length;
45 int point;
46
47 CHECK(FastFixedDtoa(1.0, 1, buffer, &length, &point));
48 CHECK_EQ("1", buffer.start());
49 CHECK_EQ(1, point);
50
51 CHECK(FastFixedDtoa(1.0, 15, buffer, &length, &point));
52 CHECK_EQ("1", buffer.start());
53 CHECK_EQ(1, point);
54
55 CHECK(FastFixedDtoa(1.0, 0, buffer, &length, &point));
56 CHECK_EQ("1", buffer.start());
57 CHECK_EQ(1, point);
58
59 CHECK(FastFixedDtoa(0xFFFFFFFF, 5, buffer, &length, &point));
60 CHECK_EQ("4294967295", buffer.start());
61 CHECK_EQ(10, point);
62
63 CHECK(FastFixedDtoa(4294967296.0, 5, buffer, &length, &point));
64 CHECK_EQ("4294967296", buffer.start());
65 CHECK_EQ(10, point);
66
67 CHECK(FastFixedDtoa(1e21, 5, buffer, &length, &point));
68 CHECK_EQ("1", buffer.start());
69 // CHECK_EQ(22, point);
70 CHECK_EQ(22, point);
71
72 CHECK(FastFixedDtoa(999999999999999868928.00, 2, buffer, &length, &point));
73 CHECK_EQ("999999999999999868928", buffer.start());
74 CHECK_EQ(21, point);
75
76 CHECK(FastFixedDtoa(6.9999999999999989514240000e+21, 5, buffer,
77 &length, &point));
78 CHECK_EQ("6999999999999998951424", buffer.start());
79 CHECK_EQ(22, point);
80
81 CHECK(FastFixedDtoa(1.5, 5, buffer, &length, &point));
82 CHECK_EQ("15", buffer.start());
83 CHECK_EQ(1, point);
84
85 CHECK(FastFixedDtoa(1.55, 5, buffer, &length, &point));
86 CHECK_EQ("155", buffer.start());
87 CHECK_EQ(1, point);
88
89 CHECK(FastFixedDtoa(1.55, 1, buffer, &length, &point));
90 CHECK_EQ("16", buffer.start());
91 CHECK_EQ(1, point);
92
93 CHECK(FastFixedDtoa(1.00000001, 15, buffer, &length, &point));
94 CHECK_EQ("100000001", buffer.start());
95 CHECK_EQ(1, point);
96
97 CHECK(FastFixedDtoa(0.1, 10, buffer, &length, &point));
98 CHECK_EQ("1", buffer.start());
99 CHECK_EQ(0, point);
100
101 CHECK(FastFixedDtoa(0.01, 10, buffer, &length, &point));
102 CHECK_EQ("1", buffer.start());
103 CHECK_EQ(-1, point);
104
105 CHECK(FastFixedDtoa(0.001, 10, buffer, &length, &point));
106 CHECK_EQ("1", buffer.start());
107 CHECK_EQ(-2, point);
108
109 CHECK(FastFixedDtoa(0.0001, 10, buffer, &length, &point));
110 CHECK_EQ("1", buffer.start());
111 CHECK_EQ(-3, point);
112
113 CHECK(FastFixedDtoa(0.00001, 10, buffer, &length, &point));
114 CHECK_EQ("1", buffer.start());
115 CHECK_EQ(-4, point);
116
117 CHECK(FastFixedDtoa(0.000001, 10, buffer, &length, &point));
118 CHECK_EQ("1", buffer.start());
119 CHECK_EQ(-5, point);
120
121 CHECK(FastFixedDtoa(0.0000001, 10, buffer, &length, &point));
122 CHECK_EQ("1", buffer.start());
123 CHECK_EQ(-6, point);
124
125 CHECK(FastFixedDtoa(0.00000001, 10, buffer, &length, &point));
126 CHECK_EQ("1", buffer.start());
127 CHECK_EQ(-7, point);
128
129 CHECK(FastFixedDtoa(0.000000001, 10, buffer, &length, &point));
130 CHECK_EQ("1", buffer.start());
131 CHECK_EQ(-8, point);
132
133 CHECK(FastFixedDtoa(0.0000000001, 15, buffer, &length, &point));
134 CHECK_EQ("1", buffer.start());
135 CHECK_EQ(-9, point);
136
137 CHECK(FastFixedDtoa(0.00000000001, 15, buffer, &length, &point));
138 CHECK_EQ("1", buffer.start());
139 CHECK_EQ(-10, point);
140
141 CHECK(FastFixedDtoa(0.000000000001, 15, buffer, &length, &point));
142 CHECK_EQ("1", buffer.start());
143 CHECK_EQ(-11, point);
144
145 CHECK(FastFixedDtoa(0.0000000000001, 15, buffer, &length, &point));
146 CHECK_EQ("1", buffer.start());
147 CHECK_EQ(-12, point);
148
149 CHECK(FastFixedDtoa(0.00000000000001, 15, buffer, &length, &point));
150 CHECK_EQ("1", buffer.start());
151 CHECK_EQ(-13, point);
152
153 CHECK(FastFixedDtoa(0.000000000000001, 20, buffer, &length, &point));
154 CHECK_EQ("1", buffer.start());
155 CHECK_EQ(-14, point);
156
157 CHECK(FastFixedDtoa(0.0000000000000001, 20, buffer, &length, &point));
158 CHECK_EQ("1", buffer.start());
159 CHECK_EQ(-15, point);
160
161 CHECK(FastFixedDtoa(0.00000000000000001, 20, buffer, &length, &point));
162 CHECK_EQ("1", buffer.start());
163 CHECK_EQ(-16, point);
164
165 CHECK(FastFixedDtoa(0.000000000000000001, 20, buffer, &length, &point));
166 CHECK_EQ("1", buffer.start());
167 CHECK_EQ(-17, point);
168
169 CHECK(FastFixedDtoa(0.0000000000000000001, 20, buffer, &length, &point));
170 CHECK_EQ("1", buffer.start());
171 CHECK_EQ(-18, point);
172
173 CHECK(FastFixedDtoa(0.00000000000000000001, 20, buffer, &length, &point));
174 CHECK_EQ("1", buffer.start());
175 CHECK_EQ(-19, point);
176
177 CHECK(FastFixedDtoa(0.10000000004, 10, buffer, &length, &point));
178 CHECK_EQ("1", buffer.start());
179 CHECK_EQ(0, point);
180
181 CHECK(FastFixedDtoa(0.01000000004, 10, buffer, &length, &point));
182 CHECK_EQ("1", buffer.start());
183 CHECK_EQ(-1, point);
184
185 CHECK(FastFixedDtoa(0.00100000004, 10, buffer, &length, &point));
186 CHECK_EQ("1", buffer.start());
187 CHECK_EQ(-2, point);
188
189 CHECK(FastFixedDtoa(0.00010000004, 10, buffer, &length, &point));
190 CHECK_EQ("1", buffer.start());
191 CHECK_EQ(-3, point);
192
193 CHECK(FastFixedDtoa(0.00001000004, 10, buffer, &length, &point));
194 CHECK_EQ("1", buffer.start());
195 CHECK_EQ(-4, point);
196
197 CHECK(FastFixedDtoa(0.00000100004, 10, buffer, &length, &point));
198 CHECK_EQ("1", buffer.start());
199 CHECK_EQ(-5, point);
200
201 CHECK(FastFixedDtoa(0.00000010004, 10, buffer, &length, &point));
202 CHECK_EQ("1", buffer.start());
203 CHECK_EQ(-6, point);
204
205 CHECK(FastFixedDtoa(0.00000001004, 10, buffer, &length, &point));
206 CHECK_EQ("1", buffer.start());
207 CHECK_EQ(-7, point);
208
209 CHECK(FastFixedDtoa(0.00000000104, 10, buffer, &length, &point));
210 CHECK_EQ("1", buffer.start());
211 CHECK_EQ(-8, point);
212
213 CHECK(FastFixedDtoa(0.0000000001000004, 15, buffer, &length, &point));
214 CHECK_EQ("1", buffer.start());
215 CHECK_EQ(-9, point);
216
217 CHECK(FastFixedDtoa(0.0000000000100004, 15, buffer, &length, &point));
218 CHECK_EQ("1", buffer.start());
219 CHECK_EQ(-10, point);
220
221 CHECK(FastFixedDtoa(0.0000000000010004, 15, buffer, &length, &point));
222 CHECK_EQ("1", buffer.start());
223 CHECK_EQ(-11, point);
224
225 CHECK(FastFixedDtoa(0.0000000000001004, 15, buffer, &length, &point));
226 CHECK_EQ("1", buffer.start());
227 CHECK_EQ(-12, point);
228
229 CHECK(FastFixedDtoa(0.0000000000000104, 15, buffer, &length, &point));
230 CHECK_EQ("1", buffer.start());
231 CHECK_EQ(-13, point);
232
233 CHECK(FastFixedDtoa(0.000000000000001000004, 20, buffer, &length, &point));
234 CHECK_EQ("1", buffer.start());
235 CHECK_EQ(-14, point);
236
237 CHECK(FastFixedDtoa(0.000000000000000100004, 20, buffer, &length, &point));
238 CHECK_EQ("1", buffer.start());
239 CHECK_EQ(-15, point);
240
241 CHECK(FastFixedDtoa(0.000000000000000010004, 20, buffer, &length, &point));
242 CHECK_EQ("1", buffer.start());
243 CHECK_EQ(-16, point);
244
245 CHECK(FastFixedDtoa(0.000000000000000001004, 20, buffer, &length, &point));
246 CHECK_EQ("1", buffer.start());
247 CHECK_EQ(-17, point);
248
249 CHECK(FastFixedDtoa(0.000000000000000000104, 20, buffer, &length, &point));
250 CHECK_EQ("1", buffer.start());
251 CHECK_EQ(-18, point);
252
253 CHECK(FastFixedDtoa(0.000000000000000000014, 20, buffer, &length, &point));
254 CHECK_EQ("1", buffer.start());
255 CHECK_EQ(-19, point);
256
257 CHECK(FastFixedDtoa(0.10000000006, 10, buffer, &length, &point));
258 CHECK_EQ("1000000001", buffer.start());
259 CHECK_EQ(0, point);
260
261 CHECK(FastFixedDtoa(0.01000000006, 10, buffer, &length, &point));
262 CHECK_EQ("100000001", buffer.start());
263 CHECK_EQ(-1, point);
264
265 CHECK(FastFixedDtoa(0.00100000006, 10, buffer, &length, &point));
266 CHECK_EQ("10000001", buffer.start());
267 CHECK_EQ(-2, point);
268
269 CHECK(FastFixedDtoa(0.00010000006, 10, buffer, &length, &point));
270 CHECK_EQ("1000001", buffer.start());
271 CHECK_EQ(-3, point);
272
273 CHECK(FastFixedDtoa(0.00001000006, 10, buffer, &length, &point));
274 CHECK_EQ("100001", buffer.start());
275 CHECK_EQ(-4, point);
276
277 CHECK(FastFixedDtoa(0.00000100006, 10, buffer, &length, &point));
278 CHECK_EQ("10001", buffer.start());
279 CHECK_EQ(-5, point);
280
281 CHECK(FastFixedDtoa(0.00000010006, 10, buffer, &length, &point));
282 CHECK_EQ("1001", buffer.start());
283 CHECK_EQ(-6, point);
284
285 CHECK(FastFixedDtoa(0.00000001006, 10, buffer, &length, &point));
286 CHECK_EQ("101", buffer.start());
287 CHECK_EQ(-7, point);
288
289 CHECK(FastFixedDtoa(0.00000000106, 10, buffer, &length, &point));
290 CHECK_EQ("11", buffer.start());
291 CHECK_EQ(-8, point);
292
293 CHECK(FastFixedDtoa(0.0000000001000006, 15, buffer, &length, &point));
294 CHECK_EQ("100001", buffer.start());
295 CHECK_EQ(-9, point);
296
297 CHECK(FastFixedDtoa(0.0000000000100006, 15, buffer, &length, &point));
298 CHECK_EQ("10001", buffer.start());
299 CHECK_EQ(-10, point);
300
301 CHECK(FastFixedDtoa(0.0000000000010006, 15, buffer, &length, &point));
302 CHECK_EQ("1001", buffer.start());
303 CHECK_EQ(-11, point);
304
305 CHECK(FastFixedDtoa(0.0000000000001006, 15, buffer, &length, &point));
306 CHECK_EQ("101", buffer.start());
307 CHECK_EQ(-12, point);
308
309 CHECK(FastFixedDtoa(0.0000000000000106, 15, buffer, &length, &point));
310 CHECK_EQ("11", buffer.start());
311 CHECK_EQ(-13, point);
312
313 CHECK(FastFixedDtoa(0.000000000000001000006, 20, buffer, &length, &point));
314 CHECK_EQ("100001", buffer.start());
315 CHECK_EQ(-14, point);
316
317 CHECK(FastFixedDtoa(0.000000000000000100006, 20, buffer, &length, &point));
318 CHECK_EQ("10001", buffer.start());
319 CHECK_EQ(-15, point);
320
321 CHECK(FastFixedDtoa(0.000000000000000010006, 20, buffer, &length, &point));
322 CHECK_EQ("1001", buffer.start());
323 CHECK_EQ(-16, point);
324
325 CHECK(FastFixedDtoa(0.000000000000000001006, 20, buffer, &length, &point));
326 CHECK_EQ("101", buffer.start());
327 CHECK_EQ(-17, point);
328
329 CHECK(FastFixedDtoa(0.000000000000000000106, 20, buffer, &length, &point));
330 CHECK_EQ("11", buffer.start());
331 CHECK_EQ(-18, point);
332
333 CHECK(FastFixedDtoa(0.000000000000000000016, 20, buffer, &length, &point));
334 CHECK_EQ("2", buffer.start());
335 CHECK_EQ(-19, point);
336
337 CHECK(FastFixedDtoa(0.6, 0, buffer, &length, &point));
338 CHECK_EQ("1", buffer.start());
339 CHECK_EQ(1, point);
340
341 CHECK(FastFixedDtoa(0.96, 1, buffer, &length, &point));
342 CHECK_EQ("1", buffer.start());
343 CHECK_EQ(1, point);
344
345 CHECK(FastFixedDtoa(0.996, 2, buffer, &length, &point));
346 CHECK_EQ("1", buffer.start());
347 CHECK_EQ(1, point);
348
349 CHECK(FastFixedDtoa(0.9996, 3, buffer, &length, &point));
350 CHECK_EQ("1", buffer.start());
351 CHECK_EQ(1, point);
352
353 CHECK(FastFixedDtoa(0.99996, 4, buffer, &length, &point));
354 CHECK_EQ("1", buffer.start());
355 CHECK_EQ(1, point);
356
357 CHECK(FastFixedDtoa(0.999996, 5, buffer, &length, &point));
358 CHECK_EQ("1", buffer.start());
359 CHECK_EQ(1, point);
360
361 CHECK(FastFixedDtoa(0.9999996, 6, buffer, &length, &point));
362 CHECK_EQ("1", buffer.start());
363 CHECK_EQ(1, point);
364
365 CHECK(FastFixedDtoa(0.99999996, 7, buffer, &length, &point));
366 CHECK_EQ("1", buffer.start());
367 CHECK_EQ(1, point);
368
369 CHECK(FastFixedDtoa(0.999999996, 8, buffer, &length, &point));
370 CHECK_EQ("1", buffer.start());
371 CHECK_EQ(1, point);
372
373 CHECK(FastFixedDtoa(0.9999999996, 9, buffer, &length, &point));
374 CHECK_EQ("1", buffer.start());
375 CHECK_EQ(1, point);
376
377 CHECK(FastFixedDtoa(0.99999999996, 10, buffer, &length, &point));
378 CHECK_EQ("1", buffer.start());
379 CHECK_EQ(1, point);
380
381 CHECK(FastFixedDtoa(0.999999999996, 11, buffer, &length, &point));
382 CHECK_EQ("1", buffer.start());
383 CHECK_EQ(1, point);
384
385 CHECK(FastFixedDtoa(0.9999999999996, 12, buffer, &length, &point));
386 CHECK_EQ("1", buffer.start());
387 CHECK_EQ(1, point);
388
389 CHECK(FastFixedDtoa(0.99999999999996, 13, buffer, &length, &point));
390 CHECK_EQ("1", buffer.start());
391 CHECK_EQ(1, point);
392
393 CHECK(FastFixedDtoa(0.999999999999996, 14, buffer, &length, &point));
394 CHECK_EQ("1", buffer.start());
395 CHECK_EQ(1, point);
396
397 CHECK(FastFixedDtoa(0.9999999999999996, 15, buffer, &length, &point));
398 CHECK_EQ("1", buffer.start());
399 CHECK_EQ(1, point);
400
401 CHECK(FastFixedDtoa(0.00999999999999996, 16, buffer, &length, &point));
402 CHECK_EQ("1", buffer.start());
403 CHECK_EQ(-1, point);
404
405 CHECK(FastFixedDtoa(0.000999999999999996, 17, buffer, &length, &point));
406 CHECK_EQ("1", buffer.start());
407 CHECK_EQ(-2, point);
408
409 CHECK(FastFixedDtoa(0.0000999999999999996, 18, buffer, &length, &point));
410 CHECK_EQ("1", buffer.start());
411 CHECK_EQ(-3, point);
412
413 CHECK(FastFixedDtoa(0.00000999999999999996, 19, buffer, &length, &point));
414 CHECK_EQ("1", buffer.start());
415 CHECK_EQ(-4, point);
416
417 CHECK(FastFixedDtoa(0.000000999999999999996, 20, buffer, &length, &point));
418 CHECK_EQ("1", buffer.start());
419 CHECK_EQ(-5, point);
420
421 CHECK(FastFixedDtoa(323423.234234, 10, buffer, &length, &point));
422 CHECK_EQ("323423234234", buffer.start());
423 CHECK_EQ(6, point);
424
425 CHECK(FastFixedDtoa(12345678.901234, 4, buffer, &length, &point));
426 CHECK_EQ("123456789012", buffer.start());
427 CHECK_EQ(8, point);
428
429 CHECK(FastFixedDtoa(98765.432109, 5, buffer, &length, &point));
430 CHECK_EQ("9876543211", buffer.start());
431 CHECK_EQ(5, point);
432
433 CHECK(FastFixedDtoa(42, 20, buffer, &length, &point));
434 CHECK_EQ("42", buffer.start());
435 CHECK_EQ(2, point);
436
437 CHECK(FastFixedDtoa(0.5, 0, buffer, &length, &point));
438 CHECK_EQ("1", buffer.start());
439 CHECK_EQ(1, point);
440
441 CHECK(FastFixedDtoa(1e-23, 10, buffer, &length, &point));
442 CHECK_EQ("", buffer.start());
443 CHECK_EQ(-10, point);
444
445 CHECK(FastFixedDtoa(1e-123, 2, buffer, &length, &point));
446 CHECK_EQ("", buffer.start());
447 CHECK_EQ(-2, point);
448
449 CHECK(FastFixedDtoa(1e-123, 0, buffer, &length, &point));
450 CHECK_EQ("", buffer.start());
451 CHECK_EQ(0, point);
452
453 CHECK(FastFixedDtoa(1e-23, 20, buffer, &length, &point));
454 CHECK_EQ("", buffer.start());
455 CHECK_EQ(-20, point);
456
457 CHECK(FastFixedDtoa(1e-21, 20, buffer, &length, &point));
458 CHECK_EQ("", buffer.start());
459 CHECK_EQ(-20, point);
460
461 CHECK(FastFixedDtoa(1e-22, 20, buffer, &length, &point));
462 CHECK_EQ("", buffer.start());
463 CHECK_EQ(-20, point);
464
465 CHECK(FastFixedDtoa(6e-21, 20, buffer, &length, &point));
466 CHECK_EQ("1", buffer.start());
467 CHECK_EQ(-19, point);
468
469 CHECK(FastFixedDtoa(9.1193616301674545152000000e+19, 0,
470 buffer, &length, &point));
471 CHECK_EQ("91193616301674545152", buffer.start());
472 CHECK_EQ(20, point);
473
474 CHECK(FastFixedDtoa(4.8184662102767651659096515e-04, 19,
475 buffer, &length, &point));
476 CHECK_EQ("4818466210276765", buffer.start());
477 CHECK_EQ(-3, point);
478
479 CHECK(FastFixedDtoa(1.9023164229540652612705182e-23, 8,
480 buffer, &length, &point));
481 CHECK_EQ("", buffer.start());
482 CHECK_EQ(-8, point);
483
484 CHECK(FastFixedDtoa(1000000000000000128.0, 0,
485 buffer, &length, &point));
486 CHECK_EQ("1000000000000000128", buffer.start());
487 CHECK_EQ(19, point);
488
489 CHECK(FastFixedDtoa(2.10861548515811875e+15, 17, buffer, &length, &point));
490 CHECK_EQ("210861548515811875", buffer.start());
491 CHECK_EQ(16, point);
492 }
493
494
TEST(FastFixedDtoaGayFixed)495 TEST(FastFixedDtoaGayFixed) {
496 char buffer_container[kBufferSize];
497 Vector<char> buffer(buffer_container, kBufferSize);
498 bool status;
499 int length;
500 int point;
501
502 Vector<const PrecomputedFixed> precomputed =
503 PrecomputedFixedRepresentations();
504 for (int i = 0; i < precomputed.length(); ++i) {
505 const PrecomputedFixed current_test = precomputed[i];
506 double v = current_test.v;
507 int number_digits = current_test.number_digits;
508 status = FastFixedDtoa(v, number_digits,
509 buffer, &length, &point);
510 CHECK(status);
511 CHECK_EQ(current_test.decimal_point, point);
512 CHECK(number_digits >= length - point);
513 CHECK_EQ(current_test.representation, buffer.start());
514 }
515 }
516