OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
54 // Input: * buffer containing the digits of too_high / 10^kappa | 54 // Input: * buffer containing the digits of too_high / 10^kappa |
55 // * the buffer's length | 55 // * the buffer's length |
56 // * distance_too_high_w == (too_high - w).f() * unit | 56 // * distance_too_high_w == (too_high - w).f() * unit |
57 // * unsafe_interval == (too_high - too_low).f() * unit | 57 // * unsafe_interval == (too_high - too_low).f() * unit |
58 // * rest = (too_high - buffer * 10^kappa).f() * unit | 58 // * rest = (too_high - buffer * 10^kappa).f() * unit |
59 // * ten_kappa = 10^kappa * unit | 59 // * ten_kappa = 10^kappa * unit |
60 // * unit = the common multiplier | 60 // * unit = the common multiplier |
61 // Output: returns true if the buffer is guaranteed to contain the closest | 61 // Output: returns true if the buffer is guaranteed to contain the closest |
62 // representable number to the input. | 62 // representable number to the input. |
63 // Modifies the generated digits in the buffer to approach (round towards) w. | 63 // Modifies the generated digits in the buffer to approach (round towards) w. |
64 bool RoundWeed(char* buffer, | 64 bool RoundWeed(Vector<char> buffer, |
65 int length, | 65 int length, |
66 uint64_t distance_too_high_w, | 66 uint64_t distance_too_high_w, |
67 uint64_t unsafe_interval, | 67 uint64_t unsafe_interval, |
68 uint64_t rest, | 68 uint64_t rest, |
69 uint64_t ten_kappa, | 69 uint64_t ten_kappa, |
70 uint64_t unit) { | 70 uint64_t unit) { |
71 uint64_t small_distance = distance_too_high_w - unit; | 71 uint64_t small_distance = distance_too_high_w - unit; |
72 uint64_t big_distance = distance_too_high_w + unit; | 72 uint64_t big_distance = distance_too_high_w + unit; |
73 // Let w_low = too_high - big_distance, and | 73 // Let w_low = too_high - big_distance, and |
74 // w_high = too_high - small_distance. | 74 // w_high = too_high - small_distance. |
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
317 // get each digit. Example the first digit after the comma would be computed by | 317 // get each digit. Example the first digit after the comma would be computed by |
318 // (0x567890abcdef * 10) >> 48. -> 3 | 318 // (0x567890abcdef * 10) >> 48. -> 3 |
319 // The whole thing becomes slightly more complicated because we want to stop | 319 // The whole thing becomes slightly more complicated because we want to stop |
320 // once we have enough digits. That is, once the digits inside the buffer | 320 // once we have enough digits. That is, once the digits inside the buffer |
321 // represent 'w' we can stop. Everything inside the interval low - high | 321 // represent 'w' we can stop. Everything inside the interval low - high |
322 // represents w. However we have to pay attention to low, high and w's | 322 // represents w. However we have to pay attention to low, high and w's |
323 // imprecision. | 323 // imprecision. |
324 bool DigitGen(DiyFp low, | 324 bool DigitGen(DiyFp low, |
325 DiyFp w, | 325 DiyFp w, |
326 DiyFp high, | 326 DiyFp high, |
327 char* buffer, | 327 Vector<char> buffer, |
328 int* length, | 328 int* length, |
329 int* kappa) { | 329 int* kappa) { |
330 ASSERT(low.e() == w.e() && w.e() == high.e()); | 330 ASSERT(low.e() == w.e() && w.e() == high.e()); |
331 ASSERT(low.f() + 1 <= high.f() - 1); | 331 ASSERT(low.f() + 1 <= high.f() - 1); |
332 ASSERT(minimal_target_exponent <= w.e() && w.e() <= maximal_target_exponent); | 332 ASSERT(minimal_target_exponent <= w.e() && w.e() <= maximal_target_exponent); |
333 // low, w and high are imprecise, but by less than one ulp (unit in the last | 333 // low, w and high are imprecise, but by less than one ulp (unit in the last |
334 // place). | 334 // place). |
335 // If we remove (resp. add) 1 ulp from low (resp. high) we are certain that | 335 // If we remove (resp. add) 1 ulp from low (resp. high) we are certain that |
336 // the new numbers are outside of the interval we want the final | 336 // the new numbers are outside of the interval we want the final |
337 // representation to lie in. | 337 // representation to lie in. |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
430 // Returns true if it succeeds, otherwise the result cannot be trusted. | 430 // Returns true if it succeeds, otherwise the result cannot be trusted. |
431 // There will be *length digits inside the buffer (not null-terminated). | 431 // There will be *length digits inside the buffer (not null-terminated). |
432 // If the function returns true then | 432 // If the function returns true then |
433 // v == (double) (buffer * 10^decimal_exponent). | 433 // v == (double) (buffer * 10^decimal_exponent). |
434 // The digits in the buffer are the shortest representation possible: no | 434 // The digits in the buffer are the shortest representation possible: no |
435 // 0.09999999999999999 instead of 0.1. The shorter representation will even be | 435 // 0.09999999999999999 instead of 0.1. The shorter representation will even be |
436 // chosen even if the longer one would be closer to v. | 436 // chosen even if the longer one would be closer to v. |
437 // The last digit will be closest to the actual v. That is, even if several | 437 // The last digit will be closest to the actual v. That is, even if several |
438 // digits might correctly yield 'v' when read again, the closest will be | 438 // digits might correctly yield 'v' when read again, the closest will be |
439 // computed. | 439 // computed. |
440 bool grisu3(double v, char* buffer, int* length, int* decimal_exponent) { | 440 bool grisu3(double v, Vector<char> buffer, int* length, int* decimal_exponent) { |
441 DiyFp w = Double(v).AsNormalizedDiyFp(); | 441 DiyFp w = Double(v).AsNormalizedDiyFp(); |
442 // boundary_minus and boundary_plus are the boundaries between v and its | 442 // boundary_minus and boundary_plus are the boundaries between v and its |
443 // closest floating-point neighbors. Any number strictly between | 443 // closest floating-point neighbors. Any number strictly between |
444 // boundary_minus and boundary_plus will round to v when convert to a double. | 444 // boundary_minus and boundary_plus will round to v when convert to a double. |
445 // Grisu3 will never output representations that lie exactly on a boundary. | 445 // Grisu3 will never output representations that lie exactly on a boundary. |
446 DiyFp boundary_minus, boundary_plus; | 446 DiyFp boundary_minus, boundary_plus; |
447 Double(v).NormalizedBoundaries(&boundary_minus, &boundary_plus); | 447 Double(v).NormalizedBoundaries(&boundary_minus, &boundary_plus); |
448 ASSERT(boundary_plus.e() == w.e()); | 448 ASSERT(boundary_plus.e() == w.e()); |
449 DiyFp ten_mk; // Cached power of ten: 10^-k | 449 DiyFp ten_mk; // Cached power of ten: 10^-k |
450 int mk; // -k | 450 int mk; // -k |
(...skipping 30 matching lines...) Expand all Loading... |
481 // the buffer will be filled with "123" und the decimal_exponent will be | 481 // the buffer will be filled with "123" und the decimal_exponent will be |
482 // decreased by 2. | 482 // decreased by 2. |
483 int kappa; | 483 int kappa; |
484 bool result = DigitGen(scaled_boundary_minus, scaled_w, scaled_boundary_plus, | 484 bool result = DigitGen(scaled_boundary_minus, scaled_w, scaled_boundary_plus, |
485 buffer, length, &kappa); | 485 buffer, length, &kappa); |
486 *decimal_exponent = -mk + kappa; | 486 *decimal_exponent = -mk + kappa; |
487 return result; | 487 return result; |
488 } | 488 } |
489 | 489 |
490 | 490 |
491 bool FastDtoa(double v, char* buffer, int* sign, int* length, int* point) { | 491 bool FastDtoa(double v, |
| 492 Vector<char> buffer, |
| 493 int* sign, |
| 494 int* length, |
| 495 int* point) { |
492 ASSERT(v != 0); | 496 ASSERT(v != 0); |
493 ASSERT(!Double(v).IsSpecial()); | 497 ASSERT(!Double(v).IsSpecial()); |
494 | 498 |
495 if (v < 0) { | 499 if (v < 0) { |
496 v = -v; | 500 v = -v; |
497 *sign = 1; | 501 *sign = 1; |
498 } else { | 502 } else { |
499 *sign = 0; | 503 *sign = 0; |
500 } | 504 } |
501 int decimal_exponent; | 505 int decimal_exponent; |
502 bool result = grisu3(v, buffer, length, &decimal_exponent); | 506 bool result = grisu3(v, buffer, length, &decimal_exponent); |
503 *point = *length + decimal_exponent; | 507 *point = *length + decimal_exponent; |
504 buffer[*length] = '\0'; | 508 buffer[*length] = '\0'; |
505 return result; | 509 return result; |
506 } | 510 } |
507 | 511 |
508 } } // namespace v8::internal | 512 } } // namespace v8::internal |
OLD | NEW |