溢出与 Inf

Overflow vs Inf

提问人:Dante 提问时间:10/27/2014 最后编辑:AmroDante 更新时间:10/29/2014 访问量:882

问:

当我在 Matlab 中输入一个大于 max double 的数字时,例如,它返回 。出于教育目的,我想像 C 编译器一样获得溢出异常,返回溢出错误消息,而不是 .我的问题是:1.79769e+30810^309InfInf

  1. 溢出是例外吗?Inf

  2. 如果是,为什么 C 编译器不返回?Inf

  3. 如果没有,我可以在 Matlab 中得到溢出异常吗?

  4. 溢出异常之间有什么区别吗?Inf

另外,我不想在Matlab中签入,然后用函数抛出异常。Inferror()

C MATLAB 点浮 异常

评论

0赞 Dante 10/27/2014
@lakesh 什么意思?
1赞 Dante 10/27/2014
@lakesh我不想计算。也是不正确的。我想你的意思是.1e^30910^309=1.0e309
0赞 David 10/27/2014
你为什么要这样做?检查然后抛出异常有什么问题?Inf
4赞 horchler 10/27/2014
这是一个有效且有趣的问题。那些投反对票或投票关闭的人应该阅读浮点规范如何处理无穷大和溢出。它们通常是混合的,就像在Matlab中一样,但两者并不相同。
2赞 rayryeng 10/29/2014
我也不明白反对票。这是一个完全有效的问题,也是我真正好奇的问题!

答:

2赞 TroyHaskin 10/28/2014 #1

浮点

MATLAB 实现了用于浮点运算的 IEEE 标准 754。 本标准有五个定义的例外情况:

  1. 无效操作
  2. 除以零
  3. 溢出
  4. 下溢
  5. 准确

正如 GNU C 库所指出的,这些异常由状态词表示,但不会终止程序。 相反,将返回与异常相关的默认值;该值可以是实际数字,也可以是特殊值 MATLAB 中的特殊值是 、 、 和 ;这些 MATLAB 符号用于代替官方标准保留的二进制表示,以提高可读性和可用性(有点不错的语法糖)。 对特殊值的操作是明确定义的,并且以直观的方式操作。Inf-InfNaN-0

有了这些信息,问题的答案是:

  1. Inf表示执行的操作引发了上述异常之一(即 1、2 或 3),并被确定为默认返回值。Inf

  2. 根据程序的编写方式、使用的编译器以及存在的硬件,INFINITYNaN 是操作可以返回的特殊值。这取决于 IEEE-754 标准是否以及如何实施。C99 将 IEEE-754 实现作为标准的一部分,但最终取决于编译器如何实现(这可能会因激进的优化和标准选项(如舍入模式)而变得复杂)。CC

  3. 返回值 or 指示可能发生了溢出异常,但也可能是无效操作或除以零。我不认为MATLAB会告诉你它是什么(尽管也许你可以通过编译的MEX文件访问这些信息,但我不熟悉这些)。Inf-Inf

  4. 请参阅答案 1。

如需更多有趣和深入的示例,这里有一个不错的 PDF。


整数

整数在 MATLAB 中的行为与上述不同。 如果对指定位大小的整数的操作将超过该类的最大值,则该操作将设置为最大值,反之亦然。 换言之,MATLAB 整数不换行。

2赞 Amro 10/28/2014 #2

我将重复 Jan Simon 在“MATLAB Answers”网站上的回答:

若要停止(在调试器模式下)除以零,请使用:

warning on MATLAB:divideByZero
dbstop if warning MATLAB:divideByZero

同样,在取零的对数时停止:

warning on MATLAB:log:LogOfZero
dbstop if warning MATLAB:log:LogOfZero

若要在操作(函数调用或赋值)返回 或 时停止,请使用:NaNInf

dbstop if naninf

不幸的是,前两个警告似乎不再受支持,尽管最后一个选项在 R2014a 上仍然适用于我,并且实际上已记录在案

error_warning_handling_dialog1 error_warning_handling_dialog2

评论

0赞 horchler 10/29/2014
请参阅此问题和答案以及 Undocumented Matlab 关于捕获警告的这篇文章。
3赞 Amro 10/29/2014 #3

1) C/C++ 中的浮点

浮点数的运算可能会产生非数值的结果。例子:

  • 运算的结果是一个复数(想想sqrt(-1.0))
  • 操作的结果是未定义的(想想1.0 / 0.0)
  • 操作的结果太大而无法表示
  • 在其中一个操作数已经是 NaN 或 Inf 的情况下执行操作

IEEE754的理念是默认不捕获此类异常,而是生成特殊值 ( 和 ),并允许计算在不中断程序的情况下正常继续。由用户来测试这些结果并单独处理它们(就像 MATLAB 中的函数一样)。InfNaNisinfisnan

存在两种类型的 NaN 值:NaN(安静 NaN)和 sNaN(信号 NaN)。通常,当运算无法成功完成时,浮点数的所有算术运算都会产生安静类型(而不是信令类型)。

有一些(依赖于平台的)函数来控制浮点环境和捕获 FP 异常:

例如,查看 Python 如何为不同平台实现 FP 异常控制模块: https://hg.python.org/cpython/file/tip/Modules/fpectlmodule.c

2) C/C++ 中的整数

这显然与浮点完全不同,因为整数类型不能表示 Inf 或 NaN:

  • 无符号整数使用模块化算术(因此,如果结果超过最大整数,则值环绕)。这意味着无符号算术运算的结果始终是“数学定义的”,并且永远不会溢出。将其与MATLAB进行比较,MATLAB使用饱和算术来计算整数(将是)。uint8(200) + uint8(200)uint8(255)
  • 另一方面,有符号整数溢出是未定义的行为
  • 整数以零是未定义的行为。