Unexpected integer/float math behavior in Python

I wasted some time today tracking down a bug in one of my programs.  It turned out to be “unexpected behavior” rather than a bug.  I was aware of this aspect of the language, but I made an assumption and got bit.  Read on for a valuable lesson.

Python handles integer math differently than floating point math.  If you type a number without a decimal point, Python treats it as an integer.  All math performed only with integers results in integers. For example, 1/2 evaluates to 0 while 1./2. evaluates to 0.5.  If you mix integers and floats, Python will  produce a floating point result (1/2.=0.5), but you must be very careful.  For example, you might expect the expression 4/3*3.14159 to yield a floating point result.  It does yield a floating point number, but not the one you were expecting!  4/3*3.14159 yields 3.14159.  What happened?  Python works from left to right.  4/3 evaluates to the integer “1”.  1*3.14159 evaluates to  3.14159.  For comparison, 4./3.*3.14159 evaluates to 4.1887866.  Here’s the problem with this particular aspect of Python: according to the rules of math, 4/3*3.14159 is exactly the same expression as 4*3.14159/3, but in Python they yield different results if you forget the decimal points!  4*3.14159 evaluates to a floating point, so (4*3.14159)/3 yields the “correct” floating point value.

Lesson Learned: be explicit about specifying all floats if you are doing floating-point math!  Sometimes I get lazy and leave a trailing decimal point off of a number when doing a floating point calculation, knowing that the results are “upcast” into floats. Not any more!

Note: this unexpected behavior goes away in Python 3.0

Leave a Reply