Patch for F32's ATan2 Method
Duane Degn
Posts: 10,588
The recent floating point discussion in this thread has got me wondering if the patch I'm using for the ATan2 method in Jonathan's F32 object.
Quoting Heater from the other thread.
Now you tell me. A while back I found a bug in F32's ATan2 method. I added an ugly patch until Jonathan or someone else could apply a proper fix.
I added a few constants which I use in the patch code.
And here's the patched "ATan2" method.
The code I added is in bold. (Kind of like using a crayon to restore a fine art oil painting.)
Do any of you see a problem with this? It appears to work okay but I haven't been very rigorous with my testing.
I often think of this saying when I resort to using floating point math in a project. And yes, sometimes I don't really understand the problem well enough to not use floats.
One of the big reasons I use the Propeller is so I can be lazy. I'm often trying to get some machine to do my work for me. IMO, sometimes lazy is good.
I think it safe to say I don't understand all the subtleties of floating point calculations. Hence this post.
Thanks for all the help so far.
Quoting Heater from the other thread.
WARNING: NEVER COMPARE FLOATS FOR EQUALITY.
Now you tell me. A while back I found a bug in F32's ATan2 method. I added an ugly patch until Jonathan or someone else could apply a proper fix.
I added a few constants which I use in the patch code.
CON ONE_ = 1.0 NEG_ONE = -1.0 ZERO = 0.0 PI_OVER_TWO = pi / 2.0 THREE_PI_OVER_TWO = (3.0 * pi) / 2.0
And here's the patched "ATan2" method.
PUB ATan2(a, b) {{ Arc Tangent of vector a, b (in radians, no division is performed, so b==0 is legal). Parameters: a 32-bit floating point value b 32-bit floating point value Returns: 32-bit floating point value (angle in radians) }} [B] if b == ZERO if a == a & $7FFF_FFFF return PI_OVER_TWO else return THREE_PI_OVER_TWO result := b & $7FFF_FFFF ' absolute value if b == result b := ONE_ else b := NEG_ONE a := FDiv(a, result)[/B] result := cmdATan2 f32_Cmd := @result repeat while f32_Cmd
The code I added is in bold. (Kind of like using a crayon to restore a fine art oil painting.)
Do any of you see a problem with this? It appears to work okay but I haven't been very rigorous with my testing.
My old boss used to say to all new team members on a radar signal processing project "If you think you need floating point maths to solve the problem then you don't understand the problem."
I often think of this saying when I resort to using floating point math in a project. And yes, sometimes I don't really understand the problem well enough to not use floats.
I always though he meant that you can do most things with fixed point arithmetic if you think about it enough and the floating point was just the lazy way out.
One of the big reasons I use the Propeller is so I can be lazy. I'm often trying to get some machine to do my work for me. IMO, sometimes lazy is good.
Thirty years later I realize that his statement has another meaning, if you really do need floating point to solve your problem then you won't understand your problem any more! Reason being that floating point is hard and takes a lot of effort to understand all it's subtleties. As my error above shows:)
I think it safe to say I don't understand all the subtleties of floating point calculations. Hence this post.
Thanks for all the help so far.
Comments
I'm a bit too tired to think about this but without understanding the problem or your solution there are two things that bother me:
1) Is the "if b == ZERO". In the floating point number representation we have two zeros, +0 and -0, which one do you mean? If you mean both, then what?
2) Is that Lonesock was always very quick to fix issues in F32. What does he think?
In post #87 of Lonesock's F32 thread, I mentioned how the ATan2 method returns erroneous results with some numbers. I found the results were correct, if I insured the "b" argument was always one (effectively making it an ATan function).
I'm afraid I probably mean both. I just barely learned in the other thread that floating points have a negative zero.
I used the "if b == ZERO" statement assuming it would be faster than the "Cmp" method. Now I think I may need to use "Cmp" after all.
The value of b will likely be the result of a previous floating point calculation. I don't understand this stuff well enough to know what situations produce a negative zero.
He appears to be busy lately. I'll give the F32 thread a bump and hope he has some time to fix this.
How about "b = -0.0", that should do it.
What about "x = y - z" and now set y and z to 0.0.
What about "x = -2y" and set y = 0.0.
And so on.