Floating point 二进制浮点数的十进制精度

Floating point 二进制浮点数的十进制精度,floating-point,floating-point-precision,numerical,Floating Point,Floating Point Precision,Numerical,我在很多面试考试中都发现了这个问题,但我自己却不知道该如何解决。问题是: 由两个16位字表示的浮点数可以表示多少位精度 答案显然是大约6位数 这是从哪里来的,你怎么计算出来的?一个IEEE-754浮点数有一个符号位,一些位数(e)表示指数,一些位数(m)表示尾数,这个数字乘以2表示指数。结果数字的形式如下所示 ±m×2e 例如,0b1.01×2-0b0100=1.25×2-4=.078125 它直接类似于(十进制)科学记数法中的实数 ±m×10e 如7.8125×10-2 正如十进制中的有效位数

我在很多面试考试中都发现了这个问题,但我自己却不知道该如何解决。问题是:

由两个16位字表示的浮点数可以表示多少位精度

答案显然是大约6位数


这是从哪里来的,你怎么计算出来的?

一个IEEE-754浮点数有一个符号位,一些位数(e)表示指数,一些位数(m)表示尾数,这个数字乘以2表示指数。结果数字的形式如下所示

±m×2e
例如,0b1.01×2-0b0100=1.25×2-4=.078125

它直接类似于(十进制)科学记数法中的实数

±m×10e
如7.8125×10-2

正如十进制中的有效位数与指数部分无关,二进制浮点中的精度也完全由尾数中的位数设置。尾数越长,数字所代表的精度越高。对于32位浮点数,将尾数中的位数设置为23位(+1加号+8表示指数);对于64位浮点数,它是52位(+1,+11)

科学记数法还有另一个惯例;尾数必须介于1(100)和10(101)之间。通过使科学记数法中的表示形式独特,这大大简化了比较——在科学记数法中只有一种方法可以写出数字。也就是说,200表示为2×102,而不是20×101或0.2×103。因此,可以非常快速地比较数字-任何形式+xyz×102的数字必然小于形式+abc×103的数字

类似地,在二进制中,尾数必须介于1和2(20…21)之间。因此尾数的第一位必须是1;因为它知道它的值必须是什么,所以不需要显式存储,所以实际上有24位和53位尾数。(对于非常小的数字——该位隐式为0,而不是1,但结果相同)

因此,32位浮点数中的24位尾数的范围为

0b1.00000000000000000000001 ~ 1.00000012
     to
0b1.11111111111111111111111 ~ 1.99999988
也就是说,大于1或小于1的最小增量位于小数点后第7位。另一种观察方法是考虑一个靠近中间的数字,看看间隔是什么:

0b1.01111111111111111111110 ~ 1.49999976
0b1.01111111111111111111111 ~ 1.49999988
0b1.10000000000000000000000 ~ 1.5
0b1.10000000000000000000001 ~ 1.50000012
因此,在小数点后第七位,间距约为1.2,因此精度小于7,但大于6位。间距在数字范围内有所不同;此外,人们很少只做一个浮点运算,这些误差由于舍入而传播,所以人们通常谈论6位精度。还应注意的是,虽然精度仅取决于尾数的大小,但如何“转换”为十进制数字中的错误在某种程度上也取决于指数;通过取其中一些值并乘以二的幂,可以看出这一点。但六位数的精度是一个很好的经验法则


在概述浮点数方面做得很好,综合参考文献是Goldberg的。

非常简单:32位IEEE-754浮点数的尾数为23+1位(在IEEE中称为有效位)。尾数的大小或多或少决定了可表示数字的数量

要获得有效位数,只需计算log10(224),约为7.22。(或者,如果您认为只有23位可以计算,因为顶部的位是固定的,那么您会得到log10(223),大约为6.92)。实际上,对于标准化值,有大约6-7个有效数字


对于64位浮点值(双精度)也可以这样做。它们有52(或53)位来存储尾数,因此计算log10(252),这大约是15.6(或15.9,53位),这将为您提供大约15个有效位。

建议:使用一个符号位、两个指数位和29个有效位。这可以得到大约九位数的精度。(它也使1+1等于无穷大,但你没有要求一些不愚蠢的东西!)可能重复@Mark:不,不是重复。该问题询问如何计算有效位数,这是一个有效的问题,IMO。这并不意味着提问者不知道浮点值不准确的原因。相反,虽然一般问题没有明确规定IEEE格式,但一般来说,单精度(32位)浮点的精度为6位小数。例如,IBM360float有24位分数,给你略多于7位的数字。当然,正如@ TMykLuBu演示的那样,你可以设计一个“不平衡”的FP格式,它给你带来了很多或更少,但是普通的设计会找到一个“平衡”,大约1/4个指数和3/4个分数。+ 1矛盾的是,如果你看C++ STD::数字限制,你会发现虽然双倍的精度小于16位数。最多需要17位十进制数字来区分打印的十进制表示法-最大10位整数位数(以十进制为基数),以确保始终区分不同的值。