src/libm/e_atan2.c
author Ryan C. Gordon <icculus@icculus.org>
Fri, 12 Aug 2016 19:59:00 -0400
changeset 10266 c09f06c4e8c8
parent 7678 286c42d7c5ed
permissions -rw-r--r--
emscripten: send fake mouse events for touches, like other targets do. (This really should be handled at the higher level and not in the individual targets, but this fixes the immediate bug.)
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
4870
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
     1
/*
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
     2
 * ====================================================
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
     3
 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
     4
 *
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
     5
 * Developed at SunPro, a Sun Microsystems, Inc. business.
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
     6
 * Permission to use, copy, modify, and distribute this
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
     7
 * software is freely granted, provided that this notice
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
     8
 * is preserved.
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
     9
 * ====================================================
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    10
 */
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    11
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    12
/* __ieee754_atan2(y,x)
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    13
 * Method :
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    14
 *	1. Reduce y to positive by atan2(y,x)=-atan2(-y,x).
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    15
 *	2. Reduce x to positive by (if x and y are unexceptional):
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    16
 *		ARG (x+iy) = arctan(y/x)   	   ... if x > 0,
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    17
 *		ARG (x+iy) = pi - arctan[y/(-x)]   ... if x < 0,
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    18
 *
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    19
 * Special cases:
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    20
 *
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    21
 *	ATAN2((anything), NaN ) is NaN;
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    22
 *	ATAN2(NAN , (anything) ) is NaN;
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    23
 *	ATAN2(+-0, +(anything but NaN)) is +-0  ;
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    24
 *	ATAN2(+-0, -(anything but NaN)) is +-pi ;
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    25
 *	ATAN2(+-(anything but 0 and NaN), 0) is +-pi/2;
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    26
 *	ATAN2(+-(anything but INF and NaN), +INF) is +-0 ;
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    27
 *	ATAN2(+-(anything but INF and NaN), -INF) is +-pi;
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    28
 *	ATAN2(+-INF,+INF ) is +-pi/4 ;
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    29
 *	ATAN2(+-INF,-INF ) is +-3pi/4;
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    30
 *	ATAN2(+-INF, (anything but,0,NaN, and INF)) is +-pi/2;
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    31
 *
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    32
 * Constants:
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    33
 * The hexadecimal values are the intended ones for the following
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    34
 * constants. The decimal values may be used, provided that the
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    35
 * compiler will convert from decimal to binary accurately enough
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    36
 * to produce the hexadecimal values shown.
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    37
 */
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    38
6044
35448a5ea044 Lots of fixes importing SDL source wholesale into a new iOS project
Sam Lantinga <slouken@libsdl.org>
parents: 4874
diff changeset
    39
