[译]浮点数的危害

The Perils of FloatingPoint

by Bruce M. Bush

Copyright (c) 1996 Lahey Computer Systems, Inc. Permission to copy isgranted with acknowledgement of the source.

原文参见  The Perils of Floating Point

[译]浮点数的危害

By wttttt

@2016.10.24【庆祝这个伟大的程序员的节日?233】

如果没有数字电脑的浮点数能力,许多伟大的程序员和科学家们可能不会有近些年的进展。然而,即使对有着多年数学经验的人而言,一些浮点数的计算结果还是看起来十分奇怪。我将试图解释这其中一些奇怪结果的产生原因,并在适当时给出一些建议。

    浮点数表示和计算是不精确的,但是我不认为这对程序员而言是十分麻烦的。许多输入值是测量结果,它们本身就是不精确的,因此关于输出值的问题不在于是否存在错误,而在于错误被预料的程度。然而,当你可以在脑海里计算的结果比比电脑用它的浮点数计算结果更精确时,你就会开始感到怀疑了。  

我使用FORTRAN编写我的例子,原因如下:

1.   FORTRAN比其他的计算机语言有更多的浮点数计算;

2.   我在Lahey Computer Systems公司工作,它们开发和销售FORTRAN语言系统。

二进制浮点数

许多奇怪结果的核心根本都是:计算机的浮点数通常是二进制的,然而外部表示是十进制的。我们预计1/3将不会是可精确表示的,但是直觉上似乎.01是可以的。不是这样的!.01在IEEE单精度表示是10737418/1073741824或近似地0.009999999776482582。你甚至可能没有注意到这些区别,知道你看到如下所示的代码:

REAL X

DATA X/.01/

IF ( X* 100.d0 .NE. 1.0 ) THEN

   PRINT *, 'Many systems print this surprisingresult. '

ELSE

   PRINT *, 'And some may print this.'

ENDIF

十进制浮点数实现没有这种奇怪现象。然而,十进制浮点数实现是很稀少的,因为在数字电脑中二进制计算要快很多。

不精确性

数字电脑上的浮点数运算的不精确性是天性的。一个32位浮点数的24比特(包括隐藏比特)尾数近似地表示7个重要的十进制数字。不想连续的实数系统,一个浮点数系统在数字之间时有间隔的。如果一个数字是不可精确表示的,那么它一定是通过最近的可表示的值来近似的。

因为相同数量的数字被用来表示所有的正常化的数字,所以样品数量越小,可表示数字的密度越大。比如,在1.0和2.0之间近似有8,388,607个单精度数字,然而1023.0和1024.0之间仅仅有大约8191个单精度数字。

在任意计算上,数学上等价的表达式使用浮点计算可以产生不同值。在如下例子中,Z和Z1将有不同值,因为(1/Y)或者1/7在二进制浮点数中是不可精确表示的。

REALX, Y, Y1, Z, Z1

DATAX/77777/, Y/7/

Y1 = 1/ Y

Z = X/ Y

Z1 = X* Y1

IF (Z.NE. Z1) PRINT *, 'Not equal!'

END

 

不重要的数字

如下的示例代码阐述了一个现象--看起来重要的无意义的数字:

REALA, Y

DATA Y/1000.2/     ! About 7 digits ofprecision in Y

A = Y- 1000.0      ! About 3 significantdigits in result

PRINT*, A          ! Prints 0.200012

END

一个单精度(实数)实体可以最大表示大约7个十进制精度数字,因此

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值