mirror of
https://github.com/Tencent/rapidjson.git
synced 2025-03-09 11:09:32 +01:00
Minor refactoring before optimization trial
This commit is contained in:
parent
5171775d4c
commit
475b242087
@ -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
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user