]>
Commit | Line | Data |
---|---|---|
abfbdde1 UD |
1 | /* s_nearbyintl.c -- long double 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 | * nearbyintl(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 rintl(x). | |
24 | */ | |
25 | ||
26 | #include <fenv.h> | |
1ed0291c RH |
27 | #include <math.h> |
28 | #include <math_private.h> | |
abfbdde1 | 29 | |
15089e04 | 30 | static const _Float128 |
abfbdde1 | 31 | TWO112[2]={ |
02bbfb41 PM |
32 | L(5.19229685853482762853049632922009600E+33), /* 0x406F000000000000, 0 */ |
33 | L(-5.19229685853482762853049632922009600E+33) /* 0xC06F000000000000, 0 */ | |
abfbdde1 UD |
34 | }; |
35 | ||
15089e04 | 36 | _Float128 __nearbyintl(_Float128 x) |
abfbdde1 UD |
37 | { |
38 | fenv_t env; | |
39 | int64_t i0,j0,sx; | |
cf9a5d18 | 40 | u_int64_t i1 __attribute__ ((unused)); |
15089e04 | 41 | _Float128 w,t; |
abfbdde1 UD |
42 | GET_LDOUBLE_WORDS64(i0,i1,x); |
43 | sx = (((u_int64_t)i0)>>63); | |
44 | j0 = ((i0>>48)&0x7fff)-0x3fff; | |
a78bc654 | 45 | if(j0<112) { |
abfbdde1 | 46 | if(j0<0) { |
abfbdde1 UD |
47 | feholdexcept (&env); |
48 | w = TWO112[sx]+x; | |
49 | t = w-TWO112[sx]; | |
3e694268 | 50 | math_force_eval (t); |
abfbdde1 UD |
51 | fesetenv (&env); |
52 | GET_LDOUBLE_MSW64(i0,t); | |
53 | SET_LDOUBLE_MSW64(t,(i0&0x7fffffffffffffffLL)|(sx<<63)); | |
54 | return t; | |
abfbdde1 | 55 | } |
a78bc654 | 56 | } else { |
abfbdde1 UD |
57 | if(j0==0x4000) return x+x; /* inf or NaN */ |
58 | else return x; /* x is integral */ | |
abfbdde1 | 59 | } |
abfbdde1 UD |
60 | feholdexcept (&env); |
61 | w = TWO112[sx]+x; | |
62 | t = w-TWO112[sx]; | |
3e694268 | 63 | math_force_eval (t); |
abfbdde1 UD |
64 | fesetenv (&env); |
65 | return t; | |
66 | } | |
67 | weak_alias (__nearbyintl, nearbyintl) |