1.005*1000=1004.99999` why?

1.005*1000=1004.99999 why?
and (1.003 or 1.005 or 1.007 or 1.009)*1000 ?

1003/1.003=1000.0000000000001 whay?

erorr number (1.003 1.005 1.007 1.009) in * and / its Bug ?

See 15. Floating Point Arithmetic: Issues and Limitations — Python 3.11.0 documentation

This is because floating point numbers are not artbitrary precision
exact representations of the decimal value you may write down. Instead
they are fixed size (in terms of storage) numbers in scientific notation
style, using base 2 (as you might imagine).

What does this mean?

In short, the decimal value 1.005 cannot be stored precisely as a
Python float. Why not?

Internally, a float is composed of 2 values: an integer (the
“mantissa”) and an exponent (an integer power of 2). Both are of a fixed
storage size, which means that they can only hold a certain range of
values. So the value expressed by that pair is:

 mantissa * (2 ^ exponent)

If the exponent is positive that’s a straight up multiplication and if
the exponent is negative that’s effectively division, a fraction:

 mantissa / (2 ^ (-exponent))

You might think: ok, 1.005 could be written as 1005 / 1000 and they’re
both integers, and neither is particularly big so they can both fit in
the range of values we’ve got room to store.

However, 1000 is not a power of 2 and therefore there’s no expression:

 2 ^ (-exponent)

which equals 1000 if the exponent is an integer. So we can’t express
1.005 as 1005 / 1000 in this scheme - the mantissa can be 1005 but the
2^exponent cannot equal 1000.

The nearest power of 2 is 1024. To use that for the 2^exponent part,
the mantissa would need to be 1005*1024/1000 or 1029.12. Not an
integer!

The nearest integer is 1029, and 1029/1024 is 1.0048828125 (roughly).
Close to, but not exactly, 1.005.

Now, in fact a float mantissa is effectively a fraction (still in base
2) with quite a few bits of storage. So we can in fact get quite close
to the decimal value 1.005 in a float. But that particular value will
never be exactly represented as a float.

The same logic applies to many other values (really, anything which
isn’t an integer multiple of an integer power of 2), and as a
consequence almost all operations on floats produce values slightly
different from what you might naively expect from a base 10 computation.
The exact different depends very much on the values you’re using and the
order in which those operations are done.

For this reason, we almost never compare float values with ==
because if they’re the result of a computation they’re likely to be very
slightly off.

There are alternatives to float. Python ships with a fractions
module and a decimal module. Both have their uses (and limitations).

Cheers,
Cameron Simpson cs@cskk.id.au

1 Like

See the FAQ.

>>> 1.005 == 1.004999999999999999
True

IDLE tries to print the fractional part of a float with as few decimal digits at possible. There is an algorithm for this.

>>> 1005 == 1004.99999999999999999
True

But IDLE does not fiddle with the integer part of a float. So it outputs ‘1004’ as the int part and then looks at the fractional part without changing the integer part.

1 Like