2

I was looking for a value of i where i==i+1 should always be true. Some others used double and float to find a solution to the problem.

I was trying to answer to a question on stack overflow. And thought about integers, trying to see if that could be possible too.

But while manipulating Integer.MAX_VALUE and Integer.MIN_VALUE many times, I found this strange behavior:

Integer.MAX_VALUE + 1 == Integer.MIN_VALUE

But Integer.MAX_VALUE * 2 == -2 and Integer.MAX_VALUE * 4 == -4

This happens only if I use even values like (2,4,6,8,10,12...). When I use odd values except 1, this happens:

Integer.MAX_VALUE * n == Integer.MAX_VALUE - n + 1 where n != Integer.MIN_VALUE and n > Integer.MIN_VALUE

Why is this behaving so? Is there something I am missing?

EDIT: I saw someone flagging the question as duplicate but navigating to the referred link, my question is different.

If it overflows, it goes back to the minimum value and continues from >there. If it underflows, it goes back to the maximum value and continues >from there.

I've carefully read answers from there but none of them explained why:

Integer.MAX_VALUE*x should be -x if x is an even number and Integer.MAX_VALUE*y should be Integer.MAX_VALUE-y+1 if y is an odd number.

That's exactly what is confusing me the most.

Gratien Asimbahwe
  • 1,606
  • 4
  • 19
  • 30

2 Answers2

3

That's because Java's signed integers follow two's complement representation.

In a two's complement representation, negative numbers are represented as an N-bit complement of their corresponding positive value, i.e. their sum modulo 2n is 0.

Integer.MAX_VALUE is 2147483647 (hex 0x7FFFFFFF). When multiplied, it overflows, and what remains is the lowest 32 bits (i.e. modulo 232):

0x7FFFFFFF * 2 = 0x0FFFFFFFE (mod32 = 0xFFFFFFFE = -2)
0x7FFFFFFF * 3 = 0x17FFFFFFD (mod32 = 0x7FFFFFFD = 2147483645)
0x7FFFFFFF * 4 = 0x1FFFFFFFC (mod32 = 0xFFFFFFFC = -4)
0x7FFFFFFF * 5 = 0x27FFFFFFB (mod32 = 0x7FFFFFFB = 2147483643)
0x7FFFFFFF * 6 = 0x2FFFFFFFA (mod32 = 0xFFFFFFFA = -6)
0x7FFFFFFF * 7 = 0x37FFFFFF9 (mod32 = 0x7FFFFFF9 = 2147483641)

An interesting property of two's complement representation is that the highest bit corresponds to the sign of the value.

Notice how the leftmost 7 results in alternating 0/1 bit 31. That bit happens to control the sign of the result, hence the alternating sign.

Why 0x7FFFFFFF * 2 is -2 is because 0x7FFFFFFF in a 31-bit representation (the largest possible representation without overflowing) is -1. And -1 * 2 = -2.

You can achieve a similar result if you take Long.MAX_VALUE and cast the result to int:

long x = Long.MAX_VALUE;
for (int i = 2; i < 8; i++) {
    System.out.println((int)(x * i));
}

Just prints:

-2
-3
-4
-5
-6
-7

Now bit 31 isn't alternating anymore so we get stable results.

rustyx
  • 80,671
  • 25
  • 200
  • 267
1

2147483647 is the max value, now try executing below set of instructions:

int i = 2147483647;
i++;
System.out.println(i);//prints -2147483647 as the 32 bit limit exceeds 

binary equivalent of 2147483647 is 01111111111111111111111111111111
binary equivalent of 2 is 00000000000000000000000000000010

binary addition is 110000000000000000000000000000000

NOTE: The last bit at left stands for sign, int being 32 bit signed integer

thus, the number becomes -2147483647

i++;
System.out.println(i); // prints -2147483647

on the same lines, 2147483647 * 2 is actually -> 2147483647 + 2147483647

int j = 2147483647;
j += 2147483647;
System.out.println(j); // prints -2

and thus you answer. now when you do 2147483647 * 3,

it is:

2147483647 + 2147483647 + 2147483647 = -2 + 2147483647 = 2147483645

AppleCiderGuy
  • 1,249
  • 1
  • 9
  • 16