如何处理上溢和下溢?

2023-12-06

我是 Matlab 新手,试图弄清楚当答案实际上在范围内时如何处理溢出和下溢算术。

例如:

x = 2e+160
x = x*x (which returns inf, an overflow)
x = sqrt(x) (which is in the range)

任何帮助表示赞赏。


我不是 Matlab 用户,所以请记住这一点。

这背后的主要问题是首先检测上溢/下溢

这有时很困难,因为它们也会出现在计算不返回的其他情况下zero or inf。例如,在数值积分期间,上溢/下溢可能会导致结果错误,但仍然是非零数。

根据我的经验,我倾向于认为查看十六进制表示形式的数字很有用(除非您的硬件/软件计算在内部使用十进制基数来表示变量,这种情况很少见,因为大多数硬件/软件都是二进制的)。因此,查看十六进制形式的数字并检测如下模式:

??????????.????FFFFFFFFFFF?? hex

当你查看小数部分并发现这么多FFFFF出现在最低数字附近,那么您的数字是最有可能的下溢或非常接近该点。零的数量或最后的数量通常会随着每次迭代的饱和而减少:

??????????.????FFFFFFFFFFF hex

溢出同样饱和,但在另一侧是这样的:

FFFFFFFFFFF.FFFFFF?????? hex

对于某些算法来说,在下一次迭代之前对这些数字进行向上/向下舍入更为精确,但在应用于未知数之前,您始终需要检查一些众所周知的计算示例是否属于这种情况......请看这里:

  • 浮点除法器

这是使用这种技术的算法的一个很好的例子

检测上溢/下溢的另一种方法是预测结果数大小。例如

  • *将指数相加
  • /减去指数
  • sqrt将指数减半
  • +,-可以导致+1/-1较大指数的

因此,如果您正在处理大/小指数,您知道哪些操作可能会导致溢出问题。

最重要的是,当结果精度不适合尾数时,可能会发生下溢。因此,您需要小心增加结果已使用位的操作,例如:

  • a*b中已用位的总和a,b
  • +,-(a,b) 的最大使用位 - (a,b) 的最小使用位
  • /添加一些位来保存分数...

The +,-操作是最糟糕的,例如如果您添加2^100 + 2^-100那么结果需要 200 位尾数,而操作数本身只有 1 位尾数。

如果检测到上溢/下溢该怎么办:

  1. 变化方程

    如前所述,您可以切换到log它可以轻松处理更大的范围,但也存在其他问题。通常情况下,算法的轻微变化可能会导致结果按不同的因子缩放,但子结果仍在安全范围内,因此您只需要最终结果即可缩放到危险范围。在更改方程时,您应该始终考虑结果的精度和有效性。

  2. 使用更大的变量数据类型

    如果我没记错的话,Matlab 有任意精度的数字,所以如果需要的话可以使用它们。您也可以使用标准float/double变量并将值存储到更多变量中,如下所示:

    • 提高数值积分精度
  3. 停止迭代

    例如,某些算法使用以下系列:

    1/1! + 1/2! + 1/3! + ... + 1/n!
    

    在某些情况下,如果您在停止迭代时检测到子结果溢出/下溢,您仍然可以获得相对准确的计算结果。不要忘记不要将溢出的子结果包含到最终结果中。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何处理上溢和下溢? 的相关文章

随机推荐