MATLAB: Atan2 not consisent

atan2binary floating pointieee-754mathMATLABnegative zeropositive zerosigned zerotangent

I have the following values that I run through the atan2 function:
a(77:78,:)
ans =
-0.250000000000000 0 -0.950000000000000
-0.260000000000000 0 -0.950000000000000
when I put the above array through the atan2 function, the first value is positive and the second is negative,
atan2(a(77:78,2),a(77:78,3))
ans =
3.141592653589793
-3.141592653589793
If I type in each value of the second row of data by hand, the result is differnt for the atan2 function (it is positive):
atan2(0,-0.95)
ans =
3.141592653589793
If I build a test matrix, manually inputing the values, the atan2 results are both positive.
test = [-0.25, 0 , -0.95; -0.26, 0 , -0.95]
test =
-0.250000000000000 0 -0.950000000000000
-0.260000000000000 0 -0.950000000000000
>> atan2(test(1,2),test(1,3))
ans =
3.141592653589793
>> atan2(test(2,2),test(2,3))
ans =
3.141592653589793
Question: Why are the values of atan2 function positive and negative in the first case but then both positive when I type out the values?
Aside: If done separately:
atan2(a(77,2),a(77,3))
ans =
3.141592653589793
>> atan2(a(78,2),a(78,3))
ans =
-3.141592653589793
Thank you

Best Answer

  • The reason is a little arcane: negative zero:
    The other answers and comments are wrong: this has nothing to do with floating point error or "almost zero" values.
    The second column values are exactly zero, and we know that the value is exactly zero because in both long and short format only the exact value zero is displayed as one single digit "0", just as all of your examples show.
    So what is the catch?
    The catch is simply the IEEE 754 defines two zeros, a positive zero and a negative zero. Same value, different signs. Some (but not all) operations retain the sign when operating on them.
    One of your zeros is negative and one is positive, but unfortunately MATLAB** displays them without the sign:
    Y = [0;-0] % positive and negative zero!
    Y = 2×1
    0 0
    X = [-0.95;-0.95]; % these values are not really relevant
    atan2(Y,X)
    ans = 2×1
    3.1416 -3.1416
    Here is a useful trick to detect if a zero is positive or negative (simply displaying it doesn't work):
    Y % they look the same ... but are they?
    Y = 2×1
    0 0
    sign(1./Y) % no!
    ans = 2×1
    1 -1
    Negative zeros can be generated by some arithmetic operations, or perhaps by converting data from text. If you want to remove negative zeros from an array without changing the sign of the other data, just add zero:
    Z = [-0,-2,+0,3]
    Z = 1×4
    0 -2 0 3
    sign(1./Z)
    ans = 1×4
    -1 -1 1 1
    Z = 0+Z % remove negative zeros
    Z = 1×4
    0 -2 0 3
    sign(1./Z)
    ans = 1×4
    1 -1 1 1
    ** for what it's worth, Octave does display the sign.