(完成)若要了解 IEEE 浮点错误的教程

文章翻译 文章翻译
文章编号: 42980 - 查看本文应用于的产品
展开全部 | 关闭全部

本文内容

概要

浮点数学运算是一个复杂的话题迷惑很多程序员的。下面的教程来帮助您识别编程的情况下浮点错误可能发生以及如何避免它们。它还应允许您识别由相对于实际的编译器错误的固有的浮点数学限制导致的情况。

更多信息

十进制和二进制数字系统

通常情况下,我们计算以 10 为基中的内容。基是完全任意的。人们具有传统上使用以 10 为基的唯一原因是它们具有做很方便的盘点工具这 10 个手指。

数量 532.25 十进制 (以 10 为基) 意味着:
   (5 * 10^2) + (3 * 10^1) + (2 * 10^0) + (2 * 10^-1) + (5 * 10^-2)
       500    +     30     +      2     +     2/10    +    5/100
   _________
   =  532.25
				

在二进制数字系统 (基 2) 中,每一列表示 2 而不是 10 的幂。例如对于数 101.01 意味着:
   (1 * 2^2) + (0 * 2^1) + (1 * 2^0) + (0 * 2^-1) + (1 * 2^-2)
       4     +      0    +     1     +      0     +    1/4
   _________
   =  5.25  Decimal
				

整数是否在 pc 中的表示方式

因为没有小数部分的整数其计算机表示形式是为浮点值比简单得多。在个人计算机 (pc) 上的正常整数是 2 个字节 (16 位) 多长时间的表示符号的最高有效位。长整数是 4 个字节长。 正值是简单的二进制数字。例如:
    1 Decimal = 1 Binary
    2 Decimal = 10 Binary
   22 Decimal = 10110 Binary, etc.
				

但是,使用 2 的补数方案表示负整数。若要将 2 的补数表示为负数花数的绝对值的二进制表示形式,然后翻转所有位并加 1。例如:
   4 Decimal = 0000 0000 0000 0100
               1111 1111 1111 1011     Flip the Bits
   -4        = 1111 1111 1111 1100     Add 1
				

请注意,-1 十进制 = 1111年 1111年 1111年 1111 二进制,在其中解释为什么 Basic 都视为逻辑 true 的-1 (所有位 = 1)。这是不具有单独的运算符按位和逻辑比较的结果。通常在 Basic,很方便地使用代码段,下面时程序将使被多个逻辑比较。这极大地帮助提高可读性。
   CONST TRUE = -1
   CONST FALSE = NOT TRUE
				

请注意,添加的两个的任意组合补充一起使用普通的二进制运算的数字会产生正确的结果。

浮点的复杂因素

每个十进制整数可以准确地用来表示一个二进制整数 ; 但是,这并不是小数的数字,则返回 true。事实上,irrational 以 10 为基中的每个数字也将 irrational 其中某个底数小于 10 的任何系统中。

有关二进制文件,在具体的而言仅小数的数字,可在其中 q 是 2 的一个整数幂,该窗体 p/q,表示可以表示完全,具有有限数量的位。

不能完全以二进制表示如十进制的 0.0001 的甚至常见十进制小数。(0.0001 是一个重复的二进制分数,周期为 104 位 !)

这解释的原因如下所示的简单示例
   SUM = 0
   FOR I% = 1 TO 10000
      SUM = SUM + 0.0001
   NEXT I%
   PRINT SUM                   ' Theoretically = 1.0.
				

将 PRINT 1.000054 作为输出。小错误表示 0.0001 的二进制文件中将传播到总和中。

出于同样的原因您始终应非常谨慎实数上进行比较时。下面的示例阐释了一个常见的编程错误:
   item1# = 69.82#
   item2# = 69.20# + 0.62#
   IF item1# = item2# then print "Equality!"
				

