1
>>> num = 4.123456
>>> round(num, 3) # expecting 4.123
4.1230000000000002

I'm expecting 4.123 as a result, Am I wrong?

3

4 Answers 4

7

This is not a mistake. You need to read What Every computer Scientist Should Know About Floating Point Arithmetic:

http://docs.sun.com/source/806-3568/ncg_goldberg.html

Sign up to request clarification or add additional context in comments.

Comments

6

Yep, your expectations don't match the design intent of your tools.

Check out this section of the Python tutorial.


Using math.round is actually pretty rare. if you're trying to display a number as a string to a certain precision, you might want something more like

>>> num = 4.123456
>>> print "%.3f" % num
4.123

You might be interested in the documentation on string formatting.

5 Comments

I'm finding the canon floating point page over-linked. The link you gave in Python docs is way more practical, and on a level most people can understand and appreciate.
Both are valuable resources. I agree this one is a lot better for beginners, but eventually people will want to read the Goldberg article as well.
Thanks. But I just want to get that as a number, not string.
@pocoa, What is wrong with 4.1230000000000002? If you think decimal.Decimal is the answer, you are most likely not understanding the situation well enough.
maybe you're right. I just wanted to store the first 3 digits. I could have the same effect with doing string formatting when displaying it. I was just confused.
4

Why do you care? (That's a serious question.)

The answer that you're getting is so close to 4.123 as to make no difference. It can't be exactly 4.123, since there are only finitely many numbers (around 2**64 on a typical machine) that Python can represent exactly, and without going into detail about floating-point representations, it just so happens that 4.123 isn't one of those numbers. By the way, 4.1230000000000002 isn't one of the numbers that can be exactly represented, either; the actual number stored is 4.12300000000000022026824808563105762004852294921875, but Python truncates the decimal representation to 17 significant digits for display purposes. So:

  1. If you're doing mathematics with the result, then the difference between 4.123 and what you're getting is so tiny as to make no real difference. Just don't worry about it.
  2. If you just care about the output looking pretty (i.e., what you're after here is a string rather than a number) then use str, or string formatting.
  3. In the unlikely case that the difference really does matter, e.g., because you're doing financial work and this affects the direction that something rounds later on, use the decimal module.

Final note: In Python 3.x and Python 2.7, the repr of a float has changed so that you will actually get 4.123 as you expect here.

2 Comments

+1, "If you're doing mathematics with the result, then the difference between 4.123 and what you're getting is so tiny as to make no real difference." <--- exactly
Yes, you're right. Thank you guys for making me understand/remember that.
2

If you want to have an exact representation of your floating point number, you have to use decimal.

6 Comments

Decimal is in general no more exact than binary floating point. It can represent decimal fractions exactly (up to a point), which is of course the entire point of the data type, but it also has its limitations.
decimal.Decimal has both representation and roundoff errors, just like float, though you can control them some additional ways. I have yet to see a case where someone's problem of float inexactness had the best solution of using Decimal instead. Decimal is mostly useful in niche financial applications.
@Joren: Compared to the built-in float implementation of binary floating point, the new class is especially helpful for financial applications and other uses which require exact decimal representation, control over precision, control over rounding to meet legal or regulatory requirements, tracking of significant decimal places, or for applications where the user expects the results to match calculations done by hand. from this book. Maybe my answer is not well phrased but this is what I meant.
"Exact decimal representations" (which slightly oversells decimal.Decimal to start with) is a lot different than "exact floating point numbers". The key phrase in that quote is "helpful for financial applications".
@Felix: What Mike says. For what it's worth, that downvote wasn't mine, I think your suggestion can be helpful for dealing with the OP's problem. But I needed to remark that 'exact floating point' is misleading. Decimal floating point will not represent, for example, 1/3 exactly. For that you'd need to have ternary floating point. There is an infinite amount of other fractions decimal floating point can't represent exactly.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.