2015-09-17 5 views
1

Я работаю над скриптом калькулятора изменений для моего курса CS. Код ниже:Оператор '//' в Python не возвращает правильное решение

# Set up our money variables 
centValueOfTenDollarBill = 1000 
centValueOfFiveDollarBill = 500 
centValueOfToonie = 200 
centValueOfLoonie = 100 
centValueOfQuarter = 25 
centValueOfDime = 10 
centValueOfNickel = 5 

# Set up our variables 
purchaseTotal = input("Enter purchase total: ") # Purchase costs $12.50 
moneyPaid = input("Enter money paid: ")  # Customer gives cashier $20.00 

# Figure out the change 
change = moneyPaid - purchaseTotal 

# Echo input data to user 
print("""The total of the purchase is $%0.2f. 
The customer paid $%0.2f. 
The cashier gives $%0.2f back to the customer in the following fashion: """ %(purchaseTotal, moneyPaid, change)) 

#Convert dollars into cents to facilitate the computation 
purchaseTotalInCents = purchaseTotal * 100 
moneyPaidInCents = moneyPaid * 100 
changeInCents = change * 100 

# Determine # of $10 to be given back as part of the change 
numberOfTenDollarBills = changeInCents // centValueOfTenDollarBill 
changeInCents = changeInCents - (centValueOfTenDollarBill * numberOfTenDollarBills) 

# Determine # of $5 to be given back as part of the change 
numberOfFiveDollarBills = changeInCents // centValueOfFiveDollarBill 
changeInCents -= (centValueOfFiveDollarBill * numberOfFiveDollarBills) 

# Determine # of $2 (toonies) to be given back as part of the change 
numberOfToonieCoins = changeInCents // centValueOfToonie 
changeInCents -= (centValueOfToonie * numberOfToonieCoins) 

# Determine # of $1 (loonies) to be given back as part of the change 
numberOfLoonieCoins = changeInCents // centValueOfLoonie 
changeInCents -= (centValueOfLoonie * numberOfLoonieCoins) 

# Determine # of $0.25 (quarters) to be given back as part of the change 
numberOfQuarterCoins = changeInCents // centValueOfQuarter 
changeInCents -= (centValueOfQuarter * numberOfQuarterCoins) 

# Determine # of $0.10 (dimes) to be given back as part of the change 
numberOfDimeCoins = changeInCents // centValueOfDime #<--- PROBLEM HERE IF DIMES ARE TWO 
print (numberOfDimeCoins) 
changeInCents -= (centValueOfDime * numberOfDimeCoins) 

# At this point, changeInCents can either be 
# 5 -> 1 x $0.05 (nickels) or 
# 0 -> 0 x $0.05 (nickels) 
numberOfNickelCoins = changeInCents // centValueOfNickel 

# Output the result: change cashier needs to give back to customer 
print("\t%i x $10.00" %numberOfTenDollarBills) 
print("\t%i x $ 5.00" %numberOfFiveDollarBills) 
print("\t%i x $ 2.00" %numberOfToonieCoins) 
print("\t%i x $ 1.00" %numberOfLoonieCoins) 
print("\t%i x $ 0.25" %numberOfQuarterCoins) 
print("\t%i x $ 0.10" %numberOfDimeCoins) 
print("\t%i x $ 0.05" %numberOfNickelCoins) 

# Indicates the end of execution 
print("----\n") 

Все, что не так (по крайней мере, от того, что я могу видеть), что если программа должна вернуть десятицентовики, он возвращает одну монетки и один никель, который короткие изменяют клиент пять центов. Если он должен отдать одну копейку, тогда нет никаких проблем.

Пример: Скажите, что клиент заплатил 20 долларов за пункт 13,30 доллара США. Изменение составляет $ 6,70.

numberOfDimeCoins = changeInCents // centValueOfDime 

Эта линия выше должна быть такой же, как 2.0 = 20.0//10.0, но вместо этого он возвращался 1.0.

Если вы заплатили 20 долларов за все, где требуется одна копейка, все будет правильно, например, 13,13 долларов США, 13,90 долларов США или 13,75 доллара.