这不会打印"相等!,因为不能完全以使结果从 (以二进制形式) 稍有不同的工作分配的值的二进制表示 69.82 比从表达式生成的值。在练习中,代码应当始终中采用的方式实现的一些能力允许此类比较。例如:
   IF (item1# < 69.83#) AND (item1# > 69.81#) then print "Equal"
				

这将 PRINT"等于"。

IEEE 格式的数字

为 MS-DOS,3.0 版 QuickBasic 附带的 MBF (Microsoft 二进制浮动点) 版本和数学协处理器的计算机的 IEEE (电气与电子工程师) 版本。为 MS-DOS QuickBasic,4.0 版和更高版本仅使用 IEEE。Microsoft 选择了 IEEE 标准来表示浮点值的基本的当前版本中,三个主要原因如下:
  1. 若要允许使用英特尔数学 coprocessors,哪种使用 IEEE 格式的基本。英特尔 80 x 87 系列 coprocessors 不能使用的 Microsoft 二进制格式数字。
  2. 若要使 interlanguage 之间进行调用基本、 C、 Pascal、 FORTRAN,和 MASM 变得更加容易。否则,转换例程必须能用于从一种语言的数字值发送到另一个。
  3. 以达到一致性。IEEE 是已接受的业界标准的 C 和 $ FORTRAN 编译器。
下面是一个双精度数字 IEEE 和 MBF 表示形式的快速比较:
               Sign Bits   Exponent Bits   Mantissa Bits
               ---------   -------------   -------------
   IEEE        1           11              52 + 1 (Implied)
    MBF        1            8              56
				

IEEE 和 MBF 浮点表示形式,查询 Microsoft 知识库中的以下的词之间差异的详细信息:
   IEEE and floating and point and appnote
				

请注意 IEEE 专用于指数使它可以表示值的范围更广的更多位数。MBF 有更多的尾数位,这样在将其变窄的范围内更准确。

一般的浮点概念

它是非常重要,认识到任何二进制浮点系统可以表示只有有限数量的确切的窗体中的浮点值。其他所有值必须被都近似由最接近的可表示值。IEEE 标准指定该方法的舍入到"最近"的可表示值的值。为 MS-DOS QuickBasic 支持标准,并根据在 IEEE 规则将舍入。

同时,请记住,可在 IEEE 中表示的数字分布在很宽的范围内。您可以假设它们在数量的行上。有一个高密度靠近 1.0 和-1.0 的可表示数字的但少于和少于为您转向 0 或无穷大。

专为工程计算在 IEEE 标准标准的目标是以最大限度地提高准确性 (获取关闭以实际进行编号)。精度是指可以表示的位数。标准的 IEEE 尝试平衡保持在可接受的限度内的精度和准确性用于号的小数部分的位的数目与专用于指数的位的数目。

IEEE 详细信息

浮点数表示其中 [指数] 是二进制指数按照以下格式:
   X =  Fraction * 2^(exponent - bias)
				

[部分] 是规范化指数进行调整,以便前导位始终为 1,因为这一数量的正态化的小数部分。此的方式它并没有存储,并获得一个更多的位的精度。这是一个隐含的位的原因。您可以认为这与科学记数法类似您操作指数中二进制,除了有一位数字的十进制的小数点左侧的位置您总是可以操作指数,以便第一位是一个 1,因为有唯一的 1 和 0。

[别名] 是用于避免必须存储负指数偏向值。

单精度数字的偏差是 127 和双精度数字的 (十进制) 1023年。

值等于所有 0 和所有 1 的 (二进制) 都保留给表示特殊情况。有其他特殊情况下为很好地指示各种错误条件。

单精度示例

2 = 1 * 2 ^1 = 0100年 0000 0000 0000...0000 0000 = 4000 0000 十六进制
请注意符号位是 0,和存储的指数是 128,或 100 0000 0,二进制,即 127 加 1。存储的尾数是 (1) 000 0000...它有一个隐含的前导 1 和二进制 0000 0000 点,所以实际的尾数是 1。

-2 =-1 * 2 ^1 = 1100年 0000 0000 0000...0000 0000 = C000 0000 十六进制
除了设置符号位以外,与 + 2 相同。这是对于所有 IEEE 格式浮点数字,则返回 true。

4 = 1 * 2 ^2 = 0100年 0000 1000年 0000...0000 0000 = 4080 0000 十六进制
相同的尾数指数增加 1 (偏差的值是 129,或 100 0000 1,在 $ 二进制中。

6 = 1.5 * 2 ^2 = 0100年 0000 1100年 0000...0000 0000 = 40 C 0 0000 十六进制
指数相同尾数是较大一半--它是 (1) 100 0000...0000 0000,其中由于这是一个二进制分数是 1-1/2 (小数位数的值是 1/2、 1/4、 1/8 等等)。

1 = 1 * 2 ^0 = 0011 1111年 1000年 0000...0000 0000 = 3F80 0000 十六进制
作为其他 2 的幂指数相同,尾数是一个小于 2 以二进制形式的 127,或 011 1111年 1 处。

.75 = 1.5 * 2 ^-1 = 0011 1111年 0100年 0000...0000 0000 = 3F40 0000 十六进制
是 126,011 1111年 0 中的二进制文件和尾数是 (1) 100 0000...是 1-1/2 0000 0000。

2.5 = 1.25 * 2 ^1 = 0100年 0000 0010 0000...0000 0000 = 4020 0000 十六进制
完全相同,2 除外,它表示 1/4 位设置在尾数中。

0.1 = 1.6 * 2 ^-4 = 0011 1101年...1100年 1100年 1100年 1101年 = 3DCC CCCD 十六进制
在 $ 二进制中的重复分数 1/10。尾数是 1.6 的只是不好意思,有偏差的指数说 1.6 就是将除以 16 (它是 011 1101年是十进制 123 的二进制中的 1)。真正的指数是 123-127 =-4,这意味着要相乘的系数是 2 **-4 = 1/16。请注意,存储的尾数在最后一位向上舍入。这是尝试尽可能按准确地表示 unrepresentable 的数量。(原因 1/10 和 1/100 是在 $ 二进制中表示不完全是 1/3 是不完全可表示十进制方式类似于)

0 = 1.0 * 2 ^-128 = 全零--一种特殊情况。

其他常见的浮点错误

以下是常见的浮点错误:
  1. 舍入误差

    在计算中的所有位二进制数中不能使用时,将导致此错误。

    示例: 添加到 0.9900 0.0001 (单精度)

    十进制的 0.0001 表示为:
    (1) 10100011011011100010111 * 2^(-14+Bias) (前导 0,在 $ 二进制中的 13 !)
    0.9900 表示为:
    (1) 11111010111000010100011 * 2^(-1+Bias)
    现在实际上将这些数字,必须对齐十进制 (二进制) 的点。为此,它们必须是 Unnormalized。下面是结果加法:
           .000000000000011010001101 * 2^0  <- Only 11 of 23 Bits retained
          +.111111010111000010100011 * 2^0
          ________________________________
           .111111010111011100110000 * 2^0
    
    						
    这被称为一个舍入误差,因为添加切换时,某些计算机舍入。其他人只需截断。圆-关闭错误是,必须考虑只要添加或将两个非常不同的值相乘。
  2. 减去两个几乎相等值
           .1235
          -.1234
           _____
           .0001
    
    						
    这将其折算。请注意尽管原始数字每个有四个有效位,结果有一个有效的数字。
  3. 溢出和下溢

    在结果太大或太小,无法表示为该数据类型,就会发生此事件。
  4. quantizing 错误

    浮点标准不能在确切的窗体中表示这些数字与会出现这种情况。
  5. 除数非常小的数

    这可以触发"被零除"错误或产生如下例所示的错误结果:
          A = 112000000
          B = 100000
          C = 0.0009
          X = A - B / C
    
    						
    入 QuickBasic MS-DOS,X 现在为具有值 888887,而不是正确的答案 900000。
  6. 输出错误

    当输出函数更改正在使用的值时,将发生这种类型的错误。

属性

文章编号: 42980 - 最后修改: 2005年8月16日 - 修订: 3.1
这篇文章中的信息适用于:
  • Microsoft Visual Basic 2.0 Standard Edition
  • Microsoft Visual Basic 3.0 Professional Edition
  • Microsoft Visual Basic 4.0 标准版
  • Microsoft Visual Basic 1.0 Standard Edition
  • Microsoft Visual Basic 2.0 Professional Edition
  • Microsoft Visual Basic 3.0 Professional Edition
  • Microsoft Visual Basic 4.0 专业版
  • Microsoft Visual Basic for MS-DOS
  • Microsoft QuickBasic 4.0
  • Microsoft QuickBASIC 4.0b
  • Microsoft QuickBasic 4.5 for MS-DOS
  • Microsoft BASIC 编译器 6.0
  • Microsoft BASIC Compiler 6.0b
  • Microsoft BASIC 专业开发系统 7.0
  • Microsoft Cinemania 97 标准版
关键字:?
kbmt KB42980 KbMtzh
机器翻译
注意:这篇文章是由无人工介入的微软自动的机器翻译软件翻译完成。微软很高兴能同时提供给您由人工翻译的和由机器翻译的文章, 以使您能使用您的语言访问所有的知识库文章。然而由机器翻译的文章并不总是完美的。它可能存在词汇,语法或文法的问题,就像是一个外国人在说中文时总是可能犯这样的错误。虽然我们经常升级机器翻译软件以提高翻译质量,但是我们不保证机器翻译的正确度,也不对由于内容的误译或者客户对它的错误使用所引起的任何直接的, 或间接的可能的问题负责。
点击这里察看该文章的英文版: 42980
Microsoft和/或其各供应商对于为任何目的而在本服务器上发布的文件及有关图形所含信息的适用性,不作任何声明。 所有该等文件及有关图形均"依样"提供,而不带任何性质的保证。Microsoft和/或其各供应商特此声明,对所有与该等信息有关的保证和条件不负任何责任,该等保证和条件包括关于适销性、符合特定用途、所有权和非侵权的所有默示保证和条件。在任何情况下,在由于使用或运行本服务器上的信息所引起的或与该等使用或运行有关的诉讼中,Microsoft和/或其各供应商就因丧失使用、数据或利润所导致的任何特别的、间接的、衍生性的损害或任何因使用而丧失所导致的之损害、数据或利润不负任何责任。
不再更新的 KB 内容免责声明
本文介绍那些 Microsoft 不再提供支持的产品。因此本文按“原样”提供,并且不再更新。

提供反馈

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com