Back to index

glibc  2.9
s_nearbyintf.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 /* Adapted for use as nearbyint by Ulrich Drepper <drepper@cygnus.com>.  */
00005 
00006 /*
00007  * ====================================================
00008  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
00009  *
00010  * Developed at SunPro, a Sun Microsystems, Inc. business.
00011  * Permission to use, copy, modify, and distribute this
00012  * software is freely granted, provided that this notice
00013  * is preserved.
00014  * ====================================================
00015  */
00016 
00017 
00018 #include <fenv.h>
00019 #include "math.h"
00020 #include "math_private.h"
00021 
00022 #ifdef __STDC__
00023 static const float
00024 #else
00025 static float
00026 #endif
00027 TWO23[2]={
00028   8.3886080000e+06, /* 0x4b000000 */
00029  -8.3886080000e+06, /* 0xcb000000 */
00030 };
00031 
00032 #ifdef __STDC__
00033        float __nearbyintf(float x)
00034 #else
00035        float __nearbyintf(x)
00036        float x;
00037 #endif
00038 {
00039        fenv_t env;
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               feholdexcept (&env);
00054                w = TWO23[sx]+x;
00055                t =  w-TWO23[sx];
00056               fesetenv (&env);
00057               GET_FLOAT_WORD(i0,t);
00058               SET_FLOAT_WORD(t,(i0&0x7fffffff)|(sx<<31));
00059                return t;
00060            } else {
00061               i = (0x007fffff)>>j0;
00062               if((i0&i)==0) return x; /* x is integral */
00063               i>>=1;
00064               if((i0&i)!=0) i0 = (i0&(~i))|((0x100000)>>j0);
00065            }
00066        } else {
00067            if(j0==0x80) return x+x;       /* inf or NaN */
00068            else return x;          /* x is integral */
00069        }
00070        SET_FLOAT_WORD(x,i0);
00071        feholdexcept (&env);
00072        w = TWO23[sx]+x;
00073        t = w-TWO23[sx];
00074        fesetenv (&env);
00075        return t;
00076 }
00077 weak_alias (__nearbyintf, nearbyintf)