parse static method
Converts a string representation of a real number into a DoubleDouble value. The format accepted is similar to the standard Java real number syntax. It is defined by the following regular expression:
[+|-] {digit} [ . {digit} ] [ ( e | E ) [+|-] {digit}+
@param str the string to parse @return the value of the parsed number @throws NumberFormatException if str is not a valid representation of a number
Implementation
static DD parse(String str) {
int i = 0;
int strlen = str.length;
// skip leading whitespace
String strTrim = str.trimLeft();
//while ( Character.isWhitespace(str.charAt(i)))
//i++;
// check for sign
bool isNegative = false;
if (i < strlen) {
String signCh = strTrim[i];
if (signCh == '-' || signCh == '+') {
i++;
if (signCh == '-') isNegative = true;
}
}
// scan all digits and accumulate into an integral value
// Keep track of the location of the decimal point (if any) to allow scaling later
DD val = new DD.empty();
int numDigits = 0;
int numBeforeDec = 0;
int exp = 0;
bool hasDecimalChar = false;
while (true) {
if (i >= strlen) break;
String ch = str[i];
i++;
if (StringUtils.isDigit(ch, 0)) {
double d = (ch.codeUnitAt(0) - '0'.codeUnitAt(0)).toDouble();
val.selfMultiplyDD(TEN);
// MD: need to optimize this
val.selfAdd(d);
numDigits++;
continue;
}
if (ch == '.') {
numBeforeDec = numDigits;
hasDecimalChar = true;
continue;
}
if (ch == 'e' || ch == 'E') {
String expStr = str.substring(i);
// this should catch any format problems with the exponent
try {
exp = int.parse(expStr);
} catch (ex) {
throw new ArgumentError("Invalid exponent $expStr in string $str");
}
break;
}
throw new ArgumentError(
"Unexpected character '$ch' at position $i in string $str");
}
DD val2 = val;
// correct number of digits before decimal sign if we don't have a decimal sign in the string
if (!hasDecimalChar) numBeforeDec = numDigits;
// scale the number correctly
int numDecPlaces = numDigits - numBeforeDec - exp;
if (numDecPlaces == 0) {
val2 = val;
} else if (numDecPlaces > 0) {
DD scale = TEN.pow(numDecPlaces);
val2 = val.divideDD(scale);
} else if (numDecPlaces < 0) {
DD scale = TEN.pow(-numDecPlaces);
val2 = val.multiplyDD(scale);
}
// apply leading sign, if any
if (isNegative) {
return val2.negate();
}
return val2;
}