comparison libquadmath/math/llrintq.c @ 111:04ced10e8804

gcc 7
author kono
date Fri, 27 Oct 2017 22:46:09 +0900
parents 561a7518be6b
children 1830386684a0
comparison
equal deleted inserted replaced
68:561a7518be6b 111:04ced10e8804
1 /* Round argument to nearest integral value according to current rounding 1 /* Round argument to nearest integral value according to current rounding
2 direction. 2 direction.
3 Copyright (C) 1997, 1999, 2006 Free Software Foundation, Inc. 3 Copyright (C) 1997-2017 Free Software Foundation, Inc.
4 This file is part of the GNU C Library. 4 This file is part of the GNU C Library.
5 Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997 and 5 Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997 and
6 Jakub Jelinek <jj@ultra.linux.cz>, 1999. 6 Jakub Jelinek <jj@ultra.linux.cz>, 1999.
7 7
8 The GNU C Library is free software; you can redistribute it and/or 8 The GNU C Library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public 9 modify it under the terms of the GNU Lesser General Public
10 License as published by the Free Software Foundation; either 10 License as published by the Free Software Foundation; either
11 version 2.1 of the License, or (at your option) any later version. 11 version 2.1 of the License, or (at your option) any later version.
31 long long int 31 long long int
32 llrintq (__float128 x) 32 llrintq (__float128 x)
33 { 33 {
34 int32_t j0; 34 int32_t j0;
35 uint64_t i0,i1; 35 uint64_t i0,i1;
36 volatile __float128 w; 36 __float128 w;
37 __float128 t; 37 __float128 t;
38 long long int result; 38 long long int result;
39 int sx; 39 int sx;
40 40
41 GET_FLT128_WORDS64 (i0, i1, x); 41 GET_FLT128_WORDS64 (i0, i1, x);
44 i0 &= 0x0000ffffffffffffLL; 44 i0 &= 0x0000ffffffffffffLL;
45 i0 |= 0x0001000000000000LL; 45 i0 |= 0x0001000000000000LL;
46 46
47 if (j0 < (int32_t) (8 * sizeof (long long int)) - 1) 47 if (j0 < (int32_t) (8 * sizeof (long long int)) - 1)
48 { 48 {
49 w = two112[sx] + x; 49 #if defined FE_INVALID || defined FE_INEXACT
50 t = w - two112[sx]; 50 /* X < LLONG_MAX + 1 implied by J0 < 63. */
51 if (x > (__float128) LLONG_MAX)
52 {
53 /* In the event of overflow we must raise the "invalid"
54 exception, but not "inexact". */
55 t = nearbyintq (x);
56 #ifdef USE_FENV_H
57 feraiseexcept (t == LLONG_MAX ? FE_INEXACT : FE_INVALID);
58 #endif
59 }
60 else
61 #endif
62 {
63 w = two112[sx] + x;
64 t = w - two112[sx];
65 }
51 GET_FLT128_WORDS64 (i0, i1, t); 66 GET_FLT128_WORDS64 (i0, i1, t);
52 j0 = ((i0 >> 48) & 0x7fff) - 0x3fff; 67 j0 = ((i0 >> 48) & 0x7fff) - 0x3fff;
53 i0 &= 0x0000ffffffffffffLL; 68 i0 &= 0x0000ffffffffffffLL;
54 i0 |= 0x0001000000000000LL; 69 i0 |= 0x0001000000000000LL;
55 70
60 else 75 else
61 result = ((long long int) i0 << (j0 - 48)) | (i1 >> (112 - j0)); 76 result = ((long long int) i0 << (j0 - 48)) | (i1 >> (112 - j0));
62 } 77 }
63 else 78 else
64 { 79 {
80 /* The number is too large. Unless it rounds to LLONG_MIN,
81 FE_INVALID must be raised and the return value is
82 unspecified. */
83 #if defined FE_INVALID || defined FE_INEXACT
84 if (x < (__float128) LLONG_MIN
85 && x > (__float128) LLONG_MIN - 1.0Q)
86 {
87 /* If truncation produces LLONG_MIN, the cast will not raise
88 the exception, but may raise "inexact". */
89 t = nearbyintq (x);
90 #ifdef USE_FENV_H
91 feraiseexcept (t == LLONG_MIN ? FE_INEXACT : FE_INVALID);
92 #endif
93 return LLONG_MIN;
94 }
95
96 #endif
97
65 /* The number is too large. It is left implementation defined 98 /* The number is too large. It is left implementation defined
66 what happens. */ 99 what happens. */
67 return (long long int) x; 100 return (long long int) x;
68 } 101 }
69 102