strtod method
Converts the string nptr to a double.
Trims leading whitespace, handles optional signs, INF, NAN, and scientific notation.
Stops at the first invalid character.
If endptr is provided, endptr[0] is set to the unparsed remainder of the string.
Implementation
double strtod(String nptr, {List<String>? endptr}) {
if (nptr.isEmpty) {
if (endptr != null && endptr.isNotEmpty) endptr[0] = nptr;
return 0.0;
}
int i = 0;
while (i < nptr.length) {
int c = nptr.codeUnitAt(i);
if (c == 32 || (c >= 9 && c <= 13)) {
i++;
} else {
break;
}
}
if (i >= nptr.length) {
if (endptr != null && endptr.isNotEmpty) endptr[0] = nptr;
return 0.0;
}
int start = i;
bool negative = false;
int c = nptr.codeUnitAt(i);
if (c == 45) { // '-'
negative = true;
i++;
} else if (c == 43) { // '+'
i++;
}
String upper = nptr.substring(i).toUpperCase();
if (upper.startsWith("INFINITY")) {
i += 8;
if (endptr != null && endptr.isNotEmpty) endptr[0] = nptr.substring(i);
return negative ? double.negativeInfinity : double.infinity;
} else if (upper.startsWith("INF")) {
i += 3;
if (endptr != null && endptr.isNotEmpty) endptr[0] = nptr.substring(i);
return negative ? double.negativeInfinity : double.infinity;
} else if (upper.startsWith("NAN")) {
i += 3;
if (endptr != null && endptr.isNotEmpty) endptr[0] = nptr.substring(i);
return double.nan;
}
bool hasDigits = false;
bool hasDot = false;
while (i < nptr.length) {
c = nptr.codeUnitAt(i);
if (c >= 48 && c <= 57) {
hasDigits = true;
i++;
} else if (c == 46 && !hasDot) { // '.'
hasDot = true;
i++;
} else {
break;
}
}
if (!hasDigits) {
if (endptr != null && endptr.isNotEmpty) endptr[0] = nptr;
return 0.0;
}
// Check for exponent
if (i < nptr.length) {
c = nptr.codeUnitAt(i);
if (c == 101 || c == 69) { // 'e' or 'E'
int expStart = i;
i++;
if (i < nptr.length) {
c = nptr.codeUnitAt(i);
if (c == 45 || c == 43) i++;
}
bool hasExpDigits = false;
while (i < nptr.length) {
c = nptr.codeUnitAt(i);
if (c >= 48 && c <= 57) {
hasExpDigits = true;
i++;
} else {
break;
}
}
if (!hasExpDigits) {
i = expStart;
}
}
}
if (endptr != null && endptr.isNotEmpty) {
endptr[0] = nptr.substring(i);
}
String valStr = nptr.substring(start, i);
return double.tryParse(valStr) ?? 0.0;
}