template unsigned int mod()

in include/half.hpp [1409:1473]


		template<bool Q,bool R> unsigned int mod(unsigned int x, unsigned int y, int *quo = NULL)
		{
			unsigned int q = 0;
			if(x > y)
			{
				int absx = x, absy = y, expx = 0, expy = 0;
				for(; absx<0x400; absx<<=1,--expx) ;
				for(; absy<0x400; absy<<=1,--expy) ;
				expx += absx >> 10;
				expy += absy >> 10;
				int mx = (absx&0x3FF) | 0x400, my = (absy&0x3FF) | 0x400;
				for(int d=expx-expy; d; --d)
				{
					if(!Q && mx == my)
						return 0;
					if(mx >= my)
					{
						mx -= my;
						q += Q;
					}
					mx <<= 1;
					q <<= static_cast<int>(Q);
				}
				if(!Q && mx == my)
					return 0;
				if(mx >= my)
				{
					mx -= my;
					++q;
				}
				if(Q)
				{
					q &= (1<<(std::numeric_limits<int>::digits-1)) - 1;
					if(!mx)
						return *quo = q, 0;
				}
				for(; mx<0x400; mx<<=1,--expy) ;
				x = (expy>0) ? ((expy<<10)|(mx&0x3FF)) : (mx>>(1-expy));
			}
			if(R)
			{
				unsigned int a, b;
				if(y < 0x800)
				{
					a = (x<0x400) ? (x<<1) : (x+0x400);
					b = y;
				}
				else
				{
					a = x;
					b = y - 0x400;
				}
				if(a > b || (a == b && (q&1)))
				{
					int exp = (y>>10) + (y<=0x3FF), d = exp - (x>>10) - (x<=0x3FF);
					int m = (((y&0x3FF)|((y>0x3FF)<<10))<<1) - (((x&0x3FF)|((x>0x3FF)<<10))<<(1-d));
					for(; m<0x800 && exp>1; m<<=1,--exp) ;
					x = 0x8000 + ((exp-1)<<10) + (m>>1);
					q += Q;
				}
			}
			if(Q)
				*quo = q;
			return x;
		}