如果将最小的正浮点值乘以一个非零数,是否保证得到非零结果?
If you multiply the smallest positive floating point value by a non-zero number, are you guaranteed a non-zero result?
如果我将 epsilon
取为最小的正非零浮点数(可以是 16
、32
或 64
位)并乘以 epsilon
通过相同大小的非零浮点值:
Am I guaranteed a non-zero result of the same sign as the original
value? Or do I risk rounding error (zero, or switching signs)?
环境:Python/Numpy
没有
In [1]: import numpy
In [2]: x = numpy.nextafter(0, 1)
In [3]: x
Out[3]: 4.9406564584124654e-324
In [4]: x*x
Out[4]: 0.0
当精确结果介于 0 和最小正浮点数之间时,它必须舍入到这些选项之一,在这种情况下,0 更接近。
如果出于某种原因您想自定义此行为,NumPy 允许您使用 numpy.seterr
自定义下溢和其他 IEEE 754 浮点异常的行为,尽管它不会影响对普通 Python 个对象:
In [5]: numpy.seterr(under='raise')
Out[5]: {'divide': 'warn', 'invalid': 'warn', 'over': 'warn', 'under': 'ignore'}
In [6]: x # NumPy float, not regular float, despite its looks
Out[6]: 4.9406564584124654e-324
In [7]: x*x
---------------------------------------------------------------------------
FloatingPointError Traceback (most recent call last)
<ipython-input-7-a3ff2a28c75d> in <module>()
----> 1 x*x
FloatingPointError: underflow encountered in double_scalars
In [8]: (4.9406564584124654e-324)**2 # regular float
Out[8]: 0.0
无法更改舍入模式。
当然不是,和epsilon关系不大。例如,
>>> x = 1e-200
>>> x
1e-200
远离 epsilon,但是
>>> x * x
0.0
下溢为 0。如果我们实际上使用 epsilon,那么,例如,将其乘以 0.25 也会下溢为 0。
不过,如果您的平台 C 编译器和硬件支持 754 标准,零的符号将与被乘数的符号匹配:
>>> x * -x
-0.0
如果我将 epsilon
取为最小的正非零浮点数(可以是 16
、32
或 64
位)并乘以 epsilon
通过相同大小的非零浮点值:
Am I guaranteed a non-zero result of the same sign as the original value? Or do I risk rounding error (zero, or switching signs)?
环境:Python/Numpy
没有
In [1]: import numpy
In [2]: x = numpy.nextafter(0, 1)
In [3]: x
Out[3]: 4.9406564584124654e-324
In [4]: x*x
Out[4]: 0.0
当精确结果介于 0 和最小正浮点数之间时,它必须舍入到这些选项之一,在这种情况下,0 更接近。
如果出于某种原因您想自定义此行为,NumPy 允许您使用 numpy.seterr
自定义下溢和其他 IEEE 754 浮点异常的行为,尽管它不会影响对普通 Python 个对象:
In [5]: numpy.seterr(under='raise')
Out[5]: {'divide': 'warn', 'invalid': 'warn', 'over': 'warn', 'under': 'ignore'}
In [6]: x # NumPy float, not regular float, despite its looks
Out[6]: 4.9406564584124654e-324
In [7]: x*x
---------------------------------------------------------------------------
FloatingPointError Traceback (most recent call last)
<ipython-input-7-a3ff2a28c75d> in <module>()
----> 1 x*x
FloatingPointError: underflow encountered in double_scalars
In [8]: (4.9406564584124654e-324)**2 # regular float
Out[8]: 0.0
无法更改舍入模式。
当然不是,和epsilon关系不大。例如,
>>> x = 1e-200
>>> x
1e-200
远离 epsilon,但是
>>> x * x
0.0
下溢为 0。如果我们实际上使用 epsilon,那么,例如,将其乘以 0.25 也会下溢为 0。
不过,如果您的平台 C 编译器和硬件支持 754 标准,零的符号将与被乘数的符号匹配:
>>> x * -x
-0.0