Python Why is Python displaying inaccurate decimal values for floating point numbers?

  • Thread starter Thread starter ali PMPAINT
  • Start date Start date
  • Tags Tags
    Float
Click For Summary
The discussion centers on the challenges of floating-point arithmetic in programming, particularly in Python. A user expresses frustration over the imprecision of floating-point division, specifically when dividing 1 by 3, which yields a result that appears truncated and imprecise. The conversation highlights that this behavior is expected due to the nature of floating-point representation, which can introduce rounding errors. To achieve a more precise representation, it is suggested to use the Decimal class in Python, emphasizing that the division should occur after converting integers to Decimals. This approach allows for greater precision and avoids the pitfalls of floating-point arithmetic. The discussion also touches on differences between Python 2 and Python 3 regarding division operations, noting that Python 3 promotes integers to floats automatically, while Python 2 requires explicit float usage for floating-point division. Overall, the conversation underscores the importance of understanding floating-point arithmetic and its limitations in programming.
ali PMPAINT
Messages
44
Reaction score
8
TL;DR
I want to obtain 1/3 for 20 decimal point, but I get wrong result:
So, I searched the whole internet, but wasn't the thing I actually wanted.
Capture.PNG

Which is obviously wrong! it should be 0.333333333333333333333333333333333333333333333333333333333333333333333...
And please, don't tell me the reason, I heard it a lot, I just want the solution to my problem.
 
Technology news on Phys.org
The title is somewhat misleading - floats are working as designed. You've divided one float by another, got the floating point precision result of 1÷3, then converted it to a higher precision representation of the same truncated result.

If you don't want to divide a float by a float and get a float, then you need to do the type conversion before the division.
 
Last edited:
  • Like
Likes ali PMPAINT
A side-effect of the approximate nature of floating points (and numerical methods in general) is that they introduce their own set of non-trivial errors in results compared to a purely mathematical formulation.

To understand and work with these errors there is probably no way around studying the topic a bit, even if it can appear a bit complicated. I would recommend the old classic What Every Computer Scientist Should Know About Floating-Point Arithmetic, but if that is too heavy for you then at least search for "floating point rounding errors" and go trough some of those descriptions.
 
  • Like
Likes Klystron, QuantumQuest and ali PMPAINT
So, Thanks, but I didn't understand anything. I am a beginner, it's my first time learning programming. I just want to change0.333333333333333314829616256247390992939472198486328125 to 0.333333333333333333333333333333333333333333333333333333, how?
 
Filip Larsen said:
at least search for "floating point rounding errors" and go trough some of those descriptions.
I did, but everything not related to my problem appeared.
 
The default representation of a number has a limited number of decimal places (more than I'm writing here, but you'll see the point). So 1/3 is interpreted something like 1.00/3.00 and gives you 0.33. Then you give this number to the Decimal class, asking for more digits. So it stores 0.3300, which is exactly 0.33 with more digits. Since this is all being done in binary, adding a string of zeroes to the end gives you a string of apparently random digits to the end of the base 10 number that gets printed.

If you want to get 0.3333, you need to start with 1.0000. So you need to create a Decimal 1, a Decimal 3, and divide them, not divide them then create a Decimal.
 
  • Like
Likes Klystron, QuantumQuest and ali PMPAINT
Ibix said:
The default representation of a number has a limited number of decimal places (more than I'm writing here, but you'll see the point). So 1/3 is interpreted something like 1.00/3.00 and gives you 0.33. Then you give this number to the Decimal class, asking for more digits. So it stores 0.3300, which is exactly 0.33 with more digits. Since this is all being done in binary, adding a string of zeroes to the end gives you a string of apparently random digits to the end of the base 10 number that gets printed.

If you want to get 0.3333, you need to start with 1.0000. So you need to create a Decimal 1, a Decimal 3, and divide them, not divide them then create a Decimal.
Thank you! That fixed my issue.
 
Get used to dealing with rounding errors like this. It's an issue to which there is no general solution.
 
  • Like
  • Informative
Likes Filip Larsen and ali PMPAINT
  • #10
ali PMPAINT said:
And please, don't tell me the reason, I heard it a lot, I just want the solution to my problem.

Please don't tell you the reason? Well...OK.

Python:
print "0.33333333333333333333"

will do what you want without us telling you the reason.
 
  • Like
Likes phinds, hmmm27, ali PMPAINT and 3 others
  • #11
There is also the python 2 vs 3 issues with respect to the / operator.

In 2, 1 / 3 = 0 because it notices you used integers and so used an integer division.

Whereas 1. / 3. will use a floating pt division because one of the operands is a float.

In 3, the 1 / 3 will promote the operands to floats and use a floating pt divide too and give you a floating pt answer.

So to get an integer divide, you need to use the new operator // ie (1 // 3) which complements the % operator for module math.

This is important to know, should you need to port code from python 2 to 3 for some project.
 
  • Like
  • Informative
Likes ali PMPAINT, Klystron, QuantumQuest and 1 other person
  • #12
jedishrfu said:
This is important to know, should you need to port code from python 2 to 3 for some project.
And there is double fun because from __future__ import division makes python2 behave like python3 in this respect.
 
  • Informative
Likes ali PMPAINT
  • #13
ali PMPAINT said:
So, I searched the whole internet
The whole internet? That must have taken quite a bit of time...
 
  • Like
  • Haha
Likes phinds, ali PMPAINT, jim mcnamara and 1 other person
  • #14
Vanadium 50 said:
Please don't tell you the reason? Well...OK.

Python:
print "0.33333333333333333333"

will do what you want without us telling you the reason.
lol, but I meant the reason that why python is showing me 0.333333333333333314829616256247390992939472198486328125 instead of 0.333333333333333333333333333333333333333333333333333333 , which I have read it in many sites, but they didn't write any proper solution.
 
  • #15
ali PMPAINT said:
but they didn't write any proper solution.

This is because the solution that will work best will depend on exactly what you are doing.

Using decimal for everything will solve your immediate problem but unless more information is given we can't determine if there any pitfalls to doing that.

BoB
 
  • Informative
Likes ali PMPAINT
  • #16
ali PMPAINT said:
lol, but I meant the reason that why python is showing me 0.333333333333333314829616256247390992939472198486328125 instead of 0.333333333333333333333333333333333333333333333333333333 , which I have read it in many sites, but they didn't write any proper solution.
It's because floating point arithmetic is inherently imprecise, for most numbers. Floating point numbers are stored in just a few bytes, so numbers that have an infinitely long binary representation get rounded or truncated. Even some numbers that have a short decimal representation, such as 0.1 or 0.2, can have an infinitely long binary representation.

Other numbers, such as 0.5 and .25, with short decimal representations, also have short binary representations, so they are stored in exact form.
 
  • Informative
Likes ali PMPAINT

Similar threads

  • · Replies 8 ·
Replies
8
Views
2K
  • · Replies 4 ·
Replies
4
Views
6K
  • · Replies 6 ·
Replies
6
Views
3K
  • · Replies 8 ·
Replies
8
Views
2K
Replies
2
Views
2K
  • · Replies 3 ·
Replies
3
Views
2K
  • · Replies 1 ·
Replies
1
Views
4K
Replies
8
Views
2K
  • · Replies 2 ·
Replies
2
Views
3K
  • · Replies 20 ·
Replies
20
Views
2K