Якщо я напишу:
int x = /* any non-zero integer value */;
float y = x;
float z = y / y;
Є чи zгарантовано точно 1.f?
Якщо я напишу:
int x = /* any non-zero integer value */;
float y = x;
float z = y / y;
Є чи zгарантовано точно 1.f?
x, static_cast<int>(y) != x(якщо обидва 32-біт), але по- z, як і раніше буде дорівнює , 1.0fякщо x == 0тому як чисельник і знаменник не мають ту ж помилку округлення.
xі yдосить великі, і досить близькі одне до одного (не будучи рівними), то x/y, ймовірно, буде 1.fтеж через помилку при перетворенні. Спробуйте ввести це в консолі браузера (який , ймовірно , також використовує IEEE754) і натиснути ENTER: 9223372036854775700/9223372036854775800.
Відповіді:
Якщо у вашій реалізації C ++ використовується IEEE754, тоді так, це гарантовано. (Оператор ділення повинен повернути найкраще можливе значення з плаваючою комою).
В тільки виключення для y / y, в загальному, не будучи 1.fє випадки , коли yце NaN, +Inf, -Inf, 0.f, і -0.f, або , якщо ви перебуваєте на платформі , де intнастільки широкий , що деякі випадки нього не можуть бути представлені в floatбез того float, встановленим на +Infабо -Inf1 . Якщо відкласти останню точку, у вашому випадку це означає, що це int x = 0;буде єдиним винятком.
IEEE754 надзвичайно поширений. Але щоб перевірити напевно, протестуйте значення
std::numeric_limits<float>::is_iec559;
1 Платформа, наприклад, із 128-бітовим intта 32-бітовим IEEE754 floatможе виявляти таку поведінку для певних значень x.
yможе стати NaN.
NaN, деякі з яких мають бітовий знак. Але, як NaN != NaNі для будь-якого бітового шаблону NaN, безглуздо сперечатися, чи "+ NaN == -NaN".
yзначення було як в регістрі, так і в пам'яті, і компілятор вирішив завантажити знаменник з пам'яті. Отже, ви закінчуєте y_from_register / y_from_memory. Якщо регістр має більшу точність, ніж пам'ять, що гарантує, що 1 є найкращим результатом ділення?
floatне може містити xзначення.
Ні, не у всіх випадках, навіть для IEEE754.
Наприклад, за допомогою int x = 0;, ви отримаєте NaN. ( Прямий ефір )
infабо 0fабо підписує варіанти тих, то результат також не1f
std::numeric_limits<int>::max()може бути більше, ніжstd::numeric_limits<float>::max().