On 01/01/2012 09:48 PM, brian arb wrote:
Hello,
Can some please explain this to me?
My while loop should continue while "owed" is greater than or equal to "d"
first time the function is called
the loop exits as expected
False: 0.000000>= 0.010000
the next time it does not
False: 0.010000>= 0.010000
Below is the snippet of code, and the out put.
Thanks!
def make_change(arg):
denom = [100.0, 50.0, 20.0, 10.0, 5.0, 1.0, 0.25, 0.10, 0.05, 0.01]
owed = float(arg)
payed = []
for d in denom:
while owed>= d:
owed -= d
b = owed>= d
print '%s: %f>= %f' % (b, owed, d)
payed.append(d)
print sum(payed), payed
return sum(payed)
if __name__ == '__main__':
values = [21.48, 487.69] #, 974.41, 920.87, 377.93, 885.12, 263.47,
630.91, 433.23, 800.58]
for i in values:
make_change(i))
False: 1.480000>= 20.000000
False: 0.480000>= 1.000000
False: 0.230000>= 0.250000
True: 0.130000>= 0.100000
False: 0.030000>= 0.100000
True: 0.020000>= 0.010000
True: 0.010000>= 0.010000
False: 0.000000>= 0.010000
21.48 [20.0, 1.0, 0.25, 0.1, 0.1, 0.01, 0.01, 0.01]
True: 387.690000>= 100.000000
True: 287.690000>= 100.000000
True: 187.690000>= 100.000000
False: 87.690000>= 100.000000
False: 37.690000>= 50.000000
False: 17.690000>= 20.000000
False: 7.690000>= 10.000000
False: 2.690000>= 5.000000
True: 1.690000>= 1.000000
False: 0.690000>= 1.000000
True: 0.440000>= 0.250000
False: 0.190000>= 0.250000
False: 0.090000>= 0.100000
False: 0.040000>= 0.050000
True: 0.030000>= 0.010000
True: 0.020000>= 0.010000
False: 0.010000>= 0.010000
487.68 [100.0, 100.0, 100.0, 100.0, 50.0, 20.0, 10.0, 5.0, 1.0, 1.0, 0.25,
0.25, 0.1, 0.05, 0.01, 0.01, 0.01]
You're using float values and pretending that they can accurately
represent dollars and cents. 0.19 (for example) cannot be exactly
represented in a float, and when you start adding up multiple of these,
sooner or later the error will become visible. This is a problem with
binary floating point, and I first encountered it in 1967, when the
textbook for Fortran made an important point about never comparing
floating point values for equals, as small invisible errors are bound to
bite you.
Easiest answer is to use integers. Scale everything up by a factor of
100, and you won't need floats at all. Just convert when printing (and
even then you may get into trouble).
Another answer is to use Decimal class, which CAN represent decimal
values exactly.
BTW, if this is supposed to represent US legal tender, you left out the
fifty-cent piece as well as the two dollar bill.
--
DaveA
_______________________________________________
Tutor maillist - Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor