Якщо я напишу:
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
або -Inf
1 . Якщо відкласти останню точку, у вашому випадку це означає, що це 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()
.