Browse Source

implement floating point number formatting which matches access

git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/branches/exprs@1159 f203690c-595d-4dc9-a70b-905162fa7fd2
tags/jackcess-2.2.0
James Ahlborn 6 years ago
parent
commit
6d200f6948

+ 3
- 8
src/main/java/com/healthmarketscience/jackcess/impl/expr/BaseNumericValue.java View File

@@ -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()));

+ 3
- 2
src/main/java/com/healthmarketscience/jackcess/impl/expr/BaseValue.java View File

@@ -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() + "'";

+ 4
- 2
src/main/java/com/healthmarketscience/jackcess/impl/expr/BigDecimalValue.java View File

@@ -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

+ 12
- 11
src/main/java/com/healthmarketscience/jackcess/impl/expr/BuiltinOperators.java View File

@@ -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) {

+ 2
- 1
src/main/java/com/healthmarketscience/jackcess/impl/expr/DefaultFunctions.java View File

@@ -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);
}
});

+ 3
- 2
src/main/java/com/healthmarketscience/jackcess/impl/expr/DefaultNumberFunctions.java View File

@@ -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);
}
});

+ 8
- 1
src/main/java/com/healthmarketscience/jackcess/impl/expr/DoubleValue.java View File

@@ -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);
}
}

+ 6
- 1
src/main/java/com/healthmarketscience/jackcess/impl/expr/LongValue.java View File

@@ -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();
}
}

+ 4
- 3
src/test/java/com/healthmarketscience/jackcess/impl/expr/ExpressionatorTest.java View File

@@ -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) {

Loading…
Cancel
Save