如何获得浮点序列中的下一个值?

Mar*_*som 11 python math floating-point

Python是否提供了一个函数来获取通过递增现有浮点值的最低有效位而得到的浮点值?

我正在寻找类似于std::nextafterC++ 11中添加的功能的东西.

Mar*_*son 18

回答问题的第一部分:不,Python不直接提供此功能.但是编写一个Python函数很容易做到这一点,假设是IEEE 754浮点数.

IEEE 754二进制浮点格式设计得非常巧妙,因此从一个浮点数移动到"下一个"浮点数就像递增位表示一样简单.这适用于范围内的任何数字[0, infinity),跨越指数边界和次正规数.要生成nextUp涵盖完整浮点范围的版本,您还需要处理负数,无穷大,nans和一个涉及负零的特殊情况.下面是nextUpPython 中IEEE 754 函数的标准兼容版本.它涵盖了所有角落案例.

import math
import struct

def next_up(x):
    # NaNs and positive infinity map to themselves.
    if math.isnan(x) or (math.isinf(x) and x > 0):
        return x

    # 0.0 and -0.0 both map to the smallest +ve float.
    if x == 0.0:
        x = 0.0

    n = struct.unpack('<q', struct.pack('<d', x))[0]
    if n >= 0:
        n += 1
    else:
        n -= 1
    return struct.unpack('<d', struct.pack('<q', n))[0]
Run Code Online (Sandbox Code Playgroud)

的实施nextDownnextAfter再这个样子.(注意,这nextAfter不是IEEE 754规定的功能,因此对于IEEE特殊值应该发生什么有一些猜测.这里我遵循Python decimal.Decimal类所基于的IBM Decimal Arithmetic标准.)

def next_down(x):
    return -next_up(-x)

def next_after(x, y):
    # If either argument is a NaN, return that argument.
    # This matches the implementation in decimal.Decimal
    if math.isnan(x):
        return x
    if math.isnan(y):
        return y

    if y == x:
        return y
    elif y > x:
        return next_up(x)
    else:
        return next_down(x)
Run Code Online (Sandbox Code Playgroud)