19 #ifndef RAPIDJSON_STRTOD_ 20 #define RAPIDJSON_STRTOD_ 32 inline double FastPath(
double significand,
int exp) {
63 const int hExp = bExp - 1;
65 int dS_Exp2 = 0, dS_Exp5 = 0, bS_Exp2 = 0, bS_Exp5 = 0, hS_Exp2 = 0,
96 int common_Exp2 =
Min3(dS_Exp2, bS_Exp2, hS_Exp2);
97 dS_Exp2 -= common_Exp2;
98 bS_Exp2 -= common_Exp2;
99 hS_Exp2 -= common_Exp2;
103 static_cast<unsigned>(dS_Exp2);
107 static_cast<unsigned>(bS_Exp2);
111 static_cast<unsigned>(hS_Exp2);
123 if (p > 22 && p < 22 + 16) {
129 if (p >= -22 && p <= 22 && d <= 9007199254740991.0) {
142 for (; i < dLen; i++) {
147 significand = significand * 10u +
static_cast<unsigned>(decimals[i] -
'0');
150 if (i < dLen && decimals[i] >=
'5')
153 int remaining = dLen - i;
154 const int kUlpShift = 3;
155 const int kUlp = 1 << kUlpShift;
156 int64_t error = (remaining == 0) ? 0 : kUlp / 2;
158 DiyFp v(significand, 0);
166 if (actualExp != dExp) {
167 static const DiyFp kPow10[] = {
176 int adjustment = dExp - actualExp;
178 v = v * kPow10[adjustment - 1];
179 if (dLen + adjustment >
186 error += kUlp + (error == 0 ? 0 : 1);
188 const int oldExp = v.
e;
190 error <<= oldExp - v.
e;
192 const int effectiveSignificandSize =
194 int precisionSize = 64 - effectiveSignificandSize;
195 if (precisionSize + kUlpShift >= 64) {
196 int scaleExp = (precisionSize + kUlpShift) - 63;
199 error = (error >> scaleExp) + 1 + kUlp;
200 precisionSize -= scaleExp;
203 DiyFp rounded(v.
f >> precisionSize, v.
e + precisionSize);
205 (v.
f & ((
uint64_t(1) << precisionSize) - 1)) * kUlp;
207 if (precisionBits >= halfWay + static_cast<unsigned>(error)) {
218 return halfWay -
static_cast<unsigned>(error) >= precisionBits ||
219 precisionBits >= halfWay + static_cast<unsigned>(error);
225 const BigInteger dInt(decimals, static_cast<unsigned>(dLen));
241 size_t length,
size_t decimalPosition,
250 int dLen =
static_cast<int>(length);
254 int dExpAdjust =
static_cast<int>(length - decimalPosition);
257 int dExp = exp - dExpAdjust;
263 while (dLen > 0 && *decimals ==
'0') {
269 while (dLen > 0 && decimals[dLen - 1] ==
'0') {
279 const int kMaxDecimalDigit = 767 + 1;
280 if (dLen > kMaxDecimalDigit) {
281 dExp += dLen - kMaxDecimalDigit;
282 dLen = kMaxDecimalDigit;
287 if (dLen + dExp <= -324)
return 0.0;
291 if (dLen + dExp > 309)
return std::numeric_limits<double>::infinity();
293 if (
StrtodDiyFp(decimals, dLen, dExp, &result))
return result;
303 #endif // RAPIDJSON_STRTOD_ double StrtodFullPrecision(double d, int p, const char *decimals, size_t length, size_t decimalPosition, int exp)
#define RAPIDJSON_ASSERT(x)
Assertion.
#define RAPIDJSON_UINT64_C2(high32, low32)
Construct a 64-bit literal by a pair of 32-bit integer.
#define RAPIDJSON_NAMESPACE_END
provide custom rapidjson namespace (closing expression)
uint64_t Significand() const
DiyFp GetCachedPower10(int exp, int *outExp)
int Compare(const BigInteger &rhs) const
static int EffectiveSignificandSize(int order)
#define RAPIDJSON_NAMESPACE_BEGIN
provide custom rapidjson namespace (opening expression)
double NextPositiveDouble() const
bool StrtodFast(double d, int p, double *result)
double StrtodNormalPrecision(double d, int p)
int CheckWithinHalfULP(double b, const BigInteger &d, int dExp)
bool StrtodDiyFp(const char *decimals, int dLen, int dExp, double *result)
unsigned __int64 uint64_t
uint64_t IntegerSignificand() const
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
double Pow10(int n)
Computes integer powers of 10 in double (10.0^n).
int IntegerExponent() const
double StrtodBigInteger(double approx, const char *decimals, int dLen, int dExp)
BigInteger & MultiplyPow5(unsigned exp)
static const uint64_t kDpHiddenBit
double FastPath(double significand, int exp)
bool Difference(const BigInteger &rhs, BigInteger *out) const