#### Weird behaviour

No. 217

Q:

We consider a method computing a given int's square value:

static public int getSquare (int value) {
return value * value;
}

A larger piece of software using this method produces erroneous results. Tracing for possible errors the developing team adds a logging statement:

static public int getSquare (int value) {
final int result = value * value;
log.info(result);
return result;
}

The team is baffled: Albeit squares of integer values are expected to be strictly positive occasionally negative results show up:

INFO  [main] sd1.SupportMethods (SupportMethods.java:15) - -1757895751
1. Explain the underlying reason.

2. You are allowed to modify the method's return type. Provide a solution.

A:

1. The problem is caused by arithmetic overflow errors. The largest possible int is $2 31 - 1$ or 2147483647. Its square root is 46340.95... .Thus up to the value of 46340 all squares are being calculated correctly e.g.:

Code Result
System.out.println(46340 * 46340);
2147395600

The product 46341 * 46341 of type int for example exceeds $2 31 - 1$ for the very first time. Due to an int's four-byte two complement representation we have:

Code Result
System.out.println(46341 * 46341);
-2147479015

Starting from 46341 all computed squares are simply wrong due to arithmetic overflow regardless of their result's sign.

2. Solving the issue requires a data type to accommodate squares of arbitrary int values. The smallest int value (having maximum amount) is $- 2 31$. Its square is thus $2 62$ representing the method's largest possible result. Choosing return type long allows for a maximum value of $2 63 - 1$being ways larger than required. Turning the int into a long expression is easy:

static public long getSquare (int value) {
final long result = (long) value * value; // Cast: long * int expression
log.info(result);
return result;
}