mirror of
https://github.com/Tencent/rapidjson.git
synced 2025-03-09 11:09:32 +01:00
Limit significand to 17 digits for fast path
Should fix gcc debug error in tranvis. May need further refactoring.
This commit is contained in:
parent
bea4fa7f6a
commit
b29acfb90d
@ -447,12 +447,11 @@ inline int CheckWithinHalfULP(double b, const BigInteger& d, int dExp, bool* adj
|
||||
return cmp;
|
||||
}
|
||||
|
||||
inline double FullPrecision(double d, int dExp, const char* decimals, size_t length) {
|
||||
inline double FullPrecision(double d, int p, const char* decimals, size_t length, size_t decimalPosition, int exp) {
|
||||
RAPIDJSON_ASSERT(d >= 0.0);
|
||||
|
||||
// Use fast path for string-to-double conversion if possible
|
||||
// see http://www.exploringbinary.com/fast-path-decimal-to-floating-point-conversion/
|
||||
int p = dExp;
|
||||
if (p > 22) {
|
||||
if (p < 22 + 16) {
|
||||
// Fast Path Cases In Disguise
|
||||
@ -468,6 +467,7 @@ inline double FullPrecision(double d, int dExp, const char* decimals, size_t len
|
||||
return 0.0;
|
||||
|
||||
const BigInteger dInt(decimals, length);
|
||||
const int dExp = (int)decimalPosition - (int)length + exp;
|
||||
Double approx = NormalPrecision(d, p);
|
||||
for (int i = 0; i < 10; i++) {
|
||||
bool adjustToNegative;
|
||||
|
@ -779,6 +779,7 @@ private:
|
||||
unsigned i = 0;
|
||||
uint64_t i64 = 0;
|
||||
bool use64bit = false;
|
||||
int significandDigit = 0;
|
||||
if (s.Peek() == '0') {
|
||||
i = 0;
|
||||
s.TakePush();
|
||||
@ -796,6 +797,7 @@ private:
|
||||
}
|
||||
}
|
||||
i = i * 10 + static_cast<unsigned>(s.TakePush() - '0');
|
||||
significandDigit++;
|
||||
}
|
||||
else
|
||||
while (s.Peek() >= '0' && s.Peek() <= '9') {
|
||||
@ -807,6 +809,7 @@ private:
|
||||
}
|
||||
}
|
||||
i = i * 10 + static_cast<unsigned>(s.TakePush() - '0');
|
||||
significandDigit++;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -825,6 +828,7 @@ private:
|
||||
break;
|
||||
}
|
||||
i64 = i64 * 10 + static_cast<unsigned>(s.TakePush() - '0');
|
||||
significandDigit++;
|
||||
}
|
||||
else
|
||||
while (s.Peek() >= '0' && s.Peek() <= '9') {
|
||||
@ -835,6 +839,7 @@ private:
|
||||
break;
|
||||
}
|
||||
i64 = i64 * 10 + static_cast<unsigned>(s.TakePush() - '0');
|
||||
significandDigit++;
|
||||
}
|
||||
}
|
||||
|
||||
@ -849,8 +854,13 @@ private:
|
||||
|
||||
// Parse frac = decimal-point 1*DIGIT
|
||||
int expFrac = 0;
|
||||
size_t decimalPosition;
|
||||
if (s.Peek() == '.') {
|
||||
s.Take();
|
||||
decimalPosition = s.Length();
|
||||
|
||||
if (!(s.Peek() >= '0' && s.Peek() <= '9'))
|
||||
RAPIDJSON_PARSE_ERROR(kParseErrorNumberMissFraction, s.Tell());
|
||||
|
||||
if (!useDouble) {
|
||||
#if RAPIDJSON_64BIT
|
||||
@ -864,6 +874,8 @@ private:
|
||||
else {
|
||||
i64 = i64 * 10 + static_cast<unsigned>(s.TakePush() - '0');
|
||||
--expFrac;
|
||||
if (i64 != 0)
|
||||
significandDigit++;
|
||||
}
|
||||
}
|
||||
|
||||
@ -876,13 +888,18 @@ private:
|
||||
}
|
||||
|
||||
while (s.Peek() >= '0' && s.Peek() <= '9') {
|
||||
d = d * 10.0 + (s.TakePush() - '0');
|
||||
--expFrac;
|
||||
if (significandDigit < 17) {
|
||||
d = d * 10.0 + (s.TakePush() - '0');
|
||||
--expFrac;
|
||||
if (d != 0.0)
|
||||
significandDigit++;
|
||||
}
|
||||
else
|
||||
s.TakePush();
|
||||
}
|
||||
|
||||
if (expFrac == 0)
|
||||
RAPIDJSON_PARSE_ERROR(kParseErrorNumberMissFraction, s.Tell());
|
||||
}
|
||||
else
|
||||
decimalPosition = s.Length(); // decimal position at the end of integer.
|
||||
|
||||
// Parse exp = e [ minus / plus ] 1*DIGIT
|
||||
int exp = 0;
|
||||
@ -924,7 +941,7 @@ private:
|
||||
if (useDouble) {
|
||||
int p = exp + expFrac;
|
||||
if (parseFlags & kParseFullPrecisionFlag)
|
||||
d = internal::FullPrecision(d, p, decimal, length);
|
||||
d = internal::FullPrecision(d, p, decimal, length, decimalPosition, exp);
|
||||
else
|
||||
d = internal::NormalPrecision(d, p);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user