代码之家  ›  专栏  ›  技术社区  ›  Adam Luchjenbroers

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

  •  3
  • Adam Luchjenbroers  · 技术社区  · 15 年前

    有关守则是:

        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为无的情况(应解释为分别没有最小值或最大值)。

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

        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 回复  |  直到 15 年前
        1
  •  2
  •   John La Rooy    15 年前

    使用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
    
        2
  •  4
  •   Johannes Charra    15 年前

    为了可读性,也许我应该先定义一个checker函数:

    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

        3
  •  4
  •   atzz    15 年前

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

    INF = float(1e3000)
    

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

    第一种选择可被视为实用的便携式选择;只需使用一些非常大的值,它保证超出平台浮点类型所能表示的范围。第二个选项是“真正”可移植的,但需要Python2.6或更高版本。

    编辑:仅当 tmin tmax 不能是零! ):

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

    编辑 : 我犯了一个粗略的错误,遗漏了0.0是的合法值 tmax

        4
  •  3
  •   Roger Pate Roger Pate    15 年前

    使用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