Export to GitHub

jsr-305 - issue #7

It worth nothing that BigInteger and BigDecimal are Number's.


Posted on Jan 27, 2009 by Helpful Horse

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 &lt; 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