IEEE754-2008 标准详解(五):异常

IEEE754-2008 标准详解(五):异常


本文为原创文章,转载请注明出处,并注明转载自“黄邦勇帅(原名:黄勇)”

由于能力有限,文中难免有错漏之处,望广大读者指出更正,不胜感激

本文是对《C++语法详解》一书相关章节的增补,以增强读者对浮点数的理解,《C++语法详解》网盘地址:https://pan.baidu.com/s/1dIxLMN5b91zpJN2sZv1MNg

本文摘自本人所作《IEEE754-2008标准详解》网盘地址
链接:https://pan.baidu.com/s/10soDctgCJ84MDs3PyhJBcw?pwd=lzku
提取码:lzku

有兴趣的读者可参阅本人所著《C++语法详解》一书,电子工业出版社出版,该书语法示例短小精悍,对查阅C++知识点相当方便,并对语法原理进行了透彻、深入详细的讲解,可确保读者彻底弄懂C++的原理,彻底解惑C++,使其知其然更知其所以然。此书是一本全面了解C++不可多得的案头必备图书。

由于本人能力有限,文中难免有错漏之处,望广大读者指出更正,不胜感激


IEEE 754规定了以下5种异常。发送这些异常时调用发送异常信号的默认或备用处理。对于每种异常,实现必须提供相应的状态标志。

  • Invalid operation(无效操作)
  • divideByZero(除零)
  • overflow (溢出)
  • underflow (下溢)
  • inexact(不精确的)

5.1 异常和状态标志基本规则


1、异常发送基本规则

  • 1)、规则1:对IEEE754所要求的任何运算的调用最多只能直接发送一个异常信号
  • 2)、规则2:对于第一个异常,可以通过默认或备用异常处理发送额外的(additional )异常(异常处理详见后文)。如,调用某运算函数x(),此时仅能发送一个异常,但处理该异常的处理函数(默认或备用异常处理)可以再发送额外异常。下面是常见的两种情形
  • 规则3:溢出的默认异常处理会发送不精确的异常信号(见后文)。
  • 规则4:如果默认结果是不精确的,则下溢的默认异常处理会发送不精确的异常信号(见后文)。

2、非IEEE754定义的运算发送异常的规则

  • 1)、规则5:IEEE754定义的计算运算,仅在IEEE754指定的条件出现时,发送异常,但这并不意味着,这些异常是由IEEE754中定义的运算发送的。也就是说,非IEEE754的运算也可能发送异常。如复杂(complex )算术或某些超越函数(transcendental functions)。
  • 2)、规则6:IEEE754未指定的那些运算和其他运算,应根据IEEE754定义的标准运算来发送那些异常信号,但这可能并不总是经济的(合算的)。
  • 3)、规则7:非标准函数的标准异常是由语言定义的(language-defined)。

3、状态标志的设置

  • 1)、在IEEE754中,有一个专门的异常标志(简称标志或状态标志)来描述异常的状态,当有异常产生时有可能会设置或清除某个异常状态标志,因此,在IEEE754中,有专门的有关标志的规定。注意:在IEEE754中设置标志被称为“提升(raise)”标志,而清除标志被称为“降低(lower)”标志。
  • 2)、规则8:一个状态标志可以通过默认、备用的异常处理,或者通过显式的用户行为(action)提升(raise)。这里说明了,标志被设置的三种情形:默认处理,备用处理和用户行为。
  • 3)、规则9:对于默认的异常处理,提升(raise)的状态标志通常表示相应的异常已被发送并已通过默认处理。
  • 4)、规则10:只有在精确下溢的情况下,才会处理异常而不提升(即,设置)状态标志,而只有在用户请求时才会提升状态标志而不发送异常。只有在用户请求时,状态标志必须被降低(lowered,即清除)。
  • 5)、规则11:用户应能够单独或集体测试和更改状态标志,并必须进一步能够一次保存和恢复所有状态标志。
  • 6)、规则12:restoreFlags或raiseFlags运算的调用可以直接提升状态标志的任意组合。当通过默认处理所有异常时,本标准要求的任何其他运算的调用最多可以提升两个状态标志,即,具有不精确的溢出或具有不精确的下溢。
  • 7)、规则13:不从其他源继承状态标志的程序,以所有状态标志都降低(即清除)开始执行

5.2 无效操作异常


5.2.1、发送无效操作异常的条件

当且仅当没有有用的可定义的结果时(即,不能产生正确的结果),才发送无效操作异常。此时,被执行的运算的操作数是无效的。

5.2.2、发送无效操作异常的规则

