mirror of
https://github.com/pocoproject/poco.git
synced 2025-10-25 02:06:04 +02:00
GH #1538: update double-conversion to v1.1.5
This commit is contained in:
@@ -192,13 +192,13 @@ static void GenerateShortestDigits(Bignum* numerator, Bignum* denominator,
|
|||||||
delta_plus = delta_minus;
|
delta_plus = delta_minus;
|
||||||
}
|
}
|
||||||
*length = 0;
|
*length = 0;
|
||||||
while (true) {
|
for (;;) {
|
||||||
uint16_t digit;
|
uint16_t digit;
|
||||||
digit = numerator->DivideModuloIntBignum(*denominator);
|
digit = numerator->DivideModuloIntBignum(*denominator);
|
||||||
ASSERT(digit <= 9); // digit is a uint16_t and therefore always positive.
|
ASSERT(digit <= 9); // digit is a uint16_t and therefore always positive.
|
||||||
// digit = numerator / denominator (integer division).
|
// digit = numerator / denominator (integer division).
|
||||||
// numerator = numerator % denominator.
|
// numerator = numerator % denominator.
|
||||||
buffer[(*length)++] = digit + '0';
|
buffer[(*length)++] = static_cast<char>(digit + '0');
|
||||||
|
|
||||||
// Can we stop already?
|
// Can we stop already?
|
||||||
// If the remainder of the division is less than the distance to the lower
|
// If the remainder of the division is less than the distance to the lower
|
||||||
@@ -282,7 +282,7 @@ static void GenerateShortestDigits(Bignum* numerator, Bignum* denominator,
|
|||||||
// exponent (decimal_point), when rounding upwards.
|
// exponent (decimal_point), when rounding upwards.
|
||||||
static void GenerateCountedDigits(int count, int* decimal_point,
|
static void GenerateCountedDigits(int count, int* decimal_point,
|
||||||
Bignum* numerator, Bignum* denominator,
|
Bignum* numerator, Bignum* denominator,
|
||||||
Vector<char>(buffer), int* length) {
|
Vector<char> buffer, int* length) {
|
||||||
ASSERT(count >= 0);
|
ASSERT(count >= 0);
|
||||||
for (int i = 0; i < count - 1; ++i) {
|
for (int i = 0; i < count - 1; ++i) {
|
||||||
uint16_t digit;
|
uint16_t digit;
|
||||||
@@ -290,7 +290,7 @@ static void GenerateCountedDigits(int count, int* decimal_point,
|
|||||||
ASSERT(digit <= 9); // digit is a uint16_t and therefore always positive.
|
ASSERT(digit <= 9); // digit is a uint16_t and therefore always positive.
|
||||||
// digit = numerator / denominator (integer division).
|
// digit = numerator / denominator (integer division).
|
||||||
// numerator = numerator % denominator.
|
// numerator = numerator % denominator.
|
||||||
buffer[i] = digit + '0';
|
buffer[i] = static_cast<char>(digit + '0');
|
||||||
// Prepare for next iteration.
|
// Prepare for next iteration.
|
||||||
numerator->Times10();
|
numerator->Times10();
|
||||||
}
|
}
|
||||||
@@ -300,7 +300,8 @@ static void GenerateCountedDigits(int count, int* decimal_point,
|
|||||||
if (Bignum::PlusCompare(*numerator, *numerator, *denominator) >= 0) {
|
if (Bignum::PlusCompare(*numerator, *numerator, *denominator) >= 0) {
|
||||||
digit++;
|
digit++;
|
||||||
}
|
}
|
||||||
buffer[count - 1] = digit + '0';
|
ASSERT(digit <= 10);
|
||||||
|
buffer[count - 1] = static_cast<char>(digit + '0');
|
||||||
// Correct bad digits (in case we had a sequence of '9's). Propagate the
|
// Correct bad digits (in case we had a sequence of '9's). Propagate the
|
||||||
// carry until we hat a non-'9' or til we reach the first digit.
|
// carry until we hat a non-'9' or til we reach the first digit.
|
||||||
for (int i = count - 1; i > 0; --i) {
|
for (int i = count - 1; i > 0; --i) {
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ Bignum::Bignum()
|
|||||||
|
|
||||||
template<typename S>
|
template<typename S>
|
||||||
static int BitSize(S value) {
|
static int BitSize(S value) {
|
||||||
|
(void) value; // Mark variable as used.
|
||||||
return 8 * sizeof(value);
|
return 8 * sizeof(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,9 +123,8 @@ void Bignum::AssignDecimalString(Vector<const char> value) {
|
|||||||
static int HexCharValue(char c) {
|
static int HexCharValue(char c) {
|
||||||
if ('0' <= c && c <= '9') return c - '0';
|
if ('0' <= c && c <= '9') return c - '0';
|
||||||
if ('a' <= c && c <= 'f') return 10 + c - 'a';
|
if ('a' <= c && c <= 'f') return 10 + c - 'a';
|
||||||
if ('A' <= c && c <= 'F') return 10 + c - 'A';
|
ASSERT('A' <= c && c <= 'F');
|
||||||
UNREACHABLE();
|
return 10 + c - 'A';
|
||||||
return 0; // To make compiler happy.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -501,13 +501,14 @@ uint16_t Bignum::DivideModuloIntBignum(const Bignum& other) {
|
|||||||
// Start by removing multiples of 'other' until both numbers have the same
|
// Start by removing multiples of 'other' until both numbers have the same
|
||||||
// number of digits.
|
// number of digits.
|
||||||
while (BigitLength() > other.BigitLength()) {
|
while (BigitLength() > other.BigitLength()) {
|
||||||
// This naive approach is extremely inefficient if the this divided other
|
// This naive approach is extremely inefficient if `this` divided by other
|
||||||
// might be big. This function is implemented for doubleToString where
|
// is big. This function is implemented for doubleToString where
|
||||||
// the result should be small (less than 10).
|
// the result should be small (less than 10).
|
||||||
ASSERT(other.bigits_[other.used_digits_ - 1] >= ((1 << kBigitSize) / 16));
|
ASSERT(other.bigits_[other.used_digits_ - 1] >= ((1 << kBigitSize) / 16));
|
||||||
|
ASSERT(bigits_[used_digits_ - 1] < 0x10000);
|
||||||
// Remove the multiples of the first digit.
|
// Remove the multiples of the first digit.
|
||||||
// Example this = 23 and other equals 9. -> Remove 2 multiples.
|
// Example this = 23 and other equals 9. -> Remove 2 multiples.
|
||||||
result += bigits_[used_digits_ - 1];
|
result += static_cast<uint16_t>(bigits_[used_digits_ - 1]);
|
||||||
SubtractTimes(other, bigits_[used_digits_ - 1]);
|
SubtractTimes(other, bigits_[used_digits_ - 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -523,13 +524,15 @@ uint16_t Bignum::DivideModuloIntBignum(const Bignum& other) {
|
|||||||
// Shortcut for easy (and common) case.
|
// Shortcut for easy (and common) case.
|
||||||
int quotient = this_bigit / other_bigit;
|
int quotient = this_bigit / other_bigit;
|
||||||
bigits_[used_digits_ - 1] = this_bigit - other_bigit * quotient;
|
bigits_[used_digits_ - 1] = this_bigit - other_bigit * quotient;
|
||||||
result += quotient;
|
ASSERT(quotient < 0x10000);
|
||||||
|
result += static_cast<uint16_t>(quotient);
|
||||||
Clamp();
|
Clamp();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int division_estimate = this_bigit / (other_bigit + 1);
|
int division_estimate = this_bigit / (other_bigit + 1);
|
||||||
result += division_estimate;
|
ASSERT(division_estimate < 0x10000);
|
||||||
|
result += static_cast<uint16_t>(division_estimate);
|
||||||
SubtractTimes(other, division_estimate);
|
SubtractTimes(other, division_estimate);
|
||||||
|
|
||||||
if (other_bigit * (division_estimate + 1) > this_bigit) {
|
if (other_bigit * (division_estimate + 1) > this_bigit) {
|
||||||
@@ -560,8 +563,8 @@ static int SizeInHexChars(S number) {
|
|||||||
|
|
||||||
static char HexCharOfValue(int value) {
|
static char HexCharOfValue(int value) {
|
||||||
ASSERT(0 <= value && value <= 16);
|
ASSERT(0 <= value && value <= 16);
|
||||||
if (value < 10) return value + '0';
|
if (value < 10) return static_cast<char>(value + '0');
|
||||||
return value - 10 + 'A';
|
return static_cast<char>(value - 10 + 'A');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -755,7 +758,6 @@ void Bignum::SubtractTimes(const Bignum& other, int factor) {
|
|||||||
Chunk difference = bigits_[i] - borrow;
|
Chunk difference = bigits_[i] - borrow;
|
||||||
bigits_[i] = difference & kBigitMask;
|
bigits_[i] = difference & kBigitMask;
|
||||||
borrow = difference >> (kChunkSize - 1);
|
borrow = difference >> (kChunkSize - 1);
|
||||||
++i;
|
|
||||||
}
|
}
|
||||||
Clamp();
|
Clamp();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -152,6 +152,7 @@ void PowersOfTenCache::GetCachedPowerForBinaryExponentRange(
|
|||||||
ASSERT(0 <= index && index < kCachedPowersLength);
|
ASSERT(0 <= index && index < kCachedPowersLength);
|
||||||
CachedPower cached_power = kCachedPowers[index];
|
CachedPower cached_power = kCachedPowers[index];
|
||||||
ASSERT(min_exponent <= cached_power.binary_exponent);
|
ASSERT(min_exponent <= cached_power.binary_exponent);
|
||||||
|
(void) max_exponent; // Mark variable as used.
|
||||||
ASSERT(cached_power.binary_exponent <= max_exponent);
|
ASSERT(cached_power.binary_exponent <= max_exponent);
|
||||||
*decimal_exponent = cached_power.decimal_exponent;
|
*decimal_exponent = cached_power.decimal_exponent;
|
||||||
*power = DiyFp(cached_power.significand, cached_power.binary_exponent);
|
*power = DiyFp(cached_power.significand, cached_power.binary_exponent);
|
||||||
|
|||||||
@@ -348,7 +348,6 @@ static BignumDtoaMode DtoaToBignumDtoaMode(
|
|||||||
case DoubleToStringConverter::PRECISION: return BIGNUM_DTOA_PRECISION;
|
case DoubleToStringConverter::PRECISION: return BIGNUM_DTOA_PRECISION;
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
return BIGNUM_DTOA_SHORTEST; // To silence compiler.
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -403,8 +402,8 @@ void DoubleToStringConverter::DoubleToAscii(double v,
|
|||||||
vector, length, point);
|
vector, length, point);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
|
||||||
fast_worked = false;
|
fast_worked = false;
|
||||||
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
if (fast_worked) return;
|
if (fast_worked) return;
|
||||||
|
|
||||||
@@ -462,6 +461,28 @@ static double SignedZero(bool sign) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Returns true if 'c' is a decimal digit that is valid for the given radix.
|
||||||
|
//
|
||||||
|
// The function is small and could be inlined, but VS2012 emitted a warning
|
||||||
|
// because it constant-propagated the radix and concluded that the last
|
||||||
|
// condition was always true. By moving it into a separate function the
|
||||||
|
// compiler wouldn't warn anymore.
|
||||||
|
static bool IsDecimalDigitForRadix(int c, int radix) {
|
||||||
|
return '0' <= c && c <= '9' && (c - '0') < radix;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns true if 'c' is a character digit that is valid for the given radix.
|
||||||
|
// The 'a_character' should be 'a' or 'A'.
|
||||||
|
//
|
||||||
|
// The function is small and could be inlined, but VS2012 emitted a warning
|
||||||
|
// because it constant-propagated the radix and concluded that the first
|
||||||
|
// condition was always false. By moving it into a separate function the
|
||||||
|
// compiler wouldn't warn anymore.
|
||||||
|
static bool IsCharacterDigitForRadix(int c, int radix, char a_character) {
|
||||||
|
return radix > 10 && c >= a_character && c < a_character + radix - 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Parsing integers with radix 2, 4, 8, 16, 32. Assumes current != end.
|
// Parsing integers with radix 2, 4, 8, 16, 32. Assumes current != end.
|
||||||
template <int radix_log_2>
|
template <int radix_log_2>
|
||||||
static double RadixStringToIeee(const char* current,
|
static double RadixStringToIeee(const char* current,
|
||||||
@@ -492,11 +513,11 @@ static double RadixStringToIeee(const char* current,
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
int digit;
|
int digit;
|
||||||
if (*current >= '0' && *current <= '9' && *current < '0' + radix) {
|
if (IsDecimalDigitForRadix(*current, radix)) {
|
||||||
digit = static_cast<char>(*current) - '0';
|
digit = static_cast<char>(*current) - '0';
|
||||||
} else if (radix > 10 && *current >= 'a' && *current < 'a' + radix - 10) {
|
} else if (IsCharacterDigitForRadix(*current, radix, 'a')) {
|
||||||
digit = static_cast<char>(*current) - 'a' + 10;
|
digit = static_cast<char>(*current) - 'a' + 10;
|
||||||
} else if (radix > 10 && *current >= 'A' && *current < 'A' + radix - 10) {
|
} else if (IsCharacterDigitForRadix(*current, radix, 'A')) {
|
||||||
digit = static_cast<char>(*current) - 'A' + 10;
|
digit = static_cast<char>(*current) - 'A' + 10;
|
||||||
} else {
|
} else {
|
||||||
if (allow_trailing_junk || !AdvanceToNonspace(¤t, end)) {
|
if (allow_trailing_junk || !AdvanceToNonspace(¤t, end)) {
|
||||||
@@ -523,7 +544,7 @@ static double RadixStringToIeee(const char* current,
|
|||||||
exponent = overflow_bits_count;
|
exponent = overflow_bits_count;
|
||||||
|
|
||||||
bool zero_tail = true;
|
bool zero_tail = true;
|
||||||
while (true) {
|
for (;;) {
|
||||||
++current;
|
++current;
|
||||||
if (current == end || !isDigit(*current, radix)) break;
|
if (current == end || !isDigit(*current, radix)) break;
|
||||||
zero_tail = zero_tail && *current == '0';
|
zero_tail = zero_tail && *current == '0';
|
||||||
@@ -577,7 +598,7 @@ double StringToDoubleConverter::StringToIeee(
|
|||||||
const char* input,
|
const char* input,
|
||||||
int length,
|
int length,
|
||||||
int* processed_characters_count,
|
int* processed_characters_count,
|
||||||
bool read_as_double) {
|
bool read_as_double) const {
|
||||||
const char* current = input;
|
const char* current = input;
|
||||||
const char* end = input + length;
|
const char* end = input + length;
|
||||||
|
|
||||||
@@ -600,7 +621,7 @@ double StringToDoubleConverter::StringToIeee(
|
|||||||
|
|
||||||
if (allow_leading_spaces || allow_trailing_spaces) {
|
if (allow_leading_spaces || allow_trailing_spaces) {
|
||||||
if (!AdvanceToNonspace(¤t, end)) {
|
if (!AdvanceToNonspace(¤t, end)) {
|
||||||
*processed_characters_count = current - input;
|
*processed_characters_count = static_cast<int>(current - input);
|
||||||
return empty_string_value_;
|
return empty_string_value_;
|
||||||
}
|
}
|
||||||
if (!allow_leading_spaces && (input != current)) {
|
if (!allow_leading_spaces && (input != current)) {
|
||||||
@@ -649,7 +670,7 @@ double StringToDoubleConverter::StringToIeee(
|
|||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(buffer_pos == 0);
|
ASSERT(buffer_pos == 0);
|
||||||
*processed_characters_count = current - input;
|
*processed_characters_count = static_cast<int>(current - input);
|
||||||
return sign ? -Double::Infinity() : Double::Infinity();
|
return sign ? -Double::Infinity() : Double::Infinity();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -668,7 +689,7 @@ double StringToDoubleConverter::StringToIeee(
|
|||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(buffer_pos == 0);
|
ASSERT(buffer_pos == 0);
|
||||||
*processed_characters_count = current - input;
|
*processed_characters_count = static_cast<int>(current - input);
|
||||||
return sign ? -Double::NaN() : Double::NaN();
|
return sign ? -Double::NaN() : Double::NaN();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -677,7 +698,7 @@ double StringToDoubleConverter::StringToIeee(
|
|||||||
if (*current == '0') {
|
if (*current == '0') {
|
||||||
++current;
|
++current;
|
||||||
if (current == end) {
|
if (current == end) {
|
||||||
*processed_characters_count = current - input;
|
*processed_characters_count = static_cast<int>(current - input);
|
||||||
return SignedZero(sign);
|
return SignedZero(sign);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -700,7 +721,7 @@ double StringToDoubleConverter::StringToIeee(
|
|||||||
&tail_pointer);
|
&tail_pointer);
|
||||||
if (tail_pointer != NULL) {
|
if (tail_pointer != NULL) {
|
||||||
if (allow_trailing_spaces) AdvanceToNonspace(&tail_pointer, end);
|
if (allow_trailing_spaces) AdvanceToNonspace(&tail_pointer, end);
|
||||||
*processed_characters_count = tail_pointer - input;
|
*processed_characters_count = static_cast<int>(tail_pointer - input);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -709,7 +730,7 @@ double StringToDoubleConverter::StringToIeee(
|
|||||||
while (*current == '0') {
|
while (*current == '0') {
|
||||||
++current;
|
++current;
|
||||||
if (current == end) {
|
if (current == end) {
|
||||||
*processed_characters_count = current - input;
|
*processed_characters_count = static_cast<int>(current - input);
|
||||||
return SignedZero(sign);
|
return SignedZero(sign);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -757,7 +778,7 @@ double StringToDoubleConverter::StringToIeee(
|
|||||||
while (*current == '0') {
|
while (*current == '0') {
|
||||||
++current;
|
++current;
|
||||||
if (current == end) {
|
if (current == end) {
|
||||||
*processed_characters_count = current - input;
|
*processed_characters_count = static_cast<int>(current - input);
|
||||||
return SignedZero(sign);
|
return SignedZero(sign);
|
||||||
}
|
}
|
||||||
exponent--; // Move this 0 into the exponent.
|
exponent--; // Move this 0 into the exponent.
|
||||||
@@ -864,7 +885,7 @@ double StringToDoubleConverter::StringToIeee(
|
|||||||
read_as_double,
|
read_as_double,
|
||||||
&tail_pointer);
|
&tail_pointer);
|
||||||
ASSERT(tail_pointer != NULL);
|
ASSERT(tail_pointer != NULL);
|
||||||
*processed_characters_count = current - input;
|
*processed_characters_count = static_cast<int>(current - input);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -882,7 +903,7 @@ double StringToDoubleConverter::StringToIeee(
|
|||||||
} else {
|
} else {
|
||||||
converted = Strtof(Vector<const char>(buffer, buffer_pos), exponent);
|
converted = Strtof(Vector<const char>(buffer, buffer_pos), exponent);
|
||||||
}
|
}
|
||||||
*processed_characters_count = current - input;
|
*processed_characters_count = static_cast<int>(current - input);
|
||||||
return sign? -converted: converted;
|
return sign? -converted: converted;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -502,7 +502,7 @@ class StringToDoubleConverter {
|
|||||||
// in the 'processed_characters_count'. Trailing junk is never included.
|
// in the 'processed_characters_count'. Trailing junk is never included.
|
||||||
double StringToDouble(const char* buffer,
|
double StringToDouble(const char* buffer,
|
||||||
int length,
|
int length,
|
||||||
int* processed_characters_count) {
|
int* processed_characters_count) const {
|
||||||
return StringToIeee(buffer, length, processed_characters_count, true);
|
return StringToIeee(buffer, length, processed_characters_count, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -511,7 +511,7 @@ class StringToDoubleConverter {
|
|||||||
// due to potential double-rounding.
|
// due to potential double-rounding.
|
||||||
float StringToFloat(const char* buffer,
|
float StringToFloat(const char* buffer,
|
||||||
int length,
|
int length,
|
||||||
int* processed_characters_count) {
|
int* processed_characters_count) const {
|
||||||
return static_cast<float>(StringToIeee(buffer, length,
|
return static_cast<float>(StringToIeee(buffer, length,
|
||||||
processed_characters_count, false));
|
processed_characters_count, false));
|
||||||
}
|
}
|
||||||
@@ -526,7 +526,7 @@ class StringToDoubleConverter {
|
|||||||
double StringToIeee(const char* buffer,
|
double StringToIeee(const char* buffer,
|
||||||
int length,
|
int length,
|
||||||
int* processed_characters_count,
|
int* processed_characters_count,
|
||||||
bool read_as_double);
|
bool read_as_double) const;
|
||||||
|
|
||||||
DISALLOW_IMPLICIT_CONSTRUCTORS(StringToDoubleConverter);
|
DISALLOW_IMPLICIT_CONSTRUCTORS(StringToDoubleConverter);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -248,10 +248,7 @@ static void BiggestPowerTen(uint32_t number,
|
|||||||
// Note: kPowersOf10[i] == 10^(i-1).
|
// Note: kPowersOf10[i] == 10^(i-1).
|
||||||
exponent_plus_one_guess++;
|
exponent_plus_one_guess++;
|
||||||
// We don't have any guarantees that 2^number_bits <= number.
|
// We don't have any guarantees that 2^number_bits <= number.
|
||||||
// TODO(floitsch): can we change the 'while' into an 'if'? We definitely see
|
if (number < kSmallPowersOfTen[exponent_plus_one_guess]) {
|
||||||
// number < (2^number_bits - 1), but I haven't encountered
|
|
||||||
// number < (2^number_bits - 2) yet.
|
|
||||||
while (number < kSmallPowersOfTen[exponent_plus_one_guess]) {
|
|
||||||
exponent_plus_one_guess--;
|
exponent_plus_one_guess--;
|
||||||
}
|
}
|
||||||
*power = kSmallPowersOfTen[exponent_plus_one_guess];
|
*power = kSmallPowersOfTen[exponent_plus_one_guess];
|
||||||
@@ -350,7 +347,8 @@ static bool DigitGen(DiyFp low,
|
|||||||
// that is smaller than integrals.
|
// that is smaller than integrals.
|
||||||
while (*kappa > 0) {
|
while (*kappa > 0) {
|
||||||
int digit = integrals / divisor;
|
int digit = integrals / divisor;
|
||||||
buffer[*length] = '0' + digit;
|
ASSERT(digit <= 9);
|
||||||
|
buffer[*length] = static_cast<char>('0' + digit);
|
||||||
(*length)++;
|
(*length)++;
|
||||||
integrals %= divisor;
|
integrals %= divisor;
|
||||||
(*kappa)--;
|
(*kappa)--;
|
||||||
@@ -379,13 +377,14 @@ static bool DigitGen(DiyFp low,
|
|||||||
ASSERT(one.e() >= -60);
|
ASSERT(one.e() >= -60);
|
||||||
ASSERT(fractionals < one.f());
|
ASSERT(fractionals < one.f());
|
||||||
ASSERT(UINT64_2PART_C(0xFFFFFFFF, FFFFFFFF) / 10 >= one.f());
|
ASSERT(UINT64_2PART_C(0xFFFFFFFF, FFFFFFFF) / 10 >= one.f());
|
||||||
while (true) {
|
for (;;) {
|
||||||
fractionals *= 10;
|
fractionals *= 10;
|
||||||
unit *= 10;
|
unit *= 10;
|
||||||
unsafe_interval.set_f(unsafe_interval.f() * 10);
|
unsafe_interval.set_f(unsafe_interval.f() * 10);
|
||||||
// Integer division by one.
|
// Integer division by one.
|
||||||
int digit = static_cast<int>(fractionals >> -one.e());
|
int digit = static_cast<int>(fractionals >> -one.e());
|
||||||
buffer[*length] = '0' + digit;
|
ASSERT(digit <= 9);
|
||||||
|
buffer[*length] = static_cast<char>('0' + digit);
|
||||||
(*length)++;
|
(*length)++;
|
||||||
fractionals &= one.f() - 1; // Modulo by one.
|
fractionals &= one.f() - 1; // Modulo by one.
|
||||||
(*kappa)--;
|
(*kappa)--;
|
||||||
@@ -459,7 +458,8 @@ static bool DigitGenCounted(DiyFp w,
|
|||||||
// that is smaller than 'integrals'.
|
// that is smaller than 'integrals'.
|
||||||
while (*kappa > 0) {
|
while (*kappa > 0) {
|
||||||
int digit = integrals / divisor;
|
int digit = integrals / divisor;
|
||||||
buffer[*length] = '0' + digit;
|
ASSERT(digit <= 9);
|
||||||
|
buffer[*length] = static_cast<char>('0' + digit);
|
||||||
(*length)++;
|
(*length)++;
|
||||||
requested_digits--;
|
requested_digits--;
|
||||||
integrals %= divisor;
|
integrals %= divisor;
|
||||||
@@ -492,7 +492,8 @@ static bool DigitGenCounted(DiyFp w,
|
|||||||
w_error *= 10;
|
w_error *= 10;
|
||||||
// Integer division by one.
|
// Integer division by one.
|
||||||
int digit = static_cast<int>(fractionals >> -one.e());
|
int digit = static_cast<int>(fractionals >> -one.e());
|
||||||
buffer[*length] = '0' + digit;
|
ASSERT(digit <= 9);
|
||||||
|
buffer[*length] = static_cast<char>('0' + digit);
|
||||||
(*length)++;
|
(*length)++;
|
||||||
requested_digits--;
|
requested_digits--;
|
||||||
fractionals &= one.f() - 1; // Modulo by one.
|
fractionals &= one.f() - 1; // Modulo by one.
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ static void FillDigits32(uint32_t number, Vector<char> buffer, int* length) {
|
|||||||
while (number != 0) {
|
while (number != 0) {
|
||||||
int digit = number % 10;
|
int digit = number % 10;
|
||||||
number /= 10;
|
number /= 10;
|
||||||
buffer[(*length) + number_length] = '0' + digit;
|
buffer[(*length) + number_length] = static_cast<char>('0' + digit);
|
||||||
number_length++;
|
number_length++;
|
||||||
}
|
}
|
||||||
// Exchange the digits.
|
// Exchange the digits.
|
||||||
@@ -150,7 +150,7 @@ static void FillDigits32(uint32_t number, Vector<char> buffer, int* length) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void FillDigits64FixedLength(uint64_t number, int requested_length,
|
static void FillDigits64FixedLength(uint64_t number,
|
||||||
Vector<char> buffer, int* length) {
|
Vector<char> buffer, int* length) {
|
||||||
const uint32_t kTen7 = 10000000;
|
const uint32_t kTen7 = 10000000;
|
||||||
// For efficiency cut the number into 3 uint32_t parts, and print those.
|
// For efficiency cut the number into 3 uint32_t parts, and print those.
|
||||||
@@ -253,7 +253,8 @@ static void FillFractionals(uint64_t fractionals, int exponent,
|
|||||||
fractionals *= 5;
|
fractionals *= 5;
|
||||||
point--;
|
point--;
|
||||||
int digit = static_cast<int>(fractionals >> point);
|
int digit = static_cast<int>(fractionals >> point);
|
||||||
buffer[*length] = '0' + digit;
|
ASSERT(digit <= 9);
|
||||||
|
buffer[*length] = static_cast<char>('0' + digit);
|
||||||
(*length)++;
|
(*length)++;
|
||||||
fractionals -= static_cast<uint64_t>(digit) << point;
|
fractionals -= static_cast<uint64_t>(digit) << point;
|
||||||
}
|
}
|
||||||
@@ -274,7 +275,8 @@ static void FillFractionals(uint64_t fractionals, int exponent,
|
|||||||
fractionals128.Multiply(5);
|
fractionals128.Multiply(5);
|
||||||
point--;
|
point--;
|
||||||
int digit = fractionals128.DivModPowerOf2(point);
|
int digit = fractionals128.DivModPowerOf2(point);
|
||||||
buffer[*length] = '0' + digit;
|
ASSERT(digit <= 9);
|
||||||
|
buffer[*length] = static_cast<char>('0' + digit);
|
||||||
(*length)++;
|
(*length)++;
|
||||||
}
|
}
|
||||||
if (fractionals128.BitAt(point - 1) == 1) {
|
if (fractionals128.BitAt(point - 1) == 1) {
|
||||||
@@ -358,7 +360,7 @@ bool FastFixedDtoa(double v,
|
|||||||
remainder = (dividend % divisor) << exponent;
|
remainder = (dividend % divisor) << exponent;
|
||||||
}
|
}
|
||||||
FillDigits32(quotient, buffer, length);
|
FillDigits32(quotient, buffer, length);
|
||||||
FillDigits64FixedLength(remainder, divisor_power, buffer, length);
|
FillDigits64FixedLength(remainder, buffer, length);
|
||||||
*decimal_point = *length;
|
*decimal_point = *length;
|
||||||
} else if (exponent >= 0) {
|
} else if (exponent >= 0) {
|
||||||
// 0 <= exponent <= 11
|
// 0 <= exponent <= 11
|
||||||
|
|||||||
@@ -256,6 +256,8 @@ class Double {
|
|||||||
return (significand & kSignificandMask) |
|
return (significand & kSignificandMask) |
|
||||||
(biased_exponent << kPhysicalSignificandSize);
|
(biased_exponent << kPhysicalSignificandSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(Double);
|
||||||
};
|
};
|
||||||
|
|
||||||
class Single {
|
class Single {
|
||||||
@@ -391,6 +393,8 @@ class Single {
|
|||||||
static const uint32_t kNaN = 0x7FC00000;
|
static const uint32_t kNaN = 0x7FC00000;
|
||||||
|
|
||||||
const uint32_t d32_;
|
const uint32_t d32_;
|
||||||
|
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(Single);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace double_conversion
|
} // namespace double_conversion
|
||||||
|
|||||||
@@ -137,6 +137,7 @@ static void TrimAndCut(Vector<const char> buffer, int exponent,
|
|||||||
Vector<const char> right_trimmed = TrimTrailingZeros(left_trimmed);
|
Vector<const char> right_trimmed = TrimTrailingZeros(left_trimmed);
|
||||||
exponent += left_trimmed.length() - right_trimmed.length();
|
exponent += left_trimmed.length() - right_trimmed.length();
|
||||||
if (right_trimmed.length() > kMaxSignificantDecimalDigits) {
|
if (right_trimmed.length() > kMaxSignificantDecimalDigits) {
|
||||||
|
(void) space_size; // Mark variable as used.
|
||||||
ASSERT(space_size >= kMaxSignificantDecimalDigits);
|
ASSERT(space_size >= kMaxSignificantDecimalDigits);
|
||||||
CutToMaxSignificantDigits(right_trimmed, exponent,
|
CutToMaxSignificantDigits(right_trimmed, exponent,
|
||||||
buffer_copy_space, updated_exponent);
|
buffer_copy_space, updated_exponent);
|
||||||
@@ -515,6 +516,7 @@ float Strtof(Vector<const char> buffer, int exponent) {
|
|||||||
double double_next2 = Double(double_next).NextDouble();
|
double double_next2 = Double(double_next).NextDouble();
|
||||||
f4 = static_cast<float>(double_next2);
|
f4 = static_cast<float>(double_next2);
|
||||||
}
|
}
|
||||||
|
(void) f2; // Mark variable as used.
|
||||||
ASSERT(f1 <= f2 && f2 <= f3 && f3 <= f4);
|
ASSERT(f1 <= f2 && f2 <= f3 && f3 <= f4);
|
||||||
|
|
||||||
// If the guess doesn't lie near a single-precision boundary we can simply
|
// If the guess doesn't lie near a single-precision boundary we can simply
|
||||||
|
|||||||
@@ -33,7 +33,8 @@
|
|||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#ifndef ASSERT
|
#ifndef ASSERT
|
||||||
#define ASSERT(condition) (assert(condition))
|
#define ASSERT(condition) \
|
||||||
|
assert(condition);
|
||||||
#endif
|
#endif
|
||||||
#ifndef UNIMPLEMENTED
|
#ifndef UNIMPLEMENTED
|
||||||
#define UNIMPLEMENTED() (abort())
|
#define UNIMPLEMENTED() (abort())
|
||||||
@@ -56,7 +57,8 @@
|
|||||||
defined(__ARMEL__) || defined(_M_ARM) || defined(__arm__) || defined(__arm64__) || \
|
defined(__ARMEL__) || defined(_M_ARM) || defined(__arm__) || defined(__arm64__) || \
|
||||||
defined(__avr32__) || \
|
defined(__avr32__) || \
|
||||||
defined(__hppa__) || defined(__ia64__) || \
|
defined(__hppa__) || defined(__ia64__) || \
|
||||||
defined(__mips__) || defined(__powerpc__) || \
|
defined(__mips__) || \
|
||||||
|
defined(__powerpc__) || defined(__ppc__) || defined(__ppc64__) || \
|
||||||
defined(__sparc__) || defined(__sparc) || defined(__s390__) || \
|
defined(__sparc__) || defined(__sparc) || defined(__s390__) || \
|
||||||
defined(__SH4__) || defined(__alpha__) || \
|
defined(__SH4__) || defined(__alpha__) || \
|
||||||
defined(_MIPS_ARCH_MIPS32R2) || \
|
defined(_MIPS_ARCH_MIPS32R2) || \
|
||||||
@@ -74,6 +76,11 @@
|
|||||||
#error Target architecture was not detected as supported by Double-Conversion.
|
#error Target architecture was not detected as supported by Double-Conversion.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
#define DOUBLE_CONVERSION_UNUSED __attribute__((unused))
|
||||||
|
#else
|
||||||
|
#define DOUBLE_CONVERSION_UNUSED
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(_WIN32) && !defined(__MINGW32__)
|
#if defined(_WIN32) && !defined(__MINGW32__)
|
||||||
|
|
||||||
@@ -299,7 +306,8 @@ template <class Dest, class Source>
|
|||||||
inline Dest BitCast(const Source& source) {
|
inline Dest BitCast(const Source& source) {
|
||||||
// Compile time assertion: sizeof(Dest) == sizeof(Source)
|
// Compile time assertion: sizeof(Dest) == sizeof(Source)
|
||||||
// A compile error here means your Dest and Source have different sizes.
|
// A compile error here means your Dest and Source have different sizes.
|
||||||
typedef char VerifySizesAreEqual[sizeof(Dest) == sizeof(Source) ? 1 : -1];
|
DOUBLE_CONVERSION_UNUSED
|
||||||
|
typedef char VerifySizesAreEqual[sizeof(Dest) == sizeof(Source) ? 1 : -1];
|
||||||
|
|
||||||
Dest dest;
|
Dest dest;
|
||||||
memmove(&dest, &source, sizeof(dest));
|
memmove(&dest, &source, sizeof(dest));
|
||||||
|
|||||||
Reference in New Issue
Block a user