inline half atan2()

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
	}