xref: /netbsd-src/external/gpl3/gcc.old/dist/libquadmath/math/jnq.c (revision 627f7eb200a4419d89b531d55fccd2ee3ffdcde0)
1*627f7eb2Smrg /*
2*627f7eb2Smrg  * ====================================================
3*627f7eb2Smrg  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
4*627f7eb2Smrg  *
5*627f7eb2Smrg  * Developed at SunPro, a Sun Microsystems, Inc. business.
6*627f7eb2Smrg  * Permission to use, copy, modify, and distribute this
7*627f7eb2Smrg  * software is freely granted, provided that this notice
8*627f7eb2Smrg  * is preserved.
9*627f7eb2Smrg  * ====================================================
10*627f7eb2Smrg  */
11*627f7eb2Smrg 
12*627f7eb2Smrg /* Modifications for 128-bit long double are
13*627f7eb2Smrg    Copyright (C) 2001 Stephen L. Moshier <moshier@na-net.ornl.gov>
14*627f7eb2Smrg    and are incorporated herein by permission of the author.  The author
15*627f7eb2Smrg    reserves the right to distribute this material elsewhere under different
16*627f7eb2Smrg    copying permissions.  These modifications are distributed here under
17*627f7eb2Smrg    the following terms:
18*627f7eb2Smrg 
19*627f7eb2Smrg     This library is free software; you can redistribute it and/or
20*627f7eb2Smrg     modify it under the terms of the GNU Lesser General Public
21*627f7eb2Smrg     License as published by the Free Software Foundation; either
22*627f7eb2Smrg     version 2.1 of the License, or (at your option) any later version.
23*627f7eb2Smrg 
24*627f7eb2Smrg     This library is distributed in the hope that it will be useful,
25*627f7eb2Smrg     but WITHOUT ANY WARRANTY; without even the implied warranty of
26*627f7eb2Smrg     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
27*627f7eb2Smrg     Lesser General Public License for more details.
28*627f7eb2Smrg 
29*627f7eb2Smrg     You should have received a copy of the GNU Lesser General Public
30*627f7eb2Smrg     License along with this library; if not, see
31*627f7eb2Smrg     <http://www.gnu.org/licenses/>.  */
32*627f7eb2Smrg 
33*627f7eb2Smrg /*
34*627f7eb2Smrg  * __ieee754_jn(n, x), __ieee754_yn(n, x)
35*627f7eb2Smrg  * floating point Bessel's function of the 1st and 2nd kind
36*627f7eb2Smrg  * of order n
37*627f7eb2Smrg  *
38*627f7eb2Smrg  * Special cases:
39*627f7eb2Smrg  *	y0(0)=y1(0)=yn(n,0) = -inf with division by zero signal;
40*627f7eb2Smrg  *	y0(-ve)=y1(-ve)=yn(n,-ve) are NaN with invalid signal.
41*627f7eb2Smrg  * Note 2. About jn(n,x), yn(n,x)
42*627f7eb2Smrg  *	For n=0, j0(x) is called,
43*627f7eb2Smrg  *	for n=1, j1(x) is called,
44*627f7eb2Smrg  *	for n<x, forward recursion us used starting
45*627f7eb2Smrg  *	from values of j0(x) and j1(x).
46*627f7eb2Smrg  *	for n>x, a continued fraction approximation to
47*627f7eb2Smrg  *	j(n,x)/j(n-1,x) is evaluated and then backward
48*627f7eb2Smrg  *	recursion is used starting from a supposed value
49*627f7eb2Smrg  *	for j(n,x). The resulting value of j(0,x) is
50*627f7eb2Smrg  *	compared with the actual value to correct the
51*627f7eb2Smrg  *	supposed value of j(n,x).
52*627f7eb2Smrg  *
53*627f7eb2Smrg  *	yn(n,x) is similar in all respects, except
54*627f7eb2Smrg  *	that forward recursion is used for all
55*627f7eb2Smrg  *	values of n>1.
56*627f7eb2Smrg  *
57*627f7eb2Smrg  */
58*627f7eb2Smrg 
59*627f7eb2Smrg #include "quadmath-imp.h"
60*627f7eb2Smrg 
61*627f7eb2Smrg static const __float128
62*627f7eb2Smrg   invsqrtpi = 5.6418958354775628694807945156077258584405E-1Q,
63*627f7eb2Smrg   two = 2,
64*627f7eb2Smrg   one = 1,
65*627f7eb2Smrg   zero = 0;
66*627f7eb2Smrg 
67*627f7eb2Smrg 
68*627f7eb2Smrg __float128
jnq(int n,__float128 x)69*627f7eb2Smrg jnq (int n, __float128 x)
70*627f7eb2Smrg {
71*627f7eb2Smrg   uint32_t se;
72*627f7eb2Smrg   int32_t i, ix, sgn;
73*627f7eb2Smrg   __float128 a, b, temp, di, ret;
74*627f7eb2Smrg   __float128 z, w;
75*627f7eb2Smrg   ieee854_float128 u;
76*627f7eb2Smrg 
77*627f7eb2Smrg 
78*627f7eb2Smrg   /* J(-n,x) = (-1)^n * J(n, x), J(n, -x) = (-1)^n * J(n, x)
79*627f7eb2Smrg    * Thus, J(-n,x) = J(n,-x)
80*627f7eb2Smrg    */
81*627f7eb2Smrg 
82*627f7eb2Smrg   u.value = x;
83*627f7eb2Smrg   se = u.words32.w0;
84*627f7eb2Smrg   ix = se & 0x7fffffff;
85*627f7eb2Smrg 
86*627f7eb2Smrg   /* if J(n,NaN) is NaN */
87*627f7eb2Smrg   if (ix >= 0x7fff0000)
88*627f7eb2Smrg     {
89*627f7eb2Smrg       if ((u.words32.w0 & 0xffff) | u.words32.w1 | u.words32.w2 | u.words32.w3)
90*627f7eb2Smrg 	return x + x;
91*627f7eb2Smrg     }
92*627f7eb2Smrg 
93*627f7eb2Smrg   if (n < 0)
94*627f7eb2Smrg     {
95*627f7eb2Smrg       n = -n;
96*627f7eb2Smrg       x = -x;
97*627f7eb2Smrg       se ^= 0x80000000;
98*627f7eb2Smrg     }
99*627f7eb2Smrg   if (n == 0)
100*627f7eb2Smrg     return (j0q (x));
101*627f7eb2Smrg   if (n == 1)
102*627f7eb2Smrg     return (j1q (x));
103*627f7eb2Smrg   sgn = (n & 1) & (se >> 31);	/* even n -- 0, odd n -- sign(x) */
104*627f7eb2Smrg   x = fabsq (x);
105*627f7eb2Smrg 
106*627f7eb2Smrg   {
107*627f7eb2Smrg     SET_RESTORE_ROUNDF128 (FE_TONEAREST);
108*627f7eb2Smrg     if (x == 0 || ix >= 0x7fff0000)	/* if x is 0 or inf */
109*627f7eb2Smrg       return sgn == 1 ? -zero : zero;
110*627f7eb2Smrg     else if ((__float128) n <= x)
111*627f7eb2Smrg       {
112*627f7eb2Smrg 	/* Safe to use J(n+1,x)=2n/x *J(n,x)-J(n-1,x) */
113*627f7eb2Smrg 	if (ix >= 0x412D0000)
114*627f7eb2Smrg 	  {			/* x > 2**302 */
115*627f7eb2Smrg 
116*627f7eb2Smrg 	    /* ??? Could use an expansion for large x here.  */
117*627f7eb2Smrg 
118*627f7eb2Smrg 	    /* (x >> n**2)
119*627f7eb2Smrg 	     *      Jn(x) = cos(x-(2n+1)*pi/4)*sqrt(2/x*pi)
120*627f7eb2Smrg 	     *      Yn(x) = sin(x-(2n+1)*pi/4)*sqrt(2/x*pi)
121*627f7eb2Smrg 	     *      Let s=sin(x), c=cos(x),
122*627f7eb2Smrg 	     *          xn=x-(2n+1)*pi/4, sqt2 = sqrt(2),then
123*627f7eb2Smrg 	     *
124*627f7eb2Smrg 	     *             n    sin(xn)*sqt2    cos(xn)*sqt2
125*627f7eb2Smrg 	     *          ----------------------------------
126*627f7eb2Smrg 	     *             0     s-c             c+s
127*627f7eb2Smrg 	     *             1    -s-c            -c+s
128*627f7eb2Smrg 	     *             2    -s+c            -c-s
129*627f7eb2Smrg 	     *             3     s+c             c-s
130*627f7eb2Smrg 	     */
131*627f7eb2Smrg 	    __float128 s;
132*627f7eb2Smrg 	    __float128 c;
133*627f7eb2Smrg 	    sincosq (x, &s, &c);
134*627f7eb2Smrg 	    switch (n & 3)
135*627f7eb2Smrg 	      {
136*627f7eb2Smrg 	      case 0:
137*627f7eb2Smrg 		temp = c + s;
138*627f7eb2Smrg 		break;
139*627f7eb2Smrg 	      case 1:
140*627f7eb2Smrg 		temp = -c + s;
141*627f7eb2Smrg 		break;
142*627f7eb2Smrg 	      case 2:
143*627f7eb2Smrg 		temp = -c - s;
144*627f7eb2Smrg 		break;
145*627f7eb2Smrg 	      case 3:
146*627f7eb2Smrg 		temp = c - s;
147*627f7eb2Smrg 		break;
148*627f7eb2Smrg 	      }
149*627f7eb2Smrg 	    b = invsqrtpi * temp / sqrtq (x);
150*627f7eb2Smrg 	  }
151*627f7eb2Smrg 	else
152*627f7eb2Smrg 	  {
153*627f7eb2Smrg 	    a = j0q (x);
154*627f7eb2Smrg 	    b = j1q (x);
155*627f7eb2Smrg 	    for (i = 1; i < n; i++)
156*627f7eb2Smrg 	      {
157*627f7eb2Smrg 		temp = b;
158*627f7eb2Smrg 		b = b * ((__float128) (i + i) / x) - a;	/* avoid underflow */
159*627f7eb2Smrg 		a = temp;
160*627f7eb2Smrg 	      }
161*627f7eb2Smrg 	  }
162*627f7eb2Smrg       }
163*627f7eb2Smrg     else
164*627f7eb2Smrg       {
165*627f7eb2Smrg 	if (ix < 0x3fc60000)
166*627f7eb2Smrg 	  {			/* x < 2**-57 */
167*627f7eb2Smrg 	    /* x is tiny, return the first Taylor expansion of J(n,x)
168*627f7eb2Smrg 	     * J(n,x) = 1/n!*(x/2)^n  - ...
169*627f7eb2Smrg 	     */
170*627f7eb2Smrg 	    if (n >= 400)		/* underflow, result < 10^-4952 */
171*627f7eb2Smrg 	      b = zero;
172*627f7eb2Smrg 	    else
173*627f7eb2Smrg 	      {
174*627f7eb2Smrg 		temp = x * 0.5;
175*627f7eb2Smrg 		b = temp;
176*627f7eb2Smrg 		for (a = one, i = 2; i <= n; i++)
177*627f7eb2Smrg 		  {
178*627f7eb2Smrg 		    a *= (__float128) i;	/* a = n! */
179*627f7eb2Smrg 		    b *= temp;	/* b = (x/2)^n */
180*627f7eb2Smrg 		  }
181*627f7eb2Smrg 		b = b / a;
182*627f7eb2Smrg 	      }
183*627f7eb2Smrg 	  }
184*627f7eb2Smrg 	else
185*627f7eb2Smrg 	  {
186*627f7eb2Smrg 	    /* use backward recurrence */
187*627f7eb2Smrg 	    /*                      x      x^2      x^2
188*627f7eb2Smrg 	     *  J(n,x)/J(n-1,x) =  ----   ------   ------   .....
189*627f7eb2Smrg 	     *                      2n  - 2(n+1) - 2(n+2)
190*627f7eb2Smrg 	     *
191*627f7eb2Smrg 	     *                      1      1        1
192*627f7eb2Smrg 	     *  (for large x)   =  ----  ------   ------   .....
193*627f7eb2Smrg 	     *                      2n   2(n+1)   2(n+2)
194*627f7eb2Smrg 	     *                      -- - ------ - ------ -
195*627f7eb2Smrg 	     *                       x     x         x
196*627f7eb2Smrg 	     *
197*627f7eb2Smrg 	     * Let w = 2n/x and h=2/x, then the above quotient
198*627f7eb2Smrg 	     * is equal to the continued fraction:
199*627f7eb2Smrg 	     *                  1
200*627f7eb2Smrg 	     *      = -----------------------
201*627f7eb2Smrg 	     *                     1
202*627f7eb2Smrg 	     *         w - -----------------
203*627f7eb2Smrg 	     *                        1
204*627f7eb2Smrg 	     *              w+h - ---------
205*627f7eb2Smrg 	     *                     w+2h - ...
206*627f7eb2Smrg 	     *
207*627f7eb2Smrg 	     * To determine how many terms needed, let
208*627f7eb2Smrg 	     * Q(0) = w, Q(1) = w(w+h) - 1,
209*627f7eb2Smrg 	     * Q(k) = (w+k*h)*Q(k-1) - Q(k-2),
210*627f7eb2Smrg 	     * When Q(k) > 1e4      good for single
211*627f7eb2Smrg 	     * When Q(k) > 1e9      good for double
212*627f7eb2Smrg 	     * When Q(k) > 1e17     good for quadruple
213*627f7eb2Smrg 	     */
214*627f7eb2Smrg 	    /* determine k */
215*627f7eb2Smrg 	    __float128 t, v;
216*627f7eb2Smrg 	    __float128 q0, q1, h, tmp;
217*627f7eb2Smrg 	    int32_t k, m;
218*627f7eb2Smrg 	    w = (n + n) / (__float128) x;
219*627f7eb2Smrg 	    h = 2 / (__float128) x;
220*627f7eb2Smrg 	    q0 = w;
221*627f7eb2Smrg 	    z = w + h;
222*627f7eb2Smrg 	    q1 = w * z - 1;
223*627f7eb2Smrg 	    k = 1;
224*627f7eb2Smrg 	    while (q1 < 1.0e17Q)
225*627f7eb2Smrg 	      {
226*627f7eb2Smrg 		k += 1;
227*627f7eb2Smrg 		z += h;
228*627f7eb2Smrg 		tmp = z * q1 - q0;
229*627f7eb2Smrg 		q0 = q1;
230*627f7eb2Smrg 		q1 = tmp;
231*627f7eb2Smrg 	      }
232*627f7eb2Smrg 	    m = n + n;
233*627f7eb2Smrg 	    for (t = zero, i = 2 * (n + k); i >= m; i -= 2)
234*627f7eb2Smrg 	      t = one / (i / x - t);
235*627f7eb2Smrg 	    a = t;
236*627f7eb2Smrg 	    b = one;
237*627f7eb2Smrg 	    /*  estimate log((2/x)^n*n!) = n*log(2/x)+n*ln(n)
238*627f7eb2Smrg 	     *  Hence, if n*(log(2n/x)) > ...
239*627f7eb2Smrg 	     *  single 8.8722839355e+01
240*627f7eb2Smrg 	     *  double 7.09782712893383973096e+02
241*627f7eb2Smrg 	     *  long double 1.1356523406294143949491931077970765006170e+04
242*627f7eb2Smrg 	     *  then recurrent value may overflow and the result is
243*627f7eb2Smrg 	     *  likely underflow to zero
244*627f7eb2Smrg 	     */
245*627f7eb2Smrg 	    tmp = n;
246*627f7eb2Smrg 	    v = two / x;
247*627f7eb2Smrg 	    tmp = tmp * logq (fabsq (v * tmp));
248*627f7eb2Smrg 
249*627f7eb2Smrg 	    if (tmp < 1.1356523406294143949491931077970765006170e+04Q)
250*627f7eb2Smrg 	      {
251*627f7eb2Smrg 		for (i = n - 1, di = (__float128) (i + i); i > 0; i--)
252*627f7eb2Smrg 		  {
253*627f7eb2Smrg 		    temp = b;
254*627f7eb2Smrg 		    b *= di;
255*627f7eb2Smrg 		    b = b / x - a;
256*627f7eb2Smrg 		    a = temp;
257*627f7eb2Smrg 		    di -= two;
258*627f7eb2Smrg 		  }
259*627f7eb2Smrg 	      }
260*627f7eb2Smrg 	    else
261*627f7eb2Smrg 	      {
262*627f7eb2Smrg 		for (i = n - 1, di = (__float128) (i + i); i > 0; i--)
263*627f7eb2Smrg 		  {
264*627f7eb2Smrg 		    temp = b;
265*627f7eb2Smrg 		    b *= di;
266*627f7eb2Smrg 		    b = b / x - a;
267*627f7eb2Smrg 		    a = temp;
268*627f7eb2Smrg 		    di -= two;
269*627f7eb2Smrg 		    /* scale b to avoid spurious overflow */
270*627f7eb2Smrg 		    if (b > 1e100Q)
271*627f7eb2Smrg 		      {
272*627f7eb2Smrg 			a /= b;
273*627f7eb2Smrg 			t /= b;
274*627f7eb2Smrg 			b = one;
275*627f7eb2Smrg 		      }
276*627f7eb2Smrg 		  }
277*627f7eb2Smrg 	      }
278*627f7eb2Smrg 	    /* j0() and j1() suffer enormous loss of precision at and
279*627f7eb2Smrg 	     * near zero; however, we know that their zero points never
280*627f7eb2Smrg 	     * coincide, so just choose the one further away from zero.
281*627f7eb2Smrg 	     */
282*627f7eb2Smrg 	    z = j0q (x);
283*627f7eb2Smrg 	    w = j1q (x);
284*627f7eb2Smrg 	    if (fabsq (z) >= fabsq (w))
285*627f7eb2Smrg 	      b = (t * z / b);
286*627f7eb2Smrg 	    else
287*627f7eb2Smrg 	      b = (t * w / a);
288*627f7eb2Smrg 	  }
289*627f7eb2Smrg       }
290*627f7eb2Smrg     if (sgn == 1)
291*627f7eb2Smrg       ret = -b;
292*627f7eb2Smrg     else
293*627f7eb2Smrg       ret = b;
294*627f7eb2Smrg   }
295*627f7eb2Smrg   if (ret == 0)
296*627f7eb2Smrg     {
297*627f7eb2Smrg       ret = copysignq (FLT128_MIN, ret) * FLT128_MIN;
298*627f7eb2Smrg       errno = ERANGE;
299*627f7eb2Smrg     }
300*627f7eb2Smrg   else
301*627f7eb2Smrg     math_check_force_underflow (ret);
302*627f7eb2Smrg   return ret;
303*627f7eb2Smrg }
304*627f7eb2Smrg 
305*627f7eb2Smrg 
306*627f7eb2Smrg __float128
ynq(int n,__float128 x)307*627f7eb2Smrg ynq (int n, __float128 x)
308*627f7eb2Smrg {
309*627f7eb2Smrg   uint32_t se;
310*627f7eb2Smrg   int32_t i, ix;
311*627f7eb2Smrg   int32_t sign;
312*627f7eb2Smrg   __float128 a, b, temp, ret;
313*627f7eb2Smrg   ieee854_float128 u;
314*627f7eb2Smrg 
315*627f7eb2Smrg   u.value = x;
316*627f7eb2Smrg   se = u.words32.w0;
317*627f7eb2Smrg   ix = se & 0x7fffffff;
318*627f7eb2Smrg 
319*627f7eb2Smrg   /* if Y(n,NaN) is NaN */
320*627f7eb2Smrg   if (ix >= 0x7fff0000)
321*627f7eb2Smrg     {
322*627f7eb2Smrg       if ((u.words32.w0 & 0xffff) | u.words32.w1 | u.words32.w2 | u.words32.w3)
323*627f7eb2Smrg 	return x + x;
324*627f7eb2Smrg     }
325*627f7eb2Smrg   if (x <= 0)
326*627f7eb2Smrg     {
327*627f7eb2Smrg       if (x == 0)
328*627f7eb2Smrg 	return ((n < 0 && (n & 1) != 0) ? 1 : -1) / 0.0Q;
329*627f7eb2Smrg       if (se & 0x80000000)
330*627f7eb2Smrg 	return zero / (zero * x);
331*627f7eb2Smrg     }
332*627f7eb2Smrg   sign = 1;
333*627f7eb2Smrg   if (n < 0)
334*627f7eb2Smrg     {
335*627f7eb2Smrg       n = -n;
336*627f7eb2Smrg       sign = 1 - ((n & 1) << 1);
337*627f7eb2Smrg     }
338*627f7eb2Smrg   if (n == 0)
339*627f7eb2Smrg     return (y0q (x));
340*627f7eb2Smrg   {
341*627f7eb2Smrg     SET_RESTORE_ROUNDF128 (FE_TONEAREST);
342*627f7eb2Smrg     if (n == 1)
343*627f7eb2Smrg       {
344*627f7eb2Smrg 	ret = sign * y1q (x);
345*627f7eb2Smrg 	goto out;
346*627f7eb2Smrg       }
347*627f7eb2Smrg     if (ix >= 0x7fff0000)
348*627f7eb2Smrg       return zero;
349*627f7eb2Smrg     if (ix >= 0x412D0000)
350*627f7eb2Smrg       {				/* x > 2**302 */
351*627f7eb2Smrg 
352*627f7eb2Smrg 	/* ??? See comment above on the possible futility of this.  */
353*627f7eb2Smrg 
354*627f7eb2Smrg 	/* (x >> n**2)
355*627f7eb2Smrg 	 *      Jn(x) = cos(x-(2n+1)*pi/4)*sqrt(2/x*pi)
356*627f7eb2Smrg 	 *      Yn(x) = sin(x-(2n+1)*pi/4)*sqrt(2/x*pi)
357*627f7eb2Smrg 	 *      Let s=sin(x), c=cos(x),
358*627f7eb2Smrg 	 *          xn=x-(2n+1)*pi/4, sqt2 = sqrt(2),then
359*627f7eb2Smrg 	 *
360*627f7eb2Smrg 	 *             n    sin(xn)*sqt2    cos(xn)*sqt2
361*627f7eb2Smrg 	 *          ----------------------------------
362*627f7eb2Smrg 	 *             0     s-c             c+s
363*627f7eb2Smrg 	 *             1    -s-c            -c+s
364*627f7eb2Smrg 	 *             2    -s+c            -c-s
365*627f7eb2Smrg 	 *             3     s+c             c-s
366*627f7eb2Smrg 	 */
367*627f7eb2Smrg 	__float128 s;
368*627f7eb2Smrg 	__float128 c;
369*627f7eb2Smrg 	sincosq (x, &s, &c);
370*627f7eb2Smrg 	switch (n & 3)
371*627f7eb2Smrg 	  {
372*627f7eb2Smrg 	  case 0:
373*627f7eb2Smrg 	    temp = s - c;
374*627f7eb2Smrg 	    break;
375*627f7eb2Smrg 	  case 1:
376*627f7eb2Smrg 	    temp = -s - c;
377*627f7eb2Smrg 	    break;
378*627f7eb2Smrg 	  case 2:
379*627f7eb2Smrg 	    temp = -s + c;
380*627f7eb2Smrg 	    break;
381*627f7eb2Smrg 	  case 3:
382*627f7eb2Smrg 	    temp = s + c;
383*627f7eb2Smrg 	    break;
384*627f7eb2Smrg 	  }
385*627f7eb2Smrg 	b = invsqrtpi * temp / sqrtq (x);
386*627f7eb2Smrg       }
387*627f7eb2Smrg     else
388*627f7eb2Smrg       {
389*627f7eb2Smrg 	a = y0q (x);
390*627f7eb2Smrg 	b = y1q (x);
391*627f7eb2Smrg 	/* quit if b is -inf */
392*627f7eb2Smrg 	u.value = b;
393*627f7eb2Smrg 	se = u.words32.w0 & 0xffff0000;
394*627f7eb2Smrg 	for (i = 1; i < n && se != 0xffff0000; i++)
395*627f7eb2Smrg 	  {
396*627f7eb2Smrg 	    temp = b;
397*627f7eb2Smrg 	    b = ((__float128) (i + i) / x) * b - a;
398*627f7eb2Smrg 	    u.value = b;
399*627f7eb2Smrg 	    se = u.words32.w0 & 0xffff0000;
400*627f7eb2Smrg 	    a = temp;
401*627f7eb2Smrg 	  }
402*627f7eb2Smrg       }
403*627f7eb2Smrg     /* If B is +-Inf, set up errno accordingly.  */
404*627f7eb2Smrg     if (! finiteq (b))
405*627f7eb2Smrg       errno = ERANGE;
406*627f7eb2Smrg     if (sign > 0)
407*627f7eb2Smrg       ret = b;
408*627f7eb2Smrg     else
409*627f7eb2Smrg       ret = -b;
410*627f7eb2Smrg   }
411*627f7eb2Smrg  out:
412*627f7eb2Smrg   if (isinfq (ret))
413*627f7eb2Smrg     ret = copysignq (FLT128_MAX, ret) * FLT128_MAX;
414*627f7eb2Smrg   return ret;
415*627f7eb2Smrg }
416