Могу ли я напечатать точно представимое число без потери точности? - PullRequest
2 голосов
/ 03 мая 2019

Я пытаюсь напечатать значение с плавающей точкой 299792450 со следующим кодом:

#include <stdio.h>

int main()
{
    printf("%f\n", 299792450.0f);
    return 0;
}

Согласно IEEE 754 Calculator , это точно представимое значение с плавающей точкой в ​​формате binary32. Однако я получаю другое значение в выводе:

$ ./a.out 
299792448.000000

Почему оно не равно 299792450? Я ожидал, что оно будет 299792450, потому что оно точно представимо и не должно быть потери точности.

Ответы [ 3 ]

5 голосов
/ 03 мая 2019

Если предположить, что float - это число с плавающей запятой IEEE754 с одинарной точностью, 299792450 не может быть точно представлено .

Это значение требует как минимум 28 бит точности, но float имеет не более 24 бит точности. Таким образом, значение округляется до максимально возможного значения, которое может быть представлено.

Если вы использовали double, который имеет точность 53 бита, вы увидите точное значение.

printf("%f\n", 299792450.0);
4 голосов
/ 03 мая 2019

Калькулятор IEEE 754 , даже в режиме «binary32», сообщает значения как округленные десятичные значения, а не точные значения.

"это точно представимое плавающее значениезначение точки в двоичном формате 32 "

1 голос
/ 03 мая 2019
Значение

A float не имеет достаточной точности для такого значения, вам нужно использовать double или, для максимальной точности, long double:

#include <stdio.h>

int main()
{
    printf("%Lf\n", 299792450.0L);
    return 0;
}
...