Back to index

glibc  2.9
s_rintf.c
Go to the documentation of this file.
00001 /* s_rintf.c -- float version of s_rint.c.
00002  * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
00003  */
00004 
00005 /*
00006  * ====================================================
00007  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
00008  *
00009  * Developed at SunPro, a Sun Microsystems, Inc. business.
00010  * Permission to use, copy, modify, and distribute this
00011  * software is freely granted, provided that this notice 
00012  * is preserved.
00013  * ====================================================
00014  */
00015 
00016 #if defined(LIBM_SCCS) && !defined(lint)
00017 static char rcsid[] = "$NetBSD: s_rintf.c,v 1.4 1995/05/10 20:48:06 jtc Exp $";
00018 #endif
00019 
00020 #include "math.h"
00021 #include "math_private.h"
00022 
00023 #ifdef __STDC__
00024 static const float
00025 #else
00026 static float 
00027 #endif
00028 TWO23[2]={
00029   8.3886080000e+06, /* 0x4b000000 */
00030  -8.3886080000e+06, /* 0xcb000000 */
00031 };
00032 
00033 #ifdef __STDC__
00034        float __rintf(float x)
00035 #else
00036        float __rintf(x)
00037        float x;
00038 #endif
00039 {
00040        int32_t i0,j0,sx;
00041        u_int32_t i,i1;
00042        float w,t;
00043        GET_FLOAT_WORD(i0,x);
00044        sx = (i0>>31)&1;
00045        j0 = ((i0>>23)&0xff)-0x7f;
00046        if(j0<23) {
00047            if(j0<0) {       
00048               if((i0&0x7fffffff)==0) return x;
00049               i1 = (i0&0x07fffff);
00050               i0 &= 0xfff00000;
00051               i0 |= ((i1|-i1)>>9)&0x400000;
00052               SET_FLOAT_WORD(x,i0);
00053                w = TWO23[sx]+x;
00054                t =  w-TWO23[sx];
00055               GET_FLOAT_WORD(i0,t);
00056               SET_FLOAT_WORD(t,(i0&0x7fffffff)|(sx<<31));
00057                return t;
00058            } else {
00059               i = (0x007fffff)>>j0;
00060               if((i0&i)==0) return x; /* x is integral */
00061               i>>=1;
00062               if((i0&i)!=0) i0 = (i0&(~i))|((0x100000)>>j0);
00063            }
00064        } else {
00065            if(j0==0x80) return x+x;       /* inf or NaN */
00066            else return x;          /* x is integral */
00067        }
00068        SET_FLOAT_WORD(x,i0);
00069        w = TWO23[sx]+x;
00070        return w-TWO23[sx];
00071 }
00072 weak_alias (__rintf, rintf)