How to fix the floating point error in python [duplicate] - python

This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 1 year ago.
I have been recently trying to make a calculator in python and added floating points in it
but unfortunately it gives me for this simple code
print(0.1 + 0.2)
out put
0.30000004
I have searched a lot for it in stackoverflow but I keep getting questions about why it happened and not how to fix it.
Edit:
a lot of people have been recently giving me private feedbacks about this already exists I appreciate that to improve stackoverflow but there are no questions most of them are explanations about why it is happening and not how to fix it. some of the feedbacks have got even questions that are not python

you can try any of the follow methods which is conventional for you
#for two decimal places use 2f, for 3 use 3f
val = 0.1 + 0.2
print(f"val = {val:.2f}")
#output | val = 0.30
#or else
print(round(val,2))
#output | val = 0.30

You can use the decimal built-in module with strings and make your own methods:
from decimal import Decimal
def exact_add(*nbs):
return float(sum([Decimal(str(nb)) for nb in nbs]))
exact_add(0.1, 0.2)
# > 0.3

I think the recommended way to resolve this is to determine a number of decimal places you want to consider and round to that using the built-in round function. Say you want to use 5 decimal places, you could do:
ans = 0.1 + 0.2
print(ans) # 0.30000004
round(ans,5)
print(ans) # 0.3
Note that round also gets rid of extra zeroes in the end. If you round 0.333333333333 to 5 decimals it will return 0.33333, but rounding 0.30000000004 returns 0.3.

This has nothing to do with python, but with the way floating point values are represented on your machine. The way floating point works is the same for all languages, and it can potentially introduce rounding errors. This link shows you exactly why you get this error.
Just reduce the number of visible digits and you'll be fine. Just now that all computers and calculators have limited space for numbers, and all of them are prone to rounding errors.

You can use:
a = 0.1 + 0.2
a = round(a, 2)
print(a)
Output: 0.3

use round() syntax to get rid of excessive number of zeros.
'''
a = 0.1
b = 0.2
c = a + b
answer = round(c,3) # here 3 represents the number of digits you want to round
print(answer)
'''
and incase you want more clarification on round() syntax just visit this link once: https://www.bitdegree.org/learn/python-round

Related

Python Round not working as expected for some values [duplicate]

