如何将浮点数剪切到略低于限制?

时间:2012-02-23 02:12:23

标签: python numpy floating-point clipping

numpy.random.uniform()之类的函数返回两个边界之间的浮点值,包括第一个绑定但排除顶部绑定。也就是说,numpy.random.uniform(0,1)可能会产生0,但永远不会产生1。

我正在使用这样的数字并使用有时会返回范围之外的结果的函数来处理它们。我可以使用numpy.clip()将范围之外的值切换回0-1,但不幸的是,该限制是包含的顶部数字。

如何在python中指定“无限小于1的数字?”

3 个答案:

答案 0 :(得分:7)

好吧,如果你正在使用numpy,你只需使用numpy.nextafter

>>> import numpy
>>> numpy.nextafter(1, 0)
0.99999999999999989

请注意(至少对我而言):

>>> import sys
>>> 1-sys.float_info.epsilon
0.9999999999999998
>>> numpy.nextafter(1, 0) - (1-sys.float_info.epsilon)
1.1102230246251565e-16
>>> numpy.nextafter(1, 0) > (1-sys.float_info.epsilon)
True

顺便提一下,对于@Robert Kern的第二点,有时random.uniform 包含除(0,1)之外的某些输入的上限:

>>> import random, numpy
>>> numpy.nextafter(0,1)
4.9406564584124654e-324
>>> random.uniform(0, numpy.nextafter(0,1))
0.0
>>> random.uniform(0, numpy.nextafter(0,1))
0.0
>>> random.uniform(0, numpy.nextafter(0,1))
4.9406564584124654e-324

[我有一般认为,可能有更好的方法来解决这个问题。]

答案 1 :(得分:3)

Python sys提供float_info结构,其epsilon属性,定义为

  

1和最小值之间的差值,大于1,可表示为浮点数

所以我想像

这样的东西
def clip(num):
    if(num >= 1):
        return 1 - sys.float_info.epsilon
    return num

应该做的伎俩。虽然这通常很糟糕,但你可能永远不会尝试这个原因的原因很多。

编辑我刚刚观察到一个这样的原因 - 实施。虽然CPython做了你期望的,但我的第一个选择是IronPython,doesn't(尽管这是一个bug)。你要警告!

答案 2 :(得分:2)

在大多数实际情况下,您不需要无限小,您可以近似它。因此,对于您的示例,我使用0.9999999而不是1.0。