`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 ?

`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 ?

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 `float`

s 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

```
>>> 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