Subversion Repositories Kolibri OS

Rev

Rev 4872 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
4349 Serge 1
/* ef_atan2.c -- float version of e_atan2.c.
2
 * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
3
 */
4
 
5
/*
6
 * ====================================================
7
 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
8
 *
9
 * Developed at SunPro, a Sun Microsystems, Inc. business.
10
 * Permission to use, copy, modify, and distribute this
11
 * software is freely granted, provided that this notice
12
 * is preserved.
13
 * ====================================================
14
 *
15
 */
16
 
17
#include "fdlibm.h"
18
 
19
#ifdef __STDC__
20
static const float
21
#else
22
static float
23
#endif
24
tiny  = 1.0e-30,
25
zero  = 0.0,
26
pi_o_4  = 7.8539818525e-01, /* 0x3f490fdb */
27
pi_o_2  = 1.5707963705e+00, /* 0x3fc90fdb */
28
pi      = 3.1415927410e+00,  /* 0x40490fdb */
29
pi_lo   = -8.7422776573e-08; /* 0xb3bbbd2e */
30
 
31
#ifdef __STDC__
32
	float __ieee754_atan2f(float y, float x)
33
#else
34
	float __ieee754_atan2f(y,x)
35
	float  y,x;
36
#endif
37
{
38
	float z;
39
	__int32_t k,m,hx,hy,ix,iy;
40
 
41
	GET_FLOAT_WORD(hx,x);
42
	ix = hx&0x7fffffff;
43
	GET_FLOAT_WORD(hy,y);
44
	iy = hy&0x7fffffff;
45
	if(FLT_UWORD_IS_NAN(ix)||
46
	   FLT_UWORD_IS_NAN(iy))	/* x or y is NaN */
47
	   return x+y;
48
	if(hx==0x3f800000) return atanf(y);   /* x=1.0 */
49
	m = ((hy>>31)&1)|((hx>>30)&2);	/* 2*sign(x)+sign(y) */
50
 
51
    /* when y = 0 */
52
	if(FLT_UWORD_IS_ZERO(iy)) {
53
	    switch(m) {
54
		case 0:
55
		case 1: return y; 	/* atan(+-0,+anything)=+-0 */
56
		case 2: return  pi+tiny;/* atan(+0,-anything) = pi */
57
		case 3: return -pi-tiny;/* atan(-0,-anything) =-pi */
58
	    }
59
	}
60
    /* when x = 0 */
61
	if(FLT_UWORD_IS_ZERO(ix)) return (hy<0)?  -pi_o_2-tiny: pi_o_2+tiny;
62
 
63
    /* when x is INF */
64
	if(FLT_UWORD_IS_INFINITE(ix)) {
65
	    if(FLT_UWORD_IS_INFINITE(iy)) {
66
		switch(m) {
67
		    case 0: return  pi_o_4+tiny;/* atan(+INF,+INF) */
68
		    case 1: return -pi_o_4-tiny;/* atan(-INF,+INF) */
69
		    case 2: return  (float)3.0*pi_o_4+tiny;/*atan(+INF,-INF)*/
70
		    case 3: return (float)-3.0*pi_o_4-tiny;/*atan(-INF,-INF)*/
71
		}
72
	    } else {
73
		switch(m) {
74
		    case 0: return  zero  ;	/* atan(+...,+INF) */
75
		    case 1: return -zero  ;	/* atan(-...,+INF) */
76
		    case 2: return  pi+tiny  ;	/* atan(+...,-INF) */
77
		    case 3: return -pi-tiny  ;	/* atan(-...,-INF) */
78
		}
79
	    }
80
	}
81
    /* when y is INF */
82
	if(FLT_UWORD_IS_INFINITE(iy)) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny;
83
 
84
    /* compute y/x */
85
	k = (iy-ix)>>23;
86
	if(k > 60) z=pi_o_2+(float)0.5*pi_lo; 	/* |y/x| >  2**60 */
87
	else if(hx<0&&k<-60) z=0.0; 	/* |y|/x < -2**60 */
88
	else z=atanf(fabsf(y/x));	/* safe to do y/x */
89
	switch (m) {
90
	    case 0: return       z  ;	/* atan(+,+) */
91
	    case 1: {
92
	    	      __uint32_t zh;
93
		      GET_FLOAT_WORD(zh,z);
94
		      SET_FLOAT_WORD(z,zh ^ 0x80000000);
95
		    }
96
		    return       z  ;	/* atan(-,+) */
97
	    case 2: return  pi-(z-pi_lo);/* atan(+,-) */
98
	    default: /* case 3 */
99
	    	    return  (z-pi_lo)-pi;/* atan(-,-) */
100
	}
101
}