e_remainderf.c revision 2116
12116Sjkh/* e_remainderf.c -- float version of e_remainder.c.
22116Sjkh * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
32116Sjkh */
42116Sjkh
52116Sjkh/*
62116Sjkh * ====================================================
72116Sjkh * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
82116Sjkh *
92116Sjkh * Developed at SunPro, a Sun Microsystems, Inc. business.
102116Sjkh * Permission to use, copy, modify, and distribute this
112116Sjkh * software is freely granted, provided that this notice
122116Sjkh * is preserved.
132116Sjkh * ====================================================
142116Sjkh */
152116Sjkh
162116Sjkh#ifndef lint
172116Sjkhstatic char rcsid[] = "$Id: e_remainderf.c,v 1.2 1994/08/18 23:06:02 jtc Exp $";
182116Sjkh#endif
192116Sjkh
202116Sjkh#include "math.h"
212116Sjkh#include "math_private.h"
222116Sjkh
232116Sjkh#ifdef __STDC__
242116Sjkhstatic const float zero = 0.0;
252116Sjkh#else
262116Sjkhstatic float zero = 0.0;
272116Sjkh#endif
282116Sjkh
292116Sjkh
302116Sjkh#ifdef __STDC__
312116Sjkh	float __ieee754_remainderf(float x, float p)
322116Sjkh#else
332116Sjkh	float __ieee754_remainderf(x,p)
342116Sjkh	float x,p;
352116Sjkh#endif
362116Sjkh{
372116Sjkh	int32_t hx,hp;
382116Sjkh	u_int32_t sx;
392116Sjkh	float p_half;
402116Sjkh
412116Sjkh	GET_FLOAT_WORD(hx,x);
422116Sjkh	GET_FLOAT_WORD(hp,p);
432116Sjkh	sx = hx&0x80000000;
442116Sjkh	hp &= 0x7fffffff;
452116Sjkh	hx &= 0x7fffffff;
462116Sjkh
472116Sjkh    /* purge off exception values */
482116Sjkh	if(hp==0) return (x*p)/(x*p);	 	/* p = 0 */
492116Sjkh	if((hx>=0x7f800000)||			/* x not finite */
502116Sjkh	  ((hp>0x7f800000)))			/* p is NaN */
512116Sjkh	    return (x*p)/(x*p);
522116Sjkh
532116Sjkh
542116Sjkh	if (hp<=0x7effffff) x = __ieee754_fmodf(x,p+p);	/* now x < 2p */
552116Sjkh	if ((hx-hp)==0) return zero*x;
562116Sjkh	x  = fabsf(x);
572116Sjkh	p  = fabsf(p);
582116Sjkh	if (hp<0x01000000) {
592116Sjkh	    if(x+x>p) {
602116Sjkh		x-=p;
612116Sjkh		if(x+x>=p) x -= p;
622116Sjkh	    }
632116Sjkh	} else {
642116Sjkh	    p_half = (float)0.5*p;
652116Sjkh	    if(x>p_half) {
662116Sjkh		x-=p;
672116Sjkh		if(x>=p_half) x -= p;
682116Sjkh	    }
692116Sjkh	}
702116Sjkh	GET_FLOAT_WORD(hx,x);
712116Sjkh	SET_FLOAT_WORD(x,hx^sx);
722116Sjkh	return x;
732116Sjkh}
74