Quellcode durchsuchen

Update double-conversion to latest master

return-trailer
Paul J. Davis vor 9 Jahren
Ursprung
Commit
5d6b2651c9
21 geänderte Dateien mit 315 neuen und 161 gelöschten Zeilen
  1. +2
    -0
      c_src/double-conversion/AUTHORS
  2. +0
    -3
      c_src/double-conversion/DOWNLOADED
  3. +44
    -1
      c_src/double-conversion/README
  4. +2
    -0
      c_src/double-conversion/VERSION
  5. +6
    -5
      c_src/double-conversion/bignum-dtoa.cc
  6. +1
    -1
      c_src/double-conversion/bignum-dtoa.h
  7. +16
    -14
      c_src/double-conversion/bignum.cc
  8. +1
    -2
      c_src/double-conversion/bignum.h
  9. +2
    -1
      c_src/double-conversion/cached-powers.cc
  10. +2
    -2
      c_src/double-conversion/diy-fp.cc
  11. +12
    -12
      c_src/double-conversion/diy-fp.h
  12. +157
    -64
      c_src/double-conversion/double-conversion.cc
  13. +21
    -14
      c_src/double-conversion/double-conversion.h
  14. +10
    -11
      c_src/double-conversion/fast-dtoa.cc
  15. +1
    -1
      c_src/double-conversion/fast-dtoa.h
  16. +7
    -5
      c_src/double-conversion/fixed-dtoa.cc
  17. +1
    -1
      c_src/double-conversion/fixed-dtoa.h
  18. +4
    -0
      c_src/double-conversion/ieee.h
  19. +3
    -2
      c_src/double-conversion/strtod.cc
  20. +1
    -1
      c_src/double-conversion/strtod.h
  21. +22
    -21
      c_src/double-conversion/utils.h

+ 2
- 0
c_src/double-conversion/AUTHORS Datei anzeigen

@ -10,3 +10,5 @@ Mozilla Foundation
Jeff Muizelaar <jmuizelaar@mozilla.com>
Mike Hommey <mhommey@mozilla.com>
Martin Olsson <mnemo@minimum.se>
Kent Williams <chaircrusher@gmail.com>
Elan Ruusamäe <glen@delfi.ee>

+ 0
- 3
c_src/double-conversion/DOWNLOADED Datei anzeigen

@ -1,3 +0,0 @@
Downloaded: 2013-02-24
https://double-conversion.googlecode.com/files/double-conversion-1.1.1.tar.gz

+ 44
- 1
c_src/double-conversion/README Datei anzeigen

@ -1,4 +1,4 @@
http://code.google.com/p/double-conversion
https://github.com/google/double-conversion/
This project (double-conversion) provides binary-decimal and decimal-binary
routines for IEEE doubles.
@ -9,3 +9,46 @@ it can be used more easily in other projects.
There is extensive documentation in src/double-conversion.h. Other examples can
be found in test/cctest/test-conversions.cc.
Building
========
This library can be built with scons [0] or cmake [1].
The checked-in Makefile simply forwards to scons, and provides a
shortcut to run all tests:
make
make test
Scons
-----
The easiest way to install this library is to use `scons`. It builds
the static and shared library, and is set up to install those at the
correct locations:
scons install
Use the `DESTDIR` option to change the target directory:
scons DESTDIR=alternative_directory install
Cmake
-----
To use cmake run `cmake .` in the root directory. This overwrites the
existing Makefile.
Use `-DBUILD_SHARED_LIBS=ON` to enable the compilation of shared libraries.
Note that this disables static libraries. There is currently no way to
build both libraries at the same time with cmake.
Use `-DBUILD_TESTING=ON` to build the test executable.
cmake . -DBUILD_TESTING=ON
make
test/cctest/cctest --list | tr -d '<' | xargs test/cctest/cctest
[0]: http://www.scons.org
[1]: http://www.cmake.org

+ 2
- 0
c_src/double-conversion/VERSION Datei anzeigen

@ -0,0 +1,2 @@
Clone from: https://github.com/google/double-conversion
Version: v2.0.1-23-gc3e0c97

+ 6
- 5
c_src/double-conversion/bignum-dtoa.cc Datei anzeigen

