Update.
[glibc.git] / sysdeps / libm-ieee754 / s_nearbyintf.c
blob7d6f262f51efcb912a9cab2fe55452dba02c5bbc
1 /* s_rintf.c -- float version of s_rint.c.
2 * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
3 */
4 /* Adapted for use as nearbyint by Ulrich Drepper <drepper@cygnus.com>. */
6 /*
7 * ====================================================
8 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
10 * Developed at SunPro, a Sun Microsystems, Inc. business.
11 * Permission to use, copy, modify, and distribute this
12 * software is freely granted, provided that this notice
13 * is preserved.
14 * ====================================================
18 #include <fenv.h>
19 #include "math.h"
20 #include "math_private.h"
22 #ifdef __STDC__
23 static const float
24 #else
25 static float
26 #endif
27 TWO23[2]={
28 8.3886080000e+06, /* 0x4b000000 */
29 -8.3886080000e+06, /* 0xcb000000 */
32 #ifdef __STDC__
33 float __nearbyintf(float x)
34 #else
35 float __nearbyintf(x)
36 float x;
37 #endif
39 fenv_t env;
40 int32_t i0,j0,sx;
41 u_int32_t i,i1;
42 float w,t;
43 GET_FLOAT_WORD(i0,x);
44 sx = (i0>>31)&1;
45 j0 = ((i0>>23)&0xff)-0x7f;
46 if(j0<23) {
47 if(j0<0) {
48 if((i0&0x7fffffff)==0) return x;
49 i1 = (i0&0x07fffff);
50 i0 &= 0xfff00000;
51 i0 |= ((i1|-i1)>>9)&0x400000;
52 SET_FLOAT_WORD(x,i0);
53 feholdexcept (&env);
54 w = TWO23[sx]+x;
55 t = w-TWO23[sx];
56 fesetenv (&env);
57 GET_FLOAT_WORD(i0,t);
58 SET_FLOAT_WORD(t,(i0&0x7fffffff)|(sx<<31));
59 return t;
60 } else {
61 i = (0x007fffff)>>j0;
62 if((i0&i)==0) return x; /* x is integral */
63 i>>=1;
64 if((i0&i)!=0) i0 = (i0&(~i))|((0x100000)>>j0);
66 } else {
67 if(j0==0x80) return x+x; /* inf or NaN */
68 else return x; /* x is integral */
70 SET_FLOAT_WORD(x,i0);
71 feholdexcept (&env);
72 w = TWO23[sx]+x;
73 t = w-TWO23[sx];
74 fesetenv (&env);
75 return t;
77 weak_alias (__nearbyintf, nearbyintf)