我在维基百科log 224 = 7.22中看到了这一点。
我不知道为什么我们应该计算2 ^ 24以及为什么我们应该使用log10 ......我真的需要你的帮助。
答案 0 :(得分:4)
为什么浮点数的有效数字是7或6(?)
考虑使用Pigeonhole principle的一些想法:
float
可以编码大约2 32 不同的数字完全。即使我们将自己限制在-10 38 ... +10 38 。任何时间代码都有0.1f
等文本值,它会被编码到附近的float
,这可能不是完全相同的文本值。问题是:我们可以编码多少位数并仍保持独特float
? 把它放在一起......
作为文本,范围[1.000_000 ... 2.000_000),使用1个引导数字和6个跟踪数字,有1,000,000个不同的值。每#3,在相同的范围内,存在8,388,608个不同的float
,允许每个文本值映射到不同的float
。 在此范围内,我们可以使用7位。
作为文本,范围[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 <float.h>
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 <舍入为浮点数/ em> radix b 数字并再次返回而不更改 q 十进制数字,
p log 10 b .............如果b是10的幂/> ⎣( p - 1)log 10 b ⎦..否则
注意“log 10 2 24 ”与“24 log 10 2”相同。
作为float
,值在2的幂之间以线性分布,如#2,3,4所示。
作为 text ,值在10的幂之间以线性分布,如7个有效数字值[1.000000 ... 9.999999] * 10 some_exponent
这两组的转变发生在不同的值。 1,2,4,8,16,32 ...与1,10,100,......在确定最坏情况时,我们从24位中减去1以解决错位。
⎣( p - 1)log 10 b ⎦ - &gt; floor((24 − 1) log10(2))
- &gt; floor(6.923...)
- &gt; 6。
如果我们的float
使用了基数10,100或1000,而不是非常常见的2,则这两组的转换发生在相同的值,我们不会减去一个。
答案 1 :(得分:2)
IEEE 754 single-precision 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到0 1677721500,但逐渐不那么精确 - 总是有~7位数的精度,这意味着我们开始将低位数字的精度丢失到小数点的 left 。)
另一种方法是注意log10(2)约为0.3。这意味着1位对应于约0.3个十进制数字。所以24位对应24×0.3 = 7.2。
(实际上,IEEE 754单精度浮点只显式地存储了23位,而不是24位。但是那里有一个隐含的前导1位,所以我们确实得到了24位的效果。)
答案 2 :(得分:0)
让我们开始小一些。使用10位(或10个基数2位数),您可以将数字0表示为1023.因此,对于某些值,您最多可以表示4位数,但对于大多数其他值(1000以下的数字),最多可以表示3位数。
要找出一堆基数为2位(位)可以表示多少个10(十进制)数,你可以使用最大可表示值的log10(),即log10(2 ^ 10) = log10(2)* 10 = 3.01 ....
以上意味着您可以表示所有3位数或更小值 - 以及几个4位数值。嗯,这很容易验证: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位数。