Чому Math.ceil повертає дубль?


75

Коли я дзвоню, Math.ceil(5.2)повернення - це double 6.0. Моє природне схильність було думати, що Math.ceil(double a)це поверне a long. З документації:

ceil(double a)

Повертає найменше (найближче до негативної нескінченності) doubleзначення, яке не менше аргументу і дорівнює цілому математичному числу.

Але навіщо повертати doubleзамість a, longколи результатом є ціле число? Думаю, розуміння причини, що це може допомогти мені трохи краще зрозуміти Java. Це також може допомогти мені зрозуміти, чи потраплятиму в неприємності, кидаючи на a long, наприклад, is

long b = (long)Math.ceil(a);

завжди те, що я думаю, що це повинно бути? Я боюся, що можуть бути певні кордони, які є проблематичними.


Відповіді:


70

Діапазон doubleбільше, ніж у long. Наприклад:

double x = Long.MAX_VALUE;
x = x * 1000;
x = Math.ceil(x);

Що б ви очікували зробити останній рядок у разі Math.ceilповернення long?

Зверніть увагу, що при дуже великих значеннях (позитивних чи негативних) числа в кінцевому підсумку розподіляються дуже рідко - отже, наступне ціле число, більше цілого x, не буде, x + 1якщо ви розумієте, що я маю на увазі.


Я думаю, у вашому останньому реченні ви говорите про втрату точності, але я думаю, що це залежить не від великого числа, а від кількості його значущих цифр (у двійковому вигляді). Спробую знайти приклад.
aalku

@ user270349: Абсолютний розрив між послідовними подвійними значеннями стає більшим із збільшенням значення. Кількість значущих цифр, що представлені, залишається незмінною (крім субнормальних чисел).
Джон Скіт,

2
Приклад: 2^60може бути представлений як подвійний, тоді як 2^60 (+/-) 1не може
aalku

Ти правий. Збільшення одиниці в мантисі передбачає набагато більше число, якщо показник великого, очевидний.
aalku

6
Але чому тоді roundповертається a long?
Золтан,

14

Подвійний може бути більше Long.MAX_VALUE. Якщо ви зателефонуєте Math.ceil()за таким значенням, ви очікували б повернути те саме значення. Однак, якщо воно повертає довгий, значення буде неправильним.


ці doubleзначення, які більше , ніж Long.MAX_VALUEне можуть бути представлені точно, так що doubleрезультат ceil(big_double)НЕ буде big_double + 1. Тож це все ще неправильно ...
Ciprian Tomoiagă

@CiprianTomoiaga ти маєш рацію, що це не буде big_double +1, оскільки це буде big_double. Будь-яке значення, яке є занадто великим, щоб представляти його як a, longне має дробової частини.
Пітер Лорі
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.