|
I 've the following code: If I run with Python 2.7.1 + (on my linux box) I have the correct result (1/5 in each cell): But if I run through the web interpret, I've as result:
|
|
This is due to the floating point representation. Because digital floating points are binary, it's quite hard to represent certain floating point numbers with the precision we would like them to be represented. It may be that your interpreter is truncating the display so that it looks nicer to the eye. Internally it's always going to hold this very small "error", because it's intrinsic to the representation used in the computer. More info in the python page about floating points. Excellent answer marga, thank you! For questions like this, we always have a window of acceptance. For this particular question, anything between 0.19999 and 0.20001 (I think) would have been accepted as correct. |
|
This is actually a really great teaching moment as floating point unreliability extends beyond just python. For example, the number .1 seems like an awful easy number to represent, right? It's just one tenth. Unfortunately, the computer doesn't work in base 10, but base 2, and in base 2, .1 is an irrational number (a number that repeats on and on for infinity, like 1/3 is .33333333333). This actually ties back swimmingly to our discussion of the posterior distribution. Every time we work with floating point, we slightly reduce our confidence. For example, if we write the code
then foo is actually just a hair off from 1.0. Python's pretty smart and can figure out that rounding error in most cases, but if it didn't automatically correct for us and we kept running the last 2 lines over and over again, we'd slowly be less and less able to say we were confidently at 1.0, but could only say we were close to it. Now think about that in the context of the robot moving from the imprecise movement lesson. Every time the robot moves, it's fairly confident it knows where it moved, but it could be a little to the left or a little to the right. The more it moves, the less confident it's actually where it expects. If you want to delve deeper into the topic, there's an MSDN article talking about the imprecision of floating point Here. I know this is a little deeper than the question you asked, but it's really interesting, especially the way it ties back so perfectly with the class, so I thought I'd share that neat little tidbit. |
|
Thank you marga by your explanation and link. I admit that I 've many years of experience in languages like C, C + +, Java and PL / SQL and had never seen an error in floating-point values that have an exact division (like this: 1.0/5 = 0.2) in such languages. I hope that the inf.system in my bank do not have been programmed in Python :) (Is just a joke). But I also admit that I'm a python newbie :) Anyway, in your related link explain why I've in Python 2.7.1 a different result: "In versions prior to Python 2.7 and Python 3.1, Python rounded this value to 17 significant digits, giving ‘0.10000000000000001’. In current versions, Python displays a value based on the shortest decimal fraction that rounds correctly back to the true binary value, resulting simply in ‘0.1’ " Thank you for the answers! |
|
If anyone wishes to read into this a bit deeper, I highly recommend this paper: What Every Computer Scientist Should Know About Floating-Point Arithmetic |
|
For an excellent discussion about floating point numbers and these weird rounding errors, check out this lecture from MIT's introductory programming class. Start at 5:40 to get to the relevant part. |
|
Thanks for asking this question many students may be wondering why this occurs, well worth reading. Maybe add a link back to this question from Course web page? I bet It will get used. Consider adding links for 10 most popular answers. |
|
MrSparc, I just checked g++. (SEE EDIT BELOW, this code originally compared 1/5==2 rather than .2 :( )
The first EDIT: The above code was completely wrong because I dyslexically swapped 0.2 with 2.0. The first is given ("Python is weird"), but as a commenter below pointed out, there are potentially optimization issues going on here. I'm going to check the assembler to see what's going on. @ChrisG That's a relief, I'd actually be worried if it printed the first string ;) 1
1/5.0 is actually 0.2 in math furthermore, g++ might produce different optimization for this code up to evaluating the condition at compile time and throwing out unnecessary code. 1
@ftynse I changed things to use 1) the correct value and 2) volatile variables to prevent optimization. "Python is Weird is the Result". Let me know if I made any more boneheaded mistakes. |
Hi! If you liked the answer, please mark it as valid so that it doesn't show up as unanswered, thank you!