164562Sgshapiro/* e_remainderf.c -- float version of e_remainder.c. 2261363Sgshapiro * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. 364562Sgshapiro */ 464562Sgshapiro 564562Sgshapiro/* 664562Sgshapiro * ==================================================== 764562Sgshapiro * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. 864562Sgshapiro * 964562Sgshapiro * Developed at SunPro, a Sun Microsystems, Inc. business. 1064562Sgshapiro * Permission to use, copy, modify, and distribute this 1164562Sgshapiro * software is freely granted, provided that this notice 12266692Sgshapiro * is preserved. 1364562Sgshapiro * ==================================================== 1464562Sgshapiro */ 1590792Sgshapiro 1690792Sgshapiro#include <sys/cdefs.h> 1764562Sgshapiro__FBSDID("$FreeBSD$"); 1864562Sgshapiro 1990792Sgshapiro#include "math.h" 2090792Sgshapiro#include "math_private.h" 2190792Sgshapiro 2290792Sgshapirostatic const float zero = 0.0; 2390792Sgshapiro 2490792Sgshapiro 2590792Sgshapirofloat 2664562Sgshapiro__ieee754_remainderf(float x, float p) 2790792Sgshapiro{ 2890792Sgshapiro int32_t hx,hp; 2990792Sgshapiro u_int32_t sx; 3090792Sgshapiro float p_half; 3190792Sgshapiro 3290792Sgshapiro GET_FLOAT_WORD(hx,x); 3390792Sgshapiro GET_FLOAT_WORD(hp,p); 3464562Sgshapiro sx = hx&0x80000000; 3590792Sgshapiro hp &= 0x7fffffff; 3690792Sgshapiro hx &= 0x7fffffff; 3790792Sgshapiro 3864562Sgshapiro /* purge off exception values */ 3990792Sgshapiro if(hp==0) return (x*p)/(x*p); /* p = 0 */ 4098121Sgshapiro if((hx>=0x7f800000)|| /* x not finite */ 4190792Sgshapiro ((hp>0x7f800000))) /* p is NaN */ 4290792Sgshapiro return ((long double)x*p)/((long double)x*p); 4390792Sgshapiro 4490792Sgshapiro 4590792Sgshapiro if (hp<=0x7effffff) x = __ieee754_fmodf(x,p+p); /* now x < 2p */ 4690792Sgshapiro if ((hx-hp)==0) return zero*x; 4790792Sgshapiro x = fabsf(x); 4890792Sgshapiro p = fabsf(p); 4990792Sgshapiro if (hp<0x01000000) { 5090792Sgshapiro if(x+x>p) { 5190792Sgshapiro x-=p; 5290792Sgshapiro if(x+x>=p) x -= p; 5390792Sgshapiro } 5490792Sgshapiro } else { 5590792Sgshapiro p_half = (float)0.5*p; 5690792Sgshapiro if(x>p_half) { 5790792Sgshapiro x-=p; 5890792Sgshapiro if(x>=p_half) x -= p; 5990792Sgshapiro } 6090792Sgshapiro } 6190792Sgshapiro GET_FLOAT_WORD(hx,x); 6290792Sgshapiro if ((hx&0x7fffffff)==0) hx = 0; 63 SET_FLOAT_WORD(x,hx^sx); 64 return x; 65} 66