Есть код
int a = Integer.MAX_VALUE;
int b = 5000;
int c = 123;
int min = Math.min(a, Math.min(b,c));
int max = Math.max(a, Math.max(b,c));
int d = a + b + c - min - max;
Почему в переменной d сохраняется правильное значение ( b )?
Ведь когда мы делаем a + b ( Integer.MAX_VALUE + 5000) у нас будет переполнение int'a
Да нет, все правильно. Вместе с переполнениями так и получается.
Рассчитаем по шагам:
int step1 = a+b+c;
System.out.println(step1);
int step2 = step1-min;
System.out.println(step2);
int d = step2 - max;
System.out.println(d);
Выводится:
-2147478526
-2147478649
5000
Просто на последнем шаге происходит второе переполнение -2147478649 -2147483647 и получается 5000.
P.S. Вообще, наличие переполнения не влияет на ассоциативность операции сложения. В Java сложение значений одного целого типа всегда ассоциативно, о чем упомянуто в спецификации (§JLS 15.18.2):
Integer addition is associative when the operands are all of the same type.
Соответственно, для любых a и b значение a + b - b будет равно a.
Из этого следует, что в Вашем случае d всегда будет равно среднему по величине из трех чисел (a, b и c) независимо от их значений.
грубо говоря возьмём более простой восьмибитный тип: [-127; 128] - диапазон значений. если к 128 + 1 в восьмибитной переменной - получится -127. так и у вас: int a = Integer.MAX_VALUE; int b = a + 5000;
тут b будет равно Integer.MIN_VALUE + 4999, т.к. произошло переполнение.
Сборка персонального компьютера от Artline: умный выбор для современных пользователей