s_rintl.c (176458) | s_rintl.c (176461) |
---|---|
1/*- 2 * Copyright (c) 2008 David Schultz <das@FreeBSD.ORG> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 11 unchanged lines hidden (view full) --- 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2008 David Schultz <das@FreeBSD.ORG> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 11 unchanged lines hidden (view full) --- 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> |
28__FBSDID("$FreeBSD: head/lib/msun/src/s_rintl.c 176458 2008-02-22 10:04:53Z bde $"); | 28__FBSDID("$FreeBSD: head/lib/msun/src/s_rintl.c 176461 2008-02-22 11:59:05Z bde $"); |
29 30#include <float.h> 31#include <math.h> 32 33#include "fpmath.h" 34 | 29 30#include <float.h> 31#include <math.h> 32 33#include "fpmath.h" 34 |
35#if LDBL_MAX_EXP != 0x4000 36/* We also require the usual bias, min exp and expsign packing. */ 37#error "Unsupported long double format" 38#endif 39 |
|
35#define BIAS (LDBL_MAX_EXP - 1) 36 37static const float 38shift[2] = { 39#if LDBL_MANT_DIG == 64 40 0x1.0p63, -0x1.0p63 41#elif LDBL_MANT_DIG == 113 42 0x1.0p112, -0x1.0p112 43#else 44#error "Unsupported long double format" 45#endif 46}; 47static const float zero[2] = { 0.0, -0.0 }; 48 49long double 50rintl(long double x) 51{ 52 union IEEEl2bits u; | 40#define BIAS (LDBL_MAX_EXP - 1) 41 42static const float 43shift[2] = { 44#if LDBL_MANT_DIG == 64 45 0x1.0p63, -0x1.0p63 46#elif LDBL_MANT_DIG == 113 47 0x1.0p112, -0x1.0p112 48#else 49#error "Unsupported long double format" 50#endif 51}; 52static const float zero[2] = { 0.0, -0.0 }; 53 54long double 55rintl(long double x) 56{ 57 union IEEEl2bits u; |
53 short sign; | 58 uint32_t expsign; 59 int ex, sign; |
54 55 u.e = x; | 60 61 u.e = x; |
62 expsign = u.xbits.expsign; 63 ex = expsign & 0x7fff; |
|
56 | 64 |
57 if (u.bits.exp >= BIAS + LDBL_MANT_DIG - 1) { 58 if (u.bits.exp == BIAS + LDBL_MAX_EXP) | 65 if (ex >= BIAS + LDBL_MANT_DIG - 1) { 66 if (ex == BIAS + LDBL_MAX_EXP) |
59 return (x + x); /* Inf, NaN, or unsupported format */ 60 return (x); /* finite and already an integer */ 61 } | 67 return (x + x); /* Inf, NaN, or unsupported format */ 68 return (x); /* finite and already an integer */ 69 } |
62 sign = u.bits.sign; | 70 sign = expsign >> 15; |
63 64 /* 65 * The following code assumes that intermediate results are 66 * evaluated in long double precision. If they are evaluated in 67 * greater precision, double rounding may occur, and if they are 68 * evaluated in less precision (as on i386), results will be 69 * wildly incorrect. 70 */ 71 x += shift[sign]; 72 x -= shift[sign]; 73 74 /* 75 * If the result is +-0, then it must have the same sign as x, but 76 * the above calculation doesn't always give this. Fix up the sign. 77 */ | 71 72 /* 73 * The following code assumes that intermediate results are 74 * evaluated in long double precision. If they are evaluated in 75 * greater precision, double rounding may occur, and if they are 76 * evaluated in less precision (as on i386), results will be 77 * wildly incorrect. 78 */ 79 x += shift[sign]; 80 x -= shift[sign]; 81 82 /* 83 * If the result is +-0, then it must have the same sign as x, but 84 * the above calculation doesn't always give this. Fix up the sign. 85 */ |
78 if (u.bits.exp < BIAS && x == 0.0L) | 86 if (ex < BIAS && x == 0.0L) |
79 return (zero[sign]); 80 81 return (x); 82} | 87 return (zero[sign]); 88 89 return (x); 90} |