Java-арифметика

почему этот код возвращает неправильное значение?

int i=Integer.MAX_VALUE+1;
long l=Integer.MAX_VALUE+1;
System.out.println(l);
System.out.println(i);

person user471011    schedule 09.10.2010    source источник
comment
байт b1=100; //байт b2=200; // возможная потеря точности byte b3=100+1; //байт b4=127+1; // возможная потеря точности int i1=2000000000; //целое i2=2999999999; // слишком большое целое число: 2999999999 int i3=2000000000+1; интервал i4=2147483647+1; а теперь не понимаю почему разные типы ошибок. для переменной b4 - есть ошибка, для i4 - нет ошибки.   -  person user471011    schedule 09.10.2010


Ответы (4)


Когда вы добавляете 1 к Integer.MAX_VALUE, оно переполняется и переносится на Integer.MIN_VALUE.

Это происходит потому, что Java использует дополнение до двух для представления целых чисел. Пример в 4 бита:

0000 : 0
0001 : 1
...
0111 : 7 (max value)
1000 : -8 (min value)
...
1110 : -2
1111 : -1

Поэтому, когда вы добавляете 1 к 0111 (максимум), получается 1000, и это минимум. Расширьте эту идею до 32-бит, и она будет работать точно так же.


Что касается того, почему ваш long также показывает неправильный результат, это потому, что он выполняет сложение int и затем неявно преобразует в long. Вам нужно сделать:

long l = (long) Integer.MAX_VALUE + 1
System.out.println(l); // now prints the correct value
person NullUserException    schedule 09.10.2010
comment
Подскажите пожалуйста, понял ли я алгоритм разбора этого кода виртуальной машины: long l = Integer.MAX_VALUE +1; 1. long l - я сказал виртуальной машине выделить 64 бита памяти под эту переменную. 2. Integer.MAX_VALUE +1 - в этой строке виртуальная машина ничего не знает о переменной l. Здесь простая арифметическая операция, результат которой — целочисленное переполнение. 3. в область памяти 64 бита (переменная l) записан результат выражения из 2-й строки - 32 бит неверное значение. Я вижу, что у нас нет логической связи между первым и вторым шагом? это так? - person user471011; 09.10.2010

Как следует из названия, Integer.MAX_VALUE — это максимальное значение, доступное для Integer. В java, когда Integer превышает свое максимальное значение на 1 (или переполняется на 1), его значение будет Integer.MIN_VALUE.

Если целочисленное сложение переполняется, то результатом являются младшие биты математической суммы, представленные в некотором достаточно большом формате с дополнением до двух. Если происходит переполнение, то знак результата не совпадает со знаком математической суммы двух значений операнда.

Осторожно, с Float или Double у вас не будет этого переполнения, значение будет POSITIVE_INFINITY

Операция, которая переполняется, дает бесконечность со знаком, операция, которая теряет значение, дает денормализованное значение или ноль со знаком, а операция, которая не имеет математически определенного результата, дает NaN.


Ресурсы:

person Colin Hebert    schedule 09.10.2010

Здесь вы переполняете 32-битный целочисленный тип, пытаясь сохранить значение, которое не может быть представлено этим типом (2 ^ 31 - 1):

int i = Integer.MAX_VALUE + 1;
person Darin Dimitrov    schedule 09.10.2010

Целое число Java представляет собой 32-битный знаковый тип, диапазон значений: от -2 147 483 648 до 2 147 483 647.

Вы не можете установить i целочисленную переменную, как в i=Integer.MAX_VALUE+1;

person Junior Mayhé    schedule 09.10.2010
comment
и что происходит в этом случае: long l=Integer.MAX_VALUE+1; теперь l 64 бита. - person user471011; 09.10.2010