наибольшее целое число, которое может быть сохранено в double

какое самое большое целое число" без плавающего", которое может быть сохранено в двойном типе IEEE 754 без потери точности ?

7 ответов


наибольшее / наибольшее целое число, которое может быть сохранено в double без потери точности, совпадает с максимально возможным значением double. То есть, DBL_MAX или приблизительно 1,8 × 10308 (Если ваш двойник является 64-разрядным двойником IEEE 754). Это целое число. Он представлен точно. Чего ты еще хочешь?

продолжайте, спросите меня, какое наибольшее целое число такое, что оно и все меньшие целые смогите храниться в двойниках ИЭЭЭ 64-разрядных без терять точность. 64-разрядный двойной IEEE имеет 52 бита мантиссы, поэтому я думаю, что это 253:

  • 253 + 1 нельзя сохранить, потому что 1 в начале и 1 в конце имеют слишком много нулей между ними.
  • что-нибудь меньше 253 может быть сохранен, с 52 битами, явно сохраненными в мантиссе,а затем показатель, по сути, дает вам еще один.
  • 253 очевидно, может храниться, так как это небольшая мощность 2.

или другой способ взглянуть на это: как только смещение было снято с экспоненты и игнорирование бита знака как не относящегося к вопросу, значение, хранящееся в double, равно степени 2, плюс 52-разрядное целое число, умноженное на 2показатель - 52. Поэтому с показателем 52 вы можете хранить все значения 252 до 253 - 1. Затем с показателем 53, следующее число вы можете сохранить после 253 is 253 + 1 × 253 - 52. Таким образом, потеря точности сначала происходит с 253 + 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

Википедия имеет это сказать в том же контексте со ссылкой на IEEE 754:

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

2^53 чуть больше 9 * 10^15.


наибольшее целое число, которое может быть представлено в IEEE 754 double (64-бит), совпадает с наибольшим значением, которое может представлять тип, так как это значение само является целым числом.

это представлено как 0x7FEFFFFFFFFFFFFF, которая состоит из:

  • знак бит 0 (положительный), а не 1 (отрицательный)
  • максимальный показатель 0x7FE (2046, который представляет 1023 после вычитания смещения), а не 0x7FF (2047, что указывает на NaN или бесконечность.)
  • максимальное мантисса 0xFFFFFFFFFFFFF что составляет 52 бита все 1.

в двоичном формате значение является неявным 1, за которым следуют еще 52 единицы из мантиссы, затем 971 нуль (1023 - 52 = 971) из экспоненты.

точное десятичное значение есть:

179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368

это приблизительно 1.8 x 10308.


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



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