src/libm/s_atan.c
author Ryan C. Gordon <icculus@icculus.org>
Fri, 12 Aug 2016 19:59:00 -0400
changeset 10266 c09f06c4e8c8
parent 8056 abd9434c5d3e
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:
4873
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
     1
/*
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
     2
 * ====================================================
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
     3
 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
     4
 *
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
     5
 * Developed at SunPro, a Sun Microsystems, Inc. business.
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
     6
 * Permission to use, copy, modify, and distribute this
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
     7
 * software is freely granted, provided that this notice
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
     8
 * is preserved.
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
     9
 * ====================================================
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    10
 */
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    11
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    12
/* atan(x)
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    13
 * Method
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    14
 *   1. Reduce x to positive by atan(x) = -atan(-x).
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    15
 *   2. According to the integer k=4t+0.25 chopped, t=x, the argument
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    16
 *      is further reduced to one of the following intervals and the
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    17
 *      arctangent of t is evaluated by the corresponding formula:
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    18
 *
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    19
 *      [0,7/16]      atan(x) = t-t^3*(a1+t^2*(a2+...(a10+t^2*a11)...)
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    20
 *      [7/16,11/16]  atan(x) = atan(1/2) + atan( (t-0.5)/(1+t/2) )
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    21
 *      [11/16.19/16] atan(x) = atan( 1 ) + atan( (t-1)/(1+t) )
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    22
 *      [19/16,39/16] atan(x) = atan(3/2) + atan( (t-1.5)/(1+1.5t) )
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    23
 *      [39/16,INF]   atan(x) = atan(INF) + atan( -1/t )
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    24
 *
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    25
 * Constants:
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    26
 * The hexadecimal values are the intended ones for the following
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    27
 * constants. The decimal values may be used, provided that the
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    28
 * compiler will convert from decimal to binary accurately enough
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    29
 * to produce the hexadecimal values shown.
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    30
 */
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    31
6044
35448a5ea044 Lots of fixes importing SDL source wholesale into a new iOS project
Sam Lantinga <slouken@libsdl.org>
parents: 4873
diff changeset
    32
#include "math_libm.h"
4873
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    33
#include "math_private.h"
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    34
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    35
static const double atanhi[] = {
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    36
  4.63647609000806093515e-01, /* atan(0.5)hi 0x3FDDAC67, 0x0561BB4F */
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    37
  7.85398163397448278999e-01, /* atan(1.0)hi 0x3FE921FB, 0x54442D18 */
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    38
  9.82793723247329054082e-01, /* atan(1.5)hi 0x3FEF730B, 0xD281F69B */
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    39
  1.57079632679489655800e+00, /* atan(inf)hi 0x3FF921FB, 0x54442D18 */
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    40
};
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    41
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    42
static const double atanlo[] = {
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    43
  2.26987774529616870924e-17, /* atan(0.5)lo 0x3C7A2B7F, 0x222F65E2 */
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    44
  3.06161699786838301793e-17, /* atan(1.0)lo 0x3C81A626, 0x33145C07 */
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    45
  1.39033110312309984516e-17, /* atan(1.5)lo 0x3C700788, 0x7AF0CBBD */
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    46
  6.12323399573676603587e-17, /* atan(inf)lo 0x3C91A626, 0x33145C07 */
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    47
};
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    48
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    49
static const double aT[] = {
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    50
  3.33333333333329318027e-01, /* 0x3FD55555, 0x5555550D */
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    51
 -1.99999999998764832476e-01, /* 0xBFC99999, 0x9998EBC4 */
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    52
  1.42857142725034663711e-01, /* 0x3FC24924, 0x920083FF */
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    53
 -1.11111104054623557880e-01, /* 0xBFBC71C6, 0xFE231671 */
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    54
  9.09088713343650656196e-02, /* 0x3FB745CD, 0xC54C206E */
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    55
 -7.69187620504482999495e-02, /* 0xBFB3B0F2, 0xAF749A6D */
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    56
  6.66107313738753120669e-02, /* 0x3FB10D66, 0xA0D03D51 */
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    57
 -5.83357013379057348645e-02, /* 0xBFADDE2D, 0x52DEFD9A */
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    58
  4.97687799461593236017e-02, /* 0x3FA97B4B, 0x24760DEB */
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    59
 -3.65315727442169155270e-02, /* 0xBFA2B444, 0x2C6A6C2F */
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    60
  1.62858201153657823623e-02, /* 0x3F90AD3A, 0xE322DA11 */
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    61
};
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    62
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    63
static const double
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    64
one   = 1.0,
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    65
huge   = 1.0e300;
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    66
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    67
double atan(double x)
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    68
{
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    69
	double w,s1,s2,z;
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    70
	int32_t ix,hx,id;
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    71
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    72
	GET_HIGH_WORD(hx,x);
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    73
	ix = hx&0x7fffffff;
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    74
	if(ix>=0x44100000) {	/* if |x| >= 2^66 */
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    75
	    u_int32_t low;
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    76
	    GET_LOW_WORD(low,x);
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    77
	    if(ix>0x7ff00000||
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    78
		(ix==0x7ff00000&&(low!=0)))
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    79
		return x+x;		/* NaN */
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    80
	    if(hx>0) return  atanhi[3]+atanlo[3];
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    81
	    else     return -atanhi[3]-atanlo[3];
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    82
	} if (ix < 0x3fdc0000) {	/* |x| < 0.4375 */
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    83
	    if (ix < 0x3e200000) {	/* |x| < 2^-29 */
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    84
		if(huge+x>one) return x;	/* raise inexact */
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    85
	    }
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    86
	    id = -1;
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    87
	} else {
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    88
	x = fabs(x);
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    89
	if (ix < 0x3ff30000) {		/* |x| < 1.1875 */
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    90
	    if (ix < 0x3fe60000) {	/* 7/16 <=|x|<11/16 */
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    91
		id = 0; x = (2.0*x-one)/(2.0+x);
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    92
	    } else {			/* 11/16<=|x|< 19/16 */
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    93
		id = 1; x  = (x-one)/(x+one);
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    94
	    }
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    95
	} else {
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    96
	    if (ix < 0x40038000) {	/* |x| < 2.4375 */
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    97
		id = 2; x  = (x-1.5)/(one+1.5*x);
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    98
	    } else {			/* 2.4375 <= |x| < 2^66 */
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    99
		id = 3; x  = -1.0/x;
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   100
	    }
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   101
	}}
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   102
    /* end of argument reduction */
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   103
	z = x*x;
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   104
	w = z*z;
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   105
    /* break sum from i=0 to 10 aT[i]z**(i+1) into odd and even poly */
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   106
	s1 = z*(aT[0]+w*(aT[2]+w*(aT[4]+w*(aT[6]+w*(aT[8]+w*aT[10])))));
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   107
	s2 = w*(aT[1]+w*(aT[3]+w*(aT[5]+w*(aT[7]+w*aT[9]))));
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   108
	if (id<0) return x - x*(s1+s2);
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   109
	else {
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   110
	    z = atanhi[id] - ((x*(s1+s2) - atanlo[id]) - x);
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   111
	    return (hx<0)? -z:z;
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   112
	}
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   113
}
67ad1c88dda0 Added atan implementation from uClibc
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   114
libm_hidden_def(atan)
8004
13da154af020 Fixed bug 2245 - add SDL_acos and SDL_asin
Sam Lantinga <slouken@libsdl.org>
parents: 6044
diff changeset
   115