Точность поплавков с printf

как все знают, у вас есть ограниченная точность при использовании printf для вывода значения a 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;
}

и мой вопрос в том, почему люди не используют этот трюк чаще?

3 ответов


первоапрельская?

ваше "случайное число"1318926965 имеют одинаковое базовое представление как в десятичной, так и в форме с плавающей запятой.

попробуйте другое значение, например 10. Он будет печатать как:

        10
1092616192

Итак, чтобы ответить на ваш вопрос:

and my question is, why don't people use this trick more often?

потому что только один день в году-апрельский день дураков... В остальное время трюк не срабатывает...


попробуйте тот же трюк с другим номером, скажем, 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

Я не вижу увеличения точности вообще с вашим "трюком", который зависит от битового представления поплавков на вашей платформе (насколько я понимаю).

этой теме имеет несколько других из этих "волшебных поплавков" и способ их генерации.


предел точности - с представлением с плавающей запятой, а не с printf() Это ложная предпосылка.

кроме того, один прецизионный поплавок гарантированно корректен только до 6 цифр точности, поэтому "трюк" будет обманывать себя; в общем случае это не сработает.

Если вы хотите 10-значные числа с плавающей запятой, то вы должны использовать двойную точность, которая хороша для 15 цифр.