printf浮点数默认精度的历史是什么?

3

似乎每个人在使用printf格式化浮点数时都使用默认的6个字符精度。

为什么是6?

这是在32位浮点数广泛使用之前出现的吗?


你怎么算出来的?33.30 作为一个32位IEE754浮点数确切地是33.29999923706055。 - Secto Kia
一个IEEE754(不是“IEE754”)二进制32位有7.22个十进制数字。你似乎在谈论binary64(即双精度),或者可能是完全不同的东西。请阅读关于IEEE754浮点格式的一些资料。 - Lightness Races in Orbit
不,你似乎把我的意思弄混了。确切的小数表示并不是7.22位数字,它可以是任意数量的数字,但由于某种原因,选择了6作为截止点。 - Secto Kia
不,它可以是7.22位数字(确切数量取决于值)。不能再多了。格式中的空间不足以提供更高的精度。仅仅因为您打印了超过6个有效数字并不意味着它们中的任何一个具有意义; 这是输出例程中的错误(或者您意外地转换为“double”)。 6不是任意的。它也不是“选择”的,而是IEEE754格式的大小和布局的结果。就像我三年前说的那样,请阅读有关浮点运算的工作原理的资料。 - Lightness Races in Orbit
你显然没有理解... printf 的目的是打印实际以十进制存储的值。为了做到这一点,你需要比 7.22 位数字更多的精度。这与浮点数的精度无关。 - Secto Kia
显示剩余3条评论
3个回答

6

根据维基百科的介绍,使用32位的IEEE 754浮点表示法,精确度约为7个十进制数字。因此,6看起来是一个合理的值。

如果需要获得大约16个十进制数位,则需要使用双精度(64位)。


3

这并不是在32位浮点数广泛使用之前出现的。最早的浮点表示法比IEEE规范存在得更早,为32位(或大约如此),因此在那之前没有输出浮点值的“默认精度”。

无论如何,对于32位浮点类型,尾数或有效数字的典型大小为20到25位(IEEE 32位浮点数具有24位的尾数),可表示最大精度为四到七个有效数字(通过24*log(2) 约等于 7.2 计算得出)。

一个典型的64位浮点表示法具有50到55位的尾数(64位IEEE表示法具有53位的尾数),最多可表示十五位小数的最大精度。

这意味着程序员通常会默认在输出浮点值时使用5到6位小数。更少的精度会截断值(增加由打印值并再次读取它导致的误差),而更高的精度则会产生“噪音”(小数点后面的杂散数字,影响了人类的可读性,并没有多大帮助写/读往返操作)。

所有这些都发生在C之前-实际上,在Algol之前(一种早期的编程语言,其设计影响了C的祖先语言)。


我不同意你对精度的计算。在标准的23位尾数中,最不显著的小数是1/8388608,因此有效数字的数量至少为14。 - Secto Kia

2
printf的历史中,6位数的默认值至少可以追溯到Version 5 Unix。请参阅古老的源代码:
  • fltpr.s函数实现了%fpscien函数实现了%e,两者都在指令mov $6,_ndigit中包含了神奇数字6。
  • printf.s在找到%f%e转换时调用pfloatpscien。一个重要的变量是ndfnd,如果转换没有指定数字,则该变量为0。
  • ecvt.s实际上生成数字字符串的fcvtecvt函数。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接