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:
parent
bc6f05f41b
commit
e587614c22
@ -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");
|
||||
|
@ -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 == '.') {
|
||||
if (_index < _limit && (c == '.' || c == 'e')) {
|
||||
double value2 = value;
|
||||
if (c == '.') {
|
||||
_index++;
|
||||
|
||||
double division = 1;
|
||||
while (_index < _limit && Character.isDigit(c = _text.charAt(_index))) {
|
||||
value = value * 10 + (c - '0');
|
||||
value2 = value2 * 10 + (c - '0');
|
||||
division *= 10;
|
||||
_index++;
|
||||
}
|
||||
|
||||
value /= division;
|
||||
value2 /= 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
|
||||
);
|
||||
}
|
||||
} else if (c == '"' || c == '\'') {
|
||||
/*
|
||||
* String Literal
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user