Будет ли двойное число, равное целому, всегда приведено к этому целому числу? - PullRequest
13 голосов
/ 17 февраля 2012

Будет ли двойное число, равное целому числу, всегда приведено к этому целому числу (при условии, что двойное число не вызывает переполнение).Пример: Math.ceil () вернет значение типа double, равное целому числу.При условии отсутствия переполнения, оно всегда будет приводить к одному и тому же целому числу, которому оно предположительно равно?

Если нет, как я могу округлить double до int или long?

Ответы [ 5 ]

9 голосов
/ 17 февраля 2012

Поскольку типы Java являются фиксированными, а двойники Java имеют 52-битную мантиссу , они могут (с легкостью) представлять 32-битный Java int без округления.

6 голосов
/ 17 февраля 2012

Да, он будет преобразован точно.Это описано в Разделе 5.1.3 JLS, в котором упоминается

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

Поскольку ваше double точно равно int, "округленное" значение является просто точнымто же значение, но вы можете прочитать спецификацию для деталей.

1 голос
/ 17 февраля 2012

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

double d = 
long l = (long) Math.ceil(d); // note: could overflow.
1 голос
/ 17 февраля 2012

Эмпирически, ответ, кажется, да - обратите внимание, что он также работает с i2 = (int) d;.

public static void main(String[] args) {
    for (int i = Integer.MIN_VALUE + 1; i < Integer.MAX_VALUE; i++) {
        double d = i;
        int i2 = (int) Math.ceil(d);
        if (i != i2) {
            System.out.println("i=" + i + " and i2=" + i2); //Never executed
        }
    }
}
1 голос
/ 17 февраля 2012

Я верю в это, но вы можете проверить это сами:

public static void main(String... args) throws Exception {
    int interactions = Integer.MAX_VALUE;
    int i = Integer.MIN_VALUE;
    double d = Integer.MIN_VALUE;
    long init = System.currentTimeMillis();
    for (; i < interactions; i++, d++)
        if (!(i == (int) Math.ceil(d)))
            throw new Exception("something went wrong with i=" + i + " and d=" + d + ", Math.ceil(d)="+Math.ceil(d));

    System.out.println("Finished in: "+(System.currentTimeMillis() - init)+"ms");
}
...