Точность поплавков с printf
Как известно, у вас ограниченная точность, когда вы используете printf
для вывода значения float
.
Однако есть смысл повысить точность вывода, как показано в этом примере:
#include <stdio.h>
int main()
{
float f = 1318926965; /* 10 random digits */
printf("%10.f\n", f); /* prints only 8 correct digits */
printf("%10d\n", *(int*)&f); /* prints all digits correctly */
return 0;
}
и мой вопрос: почему люди чаще не используют этот трюк?
Ответы
Ответ 1
Апрельский дурак?
Ваше "случайное число" 1318926965
имеет одно и то же основное представление как в десятичной, так и в плавающей форме.
Попробуйте другое значение, например 10
. Он будет печатать как:
10
1092616192
Итак, чтобы ответить на ваш вопрос:
and my question is, why don't people use this trick more often?
Потому что только один день года - День дураков... Остальные дни трюк не работает...
Ответ 2
Попробуйте тот же трюк с другим номером, скажем, 2318926965.
#include <stdio.h>
int main()
{
float f = 2318926965; /* 10 random digits */
printf("%10.f\n", f); /* prints only 8 correct digits */
printf("%10d\n", *(int*)&f); /* prints all digits correctly */
return 0;
}
$ gcc -Wall -O3 t.c
t.c: In function ‘main’:
t.c:7:5: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
$ ./a.out
2318926848
1326069764
Я не вижу увеличения точности вообще с вашим "трюком", который зависит от представления бит поплавков на вашей платформе (насколько я понимаю).
В этом потоке есть несколько других этих "волшебных поплавков" и способ их генерации.
Ответ 3
Предел точности с представлением с плавающей запятой, а не с printf()
является ложным положением.
Кроме того, одиночный прецизионный поплавок гарантирован только на 6 цифр точности, поэтому "трюк" будет обманывать себя; в общем случае это не сработает.
Если вам нужны 10-значные числа с плавающей запятой, вы должны использовать двойную точность, которая хороша для 15 цифр.