3

可能重复:
python - 浮点数的小数位问题
Python 浮点相等怪异

在下面的代码中,我有percentage一个浮点变量。我已经将它设置为 ifnumber到达10,000percentage应该会上升.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

4 回答 4

16

来自Python 文档

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

您可能应该使用decimal模块

于 2012-08-08T21:01:50.617 回答
6

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

您可以通过几种方式解决您的问题。

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

例子:

from decimal import Decimal
percentage = Decimal('0.1')
step = Decimal('0.01')
percentage += step
于 2012-08-08T20:59:57.453 回答
1

浮点数没有无限的精度,所以你会得到这样的奇怪行为。

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

例如:

percent_as_integer += 1

代替

percent_as_float += 0.01

当您想显示百分比时,只需执行以下操作:

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

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

于 2012-08-08T21:00:46.003 回答
1

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

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

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

于 2012-08-08T21:10:21.413 回答