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.
No comments:
Post a Comment