Вот несколько примеров выходов ниже:

Erics-MacBook-Pro:Desktop eric$ python change.py 
Enter purchase total: 13.75 
Enter money paid: 20 
The total of the purchase is $13.75. 
The customer paid $20.00. 
The cashier gives $6.25 back to the customer in the following fashion: 
    0 x $10.00 
    1 x $ 5.00 
    0 x $ 2.00 
    1 x $ 1.00 
    1 x $ 0.25 
    0 x $ 0.10 
    0 x $ 0.05 
---- 

Erics-MacBook-Pro:Desktop eric$ python change.py 
Enter purchase total: 12.8 
Enter money paid: 20 
The total of the purchase is $12.80. 
The customer paid $20.00. 
The cashier gives $7.20 back to the customer in the following fashion: 
    0 x $10.00 
    1 x $ 5.00 
    1 x $ 2.00 
    0 x $ 1.00 
    0 x $ 0.25 
    1 x $ 0.10 
    1 x $ 0.05 
---- 

Есть ли что-то, что я пропускаю или сделал не так?

Использование Python 2.7.

+0

Это тоже слишком Java, чтобы быть в разделе python. –

+1

'//' выполняет деление пола в Python2.7 и равно '/'. Скорее всего, ваше значение чуть меньше 20, и вы рассматриваете его как целое число из-за того, как хранятся поплавки. –

+1

Вы должны проверить свои предположения, когда что-то пойдет не так. Первый шаг, конечно, заключается в том, чтобы понять, что такое ваше предположение. В этом случае это означает, что 'changeInCents' - 20 перед линией, которую вы идентифицировали как проблемную. –

ответ

3

Если вы проверяете переменные, вы будете видеть проблему

>>> changeInCents 
19.999999999999886 
>>> centValueOfDime 
10 

Это происходит из-за ограниченной точности с плавающей запятой.

Вы должны преобразовать значения inital в центы. например.

numberspurchaseTotalInCents = int(purchaseTotal * 100) 
moneyPaidInCents = int(moneyPaid * 100) 
changeInCents = moneyPaidInCents - numberspurchaseTotalInCents 

Также проверьте встроенную функцию divmod()

+0

Это действительно проблема, спасибо. То, что я сделал, чтобы исправить это, было использовать round() до ближайшего нуля. Я ценю это! – Eric

2

Это происходит из-за плавающей точкой точности задачи. Попробуйте это:

purchaseTotal = 13.3 
moneyPaid = 20 

change = moneyPaid - purchaseTotal 
print(repr(change)) # 6.699999999999999 

Вы, вероятно, ожидать change быть 0.7, но на самом деле это число очень близко к 0.7, но не точно. В конце концов, changeInCents получает номер, который вы ожидаете от 20.0, но на самом деле немного меньше.

+0

Чтобы решить эту проблему, выполните все вычисления как центы, а затем конвертируйте обратно в доллар/цента. –

+0

Все вычисления _are_ выполняются в центах, @ TonySuffolk66, но они также выполняются с плавающей точкой. –

+0

@JoshCaswell хорошая точка - ugh –

0

Я пытался отладить ваш код, но другие помощники уже поняли это. У вас возникла проблема с тем, как номера хранятся в соответствии со стандартом IEEE 754 (вы можете узнать больше об этом here).

Моя рекомендация для вас работать с десятичной (читай here)

Это довольно прямо вперед,

#import and set precision 
from decimal import * 
getcontext().prec = **x** #you decide it 
a = Decimal(10) 
b = Decimal(0.9) 
print a-b 

Прочитайте документацию, это позволяет установить много актуальных вопросов, как к круглым числам.

+2

Десятичное количество излишеств здесь, я думаю - особенно для начинающего студента, но хорошее решение общей проблемы. –

+0

Я согласен, он, кажется, просто двигается из Джаваленда. Но я думаю, это будет стоить ему меньше времени и усилий, чтобы понять этот класс, чем фактически пройти через все числа чисел с плавающей запятой. –

Смежные вопросы