Какое наибольшее целое число без плавающих может быть сохранено в двойном типе IEEE 754 без потери точности?
Какое наибольшее целое число без плавающих может быть сохранено в двойном типе IEEE 754 без потери точности?
Ответы:
Наибольшее / наибольшее целое число, которое может храниться в двойном значении без потери точности, совпадает с наибольшим возможным значением двойного числа. То есть DBL_MAXили примерно 1,8 × 10 308 (если ваш двойник является 64-битным двойником IEEE 754). Это целое число. Это представлено точно. Что вы еще хотите?
Продолжайте, спросите меня, какое наибольшее целое число такое, чтобы оно и все меньшие целые числа могли быть сохранены в 64-битных двойных числах IEEE без потери точности. 64-битный дубль IEEE имеет 52 бита мантиссы, поэтому я думаю, что это 2 53 :
Или другой способ взглянуть на это: как только смещение было снято с показателя степени, и игнорируя знаковый бит как не относящийся к вопросу, значение, хранимое в double, является степенью 2 плюс 52-битное целое число, умноженное на 2 показатель степени - 52 . Таким образом, с показателем 52 вы можете сохранить все значения от 2 52 до 2 53 - 1. Затем с показателем 53 следующее число, которое вы можете сохранить после 2 53, равно 2 53 + 1 × 2 53 - 52 . Таким образом, потеря точности сначала происходит с 2 53 + 1.
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
double dbl = 1; while (dbl + 1 != dbl) dbl *= 2; while (dbl == --dbl);который дает тот же результат
while (dbl == --dbl)будет цикл навсегда или нет вообще. :) (в данном случае совсем нет, так как это 2 ^ N). Вам придется подойти к нему снизу. Это также приведет к результату, который меньше ожидаемого (поскольку проверка в цикле while уменьшает dbl). И это зависит от порядка выполнения, если декремент выполняется до или после оценки левой стороны (насколько я знаю, неопределенна). Если это первое, оно всегда будет верным и зацикливается навсегда.
while (dbl + 1 != dbl) dbl++;в том, что dbl + 1 != dblможно оценить с помощью long doubleматематики - рассмотрим FLT_EVAL_METHOD == 2. Это может закончиться бесконечным циклом.
Википедия говорит об этом в том же контексте со ссылкой на IEEE 754 :
В типичной компьютерной системе двоичное число с плавающей запятой двойной точности (64-разрядное) имеет коэффициент 53 бита (один из которых подразумевается), показатель степени 11 бит и один знаковый бит.
2 ^ 53 составляет чуть более 9 * 10 ^ 15.
Наибольшее целое число, которое может быть представлено в двойном (64-разрядном) IEEE 754, совпадает с наибольшим значением, которое может представлять тип, поскольку само это целое число.
Это представляется как 0x7FEFFFFFFFFFFFFF, который состоит из:
0x7FE(2046, который представляет 1023 после смещения вычитается), а не 0x7FF(2047, который указывает на NaNили бесконечность).0xFFFFFFFFFFFFFкоторая составляет 52 бита всего 1.В двоичном виде значение представляет собой неявную 1, за которой следуют еще 52 единицы из мантиссы, затем 971 ноль (1023 - 52 = 971) от показателя степени.
Точное десятичное значение:
179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368
Это примерно 1,8 х 10 308 .
Вам нужно посмотреть на размер мантиссы. 64-битное число с плавающей запятой IEEE 754 (которое имеет 52 бита плюс 1 подразумевается) может точно представлять целые числа с абсолютным значением, меньшим или равным 2 ^ 53.
1.7976931348623157 × 10 ^ 308
http://en.wikipedia.org/wiki/Double_precision_floating-point_format
DECIMAL_DIGот <float.h>должен дать хотя бы разумное приближение этого. Поскольку это касается десятичных цифр и действительно хранится в двоичном формате, вы, вероятно, можете хранить что-то немного больше, не теряя точности, но сколько именно трудно сказать. Я полагаю, вы сможете понять это из FLT_RADIXи DBL_MANT_DIG, но я не уверен, что полностью доверю результату.
doubleсоответствует непосредственно определенному типу IEEE, но это не требуется, и когда этот ответ был написан, в вопросе также не упоминался конкретный тип IEEE.