Точность поплавков с 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 цифр.