15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Copyright 2010 the V8 project authors. All rights reserved.
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Redistribution and use in source and binary forms, with or without
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// modification, are permitted provided that the following conditions are
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// met:
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//     * Redistributions of source code must retain the above copyright
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//       notice, this list of conditions and the following disclaimer.
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//     * Redistributions in binary form must reproduce the above
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//       copyright notice, this list of conditions and the following
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//       disclaimer in the documentation and/or other materials provided
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//       with the distribution.
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//     * Neither the name of Google Inc. nor the names of its
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//       contributors may be used to endorse or promote products derived
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//       from this software without specific prior written permission.
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h"
295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include <limits.h>
315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include <math.h>
325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "double-conversion.h"
345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "bignum-dtoa.h"
365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "double.h"
375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "fast-dtoa.h"
385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "fixed-dtoa.h"
395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "strtod.h"
405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "utils.h"
415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace WTF {
435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace double_conversion {
45fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const DoubleToStringConverter& DoubleToStringConverter::EcmaScriptConverter() {
475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        int flags = UNIQUE_ZERO | EMIT_POSITIVE_EXPONENT_SIGN;
485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        static DoubleToStringConverter converter(flags,
495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                                 "Infinity",
505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                                 "NaN",
515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                                 'e',
525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                                 -6, 21,
535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                                 6, 0);
545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return converter;
555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
56fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
57fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool DoubleToStringConverter::HandleSpecialValues(
595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                                      double value,
605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                                      StringBuilder* result_builder) const {
615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        Double double_inspect(value);
625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (double_inspect.IsInfinite()) {
635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (infinity_symbol_ == NULL) return false;
645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (value < 0) {
655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                result_builder->AddCharacter('-');
665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            result_builder->AddString(infinity_symbol_);
685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return true;
695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (double_inspect.IsNan()) {
715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (nan_symbol_ == NULL) return false;
725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            result_builder->AddString(nan_symbol_);
735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return true;
745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
77fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
78fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void DoubleToStringConverter::CreateExponentialRepresentation(
805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                                                  const char* decimal_digits,
815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                                                  int length,
825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                                                  int exponent,
835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                                                  StringBuilder* result_builder) const {
845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT(length != 0);
855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        result_builder->AddCharacter(decimal_digits[0]);
865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (length != 1) {
875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            result_builder->AddCharacter('.');
885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            result_builder->AddSubstring(&decimal_digits[1], length-1);
895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        result_builder->AddCharacter(exponent_character_);
915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (exponent < 0) {
925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            result_builder->AddCharacter('-');
935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            exponent = -exponent;
945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        } else {
955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if ((flags_ & EMIT_POSITIVE_EXPONENT_SIGN) != 0) {
965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                result_builder->AddCharacter('+');
975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (exponent == 0) {
1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            result_builder->AddCharacter('0');
1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return;
1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT(exponent < 1e4);
1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        const int kMaxExponentLength = 5;
1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        char buffer[kMaxExponentLength + 1];
1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        int first_char_pos = kMaxExponentLength;
1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        buffer[first_char_pos] = '\0';
1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        while (exponent > 0) {
1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            buffer[--first_char_pos] = '0' + (exponent % 10);
1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            exponent /= 10;
1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        result_builder->AddSubstring(&buffer[first_char_pos],
1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                     kMaxExponentLength - first_char_pos);
1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
115fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
116fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void DoubleToStringConverter::CreateDecimalRepresentation(
1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                                              const char* decimal_digits,
1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                                              int length,
1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                                              int decimal_point,
1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                                              int digits_after_point,
1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                                              StringBuilder* result_builder) const {
1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Create a representation that is padded with zeros if needed.
1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (decimal_point <= 0) {
1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // "0.00000decimal_rep".
1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            result_builder->AddCharacter('0');
1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (digits_after_point > 0) {
1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                result_builder->AddCharacter('.');
1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                result_builder->AddPadding('0', -decimal_point);
1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                ASSERT(length <= digits_after_point - (-decimal_point));
1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                result_builder->AddSubstring(decimal_digits, length);
1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                int remaining_digits = digits_after_point - (-decimal_point) - length;
1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                result_builder->AddPadding('0', remaining_digits);
1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        } else if (decimal_point >= length) {
1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // "decimal_rep0000.00000" or "decimal_rep.0000"
1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            result_builder->AddSubstring(decimal_digits, length);
1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            result_builder->AddPadding('0', decimal_point - length);
1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (digits_after_point > 0) {
1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                result_builder->AddCharacter('.');
1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                result_builder->AddPadding('0', digits_after_point);
1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        } else {
1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // "decima.l_rep000"
1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ASSERT(digits_after_point > 0);
1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            result_builder->AddSubstring(decimal_digits, decimal_point);
1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            result_builder->AddCharacter('.');
1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ASSERT(length - decimal_point <= digits_after_point);
1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            result_builder->AddSubstring(&decimal_digits[decimal_point],
1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                         length - decimal_point);
1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            int remaining_digits = digits_after_point - (length - decimal_point);
1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            result_builder->AddPadding('0', remaining_digits);
1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (digits_after_point == 0) {
1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if ((flags_ & EMIT_TRAILING_DECIMAL_POINT) != 0) {
1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                result_builder->AddCharacter('.');
1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if ((flags_ & EMIT_TRAILING_ZERO_AFTER_POINT) != 0) {
1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                result_builder->AddCharacter('0');
1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
163fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
164fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool DoubleToStringConverter::ToShortest(double value,
1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                             StringBuilder* result_builder) const {
1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (Double(value).IsSpecial()) {
1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return HandleSpecialValues(value, result_builder);
1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
170fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        int decimal_point;
1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        bool sign;
1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        const int kDecimalRepCapacity = kBase10MaximalLength + 1;
1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        char decimal_rep[kDecimalRepCapacity];
1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        int decimal_rep_length;
176fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        DoubleToAscii(value, SHORTEST, 0, decimal_rep, kDecimalRepCapacity,
1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                      &sign, &decimal_rep_length, &decimal_point);
179fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        bool unique_zero = (flags_ & UNIQUE_ZERO) != 0;
1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (sign && (value != 0.0 || !unique_zero)) {
1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            result_builder->AddCharacter('-');
1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
184fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        int exponent = decimal_point - 1;
1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if ((decimal_in_shortest_low_ <= exponent) &&
1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            (exponent < decimal_in_shortest_high_)) {
1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            CreateDecimalRepresentation(decimal_rep, decimal_rep_length,
1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                        decimal_point,
1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                        Max(0, decimal_rep_length - decimal_point),
1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                        result_builder);
1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        } else {
1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            CreateExponentialRepresentation(decimal_rep, decimal_rep_length, exponent,
1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                            result_builder);
1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return true;
1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
198fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
199fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool DoubleToStringConverter::ToFixed(double value,
2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                          int requested_digits,
2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                          StringBuilder* result_builder) const {
2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT(kMaxFixedDigitsBeforePoint == 60);
2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        const double kFirstNonFixed = 1e60;
205fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (Double(value).IsSpecial()) {
2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return HandleSpecialValues(value, result_builder);
2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
209fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (requested_digits > kMaxFixedDigitsAfterPoint) return false;
2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (value >= kFirstNonFixed || value <= -kFirstNonFixed) return false;
212fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Find a sufficiently precise decimal representation of n.
2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        int decimal_point;
2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        bool sign;
2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Add space for the '\0' byte.
2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        const int kDecimalRepCapacity =
2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        kMaxFixedDigitsBeforePoint + kMaxFixedDigitsAfterPoint + 1;
2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        char decimal_rep[kDecimalRepCapacity];
2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        int decimal_rep_length;
2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        DoubleToAscii(value, FIXED, requested_digits,
2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                      decimal_rep, kDecimalRepCapacity,
2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                      &sign, &decimal_rep_length, &decimal_point);
224fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0);
2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (sign && (value != 0.0 || !unique_zero)) {
2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            result_builder->AddCharacter('-');
2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
229fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        CreateDecimalRepresentation(decimal_rep, decimal_rep_length, decimal_point,
2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                    requested_digits, result_builder);
2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return true;
2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
234fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
235fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool DoubleToStringConverter::ToExponential(
2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                                double value,
2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                                int requested_digits,
2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                                StringBuilder* result_builder) const {
2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (Double(value).IsSpecial()) {
2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return HandleSpecialValues(value, result_builder);
2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
243fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
2445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (requested_digits < -1) return false;
2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (requested_digits > kMaxExponentialDigits) return false;
246fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        int decimal_point;
2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        bool sign;
2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Add space for digit before the decimal point and the '\0' character.
2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        const int kDecimalRepCapacity = kMaxExponentialDigits + 2;
2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT(kDecimalRepCapacity > kBase10MaximalLength);
2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        char decimal_rep[kDecimalRepCapacity];
2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        int decimal_rep_length;
254fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (requested_digits == -1) {
2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            DoubleToAscii(value, SHORTEST, 0,
2575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                          decimal_rep, kDecimalRepCapacity,
2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                          &sign, &decimal_rep_length, &decimal_point);
2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        } else {
2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            DoubleToAscii(value, PRECISION, requested_digits + 1,
2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                          decimal_rep, kDecimalRepCapacity,
2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                          &sign, &decimal_rep_length, &decimal_point);
2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ASSERT(decimal_rep_length <= requested_digits + 1);
264fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            for (int i = decimal_rep_length; i < requested_digits + 1; ++i) {
2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                decimal_rep[i] = '0';
2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            decimal_rep_length = requested_digits + 1;
2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
270fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0);
2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (sign && (value != 0.0 || !unique_zero)) {
2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            result_builder->AddCharacter('-');
2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
275fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        int exponent = decimal_point - 1;
2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        CreateExponentialRepresentation(decimal_rep,
2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                        decimal_rep_length,
2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                        exponent,
2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                        result_builder);
2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return true;
2825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
283fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
284fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool DoubleToStringConverter::ToPrecision(double value,
2865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                              int precision,
2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                              StringBuilder* result_builder) const {
2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (Double(value).IsSpecial()) {
2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return HandleSpecialValues(value, result_builder);
2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
291fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
2925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (precision < kMinPrecisionDigits || precision > kMaxPrecisionDigits) {
2935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return false;
2945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
295fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Find a sufficiently precise decimal representation of n.
2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        int decimal_point;
2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        bool sign;
2995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Add one for the terminating null character.
3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        const int kDecimalRepCapacity = kMaxPrecisionDigits + 1;
3015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        char decimal_rep[kDecimalRepCapacity];
3025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        int decimal_rep_length;
303fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
3045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        DoubleToAscii(value, PRECISION, precision,
3055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                      decimal_rep, kDecimalRepCapacity,
3065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                      &sign, &decimal_rep_length, &decimal_point);
3075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT(decimal_rep_length <= precision);
308fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
3095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0);
3105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (sign && (value != 0.0 || !unique_zero)) {
3115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            result_builder->AddCharacter('-');
3125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
313fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
3145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // The exponent if we print the number as x.xxeyyy. That is with the
3155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // decimal point after the first digit.
3165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        int exponent = decimal_point - 1;
317fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
3185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        int extra_zero = ((flags_ & EMIT_TRAILING_ZERO_AFTER_POINT) != 0) ? 1 : 0;
3195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if ((-decimal_point + 1 > max_leading_padding_zeroes_in_precision_mode_) ||
3205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            (decimal_point - precision + extra_zero >
3215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)             max_trailing_padding_zeroes_in_precision_mode_)) {
3225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                // Fill buffer to contain 'precision' digits.
3235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                // Usually the buffer is already at the correct length, but 'DoubleToAscii'
3245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                // is allowed to return less characters.
3255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                for (int i = decimal_rep_length; i < precision; ++i) {
3265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    decimal_rep[i] = '0';
3275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
328fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
3295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                CreateExponentialRepresentation(decimal_rep,
3305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                                precision,
3315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                                exponent,
3325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                                result_builder);
3335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            } else {
3345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                CreateDecimalRepresentation(decimal_rep, decimal_rep_length, decimal_point,
3355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                            Max(0, precision - decimal_point),
3365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                            result_builder);
3375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
3385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return true;
3395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
340fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
341fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
3425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    static BignumDtoaMode DtoaToBignumDtoaMode(
3435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                               DoubleToStringConverter::DtoaMode dtoa_mode) {
3445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        switch (dtoa_mode) {
3455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            case DoubleToStringConverter::SHORTEST:  return BIGNUM_DTOA_SHORTEST;
3465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            case DoubleToStringConverter::FIXED:     return BIGNUM_DTOA_FIXED;
3475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            case DoubleToStringConverter::PRECISION: return BIGNUM_DTOA_PRECISION;
3485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            default:
3495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                UNREACHABLE();
3505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                return BIGNUM_DTOA_SHORTEST;  // To silence compiler.
3515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
3525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
353fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
354fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
3555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void DoubleToStringConverter::DoubleToAscii(double v,
3565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                                DtoaMode mode,
3575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                                int requested_digits,
3585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                                char* buffer,
3595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                                int buffer_length,
3605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                                bool* sign,
3615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                                int* length,
3625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                                int* point) {
3635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        Vector<char> vector(buffer, buffer_length);
3645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT(!Double(v).IsSpecial());
3655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT(mode == SHORTEST || requested_digits >= 0);
366fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
3675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (Double(v).Sign() < 0) {
3685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            *sign = true;
3695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            v = -v;
3705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        } else {
3715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            *sign = false;
3725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
373fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
3745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (mode == PRECISION && requested_digits == 0) {
3755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            vector[0] = '\0';
3765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            *length = 0;
3775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return;
3785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
379fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
3805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (v == 0) {
3815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            vector[0] = '0';
3825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            vector[1] = '\0';
3835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            *length = 1;
3845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            *point = 1;
3855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return;
3865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
387fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
3885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        bool fast_worked;
3895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        switch (mode) {
3905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            case SHORTEST:
3915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                fast_worked = FastDtoa(v, FAST_DTOA_SHORTEST, 0, vector, length, point);
3925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                break;
3935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            case FIXED:
3945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                fast_worked = FastFixedDtoa(v, requested_digits, vector, length, point);
3955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                break;
3965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            case PRECISION:
3975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                fast_worked = FastDtoa(v, FAST_DTOA_PRECISION, requested_digits,
3985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                       vector, length, point);
3995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                break;
4005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            default:
4015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                UNREACHABLE();
4025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                fast_worked = false;
4035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
4045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (fast_worked) return;
405fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
4065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // If the fast dtoa didn't succeed use the slower bignum version.
4075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        BignumDtoaMode bignum_mode = DtoaToBignumDtoaMode(mode);
4085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        BignumDtoa(v, bignum_mode, requested_digits, vector, length, point);
4095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        vector[*length] = '\0';
4105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
411fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
412fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
4135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Maximum number of significant digits in decimal representation.
4145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // The longest possible double in decimal representation is
4155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // (2^53 - 1) * 2 ^ -1074 that is (2 ^ 53 - 1) * 5 ^ 1074 / 10 ^ 1074
4165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // (768 digits). If we parse a number whose first digits are equal to a
4175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // mean of 2 adjacent doubles (that could have up to 769 digits) the result
4185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // must be rounded to the bigger one unless the tail consists of zeros, so
4195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // we don't need to preserve all the digits.
4205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const int kMaxSignificantDigits = 772;
421fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
422fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
4235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    static double SignedZero(bool sign) {
4245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return sign ? -0.0 : 0.0;
4255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
426fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
427fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
4285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    double StringToDoubleConverter::StringToDouble(
4295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                                   const char* input,
4305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                                   size_t length,
4315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                                   size_t* processed_characters_count) {
4325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        const char* current = input;
4335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        const char* end = input + length;
434fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
4355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        *processed_characters_count = 0;
436fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
4375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // To make sure that iterator dereferencing is valid the following
4385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // convention is used:
4395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // 1. Each '++current' statement is followed by check for equality to 'end'.
4405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // 3. If 'current' becomes equal to 'end' the function returns or goes to
4415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // 'parsing_done'.
4425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // 4. 'current' is not dereferenced after the 'parsing_done' label.
4435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // 5. Code before 'parsing_done' may rely on 'current != end'.
4445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (current == end) return 0.0;
445fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
4465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // The longest form of simplified number is: "-<significant digits>.1eXXX\0".
4475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        const int kBufferSize = kMaxSignificantDigits + 10;
4485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        char buffer[kBufferSize];  // NOLINT: size is known at compile time.
4495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        int buffer_pos = 0;
450fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
4515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Exponent will be adjusted if insignificant digits of the integer part
4525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // or insignificant leading zeros of the fractional part are dropped.
4535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        int exponent = 0;
4545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        int significant_digits = 0;
4555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        int insignificant_digits = 0;
4565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        bool nonzero_digit_dropped = false;
4575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        bool sign = false;
458fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
4595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (*current == '+' || *current == '-') {
4605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            sign = (*current == '-');
4615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ++current;
4625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (current == end) return 0.0;
4635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
464fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
4655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        bool leading_zero = false;
4665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (*current == '0') {
4675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ++current;
4685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (current == end) {
4695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                *processed_characters_count = current - input;
4705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                return SignedZero(sign);
4715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
472fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
4735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            leading_zero = true;
474fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
4755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // Ignore leading zeros in the integer part.
4765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            while (*current == '0') {
4775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                ++current;
4785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (current == end) {
4795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    *processed_characters_count = current - input;
4805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    return SignedZero(sign);
4815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
4825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
4835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
484fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
4855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Copy significant digits of the integer part (if any) to the buffer.
4865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        while (*current >= '0' && *current <= '9') {
4875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (significant_digits < kMaxSignificantDigits) {
4885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                ASSERT(buffer_pos < kBufferSize);
4895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                buffer[buffer_pos++] = static_cast<char>(*current);
4905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                significant_digits++;
4915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            } else {
4925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                insignificant_digits++;  // Move the digit into the exponential part.
4935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
4945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
4955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ++current;
4965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (current == end) goto parsing_done;
4975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
498fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
4995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (*current == '.') {
5005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ++current;
5015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (current == end) {
5025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (significant_digits == 0 && !leading_zero) {
5035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    return 0.0;
5045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                } else {
5055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    goto parsing_done;
5065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
5075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
508fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
5095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (significant_digits == 0) {
5105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                // Integer part consists of 0 or is absent. Significant digits start after
5115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                // leading zeros (if any).
5125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                while (*current == '0') {
5135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    ++current;
5145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    if (current == end) {
5155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        *processed_characters_count = current - input;
5165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        return SignedZero(sign);
5175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    }
5185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    exponent--;  // Move this 0 into the exponent.
5195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
5205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
5215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // There is a fractional part.
5235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            while (*current >= '0' && *current <= '9') {
5245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (significant_digits < kMaxSignificantDigits) {
5255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    ASSERT(buffer_pos < kBufferSize);
5265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    buffer[buffer_pos++] = static_cast<char>(*current);
5275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    significant_digits++;
5285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    exponent--;
5295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                } else {
5305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    // Ignore insignificant digits in the fractional part.
5315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
5325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
5335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                ++current;
5345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (current == end) goto parsing_done;
5355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
5365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
537fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
5385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!leading_zero && exponent == 0 && significant_digits == 0) {
5395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // If leading_zeros is true then the string contains zeros.
5405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // If exponent < 0 then string was [+-]\.0*...
5415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // If significant_digits != 0 the string is not equal to 0.
5425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // Otherwise there are no digits in the string.
5435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return 0.0;
5445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
545fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
5465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Parse exponential part.
5475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (*current == 'e' || *current == 'E') {
5485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ++current;
5495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (current == end) {
5505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                --current;
5515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                goto parsing_done;
5525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
5535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            char sign = 0;
5545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (*current == '+' || *current == '-') {
5555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                sign = static_cast<char>(*current);
5565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                ++current;
5575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (current == end) {
5585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    current -= 2;
5595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    goto parsing_done;
5605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
5615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
562fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
5635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (*current < '0' || *current > '9') {
5645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (sign)
5655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    --current;
5665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                --current;
5675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                goto parsing_done;
5685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
569fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
5705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            const int max_exponent = INT_MAX / 2;
5715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ASSERT(-max_exponent / 2 <= exponent && exponent <= max_exponent / 2);
5725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            int num = 0;
5735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            do {
5745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                // Check overflow.
5755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                int digit = *current - '0';
5765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (num >= max_exponent / 10
5775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    && !(num == max_exponent / 10 && digit <= max_exponent % 10)) {
5785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    num = max_exponent;
5795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                } else {
5805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    num = num * 10 + digit;
5815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
5825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                ++current;
5835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            } while (current != end && *current >= '0' && *current <= '9');
584fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
5855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            exponent += (sign == '-' ? -num : num);
5865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
587fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
5885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    parsing_done:
5895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        exponent += insignificant_digits;
590fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
5915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (nonzero_digit_dropped) {
5925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            buffer[buffer_pos++] = '1';
5935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            exponent--;
5945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
595fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
5965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT(buffer_pos < kBufferSize);
5975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        buffer[buffer_pos] = '\0';
598fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
5995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        double converted = Strtod(Vector<const char>(buffer, buffer_pos), exponent);
6005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        *processed_characters_count = current - input;
6015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return sign? -converted: converted;
6025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
603fff8884795cb540f87cf6e6d67b629519b00eb8bBen Murdoch
6045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}  // namespace double_conversion
6055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} // namespace WTF
607