为什么浮点数的有效数字是7或6

我在Wikipedia log 2 24 = 7.22中看到了这一点。

我不知道为什么我们应该计算2 ^ 24以及为什么我们应该使用log10 ……我真的需要你的帮助。

为什么浮点数的有效数字是7或6(?)

考虑使用Pigeonhole原则的一些想法:

  1. binary32 float可以精确编码大约2 32个不同的数字。 即使我们将自己限制在-10 38 … +10 38之间的范围内,一个人可以用42.0,1.0,3.1415623等文本写的数字是无限的。 任何时候代码都有像0.1f这样的文本值,它被编码到附近的float ,它可能不是完全相同的文本值。 问题是: 我们可以编码多少位数并仍保持独特的float
  2. 对于各种2的幂范围,通常对2 23 (8,388,608)个值进行线性编码。
  3. 在[1.0 … 2.0]范围内,2 23 (8,388,608)个值被线性编码。
  4. 在[2 33或8,589,934,592 … 2 34或17,179,869,184]范围内,同样地,2 23 (8,388,608)个值被线性编码:彼此相距1024.0。 在子范围[9,000,000,000和10,000,000,000]中,大约有976,562个不同的值。

把它放在一起……

  1. 作为文本,范围[1.000_000 … 2.000_000),使用1个引导数字和6个跟踪数字,有1,000,000个不同的值。 每#3,在相同的范围内,存在8,388,608个不同的float ,允许每个文本值映射到不同的float在此范围内,我们可以使用7位数

  2. 作为文本,范围[9,000,000 * 10 3和10,000,000 * 10 3 ],使用1个引导数字和6个跟踪数字,有1,000,000个不同的值。 每#4,在相同的范围内,有不到1,000,000个不同的float值。 因此,一些十进制文本值将转换为相同的float在此范围内,我们可以使用6位不是7位数来进行特殊转换。

典型float的最坏情况是6位有效数字 。 要找到float的限制:

 #include  printf("FLT_DIG = %d\n", FLT_DIG); // this commonly prints 6 

……不知道为什么我们应该计算2 ^ 24以及我们为什么要采用log10

2 ^ 24是与普通float及其24位二进制精度的泛化,对应于具有7.22 …数字的奇异十进制系统。 我们用log10来比较二进制 float十进制文本。

2 24 == 10 7.22 ……

但我们不应该采取2 24 。 让我们看看如何从C11dr§5.2.4.2.2中定义FLT_DIG 11:

小数位数q ,使得带有q个十进制数字的任何浮点数可以舍入为p基数为b的浮点数,然后再返回而不更改为q个十进制数,

p log 10 b ………….如果b是10的幂
⎣( p – 1)log 10b⎦..否则

注意“log 10 2 24 ”与“24 log 10 2”相同。

作为float ,值在2的幂之间线性分布,如#2,3,4所示。

作为文本 ,值在10的幂之间线性分布,类似于[1.000000 … 9.999999] * 10 some_exponent的7个有效数字值。

这两组的转变发生在不同的值。 1,2,4,8,16,32 …与1,10,100,……在确定最坏情况时,我们从24位中减去1来解释未对齐。

⎣( p – 1)log 10b⎦ – > floor((24 − 1) log10(2)) – > floor(6.923...) – > 6。

如果我们的float使用10,100或1000,而不是非常常见的2,这两组的转换发生在相同的值,我们不会减去一个。

IEEE 754单精度float具有24位尾数。 这意味着它有24个二进制位的精度。

但我们可能有兴趣知道它有多少十进制数字的精度。

计算这个的一种方法是考虑有多少24位二进制数。 答案当然是2 24 。 所以这些二进制数从0到16777215。

那是多少位小数? 那么,log10给出了小数位数。 log10(2 24 )是7.2,或略多于7位小数。

看看那个:16777215有8个数字,但是前导数字只有1,所以实际上它只有7位数多一点。

(当然这并不意味着我们只能代表从0到16777215的数字!这意味着我们可以准确地表示0到16777215之间的数字。但我们也得到了指数可以使用。我们可以表示从0到1677721.5的数字或多或少精确地到达小数点后的一个地方,数字从0到167772.15或多或少精确到两个小数点等等。我们可以表示0到167772150或0到1677721500之间的数字,但逐渐不那么精确 – 总是与~7位数的精度,意味着我们开始在小数点左边的低位数字中失去精度。)

另一种方法是注意log10(2)约为0.3。 这意味着1位对应于约0.3个十进制数字。 因此24位对应于24×0.3 = 7.2。

(实际上,IEEE 754单精度浮点显式地只存储了23位,而不是24位。但是那里有一个隐含的前导1位,所以我们确实得到了24位的效果。)

让我们开始小一些。 使用10位(或10个基数2位数),您可以将数字0表示为1023.因此,对于某些值,您最多可以表示4位数,但对于大多数其他值(1000以下的数字),最多可以表示3位数。

要找出一堆基数为2(十进制)的数字可由一堆基数为2位(位)表示,您可以使用最大可表示值的log10(),即log10(2 ^ 10)= log10( 2)* 10 = 3.01 ….

以上意味着您可以表示所有3位数或更小值 – 以及几个4位数值。 嗯,这很容易validation:0-999最多有3位数,1000-1023有4位数。

现在需要24位。 在24位中,您可以存储log10(2 ^ 24)= 24 * log(2)基数为10的数字。 但由于顶部位始终相同,实际上只能存储log10(2 ^ 23)= log10(8388608)= 6.92。 这意味着您可以代表大多数7位数字,但不是全部。 您可以忠实代表的一些数字只能有6位数字。

事实上,事实有点复杂,因为指数也扮演着角色,而且许多可能更大的值中的一些也可以表示,所以6.92可能不是确切的值。 但它很接近,可以很好地作为一个经验法则,这就是为什么他们说单精度可以代表6到7位数。