提问人:Dante 提问时间:10/27/2014 最后编辑:AmroDante 更新时间:10/29/2014 访问量:882
溢出与 Inf
Overflow vs Inf
问:
当我在 Matlab 中输入一个大于 max double 的数字时,例如,它返回 。出于教育目的,我想像 C 编译器一样获得溢出异常,返回溢出错误消息,而不是 .我的问题是:1.79769e+308
10^309
Inf
Inf
溢出是例外吗?
Inf
如果是,为什么 C 编译器不返回?
Inf
如果没有,我可以在 Matlab 中得到溢出异常吗?
溢出异常之间有什么区别吗?
Inf
另外,我不想在Matlab中签入,然后用函数抛出异常。Inf
error()
答:
浮点
MATLAB 实现了用于浮点运算的 IEEE 标准 754。 本标准有五个定义的例外情况:
- 无效操作
- 除以零
- 溢出
- 下溢
- 准确
正如 GNU C 库所指出的,这些异常由状态词表示,但不会终止程序。
相反,将返回与异常相关的默认值;该值可以是实际数字,也可以是特殊值 MATLAB 中的特殊值是 、 、 和 ;这些 MATLAB 符号用于代替官方标准保留的二进制表示,以提高可读性和可用性(有点不错的语法糖)。
对特殊值的操作是明确定义的,并且以直观的方式操作。Inf
-Inf
NaN
-0
有了这些信息,问题的答案是:
Inf
表示执行的操作引发了上述异常之一(即 1、2 或 3),并被确定为默认返回值。Inf
根据程序的编写方式、使用的编译器以及存在的硬件,
INFINITY
和NaN
是操作可以返回的特殊值。这取决于 IEEE-754 标准是否以及如何实施。C99 将 IEEE-754 实现作为标准的一部分,但最终取决于编译器如何实现(这可能会因激进的优化和标准选项(如舍入模式)而变得复杂)。C
C
返回值 or 指示可能发生了溢出异常,但也可能是无效操作或除以零。我不认为MATLAB会告诉你它是什么(尽管也许你可以通过编译的MEX文件访问这些信息,但我不熟悉这些)。
Inf
-Inf
请参阅答案 1。
如需更多有趣和深入的示例,这里有一个不错的 PDF。
整数
整数在 MATLAB 中的行为与上述不同。 如果对指定位大小的整数的操作将超过该类的最大值,则该操作将设置为最大值,反之亦然。 换言之,MATLAB 整数不换行。
我将重复 Jan Simon 在“MATLAB Answers”网站上的回答:
若要停止(在调试器模式下)除以零,请使用:
warning on MATLAB:divideByZero
dbstop if warning MATLAB:divideByZero
同样,在取零的对数时停止:
warning on MATLAB:log:LogOfZero
dbstop if warning MATLAB:log:LogOfZero
若要在操作(函数调用或赋值)返回 或 时停止,请使用:NaN
Inf
dbstop if naninf
不幸的是,前两个警告似乎不再受支持,尽管最后一个选项在 R2014a 上仍然适用于我,并且实际上已记录在案。
评论
1) C/C++ 中的浮点
对浮点数的运算可能会产生非数值的结果。例子:
- 运算的结果是一个复数(想想
sqrt(-1.0)
) - 操作的结果是未定义的(想想
1.0 / 0.0
) - 操作的结果太大而无法表示
- 在其中一个操作数已经是 NaN 或 Inf 的情况下执行操作
IEEE754的理念是默认不捕获此类异常,而是生成特殊值 ( 和 ),并允许计算在不中断程序的情况下正常继续。由用户来测试这些结果并单独处理它们(就像 MATLAB 中的函数一样)。Inf
NaN
isinf
isnan
存在两种类型的 NaN 值:NaN(安静 NaN)和 sNaN(信号 NaN)。通常,当运算无法成功完成时,浮点数的所有算术运算都会产生安静类型(而不是信令类型)。
有一些(依赖于平台的)函数来控制浮点环境和捕获 FP 异常:
- Win32 API 具有
_control87()
来控制 FPU 标志。 - POSIX/Linux 系统通常通过捕获 SIGFPE 信号来处理 FP 异常(参见
feenableexcept
)。 - SunOS/Solaris 也有自己的功能(参见 Sun/Oracle 的《数值计算指南》中的第 4 章)
- C99/C++11 引入了
fenv
标头,其中包含控制浮点异常标志的函数。
例如,查看 Python 如何为不同平台实现 FP 异常控制模块: https://hg.python.org/cpython/file/tip/Modules/fpectlmodule.c
2) C/C++ 中的整数
这显然与浮点完全不同,因为整数类型不能表示 Inf 或 NaN:
评论
1e^309
10^309=1.0e309
Inf