#include "math_libm.h"
4870
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    40
#include "math_private.h"
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    41
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    42
static const double
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    43
tiny  = 1.0e-300,
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    44
zero  = 0.0,
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    45
pi_o_4  = 7.8539816339744827900E-01, /* 0x3FE921FB, 0x54442D18 */
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    46
pi_o_2  = 1.5707963267948965580E+00, /* 0x3FF921FB, 0x54442D18 */
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    47
pi      = 3.1415926535897931160E+00, /* 0x400921FB, 0x54442D18 */
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    48
pi_lo   = 1.2246467991473531772E-16; /* 0x3CA1A626, 0x33145C07 */
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    49
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    50
double attribute_hidden __ieee754_atan2(double y, double x)
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    51
{
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    52
	double z;
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    53
	int32_t k,m,hx,hy,ix,iy;
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    54
	u_int32_t lx,ly;
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    55
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    56
	EXTRACT_WORDS(hx,lx,x);
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    57
	ix = hx&0x7fffffff;
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    58
	EXTRACT_WORDS(hy,ly,y);
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    59
	iy = hy&0x7fffffff;
4874
8288636b861d Compiling in atan()/atan2() implementation on Visual Studio 2008.
Sam Lantinga <slouken@libsdl.org>
parents: 4870
diff changeset
    60
	if(((ix|((lx|-(int32_t)lx)>>31))>0x7ff00000)||
8288636b861d Compiling in atan()/atan2() implementation on Visual Studio 2008.
Sam Lantinga <slouken@libsdl.org>
parents: 4870
diff changeset
    61
	   ((iy|((ly|-(int32_t)ly)>>31))>0x7ff00000))	/* x or y is NaN */
4870
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    62
	   return x+y;
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    63
	if(((hx-0x3ff00000)|lx)==0) return atan(y);   /* x=1.0 */
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    64
	m = ((hy>>31)&1)|((hx>>30)&2);	/* 2*sign(x)+sign(y) */
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    65
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    66
    /* when y = 0 */
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    67
	if((iy|ly)==0) {
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    68
	    switch(m) {
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    69
		case 0:
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    70
		case 1: return y; 	/* atan(+-0,+anything)=+-0 */
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    71
		case 2: return  pi+tiny;/* atan(+0,-anything) = pi */
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    72
		case 3: return -pi-tiny;/* atan(-0,-anything) =-pi */
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    73
	    }
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    74
	}
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    75
    /* when x = 0 */
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    76
	if((ix|lx)==0) return (hy<0)?  -pi_o_2-tiny: pi_o_2+tiny;
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    77
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    78
    /* when x is INF */
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    79
	if(ix==0x7ff00000) {
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    80
	    if(iy==0x7ff00000) {
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    81
		switch(m) {
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    82
		    case 0: return  pi_o_4+tiny;/* atan(+INF,+INF) */
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    83
		    case 1: return -pi_o_4-tiny;/* atan(-INF,+INF) */
7678
286c42d7c5ed OCD fixes: Adds a space after /* (glory to regular expressions!)
Gabriel Jacobo <gabomdq@gmail.com>
parents: 7677
diff changeset
    84
		    case 2: return  3.0*pi_o_4+tiny;/* atan(+INF,-INF) */
286c42d7c5ed OCD fixes: Adds a space after /* (glory to regular expressions!)
Gabriel Jacobo <gabomdq@gmail.com>
parents: 7677
diff changeset
    85
		    case 3: return -3.0*pi_o_4-tiny;/* atan(-INF,-INF) */
4870
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    86
		}
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    87
	    } else {
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    88
		switch(m) {
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    89
		    case 0: return  zero  ;	/* atan(+...,+INF) */
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    90
		    case 1: return -zero  ;	/* atan(-...,+INF) */
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    91
		    case 2: return  pi+tiny  ;	/* atan(+...,-INF) */
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    92
		    case 3: return -pi-tiny  ;	/* atan(-...,-INF) */
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    93
		}
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    94
	    }
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    95
	}
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    96
    /* when y is INF */
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    97
	if(iy==0x7ff00000) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny;
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    98
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    99
    /* compute y/x */
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   100
	k = (iy-ix)>>20;
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   101
	if(k > 60) z=pi_o_2+0.5*pi_lo; 	/* |y/x| >  2**60 */
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   102
	else if(hx<0&&k<-60) z=0.0; 	/* |y|/x < -2**60 */
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   103
	else z=atan(fabs(y/x));		/* safe to do y/x */
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   104
	switch (m) {
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   105
	    case 0: return       z  ;	/* atan(+,+) */
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   106
	    case 1: {
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   107
	    	      u_int32_t zh;
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   108
		      GET_HIGH_WORD(zh,z);
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   109
		      SET_HIGH_WORD(z,zh ^ 0x80000000);
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   110
		    }
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   111
		    return       z  ;	/* atan(-,+) */
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   112
	    case 2: return  pi-(z-pi_lo);/* atan(+,-) */
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   113
	    default: /* case 3 */
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   114
	    	    return  (z-pi_lo)-pi;/* atan(-,-) */
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   115
	}
d275c95ddc05 Added atan2 implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   116
}