提问人:Zaratruta 提问时间:5/18/2023 最后编辑:phuclvZaratruta 更新时间:5/18/2023 访问量:266
如果 float 有 6 位精度,为什么我们可以用 printf 显示超过 6 位的浮点数?
If float has 6 digits of precision, why can we display more than 6 digits of floats with printf?
问:
让我们考虑以下一段代码:
#include <stdio.h>
int main()
{
float x = 0.33;
printf("%.100f",x);
return 0;
}
如果浮点数有 6 位精度,怎么可能显示超过 6 位数字?printf
答:
您尝试将十进制分数 0.33 转换为 .但是,与大多数十进制分数一样,数字 0.33 不能在内部使用的二进制表示形式中精确表示。你能得到的最接近的是 二进制分数 。如果我们将其转换回十进制,则该分数正好是 0.3300000131130218505859375。float
float
0.0101010001111010111000011
在十进制中,如果我告诉你你有 7 位数字的显着性,并且你试图表示数字 1/3 = 0.333...,你期望得到 0.3333333300000。也就是说,您希望获得一些与原始数字匹配的有效数字,然后是 0,其中没有足够的意义。二进制分数的工作方式相同:对于 type ,二进制分数总是正好有 24 位有效性,后面(如果您愿意)是任意数量的二进制 0。float
当我们将该二进制数转换回十进制时,我们会得到大约 7 位数字,与我们认为拥有的十进制数相匹配,后面不是零,而是看起来像随机数字。例如,作为二进制的 1/3 是(注 24 位有效位),转换为十进制时为 0.3333333343267440795898437500000(注 7 位准确数字)。float
0.0101010101010101010101011000000000
当您听到该类型大约有 7 位数字时,这并不意味着您将获得原始数字的 7 位数字,后跟 0。这意味着你会得到你原来的号码的大约7位数字(但可能是6位,也可能是8位或9位或更多),然后是一些可能与你原来的号码不匹配的数字,但也不都是0。但这实际上并不是问题,特别是如果(按照建议和适当的方式)您将这个数字打印回来,四舍五入到有用的位数。当它可能成为一个问题时(尽管这经常出现)是当你用一个无用的数字数字打印出来时,格式类似于 ,你会看到一些看起来很奇怪的数字,它们并不都是 0,这让你感到困惑,就像这里一样。float
%.100f
在内部键入和使用二进制表示的事实导致了无穷无尽的惊喜。表示是二进制并不奇怪(我们都知道计算机以二进制形式做所有事情),但是二进制分数无法准确表示我们习惯的十进制分数,现在这真的很令人惊讶。请参阅规范的 SO 问题浮点数学是否被破坏?float
double
如果浮点数有 6 位精度,为什么我们可以显示超过 6 位浮点数?
printf
A 没有每个定义的 6 位精度。您选择显示的数字数超出了实现所能提供的数量 - 它确实提供了。float
为什么我们可以显示超过 6 位的浮点数?
printf
你可以告诉程序显示你在 // 中拥有的任何内容,它仍然被认为是一个近似值。float
double
long double
最好在调试时显示此类变量的当前内容。
比较: https://en.wikipedia.org/wiki/IEEE_754
“如果浮点数有 6 位精度......”--> 是一个弱前提。
普通浮点数没有
6 位十进制精度,而是 24 位二进制精度。
如何使用 (?) 显示超过 6 位数字
printf
当以十进制打印二进制浮点数时,每个二进制数字都会贡献一些 2 的幂,例如 ...、16、8、4、2、1、0.5、0.25、0.125、0.0625、...
这些 2 的幂之和很容易超过 6 位十进制数字。
在极端情况下,通常具有以下确切值:FLT_TRUE_MIN
0.00000000000000000000000000000000000000000000140129846432481707092372958328991613128026194187651577175706828388979108268586060148663818836212158203125
很少有 9 位有效十进制数字更重要。
评论
float
0.3300000131130218505859375000…
float
float