Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/miloyip/rapidjson.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/rapidjson/internal/strtod.h50
-rw-r--r--include/rapidjson/reader.h4
2 files changed, 32 insertions, 22 deletions
diff --git a/include/rapidjson/internal/strtod.h b/include/rapidjson/internal/strtod.h
index c45bca6e..e1c09e17 100644
--- a/include/rapidjson/internal/strtod.h
+++ b/include/rapidjson/internal/strtod.h
@@ -29,7 +29,7 @@
namespace rapidjson {
namespace internal {
-inline double StrtodFastPath(double significand, int exp) {
+inline double FastPath(double significand, int exp) {
if (exp < -308)
return 0.0;
else if (exp >= 0)
@@ -38,14 +38,14 @@ inline double StrtodFastPath(double significand, int exp) {
return significand / internal::Pow10(-exp);
}
-inline double NormalPrecision(double d, int p) {
+inline double StrtodNormalPrecision(double d, int p) {
if (p < -308) {
// Prevent expSum < -308, making Pow10(p) = 0
- d = StrtodFastPath(d, -308);
- d = StrtodFastPath(d, p + 308);
+ d = FastPath(d, -308);
+ d = FastPath(d, p + 308);
}
else
- d = StrtodFastPath(d, p);
+ d = FastPath(d, p);
return d;
}
@@ -124,25 +124,24 @@ inline int CheckWithinHalfULP(double b, const BigInteger& d, int dExp, bool* adj
return cmp;
}
-inline double FullPrecision(double d, int p, const char* decimals, size_t length, size_t decimalPosition, int exp) {
- RAPIDJSON_ASSERT(d >= 0.0);
- RAPIDJSON_ASSERT(length >= 1);
-
+inline bool StrtodFast(double d, int p, double* result) {
// Use fast path for string-to-double conversion if possible
// see http://www.exploringbinary.com/fast-path-decimal-to-floating-point-conversion/
- if (p > 22) {
- if (p < 22 + 16) {
- // Fast Path Cases In Disguise
- d *= internal::Pow10(p - 22);
- p = 22;
- }
+ if (p > 22 && p < 22 + 16) {
+ // Fast Path Cases In Disguise
+ d *= internal::Pow10(p - 22);
+ p = 22;
}
- if (p >= -22 && p <= 22 && d <= 9007199254740991.0) // 2^53 - 1
- return StrtodFastPath(d, p);
-
- // Use slow-path with BigInteger comparison
+ if (p >= -22 && p <= 22 && d <= 9007199254740991.0) { // 2^53 - 1
+ *result = FastPath(d, p);
+ return true;
+ }
+ else
+ return false;
+}
+inline double StrtodBigInteger(double d, int p, const char* decimals, size_t length, size_t decimalPosition, int exp) {
// Trim leading zeros
while (*decimals == '0' && length > 1) {
length--;
@@ -170,7 +169,7 @@ inline double FullPrecision(double d, int p, const char* decimals, size_t length
const BigInteger dInt(decimals, length);
const int dExp = (int)decimalPosition - (int)length + exp;
- Double approx = NormalPrecision(d, p);
+ Double approx = StrtodNormalPrecision(d, p);
for (int i = 0; i < 10; i++) {
bool adjustToNegative;
int cmp = CheckWithinHalfULP(approx.Value(), dInt, dExp, &adjustToNegative);
@@ -191,6 +190,17 @@ inline double FullPrecision(double d, int p, const char* decimals, size_t length
return approx.Value();
}
+inline double StrtodFullPrecision(double d, int p, const char* decimals, size_t length, size_t decimalPosition, int exp) {
+ RAPIDJSON_ASSERT(d >= 0.0);
+ RAPIDJSON_ASSERT(length >= 1);
+
+ double result;
+ if (StrtodFast(d, p, &result))
+ return result;
+
+ return StrtodBigInteger(d, p, decimals, length, decimalPosition, exp);
+}
+
} // namespace internal
} // namespace rapidjson
diff --git a/include/rapidjson/reader.h b/include/rapidjson/reader.h
index c03a4ce5..77c9528b 100644
--- a/include/rapidjson/reader.h
+++ b/include/rapidjson/reader.h
@@ -941,9 +941,9 @@ private:
if (useDouble) {
int p = exp + expFrac;
if (parseFlags & kParseFullPrecisionFlag)
- d = internal::FullPrecision(d, p, decimal, length, decimalPosition, exp);
+ d = internal::StrtodFullPrecision(d, p, decimal, length, decimalPosition, exp);
else
- d = internal::NormalPrecision(d, p);
+ d = internal::StrtodNormalPrecision(d, p);
cont = handler.Double(minus ? -d : d);
}