2012-04-01 68 views
14

众所周知,当您使用printf输出float的值时,精度有限。
然而,还有一招,以增加输出的精度,如下例所示:使用printf漂浮物的精度

#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

因为潜在的未定义行为是不好的。 (编辑:从技术上讲,这可能不是未定义的行为,因为我不确定标准对此有何评论。尽管如此,Endianess可能会咬你。) – Corbin 2012-04-01 08:53:56

+8

对于一个好的4月的第一个笑话+1。 – Henrik 2012-04-01 09:03:02

+0

它显然让我x.x – Corbin 2012-04-01 09:16:05

回答

11

四月傻瓜?

您的“随机数”1318926965具有十进制和浮点格式相同的基础表示形式。

尝试其他值,例如10。这将打印为:

 10 
1092616192 

因此,要回答你的问题:

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

因为只有一天的一年是愚人节......天的伎俩行不通的休息...

4

尝试用不同的数字,同样的伎俩,说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 

我没有看到精度的提高,在所有依赖于该位表示你的“绝招”浮在你的平台上(据我了解)。

This thread有一些其他的“魔法浮动”和一种方式来产生它们。

+0

它取决于IEEE 754浮点数的位表示,而不是“在您的平台上”。 (模拟可能的字节顺序问题,在任何现实世界的机器上都不存在)。IMO这样的代码唯一不好的地方就是应该用工会代替的不合适的类型双关语(粗略但是所有编译器都支持)或者'memcpy'(100%合法C)。 – 2012-04-01 13:55:47

+0

如果IEEE 754是强制性的,那么'__STDC_IEC_559__'定义的用途是什么? – Mat 2012-04-01 14:09:51

+0

这不是强制性的,但考虑C标准如何破坏非IEEE符合实现的浮点数,并且没有其他方法可以告诉你可以依赖于浮点算术,我会考虑它对于想要可移植到非IEEE数学系统以便使用浮点的程序来说是一个巨大的错误。 (当然,您可以将它用于仅用于单个非IEEE数学实现的非便携式程序。) – 2012-04-01 14:15:48

0

精度的限制是浮点表示,而不是printf()这是一个错误的前提。

此外,一个单精度浮点数只能保证正确的6位数的精度,所以“诡计”会自欺欺人;在一般情况下它不起作用。

如果你想要10位浮点数,那么你应该使用双精度,这对15位数是有好处的。