comparison libquadmath/math/lrintq.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, 2004, 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 int 31 long int
32 lrintq (__float128 x) 32 lrintq (__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 int result; 38 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);
42 j0 = ((i0 >> 48) & 0x7fff) - 0x3fff; 42 j0 = ((i0 >> 48) & 0x7fff) - 0x3fff;
43 sx = i0 >> 63; 43 sx = i0 >> 63;
44 i0 &= 0x0000ffffffffffffLL; 44 i0 &= 0x0000ffffffffffffLL;
45 i0 |= 0x0001000000000000LL; 45 i0 |= 0x0001000000000000LL;
46 46
47 if (j0 < 48) 47 if (j0 < (int32_t) (8 * sizeof (long int)) - 1)
48 { 48 {
49 w = two112[sx] + x; 49 if (j0 < 48)
50 t = w - two112[sx]; 50 {
51 GET_FLT128_WORDS64 (i0, i1, t); 51 #if defined FE_INVALID || defined FE_INEXACT
52 j0 = ((i0 >> 48) & 0x7fff) - 0x3fff; 52 /* X < LONG_MAX + 1 implied by J0 < 31. */
53 i0 &= 0x0000ffffffffffffLL; 53 if (sizeof (long int) == 4
54 i0 |= 0x0001000000000000LL; 54 && x > (__float128) LONG_MAX)
55 {
56 /* In the event of overflow we must raise the "invalid"
57 exception, but not "inexact". */
58 t = nearbyintq (x);
59 #ifdef USE_FENV_H
60 feraiseexcept (t == LONG_MAX ? FE_INEXACT : FE_INVALID);
61 #endif
62 }
63 else
64 #endif
65 {
66 w = two112[sx] + x;
67 t = w - two112[sx];
68 }
69 GET_FLT128_WORDS64 (i0, i1, t);
70 j0 = ((i0 >> 48) & 0x7fff) - 0x3fff;
71 i0 &= 0x0000ffffffffffffLL;
72 i0 |= 0x0001000000000000LL;
55 73
56 result = (j0 < 0 ? 0 : i0 >> (48 - j0)); 74 result = (j0 < 0 ? 0 : i0 >> (48 - j0));
57 } 75 }
58 else if (j0 < (int32_t) (8 * sizeof (long int)) - 1) 76 else if (j0 >= 112)
59 {
60 if (j0 >= 112)
61 result = ((long int) i0 << (j0 - 48)) | (i1 << (j0 - 112)); 77 result = ((long int) i0 << (j0 - 48)) | (i1 << (j0 - 112));
62 else 78 else
63 { 79 {
64 w = two112[sx] + x; 80 #if defined FE_INVALID || defined FE_INEXACT
65 t = w - two112[sx]; 81 /* X < LONG_MAX + 1 implied by J0 < 63. */
82 if (sizeof (long int) == 8
83 && x > (__float128) LONG_MAX)
84 {
85 /* In the event of overflow we must raise the "invalid"
86 exception, but not "inexact". */
87 t = nearbyintq (x);
88 #ifdef USE_FENV_H
89 feraiseexcept (t == LONG_MAX ? FE_INEXACT : FE_INVALID);
90 #endif
91 }
92 else
93 #endif
94 {
95 w = two112[sx] + x;
96 t = w - two112[sx];
97 }
66 GET_FLT128_WORDS64 (i0, i1, t); 98 GET_FLT128_WORDS64 (i0, i1, t);
67 j0 = ((i0 >> 48) & 0x7fff) - 0x3fff; 99 j0 = ((i0 >> 48) & 0x7fff) - 0x3fff;
68 i0 &= 0x0000ffffffffffffLL; 100 i0 &= 0x0000ffffffffffffLL;
69 i0 |= 0x0001000000000000LL; 101 i0 |= 0x0001000000000000LL;
70 102
74 result = ((long int) i0 << (j0 - 48)) | (i1 >> (112 - j0)); 106 result = ((long int) i0 << (j0 - 48)) | (i1 >> (112 - j0));
75 } 107 }
76 } 108 }
77 else 109 else
78 { 110 {
79 /* The number is too large. It is left implementation defined 111 /* The number is too large. Unless it rounds to LONG_MIN,
80 what happens. */ 112 FE_INVALID must be raised and the return value is
113 unspecified. */
114 #if defined FE_INVALID || defined FE_INEXACT
115 if (x < (__float128) LONG_MIN
116 && x > (__float128) LONG_MIN - 1.0Q)
117 {
118 /* If truncation produces LONG_MIN, the cast will not raise
119 the exception, but may raise "inexact". */
120 t = nearbyintq (x);
121 #ifdef USE_FENV_H
122 feraiseexcept (t == LONG_MIN ? FE_INEXACT : FE_INVALID);
123 #endif
124 return LONG_MIN;
125 }
126 #endif
81 return (long int) x; 127 return (long int) x;
82 } 128 }
83 129
84 return sx ? -result : result; 130 return sx ? -result : result;
85 } 131 }