Точность поплавков с печатью - PullRequest
14 голосов
/ 01 апреля 2012

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

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

Ответы [ 3 ]

11 голосов
/ 01 апреля 2012

апрель дурак?

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

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

        10
1092616192

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

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

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

4 голосов
/ 01 апреля 2012

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

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

В этой теме есть еще несколько таких "магических поплавков" и способ их генерации.

0 голосов
/ 01 апреля 2012

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

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

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

...