我正在寻找一种在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
我一直认为必须有一种更好(更清晰,更易读)的方式来编写它。有什么想法吗?
答案 0 :(得分:4)
首先,一些设置:我们需要一个浮点无穷大常数。
INF = float(1e3000)
或
INF = float('inf') # Python 2.6+
第一种选择可以被认为是实用的便携式;只需使用一些非常大的值,保证超出您平台的浮点类型所代表的范围。第二个选项是“真正的”可移植的,但需要Python 2.6或更新版本。
现在,你的情况可以用这种方式写出来(编辑:仅当tmin
和tmax
不能为零!):
if (tmin or -INF) <= tval <= (tmax or +INF) :
return tval
修改强>:
错过0.0是tmin
或tmax
的合法值,我犯了一个粗略的错误。感谢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