These Numbers can have overflow and rounding errors if converted to an int value. A double is the safest default choice. (Even for long it should be fine.)
The following program prints forConstantValue(-1) is NEVER forConstantValue2(-1) is NEVER forConstantValue(-0.1) is ALWAYS // rounded to 0. forConstantValue2(-0.1) is NEVER forConstantValue(-9999999999) is NEVER forConstantValue2(-9999999999) is NEVER forConstantValue(-999999999999) is ALWAYS // overflow to a postive number. forConstantValue2(-999999999999) is NEVER forConstantValue(9999999999) is ALWAYS forConstantValue2(9999999999) is ALWAYS forConstantValue(999999999999) is NEVER // overflow to a negative number. forConstantValue2(999999999999) is ALWAYS forConstantValue(NaN) is ALWAYS // Is not signed e.g. should fail @Signed test. forConstantValue2(NaN) is UNKNOWN
public static void main(String... args) { for (Number n : new Number[]{ new BigDecimal("-1"), new BigDecimal("-0.1"), new BigInteger("-9999999999"), new BigInteger("-999999999999"), new BigInteger("9999999999"), new BigInteger("999999999999"), Double.NaN, }) { System.out.println("forConstantValue(" + n + ") is " + forConstantValue(n)); System.out.println("forConstantValue2(" + n + ") is " + forConstantValue2(n)); } }
// from Nonnegative public static When forConstantValue(Object v) { if (!(v instanceof Number)) return When.NEVER; boolean isNegative; Number value = (Number) v; if (value instanceof Long) isNegative = value.longValue() < 0; else if (value instanceof Double) isNegative = value.doubleValue() < 0; else if (value instanceof Float) isNegative = value.floatValue() < 0; else isNegative = value.intValue() < 0;
if (isNegative)
return When.NEVER;
else
return When.ALWAYS;
}
public static When forConstantValue2(Object v) { if (!(v instanceof Number)) return When.NEVER;
double value = ((Number) v).doubleValue();
if (Double.isNaN(value))
return When.UNKNOWN;
else
return value < 0 ? When.NEVER : When.ALWAYS;
}
> What steps will reproduce the problem? 1. run the program above
> What is the expected output? forConstantValue2
> What do you see instead? In valid conversion of BigInteger and BigDecimal
Status: New
Labels:
Type-Defect
Priority-Medium