0
Виконано

# Error for boolean operation at certain precision

Michael_ 8 років тому оновлено Pavel Holoborodko 8 років тому

Hello Pavel.

I got the following problem:

mp.Digits(349);
array=mp('2')*mp('10')^mp('-4'):mp('2')*mp('10')^mp('-4'):mp('1');
array(1,100)==mp('0.02')

ans =
logical
1

mp.Digits(350);
array=mp('2')*mp('10')^mp('-4'):mp('2')*mp('10')^mp('-4'):mp('1');
array(1,100)==mp('0.02')

ans =
logical
0

mp.Digits(351);
array=mp('2')*mp('10')^mp('-4'):mp('2')*mp('10')^mp('-4'):mp('1');
array(1,100)==mp('0.02')
ans =
logical
1

This apperas quite randomly, deppending on the used precision. You can try for example mp.Digits(352) to mp.Digits(355).

Виконано

Dear Michael,

Thank you for question and sorry for delay in reply.

This situation is not a bug.

Toolbox follows philosophy of IEEE standard and stores numbers in binary floating-point format.

The thing is that number 0.02 is not exactly representable in binary floating-point format regardless of precision.

We can only approximate it by the nearest representable number in given precision, for example (I use 15 digits for simplicity):

```>> mp.Digits(15);
>> fprintf('%.20e\n',mp('0.02'))
1.99999999999999900080e-02
```

Colon operation includes quite a lot of algorithms under the hood (e.g. to make sure that generated numbers are symmetric around midpoint, etc.) - and there is no guarantee that it will generate exactly the same bit-to-bit approximation to 0.02 in the middle of generated sequence:

```>> array=mp('2*10^(-4)'):mp('2*10^(-4)'):mp('1');
>> fprintf('%.20e\n',array(1,100))
2.00000000000000177636e-02
```

Both numbers are accurate approximations to 0.02 up to the same number of decimal digits:

```>> fprintf('%.14e\n',mp('0.02'))
2.00000000000000e-02
>> fprintf('%.14e\n',array(1,100))
2.00000000000000e-02
```

But they are not the same in bit-to-bit binary representation (they might be in some precisions, but there is no guarantee, of course)!

This is classical issue of decimal vs. binary floating-point numbers. And this is the reason why == shouldn't be used in floating-point world. Please compare numbers by some tolerance instead.

Would it be Ok to make this question public, since it touches common issue and can be useful for others?