1、以下规则将运算进行如下划分:

  • 1)、划分为产生浮点结果的运算和不产生浮点结果的运算。
  • 2)、按操作数是否含有qNaN、sNaN划分
  • 3)、按前文讲解的划分,即,分为通用计算运算,Quiet计算运算,Signaling计算运算、非计算运算。

2、总体规则

  • 1)、规则1:通用计算运算产生浮点或整数结果,根据IEEE754标准的规定舍入所有结果,并可能发送浮点异常。

  • 2)、规则2:Quiet计算运算产生浮点结果,并且不发送浮点异常信号。

  • 3)、规则3:Signaling计算运算不会产生浮点结果,且可能会发出浮点异常信号。Signaling计算运算仅有比较运算。

  • 4)、规则4:非计算运算不会产生浮点结果,且不会发送浮点异常信号。

3、操作数含有NaN时的规则

  • 1)、规则5:sNaN必须是被保留的操作数,在默认的异常处理下,除了formatOf 通用计算运算中的部分转换运算外,对于每一个通用计算运算和signaling计算运算,发送无效操作异常。对于非默认的处理详见后文。此规则,可以简单理解为,除某些运算外,sNaN通常发送无效操作异常

  • 2)、规则6:每一个包括一个或多个输入NaN的通用计算运算和quiet计算运算(它们都没有sNaN),除fusedMultiplyAdd可能会发出无效操作异常外,都不会发送异常信号。可把此规则简单理解为,qNaN通常不发送无效操作异常

  • 3)、规则7:qNaN会在一些不交付浮点结果的运算上发出异常信号;这些运算见下文。

  • 4)、规则8:对于一个具有qNaN输入的运算,除了maximum和minimum运算外,如果要交付一个浮点结果,结果必须是一个qNaN,它应该是输入NaN中的一个。注意:signaling计算运算并不产生浮点结果,当signaling计算运算的操作数是qNaN时,其结果IEEE754并未明确规定,因此,其结果可能是qNaN、sNaN或其他结果。

  • 5)、注意:规则5~7是指的操作数含有NaN的情形,某些运算即使操作数不是NaN,也会发送无效操作异常

4、其他规则

  • 规则9:在默认异常处理下,对于任何发送无效操作异常信号,且产生浮点结果的运算的默认结果必须是一个qNaN,它应该提供一些诊断信息。此规则并未指明操作数必须含有NaN,也就是说,无论操作数是否含有NaN,只要发送无效操作异常且产生浮点结果的运算的默认结果必须是qNaN

5、规则8和规则9说明了两种产生qNaN结果的情形,但IEEE754并未讲解,什么情况下运算会产生sNaN的结果

6、表XXX为发送无效操作异常的总结

在这里插入图片描述

5.2.3、发送无效操作异常的详细情况

1、以下产生浮点结果(其结果必是qNaN)的运算,发送无效操作异常

  • 1)、对sNaN的任何通用计算运算(除某些转换运算外)或signaling计算运算,详见表XXX

  • 2)、乘法:multiplication(0,∞)或multiplication(∞,0),即0 × ∞ 或 ∞ × 0

  • 3)、fusedMultiplyAdd(0,∞,c)或fusedMultiplyAdd(∞,0,c),即0 × ∞ + c,或 ∞ × 0 + c,其中c是qNaN,此时由实现定义是否发送无效操作异常。

  • 4)、无穷大的减法,如:addition(+∞,−∞),即+∞ − (−∞)

  • 5)、除法:division(0, 0) 或 division(∞, ∞)

  • 6)、求余:remainder(x, y),当y等于0或x是无限的且两个都不是NaN时

  • 7)、squareRoot (平方根运算),如果操作数小于零

  • 8)、quantize运算,当结果不适合目标格式或当一个操作数是有限的而另一个是无限的时候

2、对于不产生浮点结果的运算,发送无效操作异常的运算有(规则7的补充):

  • 1)、转换运算(详见表5.2):将浮点数转换为整数格式,当source为NaN、无穷大或在适当的舍入属性下可以转换为结果格式范围(rang)之外的整数的值时。

  • 2)、当关系是无序时的无序信令谓词(详见表5.3)

  • 3)、logB(NaN)、logB(∞)或logB(0) ,当logBFormat为整数格式时(详见表5.1)。

