JDK 8 BigInteger Exact Narrowing Conversion Methods
In the blog post "Exact Conversion of Long to Int in Java," I discussed using Math.toIntExact(Long) to exactly convert a Long
to an int
or else throw an ArithmeticException if this narrowing conversion is not possible. That method was introduced with JDK 8, which also introduced similar narrowing conversion methods to the BigInteger class. Those BigInteger
methods are the topic of this post.
BigInteger
had four new "exact" methods added to it in JDK 8:
- byteValueExact() - Converts
BigInteger
value exactly tobyte
if possible - shortValueExact() - Converts
BigInteger
value toshort
if possible - intValueExact() - Converts
BigInteger
value exactly toint
if possible - longValueExact() - Converts
BigInteger
value exactly tolong
if possible
As described above, each of these four "exact" methods added to BigInteger
with JDK 8 allow for the BigInteger
's value to be narrowed to the data type in the method name, if that is possible. Because all of these types (byte
, short
, int
, and long
) have smaller ranges than BigInteger
, it's possible in any of these cases to have a value in BigDecimal
with a magnitude larger than that which can be represented by any of these four types. In such a case, all four of these "Exact" methods throw an ArithmeticException
rather than quietly "forcing" the bigger value into the smaller representation (which is typically a nonsensical number for most contexts).
Examples of using these methods can be found on GitHub. When those examples are executed, the output looks like this:
===== Byte =====
125 => 125
126 => 126
127 => 127
128 => java.lang.ArithmeticException: BigInteger out of byte range
129 => java.lang.ArithmeticException: BigInteger out of byte range
===== Short =====
32765 => 32765
32766 => 32766
32767 => 32767
32768 => java.lang.ArithmeticException: BigInteger out of short range
32769 => java.lang.ArithmeticException: BigInteger out of short range
===== Int =====
2147483645 => 2147483645
2147483646 => 2147483646
2147483647 => 2147483647
2147483648 => java.lang.ArithmeticException: BigInteger out of int range
2147483649 => java.lang.ArithmeticException: BigInteger out of int range
===== Long =====
9223372036854775805 => 9223372036854775805
9223372036854775806 => 9223372036854775806
9223372036854775807 => 9223372036854775807
9223372036854775808 => java.lang.ArithmeticException: BigInteger out of long range
9223372036854775809 => java.lang.ArithmeticException: BigInteger out of long range
The addition of these "exact" methods to BigInteger
with JDK 8 is a welcome one because errors associated with numeric narrowing and overflow can be subtle. It's nice to have an easy way to get an "exact" narrowing or else have the inability to do that narrowing exactly made obvious via an exception.
Comments
Post a Comment