Viet-Trung Luu | 96b05c1 | 2016-01-11 11:26:36 -0800 | [diff] [blame] | 1 | #include <limits.h> |
| 2 | #include <fenv.h> |
| 3 | #include "libm.h" |
| 4 | |
Viet-Trung Luu | 96b05c1 | 2016-01-11 11:26:36 -0800 | [diff] [blame] | 5 | #if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 |
George Kulakowski | 17e3b04 | 2016-02-18 15:59:50 -0800 | [diff] [blame] | 6 | long long llrintl(long double x) { |
| 7 | return llrint(x); |
Viet-Trung Luu | 96b05c1 | 2016-01-11 11:26:36 -0800 | [diff] [blame] | 8 | } |
| 9 | #elif defined(FE_INEXACT) |
| 10 | /* |
| 11 | see comments in lrint.c |
| 12 | |
| 13 | Note that if LLONG_MAX == 0x7fffffffffffffff && LDBL_MANT_DIG == 64 |
| 14 | then x == 2**63 - 0.5 is the only input that overflows and |
| 15 | raises inexact (with tonearest or upward rounding mode) |
| 16 | */ |
George Kulakowski | 17e3b04 | 2016-02-18 15:59:50 -0800 | [diff] [blame] | 17 | long long llrintl(long double x) { |
| 18 | PRAGMA_STDC_FENV_ACCESS_ON |
| 19 | int e; |
Viet-Trung Luu | 96b05c1 | 2016-01-11 11:26:36 -0800 | [diff] [blame] | 20 | |
George Kulakowski | 17e3b04 | 2016-02-18 15:59:50 -0800 | [diff] [blame] | 21 | e = fetestexcept(FE_INEXACT); |
| 22 | x = rintl(x); |
| 23 | if (!e && (x > LLONG_MAX || x < LLONG_MIN)) |
| 24 | feclearexcept(FE_INEXACT); |
| 25 | /* conversion */ |
| 26 | return x; |
Viet-Trung Luu | 96b05c1 | 2016-01-11 11:26:36 -0800 | [diff] [blame] | 27 | } |
| 28 | #else |
George Kulakowski | 17e3b04 | 2016-02-18 15:59:50 -0800 | [diff] [blame] | 29 | long long llrintl(long double x) { |
| 30 | return rintl(x); |
Viet-Trung Luu | 96b05c1 | 2016-01-11 11:26:36 -0800 | [diff] [blame] | 31 | } |
| 32 | #endif |