OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/conversions.h" | 5 #include "src/conversions.h" |
6 | 6 |
7 #include <limits.h> | 7 #include <limits.h> |
8 #include <stdarg.h> | 8 #include <stdarg.h> |
9 #include <cmath> | 9 #include <cmath> |
10 | 10 |
(...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
429 int fraction_cursor = integer_cursor; | 429 int fraction_cursor = integer_cursor; |
430 | 430 |
431 bool negative = value < 0; | 431 bool negative = value < 0; |
432 if (negative) value = -value; | 432 if (negative) value = -value; |
433 | 433 |
434 // Split the value into an integer part and a fractional part. | 434 // Split the value into an integer part and a fractional part. |
435 double integer = std::floor(value); | 435 double integer = std::floor(value); |
436 double fraction = value - integer; | 436 double fraction = value - integer; |
437 // We only compute fractional digits up to the input double's precision. | 437 // We only compute fractional digits up to the input double's precision. |
438 double delta = 0.5 * (Double(value).NextDouble() - value); | 438 double delta = 0.5 * (Double(value).NextDouble() - value); |
| 439 delta = std::max(Double(0.0).NextDouble(), delta); |
| 440 DCHECK_GT(delta, 0.0); |
439 if (fraction > delta) { | 441 if (fraction > delta) { |
440 // Insert decimal point. | 442 // Insert decimal point. |
441 buffer[fraction_cursor++] = '.'; | 443 buffer[fraction_cursor++] = '.'; |
442 do { | 444 do { |
443 // Shift up by one digit. | 445 // Shift up by one digit. |
444 fraction *= radix; | 446 fraction *= radix; |
445 delta *= radix; | 447 delta *= radix; |
446 // Write digit. | 448 // Write digit. |
447 int digit = static_cast<int>(fraction); | 449 int digit = static_cast<int>(fraction); |
448 buffer[fraction_cursor++] = chars[digit]; | 450 buffer[fraction_cursor++] = chars[digit]; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
481 } | 483 } |
482 do { | 484 do { |
483 double remainder = modulo(integer, radix); | 485 double remainder = modulo(integer, radix); |
484 buffer[--integer_cursor] = chars[static_cast<int>(remainder)]; | 486 buffer[--integer_cursor] = chars[static_cast<int>(remainder)]; |
485 integer = (integer - remainder) / radix; | 487 integer = (integer - remainder) / radix; |
486 } while (integer > 0); | 488 } while (integer > 0); |
487 | 489 |
488 // Add sign and terminate string. | 490 // Add sign and terminate string. |
489 if (negative) buffer[--integer_cursor] = '-'; | 491 if (negative) buffer[--integer_cursor] = '-'; |
490 buffer[fraction_cursor++] = '\0'; | 492 buffer[fraction_cursor++] = '\0'; |
| 493 DCHECK_LT(fraction_cursor, kBufferSize); |
| 494 DCHECK_LE(0, integer_cursor); |
491 // Allocate new string as return value. | 495 // Allocate new string as return value. |
492 char* result = NewArray<char>(fraction_cursor - integer_cursor); | 496 char* result = NewArray<char>(fraction_cursor - integer_cursor); |
493 memcpy(result, buffer + integer_cursor, fraction_cursor - integer_cursor); | 497 memcpy(result, buffer + integer_cursor, fraction_cursor - integer_cursor); |
494 return result; | 498 return result; |
495 } | 499 } |
496 | 500 |
497 | 501 |
498 // ES6 18.2.4 parseFloat(string) | 502 // ES6 18.2.4 parseFloat(string) |
499 double StringToDouble(UnicodeCache* unicode_cache, Handle<String> string, | 503 double StringToDouble(UnicodeCache* unicode_cache, Handle<String> string, |
500 int flags, double empty_string_val) { | 504 int flags, double empty_string_val) { |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
566 char reverse_buffer[kBufferSize + 1]; // Result will be /0 terminated. | 570 char reverse_buffer[kBufferSize + 1]; // Result will be /0 terminated. |
567 Vector<char> reverse_vector(reverse_buffer, arraysize(reverse_buffer)); | 571 Vector<char> reverse_vector(reverse_buffer, arraysize(reverse_buffer)); |
568 const char* reverse_string = DoubleToCString(d, reverse_vector); | 572 const char* reverse_string = DoubleToCString(d, reverse_vector); |
569 for (int i = 0; i < length; ++i) { | 573 for (int i = 0; i < length; ++i) { |
570 if (static_cast<uint16_t>(reverse_string[i]) != buffer[i]) return false; | 574 if (static_cast<uint16_t>(reverse_string[i]) != buffer[i]) return false; |
571 } | 575 } |
572 return true; | 576 return true; |
573 } | 577 } |
574 } // namespace internal | 578 } // namespace internal |
575 } // namespace v8 | 579 } // namespace v8 |
OLD | NEW |