inline half hypot()

in include/half.hpp [3336:3390]


	inline half hypot(half x, half y, half z)
	{
	#ifdef HALF_ARITHMETIC_TYPE
		detail::internal_t fx = detail::half2float<detail::internal_t>(x.data_), fy = detail::half2float<detail::internal_t>(y.data_), fz = detail::half2float<detail::internal_t>(z.data_);
		return half(detail::binary, detail::float2half<half::round_style>(std::sqrt(fx*fx+fy*fy+fz*fz)));
	#else
		int absx = x.data_ & 0x7FFF, absy = y.data_ & 0x7FFF, absz = z.data_ & 0x7FFF, expx = 0, expy = 0, expz = 0;
		if(!absx)
			return hypot(y, z);
		if(!absy)
			return hypot(x, z);
		if(!absz)
			return hypot(x, y);
		if(absx >= 0x7C00 || absy >= 0x7C00 || absz >= 0x7C00)
			return half(detail::binary,	(absx==0x7C00) ? detail::select(0x7C00, detail::select(y.data_, z.data_)) :
										(absy==0x7C00) ? detail::select(0x7C00, detail::select(x.data_, z.data_)) :
										(absz==0x7C00) ? detail::select(0x7C00, detail::select(x.data_, y.data_)) :
										detail::signal(x.data_, y.data_, z.data_));
		if(absz > absy)
			std::swap(absy, absz);
		if(absy > absx)
			std::swap(absx, absy);
		if(absz > absy)
			std::swap(absy, absz);
		for(; absx<0x400; absx<<=1,--expx) ;
		for(; absy<0x400; absy<<=1,--expy) ;
		for(; absz<0x400; absz<<=1,--expz) ;
		detail::uint32 mx = (absx&0x3FF) | 0x400, my = (absy&0x3FF) | 0x400, mz = (absz&0x3FF) | 0x400;
		mx *= mx;
		my *= my;
		mz *= mz;
		int ix = mx >> 21, iy = my >> 21, iz = mz >> 21;
		expx = 2*(expx+(absx>>10)) - 15 + ix;
		expy = 2*(expy+(absy>>10)) - 15 + iy;
		expz = 2*(expz+(absz>>10)) - 15 + iz;
		mx <<= 10 - ix;
		my <<= 10 - iy;
		mz <<= 10 - iz;
		int d = expy - expz;
		mz = (d<30) ? ((mz>>d)|((mz&((static_cast<detail::uint32>(1)<<d)-1))!=0)) : 1;
		my += mz;
		if(my & 0x80000000)
		{
			my = (my>>1) | (my&1);
			if(++expy > expx)
			{
				std::swap(mx, my);
				std::swap(expx, expy);
			}
		}
		d = expx - expy;
		my = (d<30) ? ((my>>d)|((my&((static_cast<detail::uint32>(1)<<d)-1))!=0)) : 1;
		return half(detail::binary, detail::hypot_post<half::round_style>(mx+my, expx));
	#endif
	}