代码之家  ›  专栏  ›  技术社区  ›  RandomPhobia

Python奇怪的添加错误〔重复〕

  •  3
  • RandomPhobia  · 技术社区  · 12 年前

    可能重复:
    python - decimal place issues with floats
    Python float equality weirdness

    在下面的代码中,我有一个变量 percentage 其为浮子。我已经设置好了 number 达到 10,000 , 百分率 被认为是通过 .01

    # Tries to find a number that when squared and 5%'ed is still a square.
    
    import math
    
    print("Script has started:\n")
    
    percentage = .1
    number = 1
    while number != -1:
        number = number + 1
        num_powered = number ** 2
        num_5per = num_powered * percentage
        num_5per_sqrt = math.sqrt(num_5per)
        num_list = list(str(num_5per_sqrt))
        dot_location = num_list.index(".")
        not_zero = 0
        for x in num_list[dot_location + 1:]:
            if x != "0":
                not_zero = 1
                break
        if not_zero == 0:
            print("*********************************")
            print("Map :",number)
            print("Safe-Area :",num_5per_sqrt)
            print("Percentage :",percentage)
            print("*********************************")
            input()
    
        if number > 10000:
                  number = 0
                  percentage = percentage + .01
                  print(percentage)
    

    输出:

    0.11
    0.12
    0.13
    0.14
    0.15000000000000002  # Here is where it goes crazy
    0.16000000000000003
    
    4 回复  |  直到 7 年前
        1
  •  16
  •   supervacuo    12 年前

    从…起 the Python docs

    请注意,这正是二进制浮点的本质: 不是Python中的错误,也不是代码中的错误 (重点是我的)。在所有支持硬件浮点运算的语言中,您都会看到相同的情况(尽管某些语言可能在默认情况下或所有输出模式下都不会显示差异)

    你可能应该使用 the decimal module

        2
  •  8
  •   Mark Byers    12 年前

    您使用的是浮点数,并且经历了 representation error 特别地,0.01没有作为二进制浮点数的精确表示。相反,将存储非常接近但不完全等于0.01的数字。这不是一个bug。这就是浮点运算的工作方式。

    你可以用几种方法来解决你的问题。

    • 接受结果不完全准确或
    • 将所有内容乘以100并使用整数或
    • 使用 Decimal 类型

    示例:

    from decimal import Decimal
    percentage = Decimal('0.1')
    step = Decimal('0.01')
    percentage += step
    
        3
  •  1
  •   Gordon Bailey    12 年前

    漂浮物并没有无限的精确性,所以你会有这样奇怪的行为。

    一个更好的解决方案是将百分比存储为整数,表示百分比的十分之一并递增一。

    例如:

    percent_as_integer += 1
    

    而不是

    percent_as_float += 0.01
    

    如果要显示百分比,只需执行以下操作:

    print "%d.%02d" % divmod(percent_as_integer, 100)
    

    编辑:事实上,按照另一个答案的建议,使用十进制模块可能是一个更好、更像蟒蛇的解决方案。

        4
  •  1
  •   Mohammad Alhashash    6 年前

    正如在其他答案中所描述的,这是当前所有微处理器中本机浮点数的限制。

    如果您需要精确表示十进制数字(例如,用于会计和商业应用程序),则应使用 decimal 类型,而不是浮点。您也可以使用 cdecimal 模块,它是十进制类型的高性能实现。

    更新: 从Python v3.3开始,内置的十进制模块在C中实现。