当前位置: 首页 > 知识库问答 >
问题:

为什么复浮点除法下限溢位NumPy奇怪?

伊飞光
2023-03-14

考虑以下代码:

import numpy
numpy.seterr(under='warn')
x1 = 1 + 1j / (1 << 533)
x2 = 1 - 1j / (1 << 533)
y1 = x1 * 1.1
y2 = x2 * 1.1
z1 = x1 / 1.1
z2 = x2 / 1.1
print(numpy.divide(1, x1))  #              1-3.55641399918e-161j  # OK
print(numpy.divide(1, x2))  #              1+3.55641399918e-161j  # OK
print(numpy.divide(1, y1))  # 0.909090909091-3.23310363561e-161j  # underflow
print(numpy.divide(1, y2))  # 0.909090909091+3.23310363561e-161j  # underflow
print(numpy.divide(1, z1))  #            1.1-3.91205539909e-161j  # underflow
print(numpy.divide(1, z2))  #            1.1+3.91205539909e-161j  # underflow

不管我怎么看,这种下溢似乎都没有意义。正如维基百科所说,

下溢是计算机程序中的一种情况,其中计算结果的绝对值比计算机实际存储在CPU内存中的数值小。

但很明显,计算机能够存储与所讨论的值大致接近的数字,因此定义似乎与我在这里看到的行为完全不一致。

有人能解释一下为什么其中一些会产生下溢而另一些不会吗?
这是正确的行为还是错误?

共有1个答案

胡国兴
2023-03-14

要做这个数学,你需要首先“缩放”,也就是说,3.23310363561e-161。这就是触发下限溢位的原因

  0.909090909091
- 3.23310363561e-161 =
--------------------

  0.909090909091 x 10^0
- 3.23310363561 x 10^-161 =
-------------------------

  0.909090909091 x 10^0
- 0.000...                 0323310363561 =
    ^^^^^^^^^^^^^^^^^^^^^^^^
    160 0s
  --------------------------------------
 类似资料:
  • 问题内容: 问题很简单而且简短:为什么要清除浮动?我查看了w3标准文档,但没有任何暗示。 问题答案: 因为当您与其他任何东西一起使用时会建立一个新的块格式设置上下文(链接到w3.org规范)。

  • 与许多语言一样,Swift的除法运算符默认为整数除法,因此: 如果要进行浮点除法,必须执行以下操作 同样,与大多数其他语言一样,您不能强制转换整个操作: 发生这种情况是因为swift执行1和2的整数除法()并获得0,然后它尝试将其转换为,有效地为您提供0.0。 我很好奇为什么以下方法会奏效: 我觉得这应该会产生与双倍(1/2)相同的结果。为什么不呢?

  • 问题内容: 当我创建我的(有史以来第一次)两列时,我的问题浮出水面。 我的左,右列都有一个包装器,但是包装器的高度没有扩大到适合左,右列的位置,每一个分别漂浮在其侧面。 我在网上找到了一个解决方案,在该解决方案中,它向包装器添加了样式“overflow:auto”(这是对吗?)。 但是,在我的研究中,没有什么能以一种我可以理解的方式解释为什么包装器的高度不能自动扩展以适应嵌套的divs和两列。 嵌

  • 但如果将浮点数或整数减小或增大一定量,则比较运行得快得多: 更改比较运算符(例如,改用或)不会以任何明显的方式影响时间。 这不仅仅与幅度有关,因为选择较大或较小的值会导致更快的比较,所以我怀疑这是由于位排列的某种不幸方式造成的。

  • 问题内容: 我想四舍五入为。 该功能无法按我预期的方式工作。 问题答案: 你遇到了浮点数的老问题,不是所有的数字都能精确地表示。命令行只是向你显示内存中的完整浮点形式。 对于浮点表示,舍入的版本是相同的数字。由于计算机是二进制的,它们将浮点数存储为整数,然后除以2的幂,因此将以类似于的方式表示。 双精度数字有53位(16位)的精度,而常规浮点数有24位(8位)的精度。Python中的浮点类型使用双

  • 这样一个看似简单的数字怎么会“太大”而无法在64位内存中表达呢?