mirror of
https://github.com/Tencent/rapidjson.git
synced 2025-03-10 03:29:59 +01:00
Remove unused code paths in double conversions
This commit is contained in:
parent
5b89f331c5
commit
37d820a13e
@ -135,25 +135,9 @@ struct DiyFp {
|
|||||||
double d;
|
double d;
|
||||||
uint64_t u64;
|
uint64_t u64;
|
||||||
}u;
|
}u;
|
||||||
uint64_t significand = f;
|
const uint64_t be = (e == kDpDenormalExponent && (f & kDpHiddenBit) == 0) ? 0 :
|
||||||
int exponent = e;
|
static_cast<uint64_t>(e + kDpExponentBias);
|
||||||
while (significand > kDpHiddenBit + kDpSignificandMask) {
|
u.u64 = (f & kDpSignificandMask) | (be << kDpSignificandSize);
|
||||||
significand >>= 1;
|
|
||||||
exponent++;
|
|
||||||
}
|
|
||||||
while (exponent > kDpDenormalExponent && (significand & kDpHiddenBit) == 0) {
|
|
||||||
significand <<= 1;
|
|
||||||
exponent--;
|
|
||||||
}
|
|
||||||
if (exponent >= kDpMaxExponent) {
|
|
||||||
u.u64 = kDpExponentMask; // Infinity
|
|
||||||
return u.d;
|
|
||||||
}
|
|
||||||
else if (exponent < kDpDenormalExponent)
|
|
||||||
return 0.0;
|
|
||||||
const uint64_t be = (exponent == kDpDenormalExponent && (significand & kDpHiddenBit) == 0) ? 0 :
|
|
||||||
static_cast<uint64_t>(exponent + kDpExponentBias);
|
|
||||||
u.u64 = (significand & kDpSignificandMask) | (be << kDpSignificandSize);
|
|
||||||
return u.d;
|
return u.d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,8 +50,10 @@ inline unsigned CountDecimalDigit32(uint32_t n) {
|
|||||||
if (n < 1000000) return 6;
|
if (n < 1000000) return 6;
|
||||||
if (n < 10000000) return 7;
|
if (n < 10000000) return 7;
|
||||||
if (n < 100000000) return 8;
|
if (n < 100000000) return 8;
|
||||||
if (n < 1000000000) return 9;
|
// Will not reach 10 digits in DigitGen()
|
||||||
return 10;
|
//if (n < 1000000000) return 9;
|
||||||
|
//return 10;
|
||||||
|
return 9;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void DigitGen(const DiyFp& W, const DiyFp& Mp, uint64_t delta, char* buffer, int* len, int* K) {
|
inline void DigitGen(const DiyFp& W, const DiyFp& Mp, uint64_t delta, char* buffer, int* len, int* K) {
|
||||||
@ -60,13 +62,12 @@ inline void DigitGen(const DiyFp& W, const DiyFp& Mp, uint64_t delta, char* buff
|
|||||||
const DiyFp wp_w = Mp - W;
|
const DiyFp wp_w = Mp - W;
|
||||||
uint32_t p1 = static_cast<uint32_t>(Mp.f >> -one.e);
|
uint32_t p1 = static_cast<uint32_t>(Mp.f >> -one.e);
|
||||||
uint64_t p2 = Mp.f & (one.f - 1);
|
uint64_t p2 = Mp.f & (one.f - 1);
|
||||||
int kappa = CountDecimalDigit32(p1);
|
int kappa = CountDecimalDigit32(p1); // kappa in [0, 9]
|
||||||
*len = 0;
|
*len = 0;
|
||||||
|
|
||||||
while (kappa > 0) {
|
while (kappa > 0) {
|
||||||
uint32_t d;
|
uint32_t d = 0;
|
||||||
switch (kappa) {
|
switch (kappa) {
|
||||||
case 10: d = p1 / 1000000000; p1 %= 1000000000; break;
|
|
||||||
case 9: d = p1 / 100000000; p1 %= 100000000; break;
|
case 9: d = p1 / 100000000; p1 %= 100000000; break;
|
||||||
case 8: d = p1 / 10000000; p1 %= 10000000; break;
|
case 8: d = p1 / 10000000; p1 %= 10000000; break;
|
||||||
case 7: d = p1 / 1000000; p1 %= 1000000; break;
|
case 7: d = p1 / 1000000; p1 %= 1000000; break;
|
||||||
@ -76,14 +77,6 @@ inline void DigitGen(const DiyFp& W, const DiyFp& Mp, uint64_t delta, char* buff
|
|||||||
case 3: d = p1 / 100; p1 %= 100; break;
|
case 3: d = p1 / 100; p1 %= 100; break;
|
||||||
case 2: d = p1 / 10; p1 %= 10; break;
|
case 2: d = p1 / 10; p1 %= 10; break;
|
||||||
case 1: d = p1; p1 = 0; break;
|
case 1: d = p1; p1 = 0; break;
|
||||||
default:
|
|
||||||
#if defined(_MSC_VER)
|
|
||||||
__assume(0);
|
|
||||||
#elif __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
|
|
||||||
__builtin_unreachable();
|
|
||||||
#else
|
|
||||||
d = 0;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
if (d || *len)
|
if (d || *len)
|
||||||
buffer[(*len)++] = static_cast<char>('0' + static_cast<char>(d));
|
buffer[(*len)++] = static_cast<char>('0' + static_cast<char>(d));
|
||||||
|
@ -34,14 +34,6 @@ public:
|
|||||||
return Double(u + 1).Value();
|
return Double(u + 1).Value();
|
||||||
}
|
}
|
||||||
|
|
||||||
double PreviousPositiveDouble() const {
|
|
||||||
RAPIDJSON_ASSERT(!Sign());
|
|
||||||
if (IsZero())
|
|
||||||
return 0.0;
|
|
||||||
else
|
|
||||||
return Double(u - 1).Value();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Sign() const { return (u & kSignMask) != 0; }
|
bool Sign() const { return (u & kSignMask) != 0; }
|
||||||
uint64_t Significand() const { return u & kSignificandMask; }
|
uint64_t Significand() const { return u & kSignificandMask; }
|
||||||
int Exponent() const { return ((u & kExponentMask) >> kSignificandSize) - kExponentBias; }
|
int Exponent() const { return ((u & kExponentMask) >> kSignificandSize) - kExponentBias; }
|
||||||
|
@ -52,7 +52,7 @@ inline T Min3(T a, T b, T c) {
|
|||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int CheckWithinHalfULP(double b, const BigInteger& d, int dExp, bool* adjustToNegative) {
|
inline int CheckWithinHalfULP(double b, const BigInteger& d, int dExp) {
|
||||||
const Double db(b);
|
const Double db(b);
|
||||||
const uint64_t bInt = db.IntegerSignificand();
|
const uint64_t bInt = db.IntegerSignificand();
|
||||||
const int bExp = db.IntegerExponent();
|
const int bExp = db.IntegerExponent();
|
||||||
@ -104,12 +104,12 @@ inline int CheckWithinHalfULP(double b, const BigInteger& d, int dExp, bool* adj
|
|||||||
hS.MultiplyPow5(hS_Exp5) <<= hS_Exp2;
|
hS.MultiplyPow5(hS_Exp5) <<= hS_Exp2;
|
||||||
|
|
||||||
BigInteger delta(0);
|
BigInteger delta(0);
|
||||||
*adjustToNegative = dS.Difference(bS, &delta);
|
bool adjustToNegative = dS.Difference(bS, &delta);
|
||||||
|
|
||||||
int cmp = delta.Compare(hS);
|
int cmp = delta.Compare(hS);
|
||||||
// If delta is within 1/2 ULP, check for special case when significand is power of two.
|
// If delta is within 1/2 ULP, check for special case when significand is power of two.
|
||||||
// In this case, need to compare with 1/2h in the lower bound.
|
// In this case, need to compare with 1/2h in the lower bound.
|
||||||
if (cmp < 0 && *adjustToNegative && // within and dS < bS
|
if (cmp < 0 && adjustToNegative && // within and dS < bS
|
||||||
db.IsNormal() && (bInt & (bInt - 1)) == 0 && // Power of 2
|
db.IsNormal() && (bInt & (bInt - 1)) == 0 && // Power of 2
|
||||||
db.Uint64Value() != RAPIDJSON_UINT64_C2(0x00100000, 0x00000000)) // minimum normal number must not do this
|
db.Uint64Value() != RAPIDJSON_UINT64_C2(0x00100000, 0x00000000)) // minimum normal number must not do this
|
||||||
{
|
{
|
||||||
@ -213,24 +213,18 @@ inline double StrtodBigInteger(double approx, const char* decimals, size_t lengt
|
|||||||
const BigInteger dInt(decimals, length);
|
const BigInteger dInt(decimals, length);
|
||||||
const int dExp = (int)decimalPosition - (int)length + exp;
|
const int dExp = (int)decimalPosition - (int)length + exp;
|
||||||
Double a(approx);
|
Double a(approx);
|
||||||
for (int i = 0; i < 10; i++) {
|
int cmp = CheckWithinHalfULP(a.Value(), dInt, dExp);
|
||||||
bool adjustToNegative;
|
if (cmp < 0)
|
||||||
int cmp = CheckWithinHalfULP(a.Value(), dInt, dExp, &adjustToNegative);
|
return a.Value(); // within half ULP
|
||||||
if (cmp < 0)
|
else if (cmp == 0) {
|
||||||
return a.Value(); // within half ULP
|
// Round towards even
|
||||||
else if (cmp == 0) {
|
if (a.Significand() & 1)
|
||||||
// Round towards even
|
return a.NextPositiveDouble();
|
||||||
if (a.Significand() & 1)
|
else
|
||||||
return adjustToNegative ? a.PreviousPositiveDouble() : a.NextPositiveDouble();
|
return a.Value();
|
||||||
else
|
|
||||||
return a.Value();
|
|
||||||
}
|
|
||||||
else // adjustment
|
|
||||||
a = adjustToNegative ? a.PreviousPositiveDouble() : a.NextPositiveDouble();
|
|
||||||
}
|
}
|
||||||
|
else // adjustment
|
||||||
// This should not happen, but in case there is really a bug, break the infinite-loop
|
return a.NextPositiveDouble();
|
||||||
return a.Value();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline double StrtodFullPrecision(double d, int p, const char* decimals, size_t length, size_t decimalPosition, int exp) {
|
inline double StrtodFullPrecision(double d, int p, const char* decimals, size_t length, size_t decimalPosition, int exp) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user