Strange result with math.atan2()

Serge Orlov Serge.Orlov at gmail.com
Tue May 2 10:45:13 EDT 2006


Vedran Furac wrote:
> Ben Caradoc-Davies wrote:
> > Vedran Furac wrote:
> >> I think that this results must be the same:
> >> In [3]: math.atan2(-0.0,-1)
> >> Out[3]: -3.1415926535897931
> >> In [4]: math.atan2(-0,-1)
> >> Out[4]: 3.1415926535897931
> >
> > -0 is converted to 0, then to 0.0 for calculation, losing the sign. You
> > might as well write 0.0 instead of -0
> >
> > The behaviour of atan2 conforms to the ISO C99 standard (Python is
> > implemented in C). Changing the sign of the first argument changes the
> > sign of the output, with no special treatment for zero.
> >
> > http://www.ugcs.caltech.edu/manuals/libs/mpfr-2.2.0/mpfr_22.html
>
> Well, here I can read:
>
> Special values are currently handled as described in the ISO C99 standard
> for the atan2 function (note this may change in future versions):
>
>         * atan2(+0, -0) returns +Pi.
>         * atan2(-0, -0) returns -Pi. /* wrong too */
>         * atan2(+0, +0) returns +0.
>         * atan2(-0, +0) returns -0. /* wrong too */
>         * atan2(+0, x) returns +Pi for x < 0.
>         * atan2(-0, x) returns -Pi for x < 0
> 		^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>
> And the formula (also from that site):
> 	if x < 0, atan2(y, x) = sign(y)*(PI - atan (abs(y/x)))
> 				^^^^^^^
>
> So, you can convert -0 to 0, but you must multiply the result with sign of
> y, which is '-' (minus).

But you miss the fact that 0 is an *integer*, not a float, and -0
doesn't exist.
Use this code until you stop passing integers to atan2:

from math import atan2 as math_atan2
def atan2(y, x):
    if (isinstance(y, int) and y == 0) or (
        isinstance(x, int) and x == 0):
        raise ValueError("Argument that is an integer zero can \
produce wrong results")
    return math_atan2(y, x)

print atan2(-0.0, -0.0)
print atan2(-0, -0)




More information about the Python-list mailing list