s_rintf.c revision 2116
1219820Sjeff/* s_rintf.c -- float version of s_rint.c.
2219820Sjeff * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
3219820Sjeff */
4219820Sjeff
5219820Sjeff/*
6219820Sjeff * ====================================================
7219820Sjeff * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
8219820Sjeff *
9219820Sjeff * Developed at SunPro, a Sun Microsystems, Inc. business.
10219820Sjeff * Permission to use, copy, modify, and distribute this
11219820Sjeff * software is freely granted, provided that this notice
12219820Sjeff * is preserved.
13219820Sjeff * ====================================================
14219820Sjeff */
15219820Sjeff
16219820Sjeff#ifndef lint
17219820Sjeffstatic char rcsid[] = "$Id: s_rintf.c,v 1.2 1994/08/18 23:07:17 jtc Exp $";
18219820Sjeff#endif
19219820Sjeff
20219820Sjeff#include "math.h"
21219820Sjeff#include "math_private.h"
22219820Sjeff
23219820Sjeff#ifdef __STDC__
24219820Sjeffstatic const float
25219820Sjeff#else
26219820Sjeffstatic float
27219820Sjeff#endif
28219820SjeffTWO23[2]={
29219820Sjeff  8.3886080000e+06, /* 0x4b000000 */
30219820Sjeff -8.3886080000e+06, /* 0xcb000000 */
31219820Sjeff};
32219820Sjeff
33219820Sjeff#ifdef __STDC__
34219820Sjeff	float rintf(float x)
35219820Sjeff#else
36219820Sjeff	float rintf(x)
37219820Sjeff	float x;
38219820Sjeff#endif
39219820Sjeff{
40219820Sjeff	int32_t i0,j0,sx;
41219820Sjeff	u_int32_t i,i1;
42219820Sjeff	float w,t;
43219820Sjeff	GET_FLOAT_WORD(i0,x);
44219820Sjeff	sx = (i0>>31)&1;
45219820Sjeff	j0 = ((i0>>23)&0xff)-0x7f;
46219820Sjeff	if(j0<23) {
47219820Sjeff	    if(j0<0) {
48219820Sjeff		if((i0&0x7fffffff)==0) return x;
49219820Sjeff		i1 = (i0&0x07fffff);
50219820Sjeff		i0 &= 0xfff00000;
51219820Sjeff		i0 |= ((i1|-i1)>>9)&0x400000;
52219820Sjeff		SET_FLOAT_WORD(x,i0);
53219820Sjeff	        w = TWO23[sx]+x;
54219820Sjeff	        t =  w-TWO23[sx];
55219820Sjeff		GET_FLOAT_WORD(i0,t);
56219820Sjeff		SET_FLOAT_WORD(t,(i0&0x7fffffff)|(sx<<31));
57219820Sjeff	        return t;
58219820Sjeff	    } else {
59219820Sjeff		i = (0x007fffff)>>j0;
60219820Sjeff		if((i0&i)==0) return x; /* x is integral */
61219820Sjeff		i>>=1;
62219820Sjeff		if((i0&i)!=0) i0 = (i0&(~i))|((0x100000)>>j0);
63219820Sjeff	    }
64219820Sjeff	} else {
65219820Sjeff	    if(j0==0x80) return x+x;	/* inf or NaN */
66219820Sjeff	    else return x;		/* x is integral */
67219820Sjeff	}
68219820Sjeff	SET_FLOAT_WORD(x,i0);
69219820Sjeff	w = TWO23[sx]+x;
70219820Sjeff	return w-TWO23[sx];
71219820Sjeff}
72219820Sjeff