e_remainderf.c revision 256281
153537Sbrian/* e_remainderf.c -- float version of e_remainder.c.
280728Sbrian * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
353537Sbrian */
453537Sbrian
553537Sbrian/*
653537Sbrian * ====================================================
753537Sbrian * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
853537Sbrian *
953537Sbrian * Developed at SunPro, a Sun Microsystems, Inc. business.
1053537Sbrian * Permission to use, copy, modify, and distribute this
1153537Sbrian * software is freely granted, provided that this notice
1253537Sbrian * is preserved.
1353537Sbrian * ====================================================
1453537Sbrian */
1553537Sbrian
1653537Sbrian#include <sys/cdefs.h>
1753537Sbrian__FBSDID("$FreeBSD: stable/10/lib/msun/src/e_remainderf.c 176207 2008-02-12 17:11:36Z bde $");
1853537Sbrian
1953537Sbrian#include "math.h"
2053537Sbrian#include "math_private.h"
2153537Sbrian
2253537Sbrianstatic const float zero = 0.0;
2353537Sbrian
2453537Sbrian
2553537Sbrianfloat
2653537Sbrian__ieee754_remainderf(float x, float p)
2753537Sbrian{
2853537Sbrian	int32_t hx,hp;
2953537Sbrian	u_int32_t sx;
3053537Sbrian	float p_half;
3153537Sbrian
3253537Sbrian	GET_FLOAT_WORD(hx,x);
3353537Sbrian	GET_FLOAT_WORD(hp,p);
3453537Sbrian	sx = hx&0x80000000;
3553537Sbrian	hp &= 0x7fffffff;
3653537Sbrian	hx &= 0x7fffffff;
3753537Sbrian
3853537Sbrian    /* purge off exception values */
3953537Sbrian	if(hp==0) return (x*p)/(x*p);	 	/* p = 0 */
4053537Sbrian	if((hx>=0x7f800000)||			/* x not finite */
4153537Sbrian	  ((hp>0x7f800000)))			/* p is NaN */
4253537Sbrian	    return ((long double)x*p)/((long double)x*p);
4353537Sbrian
4453537Sbrian
4553537Sbrian	if (hp<=0x7effffff) x = __ieee754_fmodf(x,p+p);	/* now x < 2p */
4653537Sbrian	if ((hx-hp)==0) return zero*x;
4753537Sbrian	x  = fabsf(x);
4866602Sbrian	p  = fabsf(p);
4953537Sbrian	if (hp<0x01000000) {
5053537Sbrian	    if(x+x>p) {
5153537Sbrian		x-=p;
5253537Sbrian		if(x+x>=p) x -= p;
5353537Sbrian	    }
5453537Sbrian	} else {
5553537Sbrian	    p_half = (float)0.5*p;
5653537Sbrian	    if(x>p_half) {
5753537Sbrian		x-=p;
5853537Sbrian		if(x>=p_half) x -= p;
5953537Sbrian	    }
6053537Sbrian	}
6153537Sbrian	GET_FLOAT_WORD(hx,x);
6253537Sbrian	if ((hx&0x7fffffff)==0) hx = 0;
6353537Sbrian	SET_FLOAT_WORD(x,hx^sx);
6486705Sbrian	return x;
6586705Sbrian}
6653537Sbrian