131inline bool StrtodDiyFp(
const char* decimals,
int dLen,
int dExp,
double* result) {
134 for (; i < dLen; i++) {
138 significand = significand * 10u +
static_cast<unsigned>(decimals[i] -
'0');
141 if (i < dLen && decimals[i] >=
'5')
144 int remaining = dLen - i;
145 const int kUlpShift = 3;
146 const int kUlp = 1 << kUlpShift;
147 int64_t error = (remaining == 0) ? 0 : kUlp / 2;
149 DiyFp v(significand, 0);
157 if (actualExp != dExp) {
158 static const DiyFp kPow10[] = {
167 int adjustment = dExp - actualExp;
169 v = v * kPow10[adjustment - 1];
170 if (dLen + adjustment > 19)
176 error += kUlp + (error == 0 ? 0 : 1);
178 const int oldExp = v.
e;
180 error <<= oldExp - v.
e;
183 int precisionSize = 64 - effectiveSignificandSize;
184 if (precisionSize + kUlpShift >= 64) {
185 int scaleExp = (precisionSize + kUlpShift) - 63;
188 error = (error >> scaleExp) + 1 + kUlp;
189 precisionSize -= scaleExp;
192 DiyFp rounded(v.
f >> precisionSize, v.
e + precisionSize);
193 const uint64_t precisionBits = (v.
f & ((
uint64_t(1) << precisionSize) - 1)) * kUlp;
195 if (precisionBits >= halfWay +
static_cast<unsigned>(error)) {
205 return halfWay -
static_cast<unsigned>(error) >= precisionBits || precisionBits >= halfWay +
static_cast<unsigned>(error);
226inline double StrtodFullPrecision(
double d,
int p,
const char* decimals,
size_t length,
size_t decimalPosition,
int exp) {
235 int dLen =
static_cast<int>(length);
239 int dExpAdjust =
static_cast<int>(length - decimalPosition);
242 int dExp = exp - dExpAdjust;
248 while (dLen > 0 && *decimals ==
'0') {
254 while (dLen > 0 && decimals[dLen - 1] ==
'0') {
264 const int kMaxDecimalDigit = 767 + 1;
265 if (dLen > kMaxDecimalDigit) {
266 dExp += dLen - kMaxDecimalDigit;
267 dLen = kMaxDecimalDigit;
272 if (dLen + dExp <= -324)
277 if (dLen + dExp > 309)
278 return std::numeric_limits<double>::infinity();