【问题标题】:Float to Int type conversion in Python for large integers/numbers大整数/数字在 Python 中的 Float 到 Int 类型转换
【发布时间】:2023-01-26 23:41:11
【问题描述】:

在我正在处理的以下代码中需要一些帮助。为什么“a”中的原始数字在经过类型转换时与“c”中的数字不同。当“a”和“c”通过 float -> int 类型转换时,我们有什么方法可以使它相同?

a = '46700000000987654321'
b = float(a)  => 4.670000000098765e+19
c = int(b)    => 46700000000987652096
a == c        => False

【问题讨论】:

    标签: python-3.x floating-point type-conversion precision largenumber


    【解决方案1】:

    请阅读这份文件关于浮点运算:问题和局限性:

    https://docs.python.org/3/tutorial/floatingpoint.html

    对于你的例子:

    from decimal import Decimal
    a='46700000000987654321'
    
    b=Decimal(a)
    
    print(b)    #46700000000987654321
    
    c=int(b)
    
    print(c)    #46700000000987654321
    

    【讨论】:

      【解决方案2】:

      my answer to another question (reasonably) duped 的修改版本到这个:

      发生这种情况是因为 46700000000987654321 大于 C double 的整数表示限制(这是 Python float 的实现方式)。

      通常,Cdoubles是IEEE 75464位二进制浮点值,其中means they have 53 bits of integer precision(最后一个连续的整数值float可以表示是2 ** 53 - 1后跟2 ** 53;它不能表示@987654333 @).问题是,46700000000987654321 需要 66 位整数精度来存储((46700000000987654321).bit_length() 将提供此信息)。当一个值对于尾数(整数部分)单独来说太大时,浮点值的指数部分用于按 2 的幂缩放较小的整数值大致在原始值的范围内,但这意味着可表示的整数开始跳过,首先是 2(因为你需要 >53 位),然后是 4(对于 >54 位),然后是 8(>55 位),然后16(> 56 位)等,对于超过 53 位的每个额外位,在可表示值之间跳过两倍。

      在您的情况下,转换为float46700000000987654321 的整数值为46700000000987652096(如您所述),低位数字的精度丢失。

      如果您需要任意精确的 base-10 浮点数学,请替换您对 float with decimal.Decimal 的使用(方便的是,您的初始值已经是一个字符串,因此您不会在输入 float 之间失去精度的风险和存储的实际值);默认精度将处理这些值,如果您需要更大的值,您可以增加它。如果你这样做(并将 a 转换为 int 进行比较,因为 str 永远不等于任何数字类型),你会得到你期望的行为:

      from decimal import Decimal as Dec, getcontext
      
      a = "46700000000987654321"
      b = Dec(a); print(b)  # => 46700000000987654321
      c = int(b); print(c)  # => 46700000000987654321
      print(int(a) == c)    # => True
      

      Try it online!

      如果您在交互式解释器中回显 Decimals 而不是使用 print,您会看到 Decimal('46700000000987654321'),它是 Decimals 的 repr 形式,但它在数字上是 46700000000987654321,如果转换为 int,或通过任何不使用 repr 的方法进行字符串化,例如print,它显示为46700000000987654321

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-09-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-01-13
        • 2023-03-12
        相关资源
        最近更新 更多