2016-03-25 1 views
12
System.out.println((byte) (1.0/0)); 
    System.out.println((short) (1.0/0)); 
    System.out.println((int) (1.0/0)); 
    System.out.println((long) (1.0/0)); 

Результат:Почему отливка деления на нулевые целые примитивы дает разные результаты?

-1 
    -1 
    2147483647 
    9223372036854775807 

В двоичном формате:

1111 1111 
    1111 1111 1111 1111 
    0111 1111 1111 1111 1111 1111 1111 1111 
    0111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 

Почему отливка бесконечность в целое и длинные целые числа хранит знаковый бит, как "0", в то время как наборы знаковый бит в «1 "для байтов и коротких целых чисел?

+3

Я предполагаю, что он отличает 'int', а затем' byte'. Примечание: Integer.MAX_VALUE является самым близким значением для Infinity для 'int'. –

+0

Thx Peter, но приведение Integer.MAX_VALUE к 'long' даст нам всего лишь «2147483647L», я прав? –

+0

@PeterLawrey Невозможно было бы оценить '(1.0/0)' как 'double', а затем касту в байте считать нижние 8 бит? В то время как IEEE 754 определяет стандарт для 'double' и' float', я считаю нечетным, что бит знака равен 0 для 'int', поскольку документы не определяют спецификации бесконечности для' int'. –

ответ

10

JLS 5.1.3:

сужающее преобразование из числа с плавающей точкой к интегральному типу T принимает два шага:

На первом шаге, число с плавающей точкой преобразуется либо в долго , если T является длинным или int, если T является байтом, коротким, char или int, следующим образом:

Если число с плавающей запятой является NaN (п. 4.2.3), результат первый шаг конверсии Sion является INT или длинным 0.

В противном случае, если число с плавающей точкой не является бесконечность, значение с плавающей точкой округляется до целого значения V, округление в стороне нуля, используя IEEE 754 круглого toward- нулевой режим (п. 4.2.3). Тогда есть два случая:

Если T имеет длину, и это целое значение может быть представлено в виде длинной, то результатом первого шага является длительное значение В.

В противном случае, если это целое число, значение может быть представлена ​​как Int, то результата первого шага этого значения INT В.

в противном случае, один из следующих двух случаев должны быть истинная:

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

Значение должно быть слишком большим (положительное значение большой величины или положительной бесконечности), и в результате первой стадии является самым большим представима значение типа Int или долго.

На втором этапе:

Если Т INT или длинный, то результат преобразования является результатом первого шага.

Если Т байт, символ, или короткое замыкание, результатом преобразования является результат сужающего преобразования к типу T (§5.1.3) результата первый шаг.

Таким образом, бесконечное двойное значение первого приведение к int путем возврата Integer.MAX_VALUE, а затем это далее приведение к byte/short, который принимает соответствующее число байтов низких (и получает -1 в результате). Поражает в int и long не имеют такой дополнительный шаг, но byte и short идут первый через int и затем к byte/short.

+0

Я тоже собирался обратиться к сужению примитивного преобразования. +1 –

Смежные вопросы