| 1 | /* |
| 2 | * ==================================================== |
| 3 | * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. |
| 4 | * |
| 5 | * Developed at SunPro, a Sun Microsystems, Inc. business. |
| 6 | * Permission to use, copy, modify, and distribute this |
| 7 | * software is freely granted, provided that this notice |
| 8 | * is preserved. |
| 9 | * ==================================================== |
| 10 | */ |
| 11 | |
| 12 | /* Long double expansions are |
| 13 | Copyright (C) 2001 Stephen L. Moshier <moshier@na-net.ornl.gov> |
| 14 | and are incorporated herein by permission of the author. The author |
| 15 | reserves the right to distribute this material elsewhere under different |
| 16 | copying permissions. These modifications are distributed here under |
| 17 | the following terms: |
| 18 | |
| 19 | This library is free software; you can redistribute it and/or |
| 20 | modify it under the terms of the GNU Lesser General Public |
| 21 | License as published by the Free Software Foundation; either |
| 22 | version 2.1 of the License, or (at your option) any later version. |
| 23 | |
| 24 | This library is distributed in the hope that it will be useful, |
| 25 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 26 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 27 | Lesser General Public License for more details. |
| 28 | |
| 29 | You should have received a copy of the GNU Lesser General Public |
| 30 | License along with this library; if not, see |
| 31 | <https://www.gnu.org/licenses/>. */ |
| 32 | |
| 33 | /* __ieee754_j0(x), __ieee754_y0(x) |
| 34 | * Bessel function of the first and second kinds of order zero. |
| 35 | * Method -- j0(x): |
| 36 | * 1. For tiny x, we use j0(x) = 1 - x^2/4 + x^4/64 - ... |
| 37 | * 2. Reduce x to |x| since j0(x)=j0(-x), and |
| 38 | * for x in (0,2) |
| 39 | * j0(x) = 1 - z/4 + z^2*R0/S0, where z = x*x; |
| 40 | * for x in (2,inf) |
| 41 | * j0(x) = sqrt(2/(pi*x))*(p0(x)*cos(x0)-q0(x)*sin(x0)) |
| 42 | * where x0 = x-pi/4. It is better to compute sin(x0),cos(x0) |
| 43 | * as follow: |
| 44 | * cos(x0) = cos(x)cos(pi/4)+sin(x)sin(pi/4) |
| 45 | * = 1/sqrt(2) * (cos(x) + sin(x)) |
| 46 | * sin(x0) = sin(x)cos(pi/4)-cos(x)sin(pi/4) |
| 47 | * = 1/sqrt(2) * (sin(x) - cos(x)) |
| 48 | * (To avoid cancellation, use |
| 49 | * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x)) |
| 50 | * to compute the worse one.) |
| 51 | * |
| 52 | * 3 Special cases |
| 53 | * j0(nan)= nan |
| 54 | * j0(0) = 1 |
| 55 | * j0(inf) = 0 |
| 56 | * |
| 57 | * Method -- y0(x): |
| 58 | * 1. For x<2. |
| 59 | * Since |
| 60 | * y0(x) = 2/pi*(j0(x)*(ln(x/2)+Euler) + x^2/4 - ...) |
| 61 | * therefore y0(x)-2/pi*j0(x)*ln(x) is an even function. |
| 62 | * We use the following function to approximate y0, |
| 63 | * y0(x) = U(z)/V(z) + (2/pi)*(j0(x)*ln(x)), z= x^2 |
| 64 | * |
| 65 | * Note: For tiny x, U/V = u0 and j0(x)~1, hence |
| 66 | * y0(tiny) = u0 + (2/pi)*ln(tiny), (choose tiny<2**-27) |
| 67 | * 2. For x>=2. |
| 68 | * y0(x) = sqrt(2/(pi*x))*(p0(x)*cos(x0)+q0(x)*sin(x0)) |
| 69 | * where x0 = x-pi/4. It is better to compute sin(x0),cos(x0) |
| 70 | * by the method mentioned above. |
| 71 | * 3. Special cases: y0(0)=-inf, y0(x<0)=NaN, y0(inf)=0. |
| 72 | */ |
| 73 | |
| 74 | #include <math.h> |
| 75 | #include <math-barriers.h> |
| 76 | #include <math_private.h> |
| 77 | #include <libm-alias-finite.h> |
| 78 | |
| 79 | static long double pzero (long double), qzero (long double); |
| 80 | |
| 81 | static const long double |
| 82 | huge = 1e4930L, |
| 83 | one = 1.0L, |
| 84 | invsqrtpi = 5.6418958354775628694807945156077258584405e-1L, |
| 85 | tpi = 6.3661977236758134307553505349005744813784e-1L, |
| 86 | |
| 87 | /* J0(x) = 1 - x^2 / 4 + x^4 R0(x^2) / S0(x^2) |
| 88 | 0 <= x <= 2 |
| 89 | peak relative error 1.41e-22 */ |
| 90 | R[5] = { |
| 91 | 4.287176872744686992880841716723478740566E7L, |
| 92 | -6.652058897474241627570911531740907185772E5L, |
| 93 | 7.011848381719789863458364584613651091175E3L, |
| 94 | -3.168040850193372408702135490809516253693E1L, |
| 95 | 6.030778552661102450545394348845599300939E-2L, |
| 96 | }, |
| 97 | |
| 98 | S[4] = { |
| 99 | 2.743793198556599677955266341699130654342E9L, |
| 100 | 3.364330079384816249840086842058954076201E7L, |
| 101 | 1.924119649412510777584684927494642526573E5L, |
| 102 | 6.239282256012734914211715620088714856494E2L, |
| 103 | /* 1.000000000000000000000000000000000000000E0L,*/ |
| 104 | }; |
| 105 | |
| 106 | static const long double zero = 0.0; |
| 107 | |
| 108 | long double |
| 109 | __ieee754_j0l (long double x) |
| 110 | { |
| 111 | long double z, s, c, ss, cc, r, u, v; |
| 112 | int32_t ix; |
| 113 | uint32_t se; |
| 114 | |
| 115 | GET_LDOUBLE_EXP (se, x); |
| 116 | ix = se & 0x7fff; |
| 117 | if (__glibc_unlikely (ix >= 0x7fff)) |
| 118 | return one / (x * x); |
| 119 | x = fabsl (x); |
| 120 | if (ix >= 0x4000) /* |x| >= 2.0 */ |
| 121 | { |
| 122 | __sincosl (x, &s, &c); |
| 123 | ss = s - c; |
| 124 | cc = s + c; |
| 125 | if (ix < 0x7ffe) |
| 126 | { /* make sure x+x not overflow */ |
| 127 | z = -__cosl (x + x); |
| 128 | if ((s * c) < zero) |
| 129 | cc = z / ss; |
| 130 | else |
| 131 | ss = z / cc; |
| 132 | } |
| 133 | /* |
| 134 | * j0(x) = 1/sqrt(pi) * (P(0,x)*cc - Q(0,x)*ss) / sqrt(x) |
| 135 | * y0(x) = 1/sqrt(pi) * (P(0,x)*ss + Q(0,x)*cc) / sqrt(x) |
| 136 | */ |
| 137 | if (__glibc_unlikely (ix > 0x408e)) /* 2^143 */ |
| 138 | z = (invsqrtpi * cc) / sqrtl (x); |
| 139 | else |
| 140 | { |
| 141 | u = pzero (x); |
| 142 | v = qzero (x); |
| 143 | z = invsqrtpi * (u * cc - v * ss) / sqrtl (x); |
| 144 | } |
| 145 | return z; |
| 146 | } |
| 147 | if (__glibc_unlikely (ix < 0x3fef)) /* |x| < 2**-16 */ |
| 148 | { |
| 149 | /* raise inexact if x != 0 */ |
| 150 | math_force_eval (huge + x); |
| 151 | if (ix < 0x3fde) /* |x| < 2^-33 */ |
| 152 | return one; |
| 153 | else |
| 154 | return one - 0.25 * x * x; |
| 155 | } |
| 156 | z = x * x; |
| 157 | r = z * (R[0] + z * (R[1] + z * (R[2] + z * (R[3] + z * R[4])))); |
| 158 | s = S[0] + z * (S[1] + z * (S[2] + z * (S[3] + z))); |
| 159 | if (ix < 0x3fff) |
| 160 | { /* |x| < 1.00 */ |
| 161 | return (one - 0.25 * z + z * (r / s)); |
| 162 | } |
| 163 | else |
| 164 | { |
| 165 | u = 0.5 * x; |
| 166 | return ((one + u) * (one - u) + z * (r / s)); |
| 167 | } |
| 168 | } |
| 169 | libm_alias_finite (__ieee754_j0l, __j0l) |
| 170 | |
| 171 | |
| 172 | /* y0(x) = 2/pi ln(x) J0(x) + U(x^2)/V(x^2) |
| 173 | 0 < x <= 2 |
| 174 | peak relative error 1.7e-21 */ |
| 175 | static const long double |
| 176 | U[6] = { |
| 177 | -1.054912306975785573710813351985351350861E10L, |
| 178 | 2.520192609749295139432773849576523636127E10L, |
| 179 | -1.856426071075602001239955451329519093395E9L, |
| 180 | 4.079209129698891442683267466276785956784E7L, |
| 181 | -3.440684087134286610316661166492641011539E5L, |
| 182 | 1.005524356159130626192144663414848383774E3L, |
| 183 | }; |
| 184 | static const long double |
| 185 | V[5] = { |
| 186 | 1.429337283720789610137291929228082613676E11L, |
| 187 | 2.492593075325119157558811370165695013002E9L, |
| 188 | 2.186077620785925464237324417623665138376E7L, |
| 189 | 1.238407896366385175196515057064384929222E5L, |
| 190 | 4.693924035211032457494368947123233101664E2L, |
| 191 | /* 1.000000000000000000000000000000000000000E0L */ |
| 192 | }; |
| 193 | |
| 194 | long double |
| 195 | __ieee754_y0l (long double x) |
| 196 | { |
| 197 | long double z, s, c, ss, cc, u, v; |
| 198 | int32_t ix; |
| 199 | uint32_t se, i0, i1; |
| 200 | |
| 201 | GET_LDOUBLE_WORDS (se, i0, i1, x); |
| 202 | ix = se & 0x7fff; |
| 203 | /* Y0(NaN) is NaN, y0(-inf) is Nan, y0(inf) is 0 */ |
| 204 | if (__glibc_unlikely (se & 0x8000)) |
| 205 | return zero / (zero * x); |
| 206 | if (__glibc_unlikely (ix >= 0x7fff)) |
| 207 | return one / (x + x * x); |
| 208 | if (__glibc_unlikely ((i0 | i1) == 0)) |
| 209 | return -HUGE_VALL + x; /* -inf and overflow exception. */ |
| 210 | if (ix >= 0x4000) |
| 211 | { /* |x| >= 2.0 */ |
| 212 | |
| 213 | /* y0(x) = sqrt(2/(pi*x))*(p0(x)*sin(x0)+q0(x)*cos(x0)) |
| 214 | * where x0 = x-pi/4 |
| 215 | * Better formula: |
| 216 | * cos(x0) = cos(x)cos(pi/4)+sin(x)sin(pi/4) |
| 217 | * = 1/sqrt(2) * (sin(x) + cos(x)) |
| 218 | * sin(x0) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4) |
| 219 | * = 1/sqrt(2) * (sin(x) - cos(x)) |
| 220 | * To avoid cancellation, use |
| 221 | * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x)) |
| 222 | * to compute the worse one. |
| 223 | */ |
| 224 | __sincosl (x, &s, &c); |
| 225 | ss = s - c; |
| 226 | cc = s + c; |
| 227 | /* |
| 228 | * j0(x) = 1/sqrt(pi) * (P(0,x)*cc - Q(0,x)*ss) / sqrt(x) |
| 229 | * y0(x) = 1/sqrt(pi) * (P(0,x)*ss + Q(0,x)*cc) / sqrt(x) |
| 230 | */ |
| 231 | if (ix < 0x7ffe) |
| 232 | { /* make sure x+x not overflow */ |
| 233 | z = -__cosl (x + x); |
| 234 | if ((s * c) < zero) |
| 235 | cc = z / ss; |
| 236 | else |
| 237 | ss = z / cc; |
| 238 | } |
| 239 | if (__glibc_unlikely (ix > 0x408e)) /* 2^143 */ |
| 240 | z = (invsqrtpi * ss) / sqrtl (x); |
| 241 | else |
| 242 | { |
| 243 | u = pzero (x); |
| 244 | v = qzero (x); |
| 245 | z = invsqrtpi * (u * ss + v * cc) / sqrtl (x); |
| 246 | } |
| 247 | return z; |
| 248 | } |
| 249 | if (__glibc_unlikely (ix <= 0x3fde)) /* x < 2^-33 */ |
| 250 | { |
| 251 | z = -7.380429510868722527629822444004602747322E-2L |
| 252 | + tpi * __ieee754_logl (x); |
| 253 | return z; |
| 254 | } |
| 255 | z = x * x; |
| 256 | u = U[0] + z * (U[1] + z * (U[2] + z * (U[3] + z * (U[4] + z * U[5])))); |
| 257 | v = V[0] + z * (V[1] + z * (V[2] + z * (V[3] + z * (V[4] + z)))); |
| 258 | return (u / v + tpi * (__ieee754_j0l (x) * __ieee754_logl (x))); |
| 259 | } |
| 260 | libm_alias_finite (__ieee754_y0l, __y0l) |
| 261 | |
| 262 | /* The asymptotic expansions of pzero is |
| 263 | * 1 - 9/128 s^2 + 11025/98304 s^4 - ..., where s = 1/x. |
| 264 | * For x >= 2, We approximate pzero by |
| 265 | * pzero(x) = 1 + s^2 R(s^2) / S(s^2) |
| 266 | */ |
| 267 | static const long double pR8[7] = { |
| 268 | /* 8 <= x <= inf |
| 269 | Peak relative error 4.62 */ |
| 270 | -4.094398895124198016684337960227780260127E-9L, |
| 271 | -8.929643669432412640061946338524096893089E-7L, |
| 272 | -6.281267456906136703868258380673108109256E-5L, |
| 273 | -1.736902783620362966354814353559382399665E-3L, |
| 274 | -1.831506216290984960532230842266070146847E-2L, |
| 275 | -5.827178869301452892963280214772398135283E-2L, |
| 276 | -2.087563267939546435460286895807046616992E-2L, |
| 277 | }; |
| 278 | static const long double pS8[6] = { |
| 279 | 5.823145095287749230197031108839653988393E-8L, |
| 280 | 1.279281986035060320477759999428992730280E-5L, |
| 281 | 9.132668954726626677174825517150228961304E-4L, |
| 282 | 2.606019379433060585351880541545146252534E-2L, |
| 283 | 2.956262215119520464228467583516287175244E-1L, |
| 284 | 1.149498145388256448535563278632697465675E0L, |
| 285 | /* 1.000000000000000000000000000000000000000E0L, */ |
| 286 | }; |
| 287 | |
| 288 | static const long double pR5[7] = { |
| 289 | /* 4.54541015625 <= x <= 8 |
| 290 | Peak relative error 6.51E-22 */ |
| 291 | -2.041226787870240954326915847282179737987E-7L, |
| 292 | -2.255373879859413325570636768224534428156E-5L, |
| 293 | -7.957485746440825353553537274569102059990E-4L, |
| 294 | -1.093205102486816696940149222095559439425E-2L, |
| 295 | -5.657957849316537477657603125260701114646E-2L, |
| 296 | -8.641175552716402616180994954177818461588E-2L, |
| 297 | -1.354654710097134007437166939230619726157E-2L, |
| 298 | }; |
| 299 | static const long double pS5[6] = { |
| 300 | 2.903078099681108697057258628212823545290E-6L, |
| 301 | 3.253948449946735405975737677123673867321E-4L, |
| 302 | 1.181269751723085006534147920481582279979E-2L, |
| 303 | 1.719212057790143888884745200257619469363E-1L, |
| 304 | 1.006306498779212467670654535430694221924E0L, |
| 305 | 2.069568808688074324555596301126375951502E0L, |
| 306 | /* 1.000000000000000000000000000000000000000E0L, */ |
| 307 | }; |
| 308 | |
| 309 | static const long double pR3[7] = { |
| 310 | /* 2.85711669921875 <= x <= 4.54541015625 |
| 311 | peak relative error 5.25e-21 */ |
| 312 | -5.755732156848468345557663552240816066802E-6L, |
| 313 | -3.703675625855715998827966962258113034767E-4L, |
| 314 | -7.390893350679637611641350096842846433236E-3L, |
| 315 | -5.571922144490038765024591058478043873253E-2L, |
| 316 | -1.531290690378157869291151002472627396088E-1L, |
| 317 | -1.193350853469302941921647487062620011042E-1L, |
| 318 | -8.567802507331578894302991505331963782905E-3L, |
| 319 | }; |
| 320 | static const long double pS3[6] = { |
| 321 | 8.185931139070086158103309281525036712419E-5L, |
| 322 | 5.398016943778891093520574483111255476787E-3L, |
| 323 | 1.130589193590489566669164765853409621081E-1L, |
| 324 | 9.358652328786413274673192987670237145071E-1L, |
| 325 | 3.091711512598349056276917907005098085273E0L, |
| 326 | 3.594602474737921977972586821673124231111E0L, |
| 327 | /* 1.000000000000000000000000000000000000000E0L, */ |
| 328 | }; |
| 329 | |
| 330 | static const long double pR2[7] = { |
| 331 | /* 2 <= x <= 2.85711669921875 |
| 332 | peak relative error 2.64e-21 */ |
| 333 | -1.219525235804532014243621104365384992623E-4L, |
| 334 | -4.838597135805578919601088680065298763049E-3L, |
| 335 | -5.732223181683569266223306197751407418301E-2L, |
| 336 | -2.472947430526425064982909699406646503758E-1L, |
| 337 | -3.753373645974077960207588073975976327695E-1L, |
| 338 | -1.556241316844728872406672349347137975495E-1L, |
| 339 | -5.355423239526452209595316733635519506958E-3L, |
| 340 | }; |
| 341 | static const long double pS2[6] = { |
| 342 | 1.734442793664291412489066256138894953823E-3L, |
| 343 | 7.158111826468626405416300895617986926008E-2L, |
| 344 | 9.153839713992138340197264669867993552641E-1L, |
| 345 | 4.539209519433011393525841956702487797582E0L, |
| 346 | 8.868932430625331650266067101752626253644E0L, |
| 347 | 6.067161890196324146320763844772857713502E0L, |
| 348 | /* 1.000000000000000000000000000000000000000E0L, */ |
| 349 | }; |
| 350 | |
| 351 | static long double |
| 352 | pzero (long double x) |
| 353 | { |
| 354 | const long double *p, *q; |
| 355 | long double z, r, s; |
| 356 | int32_t ix; |
| 357 | uint32_t se, i0, i1; |
| 358 | |
| 359 | GET_LDOUBLE_WORDS (se, i0, i1, x); |
| 360 | ix = se & 0x7fff; |
| 361 | /* ix >= 0x4000 for all calls to this function. */ |
| 362 | if (ix >= 0x4002) |
| 363 | { |
| 364 | p = pR8; |
| 365 | q = pS8; |
| 366 | } /* x >= 8 */ |
| 367 | else |
| 368 | { |
| 369 | i1 = (ix << 16) | (i0 >> 16); |
| 370 | if (i1 >= 0x40019174) /* x >= 4.54541015625 */ |
| 371 | { |
| 372 | p = pR5; |
| 373 | q = pS5; |
| 374 | } |
| 375 | else if (i1 >= 0x4000b6db) /* x >= 2.85711669921875 */ |
| 376 | { |
| 377 | p = pR3; |
| 378 | q = pS3; |
| 379 | } |
| 380 | else /* x >= 2 */ |
| 381 | { |
| 382 | p = pR2; |
| 383 | q = pS2; |
| 384 | } |
| 385 | } |
| 386 | z = one / (x * x); |
| 387 | r = |
| 388 | p[0] + z * (p[1] + |
| 389 | z * (p[2] + z * (p[3] + z * (p[4] + z * (p[5] + z * p[6]))))); |
| 390 | s = |
| 391 | q[0] + z * (q[1] + z * (q[2] + z * (q[3] + z * (q[4] + z * (q[5] + z))))); |
| 392 | return (one + z * r / s); |
| 393 | } |
| 394 | |
| 395 | |
| 396 | /* For x >= 8, the asymptotic expansions of qzero is |
| 397 | * -1/8 s + 75/1024 s^3 - ..., where s = 1/x. |
| 398 | * We approximate qzero by |
| 399 | * qzero(x) = s*(-.125 + R(s^2) / S(s^2)) |
| 400 | */ |
| 401 | static const long double qR8[7] = { |
| 402 | /* 8 <= x <= inf |
| 403 | peak relative error 2.23e-21 */ |
| 404 | 3.001267180483191397885272640777189348008E-10L, |
| 405 | 8.693186311430836495238494289942413810121E-8L, |
| 406 | 8.496875536711266039522937037850596580686E-6L, |
| 407 | 3.482702869915288984296602449543513958409E-4L, |
| 408 | 6.036378380706107692863811938221290851352E-3L, |
| 409 | 3.881970028476167836382607922840452192636E-2L, |
| 410 | 6.132191514516237371140841765561219149638E-2L, |
| 411 | }; |
| 412 | static const long double qS8[7] = { |
| 413 | 4.097730123753051126914971174076227600212E-9L, |
| 414 | 1.199615869122646109596153392152131139306E-6L, |
| 415 | 1.196337580514532207793107149088168946451E-4L, |
| 416 | 5.099074440112045094341500497767181211104E-3L, |
| 417 | 9.577420799632372483249761659674764460583E-2L, |
| 418 | 7.385243015344292267061953461563695918646E-1L, |
| 419 | 1.917266424391428937962682301561699055943E0L, |
| 420 | /* 1.000000000000000000000000000000000000000E0L, */ |
| 421 | }; |
| 422 | |
| 423 | static const long double qR5[7] = { |
| 424 | /* 4.54541015625 <= x <= 8 |
| 425 | peak relative error 1.03e-21 */ |
| 426 | 3.406256556438974327309660241748106352137E-8L, |
| 427 | 4.855492710552705436943630087976121021980E-6L, |
| 428 | 2.301011739663737780613356017352912281980E-4L, |
| 429 | 4.500470249273129953870234803596619899226E-3L, |
| 430 | 3.651376459725695502726921248173637054828E-2L, |
| 431 | 1.071578819056574524416060138514508609805E-1L, |
| 432 | 7.458950172851611673015774675225656063757E-2L, |
| 433 | }; |
| 434 | static const long double qS5[7] = { |
| 435 | 4.650675622764245276538207123618745150785E-7L, |
| 436 | 6.773573292521412265840260065635377164455E-5L, |
| 437 | 3.340711249876192721980146877577806687714E-3L, |
| 438 | 7.036218046856839214741678375536970613501E-2L, |
| 439 | 6.569599559163872573895171876511377891143E-1L, |
| 440 | 2.557525022583599204591036677199171155186E0L, |
| 441 | 3.457237396120935674982927714210361269133E0L, |
| 442 | /* 1.000000000000000000000000000000000000000E0L,*/ |
| 443 | }; |
| 444 | |
| 445 | static const long double qR3[7] = { |
| 446 | /* 2.85711669921875 <= x <= 4.54541015625 |
| 447 | peak relative error 5.24e-21 */ |
| 448 | 1.749459596550816915639829017724249805242E-6L, |
| 449 | 1.446252487543383683621692672078376929437E-4L, |
| 450 | 3.842084087362410664036704812125005761859E-3L, |
| 451 | 4.066369994699462547896426554180954233581E-2L, |
| 452 | 1.721093619117980251295234795188992722447E-1L, |
| 453 | 2.538595333972857367655146949093055405072E-1L, |
| 454 | 8.560591367256769038905328596020118877936E-2L, |
| 455 | }; |
| 456 | static const long double qS3[7] = { |
| 457 | 2.388596091707517488372313710647510488042E-5L, |
| 458 | 2.048679968058758616370095132104333998147E-3L, |
| 459 | 5.824663198201417760864458765259945181513E-2L, |
| 460 | 6.953906394693328750931617748038994763958E-1L, |
| 461 | 3.638186936390881159685868764832961092476E0L, |
| 462 | 7.900169524705757837298990558459547842607E0L, |
| 463 | 5.992718532451026507552820701127504582907E0L, |
| 464 | /* 1.000000000000000000000000000000000000000E0L, */ |
| 465 | }; |
| 466 | |
| 467 | static const long double qR2[7] = { |
| 468 | /* 2 <= x <= 2.85711669921875 |
| 469 | peak relative error 1.58e-21 */ |
| 470 | 6.306524405520048545426928892276696949540E-5L, |
| 471 | 3.209606155709930950935893996591576624054E-3L, |
| 472 | 5.027828775702022732912321378866797059604E-2L, |
| 473 | 3.012705561838718956481911477587757845163E-1L, |
| 474 | 6.960544893905752937420734884995688523815E-1L, |
| 475 | 5.431871999743531634887107835372232030655E-1L, |
| 476 | 9.447736151202905471899259026430157211949E-2L, |
| 477 | }; |
| 478 | static const long double qS2[7] = { |
| 479 | 8.610579901936193494609755345106129102676E-4L, |
| 480 | 4.649054352710496997203474853066665869047E-2L, |
| 481 | 8.104282924459837407218042945106320388339E-1L, |
| 482 | 5.807730930825886427048038146088828206852E0L, |
| 483 | 1.795310145936848873627710102199881642939E1L, |
| 484 | 2.281313316875375733663657188888110605044E1L, |
| 485 | 1.011242067883822301487154844458322200143E1L, |
| 486 | /* 1.000000000000000000000000000000000000000E0L, */ |
| 487 | }; |
| 488 | |
| 489 | static long double |
| 490 | qzero (long double x) |
| 491 | { |
| 492 | const long double *p, *q; |
| 493 | long double s, r, z; |
| 494 | int32_t ix; |
| 495 | uint32_t se, i0, i1; |
| 496 | |
| 497 | GET_LDOUBLE_WORDS (se, i0, i1, x); |
| 498 | ix = se & 0x7fff; |
| 499 | /* ix >= 0x4000 for all calls to this function. */ |
| 500 | if (ix >= 0x4002) /* x >= 8 */ |
| 501 | { |
| 502 | p = qR8; |
| 503 | q = qS8; |
| 504 | } |
| 505 | else |
| 506 | { |
| 507 | i1 = (ix << 16) | (i0 >> 16); |
| 508 | if (i1 >= 0x40019174) /* x >= 4.54541015625 */ |
| 509 | { |
| 510 | p = qR5; |
| 511 | q = qS5; |
| 512 | } |
| 513 | else if (i1 >= 0x4000b6db) /* x >= 2.85711669921875 */ |
| 514 | { |
| 515 | p = qR3; |
| 516 | q = qS3; |
| 517 | } |
| 518 | else /* x >= 2 */ |
| 519 | { |
| 520 | p = qR2; |
| 521 | q = qS2; |
| 522 | } |
| 523 | } |
| 524 | z = one / (x * x); |
| 525 | r = |
| 526 | p[0] + z * (p[1] + |
| 527 | z * (p[2] + z * (p[3] + z * (p[4] + z * (p[5] + z * p[6]))))); |
| 528 | s = |
| 529 | q[0] + z * (q[1] + |
| 530 | z * (q[2] + |
| 531 | z * (q[3] + z * (q[4] + z * (q[5] + z * (q[6] + z)))))); |
| 532 | return (-.125 + z * r / s) / x; |
| 533 | } |
| 534 | |