LCOV - code coverage report
Current view: top level - mfbt/double-conversion/source - strtod.cc (source / functions) Hit Total Coverage
Test: output.info Lines: 0 220 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 13 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // Copyright 2010 the V8 project authors. All rights reserved.
       2             : // Redistribution and use in source and binary forms, with or without
       3             : // modification, are permitted provided that the following conditions are
       4             : // met:
       5             : //
       6             : //     * Redistributions of source code must retain the above copyright
       7             : //       notice, this list of conditions and the following disclaimer.
       8             : //     * Redistributions in binary form must reproduce the above
       9             : //       copyright notice, this list of conditions and the following
      10             : //       disclaimer in the documentation and/or other materials provided
      11             : //       with the distribution.
      12             : //     * Neither the name of Google Inc. nor the names of its
      13             : //       contributors may be used to endorse or promote products derived
      14             : //       from this software without specific prior written permission.
      15             : //
      16             : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
      17             : // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
      18             : // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
      19             : // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
      20             : // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      21             : // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
      22             : // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      23             : // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      24             : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      25             : // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
      26             : // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      27             : 
      28             : #include <stdarg.h>
      29             : #include <limits.h>
      30             : 
      31             : #include "strtod.h"
      32             : #include "bignum.h"
      33             : #include "cached-powers.h"
      34             : #include "ieee.h"
      35             : 
      36             : namespace double_conversion {
      37             : 
      38             : // 2^53 = 9007199254740992.
      39             : // Any integer with at most 15 decimal digits will hence fit into a double
      40             : // (which has a 53bit significand) without loss of precision.
      41             : static const int kMaxExactDoubleIntegerDecimalDigits = 15;
      42             : // 2^64 = 18446744073709551616 > 10^19
      43             : static const int kMaxUint64DecimalDigits = 19;
      44             : 
      45             : // Max double: 1.7976931348623157 x 10^308
      46             : // Min non-zero double: 4.9406564584124654 x 10^-324
      47             : // Any x >= 10^309 is interpreted as +infinity.
      48             : // Any x <= 10^-324 is interpreted as 0.
      49             : // Note that 2.5e-324 (despite being smaller than the min double) will be read
      50             : // as non-zero (equal to the min non-zero double).
      51             : static const int kMaxDecimalPower = 309;
      52             : static const int kMinDecimalPower = -324;
      53             : 
      54             : // 2^64 = 18446744073709551616
      55             : static const uint64_t kMaxUint64 = UINT64_2PART_C(0xFFFFFFFF, FFFFFFFF);
      56             : 
      57             : 
      58             : static const double exact_powers_of_ten[] = {
      59             :   1.0,  // 10^0
      60             :   10.0,
      61             :   100.0,
      62             :   1000.0,
      63             :   10000.0,
      64             :   100000.0,
      65             :   1000000.0,
      66             :   10000000.0,
      67             :   100000000.0,
      68             :   1000000000.0,
      69             :   10000000000.0,  // 10^10
      70             :   100000000000.0,
      71             :   1000000000000.0,
      72             :   10000000000000.0,
      73             :   100000000000000.0,
      74             :   1000000000000000.0,
      75             :   10000000000000000.0,
      76             :   100000000000000000.0,
      77             :   1000000000000000000.0,
      78             :   10000000000000000000.0,
      79             :   100000000000000000000.0,  // 10^20
      80             :   1000000000000000000000.0,
      81             :   // 10^22 = 0x21e19e0c9bab2400000 = 0x878678326eac9 * 2^22
      82             :   10000000000000000000000.0
      83             : };
      84             : static const int kExactPowersOfTenSize = ARRAY_SIZE(exact_powers_of_ten);
      85             : 
      86             : // Maximum number of significant digits in the decimal representation.
      87             : // In fact the value is 772 (see conversions.cc), but to give us some margin
      88             : // we round up to 780.
      89             : static const int kMaxSignificantDecimalDigits = 780;
      90             : 
      91           0 : static Vector<const char> TrimLeadingZeros(Vector<const char> buffer) {
      92           0 :   for (int i = 0; i < buffer.length(); i++) {
      93           0 :     if (buffer[i] != '0') {
      94           0 :       return buffer.SubVector(i, buffer.length());
      95             :     }
      96             :   }
      97           0 :   return Vector<const char>(buffer.start(), 0);
      98             : }
      99             : 
     100             : 
     101           0 : static Vector<const char> TrimTrailingZeros(Vector<const char> buffer) {
     102           0 :   for (int i = buffer.length() - 1; i >= 0; --i) {
     103           0 :     if (buffer[i] != '0') {
     104           0 :       return buffer.SubVector(0, i + 1);
     105             :     }
     106             :   }
     107           0 :   return Vector<const char>(buffer.start(), 0);
     108             : }
     109             : 
     110             : 
     111           0 : static void CutToMaxSignificantDigits(Vector<const char> buffer,
     112             :                                        int exponent,
     113             :                                        char* significant_buffer,
     114             :                                        int* significant_exponent) {
     115           0 :   for (int i = 0; i < kMaxSignificantDecimalDigits - 1; ++i) {
     116           0 :     significant_buffer[i] = buffer[i];
     117             :   }
     118             :   // The input buffer has been trimmed. Therefore the last digit must be
     119             :   // different from '0'.
     120           0 :   ASSERT(buffer[buffer.length() - 1] != '0');
     121             :   // Set the last digit to be non-zero. This is sufficient to guarantee
     122             :   // correct rounding.
     123           0 :   significant_buffer[kMaxSignificantDecimalDigits - 1] = '1';
     124           0 :   *significant_exponent =
     125           0 :       exponent + (buffer.length() - kMaxSignificantDecimalDigits);
     126           0 : }
     127             : 
     128             : 
     129             : // Trims the buffer and cuts it to at most kMaxSignificantDecimalDigits.
     130             : // If possible the input-buffer is reused, but if the buffer needs to be
     131             : // modified (due to cutting), then the input needs to be copied into the
     132             : // buffer_copy_space.
     133           0 : static void TrimAndCut(Vector<const char> buffer, int exponent,
     134             :                        char* buffer_copy_space, int space_size,
     135             :                        Vector<const char>* trimmed, int* updated_exponent) {
     136           0 :   Vector<const char> left_trimmed = TrimLeadingZeros(buffer);
     137           0 :   Vector<const char> right_trimmed = TrimTrailingZeros(left_trimmed);
     138           0 :   exponent += left_trimmed.length() - right_trimmed.length();
     139           0 :   if (right_trimmed.length() > kMaxSignificantDecimalDigits) {
     140             :     (void) space_size;  // Mark variable as used.
     141           0 :     ASSERT(space_size >= kMaxSignificantDecimalDigits);
     142             :     CutToMaxSignificantDigits(right_trimmed, exponent,
     143           0 :                               buffer_copy_space, updated_exponent);
     144           0 :     *trimmed = Vector<const char>(buffer_copy_space,
     145           0 :                                  kMaxSignificantDecimalDigits);
     146             :   } else {
     147           0 :     *trimmed = right_trimmed;
     148           0 :     *updated_exponent = exponent;
     149             :   }
     150           0 : }
     151             : 
     152             : 
     153             : // Reads digits from the buffer and converts them to a uint64.
     154             : // Reads in as many digits as fit into a uint64.
     155             : // When the string starts with "1844674407370955161" no further digit is read.
     156             : // Since 2^64 = 18446744073709551616 it would still be possible read another
     157             : // digit if it was less or equal than 6, but this would complicate the code.
     158           0 : static uint64_t ReadUint64(Vector<const char> buffer,
     159             :                            int* number_of_read_digits) {
     160           0 :   uint64_t result = 0;
     161           0 :   int i = 0;
     162           0 :   while (i < buffer.length() && result <= (kMaxUint64 / 10 - 1)) {
     163           0 :     int digit = buffer[i++] - '0';
     164           0 :     ASSERT(0 <= digit && digit <= 9);
     165           0 :     result = 10 * result + digit;
     166             :   }
     167           0 :   *number_of_read_digits = i;
     168           0 :   return result;
     169             : }
     170             : 
     171             : 
     172             : // Reads a DiyFp from the buffer.
     173             : // The returned DiyFp is not necessarily normalized.
     174             : // If remaining_decimals is zero then the returned DiyFp is accurate.
     175             : // Otherwise it has been rounded and has error of at most 1/2 ulp.
     176           0 : static void ReadDiyFp(Vector<const char> buffer,
     177             :                       DiyFp* result,
     178             :                       int* remaining_decimals) {
     179             :   int read_digits;
     180           0 :   uint64_t significand = ReadUint64(buffer, &read_digits);
     181           0 :   if (buffer.length() == read_digits) {
     182           0 :     *result = DiyFp(significand, 0);
     183           0 :     *remaining_decimals = 0;
     184             :   } else {
     185             :     // Round the significand.
     186           0 :     if (buffer[read_digits] >= '5') {
     187           0 :       significand++;
     188             :     }
     189             :     // Compute the binary exponent.
     190           0 :     int exponent = 0;
     191           0 :     *result = DiyFp(significand, exponent);
     192           0 :     *remaining_decimals = buffer.length() - read_digits;
     193             :   }
     194           0 : }
     195             : 
     196             : 
     197           0 : static bool DoubleStrtod(Vector<const char> trimmed,
     198             :                          int exponent,
     199             :                          double* result) {
     200             : #if !defined(DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS)
     201             :   // On x86 the floating-point stack can be 64 or 80 bits wide. If it is
     202             :   // 80 bits wide (as is the case on Linux) then double-rounding occurs and the
     203             :   // result is not accurate.
     204             :   // We know that Windows32 uses 64 bits and is therefore accurate.
     205             :   // Note that the ARM simulator is compiled for 32bits. It therefore exhibits
     206             :   // the same problem.
     207             :   return false;
     208             : #endif
     209           0 :   if (trimmed.length() <= kMaxExactDoubleIntegerDecimalDigits) {
     210             :     int read_digits;
     211             :     // The trimmed input fits into a double.
     212             :     // If the 10^exponent (resp. 10^-exponent) fits into a double too then we
     213             :     // can compute the result-double simply by multiplying (resp. dividing) the
     214             :     // two numbers.
     215             :     // This is possible because IEEE guarantees that floating-point operations
     216             :     // return the best possible approximation.
     217           0 :     if (exponent < 0 && -exponent < kExactPowersOfTenSize) {
     218             :       // 10^-exponent fits into a double.
     219           0 :       *result = static_cast<double>(ReadUint64(trimmed, &read_digits));
     220           0 :       ASSERT(read_digits == trimmed.length());
     221           0 :       *result /= exact_powers_of_ten[-exponent];
     222           0 :       return true;
     223             :     }
     224           0 :     if (0 <= exponent && exponent < kExactPowersOfTenSize) {
     225             :       // 10^exponent fits into a double.
     226           0 :       *result = static_cast<double>(ReadUint64(trimmed, &read_digits));
     227           0 :       ASSERT(read_digits == trimmed.length());
     228           0 :       *result *= exact_powers_of_ten[exponent];
     229           0 :       return true;
     230             :     }
     231             :     int remaining_digits =
     232           0 :         kMaxExactDoubleIntegerDecimalDigits - trimmed.length();
     233           0 :     if ((0 <= exponent) &&
     234           0 :         (exponent - remaining_digits < kExactPowersOfTenSize)) {
     235             :       // The trimmed string was short and we can multiply it with
     236             :       // 10^remaining_digits. As a result the remaining exponent now fits
     237             :       // into a double too.
     238           0 :       *result = static_cast<double>(ReadUint64(trimmed, &read_digits));
     239           0 :       ASSERT(read_digits == trimmed.length());
     240           0 :       *result *= exact_powers_of_ten[remaining_digits];
     241           0 :       *result *= exact_powers_of_ten[exponent - remaining_digits];
     242           0 :       return true;
     243             :     }
     244             :   }
     245           0 :   return false;
     246             : }
     247             : 
     248             : 
     249             : // Returns 10^exponent as an exact DiyFp.
     250             : // The given exponent must be in the range [1; kDecimalExponentDistance[.
     251           0 : static DiyFp AdjustmentPowerOfTen(int exponent) {
     252           0 :   ASSERT(0 < exponent);
     253           0 :   ASSERT(exponent < PowersOfTenCache::kDecimalExponentDistance);
     254             :   // Simply hardcode the remaining powers for the given decimal exponent
     255             :   // distance.
     256           0 :   ASSERT(PowersOfTenCache::kDecimalExponentDistance == 8);
     257           0 :   switch (exponent) {
     258           0 :     case 1: return DiyFp(UINT64_2PART_C(0xa0000000, 00000000), -60);
     259           0 :     case 2: return DiyFp(UINT64_2PART_C(0xc8000000, 00000000), -57);
     260           0 :     case 3: return DiyFp(UINT64_2PART_C(0xfa000000, 00000000), -54);
     261           0 :     case 4: return DiyFp(UINT64_2PART_C(0x9c400000, 00000000), -50);
     262           0 :     case 5: return DiyFp(UINT64_2PART_C(0xc3500000, 00000000), -47);
     263           0 :     case 6: return DiyFp(UINT64_2PART_C(0xf4240000, 00000000), -44);
     264           0 :     case 7: return DiyFp(UINT64_2PART_C(0x98968000, 00000000), -40);
     265             :     default:
     266           0 :       UNREACHABLE();
     267             :   }
     268             : }
     269             : 
     270             : 
     271             : // If the function returns true then the result is the correct double.
     272             : // Otherwise it is either the correct double or the double that is just below
     273             : // the correct double.
     274           0 : static bool DiyFpStrtod(Vector<const char> buffer,
     275             :                         int exponent,
     276             :                         double* result) {
     277           0 :   DiyFp input;
     278             :   int remaining_decimals;
     279           0 :   ReadDiyFp(buffer, &input, &remaining_decimals);
     280             :   // Since we may have dropped some digits the input is not accurate.
     281             :   // If remaining_decimals is different than 0 than the error is at most
     282             :   // .5 ulp (unit in the last place).
     283             :   // We don't want to deal with fractions and therefore keep a common
     284             :   // denominator.
     285           0 :   const int kDenominatorLog = 3;
     286           0 :   const int kDenominator = 1 << kDenominatorLog;
     287             :   // Move the remaining decimals into the exponent.
     288           0 :   exponent += remaining_decimals;
     289           0 :   uint64_t error = (remaining_decimals == 0 ? 0 : kDenominator / 2);
     290             : 
     291           0 :   int old_e = input.e();
     292           0 :   input.Normalize();
     293           0 :   error <<= old_e - input.e();
     294             : 
     295           0 :   ASSERT(exponent <= PowersOfTenCache::kMaxDecimalExponent);
     296           0 :   if (exponent < PowersOfTenCache::kMinDecimalExponent) {
     297           0 :     *result = 0.0;
     298           0 :     return true;
     299             :   }
     300           0 :   DiyFp cached_power;
     301             :   int cached_decimal_exponent;
     302             :   PowersOfTenCache::GetCachedPowerForDecimalExponent(exponent,
     303             :                                                      &cached_power,
     304           0 :                                                      &cached_decimal_exponent);
     305             : 
     306           0 :   if (cached_decimal_exponent != exponent) {
     307           0 :     int adjustment_exponent = exponent - cached_decimal_exponent;
     308           0 :     DiyFp adjustment_power = AdjustmentPowerOfTen(adjustment_exponent);
     309           0 :     input.Multiply(adjustment_power);
     310           0 :     if (kMaxUint64DecimalDigits - buffer.length() >= adjustment_exponent) {
     311             :       // The product of input with the adjustment power fits into a 64 bit
     312             :       // integer.
     313             :       ASSERT(DiyFp::kSignificandSize == 64);
     314             :     } else {
     315             :       // The adjustment power is exact. There is hence only an error of 0.5.
     316           0 :       error += kDenominator / 2;
     317             :     }
     318             :   }
     319             : 
     320           0 :   input.Multiply(cached_power);
     321             :   // The error introduced by a multiplication of a*b equals
     322             :   //   error_a + error_b + error_a*error_b/2^64 + 0.5
     323             :   // Substituting a with 'input' and b with 'cached_power' we have
     324             :   //   error_b = 0.5  (all cached powers have an error of less than 0.5 ulp),
     325             :   //   error_ab = 0 or 1 / kDenominator > error_a*error_b/ 2^64
     326           0 :   int error_b = kDenominator / 2;
     327           0 :   int error_ab = (error == 0 ? 0 : 1);  // We round up to 1.
     328           0 :   int fixed_error = kDenominator / 2;
     329           0 :   error += error_b + error_ab + fixed_error;
     330             : 
     331           0 :   old_e = input.e();
     332           0 :   input.Normalize();
     333           0 :   error <<= old_e - input.e();
     334             : 
     335             :   // See if the double's significand changes if we add/subtract the error.
     336           0 :   int order_of_magnitude = DiyFp::kSignificandSize + input.e();
     337             :   int effective_significand_size =
     338           0 :       Double::SignificandSizeForOrderOfMagnitude(order_of_magnitude);
     339             :   int precision_digits_count =
     340           0 :       DiyFp::kSignificandSize - effective_significand_size;
     341           0 :   if (precision_digits_count + kDenominatorLog >= DiyFp::kSignificandSize) {
     342             :     // This can only happen for very small denormals. In this case the
     343             :     // half-way multiplied by the denominator exceeds the range of an uint64.
     344             :     // Simply shift everything to the right.
     345             :     int shift_amount = (precision_digits_count + kDenominatorLog) -
     346           0 :         DiyFp::kSignificandSize + 1;
     347           0 :     input.set_f(input.f() >> shift_amount);
     348           0 :     input.set_e(input.e() + shift_amount);
     349             :     // We add 1 for the lost precision of error, and kDenominator for
     350             :     // the lost precision of input.f().
     351           0 :     error = (error >> shift_amount) + 1 + kDenominator;
     352           0 :     precision_digits_count -= shift_amount;
     353             :   }
     354             :   // We use uint64_ts now. This only works if the DiyFp uses uint64_ts too.
     355             :   ASSERT(DiyFp::kSignificandSize == 64);
     356           0 :   ASSERT(precision_digits_count < 64);
     357           0 :   uint64_t one64 = 1;
     358           0 :   uint64_t precision_bits_mask = (one64 << precision_digits_count) - 1;
     359           0 :   uint64_t precision_bits = input.f() & precision_bits_mask;
     360           0 :   uint64_t half_way = one64 << (precision_digits_count - 1);
     361           0 :   precision_bits *= kDenominator;
     362           0 :   half_way *= kDenominator;
     363           0 :   DiyFp rounded_input(input.f() >> precision_digits_count,
     364           0 :                       input.e() + precision_digits_count);
     365           0 :   if (precision_bits >= half_way + error) {
     366           0 :     rounded_input.set_f(rounded_input.f() + 1);
     367             :   }
     368             :   // If the last_bits are too close to the half-way case than we are too
     369             :   // inaccurate and round down. In this case we return false so that we can
     370             :   // fall back to a more precise algorithm.
     371             : 
     372           0 :   *result = Double(rounded_input).value();
     373           0 :   if (half_way - error < precision_bits && precision_bits < half_way + error) {
     374             :     // Too imprecise. The caller will have to fall back to a slower version.
     375             :     // However the returned number is guaranteed to be either the correct
     376             :     // double, or the next-lower double.
     377           0 :     return false;
     378             :   } else {
     379           0 :     return true;
     380             :   }
     381             : }
     382             : 
     383             : 
     384             : // Returns
     385             : //   - -1 if buffer*10^exponent < diy_fp.
     386             : //   -  0 if buffer*10^exponent == diy_fp.
     387             : //   - +1 if buffer*10^exponent > diy_fp.
     388             : // Preconditions:
     389             : //   buffer.length() + exponent <= kMaxDecimalPower + 1
     390             : //   buffer.length() + exponent > kMinDecimalPower
     391             : //   buffer.length() <= kMaxDecimalSignificantDigits
     392           0 : static int CompareBufferWithDiyFp(Vector<const char> buffer,
     393             :                                   int exponent,
     394             :                                   DiyFp diy_fp) {
     395           0 :   ASSERT(buffer.length() + exponent <= kMaxDecimalPower + 1);
     396           0 :   ASSERT(buffer.length() + exponent > kMinDecimalPower);
     397           0 :   ASSERT(buffer.length() <= kMaxSignificantDecimalDigits);
     398             :   // Make sure that the Bignum will be able to hold all our numbers.
     399             :   // Our Bignum implementation has a separate field for exponents. Shifts will
     400             :   // consume at most one bigit (< 64 bits).
     401             :   // ln(10) == 3.3219...
     402             :   ASSERT(((kMaxDecimalPower + 1) * 333 / 100) < Bignum::kMaxSignificantBits);
     403           0 :   Bignum buffer_bignum;
     404           0 :   Bignum diy_fp_bignum;
     405           0 :   buffer_bignum.AssignDecimalString(buffer);
     406           0 :   diy_fp_bignum.AssignUInt64(diy_fp.f());
     407           0 :   if (exponent >= 0) {
     408           0 :     buffer_bignum.MultiplyByPowerOfTen(exponent);
     409             :   } else {
     410           0 :     diy_fp_bignum.MultiplyByPowerOfTen(-exponent);
     411             :   }
     412           0 :   if (diy_fp.e() > 0) {
     413           0 :     diy_fp_bignum.ShiftLeft(diy_fp.e());
     414             :   } else {
     415           0 :     buffer_bignum.ShiftLeft(-diy_fp.e());
     416             :   }
     417           0 :   return Bignum::Compare(buffer_bignum, diy_fp_bignum);
     418             : }
     419             : 
     420             : 
     421             : // Returns true if the guess is the correct double.
     422             : // Returns false, when guess is either correct or the next-lower double.
     423           0 : static bool ComputeGuess(Vector<const char> trimmed, int exponent,
     424             :                          double* guess) {
     425           0 :   if (trimmed.length() == 0) {
     426           0 :     *guess = 0.0;
     427           0 :     return true;
     428             :   }
     429           0 :   if (exponent + trimmed.length() - 1 >= kMaxDecimalPower) {
     430           0 :     *guess = Double::Infinity();
     431           0 :     return true;
     432             :   }
     433           0 :   if (exponent + trimmed.length() <= kMinDecimalPower) {
     434           0 :     *guess = 0.0;
     435           0 :     return true;
     436             :   }
     437             : 
     438           0 :   if (DoubleStrtod(trimmed, exponent, guess) ||
     439           0 :       DiyFpStrtod(trimmed, exponent, guess)) {
     440           0 :     return true;
     441             :   }
     442           0 :   if (*guess == Double::Infinity()) {
     443           0 :     return true;
     444             :   }
     445           0 :   return false;
     446             : }
     447             : 
     448           0 : double Strtod(Vector<const char> buffer, int exponent) {
     449             :   char copy_buffer[kMaxSignificantDecimalDigits];
     450           0 :   Vector<const char> trimmed;
     451             :   int updated_exponent;
     452             :   TrimAndCut(buffer, exponent, copy_buffer, kMaxSignificantDecimalDigits,
     453           0 :              &trimmed, &updated_exponent);
     454           0 :   exponent = updated_exponent;
     455             : 
     456             :   double guess;
     457           0 :   bool is_correct = ComputeGuess(trimmed, exponent, &guess);
     458           0 :   if (is_correct) return guess;
     459             : 
     460           0 :   DiyFp upper_boundary = Double(guess).UpperBoundary();
     461           0 :   int comparison = CompareBufferWithDiyFp(trimmed, exponent, upper_boundary);
     462           0 :   if (comparison < 0) {
     463           0 :     return guess;
     464           0 :   } else if (comparison > 0) {
     465           0 :     return Double(guess).NextDouble();
     466           0 :   } else if ((Double(guess).Significand() & 1) == 0) {
     467             :     // Round towards even.
     468           0 :     return guess;
     469             :   } else {
     470           0 :     return Double(guess).NextDouble();
     471             :   }
     472             : }
     473             : 
     474           0 : float Strtof(Vector<const char> buffer, int exponent) {
     475             :   char copy_buffer[kMaxSignificantDecimalDigits];
     476           0 :   Vector<const char> trimmed;
     477             :   int updated_exponent;
     478             :   TrimAndCut(buffer, exponent, copy_buffer, kMaxSignificantDecimalDigits,
     479           0 :              &trimmed, &updated_exponent);
     480           0 :   exponent = updated_exponent;
     481             : 
     482             :   double double_guess;
     483           0 :   bool is_correct = ComputeGuess(trimmed, exponent, &double_guess);
     484             : 
     485           0 :   float float_guess = static_cast<float>(double_guess);
     486           0 :   if (float_guess == double_guess) {
     487             :     // This shortcut triggers for integer values.
     488           0 :     return float_guess;
     489             :   }
     490             : 
     491             :   // We must catch double-rounding. Say the double has been rounded up, and is
     492             :   // now a boundary of a float, and rounds up again. This is why we have to
     493             :   // look at previous too.
     494             :   // Example (in decimal numbers):
     495             :   //    input: 12349
     496             :   //    high-precision (4 digits): 1235
     497             :   //    low-precision (3 digits):
     498             :   //       when read from input: 123
     499             :   //       when rounded from high precision: 124.
     500             :   // To do this we simply look at the neigbors of the correct result and see
     501             :   // if they would round to the same float. If the guess is not correct we have
     502             :   // to look at four values (since two different doubles could be the correct
     503             :   // double).
     504             : 
     505           0 :   double double_next = Double(double_guess).NextDouble();
     506           0 :   double double_previous = Double(double_guess).PreviousDouble();
     507             : 
     508           0 :   float f1 = static_cast<float>(double_previous);
     509           0 :   float f2 = float_guess;
     510           0 :   float f3 = static_cast<float>(double_next);
     511             :   float f4;
     512           0 :   if (is_correct) {
     513           0 :     f4 = f3;
     514             :   } else {
     515           0 :     double double_next2 = Double(double_next).NextDouble();
     516           0 :     f4 = static_cast<float>(double_next2);
     517             :   }
     518             :   (void) f2;  // Mark variable as used.
     519           0 :   ASSERT(f1 <= f2 && f2 <= f3 && f3 <= f4);
     520             : 
     521             :   // If the guess doesn't lie near a single-precision boundary we can simply
     522             :   // return its float-value.
     523           0 :   if (f1 == f4) {
     524           0 :     return float_guess;
     525             :   }
     526             : 
     527           0 :   ASSERT((f1 != f2 && f2 == f3 && f3 == f4) ||
     528             :          (f1 == f2 && f2 != f3 && f3 == f4) ||
     529             :          (f1 == f2 && f2 == f3 && f3 != f4));
     530             : 
     531             :   // guess and next are the two possible canditates (in the same way that
     532             :   // double_guess was the lower candidate for a double-precision guess).
     533           0 :   float guess = f1;
     534           0 :   float next = f4;
     535           0 :   DiyFp upper_boundary;
     536           0 :   if (guess == 0.0f) {
     537           0 :     float min_float = 1e-45f;
     538           0 :     upper_boundary = Double(static_cast<double>(min_float) / 2).AsDiyFp();
     539             :   } else {
     540           0 :     upper_boundary = Single(guess).UpperBoundary();
     541             :   }
     542           0 :   int comparison = CompareBufferWithDiyFp(trimmed, exponent, upper_boundary);
     543           0 :   if (comparison < 0) {
     544           0 :     return guess;
     545           0 :   } else if (comparison > 0) {
     546           0 :     return next;
     547           0 :   } else if ((Single(guess).Significand() & 1) == 0) {
     548             :     // Round towards even.
     549           0 :     return guess;
     550             :   } else {
     551           0 :     return next;
     552             :   }
     553             : }
     554             : 
     555             : }  // namespace double_conversion

Generated by: LCOV version 1.13