comparison libquadmath/math/cosq_kernel.c @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents 04ced10e8804
children
comparison
equal deleted inserted replaced
131:84e7813d76e9 145:1830386684a0
1 /* Quad-precision floating point cosine on <-pi/4,pi/4>. 1 /* Quad-precision floating point cosine on <-pi/4,pi/4>.
2 Copyright (C) 1999 Free Software Foundation, Inc. 2 Copyright (C) 1999-2018 Free Software Foundation, Inc.
3 This file is part of the GNU C Library. 3 This file is part of the GNU C Library.
4 Contributed by Jakub Jelinek <jj@ultra.linux.cz> 4 Contributed by Jakub Jelinek <jj@ultra.linux.cz>
5 5
6 The GNU C Library is free software; you can redistribute it and/or 6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public 7 modify it under the terms of the GNU Lesser General Public
12 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details. 14 Lesser General Public License for more details.
15 15
16 You should have received a copy of the GNU Lesser General Public 16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, write to the Free 17 License along with the GNU C Library; if not, see
18 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 18 <http://www.gnu.org/licenses/>. */
19 02111-1307 USA. */
20 19
21 #include "quadmath-imp.h" 20 #include "quadmath-imp.h"
22 21
23 static const __float128 c[] = { 22 static const __float128 c[] = {
24 #define ONE c[0] 23 #define ONE c[0]
68 -1.98412698412698412697726277416810661E-04Q, /* bff2a01a01a01a01a019e7121e080d88 */ 67 -1.98412698412698412697726277416810661E-04Q, /* bff2a01a01a01a01a019e7121e080d88 */
69 2.75573192239848624174178393552189149E-06Q, /* 3fec71de3a556c640c6aaa51aa02ab41 */ 68 2.75573192239848624174178393552189149E-06Q, /* 3fec71de3a556c640c6aaa51aa02ab41 */
70 -2.50521016467996193495359189395805639E-08Q, /* bfe5ae644ee90c47dc71839de75b2787 */ 69 -2.50521016467996193495359189395805639E-08Q, /* bfe5ae644ee90c47dc71839de75b2787 */
71 }; 70 };
72 71
73 #define SINCOSQ_COS_HI 0 72 #define SINCOSL_COS_HI 0
74 #define SINCOSQ_COS_LO 1 73 #define SINCOSL_COS_LO 1
75 #define SINCOSQ_SIN_HI 2 74 #define SINCOSL_SIN_HI 2
76 #define SINCOSQ_SIN_LO 3 75 #define SINCOSL_SIN_LO 3
77 extern const __float128 __sincosq_table[]; 76 extern const __float128 __sincosq_table[];
78 77
79 __float128 78 __float128
80 __quadmath_kernel_cosq (__float128 x, __float128 y) 79 __quadmath_kernel_cosq(__float128 x, __float128 y)
81 { 80 {
82 __float128 h, l, z, sin_l, cos_l_m1; 81 __float128 h, l, z, sin_l, cos_l_m1;
83 int64_t ix; 82 int64_t ix;
84 uint32_t tix, hix, index; 83 uint32_t tix, hix, index;
85 GET_FLT128_MSW64 (ix, x); 84 GET_FLT128_MSW64 (ix, x);
96 z*(COS5+z*(COS6+z*(COS7+z*COS8)))))))); 95 z*(COS5+z*(COS6+z*(COS7+z*COS8))))))));
97 } 96 }
98 else 97 else
99 { 98 {
100 /* So that we don't have to use too large polynomial, we find 99 /* So that we don't have to use too large polynomial, we find
101 l and h such that x = l + h, where fabsl(l) <= 1.0/256 with 83 100 l and h such that x = l + h, where fabsq(l) <= 1.0/256 with 83
102 possible values for h. We look up cosq(h) and sinq(h) in 101 possible values for h. We look up cosq(h) and sinq(h) in
103 pre-computed tables, compute cosq(l) and sinq(l) using a 102 pre-computed tables, compute cosq(l) and sinq(l) using a
104 Chebyshev polynomial of degree 10(11) and compute 103 Chebyshev polynomial of degree 10(11) and compute
105 cosq(h+l) = cosq(h)cosq(l) - sinq(h)sinq(l). */ 104 cosq(h+l) = cosq(h)cosq(l) - sinq(h)sinq(l). */
106 index = 0x3ffe - (tix >> 16); 105 index = 0x3ffe - (tix >> 16);
107 hix = (tix + (0x200 << index)) & (0xfffffc00 << index); 106 hix = (tix + (0x200 << index)) & (0xfffffc00 << index);
108 if (signbitq (x)) 107 if (signbitq (x))
109 { 108 {
110 x = -x; 109 x = -x;
111 y = -y; 110 y = -y;
112 } 111 }
113 switch (index) 112 switch (index)
114 { 113 {
115 case 0: index = ((45 << 10) + hix - 0x3ffe0000) >> 8; break; 114 case 0: index = ((45 << 10) + hix - 0x3ffe0000) >> 8; break;
116 case 1: index = ((13 << 11) + hix - 0x3ffd0000) >> 9; break; 115 case 1: index = ((13 << 11) + hix - 0x3ffd0000) >> 9; break;
117 default: 116 default:
121 SET_FLT128_WORDS64(h, ((uint64_t)hix) << 32, 0); 120 SET_FLT128_WORDS64(h, ((uint64_t)hix) << 32, 0);
122 l = y - (h - x); 121 l = y - (h - x);
123 z = l * l; 122 z = l * l;
124 sin_l = l*(ONE+z*(SSIN1+z*(SSIN2+z*(SSIN3+z*(SSIN4+z*SSIN5))))); 123 sin_l = l*(ONE+z*(SSIN1+z*(SSIN2+z*(SSIN3+z*(SSIN4+z*SSIN5)))));
125 cos_l_m1 = z*(SCOS1+z*(SCOS2+z*(SCOS3+z*(SCOS4+z*SCOS5)))); 124 cos_l_m1 = z*(SCOS1+z*(SCOS2+z*(SCOS3+z*(SCOS4+z*SCOS5))));
126 return __sincosq_table [index + SINCOSQ_COS_HI] 125 return __sincosq_table [index + SINCOSL_COS_HI]
127 + (__sincosq_table [index + SINCOSQ_COS_LO] 126 + (__sincosq_table [index + SINCOSL_COS_LO]
128 - (__sincosq_table [index + SINCOSQ_SIN_HI] * sin_l 127 - (__sincosq_table [index + SINCOSL_SIN_HI] * sin_l
129 - __sincosq_table [index + SINCOSQ_COS_HI] * cos_l_m1)); 128 - __sincosq_table [index + SINCOSL_COS_HI] * cos_l_m1));
130 } 129 }
131 } 130 }