Яке перше ціле число, яке плавець IEEE 754 не в змозі точно представляти?


162

Для наочності, якщо я використовую мову, яка реалізує плавні IEE 754, і я заявляю:

float f0 = 0.f;
float f1 = 1.f;

... а потім надрукуйте їх назад, я отримаю 0,0000 та 1,0000 - точно.

Але IEEE 754 не здатний представляти всі числа по реальній прямій. Близько до нуля "прогалини" невеликі; чим далі ви віддаляєтесь, тим розриви збільшуються.

Отже, моє запитання: для плавця IEEE 754, яке є першим (найближчим до нуля) цілим числом, яке не може бути точно представлено? Мені зараз дуже цікаво 32-бітні плавучі, хоча мені буде цікаво почути відповідь для 64-бітових плаваючих, якщо хтось це дає!

Я думав, що це буде так само просто, як обчислити 2 bits_of_mantissa і додати 1, де bits_of_mantissa - це кількість біт, які виставляє стандарт. Я зробив це для 32-бітових плаваючих на моїй машині (MSVC ++, Win64), і це здалося прекрасним.


Чому ви додали його, якщо хотіли непередаваного номера? І яке число ви використовували чи отримували? І це домашнє завдання? І заголовок запитання говорить "ціле число", але ваше запитання говорить "плавати".
msw

5
Тому що я подумав, що максисса мантіси дасть мені найбільше представницьке число. 2 ^ 22. Ні, це питання цікавості. Я завжди відчував свою провину за те, що він вводив поплавці, навіть коли знаю, що питання, про яке йдеться, завжди буде дуже малим. Я хочу знати, що таке верхня межа. Наскільки я можу сказати, заголовок та питання однакові, лише по-різному формулюються.
Floomi



1
@KyleStrand повернувся ^ 2. Я не знаю, чому один здався мені правильнішим, ніж інший на той час. Тепер вони обоє здаються незручними в порівнянні з "... це кількість біт ..."
Паскаль Куок

Відповіді:


211

2 біти мантіси + 1 + 1

+1 в експоненті (біти мантіси + 1) відбувається тому, що якщо мантіса містить abcdef...число, яке вона представляє, це фактично 1.abcdef... × 2^e, що забезпечує додатковий неявний біт точності.

Отже, перше ціле число, яке неможливо точно представити і буде округлене, це:
For float, 16,777,217 (2 24 + 1).
Бо double9,007,199,254,740,993 (2 53 + 1).

>>> 9007199254740993.0
9007199254740992

Я оголосив floatі встановив його рівним 16 777 217. Але коли я надрукував це за допомогою coutцього, це призвело до 16 777 216. Я використовую C++. Чому я не можу отримати 16 777 217?
натрійнітрат

18
@sodiumnitrate Перевірте заголовок питання. 16777217 - це перше ціле число, нездатне точно представити.
kennytm

Добре, дякую. Я розгубився, вибачте за це. У мене є ще одне питання: після 16777216 не повинно бути наступне ціле число, яке може бути представленим, 2 * 16777216? Коли я запускаю подібну програму, я отримую 16777218 шляхом додавання 2 до 16777126.
нітрат натрію

5
Наступне ціле число - це дійсно 16777218, оскільки 2 тепер стає останньою значною двійковою цифрою.
kennytm

6
У C ++, це (1 << std::numeric_limits<float>::digits) + 1, і в C, (1 << FLT_MANT_DIG) + 1. Перший приємний тим, що може бути частиною шаблону. Не додайте +1, якщо ви просто хочете найбільше представлене ціле число.
Генрі Шрайнер

38

Найбільше значення, представлене n бітним цілим числом, - 2 n -1. Як було зазначено вище, a floatмає 24 біти точності у значенніі, що, здавалося б, означає, що 2 24 не підходить.

Однак .

Потужність 2 в межах діапазону показника точно представлена ​​як 1,0 × 2 n , тому 2 24 може вміститися, і, отже, перше нерепрезентативне ціле число для float2 24 +1. Як зазначалося вище. Знову.


1
Це чітко пояснювало частину іншої "додаткової неявної точності". Дякую.
chappjc
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.