我需要一种干净的方法来检查Python中的范围检查浮点数

时间:2009-12-09 12:35:51

标签: python

我正在寻找一种在Python中使用范围检查浮点数的简单方法,其中最小和最大边界可能为空。

有问题的代码是:

    tval = float(-b - discriminant) / float (2*a)
    if tval >= tmin and tval <= tmax:
        return tval 

    tval = float(-b + discriminant) / float (2*a)
    if tval >= tmin and tval <= tmax:
        return tval

    # Neither solution was within the acceptable range.
    return None

但是,这完全无法处理tmin或tmax为None的情况(应解释为分别表示没有最小值或最大值)。

到目前为止,我能想到的最好的是:

    tval = float(-b - discriminant) / float (2*a)
    if (tmin == None or tval >= tmin) and (tmax == None or tval <= tmax):
        return tval 

    tval = float(-b + discriminant) / float (2*a)
    if (tmin == None or tval >= tmin) and (tmax == None or tval <= tmax):
        return tval

    # Neither solution was within the acceptable range.
    return None

我一直认为必须有一种更好(更清晰,更易读)的方式来编写它。有什么想法吗?

4 个答案:

答案 0 :(得分:4)

首先,一些设置:我们需要一个浮点无穷大常数。

INF = float(1e3000)

INF = float('inf')  # Python 2.6+

第一种选择可以被认为是实用的便携式;只需使用一些非常大的值,保证超出您平台的浮点类型所代表的范围。第二个选项是“真正的”可移植的,但需要Python 2.6或更新版本。

现在,你的情况可以用这种方式写出来(编辑:仅当tmintmax不能为零!):

if (tmin or -INF) <= tval <= (tmax or +INF) :
    return tval

修改: 错过0.0是tmintmax的合法值,我犯了一个粗略的错误。感谢Roger Pate的注意。伙计们,请收回你的赞成票,这个答案不起作用......

答案 1 :(得分:4)

为了便于阅读,我可能首先定义一个检查函数:

def inrange(x, min, max):
    return (min is None or min <= x) and (max is None or max >= x)

tval = float(-b - discriminant) / float (2*a)
if inrange(tval, tmin, tmax):
    return tval 

tval = float(-b + discriminant) / float (2*a)
if inrange(tval, tmin, tmax):
    return tval 

# Neither solution was within the acceptable range.
return None

我必须有一个模块在某个地方定义这样的inrange方法。但我没有找到它(也没有找到它)。 :)

答案 2 :(得分:3)

使用来自atzz答案的INF(在使用0.0时不会失败的方式):

def coalesce(*values):
  for v in values:
    if v is not None:
      return v

if coalesce(tmin, -INF) <= tval <= coalesce(tmax, INF):
  return tval

然而,你所拥有的对我来说已经足够清楚了:

if ((tmin is None or tmin <= tval) and
    (tmax is None or tval <= tmax)):
   return tval

答案 3 :(得分:2)

使用来自atzz答案的INF

if tmin is None: tmin = -INF
if tmax is None: tmax = +INF

tval = float(-b - discriminant) / float (2*a)
if tmin <= tval <= tmax:
    return tval 

tval = float(-b + discriminant) / float (2*a)
if tmin <= tval <= tmax:
    return tval

# Neither solution was within the acceptable range.
return None