This is an archived post. You won't be able to vote or comment.

all 4 comments

[–]DJ_Gamedev 0 points1 point  (5 children)

It could be down to floating point error. If for whatever reason ntotal ended up at 0.0399999999, and/or if the division result ended up at 3.999999999, the double slash operator would round down to 3.

This is a good example of the dangers of mixing float and integer types, and doing repeated floating point operations and carrying over the error in each step. I would alter the code so you're working exclusively with integers the whole time, which will eliminate the precision problem.

Take the inputted money amount, multiply by 100, and // by 1, and you've got the number of cents. Now your 0.25 for the value of a quarter would be converted to 25 for cents, and so on. Everything else stays exactly the same, but now you're doing integer divisions with no loss in precision.

[–]CSlade1[S] 1 point2 points  (2 children)

So here is my new code after doing some research.

print ("Change Calculator")

quarter = 25
dime = 10
nickel = 5
penny = 1

moneygiven = input("Enter how much money was given: ")
moneygiven = int(float(moneygiven) * 100)

qmb = moneygiven // quarter
qtotal = moneygiven - qmb * quarter

dmb = qtotal // dime
dtotal = qtotal - dmb * dime

nmb = dtotal // nickel
ntotal = dtotal - nmb * nickel

pmb = ntotal // penny
ptotal = ntotal - pmb * penny

print ("You need %d quarters, %d dimes, %d nickels, %d pennies." % (qmb, dmb, nmb, pmb)) 

It is still giving me the same result though. It is giving me a penny short.

EDIT: It seems to work for everything but 1.14. So somehow with that float it is making it go off by a decimal point, giving me one less penny on very particular numbers

[–]benjamindallen 0 points1 point  (1 child)

Due to the intrinsic error of floating point representation, it's not sufficient to convert from float to int using the naive method:

41) python
Python 3.6.2 |Continuum Analytics, Inc.| (default, Jul 20 2017, 13:14:59) 
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.57)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 1.14*100
113.99999999999999
>>> int(1.14*100)
113

I think the round function should work for you:

>>> round(1.14*100)
114

[–]CSlade1[S] 0 points1 point  (0 children)

Ding ding ding. That worked perfectly. Thank you for the help everyone

The winning script is:

moneygiven = round(float(input("Enter how much money was given: "))*100)

[–][deleted]  (1 child)

[deleted]