This question already has answers here:
How to properly round-up half float numbers?
(21 answers)
Closed 7 months ago.
In Python 3, I'm trying to round the value 4800.5, so I was expecting it to 4801
but it's giving me 4800. I'm not able to track why this is happening.
Any help will be appreciated.
That's by design.
If you have a look at round function documentation (https://docs.python.org/3/library/functions.html#round) you will find that:
For the built-in types supporting round(), values are rounded to
the closest multiple of 10 to the power minus ndigits; if two
multiples are equally close, rounding is done toward the even choice
(so, for example, both round(0.5) and round(-0.5) are 0, and
round(1.5) is 2).
In simple words, 0.5 is a special case which is always rounded toward an even number.
But there're more interesting things. Please have a look at that example:
The behavior of round() for floats can be surprising: for
example, round(2.675, 2) gives 2.67 instead of the expected 2.68. This
is not a bug: it’s a result of the fact that most decimal fractions
can’t be represented exactly as a float.
What you might want to do is to use Decimal for more conventional rounding logic: https://docs.python.org/3/library/decimal.html
For example:
>>> Decimal('7.325').quantize(Decimal('.01'), rounding=ROUND_DOWN)
Decimal('7.32')
>>> Decimal('7.325').quantize(Decimal('.01'), rounding=ROUND_UP)
Decimal('7.33')
There are lot of ways to round a number. round() behaves according to a particular rounding strategy which may or may not be the one you need for a given situation (see the first comment to your question).
If you want to round your number to the upper, you can try this:
import math
n = 4800.5
print(math.ceil(n))
you can do something like this:
from decimal import Decimal, ROUND_HALF_UP
def round_half_up(decimal_number, places=0):
if places == 0:
exp = Decimal('1')
else:
exp_str = '0' * places
exp_str = exp_str[:-1] + '1'
exp = Decimal('.{}'.format(exp_str))
return Decimal(decimal_number).quantize(exp, rounding=ROUND_HALF_UP)
print(round_half_up(4800.5)) -> 4801
print(round_half_up(4800.555, 2)) -> 4800.56
Round() function will round up to next value, if decimal is >.5
upto .5 it would round up to just the integer part.

Why don't large floats in Python 3 get cast to integers properly? [duplicate]

This question already has answers here:
Is floating point math broken?
(31 answers)
Is floating point arbitrary precision available?
(5 answers)
Closed 7 years ago.
I don't know if this is an obvious bug, but while running a Python script for varying the parameters of a simulation, I realized the results with delta = 0.29 and delta = 0.58 were missing. On investigation, I noticed that the following Python code:
for i_delta in range(0, 101, 1):
delta = float(i_delta) / 100
(...)
filename = 'foo' + str(int(delta * 100)) + '.dat'
generated identical files for delta = 0.28 and 0.29, same with .57 and .58, the reason being that python returns float(29)/100 as 0.28999999999999998. But that isn't a systematic error, not in the sense it happens to every integer. So I created the following Python script:
import sys
n = int(sys.argv[1])
for i in range(0, n + 1):
a = int(100 * (float(i) / 100))
if i != a: print i, a
And I can't see any pattern in the numbers for which this rounding error happens. Why does this happen with those particular numbers?
Any number that can't be built from exact powers of two can't be represented exactly as a floating point number; it needs to be approximated. Sometimes the closest approximation will be less than the actual number.
Read What Every Computer Scientist Should Know About Floating-Point Arithmetic.
Its very well known due to the nature of floating point numbers.
If you want to do decimal arithmetic not floating point arithmatic there are libraries to do this.
E.g.,
>>> from decimal import Decimal
>>> Decimal(29)/Decimal(100)
Decimal('0.29')
>>> Decimal('0.29')*100
Decimal('29')
>>> int(Decimal('29'))
29
In general decimal is probably going overboard and still will have rounding errors in rare cases when the number does not have a finite decimal representation (for example any fraction where the denominator is not 1 or divisible by 2 or 5 - the factors of the decimal base (10)). For example:
>>> s = Decimal(7)
>>> Decimal(1)/s/s/s/s/s/s/s*s*s*s*s*s*s*s
Decimal('0.9999999999999999999999999996')
>>> int(Decimal('0.9999999999999999999999999996'))
0
So its best to always just round before casting floating points to ints, unless you want a floor function.
>>> int(1.9999)
1
>>> int(round(1.999))
2
Another alternative is to use the Fraction class from the fractions library which doesn't approximate. (It justs keeps adding/subtracting and multiplying the integer numerators and denominators as necessary).

Absurd data when importing from Excel to pandas [duplicate]

This question already has answers here:
Why does floating-point arithmetic not give exact results when adding decimal fractions?
(31 answers)
Is floating point arbitrary precision available?
(5 answers)
Closed 7 years ago.
I don't know if this is an obvious bug, but while running a Python script for varying the parameters of a simulation, I realized the results with delta = 0.29 and delta = 0.58 were missing. On investigation, I noticed that the following Python code:
for i_delta in range(0, 101, 1):
delta = float(i_delta) / 100
(...)
filename = 'foo' + str(int(delta * 100)) + '.dat'
generated identical files for delta = 0.28 and 0.29, same with .57 and .58, the reason being that python returns float(29)/100 as 0.28999999999999998. But that isn't a systematic error, not in the sense it happens to every integer. So I created the following Python script:
import sys
n = int(sys.argv[1])
for i in range(0, n + 1):
a = int(100 * (float(i) / 100))
if i != a: print i, a
And I can't see any pattern in the numbers for which this rounding error happens. Why does this happen with those particular numbers?
Any number that can't be built from exact powers of two can't be represented exactly as a floating point number; it needs to be approximated. Sometimes the closest approximation will be less than the actual number.
Read What Every Computer Scientist Should Know About Floating-Point Arithmetic.
Its very well known due to the nature of floating point numbers.
If you want to do decimal arithmetic not floating point arithmatic there are libraries to do this.
E.g.,
>>> from decimal import Decimal
>>> Decimal(29)/Decimal(100)
Decimal('0.29')
>>> Decimal('0.29')*100
Decimal('29')
>>> int(Decimal('29'))
29
In general decimal is probably going overboard and still will have rounding errors in rare cases when the number does not have a finite decimal representation (for example any fraction where the denominator is not 1 or divisible by 2 or 5 - the factors of the decimal base (10)). For example:
>>> s = Decimal(7)
>>> Decimal(1)/s/s/s/s/s/s/s*s*s*s*s*s*s*s
Decimal('0.9999999999999999999999999996')
>>> int(Decimal('0.9999999999999999999999999996'))
0
So its best to always just round before casting floating points to ints, unless you want a floor function.
>>> int(1.9999)
1
>>> int(round(1.999))
2
Another alternative is to use the Fraction class from the fractions library which doesn't approximate. (It justs keeps adding/subtracting and multiplying the integer numerators and denominators as necessary).

Python power of operator issue [duplicate]

This question already has answers here:
Is floating point math broken?
(31 answers)
Is floating point arbitrary precision available?
(5 answers)
Closed 7 years ago.
I don't know if this is an obvious bug, but while running a Python script for varying the parameters of a simulation, I realized the results with delta = 0.29 and delta = 0.58 were missing. On investigation, I noticed that the following Python code:
for i_delta in range(0, 101, 1):
delta = float(i_delta) / 100
(...)
filename = 'foo' + str(int(delta * 100)) + '.dat'
generated identical files for delta = 0.28 and 0.29, same with .57 and .58, the reason being that python returns float(29)/100 as 0.28999999999999998. But that isn't a systematic error, not in the sense it happens to every integer. So I created the following Python script:
import sys
n = int(sys.argv[1])
for i in range(0, n + 1):
a = int(100 * (float(i) / 100))
if i != a: print i, a
And I can't see any pattern in the numbers for which this rounding error happens. Why does this happen with those particular numbers?
Any number that can't be built from exact powers of two can't be represented exactly as a floating point number; it needs to be approximated. Sometimes the closest approximation will be less than the actual number.
Read What Every Computer Scientist Should Know About Floating-Point Arithmetic.
Its very well known due to the nature of floating point numbers.
If you want to do decimal arithmetic not floating point arithmatic there are libraries to do this.
E.g.,
>>> from decimal import Decimal
>>> Decimal(29)/Decimal(100)
Decimal('0.29')
>>> Decimal('0.29')*100
Decimal('29')
>>> int(Decimal('29'))
29
In general decimal is probably going overboard and still will have rounding errors in rare cases when the number does not have a finite decimal representation (for example any fraction where the denominator is not 1 or divisible by 2 or 5 - the factors of the decimal base (10)). For example:
>>> s = Decimal(7)
>>> Decimal(1)/s/s/s/s/s/s/s*s*s*s*s*s*s*s
Decimal('0.9999999999999999999999999996')
>>> int(Decimal('0.9999999999999999999999999996'))
0
So its best to always just round before casting floating points to ints, unless you want a floor function.
>>> int(1.9999)
1
>>> int(round(1.999))
2
Another alternative is to use the Fraction class from the fractions library which doesn't approximate. (It justs keeps adding/subtracting and multiplying the integer numerators and denominators as necessary).

Adding decimal numbers to a decimal number not working properly in python [duplicate]

This question already has answers here:
Python rounding error with float numbers [duplicate]
(2 answers)
Python weird addition bug [duplicate]
(4 answers)
Closed 9 years ago.
I'm trying to add decimal numbers a decimal number and it works correctly but when I do 1.1 + 0.1 I get 1.2000000000000002 but all I want it to equal to is 1.2. When I do 1.0 + 0.1 I get 1.1 which is perfect but i don't get that for 1.1 + 0.1. So is there a way that I can get rid of the 000000000000002 from 1.2000000000000002?
Thanks.
As has been stated countless times, 0.1 cannot be represented exactly in IEEE 754 floating point. You can read all about why in What Every Computer Scientist Should Know About Floating-Point Arithmetic or The Floating Point Guide
You can trucate or round the value:
>>> round(1.1+.1,2)
1.2
>>> "%.*f" % (1, 1.1+.1 )
'1.2'
>>> s=str(1.1+.1)
>>> s[0:s.find('.')+2]
'1.2'
If you want exact representation of those values, consider using the Decimal module:
>>> import decimal
>>> decimal.Decimal('1.1')+decimal.Decimal('.1')
Decimal('1.2')
Note that you need to start with the string representation of your float, '0.1' since 0.1 is not exactly representable in binary in IEEE floating point:
>>> decimal.Decimal(.1)
Decimal('0.1000000000000000055511151231257827021181583404541015625')
To then get a string representation back after you calculate, you can use str:
>>> str(sum(map(decimal.Decimal,['.1','.1','.5','.5'])))
'1.2'
Another alternative is to use a rational number library such as Fractions:
>>> from fractions import Fraction as Fr
>>> Fr(11,10)+Fr(1,10)
Fraction(6, 5)
With that result, you will still need to round, truncate, or use an arbitrary precision arithmetic package to get an exact number (depending on the inputs...)
You can try string formatting, documentation here.
>>> "%0.2f" % float(1.1 + 0.1)
'1.20'
Or Even:
>>> "%0.1f" % float(1.1 + 0.1)
'1.2'
As to why, it is explicitly described on PEP 327 here.
This is the literal answer to your question:
float(str(1.1 + 0.1)[0:3])
If you're interested in the "why" of the problem then refer to the links provided in the question comments.

Categories

Resources