Matlab中使用双精度浮点数的算术精度问题

5

我有点难以理解这些双精度浮点数的精度如何影响Matlab中算术运算的结果。我认为既然a和b都是双精度浮点数,它们应该能够进行高达该精度的操作。我意识到可能会有舍入误差,但由于这些数字远远在64位数字表示范围内,所以我认为这不会是一个问题。

a = 1.22e-45
b = 1
a == 0
   ans = 0  %a is not equal to zero
(a + b) == 1
   ans = 1

为什么它能够具备足够的精度来识别 a != 0,但是当加上1时却没有显示任何变化。

3个回答

6

64位IEEE-754浮点数具有足够的精度(具有53位尾数),可以表示约16个有效十进制数字。但是,要区分(1+a)= 1.00....000122和1.000这样的例子,则需要大约45个有效十进制数字。


我认为尾数有52位(11位用于指数,再加上1位表示符号,总共64位)。Cleve Moler(MATLAB第一版的作者)撰写了一篇优秀的文章,详细解释了浮点数的所有细节:[PDF链接] http://www.mathworks.com/company/newsletters/news_notes/pdf/Fall96Cleve.pdf - Amro
2
@Amro:除非数字被规范化,否则会有一个隐含的前导“1”位。因此,在大多数情况下(特别是对于这些数字),Jim是正确的。 - Drew Hall
谢谢。我在理解计算机数字表示方面还有很长的路要走。 - ZuluForce
@Drew Hall:你说得完全正确,规范化表示的形式为 ±(1+f)*2^e... 是我搞错了 :) - Amro
@Amro--容易被遗忘--毕竟它并不存在! :) (另外,在我的回答中,由于某种原因我记得它是48位。老脑子已经不如以前了...:)) - Drew Hall

6
"浮点数"的意思就是精度与数字本身的规模有关。
在您提供的具体例子中,1.22e-45可以单独表示,因为指数可以调整为表示10^-45,或者大约2^-150。
另一方面,1.0用二进制表示比例为2^0(即1)。
要添加这两个值,您需要对齐它们的小数点(嗯...二进制点),这意味着1.22e-45的所有精度都向右移动了150多位。
当然,IEEE双精度浮点值只有53位尾数(精度),这意味着在1.0的规模下,1.22e-45实际上等于零。

3

除了其他答案中提到的内容,您可以使用MATLAB函数 EPS 来可视化您遇到的精度问题。对于给定的双精度浮点数,函数EPS将告诉您它与下一个最大可表示浮点数之间的距离:

>> a = 1.22e-45;
>> b = 1;
>> eps(b)

ans =

  2.2204e-016

请注意,比1大的下一个浮点数是1.00000000000000022204...,而a的值甚至不接近两个数字之间的一半距离。因此,a+b最终保持为1。
顺便提一下,您也可以通过查看使用函数REALMIN表示的最小可表示双精度浮点值来了解为什么尽管非常小,但a被认为是非零值:
>> realmin

ans =

  2.2251e-308  %# MUCH smaller than a!

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