diff options
author | rander <rander.wang@intel.com> | 2017-04-10 10:28:56 +0800 |
---|---|---|
committer | Yang Rong <rong.r.yang@intel.com> | 2017-05-04 19:08:31 +0800 |
commit | 1e520be5063ba9d6f64c4aa0a2847d558540dc6a (patch) | |
tree | 094cd4a8d3ebe9be5a7703e2b293ff5cbabb1d47 /backend | |
parent | 8cf4cb179e19584f5a041673e494ceb7b51a24d5 (diff) | |
download | beignet-1e520be5063ba9d6f64c4aa0a2847d558540dc6a.tar.gz |
backend: refine atan2 to pass cft
refine the corner case like inf and +-0 according to spec
Signed-off-by: rander.wang <rander.wang@intel.com>
Tested-by: Yang Rong <rong.r.yang@intel.com>
Diffstat (limited to 'backend')
-rw-r--r-- | backend/src/libocl/tmpl/ocl_math_common.tmpl.cl | 66 |
1 files changed, 29 insertions, 37 deletions
diff --git a/backend/src/libocl/tmpl/ocl_math_common.tmpl.cl b/backend/src/libocl/tmpl/ocl_math_common.tmpl.cl index 8c5d54b4..d9764665 100644 --- a/backend/src/libocl/tmpl/ocl_math_common.tmpl.cl +++ b/backend/src/libocl/tmpl/ocl_math_common.tmpl.cl @@ -311,7 +311,7 @@ OVERLOADABLE double atan(double x) } } -OVERLOADABLE double atan2(double x, double y) +OVERLOADABLE double atan2(double y, double x) { double tiny = 1.0e-300, zero = 0.0, @@ -329,21 +329,9 @@ OVERLOADABLE double atan2(double x, double y) hy = __HI(y); iy = hy&0x7fffffff; ly = __LO(y); if(((ix|((lx|-lx)>>31))>0x7ff00000)|| - ((iy|((ly|-ly)>>31))>0x7ff00000)) /* x or y is NaN */ - return x+y; + ((iy|((ly|-ly)>>31))>0x7ff00000)) /* x or y is NaN */ + return x+y; - if((hx-0x3ff00000|lx)==0) - { - if(iy>=0x44100000) { /* if |x| >= 2^66 */ - if(iy>0x7ff00000 ||(iy==0x7ff00000 && (__LO(y)!=0))) - return y+y; /* NaN */ - if(hy >0) - return pi_o_2; - else - return pi; - } - return atan(y); /* x=1.0 */ - } m = ((hy>>31)&1)|((hx>>30)&2); /* 2*sign(x)+sign(y) */ /* when y = 0 */ @@ -356,29 +344,34 @@ OVERLOADABLE double atan2(double x, double y) } } /* when x = 0 */ - if((ix|lx)==0) return (hx<0)? -pi-tiny: pi+tiny; + if((ix|lx)==0) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny; /* when x is INF */ - if(ix==0x7ff00000) { - if(iy==0x7ff00000) { - switch(m) { - case 0: return pi_o_4+tiny;/* atan(+INF,+INF) */ - case 1: return 3.0*pi_o_4-tiny;/* atan(-INF,+INF) */ - case 2: return 3.0*pi_o_4+tiny;/*atan(+INF,-INF)*/ - case 3: return -3.0*pi_o_4-tiny;/*atan(-INF,-INF)*/ - } - } - else { - switch(m) { - case 0: return zero ; /* atan(+...,+INF) */ - case 1: return pi_o_2; /* atan(-...,+INF) */ - case 2: return pi_o_2+tiny ; /* atan(+...,-INF) */ - case 3: return -pi_o_2-tiny ; /* atan(-...,-INF) */ + if(ix==0x7ff00000) + { + if(iy==0x7ff00000) + { + switch(m) + { + case 0: return pi_o_4+tiny;/* atan(+INF,+INF) */ + case 1: return -pi_o_4-tiny;/* atan(-INF,+INF) */ + case 2: return 3.0*pi_o_4+tiny;/*atan(+INF,-INF)*/ + case 3: return -3.0*pi_o_4-tiny;/*atan(-INF,-INF)*/ + } } + else + { + switch(m) + { + case 0: return zero ; /* atan(+...,+INF) */ + case 1: return -zero; /* atan(-...,+INF) */ + case 2: return pi+tiny ; /* atan(+...,-INF) */ + case 3: return -pi -tiny ; /* atan(-...,-INF) */ + } } } /* when y is INF */ - if(iy==0x7ff00000) return (hx<0)? -pi-tiny: pi+tiny; + if(iy==0x7ff00000) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny; /* compute y/x */ k = (iy-ix)>>20; @@ -387,12 +380,11 @@ OVERLOADABLE double atan2(double x, double y) else z=atan(fabs(y/x)); /* safe to do y/x */ switch (m) { case 0: return z ; /* atan(+,+) */ - case 2: __setHigh(&z, __HI(z) ^ 0x80000000); - return pi_o_2 - z ; /* atan(-,+) */ - case 1: return pi_o_2 + (z-pi_lo);/* atan(+,-) */ + case 1: __setHigh(&z, __HI(z) ^ 0x80000000); + return z ; /* atan(-,+) */ + case 2: return pi-(z-pi_lo);/* atan(+,-) */ default: /* case 3 */ - __setHigh(&z, __HI(z) ^ 0x80000000); - return (z-pi_lo)-pi_o_2;/* atan(-,-) */ + return (z-pi_lo)-pi;/* atan(-,-) */ } } |