This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How is floating point stored? When does it matter?
Python rounding error with float numbers
I am trying to understand why we get floating point representation error in python. I know this is not new question here but honestly I am finding hard time to understand it. I am going through the official document of python http://docs.python.org/tutorial/floatingpoint.html on section Representation Error at bottom of the page.
But I am not able to get how this expression J/2**N comes into picture and why in my interpreter I am getting this value.
0.1--->0.10000000000000001
The closest question I found is floating point issue and How are floating point numbers are stored in memory? but not able to understand.
Can anyone please in detail and simple language? Appreciate any help.
Thanks,
Sunil
You can think of 0.1 being a rational number for a computer - a rational number whose decimal expansion is not finite.
Take 1/3 for instance. For us humans, we know that it means "one third" (no more, no less). But if we were to write it down without fractions, we would have to write 0.3333... and so on. In fact, there is no way we can represent exactly one third with a decimal notation. So there are numbers we can write using decimal notation, and numbers we can't. For the latter, we have to use fractions - and we can do so because we have been taught maths at school.
On the other hand, the computer works with bits (only 2 digits: 1 and 0), and can only work with a binary notation - no fractions. Because of the different basis (2 instead of 10), the concept of a finite rational number is somewhat shifted: numbers that we can represent exactly in decimal notation may not be represented exactly in binary notation, and vice versa. What looks like a simple case for us (1/10=one tenth=0.1, exactly) is not necessarily an easy case for a CPU.
Related
This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 2 years ago.
Good day,
I'm getting a strange rounding error and I'm unsure as to why.
print(-0.0075+0.005)
is coming out in the terminal as
-0.0024999999999999996
Which appears to be throwing off the math in the rest of my program. Given that the numbers in this function could be anywhere between 1 and 0.0001, the number of decimal places can vary.
Any ideas why I'm not getting the expected answer of -0.0025
Joe,
The 'rounding error' you refer to is a consequence of the arithmetic system Python is using to perform the requested operation (though by no means limited to Python!).
All real numbers need to be represented by a finite number of bits in a computer program, thus they are 'rounded' to a suitable representation. This is necessary because with a finite number of bits it is not possible to represent all real numbers exactly (or even a finite interval of the numbers in the real line). So while you may define a variable to be 'a=0.005', the computer will store it as something very close to, but not exactly, that. Typically this rounding is done through floating-point representations which is the case in standard Python. In the binary version of this system, real numbers are approximated by integers multiplied by powers of 2 for their representation.
Consequently, operations such as the sum that you are performing operate on this 'rounded' version of the numbers and return another rounded version of the result. This implies that the arithmetic in the computer is always approximate, although usually, it is precise enough that we do not care. If these rounding errors are too large for your application, you may try to switch to use a more precise representation (more bits). You can find a good explainer with examples on Python's docs.
This question already has answers here:
underlying data structure for float in python
(6 answers)
Closed 9 years ago.
My question is more about
Why in C++,C# and VB
std::cout<<2.2f*3.0f<<std::endl; //prints 6.6
And in Python, Java and Ruby
2.2*3.0 //prints 6.6000000000000005
I'm very familiar with floating point representation in memory.
I checked that in fact 2.2 cannot be represented precisely in memory with single precision.
But still why do C++,C# and VB cut-out the irrelevant part of the result when printing the value while the others do not?
This is not to do with Python, it's just the way computers handle floating-point arithmetic.
Imagine trying to write down 1/3 exactly as a decimal in base 10 - you can't as you don't have an infinite amount of time or paper. There are an infinite number of 3s, so any decimal representation can only ever be an approximation.
Similarly, computers don't have an infinite amount of memory, so they can't represent certain fractions exactly (although these are different fractions as computers work in base 2). So in this case, the nearest the computer can get to 2.2*3.0 is 6.6000000000000005. This isn't to do with the multiplication, it's becuase the computer can't store 2.2 completely accurately. However, most of the time, the degree of accuracy given is near enough.
If you need perfect accuracy in Python, you can use the Decimal module.
In relation to problems this causes in "precise business logic", the answer is usually that when dealing with money, don't encode £1.23 as 1.23, but as 123 (pence). However, you may need to do something more complicated when dealing with dividing amounts of money, but this something else shouldn't just be using floats.
In answer to your edited question, it's just that C++ doesn't display as much of the number as Python. It doesn't store it more accurately.
"But still why do C++,C# and VB cut-out the irrelevant part of the result when printing the value while the others do not?"
Because they do. The people who implemented those languages made a different choice to those who implemented other languages. They weighed up the benefits of printing it out fully (it means you don't forget that floating point arithmetic is inaccurate) with the downsides (it is sometimes more difficult to see what the effective result is, shortening it gives an accurate result much of the time) and came to different conclusions.
This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 9 years ago.
I'm a bit confused of how this subtraction and summation work this way:
A = 5
B = 0.1
C = A+B-A
And I found the answer is 0.099999999999999645. Why the answer is not 0.1?
This is a floating point rounding error. The Python website has a really good tutorial on floating point numbers that explains what this is and why it happens.
If you want an exact result you can:
try using the decimal module
format your result to display a set number of decimal places (this doesn't fix the rounding error):
print "%.2f"%C
I also recommend reading "What Every Computer Scientist Should Know About Floating-Point Arithmetic" from Brian's answer.
Why the answer is not 0.1?
Floating point numbers are not precise enough to get that answer. But holy cow is it ever close!
I recommend that you read "What Every Computer Scientist Should Know About Floating-Point Arithmetic"
You're seeing an artefact of floating point arithmetic, which doesn't have infinit precision. See this article for a full description of how FP maths works, and why you see rounding errors.
Computers use "binary numbers" to store information. Integers can be stored exactly, but fractional numbers are usually stored as "floating-point numbers".
There are numbers that are easy to write in base-10 that cannot be exactly represented in binary floating-point format, and 0.1 is one of those numbers.
It is possible to store numbers exactly, and work with the numbers exactly. For example, the number 0.1 can be stored as 1 / 10, in other words stored as a numerator (1) and a denominator (10), with the understanding that the numerator is divided by the denominator. Then a properly-written math library can work with these fractions and do math for you. But it is much, much slower than just using floating-point numbers, so it's not that often used. (And I think in banking, they usually just use integers instead of floating-point to store money; $1.23 can be stored as the number 123, with an implicit two decimal places. When dealing in money, floating point isn't exact enough!)
This is because of the so called epsilon value. This means that from x to x+E every floating point number is considered to be equal to x.
You can read something about this value in this Q&A
in python this epsilon value(E) depends on the magnitune of the number, you can always get it from numpy.spacing(x)
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why do simple math operations on floating point return unexpected (inacurate) results in VB.Net and Python?
Why does this happen in Python:
>>>
>>> 483.6 * 3
1450.8000000000002
>>>
I know this happens in other languages, and I'm not asking how to fix this. I know you can do:
>>>
>>> from decimal import Decimal
>>> Decimal('483.6') * 3
Decimal('1450.8')
>>>
So what exactly causes this to happen? Why do decimals get slightly inaccurate when doing math like this?
Is there any specific reason the computer doesn't get this right?
See the Python documentation on floating point numbers. Essentially when you create a floating point number you are using base 2 arithmetic. Just as 1/3 is .333.... on into infinity, so most floating point numbers cannot be exactly expressed in base 2. Hence your result.
The difference between the Python interpreter and some other languages is that others may not display these extra digits. It's not a bug in Python, just how the hardware computes using floating-point arithmetic.
Computers can't represent every floating point number perfectly.
Basically, floating point numbers are represented in scientific notation, but in base 2. Now, try representing 1/3 (base 10) with scientific notation. You might try 3 * 10-1 or, better yet, 33333333 * 10-8. You could keep adding 3's, but you'd never have an exact value of 1/3. Now, try representing 1/10 in binary scientific notation, and you'll find that the same thing happens.
Here is a good link about floating point in python.
As you delve into lower level topics, you'll see how floating point is represented in a computer. In C, for example, floating point numbers are represented as explained in this stackoverflow question. You don't need to read this to understand why decimals can't be represented exactly, but it might give you a better idea of what's going on.
Computers store numbers as bits (in binary). Unfortunately, even with infinite memory, you cannot accurately represent some decimals in binary, for example 0.3. The notion is a kin to trying to store 1/3 in decimal notation exactly.
This question already has answers here:
Why does floating-point arithmetic not give exact results when adding decimal fractions?
(31 answers)
Closed 2 years ago.
My code:
a = '2.3'
I wanted to display a as a floating point value.
Since a is a string, I tried:
float(a)
The result I got was :
2.2999999999999998
I want a solution for this problem. Please, kindly help me.
I was following this tutorial.
I think it reflects more on your understanding of floating point types than on Python. See my article about floating point numbers (.NET-based, but still relevant) for the reasons behind this "inaccuracy". If you need to keep the exact decimal representation, you should use the decimal module.
This is not a drawback of python, rather, it is a drawback of the way floating point numbers are stored on a computer. Regardless of implementation language, you will find similar problems.
You say that you want to 'display' A as a floating point, why not just display the string? Visually it will be identical to what you expect.
As Jon mentioned, if your needs are more than just 'displaying' the floating point number, you should use the decimal module to store the exact representation.
Excellent answers explaining reasons. I just wish to add a possible practical solution from the standard library:
>>> from decimal import Decimal
>>> a = Decimal('2.3')
>>> print a
2.3
This is actually a (very) F.A.Q. for Python and you can read the answer here.
Edit: I just noticed that John Skeet already mentioned this. Oh well...