OSDN Git Service

mips/sysdep.h: Unify mips sysdep.h
[uclinux-h8/uClibc.git] / libm / s_rint.c
1 /*
2  * ====================================================
3  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
4  *
5  * Developed at SunPro, a Sun Microsystems, Inc. business.
6  * Permission to use, copy, modify, and distribute this
7  * software is freely granted, provided that this notice
8  * is preserved.
9  * ====================================================
10  */
11
12 /*
13  * rint(x)
14  * Return x rounded to integral value according to the prevailing
15  * rounding mode.
16  * Method:
17  *      Using floating addition.
18  * Exception:
19  *      Inexact flag raised if x not equal to rint(x).
20  */
21
22 #include "math.h"
23 #include "math_private.h"
24
25 static const double
26 TWO52[2]={
27   4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */
28  -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */
29 };
30
31 double rint(double x)
32 {
33         int32_t i0,j0,sx;
34         u_int32_t i,i1;
35         double w,t;
36         EXTRACT_WORDS(i0,i1,x);
37         sx = (i0>>31)&1;
38         j0 = ((i0>>20)&0x7ff)-0x3ff;
39         if(j0<20) {
40             if(j0<0) {
41                 if(((i0&0x7fffffff)|i1)==0) return x;
42                 i1 |= (i0&0x0fffff);
43                 i0 &= 0xfffe0000;
44                 i0 |= ((i1|-i1)>>12)&0x80000;
45                 SET_HIGH_WORD(x,i0);
46                 w = TWO52[sx]+x;
47                 t =  w-TWO52[sx];
48                 GET_HIGH_WORD(i0,t);
49                 SET_HIGH_WORD(t,(i0&0x7fffffff)|(sx<<31));
50                 return t;
51             } else {
52                 i = (0x000fffff)>>j0;
53                 if(((i0&i)|i1)==0) return x; /* x is integral */
54                 i>>=1;
55                 if(((i0&i)|i1)!=0) {
56                     if(j0==19) i1 = 0x40000000; else
57                     i0 = (i0&(~i))|((0x20000)>>j0);
58                 }
59             }
60         } else if (j0>51) {
61             if(j0==0x400) return x+x;   /* inf or NaN */
62             else return x;              /* x is integral */
63         } else {
64             i = ((u_int32_t)(0xffffffff))>>(j0-20);
65             if((i1&i)==0) return x;     /* x is integral */
66             i>>=1;
67             if((i1&i)!=0) i1 = (i1&(~i))|((0x40000000)>>(j0-20));
68         }
69         INSERT_WORDS(x,i0,i1);
70         w = TWO52[sx]+x;
71         return w-TWO52[sx];
72 }
73 libm_hidden_def(rint)
74
75 strong_alias(rint, nearbyint)
76 libm_hidden_def(nearbyint)