| /* e_fmodl.c -- long double version of e_fmod.c. | 
 |  * Conversion to IEEE quad long double by Jakub Jelinek, jj@ultra.linux.cz. | 
 |  */ | 
 | /* | 
 |  * ==================================================== | 
 |  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. | 
 |  * | 
 |  * Developed at SunPro, a Sun Microsystems, Inc. business. | 
 |  * Permission to use, copy, modify, and distribute this | 
 |  * software is freely granted, provided that this notice | 
 |  * is preserved. | 
 |  * ==================================================== | 
 |  */ | 
 |  | 
 | /* remainderq(x,p) | 
 |  * Return : | 
 |  *	returns  x REM p  =  x - [x/p]*p as if in infinite | 
 |  *	precise arithmetic, where [x/p] is the (infinite bit) | 
 |  *	integer nearest x/p (in half way case choose the even one). | 
 |  * Method : | 
 |  *	Based on fmodl() return x-[x/p]chopped*p exactlp. | 
 |  */ | 
 |  | 
 | #include "quadmath-imp.h" | 
 |  | 
 | static const __float128 zero = 0; | 
 |  | 
 |  | 
 | __float128 | 
 | remainderq(__float128 x, __float128 p) | 
 | { | 
 | 	int64_t hx,hp; | 
 | 	uint64_t sx,lx,lp; | 
 | 	__float128 p_half; | 
 |  | 
 | 	GET_FLT128_WORDS64(hx,lx,x); | 
 | 	GET_FLT128_WORDS64(hp,lp,p); | 
 | 	sx = hx&0x8000000000000000ULL; | 
 | 	hp &= 0x7fffffffffffffffLL; | 
 | 	hx &= 0x7fffffffffffffffLL; | 
 |  | 
 |     /* purge off exception values */ | 
 | 	if((hp|lp)==0) return (x*p)/(x*p);	/* p = 0 */ | 
 | 	if((hx>=0x7fff000000000000LL)||			/* x not finite */ | 
 | 	  ((hp>=0x7fff000000000000LL)&&			/* p is NaN */ | 
 | 	  (((hp-0x7fff000000000000LL)|lp)!=0))) | 
 | 	    return (x*p)/(x*p); | 
 |  | 
 |  | 
 | 	if (hp<=0x7ffdffffffffffffLL) x = fmodq(x,p+p);	/* now x < 2p */ | 
 | 	if (((hx-hp)|(lx-lp))==0) return zero*x; | 
 | 	x  = fabsq(x); | 
 | 	p  = fabsq(p); | 
 | 	if (hp<0x0002000000000000LL) { | 
 | 	    if(x+x>p) { | 
 | 		x-=p; | 
 | 		if(x+x>=p) x -= p; | 
 | 	    } | 
 | 	} else { | 
 | 	    p_half = 0.5Q*p; | 
 | 	    if(x>p_half) { | 
 | 		x-=p; | 
 | 		if(x>=p_half) x -= p; | 
 | 	    } | 
 | 	} | 
 | 	GET_FLT128_MSW64(hx,x); | 
 | 	SET_FLT128_MSW64(x,hx^sx); | 
 | 	return x; | 
 | } |