Python weird addition bug
Solution 1
From the Python docs
Note that this is in the very nature of binary floating-point: this is not a bug in Python, and it is not a bug in your code either (emphasis mine). You’ll see the same kind of thing in all languages that support your hardware’s floating-point arithmetic (although some languages may not display the difference by default, or in all output modes)
You should probably use the decimal
module.
Solution 2
You are using floating point numbers and have experienced a representation error. In particular, 0.01 has no exact representation as a binary floating point number. Instead a number very close to, but not exactly equal to 0.01 will be stored. This is not a bug. This is just the way floating point arithmetic works.
You can solve your problem in a few ways.
- Accept that the results are not completely accurate or
- Multiply everything by 100 and working with integers or
- Use the
Decimal
type.
Example:
from decimal import Decimal
percentage = Decimal('0.1')
step = Decimal('0.01')
percentage += step
Solution 3
As described in other answers, this is a limitation of native floating point numbers in all current microprocessors.
If you need exact representation of decimal numbers (ex. for accounting and business application) you should use decimal type, not floating point. You may also use cdecimal module, which is a high-performance implementation of the decimal type.
Update: Starting with Python v3.3, the builtin decimal module is implemented in C.
Solution 4
Floats do not have infinite precision, and so you get weird behaviour like this.
A better solution would be to store your percentage as an integer, representing tenths of a percent and increment by one.
e.g.:
percent_as_integer += 1
instead of
percent_as_float += 0.01
When you want to display the percentage, simply do:
print "%d.%02d" % divmod(percent_as_integer, 100)
EDIT: Actually, using the decimal module instead as was suggested in another answer is probably a better, more pythonic solution.
RandomPhobia
Updated on June 04, 2022Comments
-
RandomPhobia almost 2 years
Possible Duplicate:
python - decimal place issues with floats
Python float equality weirdnessIn the code below I have the variable
percentage
which is a float. I have it set up so that the ifnumber
reaches10,000
,percentage
is suppose to go up by.01
.# Tries to find a number that when squared and 5%'ed is still a square. import math print("Script has started:\n") percentage = .1 number = 1 while number != -1: number = number + 1 num_powered = number ** 2 num_5per = num_powered * percentage num_5per_sqrt = math.sqrt(num_5per) num_list = list(str(num_5per_sqrt)) dot_location = num_list.index(".") not_zero = 0 for x in num_list[dot_location + 1:]: if x != "0": not_zero = 1 break if not_zero == 0: print("*********************************") print("Map :",number) print("Safe-Area :",num_5per_sqrt) print("Percentage :",percentage) print("*********************************") input() if number > 10000: number = 0 percentage = percentage + .01 print(percentage)
Output:
0.11 0.12 0.13 0.14 0.15000000000000002 # Here is where it goes crazy 0.16000000000000003
-
Mark Ransom over 11 yearsThis is incredibly common. Floating point numbers in the computer are base 2, and they can't precisely represent many numbers that are natural in base 10.
-
Chinmay Kanchi over 11 yearsThis is NOT a bug. It is a consequence of how floating point variables work. See docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html . Voting to close as duplicate.
-
RandomPhobia over 11 yearsoh I see thanks then sorry googled but didn't see duplicate.
-
phihag over 11 yearsThis misunderstanding is so common it is actually mentioned not only in the stackoverflow wiki on floating-point, but also Wikipedia.
-
-
Mark Ransom over 11 yearsThat link is an incredibly nice explanation of the phenomenon, I'd never seen it before. I suggest anybody still confused should read it in its entirety.
-
Steven Rumbalski over 11 years+1 for the listing of common ways of addressing this issue.