确定数字是否在浮点数或双精度范围内

Determine if a number is in range for float or double

提问人:Lampe2020 提问时间:8/13/2023 最后编辑:Lampe2020 更新时间:8/14/2023 访问量:39

问:

有没有办法确定一个数字是可存储为单浮点数还是双浮点数?
我正在实现自己的数据库格式,在我的帮助程序函数中,我目前有以下代码:
num2bin(n)

import struct, warnings

def num2bin(n:int|float) -> bytes:
    match type(n).__name__:
        case 'int':
            ... # Excluded because unimportant to this question 
        case 'float':
            try:
                return struct.pack('>f', n)
            except struct.error:
                try:
                    return struct.pack('>d', n)
                except struct.error:
                    warnings.warn(f"num2bin(n): Failed to store {n} as float or double")
                    return b''
        case other:
            warnings.warn(f"num2bin(n): 'n' is of type '{other}' (must be 'int' or 'float')")
            return b''

有没有更好、更优雅的方法来确定是否可以将数字存储为浮点数 () 或双精度 ()?
我认为一定有更好的方法可以做到这一点,而不仅仅是尝试并发现错误?
fd

python-3.x 浮点 精度

评论

1赞 Mark Ransom 8/14/2023
Try and catch 被认为是非常 Python 的。它甚至还有一个名字:EAFP
0赞 Lampe2020 8/14/2023
@MarkRansom 我的问题不在于它的“pythonicness”,只是它对我来说看起来非常不优雅,尤其是嵌套的 s。try…catch
0赞 chux - Reinstate Monica 8/16/2023
@Lampe2020,也许将数字转换为.然后转换为 .如果 ,则可保存,因为没有进动/范围问题。double xxfloat yx == yfloat

答:

0赞 Lampe2020 8/13/2023 #1

我不完全确定它是否将包括所有浮点数,但我现在进行以下检查:

import struct, warnings

def num2bin(n:int|float) -> bytes:
    match type(n).__name__:
        case 'int':
            ... # Excluded because unimportant to this answer 
        case 'float':
            fltmax:tuple[float] = struct.unpack(
                '>ff',
                b'\x019Dp\x7f\x7f\xff\xff'
                # Min and max single-precision float value (2.2250738585072014e-308, 1.7976931348623157e+308)
            )
            dblmax:tuple[float] = struct.unpack(
                '>dd',
                b'\x00\x10\x00\x00\x00\x00\x00\x00\x7f\xef\xff\xff\xff\xff\xff\xff'
                # Min and max double-precision float value (3.402823507664669e-38, 3.4028234663852886e+38)
            )
            if (n>fltmax[0])and(fltmax[1]>n):
                return struct.pack('>f', n)
            elif (n>dblmax[0])and(dblmax[1]>n):
                return struct.pack('>d', n)
            else:
                warnings.warn(f"num2bin(n): Failed to store {n} as float or double")
                return b''
        case other:
            warnings.warn(f"num2bin(n): 'n' is of type '{other}' (must be 'int' or 'float')")
            return b''

因为浮点数既可以很大且不精确,也可以很小且精确,因此我不确定这是否包括所有浮点数,或者对于一些实际上可存储为浮点数或双精度数的浮点数会失败......

评论

1赞 Mark Ransom 8/14/2023
这可能提供与原始结果相同的结果。两者都没有考虑数字的精度要求。