455,548 Members | 1,513 Online Need help? Post your question and get tips & solutions from a community of 455,548 IT Pros & Developers. It's quick & easy.

# Problems using modulo

 P: n/a Test program: ================================================== ============= t = 5.8 interval = 2.0 while t < 6.1: print "%s mod %s = %s " % (t, interval, t % interval ) t += 0.1 ================================================== ============== Results: 5.8 mod 2.0 = 1.8 5.9 mod 2.0 = 1.9 6.0 mod 2.0 = 2.0 !!!!!! 6.1 mod 2.0 = 0.1 ================================================== =============== if we change t to initialise at 5.9 and run the program again, ================================================== =============== t = 5.9 interval = 2.0 while t < 6.1: print "%s mod %s = %s " % (t, interval, t % interval ) t += 0.1 ================================================== =============== Results: C:\Python22>python modprob.py 5.9 mod 2.0 = 1.9 6.0 mod 2.0 = 0.0 # that's better ================================================== == I have tried this on Windows and Unix for Python versions between 1.52 and 2.3. I don't know much about how Python does its floating point, but it seems like a bug to me ? What is the best workaround so that I can get my code working as desired ? (ie I just want to tell whether my time "t" is an exact multiple of the time interval, 2.0 seconds in this case). Would be grateful for any suggestions cheers - Griff Jul 18 '05 #1
5 Replies

 P: n/a Griff wrote: Would be grateful for any suggestions Try this: t = 5.9 interval = 2.0 while t < 6.1: print (t, interval, t % interval) t+=0.1 Then you see what actually gets divided.... I'm not sure what you actually try to do, but AFAIK modulo is mathematically only properly defined on integers - so you should stick to them. If you need fractions, it might be sufficient to use fixed-point arithmetics by simply multiplying by 10 ar 100. -- Regards, Diez B. Roggisch Jul 18 '05 #2

 P: n/a Use repr to see the true values you are dealing with when printing floating point numbers (as distinct from the pretty "%s" formatter): t = 5.8 interval = 2.0 while t < 6.1: print "%r mod %r = %r " % (t, interval, t % interval ) t += 0.1 Then you'll see what's going on: P:\temp>modulofloat.py 5.7999999999999998 mod 2.0 = 1.7999999999999998 5.8999999999999995 mod 2.0 = 1.8999999999999995 5.9999999999999991 mod 2.0 = 1.9999999999999991 6.0999999999999988 mod 2.0 = 0.099999999999998757 So, 5.99999... modulo 2.0 gives you 1.999999... as you would expect. HTH, Mike Griff wrote: Test program:================================================= ==============t = 5.8interval = 2.0while t < 6.1: print "%s mod %s = %s " % (t, interval, t % interval ) t += 0.1 _______________________________________ Mike C. Fletcher Designer, VR Plumber, Coder http://members.rogers.com/mcfletch/ Jul 18 '05 #3

 P: n/a gr*****@aol.com (Griff) writes: Results: 5.9 mod 2.0 = 1.9 6.0 mod 2.0 = 2.0 !!!!!! 6.1 mod 2.0 = 0.1 I don't know much about how Python does its floating point, but it seems like a bug to me ? This is a common "feature" of floating-point arithmetic. 0.1 does not have an exact machine representation in binary, so the numbers displayed are not exact (e.g. 6.0 is actually 5.9999999... with a difference O(10^-15)). There is an appendix in the Python tutorial which discusses this, with more examples. What is the best workaround so that I can get my code working as desired ? (ie I just want to tell whether my time "t" is an exact multiple of the time interval, 2.0 seconds in this case). For exact arithmetic, work with integers (e.g. in this case multiply everything 10) or compute the difference from zero in the modulus, d, s = t % interval d = min (s, interval-s) and compare it with a small tolerance, e.g. 1e-10 or something appropriate to your problem. HTH. -- Brian Gough Network Theory Ltd, Publishing Python Manuals --- http://www.network-theory.co.uk/ Jul 18 '05 #4

 P: n/a On Mon, 19 Apr 2004 17:51:53 +0200, Diez B. Roggisch wrote: AFAIK modulo is mathematically only properly defined on integers - so you should stick to them. Modulo is fine for any number (even irrational ones). For example, acos(sqrt(3)/2) is congruent to pi/6 mod 2*pi. Technically, two numbers are congruent mod n when the rest of the division by n is the same, it doesn't matter whether n is an integer or not. Jul 18 '05 #5

 P: n/a Gonzalo Sainz-Trápaga (GomoX) wrote: On Mon, 19 Apr 2004 17:51:53 +0200, Diez B. Roggisch wrote: AFAIK modulo is mathematically only properly defined on integers - so you should stick to them. Modulo is fine for any number (even irrational ones). For example, acos(sqrt(3)/2) is congruent to pi/6 mod 2*pi. Technically, two numbers are congruent mod n when the rest of the division by n is the same, it doesn't matter whether n is an integer or not. Hum - usually, division in fields like Q or R doesn't yield a rest, doesn't it? Thats what I meant. Of course if you define division as a / b := subtract b from a until a is < b and count the iterations, you can have modulo. So I stand corrected that the modulo op in python then makes sense (even if numerical problems arise, but thats a different topic). -- Regards, Diez B. Roggisch Jul 18 '05 #6

### This discussion thread is closed

Replies have been disabled for this discussion. 