Search code examples
javabigintegerbigdecimal

Bug in Number or BigInteger and BigDecimal (or alternatively in the API documentation of those)?


According to the specification of Number.longValue() the method should...

Returns the value of the specified number as a long. This may involve rounding or truncation.

However, the BigInteger (and BigDecimal) overrides this method and returns the 64 low bits of the integer part of the number it represents. From the docs of BigInteger for example:

[...]if this BigInteger is too big to fit in a long, only the low-order 64 bits are returned.[...]

I claim that either "This may involve rounding or truncation." doesn't say anything about what the method actually should return, or, there is a bug in implementation or documentation.

Would you agree, or do I have a mistake in my reasoning?


Example code:

import java.math.BigInteger;
import static java.math.BigInteger.*;

public class Main {
    public static void main(String[] args) {

        BigInteger i = valueOf(Long.MAX_VALUE);

        // Result: Long.MAX_VALUE, just as expected.
        Number n1 = i;
        System.out.println(n1 + " -> " + n1.longValue());

        // I expect to get the "rounded" value Long.MAX_VALUE
        Number n2 = i.add(ONE);
        System.out.println(n2 + " -> " + n2.longValue());

        // I expect to get the "rounded" value Long.MAX_VALUE
        Number n3 = i.multiply(TEN);
        System.out.println(n3 + " -> " + n3.longValue());
    }
}

Output:

9223372036854775807 -> 9223372036854775807
9223372036854775808 -> -9223372036854775808
92233720368547758070 -> -10

Solution

  • The wording "This may involve rounding or truncation" appears in the javadocs for the longValue(), shortValue(), charValue() and byteValue() of Number, so it is clear that "truncation" is intended to include loss of significant high order bits in some cases.

    The problem really is that the term "truncation" conventionally means loss of lower order bits. (That's how I remember it from my numerical analysis course, 30 years ago. And Wikipedia agrees.)

    By contrast, the JLS 5.1.3 describes the same process (when narrowing integral primitive types) as follows:

    A narrowing conversion of a signed integer to an integral type T simply discards all but the n lowest order bits, where n is the number of bits used to represent type T.

    So yes, I agree that the javadoc is incorrect. Submit a bug report.

    NOTE

    I had originally deleted this because I thought my suggestion to submit a bug report was probably futile (based on my past experience with documentation bug reports). But @aioobe has submitted a bug report ... (Bug ID: 7000825)