@ -192,13 +192,13 @@ static void GenerateShortestDigits(Bignum* numerator, Bignum* denominator,
delta_plus = delta_minus;
}
*length = 0;
while (true) {
for (;;) {
uint16_t digit;
digit = numerator->DivideModuloIntBignum(*denominator);
ASSERT(digit <= 9); // digit is a uint16_t and therefore always positive.
// digit = numerator / denominator (integer division).
// numerator = numerator % denominator.
buffer[(*length)++] = digit + '0';
buffer[(*length)++] = static_cast<char>(digit + '0');
// Can we stop already?
// 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.
static void GenerateCountedDigits(int count, int* decimal_point,
Bignum* numerator, Bignum* denominator,
Vector<char> class="p">(buffer), int* length) {
Vector<char> buffer, int* length) {
ASSERT(count >= 0);
for (int i = 0; i < count - 1; ++i) {
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.
// digit = numerator / denominator (integer division).
// numerator = numerator % denominator.
buffer[i] = digit + '0';
buffer[i] = static_cast<char>(digit + '0');
// Prepare for next iteration.
numerator->Times10();
}
@ -300,7 +300,8 @@ static void GenerateCountedDigits(int count, int* decimal_point,
if (Bignum::PlusCompare(*numerator, *numerator, *denominator) >= 0) {
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
// carry until we hat a non-'9' or til we reach the first digit.
for (int i = count - 1; i > 0; --i) {

+ 1
- 1
c_src/double-conversion/bignum-dtoa.h Datei anzeigen

@ -28,7 +28,7 @@
#ifndef DOUBLE_CONVERSION_BIGNUM_DTOA_H_
#define DOUBLE_CONVERSION_BIGNUM_DTOA_H_
#include "utils.h"
#include "double-conversion/utils.h"
namespace double_conversion {

+ 16
- 14
c_src/double-conversion/bignum.cc Datei anzeigen

@ -25,8 +25,8 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "bignum.h"
#include "utils.h"
#include "double-conversion/bignum.h"
#include "double-conversion/utils.h"
namespace double_conversion {
@ -40,6 +40,7 @@ Bignum::Bignum()
template<typename S>
static int BitSize(S value) {
(void) value; // Mark variable as used.
return 8 * sizeof(value);
}
@ -103,7 +104,7 @@ void Bignum::AssignDecimalString(Vector value) {
const int kMaxUint64DecimalDigits = 19;
Zero();
int length = value.length();
unsigned int pos = 0;
int pos = 0;
// Let's just say that each digit needs 4 bits.
while (length >= kMaxUint64DecimalDigits) {
uint64_t digits = ReadUInt64(value, pos, kMaxUint64DecimalDigits);
@ -122,9 +123,8 @@ void Bignum::AssignDecimalString(Vector value) {
static int HexCharValue(char c) {
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';
UNREACHABLE();
return 0; // To make compiler happy.
ASSERT('A' <= c && c <= 'F');
return 10 + c - 'A';
}
@ -501,13 +501,14 @@ uint16_t Bignum::DivideModuloIntBignum(const Bignum& other) {
// Start by removing multiples of 'other' until both numbers have the same
// number of digits.
while (BigitLength() > other.BigitLength()) {
// This naive approach is extremely inefficient if the this divided other
// might be big. This function is implemented for doubleToString where
// This naive approach is extremely inefficient if `this` divided by other
// is big. This function is implemented for doubleToString where
// the result should be small (less than 10).
ASSERT(other.bigits_[other.used_digits_ - 1] >= ((1 << kBigitSize) / 16));
ASSERT(bigits_[used_digits_ - 1] < 0x10000);
// Remove the multiples of the first digit.
// 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]);
}
@ -523,13 +524,15 @@ uint16_t Bignum::DivideModuloIntBignum(const Bignum& other) {
// Shortcut for easy (and common) case.
int quotient = this_bigit / other_bigit;
bigits_[used_digits_ - 1] = this_bigit - other_bigit * quotient;
result += quotient;
ASSERT(quotient < 0x10000);
result += static_cast<uint16_t>(quotient);
Clamp();
return result;
}
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);
if (other_bigit * (division_estimate + 1) > this_bigit) {
@ -560,8 +563,8 @@ static int SizeInHexChars(S number) {
static char HexCharOfValue(int value) {
ASSERT(0 <= value && value <= 16);
if (value < 10) return value + '0';
return value - 10 + 'A';
if (value < 10) return static_cast<char>(value + '0');
return static_cast<char>(value - 10 + 'A');
}
@ -755,7 +758,6 @@ void Bignum::SubtractTimes(const Bignum& other, int factor) {
Chunk difference = bigits_[i] - borrow;
bigits_[i] = difference & kBigitMask;
borrow = difference >> (kChunkSize - 1);
++i;
}
Clamp();
}

+ 1
- 2
c_src/double-conversion/bignum.h Datei anzeigen

@ -28,7 +28,7 @@
#ifndef DOUBLE_CONVERSION_BIGNUM_H_
#define DOUBLE_CONVERSION_BIGNUM_H_
#include "utils.h"
#include "double-conversion/utils.h"
namespace double_conversion {
@ -49,7 +49,6 @@ class Bignum {
void AssignPowerUInt16(uint16_t base, int exponent);
void AddUInt16(uint16_t operand);
void AddUInt64(uint64_t operand);
void AddBignum(const Bignum& other);
// Precondition: this >= other.

+ 2
- 1
c_src/double-conversion/cached-powers.cc Datei anzeigen

@ -29,7 +29,7 @@
#include <limits.h>
#include <math.h>
#include "utils.h"
#include "double-conversion/utils.h"
#include "cached-powers.h"
@ -152,6 +152,7 @@ void PowersOfTenCache::GetCachedPowerForBinaryExponentRange(
ASSERT(0 <= index && index < kCachedPowersLength);
CachedPower cached_power = kCachedPowers[index];
ASSERT(min_exponent <= cached_power.binary_exponent);
(void) max_exponent; // Mark variable as used.
ASSERT(cached_power.binary_exponent <= max_exponent);
*decimal_exponent = cached_power.decimal_exponent;
*power = DiyFp(cached_power.significand, cached_power.binary_exponent);

+ 2
- 2
c_src/double-conversion/diy-fp.cc Datei anzeigen

@ -26,8 +26,8 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "diy-fp.h"
#include "utils.h"
#include "double-conversion/diy-fp.h"
#include "double-conversion/utils.h"
namespace double_conversion {

+ 12
- 12
c_src/double-conversion/diy-fp.h Datei anzeigen

@ -28,7 +28,7 @@
#ifndef DOUBLE_CONVERSION_DIY_FP_H_
#define DOUBLE_CONVERSION_DIY_FP_H_
#include "utils.h"
#include "double-conversion/utils.h"
namespace double_conversion {
@ -42,7 +42,7 @@ class DiyFp {
static const int kSignificandSize = 64;
DiyFp() : f_(0), e_(0) {}
DiyFp(uint64_t f, int e) : f_(f), e_(e) {}
DiyFp(uint64_t significand, int exponent) : f_(significand), e_(exponent) {}
// this = this - other.
// The exponents of both numbers must be the same and the significand of this
@ -76,22 +76,22 @@ class DiyFp {
void Normalize() {
ASSERT(f_ != 0);
uint64_t f = f_;
int e = e_;
uint64_t significand = f_;
int exponent = e_;
// This method is mainly called for normalizing boundaries. In general
// boundaries need to be shifted by 10 bits. We thus optimize for this case.
const uint64_t k10MSBits = UINT64_2PART_C(0xFFC00000, 00000000);
while ((f & k10MSBits) == 0) {
f <<= 10;
e -= 10;
while ((significand & k10MSBits) == 0) {
significand <<= 10;
exponent -= 10;
}
while ((f & kUint64MSB) == 0) {
f <<= 1;
e--;
while ((significand & kUint64MSB) == 0) {
significand <<= 1;
exponent--;
}
f_ = f;
e_ = e;
f_ = significand;
e_ = exponent;
}
static DiyFp Normalize(const DiyFp& a) {

+ 157
- 64
c_src/double-conversion/double-conversion.cc Datei anzeigen

@ -28,14 +28,14 @@
#include <limits.h>
#include <math.h>
#include "double-conversion.h"
#include "double-conversion/double-conversion.h"
#include "bignum-dtoa.h"
#include "fast-dtoa.h"
#include "fixed-dtoa.h"
#include "ieee.h"
#include "strtod.h"
#include "utils.h"
#include "double-conversion/bignum-dtoa.h"
#include "double-conversion/fast-dtoa.h"
#include "double-conversion/fixed-dtoa.h"
#include "double-conversion/ieee.h"
#include "double-conversion/strtod.h"
#include "double-conversion/utils.h"
namespace double_conversion {
@ -348,7 +348,6 @@ static BignumDtoaMode DtoaToBignumDtoaMode(
case DoubleToStringConverter::PRECISION: return BIGNUM_DTOA_PRECISION;
default:
UNREACHABLE();
return BIGNUM_DTOA_SHORTEST; // To silence compiler.
}
}
@ -403,8 +402,8 @@ void DoubleToStringConverter::DoubleToAscii(double v,
vector, length, point);
break;
default:
UNREACHABLE();
fast_worked = false;
UNREACHABLE();
}
if (fast_worked) return;
@ -417,8 +416,9 @@ void DoubleToStringConverter::DoubleToAscii(double v,
// Consumes the given substring from the iterator.
// Returns false, if the substring does not match.
static bool ConsumeSubString(const char** current,
const char* end,
template <class Iterator>
static bool ConsumeSubString(Iterator* current,
Iterator end,
const char* substring) {
ASSERT(**current == *substring);
for (substring++; *substring != '\0'; substring++) {
@ -440,10 +440,36 @@ static bool ConsumeSubString(const char** current,
const int kMaxSignificantDigits = 772;
static const char kWhitespaceTable7[] = { 32, 13, 10, 9, 11, 12 };
static const int kWhitespaceTable7Length = ARRAY_SIZE(kWhitespaceTable7);
static const uc16 kWhitespaceTable16[] = {
160, 8232, 8233, 5760, 6158, 8192, 8193, 8194, 8195,
8196, 8197, 8198, 8199, 8200, 8201, 8202, 8239, 8287, 12288, 65279
};
static const int kWhitespaceTable16Length = ARRAY_SIZE(kWhitespaceTable16);
static bool isWhitespace(int x) {
if (x < 128) {
for (int i = 0; i < kWhitespaceTable7Length; i++) {
if (kWhitespaceTable7[i] == x) return true;
}
} else {
for (int i = 0; i < kWhitespaceTable16Length; i++) {
if (kWhitespaceTable16[i] == x) return true;
}
}
return false;
}
// Returns true if a nonspace found and false if the end has reached.
static inline bool AdvanceToNonspace(const char** current, const char* end) {
template <class Iterator>
static inline bool AdvanceToNonspace(Iterator* current, Iterator end) {
while (*current != end) {
if (**current != ' ') return true;
if (!isWhitespace(**current)) return true;
++*current;
}
return false;
@ -462,26 +488,57 @@ 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.
#if _MSC_VER
#pragma optimize("",off)
static bool IsDecimalDigitForRadix(int c, int radix) {
return '0' <= c && c <= '9' && (c - '0') < radix;
}
#pragma optimize("",on)
#else
static bool inline IsDecimalDigitForRadix(int c, int radix) {
return '0' <= c && c <= '9' && (c - '0') < radix;
}
#endif
// 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.
template <int radix_log_2>
static double RadixStringToIeee(const char* current,
const char* end,
template <int radix_log_2, class Iterator>
static double RadixStringToIeee(Iterator* current,
Iterator end,
bool sign,
bool allow_trailing_junk,
double junk_string_value,
bool read_as_double,
const char** trailing_pointer) {
ASSERT(current != end);
bool* result_is_junk) {
ASSERT(*current != end);
const int kDoubleSize = Double::kSignificandSize;
const int kSingleSize = Single::kSignificandSize;
const int kSignificandSize = read_as_double? kDoubleSize: kSingleSize;
*result_is_junk = true;
// Skip leading 0s.
while (*current == '0') {
++current;
if (current == end) {
*trailing_pointer = end;
while (**current == '0') {
++(*current);
if (*current == end) {
*result_is_junk = false;
return SignedZero(sign);
}
}
@ -492,14 +549,14 @@ static double RadixStringToIeee(const char* current,
do {
int digit;
if (*current >= '0' && *current <= '9' && *current < '0' + radix) {
digit = static_cast<char>(*current) - '0';
} else if (radix > 10 && *current >= 'a' && *current < 'a' + radix - 10) {
digit = static_cast<char>(*current) - 'a' + 10;
} else if (radix > 10 && *current >= 'A' && *current < 'A' + radix - 10) {
digit = static_cast<char>(*current) - 'A' + 10;
if (IsDecimalDigitForRadix(**current, radix)) {
digit = static_cast<char>(**current) - '0';
} else if (IsCharacterDigitForRadix(**current, radix, 'a')) {
digit = static_cast<char>(**current) - 'a' + 10;
} else if (IsCharacterDigitForRadix(**current, radix, 'A')) {
digit = static_cast<char>(**current) - 'A' + 10;
} else {
if (allow_trailing_junk || !AdvanceToNonspace(&current, end)) {
if (allow_trailing_junk || !AdvanceToNonspace(current, end)) {
break;
} else {
return junk_string_value;
@ -523,14 +580,14 @@ static double RadixStringToIeee(const char* current,
exponent = overflow_bits_count;
bool zero_tail = true;
while (true) {
++current;
if (current == end || !isDigit(*current, radix)) break;
zero_tail = zero_tail && *current == '0';
for (;;) {
++(*current);
if (*current == end || !isDigit(**current, radix)) break;
zero_tail = zero_tail && **current == '0';
exponent += radix_log_2;
}
if (!allow_trailing_junk && AdvanceToNonspace(&current, end)) {
if (!allow_trailing_junk && AdvanceToNonspace(current, end)) {
return junk_string_value;
}
@ -552,13 +609,13 @@ static double RadixStringToIeee(const char* current,
}
break;
}
++current;
} while (current != end);
++(*current);
} while (*current != end);
ASSERT(number < ((int64_t)1 << kSignificandSize));
ASSERT(static_cast<int64_t>(static_cast<double>(number)) == number);
*trailing_pointer = current;
*result_is_junk = false;
if (exponent == 0) {
if (sign) {
@ -573,13 +630,14 @@ static double RadixStringToIeee(const char* current,
}
template <class Iterator>
double StringToDoubleConverter::StringToIeee(
const char* input,
Iterator input,
int length,
int* processed_characters_count,
bool read_as_double) {
const char* current = input;
const char* end = input + length;
bool read_as_double,
int* processed_characters_count) const {
Iterator current = input;
Iterator end = input + length;
*processed_characters_count = 0;
@ -600,7 +658,7 @@ double StringToDoubleConverter::StringToIeee(
if (allow_leading_spaces || allow_trailing_spaces) {
if (!AdvanceToNonspace(&current, end)) {
*processed_characters_count = current - input;
*processed_characters_count = static_cast<int>(current - input);
return empty_string_value_;
}
if (!allow_leading_spaces && (input != current)) {
@ -626,7 +684,7 @@ double StringToDoubleConverter::StringToIeee(
if (*current == '+' || *current == '-') {
sign = (*current == '-');
++current;
const char* next_non_space = current;
Iterator next_non_space = current;
// Skip following spaces (if allowed).
if (!AdvanceToNonspace(&next_non_space, end)) return junk_string_value_;
if (!allow_spaces_after_sign && (current != next_non_space)) {
@ -649,7 +707,7 @@ double StringToDoubleConverter::StringToIeee(
}
ASSERT(buffer_pos == 0);
*processed_characters_count = current - input;
*processed_characters_count = static_cast<int>(current - input);
return sign ? -Double::Infinity() : Double::Infinity();
}
}
@ -668,7 +726,7 @@ double StringToDoubleConverter::StringToIeee(
}
ASSERT(buffer_pos == 0);
*processed_characters_count = current - input;
*processed_characters_count = static_cast<int>(current - input);
return sign ? -Double::NaN() : Double::NaN();
}
}
@ -677,7 +735,7 @@ double StringToDoubleConverter::StringToIeee(
if (*current == '0') {
++current;
if (current == end) {
*processed_characters_count = current - input;
*processed_characters_count = static_cast<int>(current - input);
return SignedZero(sign);
}
@ -690,17 +748,17 @@ double StringToDoubleConverter::StringToIeee(
return junk_string_value_; // "0x".
}
const char* tail_pointer = NULL;
double result = RadixStringToIeee<4>(current,
bool result_is_junk;
double result = RadixStringToIeee<4>(&current,
end,
sign,
allow_trailing_junk,
junk_string_value_,
read_as_double,
&tail_pointer);
if (tail_pointer != NULL) {
if (allow_trailing_spaces) AdvanceToNonspace(&tail_pointer, end);
*processed_characters_count = tail_pointer - input;
&result_is_junk);
if (!result_is_junk) {
if (allow_trailing_spaces) AdvanceToNonspace(&current, end);
*processed_characters_count = static_cast<int>(current - input);
}
return result;
}
@ -709,7 +767,7 @@ double StringToDoubleConverter::StringToIeee(
while (*current == '0') {
++current;
if (current == end) {
*processed_characters_count = current - input;
*processed_characters_count = static_cast<int>(current - input);
return SignedZero(sign);
}
}
@ -757,7 +815,7 @@ double StringToDoubleConverter::StringToIeee(
while (*current == '0') {
++current;
if (current == end) {
*processed_characters_count = current - input;
*processed_characters_count = static_cast<int>(current - input);
return SignedZero(sign);
}
exponent--; // Move this 0 into the exponent.
@ -801,9 +859,9 @@ double StringToDoubleConverter::StringToIeee(
return junk_string_value_;
}
}
char sign = '+';
char exponen_sign = '+';
if (*current == '+' || *current == '-') {
sign = static_cast<char>(*current);
exponen_sign = static_cast<char>(*current);
++current;
if (current == end) {
if (allow_trailing_junk) {
@ -837,7 +895,7 @@ double StringToDoubleConverter::StringToIeee(
++current;
} while (current != end && *current >= '0' && *current <= '9');
exponent += (sign == '-' ? -num : num);
exponent += (exponen_sign == '-' ? -num : num);
}
if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) {
@ -855,16 +913,17 @@ double StringToDoubleConverter::StringToIeee(
if (octal) {
double result;
const char* tail_pointer = NULL;
result = RadixStringToIeee<3>(buffer,
bool result_is_junk;
char* start = buffer;
result = RadixStringToIeee<3>(&start,
buffer + buffer_pos,
sign,
allow_trailing_junk,
junk_string_value_,
read_as_double,
&tail_pointer);
ASSERT(tail_pointer != NULL);
*processed_characters_count = current - input;
&result_is_junk);
ASSERT(!result_is_junk);
*processed_characters_count = static_cast<int>(current - input);
return result;
}
@ -882,8 +941,42 @@ double StringToDoubleConverter::StringToIeee(
} else {
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;
}
double StringToDoubleConverter::StringToDouble(
const char* buffer,
int length,
int* processed_characters_count) const {
return StringToIeee(buffer, length, true, processed_characters_count);
}
double StringToDoubleConverter::StringToDouble(
const uc16* buffer,
int length,
int* processed_characters_count) const {
return StringToIeee(buffer, length, true, processed_characters_count);
}
float StringToDoubleConverter::StringToFloat(
const char* buffer,
int length,
int* processed_characters_count) const {
return static_cast<float>(StringToIeee(buffer, length, false,
processed_characters_count));
}
float StringToDoubleConverter::StringToFloat(
const uc16* buffer,
int length,
int* processed_characters_count) const {
return static_cast<float>(StringToIeee(buffer, length, false,
processed_characters_count));
}
} // namespace double_conversion

+ 21
- 14
c_src/double-conversion/double-conversion.h Datei anzeigen

@ -28,7 +28,7 @@
#ifndef DOUBLE_CONVERSION_DOUBLE_CONVERSION_H_
#define DOUBLE_CONVERSION_DOUBLE_CONVERSION_H_
#include "utils.h"
#include "double-conversion/utils.h"
namespace double_conversion {
@ -415,9 +415,10 @@ class StringToDoubleConverter {
// junk, too.
// - ALLOW_TRAILING_JUNK: ignore trailing characters that are not part of
// a double literal.
// - ALLOW_LEADING_SPACES: skip over leading spaces.
// - ALLOW_TRAILING_SPACES: ignore trailing spaces.
// - ALLOW_SPACES_AFTER_SIGN: ignore spaces after the sign.
// - ALLOW_LEADING_SPACES: skip over leading whitespace, including spaces,
// new-lines, and tabs.
// - ALLOW_TRAILING_SPACES: ignore trailing whitespace.
// - ALLOW_SPACES_AFTER_SIGN: ignore whitespace after the sign.
// Ex: StringToDouble("- 123.2") -> -123.2.
// StringToDouble("+ 123.2") -> 123.2
//
@ -502,19 +503,24 @@ class StringToDoubleConverter {
// in the 'processed_characters_count'. Trailing junk is never included.
double StringToDouble(const char* buffer,
int length,
int* processed_characters_count) {
return StringToIeee(buffer, length, processed_characters_count, true);
}
int* processed_characters_count) const;
// Same as StringToDouble above but for 16 bit characters.
double StringToDouble(const uc16* buffer,
int length,
int* processed_characters_count) const;
// Same as StringToDouble but reads a float.
// Note that this is not equivalent to static_cast<float>(StringToDouble(...))
// due to potential double-rounding.
float StringToFloat(const char* buffer,
int length,
int* processed_characters_count) {
return static_cast<float>(StringToIeee(buffer, length,
processed_characters_count, false));
}
int* processed_characters_count) const;
// Same as StringToFloat above but for 16 bit characters.
float StringToFloat(const uc16* buffer,
int length,
int* processed_characters_count) const;
private:
const int flags_;
@ -523,10 +529,11 @@ class StringToDoubleConverter {
const char* const infinity_symbol_;
const char* const nan_symbol_;
double StringToIeee(const char* buffer,
template <class Iterator>
double StringToIeee(Iterator start_pointer,
int length,
int* processed_characters_count,
bool read_as_double);
bool read_as_double,
int* processed_characters_count) const;
DISALLOW_IMPLICIT_CONSTRUCTORS(StringToDoubleConverter);
};

+ 10
- 11
c_src/double-conversion/fast-dtoa.cc Datei anzeigen

@ -248,13 +248,8 @@ static void BiggestPowerTen(uint32_t number,
// Note: kPowersOf10[i] == 10^(i-1).
exponent_plus_one_guess++;
// We don't have any guarantees that 2^number_bits <= number.
// TODO(floitsch): can we change the 'while' into an 'if'? We definitely see
// number < (2^number_bits - 1), but I haven't encountered
// number < (2^number_bits - 2) yet.
while (number < kSmallPowersOfTen[exponent_plus_one_guess]) {
if (number < kSmallPowersOfTen[exponent_plus_one_guess]) {
exponent_plus_one_guess--;
if (exponent_plus_one_guess <= 0)
break;
}
*power = kSmallPowersOfTen[exponent_plus_one_guess];
*exponent_plus_one = exponent_plus_one_guess;
@ -352,7 +347,8 @@ static bool DigitGen(DiyFp low,
// that is smaller than integrals.
while (*kappa > 0) {
int digit = integrals / divisor;
buffer[*length] = '0' + digit;
ASSERT(digit <= 9);
buffer[*length] = static_cast<char>('0' + digit);
(*length)++;
integrals %= divisor;
(*kappa)--;
@ -381,13 +377,14 @@ static bool DigitGen(DiyFp low,
ASSERT(one.e() >= -60);
ASSERT(fractionals < one.f());
ASSERT(UINT64_2PART_C(0xFFFFFFFF, FFFFFFFF) / 10 >= one.f());
while (true) {
for (;;) {
fractionals *= 10;
unit *= 10;
unsafe_interval.set_f(unsafe_interval.f() * 10);
// Integer division by one.
int digit = static_cast<int>(fractionals >> -one.e());
buffer[*length] = '0' + digit;
ASSERT(digit <= 9);
buffer[*length] = static_cast<char>('0' + digit);
(*length)++;
fractionals &= one.f() - 1; // Modulo by one.
(*kappa)--;
@ -461,7 +458,8 @@ static bool DigitGenCounted(DiyFp w,
// that is smaller than 'integrals'.
while (*kappa > 0) {
int digit = integrals / divisor;
buffer[*length] = '0' + digit;
ASSERT(digit <= 9);
buffer[*length] = static_cast<char>('0' + digit);
(*length)++;
requested_digits--;
integrals %= divisor;
@ -494,7 +492,8 @@ static bool DigitGenCounted(DiyFp w,
w_error *= 10;
// Integer division by one.
int digit = static_cast<int>(fractionals >> -one.e());
buffer[*length] = '0' + digit;
ASSERT(digit <= 9);
buffer[*length] = static_cast<char>('0' + digit);
(*length)++;
requested_digits--;
fractionals &= one.f() - 1; // Modulo by one.

+ 1
- 1
c_src/double-conversion/fast-dtoa.h Datei anzeigen

@ -28,7 +28,7 @@
#ifndef DOUBLE_CONVERSION_FAST_DTOA_H_
#define DOUBLE_CONVERSION_FAST_DTOA_H_
#include "utils.h"
#include "double-conversion/utils.h"
namespace double_conversion {

+ 7
- 5
c_src/double-conversion/fixed-dtoa.cc Datei anzeigen

@ -133,7 +133,7 @@ static void FillDigits32(uint32_t number, Vector buffer, int* length) {
while (number != 0) {
int digit = number % 10;
number /= 10;
buffer[(*length) + number_length] = '0' + digit;
buffer[(*length) + number_length] = static_cast<char>('0' + digit);
number_length++;
}
// Exchange the digits.
@ -150,7 +150,7 @@ static void FillDigits32(uint32_t number, Vector buffer, int* length) {
}
static void FillDigits64FixedLength(uint64_t number, int requested_length,
static void FillDigits64FixedLength(uint64_t number,
Vector<char> buffer, int* length) {
const uint32_t kTen7 = 10000000;
// 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;
point--;
int digit = static_cast<int>(fractionals >> point);
buffer[*length] = '0' + digit;
ASSERT(digit <= 9);
buffer[*length] = static_cast<char>('0' + digit);
(*length)++;
fractionals -= static_cast<uint64_t>(digit) << point;
}
@ -274,7 +275,8 @@ static void FillFractionals(uint64_t fractionals, int exponent,
fractionals128.Multiply(5);
point--;
int digit = fractionals128.DivModPowerOf2(point);
buffer[*length] = '0' + digit;
ASSERT(digit <= 9);
buffer[*length] = static_cast<char>('0' + digit);
(*length)++;
}
if (fractionals128.BitAt(point - 1) == 1) {
@ -358,7 +360,7 @@ bool FastFixedDtoa(double v,
remainder = (dividend % divisor) << exponent;
}
FillDigits32(quotient, buffer, length);
FillDigits64FixedLength(remainder, divisor_power, buffer, length);
FillDigits64FixedLength(remainder, buffer, length);
*decimal_point = *length;
} else if (exponent >= 0) {
// 0 <= exponent <= 11

+ 1
- 1
c_src/double-conversion/fixed-dtoa.h Datei anzeigen

@ -28,7 +28,7 @@
#ifndef DOUBLE_CONVERSION_FIXED_DTOA_H_
#define DOUBLE_CONVERSION_FIXED_DTOA_H_
#include "utils.h"
#include "double-conversion/utils.h"
namespace double_conversion {

+ 4
- 0
c_src/double-conversion/ieee.h Datei anzeigen

@ -256,6 +256,8 @@ class Double {
return (significand & kSignificandMask) |
(biased_exponent << kPhysicalSignificandSize);
}
DISALLOW_COPY_AND_ASSIGN(Double);
};
class Single {
@ -391,6 +393,8 @@ class Single {
static const uint32_t kNaN = 0x7FC00000;
const uint32_t d32_;
DISALLOW_COPY_AND_ASSIGN(Single);
};
} // namespace double_conversion

+ 3
- 2
c_src/double-conversion/strtod.cc Datei anzeigen

@ -137,6 +137,7 @@ static void TrimAndCut(Vector buffer, int exponent,
Vector<const char> right_trimmed = TrimTrailingZeros(left_trimmed);
exponent += left_trimmed.length() - right_trimmed.length();
if (right_trimmed.length() > kMaxSignificantDecimalDigits) {
(void) space_size; // Mark variable as used.
ASSERT(space_size >= kMaxSignificantDecimalDigits);
CutToMaxSignificantDigits(right_trimmed, exponent,
buffer_copy_space, updated_exponent);
@ -263,7 +264,6 @@ static DiyFp AdjustmentPowerOfTen(int exponent) {
case 7: return DiyFp(UINT64_2PART_C(0x98968000, 00000000), -40);
default:
UNREACHABLE();
return DiyFp(0, 0);
}
}
@ -286,7 +286,7 @@ static bool DiyFpStrtod(Vector buffer,
const int kDenominator = 1 << kDenominatorLog;
// Move the remaining decimals into the exponent.
exponent += remaining_decimals;
int error = (remaining_decimals == 0 ? 0 : kDenominator / 2);
uint64_t error = (remaining_decimals == 0 ? 0 : kDenominator / 2);
int old_e = input.e();
input.Normalize();
@ -515,6 +515,7 @@ float Strtof(Vector buffer, int exponent) {
double double_next2 = Double(double_next).NextDouble();
f4 = static_cast<float>(double_next2);
}
(void) f2; // Mark variable as used.
ASSERT(f1 <= f2 && f2 <= f3 && f3 <= f4);
// If the guess doesn't lie near a single-precision boundary we can simply

+ 1
- 1
c_src/double-conversion/strtod.h Datei anzeigen

@ -28,7 +28,7 @@
#ifndef DOUBLE_CONVERSION_STRTOD_H_
#define DOUBLE_CONVERSION_STRTOD_H_
#include "utils.h"
#include "double-conversion/utils.h"
namespace double_conversion {

+ 22
- 21
c_src/double-conversion/utils.h Datei anzeigen

@ -33,7 +33,8 @@
#include <assert.h>
#ifndef ASSERT
#define ASSERT(condition) (assert(condition))
#define ASSERT(condition) \
assert(condition);
#endif
#ifndef UNIMPLEMENTED
#define UNIMPLEMENTED() (abort())
@ -55,11 +56,16 @@
#if defined(_M_X64) || defined(__x86_64__) || \
defined(__ARMEL__) || defined(__avr32__) || \
defined(__hppa__) || defined(__ia64__) || \
defined(__mips__) || defined(__powerpc__) || \
defined(__mips__) || \
defined(__powerpc__) || defined(__ppc__) || defined(__ppc64__) || \
defined(_POWER) || defined(_ARCH_PPC) || defined(_ARCH_PPC64) || \
defined(__sparc__) || defined(__sparc) || defined(__s390__) || \
defined(__SH4__) || defined(__alpha__) || \
defined(_MIPS_ARCH_MIPS32R2)
defined(_MIPS_ARCH_MIPS32R2) || \
defined(__AARCH64EL__) || defined(__aarch64__)
#define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1
#elif defined(__mc68000__)
#undef DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS
#elif defined(_M_IX86) || defined(__i386__) || defined(__i386)
#if defined(_WIN32)
// Windows uses a 64bit wide floating point stack.
@ -71,6 +77,11 @@
#error Target architecture was not detected as supported by Double-Conversion.
#endif
#if defined(__GNUC__)
#define DOUBLE_CONVERSION_UNUSED __attribute__((unused))
#else
#define DOUBLE_CONVERSION_UNUSED
#endif
#if defined(_WIN32) && !defined(__MINGW32__)
@ -90,6 +101,8 @@ typedef unsigned __int64 uint64_t;
#endif
typedef uint16_t uc16;
// The following macro works on both 32 and 64-bit platforms.
// Usage: instead of writing 0x1234567890123456
// write UINT64_2PART_C(0x12345678,90123456);
@ -155,8 +168,8 @@ template
class Vector {
public:
Vector() : start_(NULL), length_(0) {}
Vector(T* data, int length) : start_(data), length_(length) {
ASSERT(length == 0 || (length > 0 && data != NULL));
Vector(T* data, int len) : start_(data), length_(len) {
ASSERT(len == 0 || (len > 0 && data != NULL));
}
// Returns a vector using the same backing storage as this one,
@ -198,8 +211,8 @@ class Vector {
// buffer bounds on all operations in debug mode.
class StringBuilder {
public:
StringBuilder(char* buffer, int size)
: buffer_(buffer, size), position_(0) { }
StringBuilder(char* buffer, int buffer_size)
: buffer_(buffer, buffer_size), position_(0) { }
~StringBuilder() { if (!is_finalized()) Finalize(); }
@ -292,24 +305,12 @@ class StringBuilder {
// you can use BitCast to cast one pointer type to another. This confuses gcc
// enough that it can no longer see that you have cast one pointer type to
// another thus avoiding the warning.
//
// Adding an unused attribute for this static check. Apparently GCC 4.8
// now throws an error for unused typedefs which triggers -Werror.
//
// PJD: 4-24-2013
//
#if defined(__GNUC__)
#define UNUSED __attribute__((unused))
#else
#define UNUSED
#endif
template <class Dest, class Source>
inline Dest BitCast(const Source& source) {
// Compile time assertion: sizeof(Dest) == sizeof(Source)
// A compile error here means your Dest and Source have different sizes.
UNUSED typedef char VerifySizesAreEqual[sizeof(Dest) == sizeof(Source) ? 1 : -1];
DOUBLE_CONVERSION_UNUSED
typedef char VerifySizesAreEqual[sizeof(Dest) == sizeof(Source) ? 1 : -1];
Dest dest;
memmove(&dest, &source, sizeof(dest));

Laden…
Abbrechen
Speichern