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