source: soft/giet_vm/giet_libs/math/s_rint.c

Last change on this file was 777, checked in by meunier, 9 years ago
  • Ajout de quelques fonction dans la lib math
  • Déplacement de certaines fonctions de stdlib vers string
File size: 2.3 KB
Line 
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/* Modified for GIET-VM static OS at UPMC, France 2015.
13 */
14
15/*
16 * rint(x)
17 * Return x rounded to integral value according to the prevailing
18 * rounding mode.
19 * Method:
20 *      Using floating addition.
21 * Exception:
22 *      Inexact flag raised if x not equal to rint(x).
23 */
24
25#include "../math.h"
26#include "math_private.h"
27
28static const double
29TWO52[2]={
30  4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */
31 -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */
32};
33
34double rint(double x)
35{
36        int32_t i0, j0, sx;
37        uint32_t i,i1;
38        double t;
39        /* We use w = x + 2^52; t = w - 2^52; trick to round x to integer.
40         * This trick requires that compiler does not optimize it
41         * by keeping intermediate result w in a register wider than double.
42         * Declaring w volatile assures that value gets truncated to double
43         * (unfortunately, it also forces store+load):
44         */
45        volatile double w;
46
47        EXTRACT_WORDS(i0,i1,x);
48        /* Unbiased exponent */
49        j0 = ((((uint32_t)i0) >> 20)&0x7ff)-0x3ff;
50
51        if (j0 > 51) {
52                //Why bother? Just returning x works too
53                //if (j0 == 0x400)  /* inf or NaN */
54                //      return x+x;
55                return x;  /* x is integral */
56        }
57
58        /* Sign */
59        sx = ((uint32_t)i0) >> 31;
60
61        if (j0<20) {
62            if (j0<0) { /* |x| < 1 */
63                if (((i0&0x7fffffff)|i1)==0) return x;
64                i1 |= (i0&0x0fffff);
65                i0 &= 0xfffe0000;
66                i0 |= ((i1|-i1)>>12)&0x80000;
67                SET_HIGH_WORD(x,i0);
68                w = TWO52[sx]+x;
69                t = w-TWO52[sx];
70                GET_HIGH_WORD(i0,t);
71                SET_HIGH_WORD(t,(i0&0x7fffffff)|(sx<<31));
72                return t;
73            } else {
74                i = (0x000fffff)>>j0;
75                if (((i0&i)|i1)==0) return x; /* x is integral */
76                i>>=1;
77                if (((i0&i)|i1)!=0) {
78                    if (j0==19) i1 = 0x40000000;
79                    else i0 = (i0&(~i))|((0x20000)>>j0);
80                }
81            }
82        } else {
83            i = ((uint32_t)(0xffffffff))>>(j0-20);
84            if ((i1&i)==0) return x;    /* x is integral */
85            i>>=1;
86            if ((i1&i)!=0) i1 = (i1&(~i))|((0x40000000)>>(j0-20));
87        }
88        INSERT_WORDS(x,i0,i1);
89        w = TWO52[sx]+x;
90        return w-TWO52[sx];
91}
Note: See TracBrowser for help on using the repository browser.