Fixed Issue 126: Large integers formatted in scientific notation in formulas

git-svn-id: http://google-refine.googlecode.com/svn/trunk@1373 7d457c2a-affb-35e4-300a-418c747d4874
This commit is contained in:
David Huynh 2010-09-28 04:21:44 +00:00
parent bc6f05f41b
commit e587614c22
3 changed files with 71 additions and 30 deletions

View File

@ -155,7 +155,10 @@ public class Parser {
next(true);
if (_token != null && _token.type == TokenType.Number) {
eval = new LiteralExpr(-((NumberToken)_token).value);
Number n = ((NumberToken)_token).value;
eval = new LiteralExpr(n instanceof Long ? -n.longValue() : -n.doubleValue());
next(false);
} else {
throw makeException("Bad negative number");

View File

@ -35,9 +35,9 @@ public class Scanner {
}
static public class NumberToken extends Token {
final public double value;
final public Number value;
public NumberToken(int start, int end, String text, double value) {
public NumberToken(int start, int end, String text, Number value) {
super(start, end, TokenType.Number, text);
this.value = value;
}
@ -94,34 +94,44 @@ public class Scanner {
String detail = null;
if (Character.isDigit(c)) { // number literal
double value = 0;
long value = 0;
while (_index < _limit && Character.isDigit(c = _text.charAt(_index))) {
value = value * 10 + (c - '0');
_index++;
}
if (_index < _limit && c == '.') {
_index++;
double division = 1;
while (_index < _limit && Character.isDigit(c = _text.charAt(_index))) {
value = value * 10 + (c - '0');
division *= 10;
if (_index < _limit && (c == '.' || c == 'e')) {
double value2 = value;
if (c == '.') {
_index++;
double division = 1;
while (_index < _limit && Character.isDigit(c = _text.charAt(_index))) {
value2 = value2 * 10 + (c - '0');
division *= 10;
_index++;
}
value2 /= division;
}
value /= division;
// TODO: support exponent e notation
return new NumberToken(
start,
_index,
_text.substring(start, _index),
value2
);
} else {
return new NumberToken(
start,
_index,
_text.substring(start, _index),
value
);
}
// TODO: support exponent e notation
return new NumberToken(
start,
_index,
_text.substring(start, _index),
value
);
} else if (c == '"' || c == '\'') {
/*
* String Literal

View File

@ -29,23 +29,47 @@ public class OperatorCallExpr implements Evaluable {
if (args.length == 2) {
if (args[0] != null && args[1] != null) {
if (args[0] instanceof Number && args[1] instanceof Number) {
if (isIntegral(args[0]) && isIntegral(args[1])) {
long n1 = ((Number) args[0]).longValue();
long n2 = ((Number) args[1]).longValue();
if ("+".equals(_op)) {
return ((Number) args[0]).doubleValue() + ((Number) args[1]).doubleValue();
return n1 + n2;
} else if ("-".equals(_op)) {
return ((Number) args[0]).doubleValue() - ((Number) args[1]).doubleValue();
return n1 - n2;
} else if ("*".equals(_op)) {
return ((Number) args[0]).doubleValue() * ((Number) args[1]).doubleValue();
return n1 * n2;
} else if ("/".equals(_op)) {
return ((Number) args[0]).doubleValue() / ((Number) args[1]).doubleValue();
return n1 / n2;
} else if (">".equals(_op)) {
return ((Number) args[0]).doubleValue() > ((Number) args[1]).doubleValue();
return n1 > n2;
} else if (">=".equals(_op)) {
return ((Number) args[0]).doubleValue() >= ((Number) args[1]).doubleValue();
return n1 >= n2;
} else if ("<".equals(_op)) {
return ((Number) args[0]).doubleValue() < ((Number) args[1]).doubleValue();
return n1 < n2;
} else if ("<=".equals(_op)) {
return ((Number) args[0]).doubleValue() <= ((Number) args[1]).doubleValue();
return n1 <= n2;
}
} else if (args[0] instanceof Number && args[1] instanceof Number) {
double n1 = ((Number) args[0]).doubleValue();
double n2 = ((Number) args[1]).doubleValue();
if ("+".equals(_op)) {
return n1 + n2;
} else if ("-".equals(_op)) {
return n1 - n2;
} else if ("*".equals(_op)) {
return n1 * n2;
} else if ("/".equals(_op)) {
return n1 / n2;
} else if (">".equals(_op)) {
return n1 > n2;
} else if (">=".equals(_op)) {
return n1 >= n2;
} else if ("<".equals(_op)) {
return n1 < n2;
} else if ("<=".equals(_op)) {
return n1 <= n2;
}
}
@ -86,4 +110,8 @@ public class OperatorCallExpr implements Evaluable {
return sb.toString();
}
private boolean isIntegral(Object n) {
return n instanceof Long || n instanceof Integer;
}
}