I implemented a function StringToDouble for converting string to double,but when I test my function and standard strtod function with the same string,the result is different,I dont know why this happened,is it a problem with precision when doing arithmetic with double? and How can I fix my function so it will generate the same result as strtod? thanks. this is StringToDouble I implemented
bool StringToDouble(const char *p, double &num) {
int frac;
double sign, value, scale;
bool canConvert = false;
if (p == NULL || *p == 0) {
num = 0;
return false;
}
// Skip leading white space, if any.
while (white_space(*p)) {
p += 1;
}
// Get sign, if any.
sign = 1.0;
if (*p == '-') {
sign = -1.0;
p += 1;
} else if (*p == '+') {
p += 1;
}
if (valid_digit(*p)) canConvert = true;
// Get digits before decimal point or exponent, if any.
for (value = 0.0; valid_digit(*p); p += 1) {
value = value * 10.0 + (*p - '0');
}
// Get digits after decimal point, if any.
if (*p == '.') {
double pow10 = 10.0;
p += 1;
if (valid_digit(*p)) canConvert = true;
while (valid_digit(*p)) {
value += (*p - '0') / pow10;
pow10 *= 10.0;
p += 1;
}
}
// Handle exponent, if any.
frac = 0;
scale = 1.0;
if ((*p == 'e') || (*p == 'E')) {
unsigned int expon;
// Get sign of exponent, if any.
p += 1;
if (*p == '-') {
frac = 1;
p += 1;
} else if (*p == '+') {
p += 1;
}
// Get digits of exponent, if any.
for (expon = 0; valid_digit(*p); p += 1) {
expon = expon * 10 + (*p - '0');
}
if (expon > 308) expon = 308;
// Calculate scaling factor.
while (expon >= 50) {
scale *= 1E50;
expon -= 50;
}
while (expon >= 8) {
scale *= 1E8;
expon -= 8;
}
while (expon > 0) {
scale *= 10.0;
expon -= 1;
}
}
// Return signed and scaled floating point result.
if (!canConvert) {
num = 0;
return false;
} else {
num = sign * (frac ? (value / scale) : (value * scale));
return true;
}
}
this is the code I use for testing
const char *p = "3e+100";
double d;
StringToDouble(p, d);
double dd = strtod(p, nullptr);
if (d == dd) {
cout.precision(17);
cout << dd << endl
<< d;
} else {
cout.precision(17);
cout << "not equal\n";
cout << dd << endl
<< d;
}
the output is
not equal
2.9999999999999999e+100
3.0000000000000006e+100
I also tested other strings,some get the same result with strtod,some not,all the cases with exponent get different result.