3、无穷大与异常

  • 1)、以下运算操作数是无穷大时不会发送异常

    • (1)、当x是有限时的加减法,如,addition(∞, x), addition(x, ∞), subtraction(∞, x), or subtraction(x, ∞),即 ∞ + x,x + ∞, ∞ − x,x−∞

    • (2)、当有限或无限的x≠0时的乘法,multiplication(∞, x) or multiplication(x, ∞),即,x∞,∞x

    • (3)、当x为有限时的除法division(∞, x) or division(x, ∞),即,x ÷∞和∞÷x

    • (4)、squareRoot(+∞),即对正无穷大的平方根

    • (5)、有限规约数x的余数remainder(x, ∞) ,即x%∞

    • (6)、以另一种格式把一个无穷大转换成相同的无穷大

  • 2)、以下情况下会发送与无穷大相关的异常

    • ∞是一个无效操作数
    • ∞是从溢出或除零的有限操作数创建的
    • remainder(subnormal, ∞)发送下溢信号,即subnormal % ∞时发送下溢信号,subnormaal是指的非规约数

4、对加、减、乘、除运算的小结

  • 1)、加、减、乘、除运算是常见运算,此处对这几种运算作一小结。

  • 2)、由前文可知,加、减、乘、除运算是会产生浮点结果的运算,因此,只要这些运算一旦发送无效操作异常,则必然会得到结果为qNaN的值(规则9),因此,

    • 以下情形会产生qNaN的结果
      • 0 × ∞ 或 ∞ × 0
      • +∞ − (−∞)
      • 0/0或 ∞/∞
      • 当具有一个qNaN操作数时 (规则8)
    • 但是以下情形 (x是有限数),其结果不一定是qNaN
      • ∞+x,x+∞, ∞−x,x−∞
      • x∞,∞x ,其中x ≠ 0
      • x ÷∞和∞÷x

5.3 其他异常


1、除零(divideByZero)异常

  • 1)、当且仅当为有限操作数上的运算定义了精确的无限结果时,才必须发送divideByZero(除零)异常,注:可把“精确的无限结果”理解为“无穷大”。

  • 2)、divideByZero的默认结果必须是根据以下运算的具有合适(correctly)符号的∞:

    • 对于除法:当除数为零,被除数为有限非零数时,无穷大的符号是操作数符号的exclusive OR(排他性或,即异或)。

    • 对于logB(0):当logBFormat为浮点格式时,无穷大的符号为负(即−∞),见第4章。

2、溢出(Overflow)异常

  • 1)、当且仅当四舍五入的浮点结果(指数范围是无界的(unbounded))超出目标格式的最大有限数的大小时,才必须发送溢出异常。
  • 2)、在溢出的默认异常处理下,溢出标志必须被提升,不精确异常必须被发送。

3、下溢(Underflow )异常

  • 1)、当检测到极小的(tiny)非零结果时,必须发送下溢异常信号。
  • 2)、对于二进制格式,检测极小非零结果的方法是:
    • a)、在四舍五入后:当计算的非零结果(就好像指数范围是无界的似的)严格位于±b emin之间时,注:bemin是最小的正规约数,−bemin是最大的负规约数。
      或者
    • b)、在四舍五入前:当计算的非零结果(就好像指数范围和精度是无界的似的)严格位于±b emin之间时。
  • 3)、实现者必须选择如何检测极小值(tininess),即,以上两种检测方法应选择其中一种执行。但必须以同样的方式检测所有以2为基数的运算的极小值,包括在二进制舍入属性下的转换运算。
  • 4)、对于十进制格式,极小值(tininess)是在四舍五入之前检测的。
  • 5)、下溢的默认异常处理必须始终交付一个四舍五入的结果,这可能是零、非规约数(subnormal)或± b emin 。也就是说,绝对值比bemin小的数,要么视为0,要么视为非规约数,要么视为bemin 或 −bemin 。
  • 6)、此外,在下溢的默认异常处理下,如果四舍五入的结果是不精确的(inexact),下溢标志必须被提升(raised),并且不精确异常必须被发送。如果四舍五入的结果是精确的,则不会提升任何标志,也不会发出不精确的异常信号。这是接收默认处理的异常信号的本标准中唯一不提升相应标志的情况。这样的下溢信号在默认处理下没有显著的影响。

4、不精确的(Inexact )异常
除非另有说明,如果一个运算的四舍五入结果是不精确的,则不精确的异常必须被发送。也就是说,不精确的异常只发生在四舍五入时。前文已讲过,在产生溢出或下溢时可能会发送不精确的异常


5.4 异常总结


发送异常通常与运算有关系,表5.1、表5.2、表5.3总结了所有发送异常的运算的详细情形

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述


作者:黄邦勇帅(原名:黄勇)

2021-11-29

在这里插入图片描述


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值