Simple Multiplication is Giving Weird Result in Python

Hi Team, Here I am keeping few examples how the Multiplication working in Python. Need your help in understand this logic and returned Result.

x = 0.29*100
print(x)
#result = 28.999999999999996

x = 0.28*100
print(x)
#result = 28.000000000000004

x = 0.27*100
print(x)
#result = 27.0

PS: Why when we multiply 28 and 29 with 100, getting some weird result? Please help me in understand this.

1 Like

I suggest to read Floating Point Arithmetic: Issues and Limitations

1 Like

https://docs.python.org/3/faq/design.html#why-am-i-getting-strange-results-with-simple-arithmetic-operations

This is the case in all programming languages not just Python (although the details sometimes differ).

For a very technical explanation, see What Ever Computer Scientist Should Know About Floating-Point Arithmetic.

See also this visual explanation.

Sure Mr. Aivar Paalberg. I would like to Thankyou for sharing the informative link. I am sure I will go through on floating Point limitations. I have simple concern that since childhood I learnt that 0.29 * 100 = 29 only, even simple calculator returning 29 only. I feel like Python proving them Wrong.

In One of my application I came across this logic which is giving wrong results for business(Business Impact). I am sure we can solve this with round(0.29 * 100). Out of curiosity posted this to understand the Python’s programmatical view in treating the multiplication in these 2 scenarios.

Regards
Vinay

Hi Vinay
Welcome to floating point numbers and computers.

The short answer is that most decimal numbers, i.e. 0.28 * 100 can not be representeded exactly as the computer stores them in binary, for example 28 .0 is not the same as 0.28 * 100.0 there is an error.

i.e. 28.0 == .28 * 100. gives False.

Its not caused by the multiplication.

This a well known problem and predates python by many, many years.
Have a look at https://docs.python.org/3/tutorial/floatingpoint.html
John

1 Like

If you don’t want to see 15 decimal places (which I seldom want), you can always format the output:

x = 0.29*100
print(f"{x:2.2f}")
#result = 29.00

x = 0.28*100
print(f"{x:2.2f}")
#result = 28.00
2 Likes

If you can uses integers and avoid floating point then you can get exact results. Especially import, as you, say in business where money is concerned.

If you want 28% this can be done by 28 * x // 100.

I hear that money values may be held in pennies, or cents and not as £ or $ etc.

In your childhood, you also probably learned that one third is 0.33333333, but that it goes on forever. Since you don’t have infinite paper, you can’t write down all the digits of one third. Try doing some arithmetic with it:

  0.666666666666667 (because you round up with two thirds)
- 0.333333333333333
===================
  0.333333333333334

It’s never going to be perfect. You always have to round one way or the other, and whichever way you round, it’ll be a little bit wrong. Computers are doing the exact same thing, and 0.28 is actually stored as (binary) 0.0100011110101110000101000111101011100001010001111011; it really should be infinitely repeating, but it just can’t.

2 Likes

Python is not proving anything wrong here. It shows the limitations of representing fractions in a limited number of digits. The representation may be exact in some number base and an approximation in another.
If you need an exact value, try fraction.Fraction (fractions — Rational numbers — Python 3.10.6 documentation). However, that’s for rational numbers, so it too has its limitations.