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