Home | History | Annotate | Download | only in src
      1 // Copyright 2011 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 <math.h>
     29 
     30 #include "../include/v8stdint.h"
     31 #include "checks.h"
     32 #include "utils.h"
     33 
     34 #include "double.h"
     35 #include "fixed-dtoa.h"
     36 
     37 namespace v8 {
     38 namespace internal {
     39 
     40 // Represents a 128bit type. This class should be replaced by a native type on
     41 // platforms that support 128bit integers.
     42 class UInt128 {
     43  public:
     44   UInt128() : high_bits_(0), low_bits_(0) { }
     45   UInt128(uint64_t high, uint64_t low) : high_bits_(high), low_bits_(low) { }
     46 
     47   void Multiply(uint32_t multiplicand) {
     48     uint64_t accumulator;
     49 
     50     accumulator = (low_bits_ & kMask32) * multiplicand;
     51     uint32_t part = static_cast<uint32_t>(accumulator & kMask32);
     52     accumulator >>= 32;
     53     accumulator = accumulator + (low_bits_ >> 32) * multiplicand;
     54     low_bits_ = (accumulator << 32) + part;
     55     accumulator >>= 32;
     56     accumulator = accumulator + (high_bits_ & kMask32) * multiplicand;
     57     part = static_cast<uint32_t>(accumulator & kMask32);
     58     accumulator >>= 32;
     59     accumulator = accumulator + (high_bits_ >> 32) * multiplicand;
     60     high_bits_ = (accumulator << 32) + part;
     61     ASSERT((accumulator >> 32) == 0);
     62   }
     63 
     64   void Shift(int shift_amount) {
     65     ASSERT(-64 <= shift_amount && shift_amount <= 64);
     66     if (shift_amount == 0) {
     67       return;
     68     } else if (shift_amount == -64) {
     69       high_bits_ = low_bits_;
     70       low_bits_ = 0;
     71     } else if (shift_amount == 64) {
     72       low_bits_ = high_bits_;
     73       high_bits_ = 0;
     74     } else if (shift_amount <= 0) {
     75       high_bits_ <<= -shift_amount;
     76       high_bits_ += low_bits_ >> (64 + shift_amount);
     77       low_bits_ <<= -shift_amount;
     78     } else {
     79       low_bits_ >>= shift_amount;
     80       low_bits_ += high_bits_ << (64 - shift_amount);
     81       high_bits_ >>= shift_amount;
     82     }
     83   }
     84 
     85   // Modifies *this to *this MOD (2^power).
     86   // Returns *this DIV (2^power).
     87   int DivModPowerOf2(int power) {
     88     if (power >= 64) {
     89       int result = static_cast<int>(high_bits_ >> (power - 64));
     90       high_bits_ -= static_cast<uint64_t>(result) << (power - 64);
     91       return result;
     92     } else {
     93       uint64_t part_low = low_bits_ >> power;
     94       uint64_t part_high = high_bits_ << (64 - power);
     95       int result = static_cast<int>(part_low + part_high);
     96       high_bits_ = 0;
     97       low_bits_ -= part_low << power;
     98       return result;
     99     }
    100   }
    101 
    102   bool IsZero() const {
    103     return high_bits_ == 0 && low_bits_ == 0;
    104   }
    105 
    106   int BitAt(int position) {
    107     if (position >= 64) {
    108       return static_cast<int>(high_bits_ >> (position - 64)) & 1;
    109     } else {
    110       return static_cast<int>(low_bits_ >> position) & 1;
    111     }
    112   }
    113 
    114  private:
    115   static const uint64_t kMask32 = 0xFFFFFFFF;
    116   // Value == (high_bits_ << 64) + low_bits_
    117   uint64_t high_bits_;
    118   uint64_t low_bits_;
    119 };
    120 
    121 
    122 static const int kDoubleSignificandSize = 53;  // Includes the hidden bit.
    123 
    124 
    125 static void FillDigits32FixedLength(uint32_t number, int requested_length,
    126                                     Vector<char> buffer, int* length) {
    127   for (int i = requested_length - 1; i >= 0; --i) {
    128     buffer[(*length) + i] = '0' + number % 10;
    129     number /= 10;
    130   }
    131   *length += requested_length;
    132 }
    133 
    134 
    135 static void FillDigits32(uint32_t number, Vector<char> buffer, int* length) {
    136   int number_length = 0;
    137   // We fill the digits in reverse order and exchange them afterwards.
    138   while (number != 0) {
    139     int digit = number % 10;
    140     number /= 10;
    141     buffer[(*length) + number_length] = '0' + digit;
    142     number_length++;
    143   }
    144   // Exchange the digits.
    145   int i = *length;
    146   int j = *length + number_length - 1;
    147   while (i < j) {
    148     char tmp = buffer[i];
    149     buffer[i] = buffer[j];
    150     buffer[j] = tmp;
    151     i++;
    152     j--;
    153   }
    154   *length += number_length;
    155 }
    156 
    157 
    158 static void FillDigits64FixedLength(uint64_t number, int requested_length,
    159                                     Vector<char> buffer, int* length) {
    160   const uint32_t kTen7 = 10000000;
    161   // For efficiency cut the number into 3 uint32_t parts, and print those.
    162   uint32_t part2 = static_cast<uint32_t>(number % kTen7);
    163   number /= kTen7;
    164   uint32_t part1 = static_cast<uint32_t>(number % kTen7);
    165   uint32_t part0 = static_cast<uint32_t>(number / kTen7);
    166 
    167   FillDigits32FixedLength(part0, 3, buffer, length);
    168   FillDigits32FixedLength(part1, 7, buffer, length);
    169   FillDigits32FixedLength(part2, 7, buffer, length);
    170 }
    171 
    172 
    173 static void FillDigits64(uint64_t number, Vector<char> buffer, int* length) {
    174   const uint32_t kTen7 = 10000000;
    175   // For efficiency cut the number into 3 uint32_t parts, and print those.
    176   uint32_t part2 = static_cast<uint32_t>(number % kTen7);
    177   number /= kTen7;
    178   uint32_t part1 = static_cast<uint32_t>(number % kTen7);
    179   uint32_t part0 = static_cast<uint32_t>(number / kTen7);
    180 
    181   if (part0 != 0) {
    182     FillDigits32(part0, buffer, length);
    183     FillDigits32FixedLength(part1, 7, buffer, length);
    184     FillDigits32FixedLength(part2, 7, buffer, length);
    185   } else if (part1 != 0) {
    186     FillDigits32(part1, buffer, length);
    187     FillDigits32FixedLength(part2, 7, buffer, length);
    188   } else {
    189     FillDigits32(part2, buffer, length);
    190   }
    191 }
    192 
    193 
    194 static void RoundUp(Vector<char> buffer, int* length, int* decimal_point) {
    195   // An empty buffer represents 0.
    196   if (*length == 0) {
    197     buffer[0] = '1';
    198     *decimal_point = 1;
    199     *length = 1;
    200     return;
    201   }
    202   // Round the last digit until we either have a digit that was not '9' or until
    203   // we reached the first digit.
    204   buffer[(*length) - 1]++;
    205   for (int i = (*length) - 1; i > 0; --i) {
    206     if (buffer[i] != '0' + 10) {
    207       return;
    208     }
    209     buffer[i] = '0';
    210     buffer[i - 1]++;
    211   }
    212   // If the first digit is now '0' + 10, we would need to set it to '0' and add
    213   // a '1' in front. However we reach the first digit only if all following
    214   // digits had been '9' before rounding up. Now all trailing digits are '0' and
    215   // we simply switch the first digit to '1' and update the decimal-point
    216   // (indicating that the point is now one digit to the right).
    217   if (buffer[0] == '0' + 10) {
    218     buffer[0] = '1';
    219     (*decimal_point)++;
    220   }
    221 }
    222 
    223 
    224 // The given fractionals number represents a fixed-point number with binary
    225 // point at bit (-exponent).
    226 // Preconditions:
    227 //   -128 <= exponent <= 0.
    228 //   0 <= fractionals * 2^exponent < 1
    229 //   The buffer holds the result.
    230 // The function will round its result. During the rounding-process digits not
    231 // generated by this function might be updated, and the decimal-point variable
    232 // might be updated. If this function generates the digits 99 and the buffer
    233 // already contained "199" (thus yielding a buffer of "19999") then a
    234 // rounding-up will change the contents of the buffer to "20000".
    235 static void FillFractionals(uint64_t fractionals, int exponent,
    236                             int fractional_count, Vector<char> buffer,
    237                             int* length, int* decimal_point) {
    238   ASSERT(-128 <= exponent && exponent <= 0);
    239   // 'fractionals' is a fixed-point number, with binary point at bit
    240   // (-exponent). Inside the function the non-converted remainder of fractionals
    241   // is a fixed-point number, with binary point at bit 'point'.
    242   if (-exponent <= 64) {
    243     // One 64 bit number is sufficient.
    244     ASSERT(fractionals >> 56 == 0);
    245     int point = -exponent;
    246     for (int i = 0; i < fractional_count; ++i) {
    247       if (fractionals == 0) break;
    248       // Instead of multiplying by 10 we multiply by 5 and adjust the point
    249       // location. This way the fractionals variable will not overflow.
    250       // Invariant at the beginning of the loop: fractionals < 2^point.
    251       // Initially we have: point <= 64 and fractionals < 2^56
    252       // After each iteration the point is decremented by one.
    253       // Note that 5^3 = 125 < 128 = 2^7.
    254       // Therefore three iterations of this loop will not overflow fractionals
    255       // (even without the subtraction at the end of the loop body). At this
    256       // time point will satisfy point <= 61 and therefore fractionals < 2^point
    257       // and any further multiplication of fractionals by 5 will not overflow.
    258       fractionals *= 5;
    259       point--;
    260       int digit = static_cast<int>(fractionals >> point);
    261       buffer[*length] = '0' + digit;
    262       (*length)++;
    263       fractionals -= static_cast<uint64_t>(digit) << point;
    264     }
    265     // If the first bit after the point is set we have to round up.
    266     if (((fractionals >> (point - 1)) & 1) == 1) {
    267       RoundUp(buffer, length, decimal_point);
    268     }
    269   } else {  // We need 128 bits.
    270     ASSERT(64 < -exponent && -exponent <= 128);
    271     UInt128 fractionals128 = UInt128(fractionals, 0);
    272     fractionals128.Shift(-exponent - 64);
    273     int point = 128;
    274     for (int i = 0; i < fractional_count; ++i) {
    275       if (fractionals128.IsZero()) break;
    276       // As before: instead of multiplying by 10 we multiply by 5 and adjust the
    277       // point location.
    278       // This multiplication will not overflow for the same reasons as before.
    279       fractionals128.Multiply(5);
    280       point--;
    281       int digit = fractionals128.DivModPowerOf2(point);
    282       buffer[*length] = '0' + digit;
    283       (*length)++;
    284     }
    285     if (fractionals128.BitAt(point - 1) == 1) {
    286       RoundUp(buffer, length, decimal_point);
    287     }
    288   }
    289 }
    290 
    291 
    292 // Removes leading and trailing zeros.
    293 // If leading zeros are removed then the decimal point position is adjusted.
    294 static void TrimZeros(Vector<char> buffer, int* length, int* decimal_point) {
    295   while (*length > 0 && buffer[(*length) - 1] == '0') {
    296     (*length)--;
    297   }
    298   int first_non_zero = 0;
    299   while (first_non_zero < *length && buffer[first_non_zero] == '0') {
    300     first_non_zero++;
    301   }
    302   if (first_non_zero != 0) {
    303     for (int i = first_non_zero; i < *length; ++i) {
    304       buffer[i - first_non_zero] = buffer[i];
    305     }
    306     *length -= first_non_zero;
    307     *decimal_point -= first_non_zero;
    308   }
    309 }
    310 
    311 
    312 bool FastFixedDtoa(double v,
    313                    int fractional_count,
    314                    Vector<char> buffer,
    315                    int* length,
    316                    int* decimal_point) {
    317   const uint32_t kMaxUInt32 = 0xFFFFFFFF;
    318   uint64_t significand = Double(v).Significand();
    319   int exponent = Double(v).Exponent();
    320   // v = significand * 2^exponent (with significand a 53bit integer).
    321   // If the exponent is larger than 20 (i.e. we may have a 73bit number) then we
    322   // don't know how to compute the representation. 2^73 ~= 9.5*10^21.
    323   // If necessary this limit could probably be increased, but we don't need
    324   // more.
    325   if (exponent > 20) return false;
    326   if (fractional_count > 20) return false;
    327   *length = 0;
    328   // At most kDoubleSignificandSize bits of the significand are non-zero.
    329   // Given a 64 bit integer we have 11 0s followed by 53 potentially non-zero
    330   // bits:  0..11*..0xxx..53*..xx
    331   if (exponent + kDoubleSignificandSize > 64) {
    332     // The exponent must be > 11.
    333     //
    334     // We know that v = significand * 2^exponent.
    335     // And the exponent > 11.
    336     // We simplify the task by dividing v by 10^17.
    337     // The quotient delivers the first digits, and the remainder fits into a 64
    338     // bit number.
    339     // Dividing by 10^17 is equivalent to dividing by 5^17*2^17.
    340     const uint64_t kFive17 = V8_2PART_UINT64_C(0xB1, A2BC2EC5);  // 5^17
    341     uint64_t divisor = kFive17;
    342     int divisor_power = 17;
    343     uint64_t dividend = significand;
    344     uint32_t quotient;
    345     uint64_t remainder;
    346     // Let v = f * 2^e with f == significand and e == exponent.
    347     // Then need q (quotient) and r (remainder) as follows:
    348     //   v            = q * 10^17       + r
    349     //   f * 2^e      = q * 10^17       + r
    350     //   f * 2^e      = q * 5^17 * 2^17 + r
    351     // If e > 17 then
    352     //   f * 2^(e-17) = q * 5^17        + r/2^17
    353     // else
    354     //   f  = q * 5^17 * 2^(17-e) + r/2^e
    355     if (exponent > divisor_power) {
    356       // We only allow exponents of up to 20 and therefore (17 - e) <= 3
    357       dividend <<= exponent - divisor_power;
    358       quotient = static_cast<uint32_t>(dividend / divisor);
    359       remainder = (dividend % divisor) << divisor_power;
    360     } else {
    361       divisor <<= divisor_power - exponent;
    362       quotient = static_cast<uint32_t>(dividend / divisor);
    363       remainder = (dividend % divisor) << exponent;
    364     }
    365     FillDigits32(quotient, buffer, length);
    366     FillDigits64FixedLength(remainder, divisor_power, buffer, length);
    367     *decimal_point = *length;
    368   } else if (exponent >= 0) {
    369     // 0 <= exponent <= 11
    370     significand <<= exponent;
    371     FillDigits64(significand, buffer, length);
    372     *decimal_point = *length;
    373   } else if (exponent > -kDoubleSignificandSize) {
    374     // We have to cut the number.
    375     uint64_t integrals = significand >> -exponent;
    376     uint64_t fractionals = significand - (integrals << -exponent);
    377     if (integrals > kMaxUInt32) {
    378       FillDigits64(integrals, buffer, length);
    379     } else {
    380       FillDigits32(static_cast<uint32_t>(integrals), buffer, length);
    381     }
    382     *decimal_point = *length;
    383     FillFractionals(fractionals, exponent, fractional_count,
    384                     buffer, length, decimal_point);
    385   } else if (exponent < -128) {
    386     // This configuration (with at most 20 digits) means that all digits must be
    387     // 0.
    388     ASSERT(fractional_count <= 20);
    389     buffer[0] = '\0';
    390     *length = 0;
    391     *decimal_point = -fractional_count;
    392   } else {
    393     *decimal_point = 0;
    394     FillFractionals(significand, exponent, fractional_count,
    395                     buffer, length, decimal_point);
    396   }
    397   TrimZeros(buffer, length, decimal_point);
    398   buffer[*length] = '\0';
    399   if ((*length) == 0) {
    400     // The string is empty and the decimal_point thus has no importance. Mimick
    401     // Gay's dtoa and and set it to -fractional_count.
    402     *decimal_point = -fractional_count;
    403   }
    404   return true;
    405 }
    406 
    407 } }  // namespace v8::internal
    408