in include/half.hpp [3712:3752]
inline half atan2(half y, half x)
{
#ifdef HALF_ARITHMETIC_TYPE
return half(detail::binary, detail::float2half<half::round_style>(std::atan2(detail::half2float<detail::internal_t>(y.data_), detail::half2float<detail::internal_t>(x.data_))));
#else
unsigned int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, signx = x.data_ >> 15, signy = y.data_ & 0x8000;
if(absx >= 0x7C00 || absy >= 0x7C00)
{
if(absx > 0x7C00 || absy > 0x7C00)
return half(detail::binary, detail::signal(x.data_, y.data_));
if(absy == 0x7C00)
return half(detail::binary, (absx<0x7C00) ? detail::rounded<half::round_style,true>(signy|0x3E48, 0, 1) :
signx ? detail::rounded<half::round_style,true>(signy|0x40B6, 0, 1) :
detail::rounded<half::round_style,true>(signy|0x3A48, 0, 1));
return (x.data_==0x7C00) ? half(detail::binary, signy) : half(detail::binary, detail::rounded<half::round_style,true>(signy|0x4248, 0, 1));
}
if(!absy)
return signx ? half(detail::binary, detail::rounded<half::round_style,true>(signy|0x4248, 0, 1)) : y;
if(!absx)
return half(detail::binary, detail::rounded<half::round_style,true>(signy|0x3E48, 0, 1));
int d = (absy>>10) + (absy<=0x3FF) - (absx>>10) - (absx<=0x3FF);
if(d > (signx ? 18 : 12))
return half(detail::binary, detail::rounded<half::round_style,true>(signy|0x3E48, 0, 1));
if(signx && d < -11)
return half(detail::binary, detail::rounded<half::round_style,true>(signy|0x4248, 0, 1));
if(!signx && d < ((half::round_style==std::round_toward_zero) ? -15 : -9))
{
for(; absy<0x400; absy<<=1,--d) ;
detail::uint32 mx = ((absx<<1)&0x7FF) | 0x800, my = ((absy<<1)&0x7FF) | 0x800;
int i = my < mx;
d -= i;
if(d < -25)
return half(detail::binary, detail::underflow<half::round_style>(signy));
my <<= 11 + i;
return half(detail::binary, detail::fixed2half<half::round_style,11,false,false,true>(my/mx, d+14, signy, my%mx!=0));
}
detail::uint32 m = detail::atan2( ((absy&0x3FF)|((absy>0x3FF)<<10))<<(19+((d<0) ? d : (d>0) ? 0 : -1)),
((absx&0x3FF)|((absx>0x3FF)<<10))<<(19-((d>0) ? d : (d<0) ? 0 : 1)));
return half(detail::binary, detail::fixed2half<half::round_style,31,false,true,true>(signx ? (0xC90FDAA2-m) : m, 15, signy, signx));
#endif
}