37. Multiplying two large int/long values and operation overflow

Let's dive into the solution starting from the * operator, as shown in the following example:

int x = 10;
int y = 5;
int z = x * y; // 50

This is a very simple approach and works fine for most of the computations that involve int, long, float, and double as well.

Now, let's apply this operator to the following two large numbers (multiply 2,147,483,647 with itself):

int x = Integer.MAX_VALUE;
int y = Integer.MAX_VALUE;
int z = x * y; // 1

This time, z will be equal to 1, which is not the expected result, that is, 4,611,686,014,132,420,609. Changing only the z type from int to long will not help. However, changing the types of x and y from int to long will:

long x = Integer.MAX_VALUE;
long y = Integer.MAX_VALUE;
long z = x * y; // 4611686014132420609

But the problem will reappear if we have Long.MAX_VALUE instead of Integer.MAX_VALUE:

long x = Long.MAX_VALUE;
long y = Long.MAX_VALUE;
long z = x * y; // 1

So, computations that overflow the domain and rely on the * operator will end up in misleading results.

Instead of using these results in further computations, it is better to be informed on time when an overflow operation occurred. JDK 8 comes with the Math.multiplyExact() method. This method tries to multiply two integers. If the result overflows, int will just throw ArithmeticException:

int x = Integer.MAX_VALUE;
int y = Integer.MAX_VALUE;
int z = Math.multiplyExact(x, y); // throw ArithmeticException
In JDK 8, Math.muliplyExact(int x, int y) returns int and Math.muliplyExact(long x, long y) returns long. In JDK 9, Math.muliplyExact(long, int y) returning long was added as well.

JDK 9 comes with Math.multiplyFull(int x, int y) returning long value. This method is very useful for obtaining the exact mathematical product of two integers as long, as follows:

int x = Integer.MAX_VALUE;
int y = Integer.MAX_VALUE;
long z = Math.multiplyFull(x, y); // 4611686014132420609

Just for the record, JDK 9 also comes with a method named Math.muliptlyHigh(long x, long y) returning a long. The long value returned by this method represents the most significant 64 bits of the 128-bit product of two 64-bit factors:

long x = Long.MAX_VALUE;
long y = Long.MAX_VALUE;
// 9223372036854775807 * 9223372036854775807 = 4611686018427387903
long z = Math.multiplyHigh(x, y);

In a functional style context, a potential solution will rely on the BinaryOperator functional interface, as follows (simply define the operation of the two operands of the same type):

int x = Integer.MAX_VALUE;
int y = Integer.MAX_VALUE;
BinaryOperator<Integer> operator = Math::multiplyExact;
int z = operator.apply(x, y); // throw ArithmeticException

For working with a large number, also focus on the BigInteger (immutable arbitrary-precision integers) and BigDecimal (immutable, arbitrary-precision signed decimal numbers) classes.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset