1

Possible Duplicate:
Matlab gives wrong answer

Can anyone explain to me why the following happens, when I use the 0:.1:1-range function?

>> vecA = 0:.1:1;
>> vecB = [0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1];
>> vecA == vecB

ans =

     1     1     1     0     1     1     1     1     1     1     1

Why is vecA(4) not equal to 0.3? They look quite the same ;)

vecA =

  Columns 1 through 7

         0    0.1000    0.2000    0.3000    0.4000    0.5000    0.6000

  Columns 8 through 11

    0.7000    0.8000    0.9000    1.0000

>> vecB

vecB =

  Columns 1 through 7

         0    0.1000    0.2000    0.3000    0.4000    0.5000    0.6000

  Columns 8 through 11

    0.7000    0.8000    0.9000    1.0000

I think there is a problem with the precision here? Or do I have a problem in my understanding?

Community
  • 1
  • 1
powerbar
  • 323
  • 3
  • 14

2 Answers2

3

Computers are binary, their native floating-point format can't exactly store decimal fractions. (You could use a ratio type, or a fixed-point decimal type, but computations using these are far slower.)

As a consequence, testing floating-point values for equality is practically useless. Check the absolute value of the difference instead.

You should definitely read What Every Computer Scientist Should Know About Floating Point Arithmetic

(There are also some simpler explanations, such as http://floating-point-gui.de/ but you should use these to help you understand Goldberg's paper, not to replace it)


What you are actually seeing in this case is that 0.2 + 0.1 != 0.3 (the range uses the first version, vecA(3) = vecA(2) + step)

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
  • I know floating-point basics but will give this paper a try. Thank you. Anyway, I would have expected the simple range function of matlab to be more robust here... – powerbar Jun 11 '12 at 13:41
  • 1
    `Computers are binary, they can't exactly store decimal fractions.` is an untrue statement. – rubenvb Jun 11 '12 at 14:07
  • @rubenvb: Clarified to refer to the native format. Of course you can represent rational numbers, including decimal fractions, as user-defined types, but then math is very inefficient. – Ben Voigt Jun 11 '12 at 15:41
  • @BenVoigt Now you have my +1 `:)`. – rubenvb Jun 11 '12 at 16:44
  • I'll take this one because of the background paper - it's quite helpful. – powerbar Jun 12 '12 at 06:58
2

This is likely to be a general consequence of finite precision floating point arithmetic. Try using

    format long

and then outputting the values to see a more precise display. I would imagine internally vecA is created using a loop and value incrementing or division of a range which is causing a tiny difference. As you are equating floating point values you are getting this problem. It is a common consequence of direct comparison of floats in general.

mathematician1975
  • 21,161
  • 6
  • 59
  • 101
  • If a loop was used, I expect the error to sum up? Or be somehow symmetrical? – powerbar Jun 11 '12 at 13:39
  • I see what you mean but it is hard to assume anything with floating point arithmetic when comparisons are being made between your values and values calculated by another persons code that you don't have access to. – mathematician1975 Jun 11 '12 at 13:47
  • I use `abs(vecA - vecB) < treshold` in my code but I just wouldn't have expected this behaviour. But I think it's a nice example, that everyone should be aware of what he/she is doing... – powerbar Jun 11 '12 at 13:52
  • I concur with your sentiments – mathematician1975 Jun 11 '12 at 13:56