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);
|
next(true);
|
||||||
|
|
||||||
if (_token != null && _token.type == TokenType.Number) {
|
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);
|
next(false);
|
||||||
} else {
|
} else {
|
||||||
throw makeException("Bad negative number");
|
throw makeException("Bad negative number");
|
||||||
|
@ -35,9 +35,9 @@ public class Scanner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static public class NumberToken extends Token {
|
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);
|
super(start, end, TokenType.Number, text);
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
@ -94,34 +94,44 @@ public class Scanner {
|
|||||||
String detail = null;
|
String detail = null;
|
||||||
|
|
||||||
if (Character.isDigit(c)) { // number literal
|
if (Character.isDigit(c)) { // number literal
|
||||||
double value = 0;
|
long value = 0;
|
||||||
|
|
||||||
while (_index < _limit && Character.isDigit(c = _text.charAt(_index))) {
|
while (_index < _limit && Character.isDigit(c = _text.charAt(_index))) {
|
||||||
value = value * 10 + (c - '0');
|
value = value * 10 + (c - '0');
|
||||||
_index++;
|
_index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_index < _limit && c == '.') {
|
if (_index < _limit && (c == '.' || c == 'e')) {
|
||||||
_index++;
|
double value2 = value;
|
||||||
|
if (c == '.') {
|
||||||
double division = 1;
|
|
||||||
while (_index < _limit && Character.isDigit(c = _text.charAt(_index))) {
|
|
||||||
value = value * 10 + (c - '0');
|
|
||||||
division *= 10;
|
|
||||||
_index++;
|
_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 == '\'') {
|
} else if (c == '"' || c == '\'') {
|
||||||
/*
|
/*
|
||||||
* String Literal
|
* String Literal
|
||||||
|
@ -29,23 +29,47 @@ public class OperatorCallExpr implements Evaluable {
|
|||||||
|
|
||||||
if (args.length == 2) {
|
if (args.length == 2) {
|
||||||
if (args[0] != null && args[1] != null) {
|
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)) {
|
if ("+".equals(_op)) {
|
||||||
return ((Number) args[0]).doubleValue() + ((Number) args[1]).doubleValue();
|
return n1 + n2;
|
||||||
} else if ("-".equals(_op)) {
|
} else if ("-".equals(_op)) {
|
||||||
return ((Number) args[0]).doubleValue() - ((Number) args[1]).doubleValue();
|
return n1 - n2;
|
||||||
} else if ("*".equals(_op)) {
|
} else if ("*".equals(_op)) {
|
||||||
return ((Number) args[0]).doubleValue() * ((Number) args[1]).doubleValue();
|
return n1 * n2;
|
||||||
} else if ("/".equals(_op)) {
|
} else if ("/".equals(_op)) {
|
||||||
return ((Number) args[0]).doubleValue() / ((Number) args[1]).doubleValue();
|
return n1 / n2;
|
||||||
} else if (">".equals(_op)) {
|
} else if (">".equals(_op)) {
|
||||||
return ((Number) args[0]).doubleValue() > ((Number) args[1]).doubleValue();
|
return n1 > n2;
|
||||||
} else if (">=".equals(_op)) {
|
} else if (">=".equals(_op)) {
|
||||||
return ((Number) args[0]).doubleValue() >= ((Number) args[1]).doubleValue();
|
return n1 >= n2;
|
||||||
} else if ("<".equals(_op)) {
|
} else if ("<".equals(_op)) {
|
||||||
return ((Number) args[0]).doubleValue() < ((Number) args[1]).doubleValue();
|
return n1 < n2;
|
||||||
} else if ("<=".equals(_op)) {
|
} 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();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isIntegral(Object n) {
|
||||||
|
return n instanceof Long || n instanceof Integer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user