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:
authorMilo Yip <miloyip@gmail.com>2014-09-16 06:52:40 +0400
committerMilo Yip <miloyip@gmail.com>2014-09-16 06:52:40 +0400
commita425ad5552605b5ac5edacd5e666a4af5f680683 (patch)
tree784eb6e66a2bdf296d21aadfad452f3f25b86cab
parent50fc3fedb2e09445f5214432387767c84e562805 (diff)
Trimming leading/trailing zeros and correct underflow case
-rw-r--r--include/rapidjson/internal/strtod.h27
1 files changed, 26 insertions, 1 deletions
diff --git a/include/rapidjson/internal/strtod.h b/include/rapidjson/internal/strtod.h
index 9c4b20df..e0b3f6f8 100644
--- a/include/rapidjson/internal/strtod.h
+++ b/include/rapidjson/internal/strtod.h
@@ -449,6 +449,7 @@ inline int CheckWithinHalfULP(double b, const BigInteger& d, int dExp, bool* adj
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);
// Use fast path for string-to-double conversion if possible
// see http://www.exploringbinary.com/fast-path-decimal-to-floating-point-conversion/
@@ -463,7 +464,31 @@ inline double FullPrecision(double d, int p, const char* decimals, size_t length
if (p >= -22 && p <= 22 && d <= 9007199254740991.0) // 2^53 - 1
return StrtodFastPath(d, p);
- if (p + int(length) < -324)
+ // Use slow-path with BigInteger comparison
+
+ // Trim leading zeros
+ while (decimals[0] == '0' && length > 1) {
+ decimals++;
+ length--;
+ decimalPosition--;
+ }
+
+ // Trim trailing zeros
+ while (decimals[length - 1] == '0' && length > 1) {
+ length--;
+ exp++;
+ decimalPosition--;
+ }
+
+ // Trim right-most digits
+ const int kMaxDecimalDigit = 780;
+ if (length > kMaxDecimalDigit) {
+ exp += (int(length) - kMaxDecimalDigit);
+ length = kMaxDecimalDigit;
+ }
+
+ // If too small, underflow to zero
+ if (int(length) + exp < -324)
return 0.0;
const BigInteger dInt(decimals, length);