найбільше ціле число, яке може зберігатися в подвійному


Відповіді:


506

Найбільше / найбільше ціле число, яке можна зберегти у подвійному, не втрачаючи точності, те саме, що найбільше можливе значення подвійного. Тобто, DBL_MAXабо приблизно 1,8 × 10 308 (якщо ваш подвійний 64-розрядний IEEE 754). Це ціле число. Він представлений точно. Що ще ти хочеш?

Далі, запитайте мене, що таке найбільше ціле число, щоб воно та всі менші цілі числа могли зберігатися в 64-розрядних подвійних дублях IEEE, не втрачаючи точності. 64-розрядний подвійний IEEE має 52 біти мантіси, тому я думаю, що це 2 53 :

  • 2 53 + 1 не можна зберігати, оскільки 1 на початку і 1 в кінці мають занадто багато нулів між ними.
  • Все, що менше 2 53Можна зберігати , причому 52 біти явно зберігаються в мантісі, а потім показник фактично дає вам ще один.
  • 2 53 очевидно можна зберігати, оскільки це мала потужність 2.

Або інший спосіб його погляду: як тільки зміщення було знято з показника, і ігнорування бітового знака як ірелевантного до питання, значення, яке зберігається у подвійному, - це потужність 2, плюс 52-бітове ціле число, помножене на 2 показник - 52 . Таким чином, за допомогою експонента 52 ви можете зберігати всі значення від 2 52 до 2 53  - 1. Потім з експонентом 53 наступне число, яке ви можете зберігати після 2 53, - 2 53 + 1 × 2 53 - 52 . Тож втрата точності спочатку відбувається з 2 53 + 1.


126
+1 Хороша робота, зауваживши, що питання насправді не означає, що, напевно, мав намір кандидат, і надав обидві відповіді ("технічно правильно" та "напевно очікували").
Паскаль Куок

62
Або "возитися" та "намагатися допомогти", як я їх називаю :-)
Стів Джессоп

8
Я кланяюся Тоні Поні, і нікому іншому.
Стів Джессоп

11
Ви не маєте на увазі "всі менші цілі числа", ви маєте на увазі всі цілі числа однакової чи меншої величини. Оскільки внизу нижче 2 ^ 53 є чимало від’ємних цілих чисел, і їх неможливо точно представити у подвійному.
Південна гостинність

13
Я маю на увазі менше, і саме це я маю на увазі, коли кажу менше :-) -1 000 000 менше 1, але це не менше.
Стів Джессоп

77

9007199254740992 (це 9,007,199,254,740,992) без гарантій :)

Програма

#include <math.h>
#include <stdio.h>

int main(void) {
  double dbl = 0; /* I started with 9007199254000000, a little less than 2^53 */
  while (dbl + 1 != dbl) dbl++;
  printf("%.0f\n", dbl - 1);
  printf("%.0f\n", dbl);
  printf("%.0f\n", dbl + 1);
  return 0;
}

Результат

9007199254740991
9007199254740992
9007199254740992

7
Припускаючи , що це буде «закрити» , але менше , ніж 2 ^ N, то швидше тест , double dbl = 1; while (dbl + 1 != dbl) dbl *= 2; while (dbl == --dbl);який дає той же результат
Seph

4
@Seph що ...? Немає? while (dbl == --dbl)буде циклічно назавжди або зовсім не буде. :) (у цьому випадку зовсім не так, оскільки це 2 ^ N). Вам доведеться підходити до нього знизу. Це дійсно також призведе до меншого, ніж очікуваного (з моменту однієї перевірки зменшення циклу в той час, як dbl). І це залежить від порядку виконання, якщо декремент робиться до або після оцінки лівої сторони (що, наскільки я знаю, не визначено). Якщо це колишнє, воно завжди буде правдою і циклічно назавжди.
falstro

10
Можливо, вкажіть, що 2 ^ 53 = 9,007,199,254,740,992 десь.
Xonatron

1
З цим важко сперечатися! Хороший експеримент
Метм

Слабкість до використання while (dbl + 1 != dbl) dbl++;в цьому dbl + 1 != dblможе оцінити використання long doubleматематики - врахуйте FLT_EVAL_METHOD == 2. Це могло закінчитися нескінченною петлею.
chux

25

У цьому ж контексті у Вікіпедії є посилання на IEEE 754 :

У типовій комп'ютерній системі двійкове число з плаваючою комою з подвійною точністю (64-бітне) має коефіцієнт 53 біт (один з яких мається на увазі), показник 11 біт і один біт знаків.

2 ^ 53 трохи більше 9 * 10 ^ 15.


@Steve Jessop більш-менш, це справді те, що я говорю. Я також стикався з апаратними системами, які не мають FPU, які все ще повинні бути сумісними з IEEE, так що "типові системні" речі насправді не допомагають мені, якщо я повернуся сюди через 8 місяців і мені потрібна така ж інформація для мій мікроконтролер на базі 68K (припустимо, що у нього немає FPU ... я не можу згадати).
San Jacinto

