| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 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. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | 27 |
| 28 #include <math.h> | 28 #include <math.h> |
| 29 | 29 |
| 30 #include "fixed-dtoa.h" | 30 #include "fixed-dtoa.h" |
| 31 #include "double.h" | 31 #include "ieee.h" |
| 32 | 32 |
| 33 namespace double_conversion { | 33 namespace double_conversion { |
| 34 | 34 |
| 35 // Represents a 128bit type. This class should be replaced by a native type on | 35 // Represents a 128bit type. This class should be replaced by a native type on |
| 36 // platforms that support 128bit integers. | 36 // platforms that support 128bit integers. |
| 37 class UInt128 { | 37 class UInt128 { |
| 38 public: | 38 public: |
| 39 UInt128() : high_bits_(0), low_bits_(0) { } | 39 UInt128() : high_bits_(0), low_bits_(0) { } |
| 40 UInt128(uint64_t high, uint64_t low) : high_bits_(high), low_bits_(low) { } | 40 UInt128(uint64_t high, uint64_t low) : high_bits_(high), low_bits_(low) { } |
| 41 | 41 |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 126 *length += requested_length; | 126 *length += requested_length; |
| 127 } | 127 } |
| 128 | 128 |
| 129 | 129 |
| 130 static void FillDigits32(uint32_t number, Vector<char> buffer, int* length) { | 130 static void FillDigits32(uint32_t number, Vector<char> buffer, int* length) { |
| 131 int number_length = 0; | 131 int number_length = 0; |
| 132 // We fill the digits in reverse order and exchange them afterwards. | 132 // We fill the digits in reverse order and exchange them afterwards. |
| 133 while (number != 0) { | 133 while (number != 0) { |
| 134 int digit = number % 10; | 134 int digit = number % 10; |
| 135 number /= 10; | 135 number /= 10; |
| 136 buffer[(*length) + number_length] = '0' + digit; | 136 buffer[(*length) + number_length] = static_cast<char>('0' + digit); |
| 137 number_length++; | 137 number_length++; |
| 138 } | 138 } |
| 139 // Exchange the digits. | 139 // Exchange the digits. |
| 140 int i = *length; | 140 int i = *length; |
| 141 int j = *length + number_length - 1; | 141 int j = *length + number_length - 1; |
| 142 while (i < j) { | 142 while (i < j) { |
| 143 char tmp = buffer[i]; | 143 char tmp = buffer[i]; |
| 144 buffer[i] = buffer[j]; | 144 buffer[i] = buffer[j]; |
| 145 buffer[j] = tmp; | 145 buffer[j] = tmp; |
| 146 i++; | 146 i++; |
| 147 j--; | 147 j--; |
| 148 } | 148 } |
| 149 *length += number_length; | 149 *length += number_length; |
| 150 } | 150 } |
| 151 | 151 |
| 152 | 152 |
| 153 static void FillDigits64FixedLength(uint64_t number, int requested_length, | 153 static void FillDigits64FixedLength(uint64_t number, |
| 154 Vector<char> buffer, int* length) { | 154 Vector<char> buffer, int* length) { |
| 155 const uint32_t kTen7 = 10000000; | 155 const uint32_t kTen7 = 10000000; |
| 156 // For efficiency cut the number into 3 uint32_t parts, and print those. | 156 // For efficiency cut the number into 3 uint32_t parts, and print those. |
| 157 uint32_t part2 = static_cast<uint32_t>(number % kTen7); | 157 uint32_t part2 = static_cast<uint32_t>(number % kTen7); |
| 158 number /= kTen7; | 158 number /= kTen7; |
| 159 uint32_t part1 = static_cast<uint32_t>(number % kTen7); | 159 uint32_t part1 = static_cast<uint32_t>(number % kTen7); |
| 160 uint32_t part0 = static_cast<uint32_t>(number / kTen7); | 160 uint32_t part0 = static_cast<uint32_t>(number / kTen7); |
| 161 | 161 |
| 162 FillDigits32FixedLength(part0, 3, buffer, length); | 162 FillDigits32FixedLength(part0, 3, buffer, length); |
| 163 FillDigits32FixedLength(part1, 7, buffer, length); | 163 FillDigits32FixedLength(part1, 7, buffer, length); |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 246 // Initially we have: point <= 64 and fractionals < 2^56 | 246 // Initially we have: point <= 64 and fractionals < 2^56 |
| 247 // After each iteration the point is decremented by one. | 247 // After each iteration the point is decremented by one. |
| 248 // Note that 5^3 = 125 < 128 = 2^7. | 248 // Note that 5^3 = 125 < 128 = 2^7. |
| 249 // Therefore three iterations of this loop will not overflow fractionals | 249 // Therefore three iterations of this loop will not overflow fractionals |
| 250 // (even without the subtraction at the end of the loop body). At this | 250 // (even without the subtraction at the end of the loop body). At this |
| 251 // time point will satisfy point <= 61 and therefore fractionals < 2^point | 251 // time point will satisfy point <= 61 and therefore fractionals < 2^point |
| 252 // and any further multiplication of fractionals by 5 will not overflow. | 252 // and any further multiplication of fractionals by 5 will not overflow. |
| 253 fractionals *= 5; | 253 fractionals *= 5; |
| 254 point--; | 254 point--; |
| 255 int digit = static_cast<int>(fractionals >> point); | 255 int digit = static_cast<int>(fractionals >> point); |
| 256 buffer[*length] = '0' + digit; | 256 ASSERT(digit <= 9); |
| 257 buffer[*length] = static_cast<char>('0' + digit); |
| 257 (*length)++; | 258 (*length)++; |
| 258 fractionals -= static_cast<uint64_t>(digit) << point; | 259 fractionals -= static_cast<uint64_t>(digit) << point; |
| 259 } | 260 } |
| 260 // If the first bit after the point is set we have to round up. | 261 // If the first bit after the point is set we have to round up. |
| 261 if (((fractionals >> (point - 1)) & 1) == 1) { | 262 if (((fractionals >> (point - 1)) & 1) == 1) { |
| 262 RoundUp(buffer, length, decimal_point); | 263 RoundUp(buffer, length, decimal_point); |
| 263 } | 264 } |
| 264 } else { // We need 128 bits. | 265 } else { // We need 128 bits. |
| 265 ASSERT(64 < -exponent && -exponent <= 128); | 266 ASSERT(64 < -exponent && -exponent <= 128); |
| 266 UInt128 fractionals128 = UInt128(fractionals, 0); | 267 UInt128 fractionals128 = UInt128(fractionals, 0); |
| 267 fractionals128.Shift(-exponent - 64); | 268 fractionals128.Shift(-exponent - 64); |
| 268 int point = 128; | 269 int point = 128; |
| 269 for (int i = 0; i < fractional_count; ++i) { | 270 for (int i = 0; i < fractional_count; ++i) { |
| 270 if (fractionals128.IsZero()) break; | 271 if (fractionals128.IsZero()) break; |
| 271 // As before: instead of multiplying by 10 we multiply by 5 and adjust the | 272 // As before: instead of multiplying by 10 we multiply by 5 and adjust the |
| 272 // point location. | 273 // point location. |
| 273 // This multiplication will not overflow for the same reasons as before. | 274 // This multiplication will not overflow for the same reasons as before. |
| 274 fractionals128.Multiply(5); | 275 fractionals128.Multiply(5); |
| 275 point--; | 276 point--; |
| 276 int digit = fractionals128.DivModPowerOf2(point); | 277 int digit = fractionals128.DivModPowerOf2(point); |
| 277 buffer[*length] = '0' + digit; | 278 ASSERT(digit <= 9); |
| 279 buffer[*length] = static_cast<char>('0' + digit); |
| 278 (*length)++; | 280 (*length)++; |
| 279 } | 281 } |
| 280 if (fractionals128.BitAt(point - 1) == 1) { | 282 if (fractionals128.BitAt(point - 1) == 1) { |
| 281 RoundUp(buffer, length, decimal_point); | 283 RoundUp(buffer, length, decimal_point); |
| 282 } | 284 } |
| 283 } | 285 } |
| 284 } | 286 } |
| 285 | 287 |
| 286 | 288 |
| 287 // Removes leading and trailing zeros. | 289 // Removes leading and trailing zeros. |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 351 // We only allow exponents of up to 20 and therefore (17 - e) <= 3 | 353 // We only allow exponents of up to 20 and therefore (17 - e) <= 3 |
| 352 dividend <<= exponent - divisor_power; | 354 dividend <<= exponent - divisor_power; |
| 353 quotient = static_cast<uint32_t>(dividend / divisor); | 355 quotient = static_cast<uint32_t>(dividend / divisor); |
| 354 remainder = (dividend % divisor) << divisor_power; | 356 remainder = (dividend % divisor) << divisor_power; |
| 355 } else { | 357 } else { |
| 356 divisor <<= divisor_power - exponent; | 358 divisor <<= divisor_power - exponent; |
| 357 quotient = static_cast<uint32_t>(dividend / divisor); | 359 quotient = static_cast<uint32_t>(dividend / divisor); |
| 358 remainder = (dividend % divisor) << exponent; | 360 remainder = (dividend % divisor) << exponent; |
| 359 } | 361 } |
| 360 FillDigits32(quotient, buffer, length); | 362 FillDigits32(quotient, buffer, length); |
| 361 FillDigits64FixedLength(remainder, divisor_power, buffer, length); | 363 FillDigits64FixedLength(remainder, buffer, length); |
| 362 *decimal_point = *length; | 364 *decimal_point = *length; |
| 363 } else if (exponent >= 0) { | 365 } else if (exponent >= 0) { |
| 364 // 0 <= exponent <= 11 | 366 // 0 <= exponent <= 11 |
| 365 significand <<= exponent; | 367 significand <<= exponent; |
| 366 FillDigits64(significand, buffer, length); | 368 FillDigits64(significand, buffer, length); |
| 367 *decimal_point = *length; | 369 *decimal_point = *length; |
| 368 } else if (exponent > -kDoubleSignificandSize) { | 370 } else if (exponent > -kDoubleSignificandSize) { |
| 369 // We have to cut the number. | 371 // We have to cut the number. |
| 370 uint64_t integrals = significand >> -exponent; | 372 uint64_t integrals = significand >> -exponent; |
| 371 uint64_t fractionals = significand - (integrals << -exponent); | 373 uint64_t fractionals = significand - (integrals << -exponent); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 393 buffer[*length] = '\0'; | 395 buffer[*length] = '\0'; |
| 394 if ((*length) == 0) { | 396 if ((*length) == 0) { |
| 395 // The string is empty and the decimal_point thus has no importance. Mimick | 397 // The string is empty and the decimal_point thus has no importance. Mimick |
| 396 // Gay's dtoa and and set it to -fractional_count. | 398 // Gay's dtoa and and set it to -fractional_count. |
| 397 *decimal_point = -fractional_count; | 399 *decimal_point = -fractional_count; |
| 398 } | 400 } |
| 399 return true; | 401 return true; |
| 400 } | 402 } |
| 401 | 403 |
| 402 } // namespace double_conversion | 404 } // namespace double_conversion |
| OLD | NEW |