Emily Wasson
Emily Wasson

Reputation: 3

While loops advancing too early and inconsistently

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

Answers (2)

Alex Hodges
Alex Hodges

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

Sıddık A&#231;ıl
Sıddık A&#231;ıl

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

Related Questions