Как работает double to int cast в Java

Я новичок в Java, и мне интересно, как работает double to int cast? Я понимаю, что это просто и долго для int, взяв младшие 32 бита, но как насчет двойного (64 бита) до int (32 бита)? эти 64 бита из double в двоичном формате находятся в формате с плавающей запятой двойной точности (Mantissa), так как же он конвертируется в int внутренне?


person peter    schedule 20.09.2012    source источник
comment
Он усекает десятичную дробь и возвращает только целое число в виде int.   -  person Corey Ogburn    schedule 20.09.2012
comment
удивлен, что этот вопрос не задавали раньше.   -  person UmNyobe    schedule 20.09.2012


Ответы (3)


Все это задокументировано в разделе 5.1. 3 JLS.

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

Если число с плавающей запятой - NaN (§4.2.3), результатом первого шага преобразования будет int или long 0.

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

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

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

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

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

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

(Второй шаг здесь не имеет значения, когда T равно int.)

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

person Jon Skeet    schedule 20.09.2012
comment
Я действительно не понимаю. Не могли бы вы привести пример? как от очень длинного числа с плавающей запятой до int - person peter; 20.09.2012
comment
В таком случае прочтите последнее предложение цитаты. Вы будете получать MAX_VALUE каждый раз. - person Peter Lawrey; 20.09.2012
comment
Извините, я не совсем понимаю первый шаг. Преобразует ли он его через двоичный код? возьмем пример double x = 54,3578, а что произойдет на первом шаге? - person peter; 20.09.2012
comment
@ user1389813: Начальное значение находится в двоичном формате. Во время компиляции компилятор преобразует литерал 54.3578 в ближайшее представимое 64-битное двойное значение IEEE-754. - person Jon Skeet; 20.09.2012
comment
@JonSkeet, но как он извлекает 54 из двоичного формата с плавающей запятой двойной точности IEEE 754, где он содержит знак, показатель степени и дробь? - person peter; 20.09.2012
comment
@ user1389813: Как я писал в своем ответе, большую часть времени это будет делать процессор. Если ЦП не поддерживает операции с плавающей запятой напрямую, это будет реализовано внутри JVM с кодом, который понимает IEEE-754 ... но на данный момент мы далеки от чего-то действительно специфичного для Java, и непонятно, почему вы действительно хотите знать. Эффект - важная часть, и это указано в моем ответе · - person Jon Skeet; 20.09.2012

Java обрезает свое значение, если вы используете приведение (int), как вы могли заметить:

    double d = 2.4d;
    int i = (int) d;
    System.out.println(i);
    d = 2.6;
    i = (int) d;
    System.out.println(i);

Выход:

2
2

Если вы не используете Math.round, Math.ceil, Math.floor ...

person arutaku    schedule 20.09.2012
comment
Думаю, вопрос не в том, как это сделать, а в механике броска - person UmNyobe; 20.09.2012

Вы можете прочитать спецификацию Java:

http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1.3.

Соответствующий раздел - 5.1.3 - «Сужение примитивного преобразования».

person mikera    schedule 20.09.2012