Reputation: 3
In my code, I want to separate an amount of money into denominations. I'm using a while loop to accomplish this. However, my variables are switching to a lower bill/coin too early.
I added some print commands to isolate the problem, and I think it's coming from line 11.
nmoney = 1.2
print 'original: ' + str(1.2)
bills = []
denominations = [100., 20., 10., 5., 1., .25, .10, .05, .01]
n = 0
while 0<nmoney<=1000:
hbill = denominations[n] #error
while nmoney>=hbill: #possible stem of error?
bills.append(hbill)
nmoney-=hbill
print '+' + str(hbill) + ' ' + str(bills) + ' ' + str(nmoney)
n+=1
print 'SWITCH from ' + str(hbill)
print 'DONE'
I expected the list output to look like this:
[1.0, 0.1, 0.1]
However, the list wound up like this:
[1.0. 0.1, 0.5, 0.01, 0.01, 0.01, 0.01]
~Edit: When I used 1.3 for my nmoney var, I got a strange output. All I changed was line 1, but for some reason a very small number was added to the variable. Here is an excerpt from the output text:
SWITCH from 0.1
+0.05 [1.0, 0.25, 0.05] 4.16333634234e-17
SWITCH from 0.5
The rightmost number in the middle line is nmomey.
Upvotes: 0
Views: 61
Reputation: 607
As pointed out by Sıddık Açıl, it's due to the accuracy of floating point arithmetic. The quantity of floating point numbers between 0.1 and 0.2 is infinite. Your computer has to draw the line somewhere.
This fix solves your issue, just remember to divide the bills by 100 again at the end.
nmoney = 1.2
nmoney = nmoney * 100
print('original: ' + str(1.2))
bills = []
denominations = [10000, 2000, 1000, 500, 100, 25, 10, 5, 1]
n = 0
while 0 < nmoney <= 1000:
hbill = denominations[n] # error
while nmoney >= hbill: # possible stem of error?
bills.append(hbill)
nmoney -= hbill
print('+' + str(hbill) + ' ' + str(bills) + ' ' + str(nmoney))
n += 1
print('SWITCH from ' + str(hbill))
print('DONE')
Upvotes: 2
Reputation: 967
Welcome to Stack Overflow. Your problem is that floating-point arithmetics is not "that" precise in computing.
1.2 - 1 is not 0.2. It is 0.19999999999999996.
0.19999999999999996 - 0.1 is 0.09999999999999995 (Which is not 0.1 clearly)
So your loop continues like it does.
Upvotes: 0