sf_rint.c 1.64 KB
Newer Older
Tom Tromey committed
1 2 3 4 5 6 7 8 9 10
/* sf_rint.c -- float version of s_rint.c.
 * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
 */

/*
 * ====================================================
 * 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
Tom Tromey committed
11
 * software is freely granted, provided that this notice
Tom Tromey committed
12 13 14 15 16 17 18 19 20
 * is preserved.
 * ====================================================
 */

#include "fdlibm.h"

#ifdef __STDC__
static const float
#else
Tom Tromey committed
21
static float
Tom Tromey committed
22 23 24 25 26 27 28 29 30 31 32 33 34
#endif
TWO23[2]={
  8.3886080000e+06, /* 0x4b000000 */
 -8.3886080000e+06, /* 0xcb000000 */
};

#ifdef __STDC__
	float rintf(float x)
#else
	float rintf(x)
	float x;
#endif
{
Tom Tromey committed
35 36
	int32_t i0,j0,sx;
	uint32_t i,i1;
Tom Tromey committed
37 38 39 40 41
	float w,t;
	GET_FLOAT_WORD(i0,x);
	sx = (i0>>31)&1;
	j0 = ((i0>>23)&0xff)-0x7f;
	if(j0<23) {
Tom Tromey committed
42
	    if(j0<0) {
Tom Tromey committed
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
		if((i0&0x7fffffff)==0) return x;
		i1 = (i0&0x07fffff);
		i0 &= 0xfff00000;
		i0 |= ((i1|-i1)>>9)&0x400000;
		SET_FLOAT_WORD(x,i0);
	        w = TWO23[sx]+x;
	        t =  w-TWO23[sx];
		GET_FLOAT_WORD(i0,t);
		SET_FLOAT_WORD(t,(i0&0x7fffffff)|(sx<<31));
	        return t;
	    } else {
		i = (0x007fffff)>>j0;
		if((i0&i)==0) return x; /* x is integral */
		i>>=1;
		if((i0&i)!=0) i0 = (i0&(~i))|((0x100000)>>j0);
	    }
	} else {
	    if(j0==0x80) return x+x;	/* inf or NaN */
	    else return x;		/* x is integral */
	}
	SET_FLOAT_WORD(x,i0);
	w = TWO23[sx]+x;
	return w-TWO23[sx];
}

#ifdef _DOUBLE_IS_32BITS

#ifdef __STDC__
	double rint(double x)
#else
	double rint(x)
	double x;
#endif
{
	return (double) rintf((float) x);
}

#endif /* defined(_DOUBLE_IS_32BITS) */