# Why is it like this?

Please have a look at the below statements…
print(((0.08 * 500 * 5) * 45) / 100)
print(((0.08 * 500 * 5) / 100) * 45)

print(((0.08 * 500 * 6) * 45) / 100)
print(((0.08 * 500 * 6) / 100) * 45)

print(((0.08 * 500 * 7) * 45) / 100)
print(((0.08 * 500 * 7) / 100) * 45)

print(((0.08 * 500 * 8) * 45) / 100)
print(((0.08 * 500 * 8) / 100) * 45)

print(((0.08 * 500 * 9) * 45) / 100)
print(((0.08 * 500 * 9) / 100) * 45)

print(((0.08 * 500 * 17) * 45) / 100)
print(((0.08 * 500 * 17) / 100) * 45)

print(((0.08 * 500 * 19) * 45) / 100)
print(((0.08 * 500 * 19) / 100) * 45)

# OITPUTS: 90.0 90.0 108.0 108.0 126.0125.99999999999999 144.0 144.0 162.0 162.0 306.0 306.0 342.0 342.0

Why do I get this value (125.99999999999999) for the above BOLD marked line of code?

Please have a look at the below statements…
print(((0.08 * 500 * 5) * 45) / 100)
[…]

The short answer is that Python floating point values (eg your 0.08 and
everything which is computed from it) effectively base 2 scientific
notation: a primary value integral (the mantissa) multiplied by an
integral scale factor (the exponent).

As such, various values cannot be precisely represented in it.

You may know that in base 10, for example, the fraction 1/3 cannot be
written precisely in the form 0.333333 because an infinite number of 3s
would be required. This is essentially because 10 has the prime factors
2 and 5, and there’s no 3 there.

The situation is analogous in base 2. 0.08 is 4/25 or 4/(5*5), and
there’s no 5 in the prime factors of 2.

We get around these issues for the most poart by having quite a few
digits of precision. Example:

`````` >>> 1.0/3.0
0.3333333333333333
``````

That isn’t 1/3, but it is quite close.

Your example computations have exposed that the value you supplied as
0.08 is not, in fact, _stored exactly equivalent to 4/25, just very
close.

When you do your arithmetic, the results aren’t exactly what you
anticipate, but because of the high precision the resulting value,
written in base 10 in the most accurate form, is usually so close that
it ends in .0000000000 and thus .0 when you trim the trailing zeroes.
But one of your computations resulted in a value where the most accurate
form is off enough to not end in all zeroes.

and there’s any number of tutorials discussing the details.

The short answer is that a floating point value is a fixed size
fraction; being fixed size means that many values cannot be precisely
represented.

Python has some modules for special purposes, such as `decimal`:

and `fractions`:

They’re slower than floating point and have their own limitations.

Cheers,
Cameron Simpson cs@cskk.id.au

Hello Cameron,
That is OK what you had explained.
But note that the 2 code lines below

print(((0.08 * 500 * 7) * 45) / 100)
print(((0.08 * 500 * 7) / 100) * 45)

give 2 different outputs as below, WHY ?
126.0
125.99999999999999

But in scientific Calculator,
they produce the same result as 126.0
Mathematically they should be same, is it not ?

Yes, they are mathematically the same.

No, they are not the same in binary FP calculations – please do go read the referenced materials.

NOTE: Floating point is HARD. I have a PhD in Engineering, do this stuff everyday, and I still get confused.

The short version is that FP calculations are not exact, and thus you will get results that are not exact, but should be very close to the exact answer. never rely on equality of a the result of a floating point calculation:

``````In : a = ((0.08 * 500 * 7) * 45) / 100

In : b = ((0.08 * 500 * 7) / 100) * 45

In : a == b
Out: False

In : math.isclose(a,b)
Out: True
``````

Your calculator gives different results for one of a couple reasons:

1. It’s rounding differently / or ordering operations differently
2. It’s using a decimal representation internally – some are made that way, for less “surprising” results.

Hello Christopher.
Thank you so much for your excellent explanation.