Numworks Epsilon  1.4.1
Graphing Calculator Operating System
s_rint.c
Go to the documentation of this file.
1 /* @(#)s_rint.c 5.1 93/09/24 */
2 /*
3  * ====================================================
4  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
5  *
6  * Developed at SunPro, a Sun Microsystems, Inc. business.
7  * Permission to use, copy, modify, and distribute this
8  * software is freely granted, provided that this notice
9  * is preserved.
10  * ====================================================
11  */
12 
13 /*
14  * rint(x)
15  * Return x rounded to integral value according to the prevailing
16  * rounding mode.
17  * Method:
18  * Using floating addition.
19  * Exception:
20  * Inexact flag raised if x not equal to rint(x).
21  */
22 
23 #include <sys/cdefs.h>
24 #include <float.h>
25 #include <math.h>
26 
27 #include "math_private.h"
28 
29 static const double
30 TWO52[2]={
31  4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */
32  -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */
33 };
34 
35 double
36 rint(double x)
37 {
38  int32_t i0,jj0,sx;
39  u_int32_t i,i1;
40  double w,t;
41  EXTRACT_WORDS(i0,i1,x);
42  sx = (i0>>31)&1;
43  jj0 = ((i0>>20)&0x7ff)-0x3ff;
44  if(jj0<20) {
45  if(jj0<0) {
46  if(((i0&0x7fffffff)|i1)==0) return x;
47  i1 |= (i0&0x0fffff);
48  i0 &= 0xfffe0000;
49  i0 |= ((i1|-i1)>>12)&0x80000;
50  SET_HIGH_WORD(x,i0);
51  w = TWO52[sx]+x;
52  t = w-TWO52[sx];
53  GET_HIGH_WORD(i0,t);
54  SET_HIGH_WORD(t,(i0&0x7fffffff)|(sx<<31));
55  return t;
56  } else {
57  i = (0x000fffff)>>jj0;
58  if(((i0&i)|i1)==0) return x; /* x is integral */
59  i>>=1;
60  if(((i0&i)|i1)!=0) {
61  if(jj0==19) i1 = 0x40000000; else
62  i0 = (i0&(~i))|((0x20000)>>jj0);
63  }
64  }
65  } else if (jj0>51) {
66  if(jj0==0x400) return x+x; /* inf or NaN */
67  else return x; /* x is integral */
68  } else {
69  i = ((u_int32_t)(0xffffffff))>>(jj0-20);
70  if((i1&i)==0) return x; /* x is integral */
71  i>>=1;
72  if((i1&i)!=0) i1 = (i1&(~i))|((0x40000000)>>(jj0-20));
73  }
74  INSERT_WORDS(x,i0,i1);
75  w = TWO52[sx]+x;
76  return w-TWO52[sx];
77 }
78 
79 #if LDBL_MANT_DIG == 53
80 #ifdef __weak_alias
81 __weak_alias(rintl, rint);
82 #endif /* __weak_alias */
83 #endif /* LDBL_MANT_DIG == 53 */
#define GET_HIGH_WORD(i, d)
Definition: math_private.h:269
uint32_t u_int32_t
Definition: types.h:10
#define SET_HIGH_WORD(d, v)
Definition: math_private.h:297
double rint(double x)
Definition: s_rint.c:36
#define EXTRACT_WORDS(ix0, ix1, d)
Definition: math_private.h:259
#define INSERT_WORDS(d, ix0, ix1)
Definition: math_private.h:287
signed int int32_t
Definition: stdint.h:11