初学者python27:更改计算器

时间:2015-08-11 01:26:07

标签: python calculator

我是初学python程序员,我想知道为什么这个脚本在输入0.30的浮点数时不起作用。我尝试了其他输入(即0.50,1.00,0.10等......)并且它们工作正常。可能有更简单的方法来执行此计算器,但我只是想知道为什么这个脚本特别不起作用。该脚本如下:

money = float(raw_input("Input the money: "))
twofive_count = 0
ten_count = 0
five_count = 0
one_count = 0
while money != 0.00:
    if money >= 0.25:
        money -= 0.25
        twofive_count +=1
    elif money < 0.25 and money >= 0.10:
        money -= 0.10
        ten_count += 1
    elif money < 0.10 and money >= 0.05:
        money -= 0.05
        five_count += 1
    elif money < 0.05 and money >= 0.01:
        money -= 0.01
        one_count += 1
print "Quarters:",twofive_count
print "Dimes:",ten_count
print "Nickels:",five_count
print "Pennies:",one_count
total_change = twofive_count + ten_count + five_count + one_count
print "Total number of coins in change:",total_change

4 个答案:

答案 0 :(得分:3)

出现问题的原因是浮动的内部表示如何工作 -

0.30 - 0.25

你得到一个结果 -

0.04999999999999999

当你从中减去0.05时,你会得到一个负数而不是0.00。示例显示 -

>>> s = float('0.30')
>>> s
0.3
>>> s-0.25
0.04999999999999999
>>> s-0.05
0.25
>>> s = s-0.25
>>> s = s - 0.05
>>> s
-1.3877787807814457e-17

我认为既然您正在处理货币,您可以随时将数字四舍五入到小数点后两位,这应该没问题。

示例 -

money = float(raw_input("Input the money: "))
twofive_count = 0
ten_count = 0
five_count = 0
one_count = 0
while money != 0.00:
    if money >= 0.25:
        money = round(money - 0.25, 2)
        twofive_count +=1
    elif money < 0.25 and money >= 0.10:
        money = round(money - 0.10, 2)
        ten_count += 1
    elif money < 0.10 and money >= 0.05:
        money = round(money - 0.05, 2)
        five_count += 1
    elif money < 0.05 and money >= 0.01:
        money -= round(money - 0.01, 2)
        one_count += 1
print "Quarters:",twofive_count
print "Dimes:",ten_count
print "Nickels:",five_count
print "Pennies:",one_count
total_change = twofive_count + ten_count + five_count + one_count
print "Total number of coins in change:",total_change

或者如果您不想舍入,可以使用decimal.Decimal,在这种情况下,您需要更改所有元素(到十进制),示例 -

from decimal import Decimal
money = Decimal(raw_input("Input the money: "))
twofive_count = 0
ten_count = 0
five_count = 0
one_count = 0
while money != 0.00:
    if money >= Decimal('0.25'):
        money -= Decimal('0.25')
        twofive_count +=1
    elif money < Decimal('0.25') and money >= Decimal('0.10'):
        money -= Decimal('0.10')
        ten_count += 1
    elif money < Decimal('0.10') and money >= Decimal('0.05'):
        money -= Decimal('0.05')
        five_count += 1
    elif money < Decimal('0.05') and money >= Decimal('0.01'):
        money -= Decimal('0.01')
        one_count += 1
print "Quarters:",twofive_count
print "Dimes:",ten_count
print "Nickels:",five_count
print "Pennies:",one_count
total_change = twofive_count + ten_count + five_count + one_count
print "Total number of coins in change:",total_change

答案 1 :(得分:3)

忘记浮点,如果你不了解幕后发生的事情,那就是疯狂。

如果您需要精确度,请尽快将值转换为整数:

money = float(raw_input("Input the money: "))

money = int (money * 100 + 0.1)           # Make integral pennies
                                          #   avoiding 0.999999 problems
twofive_count = 0
ten_count = 0
five_count = 0
one_count = 0
while money > 0:
    if money >= 25:                       # Make sure you use pennies
        money -= 25
        twofive_count +=1
    elif money >= 10:
        money -= 10
        ten_count += 1
    elif money >= 5:
        money -= 5
        five_count += 1
    elif money >= 1:
        money -= 1
        one_count += 1

print "Quarters:",twofive_count
print "Dimes:",ten_count
print "Nickels:",five_count
print "Pennies:",one_count
total_change = twofive_count + ten_count + five_count + one_count
print "Total number of coins in change:",total_change

您还会注意到我已经清理了您的硬币检测代码。无需检查范围的两端(例如,小于镍和至少一分钱),因为您正在使用elif,这意味着已经检查了该条件的第一部分。 / p>

当然,如果您仔细考虑一下,通常会有更有效的方法。第一步是将每个步骤分解为自己的 while以隔离每个硬币计数计算,例如:

while money >= 25:
    money -= 25
    twofive_count +=1
while money >= 10:
    money -= 10
    ten_count += 1
while money >= 5:
    money -= 5
    five_count += 1
while money >= 1:
    money -= 1
    one_count += 1

从那里开始,实现这一目标的一小步,一旦你计算出所有非便士价值,就可以更快地完成便士的数量:

while money >= 25:
    money -= 25
    twofive_count +=1
while money >= 10:
    money -= 10
    ten_count += 1
while money >= 5:
    money -= 5
    five_count += 1
one_count = money

也是计算每个硬币数而不重复减法的方法,因为重复减法正好为什么发明了分裂: - )

twofive_count = int (money / 25)
money -= (twofive_count * 25)

ten_count = int (money / 10)
money -= (ten_count * 10)

five_count = int (money / 5)
money -= (five_count * 5)

one_count = money

答案 2 :(得分:1)

正如其他人所说,浮点表示并不准确。要使用更精确的十进制表示,请使用Decimal Python模块[0]中的decimal类的定点表示法。

[0] https://docs.python.org/3/library/decimal.html

答案 3 :(得分:0)

我认为您的问题是while money != 0.00:

比较浮点数充满危险,因为分数的二进制表示并不完美。要正确比较一个浮点数,你需要从另一个中减去一个,然后看看结果是否在一个适合你的应用程序的公差值范围内。

我认为使用十进制类可以解决您的问题并提供一个更合理的解决方案,而不是试图让浮动为您工作。

https://docs.python.org/2/library/decimal.html

从页面:

  • 十进制数字可以准确表示。相反,像1.1和2.2这样的数字在二进制浮点中没有精确的表示。最终用户通常不希望1.1 + 2.2显示为3.3000000000000003,就像二进制浮点一样。

  • 准确性延续到算术中。在十进制浮点数中,0.1 + 0.1 + 0.1 - 0.3正好等于零。在二进制浮点数中,结果为5.5511151231257827e-017。虽然接近于零,但差异阻止了可靠的相等性测试,并且差异可能会累积。因此,在具有严格相等不变量的会计应用程序中,decimal是首选。