Mercurial > hg > CbC > CbC_gcc
comparison libquadmath/math/nearbyintq.c @ 68:561a7518be6b
update gcc-4.6
author | Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Sun, 21 Aug 2011 07:07:55 +0900 |
parents | |
children | 04ced10e8804 |
comparison
equal
deleted
inserted
replaced
67:f6334be47118 | 68:561a7518be6b |
---|---|
1 /* nearbyintq.c -- __float128 version of s_nearbyint.c. | |
2 * Conversion to IEEE quad long double by Jakub Jelinek, jj@ultra.linux.cz. | |
3 */ | |
4 | |
5 /* | |
6 * ==================================================== | |
7 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. | |
8 * | |
9 * Developed at SunPro, a Sun Microsystems, Inc. business. | |
10 * Permission to use, copy, modify, and distribute this | |
11 * software is freely granted, provided that this notice | |
12 * is preserved. | |
13 * ==================================================== | |
14 */ | |
15 | |
16 /* | |
17 * nearbyintq(x) | |
18 * Return x rounded to integral value according to the prevailing | |
19 * rounding mode. | |
20 * Method: | |
21 * Using floating addition. | |
22 * Exception: | |
23 * Inexact flag raised if x not equal to rintq(x). | |
24 */ | |
25 | |
26 #include "quadmath-imp.h" | |
27 #ifdef HAVE_FENV_H | |
28 # include <fenv.h> | |
29 # if defined HAVE_FEHOLDEXCEPT && defined HAVE_FESETENV | |
30 # define USE_FENV_H | |
31 # endif | |
32 #endif | |
33 | |
34 static const __float128 | |
35 TWO112[2]={ | |
36 5.19229685853482762853049632922009600E+33Q, /* 0x406F000000000000, 0 */ | |
37 -5.19229685853482762853049632922009600E+33Q /* 0xC06F000000000000, 0 */ | |
38 }; | |
39 | |
40 __float128 | |
41 nearbyintq(__float128 x) | |
42 { | |
43 #ifdef USE_FENV_H | |
44 fenv_t env; | |
45 #endif | |
46 int64_t i0,j0,sx; | |
47 uint64_t i,i1; | |
48 __float128 w,t; | |
49 GET_FLT128_WORDS64(i0,i1,x); | |
50 sx = (((uint64_t)i0)>>63); | |
51 j0 = ((i0>>48)&0x7fff)-0x3fff; | |
52 if(j0<48) { | |
53 if(j0<0) { | |
54 if(((i0&0x7fffffffffffffffLL)|i1)==0) return x; | |
55 i1 |= (i0&0x0000ffffffffffffLL); | |
56 i0 &= 0xffffe00000000000ULL; | |
57 i0 |= ((i1|-i1)>>16)&0x0000800000000000LL; | |
58 SET_FLT128_MSW64(x,i0); | |
59 #ifdef USE_FENV_H | |
60 feholdexcept (&env); | |
61 #endif | |
62 w = TWO112[sx]+x; | |
63 t = w-TWO112[sx]; | |
64 #ifdef USE_FENV_H | |
65 fesetenv (&env); | |
66 #endif | |
67 GET_FLT128_MSW64(i0,t); | |
68 SET_FLT128_MSW64(t,(i0&0x7fffffffffffffffLL)|(sx<<63)); | |
69 return t; | |
70 } else { | |
71 i = (0x0000ffffffffffffLL)>>j0; | |
72 if(((i0&i)|i1)==0) return x; /* x is integral */ | |
73 i>>=1; | |
74 if(((i0&i)|i1)!=0) { | |
75 if(j0==47) i1 = 0x4000000000000000ULL; else | |
76 i0 = (i0&(~i))|((0x0000200000000000LL)>>j0); | |
77 } | |
78 } | |
79 } else if (j0>111) { | |
80 if(j0==0x4000) return x+x; /* inf or NaN */ | |
81 else return x; /* x is integral */ | |
82 } else { | |
83 i = -1ULL>>(j0-48); | |
84 if((i1&i)==0) return x; /* x is integral */ | |
85 i>>=1; | |
86 if((i1&i)!=0) i1 = (i1&(~i))|((0x4000000000000000LL)>>(j0-48)); | |
87 } | |
88 SET_FLT128_WORDS64(x,i0,i1); | |
89 #ifdef USE_FENV_H | |
90 feholdexcept (&env); | |
91 #endif | |
92 w = TWO112[sx]+x; | |
93 t = w-TWO112[sx]; | |
94 #ifdef USE_FENV_H | |
95 fesetenv (&env); | |
96 #endif | |
97 return t; | |
98 } |