Rounding Problem with Python [duplicate]

2020-04-16 04:08发布

Possible Duplicate:
Python rounding error with float numbers

I have a rounding Problem in Python. If i calculate

32.50 * 0.19 = 6.1749999999999998

But this should be 6.175. If i round 6.1749999999999998 with 2 decimal places it correctly shows 6.18. So i can live with that.

But if i calculate this:

32.50 * 0.19 * 3 = 18.524999999999999

This should be 18.525. If i round the value 18.524999999999999 with two decimal places it shows 18.52.

It should show me 18.53. What am i doing wrong and how can i fix it ?

7条回答
迷人小祖宗
2楼-- · 2020-04-16 04:22

If you need exact arithmetic, you could use the decimal module:

import decimal
D=decimal.Decimal

x=D('32.50')*D('0.19')
print(x)
# 6.1750
print(x.quantize(D('0.01'),rounding=decimal.ROUND_UP))
# 6.18

y=D('32.50')*D('0.19')*D('3')
print(y)
# 18.5250
print(y.quantize(D('0.01'),rounding=decimal.ROUND_UP))
# 18.53
查看更多
聊天终结者
3楼-- · 2020-04-16 04:23

You are not doing anything wrong. This is due to the internal representation of the numbers:

For example, try this:

0.1 + 0.1 +  0.1 + 0.1 +  0.1 + 0.1 +  0.1 + 0.1 +  0.1 + 0.1

If you need more precision use the decimal representation

查看更多
我命由我不由天
4楼-- · 2020-04-16 04:27

You're doing nothing wrong, and it isn't Python's fault either. Some decimal numbers just cannot be precisely represented as binary floats.

Just like you can't write 1/3 in decimal (0.33333....), you can't write decimal 0.1 in binary (0.0001100110011001100110011001100110011001100110011...).

Solution A:

Use print 32.5 * 0.19 - it will automatically round the result.

Solution B:

Use the Decimal module if you actually need this precision, for example when calculating with monetary values.

Solution C:

Use Python 3.2 or Python 2.7 which will automatically round the result in an interactive session.

Python 2.7.2 (default, Jun 12 2011, 14:24:46) [MSC v.1500 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> 32.50 * 0.19
6.175
查看更多
女痞
5楼-- · 2020-04-16 04:29

I don't think that is wrong. Take this from the Python interpreter:

>>> round(18.524999999999999,2)
18.52
>>> round(6.1749999999999998,2)
6.17
>>> 

In both cases, the number being rounded was less than 5, so it rounded down. 18.52, and 6.17.

That is correct.

One thing I don't get is why you are getting 6.18, and I get 6.17. I am using Python 3.2.2 (the latest version)

查看更多
够拽才男人
7楼-- · 2020-04-16 04:36

What Every Computer Scientist Should Know About Floating-Point Arithmetic.

In short - you should not rely on precise values of float numbers because of the way they are stored in the memory.

See also python docs about it - Floating Point Arithmetic: Issues and Limitations. It contains the next passage:

For example, if you try to round the value 2.675 to two decimal places, you get this

>>> round(2.675, 2)
2.67

The documentation for the built-in round() function says that it rounds to the nearest value, rounding ties away from zero. Since the decimal fraction 2.675 is exactly halfway between 2.67 and 2.68, you might expect the result here to be (a binary approximation to) 2.68. It’s not, because when the decimal string 2.675 is converted to a binary floating-point number, it’s again replaced with a binary approximation, whose exact value is

2.67499999999999982236431605997495353221893310546875

Since this approximation is slightly closer to 2.67 than to 2.68, it’s rounded down.

查看更多
登录 后发表回答