14
@San Jacinto - "Це марно" є надмірно суворим. Відповідь є досить корисною, так само не настільки корисною, як це було б, якби вона включала коментар, що типові комп'ютерні системи дійсно використовують репрезентацію IEEE 754.
Стівен К. Сталь

@Stephen C. Сталь, насправді ти прав. За моїм сценарієм, повертаючись до цього пізніше і шукаючи IEEE max, неможливо неоднозначно, що таке «типова система», але все ж є заслуга у відповіді, окрім цієї скарги.
Сан-Джакінто

20

Найбільше ціле число, яке може бути представлено у подвійному (64-розрядному) IEEE, є таким самим, як найбільше значення, яке може представляти тип, оскільки саме це значення є цілим числом.

Це представлено як 0x7FEFFFFFFFFFFFFF , що складається з:

  • Біт знака 0 (позитивний), а не 1 (негативний)
  • Максимальний показник 0x7FE(2046, що становить 1023 після віднімання зміщення), а не0x7FF (2047, що вказує на a NaNабо нескінченність).
  • Максимальна мантіса 0xFFFFFFFFFFFFF яка становить 52 біти, 1.

У двійковому значенні це імпліцитна 1, а за нею ще 52 з мантіси, потім 971 нуль (1023 - 52 = 971) від показника.

Точне десяткове значення:

179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368

Це приблизно 1,8 х 10 308 .


Що з найбільшою величиною, яку вона може представляти з усіма значеннями між нею та нулем, що супроводжуються безперервно?
Аарон Франке

@AaronFranke Питання не запитувало про суміжне представництво, але відповідь на це інше питання було включено до більшості інших відповідей тут або навіть неправильно дано як фактичну відповідь. Це 2⁵³ (2 до потужності 53).
Саймон Бібер

8

Потрібно подивитися на розмір мантіси. 64-бітове число з плаваючою точкою IEEE 754 (яке має 52 біти плюс 1 мається на увазі) може точно представляти цілі числа з абсолютним значенням менше або рівним 2 ^ 53.


8
Він також може точно представляти 2 ^ 53 :-)
Стів Джессоп

6

2
ця відповідь була б набагато краща з цитуванням.
San Jacinto

2
@Carl добре, якщо ціле число має нулі вліво, то воно точно зберігається.
Вільгельм

4
@all you downvoters: 1.7976931348623157 × 10 ^ 308 - це ціле число. Вам усім потрібно відвідувати уроки з корекційної математики чи щось таке ??
Dan Molding

6
Тут ми переходимо до семантики в обговоренні цієї безнадійно заточеної відповіді. Щоправда, це число можна точно представити і тим самим виконувати букву питання. Але ми всі знаємо, що це крихітний острів точності в океані близьких промахів, і більшість з нас правильно інтерполювали питання, щоб означати «найбільша кількість, за якою точність йде вниз». Ах, хіба не дивно, що CompSci - точна наука? :)
Карл Смотрич

2
@DanMoulding 1.7976931348623157 × 10 ^ 308 - це ціле число, але я впевнений, що це ціле число не може бути збережене в подвійному.
Паскаль Куок

2

DECIMAL_DIGвід <float.h>має дати хоча б розумне наближення цього. Оскільки це стосується десяткових цифр, і він дійсно зберігається у двійковій формі, ви, ймовірно, можете зберігати щось трохи більше, не втрачаючи точності, але скільки точно важко сказати. Я припускаю, що ви зможете це зрозуміти FLT_RADIXі DBL_MANT_DIG, але я не впевнений, що я повністю довіряю результату.


Це не дає відповіді на запитання. Щоб критикувати або вимагати роз'яснення у автора, залиште коментар під їх дописом.
MichaelChirico

@MichaelChirico: Це відповідає на питання, яке він мав намір задати, як це існувало, коли відповідь була написана. Щоб побачити історію редагування питання, натисніть посилання "відредаговано 19 червня '14 о 11:40" внизу питання.
Джеррі Коффін

Ваша відповідь звучить як коментар, оскільки, здається, не вистачає впевненості / авторитетності, яку повинна мати відповідь ("повинна дати хоча б розумне ..." "саме стільки ... важко сказати" "Я думаю ... "). Я не маю досвіду щодо поставленого питання чи відповіді, тому я можу помилятися; просто поклавши два мої центи, якщо я був відправлений сюди з черги оглядів (що, мабуть, означає, що інші користувачі позначили вашу відповідь).
MichaelChirico

1
@MichaelChirico: Вони, можливо, є - ти далеко не єдиний, хто не знає про те; те, що робить тебе незвичним, це те, що ти розумієш, що ти не знаєш цього. Більшість відповідей, які звучать авторитетно щодо точності числа з плаваючою точкою в С, просто помиляються. Наприклад, багато (більшість) із них, наведених вище, ґрунтуються на хибному припущенні, що doubleвідповідність безпосередньо конкретному типу IEEE, але це не потрібно, і коли ця відповідь була написана, питання також не згадувало конкретного типу IEEE.
Джері Коффін

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