git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/branches/exprs@1159 f203690c-595d-4dc9-a70b-905162fa7fd2tags/jackcess-2.2.0
@@ -26,18 +26,13 @@ import com.healthmarketscience.jackcess.impl.ColumnImpl; | |||
* | |||
* @author James Ahlborn | |||
*/ | |||
public abstract class BaseNumericValue extends BaseValue | |||
public abstract class BaseNumericValue extends BaseValue | |||
{ | |||
protected BaseNumericValue() | |||
protected BaseNumericValue() | |||
{ | |||
} | |||
@Override | |||
public String getAsString() { | |||
return getNumber().toString(); | |||
} | |||
@Override | |||
public Integer getAsLongInt() { | |||
return roundToLongInt(); | |||
@@ -51,7 +46,7 @@ public abstract class BaseNumericValue extends BaseValue | |||
@Override | |||
public Date getAsDateTime(EvalContext ctx) { | |||
double d = getNumber().doubleValue(); | |||
SimpleDateFormat sdf = ctx.createDateFormat( | |||
ctx.getTemporalConfig().getDefaultDateTimeFormat()); | |||
return new Date(ColumnImpl.fromDateDouble(d, sdf.getCalendar())); |
@@ -22,6 +22,7 @@ import java.util.Date; | |||
import com.healthmarketscience.jackcess.expr.Value; | |||
import com.healthmarketscience.jackcess.expr.EvalContext; | |||
import com.healthmarketscience.jackcess.expr.EvalException; | |||
import com.healthmarketscience.jackcess.impl.NumberFormatter; | |||
/** | |||
* | |||
@@ -63,10 +64,10 @@ public abstract class BaseValue implements Value | |||
} | |||
protected Integer roundToLongInt() { | |||
return getAsBigDecimal().setScale(0, BuiltinOperators.ROUND_MODE) | |||
return getAsBigDecimal().setScale(0, NumberFormatter.ROUND_MODE) | |||
.intValueExact(); | |||
} | |||
@Override | |||
public String toString() { | |||
return "Value[" + getType() + "] '" + get() + "'"; |
@@ -18,6 +18,8 @@ package com.healthmarketscience.jackcess.impl.expr; | |||
import java.math.BigDecimal; | |||
import com.healthmarketscience.jackcess.impl.NumberFormatter; | |||
/** | |||
* | |||
* @author James Ahlborn | |||
@@ -26,7 +28,7 @@ public class BigDecimalValue extends BaseNumericValue | |||
{ | |||
private final BigDecimal _val; | |||
public BigDecimalValue(BigDecimal val) | |||
public BigDecimalValue(BigDecimal val) | |||
{ | |||
_val = val; | |||
} | |||
@@ -51,7 +53,7 @@ public class BigDecimalValue extends BaseNumericValue | |||
@Override | |||
public String getAsString() { | |||
return _val.toPlainString(); | |||
return NumberFormatter.format(_val); | |||
} | |||
@Override |
@@ -17,8 +17,6 @@ limitations under the License. | |||
package com.healthmarketscience.jackcess.impl.expr; | |||
import java.math.BigDecimal; | |||
import java.math.MathContext; | |||
import java.math.RoundingMode; | |||
import java.text.DateFormat; | |||
import java.util.Date; | |||
import java.util.regex.Pattern; | |||
@@ -27,6 +25,7 @@ import com.healthmarketscience.jackcess.expr.EvalContext; | |||
import com.healthmarketscience.jackcess.expr.EvalException; | |||
import com.healthmarketscience.jackcess.expr.Value; | |||
import com.healthmarketscience.jackcess.impl.ColumnImpl; | |||
import com.healthmarketscience.jackcess.impl.NumberFormatter; | |||
/** | |||
@@ -58,9 +57,6 @@ public class BuiltinOperators | |||
public static final Value EMPTY_STR_VAL = new StringValue(""); | |||
public static final Value ZERO_VAL = FALSE_VAL; | |||
public static final RoundingMode ROUND_MODE = RoundingMode.HALF_EVEN; | |||
public static final MathContext MATH_CONTEXT = | |||
new MathContext(28, ROUND_MODE); | |||
private enum CoercionType { | |||
SIMPLE(true, true), GENERAL(false, true), COMPARE(false, false); | |||
@@ -109,7 +105,8 @@ public class BuiltinOperators | |||
return toValue(-param1.getAsDouble()); | |||
case STRING: | |||
case BIG_DEC: | |||
return toValue(param1.getAsBigDecimal().negate(MATH_CONTEXT)); | |||
return toValue(param1.getAsBigDecimal().negate( | |||
NumberFormatter.DEC_MATH_CONTEXT)); | |||
default: | |||
throw new EvalException("Unexpected type " + mathType); | |||
} | |||
@@ -140,7 +137,8 @@ public class BuiltinOperators | |||
return toValue(param1.getAsDouble() + param2.getAsDouble()); | |||
case BIG_DEC: | |||
return toValue(param1.getAsBigDecimal().add( | |||
param2.getAsBigDecimal(), MATH_CONTEXT)); | |||
param2.getAsBigDecimal(), | |||
NumberFormatter.DEC_MATH_CONTEXT)); | |||
default: | |||
throw new EvalException("Unexpected type " + mathType); | |||
} | |||
@@ -169,7 +167,8 @@ public class BuiltinOperators | |||
return toValue(param1.getAsDouble() - param2.getAsDouble()); | |||
case BIG_DEC: | |||
return toValue(param1.getAsBigDecimal().subtract( | |||
param2.getAsBigDecimal(), MATH_CONTEXT)); | |||
param2.getAsBigDecimal(), | |||
NumberFormatter.DEC_MATH_CONTEXT)); | |||
default: | |||
throw new EvalException("Unexpected type " + mathType); | |||
} | |||
@@ -195,7 +194,8 @@ public class BuiltinOperators | |||
return toValue(param1.getAsDouble() * param2.getAsDouble()); | |||
case BIG_DEC: | |||
return toValue(param1.getAsBigDecimal().multiply( | |||
param2.getAsBigDecimal(), MATH_CONTEXT)); | |||
param2.getAsBigDecimal(), | |||
NumberFormatter.DEC_MATH_CONTEXT)); | |||
default: | |||
throw new EvalException("Unexpected type " + mathType); | |||
} | |||
@@ -263,7 +263,8 @@ public class BuiltinOperators | |||
// (must be a positive int exponent) | |||
try { | |||
BigDecimal result = param1.getAsBigDecimal().pow( | |||
param2.getAsBigDecimal().intValueExact(), MATH_CONTEXT); | |||
param2.getAsBigDecimal().intValueExact(), | |||
NumberFormatter.DEC_MATH_CONTEXT); | |||
return toValue(result); | |||
} catch(ArithmeticException ae) { | |||
// fall back to general handling via doubles... | |||
@@ -764,7 +765,7 @@ public class BuiltinOperators | |||
} | |||
static BigDecimal divide(BigDecimal num, BigDecimal denom) { | |||
return num.divide(denom, MATH_CONTEXT); | |||
return num.divide(denom, NumberFormatter.DEC_MATH_CONTEXT); | |||
} | |||
static boolean isIntegral(double d) { |
@@ -27,6 +27,7 @@ import com.healthmarketscience.jackcess.expr.Function; | |||
import com.healthmarketscience.jackcess.expr.FunctionLookup; | |||
import com.healthmarketscience.jackcess.expr.Value; | |||
import com.healthmarketscience.jackcess.impl.DatabaseImpl; | |||
import com.healthmarketscience.jackcess.impl.NumberFormatter; | |||
/** | |||
* | |||
@@ -365,7 +366,7 @@ public class DefaultFunctions | |||
@Override | |||
protected Value eval1(EvalContext ctx, Value param1) { | |||
BigDecimal bd = param1.getAsBigDecimal(); | |||
bd = bd.setScale(4, BuiltinOperators.ROUND_MODE); | |||
bd = bd.setScale(4, NumberFormatter.ROUND_MODE); | |||
return BuiltinOperators.toValue(bd); | |||
} | |||
}); |
@@ -22,6 +22,7 @@ import com.healthmarketscience.jackcess.expr.EvalContext; | |||
import com.healthmarketscience.jackcess.expr.EvalException; | |||
import com.healthmarketscience.jackcess.expr.Function; | |||
import com.healthmarketscience.jackcess.expr.Value; | |||
import com.healthmarketscience.jackcess.impl.NumberFormatter; | |||
import static com.healthmarketscience.jackcess.impl.expr.DefaultFunctions.*; | |||
/** | |||
@@ -56,7 +57,7 @@ public class DefaultNumberFunctions | |||
case STRING: | |||
case BIG_DEC: | |||
return BuiltinOperators.toValue(param1.getAsBigDecimal().abs( | |||
BuiltinOperators.MATH_CONTEXT)); | |||
NumberFormatter.DEC_MATH_CONTEXT)); | |||
default: | |||
throw new EvalException("Unexpected type " + mathType); | |||
} | |||
@@ -138,7 +139,7 @@ public class DefaultNumberFunctions | |||
scale = params[1].getAsLongInt(); | |||
} | |||
BigDecimal bd = param1.getAsBigDecimal() | |||
.setScale(scale, BuiltinOperators.ROUND_MODE); | |||
.setScale(scale, NumberFormatter.ROUND_MODE); | |||
return BuiltinOperators.toValue(bd); | |||
} | |||
}); |
@@ -18,6 +18,8 @@ package com.healthmarketscience.jackcess.impl.expr; | |||
import java.math.BigDecimal; | |||
import com.healthmarketscience.jackcess.impl.NumberFormatter; | |||
/** | |||
* | |||
* @author James Ahlborn | |||
@@ -26,7 +28,7 @@ public class DoubleValue extends BaseNumericValue | |||
{ | |||
private final Double _val; | |||
public DoubleValue(Double val) | |||
public DoubleValue(Double val) | |||
{ | |||
_val = val; | |||
} | |||
@@ -58,4 +60,9 @@ public class DoubleValue extends BaseNumericValue | |||
public BigDecimal getAsBigDecimal() { | |||
return BigDecimal.valueOf(_val); | |||
} | |||
@Override | |||
public String getAsString() { | |||
return NumberFormatter.format(_val); | |||
} | |||
} |
@@ -26,7 +26,7 @@ public class LongValue extends BaseNumericValue | |||
{ | |||
private final Integer _val; | |||
public LongValue(Integer val) | |||
public LongValue(Integer val) | |||
{ | |||
_val = val; | |||
} | |||
@@ -58,4 +58,9 @@ public class LongValue extends BaseNumericValue | |||
public BigDecimal getAsBigDecimal() { | |||
return BigDecimal.valueOf(_val); | |||
} | |||
@Override | |||
public String getAsString() { | |||
return _val.toString(); | |||
} | |||
} |
@@ -30,6 +30,7 @@ import com.healthmarketscience.jackcess.expr.Function; | |||
import com.healthmarketscience.jackcess.expr.Identifier; | |||
import com.healthmarketscience.jackcess.expr.TemporalConfig; | |||
import com.healthmarketscience.jackcess.expr.Value; | |||
import com.healthmarketscience.jackcess.impl.NumberFormatter; | |||
import junit.framework.TestCase; | |||
/** | |||
@@ -326,7 +327,7 @@ public class ExpressionatorTest extends TestCase | |||
public void testLiteralDefaultValue() throws Exception | |||
{ | |||
assertEquals("-28.0 blah ", eval("=CDbl(9)-37 & \" blah \"", | |||
assertEquals("-28 blah ", eval("=CDbl(9)-37 & \" blah \"", | |||
Value.Type.STRING)); | |||
assertEquals("CDbl(9)-37 & \" blah \"", | |||
eval("CDbl(9)-37 & \" blah \"", Value.Type.STRING)); | |||
@@ -385,12 +386,12 @@ public class ExpressionatorTest extends TestCase | |||
} | |||
static int roundToLongInt(double d) { | |||
return new BigDecimal(d).setScale(0, BuiltinOperators.ROUND_MODE) | |||
return new BigDecimal(d).setScale(0, NumberFormatter.ROUND_MODE) | |||
.intValueExact(); | |||
} | |||
static BigDecimal toBD(double d) { | |||
return toBD(new BigDecimal("" + d)); | |||
return toBD(BigDecimal.valueOf(d)); | |||
} | |||
static BigDecimal toBD(BigDecimal bd) { |