@ -16,7 +16,9 @@
# include <math.h>
# include <math-barriers.h>
# include <math_private.h>
# include <fenv_private.h>
# include <libm-alias-finite.h>
# include <reduce_aux.h>
static float pzerof ( float ) , qzerof ( float ) ;
@ -37,6 +39,218 @@ S04 = 1.1661400734e-09; /* 0x30a045e8 */
static const float zero = 0.0 ;
/* This is the nearest approximation of the first zero of j0. */
# define FIRST_ZERO_J0 0xf.26247p-28f
# define SMALL_SIZE 64
/* The following table contains successive zeros of j0 and degree-3
polynomial approximations of j0 around these zeros : Pj [ 0 ] for the first
zero ( 2.40482 ) , Pj [ 1 ] for the second one ( 5.520078 ) , and so on .
Each line contains :
{ x0 , xmid , x1 , p0 , p1 , p2 , p3 }
where [ x0 , x1 ] is the interval around the zero , xmid is the binary32 number
closest to the zero , and p0 + p1 * x + p2 * x ^ 2 + p3 * x ^ 3 is the approximation
polynomial . Each polynomial was generated using Sollya on the interval
[ x0 , x1 ] around the corresponding zero where the error exceeds 9 ulps
for the alternate code . Degree 3 is enough to get an error < = 9 ulps .
*/
static const float Pj [ SMALL_SIZE ] [ 7 ] = {
/* The following polynomial was optimized by hand with respect to the one
generated by Sollya , to ensure the maximal error is at most 9 ulps ,
both if the polynomial is evaluated with fma or not . */
{ 0x1 .31e5 c4p + 1 , 0x1 .33 d152p + 1 , 0x1 .3 b58dep + 1 , 0xf .2623f p - 28 ,
- 0x8 .4e6 d7p - 4 , 0x1 . ba2aaap - 4 , 0xe .4 b9ap - 8 } , /* 0 */
{ 0x1 .60 eafap + 2 , 0x1 .6148f 6 p + 2 , 0x1 .62955 cp + 2 , 0x6 .9205f p - 28 ,
0x5 .71 b98p - 4 , - 0x7 . e3e798p - 8 , - 0xd .87 d1p - 8 } , /* 1 */
{ 0x1 .14 cde2p + 3 , 0x1 .14 eb56p + 3 , 0x1 .1525 c6p + 3 , 0x1 . bcc1cap - 24 ,
- 0x4 .57 de6p - 4 , 0x4 .03e7 cp - 8 , 0xb .39 a37p - 8 } , /* 2 */
{ 0x1 .7931 d8p + 3 , 0x1 .79544 p + 3 , 0x1 .7998 d6p + 3 , - 0xf .2976f p - 32 ,
0x3 . b827ccp - 4 , - 0x2 .8603 ep - 8 , - 0x9 . bf49bp - 8 } , /* 3 */
{ 0x1 . ddb6d4p + 3 , 0x1 . ddca14p + 3 , 0x1 . ddf0c8p + 3 , - 0x1 . bd67d8p - 28 ,
- 0x3 .4e03 ap - 4 , 0x1 . c562a2p - 8 , 0x8 .90 ec2p - 8 } , /* 4 */
{ 0x1 .2118e4 p + 4 , 0x1 .212314 p + 4 , 0x1 .21375 p + 4 , 0x1 .62209 cp - 28 ,
0x3 .00 efecp - 4 , - 0x1 .5458 dap - 8 , - 0x8 .10063 p - 8 } , /* 5 */
{ 0x1 .535 d28p + 4 , 0x1 .5362 dep + 4 , 0x1 .536e48 p + 4 , - 0x2 .853f 74 p - 24 ,
- 0x2 . c5b274p - 4 , 0x1 .0 b9db4p - 8 , 0x7 .8 c3578p - 8 } , /* 6 */
{ 0x1 .859 ddp + 4 , 0x1 .85 a3bap + 4 , 0x1 .85 aff4p + 4 , 0x2 .19 ed1cp - 24 ,
0x2 .96545 cp - 4 , - 0xd .997e6 p - 12 , - 0x6 . d9af28p - 8 } , /* 7 */
{ 0x1 . b7decap + 4 , 0x1 . b7e54ap + 4 , 0x1 . b7f038p + 4 , 0xe .959 aep - 28 ,
- 0x2 .6f 5594 p - 4 , 0xb .538 dp - 12 , 0x7 .003 ea8p - 8 } , /* 8 */
{ 0x1 . ea21c6p + 4 , 0x1 . ea275ap + 4 , 0x1 . ea337ap + 4 , 0x2 .0 c3964p - 24 ,
0x2 .4e80 fcp - 4 , - 0x9 . a2216p - 12 , - 0x6 .61e0 a8p - 8 } , /* 9 */
{ 0x1 .0e3316 p + 5 , 0x1 .0e34 e2p + 5 , 0x1 .0e379 ap + 5 , - 0x3 .642554 p - 24 ,
- 0x2 .325e48 p - 4 , 0x8 .4f 49 cp - 12 , 0x7 . d37c3p - 8 } , /* 10 */
{ 0x1 .275456 p + 5 , 0x1 .275638 p + 5 , 0x1 .2759e2 p + 5 , 0x1 .6 c015ap - 24 ,
0x2 .19e7 d8p - 4 , - 0x7 .4 c1bf8p - 12 , - 0x4 . af7ef8p - 8 } , /* 11 */
{ 0x1 .4075 ecp + 5 , 0x1 .4077 a8p + 5 , 0x1 .407 b96p + 5 , - 0x4 . b18c9p - 28 ,
- 0x2 .046174 p - 4 , 0x6 .705618 p - 12 , 0x5 . f2d28p - 8 } , /* 12 */
{ 0x1 .59973 p + 5 , 0x1 .59992 cp + 5 , 0x1 .599 b2ap + 5 , - 0x1 .8 b8792p - 24 ,
0x1 . f13fbp - 4 , - 0x5 . c14938p - 12 , - 0x5 .73e0 cp - 8 } , /* 13 */
{ 0x1 .72 b958p + 5 , 0x1 .72 bacp + 5 , 0x1 .72 bc5ap + 5 , 0x3 . a26e0cp - 24 ,
- 0x1 . e018dap - 4 , 0x5 .30e8 dp - 12 , 0x2 .81099 p - 8 } , /* 14 */
{ 0x1 .8 bdb4ap + 5 , 0x1 .8 bdc62p + 5 , 0x1 .8 bde7ep + 5 , - 0x2 .18f abcp - 24 ,
0x1 . d09b22p - 4 , - 0x4 . b0b688p - 12 , - 0x5 .5f d308p - 8 } , /* 15 */
{ 0x1 . a4fcecp + 5 , 0x1 . a4fe0ep + 5 , 0x1 . a50042p + 5 , 0x3 .2370e8 p - 24 ,
- 0x1 . c28614p - 4 , 0x4 .4647e8 p - 12 , 0x5 .68 a28p - 8 } , /* 16 */
{ 0x1 . be1ebcp + 5 , 0x1 . be1fc4p + 5 , 0x1 . be21fp + 5 , - 0x5 .9 eae3p - 28 ,
0x1 . b5a622p - 4 , - 0x3 . eb9054p - 12 , - 0x5 .12 d8cp - 8 } , /* 17 */
{ 0x1 . d7405p + 5 , 0x1 . d7418p + 5 , 0x1 . d74294p + 5 , 0x2 .9f a1e8p - 24 ,
- 0x1 . a9d184p - 4 , 0x3 .9 d1e7p - 12 , 0x4 .33 d058p - 8 } , /* 18 */
{ 0x1 . f0624p + 5 , 0x1 . f06344p + 5 , 0x1 . f0645ep + 5 , 0x9 .9 ac67p - 28 ,
0x1 .9 ee5eep - 4 , - 0x3 .5816e8 p - 12 , - 0x2 .6e5004 p - 8 } , /* 19 */
{ 0x1 .04 c22ep + 6 , 0x1 .04 c286p + 6 , 0x1 .04 c316p + 6 , 0xd .6 ab94p - 28 ,
- 0x1 .94 c6f6p - 4 , 0x3 .174 efcp - 12 , 0x7 .9 a092p - 8 } , /* 20 */
{ 0x1 .1153 p + 6 , 0x1 .11536 cp + 6 , 0x1 .11541 p + 6 , - 0x4 .4 cb2d8p - 24 ,
0x1 .8 b5cccp - 4 , - 0x2 . e3c238p - 12 , - 0x4 . e5437p - 8 } , /* 21 */
{ 0x1 .1 de3d8p + 6 , 0x1 .1 de456p + 6 , 0x1 .1 de4dap + 6 , - 0x4 .4 aa8c8p - 24 ,
- 0x1 .829356 p - 4 , 0x2 . b45124p - 12 , 0x5 . baf638p - 8 } , /* 22 */
{ 0x1 .2 a74f8p + 6 , 0x1 .2 a754p + 6 , 0x1 .2 a75bp + 6 , 0x2 .077 c38p - 24 ,
0x1 .7 a597ep - 4 , - 0x2 .8 a0414p - 12 , - 0x2 .838 d3p - 8 } , /* 23 */
{ 0x1 .3705 d4p + 6 , 0x1 .37062 cp + 6 , 0x1 .3706 b2p + 6 , - 0x2 .6 a6cd8p - 24 ,
- 0x1 .72 a09ap - 4 , 0x2 .623 a3cp - 12 , 0x5 .5256 a8p - 8 } , /* 24 */
{ 0x1 .4396 dp + 6 , 0x1 .439718 p + 6 , 0x1 .43976 ep + 6 , - 0x5 .08287 p - 24 ,
0x1 .6 b5c06p - 4 , - 0x2 .3 da154p - 12 , - 0x7 . a2254p - 8 } , /* 25 */
{ 0x1 .5027 acp + 6 , 0x1 .502808 p + 6 , 0x1 .50288 cp + 6 , - 0x3 .4598 dcp - 24 ,
- 0x1 .6480 c4p - 4 , 0x2 .1 cb944p - 12 , 0x7 .27 c77p - 8 } , /* 26 */
{ 0x1 .5 cb89ap + 6 , 0x1 .5 cb8f8p + 6 , 0x1 .5 cb97ep + 6 , 0x5 .4e74 bp - 24 ,
0x1 .5e0544 p - 4 , - 0x2 .00 b158p - 12 , - 0x5 .9 bc4a8p - 8 } , /* 27 */
{ 0x1 .69498 cp + 6 , 0x1 .6949e8 p + 6 , 0x1 .694 a42p + 6 , - 0x2 .05751 cp - 24 ,
- 0x1 .57e12 p - 4 , 0x1 . e78edcp - 12 , 0x9 .9667 dp - 8 } , /* 28 */
{ 0x1 .75 da7ep + 6 , 0x1 .75 dadap + 6 , 0x1 .75 db3p + 6 , 0x4 . c5e278p - 24 ,
0x1 .520 ceep - 4 , - 0x1 . d0127cp - 12 , - 0xd .62681 p - 8 } , /* 29 */
{ 0x1 .826 b7ep + 6 , 0x1 .826 bccp + 6 , 0x1 .826 c2cp + 6 , - 0x3 .50e62 cp - 24 ,
- 0x1 .4 c822p - 4 , 0x1 . ba5832p - 12 , - 0x1 . eb2ee2p - 8 } , /* 30 */
{ 0x1 .8 efc84p + 6 , 0x1 .8 efcbep + 6 , 0x1 .8 efd16p + 6 , - 0x1 . c39f38p - 24 ,
0x1 .473 ae6p - 4 , - 0x1 . a616c8p - 12 , 0xf . f352ap - 12 } , /* 31 */
{ 0x1 .9 b8d84p + 6 , 0x1 .9 b8db2p + 6 , 0x1 .9 b8e7p + 6 , - 0x1 .9245 b6p - 28 ,
- 0x1 .42320 ap - 4 , 0x1 .932 a04p - 12 , 0x2 . dc113cp - 8 } , /* 32 */
{ 0x1 . a81e72p + 6 , 0x1 . a81ea6p + 6 , 0x1 . a81f04p + 6 , - 0x1 .0 acf8p - 24 ,
0x1 .3 d62e6p - 4 , - 0x1 .7 c4b14p - 12 , - 0x1 . cfc5c2p - 4 } , /* 33 */
{ 0x1 . b4af6ap + 6 , 0x1 . b4af9ap + 6 , 0x1 . b4afeep + 6 , 0x4 . cd92d8p - 24 ,
- 0x1 .38 c94ap - 4 , 0x1 .643154 p - 12 , 0x1 .4 c2a06p - 4 } , /* 34 */
{ 0x1 . c1406p + 6 , 0x1 . c1409p + 6 , 0x1 . c140cp + 6 , - 0x1 .37 bf8ap - 24 ,
0x1 .34617 p - 4 , - 0x1 .5f 504 ap - 12 , - 0x1 . e2d324p - 4 } , /* 35 */
{ 0x1 . cdd154p + 6 , 0x1 . cdd186p + 6 , 0x1 . cdd1eap + 6 , - 0x1 .8f 62 dep - 28 ,
- 0x1 .3027f p - 4 , 0x1 .534 a02p - 12 , 0x2 . c7f144p - 12 } , /* 36 */
{ 0x1 . da6248p + 6 , 0x1 . da627cp + 6 , 0x1 . da62e6p + 6 , - 0x9 .81e79 p - 28 ,
0x1 .2 c19b4p - 4 , - 0x1 .4 b8288p - 12 , 0x7 .2 d8bap - 8 } , /* 37 */
{ 0x1 . e6f33ep + 6 , 0x1 . e6f372p + 6 , 0x1 . e6f3a8p + 6 , 0x3 .103 b3p - 24 ,
- 0x1 .2833 eep - 4 , 0x1 .36f 4 d2p - 12 , 0x9 .29f 91 p - 8 } , /* 38 */
{ 0x1 . f38434p + 6 , 0x1 . f3846ap + 6 , 0x1 . f384d8p + 6 , 0x2 .07 b058p - 24 ,
0x1 .24740 ap - 4 , - 0x1 .2 ee58ap - 12 , 0xd . f1393p - 12 } , /* 39 */
{ 0x1 .000 a98p + 7 , 0x1 .000 abp + 7 , 0x1 .000 ac8p + 7 , 0x3 .87576 cp - 24 ,
- 0x1 .20 d7b6p - 4 , 0x1 .2083e2 p - 12 , 0x3 .9 a7aap - 8 } , /* 40 */
{ 0x1 .06531 p + 7 , 0x1 .06532 cp + 7 , 0x1 .065348 p + 7 , - 0x1 .691 ecp - 24 ,
0x1 .1 d5ccap - 4 , - 0x1 .166726 p - 12 , - 0x1 . e4af48p - 8 } , /* 41 */
{ 0x1 .0 c9b9ap + 7 , 0x1 .0 c9ba8p + 7 , 0x1 .0 c9bbep + 7 , 0x9 . b406dp - 28 ,
- 0x1 .1 a015p - 4 , 0x1 .038f 9 cp - 12 , - 0x4 .021058 p - 4 } , /* 42 */
{ 0x1 .12e412 p + 7 , 0x1 .12e424 p + 7 , 0x1 .12e436 p + 7 , - 0xf . bfd8fp - 28 ,
0x1 .16 c37ap - 4 , - 0x1 .039 edep - 12 , 0x1 . f0033p - 4 } , /* 43 */
{ 0x1 .192 c92p + 7 , 0x1 .192 cap + 7 , 0x1 .192 cb6p + 7 , 0x2 .6 d50c8p - 24 ,
- 0x1 .13 a19ep - 4 , 0xf .9 df8ap - 16 , 0x4 . ecd978p - 8 } , /* 44 */
{ 0x1 .1f 7512 p + 7 , 0x1 .1f 751 cp + 7 , 0x1 .1f 753 ap + 7 , - 0x4 . d475c8p - 24 ,
0x1 .109 a32p - 4 , - 0x1 .04f b3ap - 12 , - 0xd . c271p - 12 } , /* 45 */
{ 0x1 .25 bd8ep + 7 , 0x1 .25 bd98p + 7 , 0x1 .25 bdap + 7 , 0x8 .1982 p - 24 ,
- 0x1 .0 dabc8p - 4 , 0xe .88 eabp - 16 , - 0x4 . ed75dp - 4 } , /* 46 */
{ 0x1 .2 c060cp + 7 , 0x1 .2 c0616p + 7 , 0x1 .2 c0644p + 7 , 0x4 .864518 p - 24 ,
0x1 .0 ad51p - 4 , - 0xe .27196 p - 16 , 0xb .97 a3ep - 8 } , /* 47 */
{ 0x1 .324e86 p + 7 , 0x1 .324e92 p + 7 , 0x1 .324e9 ep + 7 , 0x6 .8917 a8p - 28 ,
- 0x1 .0814 d4p - 4 , 0xd .4f e7ep - 16 , - 0x6 .8 d8d6p - 4 } , /* 48 */
{ 0x1 .389702 p + 7 , 0x1 .38970 ep + 7 , 0x1 .389728 p + 7 , - 0x5 . fa18fp - 24 ,
0x1 .0569f p - 4 , - 0xd .5 b0d4p - 16 , 0x1 .50353 ap - 4 } , /* 49 */
{ 0x1 .3 edf84p + 7 , 0x1 .3 edf8cp + 7 , 0x1 .3 edfaap + 7 , - 0x4 .0e5 c98p - 24 ,
- 0x1 .02 d354p - 4 , 0xb .7 b255p - 16 , 0x7 .8 a916p - 4 } , /* 50 */
{ 0x1 .4527f p + 7 , 0x1 .452808 p + 7 , 0x1 .452812 p + 7 , - 0x2 . c3ddbp - 24 ,
0x1 .005004 p - 4 , - 0xd .7729 cp - 16 , - 0x3 . bcc354p - 8 } , /* 51 */
{ 0x1 .4 b7076p + 7 , 0x1 .4 b7086p + 7 , 0x1 .4 b70a4p + 7 , - 0x5 . d052p - 24 ,
- 0xf . ddf16p - 8 , 0xc .318 c1p - 16 , 0x5 .7947 p - 8 } , /* 52 */
{ 0x1 .51 b8f4p + 7 , 0x1 .51 b902p + 7 , 0x1 .51 b90ep + 7 , - 0x2 .0 b97dcp - 24 ,
0xf . b7fafp - 8 , - 0xc .1429 dp - 16 , - 0x3 .43 c36p - 4 } , /* 53 */
{ 0x1 .580168 p + 7 , 0x1 .58018 p + 7 , 0x1 .580188 p + 7 , - 0x5 .4 aab5p - 24 ,
- 0xf .930f ep - 8 , 0xa . ecc24p - 16 , 0x9 . c62cdp - 12 } , /* 54 */
{ 0x1 .5e49 eap + 7 , 0x1 .5e49 fcp + 7 , 0x1 .5e4 a12p + 7 , - 0x3 .6 dadd8p - 24 ,
0xf .6f 245 p - 8 , - 0xb .6816 cp - 16 , 0xa . d731ap - 8 } , /* 55 */
{ 0x1 .649272 p + 7 , 0x1 .64927 ap + 7 , 0x1 .64929 p + 7 , - 0x2 . d7e038p - 24 ,
- 0xf .4 c2cep - 8 , 0xb .118 bep - 16 , 0xb .69 a4ep - 8 } , /* 56 */
{ 0x1 .6 adae6p + 7 , 0x1 .6 adaf6p + 7 , 0x1 .6 adb04p + 7 , - 0x6 .977 a1p - 24 ,
0xf .2 a1fp - 8 , - 0xa . a8911p - 16 , - 0x4 . bf6d2p - 8 } , /* 57 */
{ 0x1 .712366 p + 7 , 0x1 .712374 p + 7 , 0x1 .71238 ep + 7 , 0x1 .3 cc95ep - 24 ,
- 0xf .08f 0 ap - 8 , 0x9 . f0858p - 16 , 0x1 .77f 7f 4 p - 4 } , /* 58 */
{ 0x1 .776 beap + 7 , 0x1 .776 bf2p + 7 , 0x1 .776 bfap + 7 , 0x3 . a4921p - 24 ,
0xe . e8986p - 8 , - 0xa .39 dfp - 16 , - 0x6 .7 ba3dp - 4 } , /* 59 */
{ 0x1 .7 db464p + 7 , 0x1 .7 db46ep + 7 , 0x1 .7 db476p + 7 , 0x6 . b45a7p - 24 ,
- 0xe . c90d8p - 8 , 0xa . e586fp - 16 , - 0x1 . d66becp - 4 } , /* 60 */
{ 0x1 .83f ce2p + 7 , 0x1 .83f cecp + 7 , 0x1 .83f d0ep + 7 , - 0x2 .8f 34 a4p - 24 ,
0xe . aa478p - 8 , - 0x9 .810 bp - 16 , - 0x3 . a5f3fcp - 8 } , /* 61 */
{ 0x1 .8 a455cp + 7 , 0x1 .8 a456ap + 7 , 0x1 .8 a4588p + 7 , - 0x1 .325968 p - 24 ,
- 0xe .8 c3eap - 8 , 0x9 .0 a765p - 16 , 0x1 .29 a54ap - 4 } , /* 62 */
{ 0x1 .908 dd8p + 7 , 0x1 .908 de8p + 7 , 0x1 .908 df4p + 7 , 0x4 .96 b808p - 24 ,
0xe .6 eeb5p - 8 , - 0x9 .0251 bp - 16 , 0x1 .41 a488p - 4 } , /* 63 */
} ;
/* Formula page 5 of https://www.cl.cam.ac.uk/~jrh13/papers/bessel.pdf:
j0f ( x ) ~ sqrt ( 2 / ( pi * x ) ) * beta0 ( x ) * cos ( x - pi / 4 - alpha0 ( x ) )
where beta0 ( x ) = 1 - 1 / ( 16 * x ^ 2 ) + 53 / ( 512 * x ^ 4 )
and alpha0 ( x ) = 1 / ( 8 * x ) - 25 / ( 384 * x ^ 3 ) . */
static float
j0f_asympt ( float x )
{
/* The following code fails to give an error <= 9 ulps in only two cases,
for which we tabulate the result . */
if ( x = = 0x1 .4665 d2p + 24f )
return 0xa .50206 p - 52f ;
if ( x = = 0x1 . a9afdep + 7f )
return 0xf .47039 p - 28f ;
double y = 1.0 / ( double ) x ;
double y2 = y * y ;
double beta0 = 1.0f + y2 * ( - 0x1 p - 4f + 0x1 . a8p - 4 * y2 ) ;
double alpha0 = y * ( 0x2 p - 4 - 0x1 .0 aaaaap - 4 * y2 ) ;
double h ;
int n ;
h = reduce_aux ( x , & n , alpha0 ) ;
/* Now x - pi/4 - alpha0 = h + n*pi/2 mod (2*pi). */
float xr = ( float ) h ;
n = n & 3 ;
float cst = 0xc . c422ap - 4 ; /* sqrt(2/pi) rounded to nearest */
float t = cst / sqrtf ( x ) * ( float ) beta0 ;
if ( n = = 0 )
return t * __cosf ( xr ) ;
else if ( n = = 2 ) /* cos(x+pi) = -cos(x) */
return - t * __cosf ( xr ) ;
else if ( n = = 1 ) /* cos(x+pi/2) = -sin(x) */
return - t * __sinf ( xr ) ;
else /* cos(x+3pi/2) = sin(x) */
return t * __sinf ( xr ) ;
}
/* Special code for x near a root of j0.
z is the value computed by the generic code .
For small x , we use a polynomial approximating j0 around its root .
For large x , we use an asymptotic formula ( j0f_asympt ) . */
static float
j0f_near_root ( float x , float z )
{
float index_f ;
int index ;
index_f = roundf ( ( x - FIRST_ZERO_J0 ) / ( float ) M_PI ) ;
/* j0f_asympt fails to give an error <= 9 ulps for x=0x1.324e92p+7
( index 48 ) thus we can ' t reduce SMALL_SIZE below 49. */
if ( index_f > = SMALL_SIZE )
return j0f_asympt ( x ) ;
index = ( int ) index_f ;
const float * p = Pj [ index ] ;
float x0 = p [ 0 ] ;
float x1 = p [ 2 ] ;
/* If not in the interval [x0,x1] around xmid, we return the value z. */
if ( ! ( x0 < = x & & x < = x1 ) )
return z ;
float xmid = p [ 1 ] ;
float y = x - xmid ;
return p [ 3 ] + y * ( p [ 4 ] + y * ( p [ 5 ] + y * p [ 6 ] ) ) ;
}
float
__ieee754_j0f ( float x )
{
@ -48,39 +262,35 @@ __ieee754_j0f(float x)
if ( ix > = 0x7f800000 ) return one / ( x * x ) ;
x = fabsf ( x ) ;
if ( ix > = 0x40000000 ) { /* |x| >= 2.0 */
SET_RESTORE_ROUNDF ( FE_TONEAREST ) ;
__sincosf ( x , & s , & c ) ;
ss = s - c ;
cc = s + c ;
if ( ix < 0x7f000000 ) { /* make sure x+x not overflow */
z = - __cosf ( x + x ) ;
if ( ( s * c ) < zero ) cc = z / ss ;
else ss = z / cc ;
} else {
/* We subtract (exactly) a value x0 such that
cos ( x0 ) + sin ( x0 ) is very near to 0 , and use the identity
sin ( x - x0 ) = sin ( x ) * cos ( x0 ) - cos ( x ) * sin ( x0 ) to get
sin ( x ) + cos ( x ) with extra accuracy . */
float x0 = 0xe . d4108p + 124f ;
float y = x - x0 ; /* exact */
/* sin(y) = sin(x)*cos(x0)-cos(x)*sin(x0) */
z = __sinf ( y ) ;
float eps = 0x1 .5f 263 ep - 24f ;
/* cos(x0) ~ -sin(x0) + eps */
z + = eps * __cosf ( x ) ;
/* now z ~ (sin(x)-cos(x))*cos(x0) */
float cosx0 = - 0xb .504f 3 p - 4f ;
cc = z / cosx0 ;
}
if ( ix > = 0x7f000000 )
/* x >= 2^127: use asymptotic expansion. */
return j0f_asympt ( x ) ;
/* Now we are sure that x+x cannot overflow. */
z = - __cosf ( x + x ) ;
if ( ( s * c ) < zero ) cc = z / ss ;
else ss = z / cc ;
/*
* j0 ( x ) = 1 / sqrt ( pi ) * ( P ( 0 , x ) * cc - Q ( 0 , x ) * ss ) / sqrt ( x )
* y0 ( x ) = 1 / sqrt ( pi ) * ( P ( 0 , x ) * ss + Q ( 0 , x ) * cc ) / sqrt ( x )
*/
if ( ix > 0x5c000000 ) z = ( invsqrtpi * cc ) / sqrtf ( x ) ;
else {
u = pzerof ( x ) ; v = qzerof ( x ) ;
z = invsqrtpi * ( u * cc - v * ss ) / sqrtf ( x ) ;
}
return z ;
if ( ix < = 0x5c000000 )
{
u = pzerof ( x ) ; v = qzerof ( x ) ;
cc = u * cc - v * ss ;
}
z = ( invsqrtpi * cc ) / sqrtf ( x ) ;
/* The following threshold is optimal: for x=0x1.3b58dep+1
and rounding upwards , | cc | = 0x1 .579 b26p - 4 and z is 10 ulps
far from the correctly rounded value . */
float threshold = 0x1 .579 b26p - 4 ;
if ( fabsf ( cc ) > threshold )
return z ;
else
return j0f_near_root ( x , z ) ;
}
if ( ix < 0x39000000 ) { /* |x| < 2**-13 */
math_force_eval ( huge + x ) ; /* raise inexact if x != 0 */
@ -112,6 +322,219 @@ v02 = 7.6006865129e-05, /* 0x389f65e0 */
v03 = 2.5915085189e-07 , /* 0x348b216c */
v04 = 4.4111031494e-10 ; /* 0x2ff280c2 */
/* This is the nearest approximation of the first zero of y0. */
# define FIRST_ZERO_Y0 0xe.4c166p-4f
/* The following table contains successive zeros of y0 and degree-3
polynomial approximations of y0 around these zeros : Py [ 0 ] for the first
zero ( 0.89358 ) , Py [ 1 ] for the second one ( 3.957678 ) , and so on .
Each line contains :
{ x0 , xmid , x1 , p0 , p1 , p2 , p3 }
where [ x0 , x1 ] is the interval around the zero , xmid is the binary32 number
closest to the zero , and p0 + p1 * x + p2 * x ^ 2 + p3 * x ^ 3 is the approximation
polynomial . Each polynomial was generated using Sollya on the interval
[ x0 , x1 ] around the corresponding zero where the error exceeds 9 ulps
for the alternate code . Degree 3 is enough , except for index 0 where we
use degree 5 , and the coefficients of degree 4 and 5 are hard - coded in
y0f_near_root .
*/
static const float Py [ SMALL_SIZE ] [ 7 ] = {
{ 0x1 . a681dap - 1 , 0x1 . c982ecp - 1 , 0x1 . ef6bcap - 1 , 0x3 .274468 p - 28 ,
0xe .121 b8p - 4 , - 0x7 . df8b3p - 4 , 0x3 .877 be4p - 4
/*, -0x3.a46c9p-4, 0x3.735478p-4*/ } , /* 0 */
{ 0x1 . f957c6p + 1 , 0x1 . fa9534p + 1 , 0x1 . fd11b2p + 1 , 0xa . f1f83p - 28 ,
- 0x6 .70 d098p - 4 , 0xd .04 d48p - 8 , 0xe . f61a9p - 8 } , /* 1 */
{ 0x1 . c51832p + 2 , 0x1 . c581dcp + 2 , 0x1 . c65164p + 2 , - 0x5 . e2a51p - 28 ,
0x4 . cd3328p - 4 , - 0x5 .6 bbe08p - 8 , - 0xc .46 d8p - 8 } , /* 2 */
{ 0x1 .46f d84p + 3 , 0x1 .471 d74p + 3 , 0x1 .475 bfcp + 3 , - 0x1 .4 b0aeep - 24 ,
- 0x3 . fec6b8p - 4 , 0x3 .2068 a4p - 8 , 0xa .76e2 dp - 8 } , /* 3 */
{ 0x1 . ab7afap + 3 , 0x1 . ab8e1cp + 3 , 0x1 . abb294p + 3 , - 0x8 .179 d7p - 28 ,
0x3 .7e6544 p - 4 , - 0x2 .1799f p - 8 , - 0x9 .0e1 c4p - 8 } , /* 4 */
{ 0x1 .07f 9 aap + 4 , 0x1 .0803 c8p + 4 , 0x1 .08170 cp + 4 , - 0x2 .5 b8078p - 24 ,
- 0x3 .24 b868p - 4 , 0x1 .8631 ecp - 8 , 0x8 .3 cb46p - 8 } , /* 5 */
{ 0x1 .3 a38eap + 4 , 0x1 .3 a42cep + 4 , 0x1 .3 a4d8ap + 4 , 0x1 . cd304ap - 28 ,
0x2 . e189ecp - 4 , - 0x1 .2 c6954p - 8 , - 0x7 .8178 ep - 8 } , /* 6 */
{ 0x1 .6 c7d42p + 4 , 0x1 .6 c833p + 4 , 0x1 .6 c99fp + 4 , - 0x6 . c63f1p - 28 ,
- 0x2 . acc9a8p - 4 , 0xf .09e31 p - 12 , 0x7 .0 b5ab8p - 8 } , /* 7 */
{ 0x1 .9 ebec4p + 4 , 0x1 .9 ec47p + 4 , 0x1 .9 ed016p + 4 , 0x1 . e53838p - 24 ,
0x2 .81f 2 p - 4 , - 0xc .5f f51p - 12 , - 0x7 .05 ep - 8 } , /* 8 */
{ 0x1 . d1008ep + 4 , 0x1 . d10644p + 4 , 0x1 . d11262p + 4 , 0x1 .636f eep - 24 ,
- 0x2 .5e40 dcp - 4 , 0xa .6f 81 dp - 12 , 0x5 . ff6p - 8 } , /* 9 */
{ 0x1 .01 a27cp + 5 , 0x1 .01 a442p + 5 , 0x1 .01 a924p + 5 , - 0x4 .04e1 bp - 28 ,
0x2 .3f ebd8p - 4 , - 0x8 . f11e2p - 12 , - 0x6 .0111 ap - 8 } , /* 10 */
{ 0x1 .1 ac3bcp + 5 , 0x1 .1 ac588p + 5 , 0x1 .1 ac912p + 5 , 0x3 .6063 d8p - 24 ,
- 0x2 .25 baacp - 4 , 0x7 . c93cdp - 12 , 0x4 . e7577p - 8 } , /* 11 */
{ 0x1 .33e508 p + 5 , 0x1 .33e6 ecp + 5 , 0x1 .33 ea1ap + 5 , - 0x3 . f39ebcp - 24 ,
0x2 .0 ed04cp - 4 , - 0x6 . d9434p - 12 , - 0x4 . fc0b7p - 8 } , /* 12 */
{ 0x1 .4 d0666p + 5 , 0x1 .4 d0868p + 5 , 0x1 .4 d0c14p + 5 , - 0x4 . ea23p - 28 ,
- 0x1 . fa8b4p - 4 , 0x6 .1470e8 p - 12 , 0x5 .97f 71 p - 8 } , /* 13 */
{ 0x1 .6628 b8p + 5 , 0x1 .6629f 4 p + 5 , 0x1 .662e0 ep + 5 , - 0x3 .5 df0c8p - 24 ,
0x1 . e8727ep - 4 , - 0x5 .76 a038p - 12 , - 0x4 . ee37c8p - 8 } , /* 14 */
{ 0x1 .7f 4 a7cp + 5 , 0x1 .7f 4 b9p + 5 , 0x1 .7f 4 daap + 5 , 0x1 .1 ef09ep - 24 ,
- 0x1 . d8293ap - 4 , 0x4 . ed8a28p - 12 , 0x4 . d43708p - 8 } , /* 15 */
{ 0x1 .986 c5cp + 5 , 0x1 .986 d38p + 5 , 0x1 .986f 6 p + 5 , 0x1 . b70cecp - 24 ,
0x1 . c967p - 4 , - 0x4 .7 a70b8p - 12 , - 0x5 .6840e8 p - 8 } , /* 16 */
{ 0x1 . b18dcap + 5 , 0x1 . b18ee8p + 5 , 0x1 . b19122p + 5 , 0x1 . abaadcp - 24 ,
- 0x1 . bbf246p - 4 , 0x4 .1 a35bp - 12 , 0x3 . c2d46p - 8 } , /* 17 */
{ 0x1 . caaf86p + 5 , 0x1 . cab0a2p + 5 , 0x1 . cab2fep + 5 , 0x1 .63989 ep - 24 ,
0x1 . af9cb4p - 4 , - 0x3 . c2f2dcp - 12 , - 0x4 . cf8108p - 8 } , /* 18 */
{ 0x1 . e3d146p + 5 , 0x1 . e3d262p + 5 , 0x1 . e3d492p + 5 , - 0x1 .68 a8ecp - 24 ,
- 0x1 . a4407ep - 4 , 0x3 .7733 ecp - 12 , 0x5 .97916 p - 8 } , /* 19 */
{ 0x1 . fcf316p + 5 , 0x1 . fcf428p + 5 , 0x1 . fcf59ap + 5 , 0x1 . e1bb5p - 24 ,
0x1 .99 be74p - 4 , - 0x3 .37210 cp - 12 , - 0x5 . d19bf8p - 8 } , /* 20 */
{ 0x1 .0 b0a7cp + 6 , 0x1 .0 b0afap + 6 , 0x1 .0 b0b9cp + 6 , - 0x5 .5 bbcfp - 24 ,
- 0x1 .8f fc9ap - 4 , 0x2 . ffe638p - 12 , 0x2 . ed28e8p - 8 } , /* 21 */
{ 0x1 .179 b66p + 6 , 0x1 .179 bep + 6 , 0x1 .179 d0ap + 6 , - 0x4 .9e34 a8p - 24 ,
0x1 .86e51 cp - 4 , - 0x2 . cc7a68p - 12 , - 0x3 .3642 c4p - 8 } , /* 22 */
{ 0x1 .242 c5cp + 6 , 0x1 .242 ccap + 6 , 0x1 .242 d68p + 6 , 0x1 .966706 p - 24 ,
- 0x1 .7e657 p - 4 , 0x2 .9 aed4cp - 12 , 0x7 . b87a58p - 8 } , /* 23 */
{ 0x1 .30 bd62p + 6 , 0x1 .30 bdb6p + 6 , 0x1 .30 beb2p + 6 , 0x3 .4 b3b68p - 24 ,
0x1 .766 dc2p - 4 , - 0x2 .72651 cp - 12 , - 0x3 . e347f8p - 8 } , /* 24 */
{ 0x1 .3 d4e56p + 6 , 0x1 .3 d4ea2p + 6 , 0x1 .3 d4f2ep + 6 , 0x6 . a99008p - 28 ,
- 0x1 .6 ef07ep - 4 , 0x2 .53 aec4p - 12 , 0x2 .9e3 d88p - 12 } , /* 25 */
{ 0x1 .49 df38p + 6 , 0x1 .49 df9p + 6 , 0x1 .49e042 p + 6 , - 0x7 . a9fa6p - 32 ,
0x1 .67e1 dap - 4 , - 0x2 .324 d7p - 12 , - 0xc .0e669 p - 12 } , /* 26 */
{ 0x1 .56702 ep + 6 , 0x1 .56708 p + 6 , 0x1 .567116 p + 6 , - 0x5 .026808 p - 24 ,
- 0x1 .613798 p - 4 , 0x2 .114594 p - 12 , 0x1 . a22402p - 8 } , /* 27 */
{ 0x1 .630126 p + 6 , 0x1 .63017 p + 6 , 0x1 .630226 p + 6 , 0x4 .46 aa2p - 24 ,
0x1 .5 ae8c2p - 4 , - 0x1 . f4aaa4p - 12 , - 0x3 .58593 cp - 8 } , /* 28 */
{ 0x1 .6f 9234 p + 6 , 0x1 .6f 926 p + 6 , 0x1 .6f 92 b2p + 6 , 0x1 .5 cfccp - 24 ,
- 0x1 .54 ed76p - 4 , 0x1 . dd540ap - 12 , - 0xb . e9429p - 12 } , /* 29 */
{ 0x1 .7 c22fep + 6 , 0x1 .7 c2352p + 6 , 0x1 .7 c23c2p + 6 , - 0xb .4 dc4cp - 28 ,
0x1 .4f 3 ebcp - 4 , - 0x1 . c463fp - 12 , - 0x1 . e94c54p - 8 } , /* 30 */
{ 0x1 .88 b412p + 6 , 0x1 .88 b444p + 6 , 0x1 .88 b50ap + 6 , 0x3 . f5343p - 24 ,
- 0x1 .49 d668p - 4 , 0x1 . a53f24p - 12 , 0x5 .128198 p - 8 } , /* 31 */
{ 0x1 .9544 dcp + 6 , 0x1 .954538 p + 6 , 0x1 .95459 p + 6 , - 0x6 . e6f32p - 28 ,
0x1 .44 aefap - 4 , - 0x1 .9 a6ef8p - 12 , - 0x6 . c639cp - 8 } , /* 32 */
{ 0x1 . a1d5fap + 6 , 0x1 . a1d62cp + 6 , 0x1 . a1d674p + 6 , 0x1 . f359c2p - 28 ,
- 0x1 .3f c386p - 4 , 0x1 .887 ebep - 12 , 0x1 .6 c813cp - 8 } , /* 33 */
{ 0x1 . ae66cp + 6 , 0x1 . ae672p + 6 , 0x1 . ae6788p + 6 , - 0x2 .9 de748p - 24 ,
0x1 .3 b0fa4p - 4 , - 0x1 .777f 26 p - 12 , 0x1 . c128ccp - 8 } , /* 34 */
{ 0x1 . baf7c2p + 6 , 0x1 . baf816p + 6 , 0x1 . baf86cp + 6 , - 0x2 .24 ccc8p - 24 ,
- 0x1 .368f 5 cp - 4 , 0x1 .62 bd9ep - 12 , 0xa . df002p - 8 } , /* 35 */
{ 0x1 . c788dap + 6 , 0x1 . c7890cp + 6 , 0x1 . c7896cp + 6 , 0x4 .7 dcea8p - 24 ,
0x1 .323f 16 p - 4 , - 0x1 .61 abf4p - 12 , 0xa . ad73ep - 8 } , /* 36 */
{ 0x1 . d419ccp + 6 , 0x1 . d41a02p + 6 , 0x1 . d41a68p + 6 , - 0x4 . b538p - 24 ,
- 0x1 .2e1 b98p - 4 , 0x1 .4 a4d64p - 12 , 0x3 . a47674p - 8 } , /* 37 */
{ 0x1 . e0aacep + 6 , 0x1 . e0aaf8p + 6 , 0x1 . e0ab5ep + 6 , 0x3 .09 dc4cp - 24 ,
0x1 .2 a21ecp - 4 , - 0x1 .3f a20cp - 12 , 0x2 .216e8 cp - 8 } , /* 38 */
{ 0x1 . ed3bb8p + 6 , 0x1 . ed3beep + 6 , 0x1 . ed3c56p + 6 , 0x4 . d5a58p - 28 ,
- 0x1 .264f 66 p - 4 , 0x1 .32 c4cep - 12 , 0x1 .53 cbb4p - 8 } , /* 39 */
{ 0x1 . f9ccaep + 6 , 0x1 . f9cce6p + 6 , 0x1 . f9cd52p + 6 , 0x3 . f4c44cp - 24 ,
0x1 .22 a192p - 4 , - 0x1 .1f 8514 p - 12 , - 0xc .0 de32p - 8 } , /* 40 */
{ 0x1 .032 ed6p + 7 , 0x1 .032 eeep + 7 , 0x1 .032f 0 cp + 7 , 0x2 .4 beae8p - 24 ,
- 0x1 .1f 1634 p - 4 , 0x1 .171664 p - 12 , 0x1 .72 a654p - 4 } , /* 41 */
{ 0x1 .097756 p + 7 , 0x1 .09776 ap + 7 , 0x1 .09779 cp + 7 , - 0xd . a581ep - 28 ,
0x1 .1 bab3cp - 4 , - 0xf .9f 507 p - 16 , - 0xc . ba2d4p - 8 } , /* 42 */
{ 0x1 .0f bfdp + 7 , 0x1 .0f bfe6p + 7 , 0x1 .0f bff6p + 7 , 0xa .7 c0bdp - 28 ,
- 0x1 .185 eccp - 4 , 0x1 .01 d7dep - 12 , - 0x1 . a2186ep - 4 } , /* 43 */
{ 0x1 .160856 p + 7 , 0x1 .160862 p + 7 , 0x1 .16087 ap + 7 , - 0x1 .9452 ecp - 24 ,
0x1 .152f 26 p - 4 , - 0x1 .07 b4aap - 12 , 0x1 .6 bbd7ep - 4 } , /* 44 */
{ 0x1 .1 c50dp + 7 , 0x1 .1 c50dep + 7 , 0x1 .1 c5118p + 7 , 0x3 .83 b7b8p - 24 ,
- 0x1 .121 ab2p - 4 , 0x1 .0e938 cp - 12 , - 0x5 .1 a6dfp - 8 } , /* 45 */
{ 0x1 .22995 p + 7 , 0x1 .22995 ap + 7 , 0x1 .229976 p + 7 , - 0x6 .5 ca3a8p - 24 ,
0x1 .0f 1ff 2 p - 4 , - 0xe . f198p - 16 , - 0x3 .8e98 b8p - 8 } , /* 46 */
{ 0x1 .28e1 ccp + 7 , 0x1 .28e1 d8p + 7 , 0x1 .28e1 f4p + 7 , - 0x6 . bb61ap - 24 ,
- 0x1 .0 c3d8ap - 4 , 0xf . a14b9p - 16 , 0x9 .81e82 p - 4 } , /* 47 */
{ 0x1 .2f 2 a48p + 7 , 0x1 .2f 2 a54p + 7 , 0x1 .2f 2 a74p + 7 , 0x2 .2438 p - 24 ,
0x1 .097236 p - 4 , - 0xd . fed5ep - 16 , - 0x3 .19 eb5cp - 8 } , /* 48 */
{ 0x1 .3572 b8p + 7 , 0x1 .3572 dp + 7 , 0x1 .3572 ecp + 7 , 0x3 .1e0054 p - 24 ,
- 0x1 .06 bcc8p - 4 , 0xd . d2596p - 16 , - 0x1 .67e00 ap - 4 } , /* 49 */
{ 0x1 .3 bbb3ep + 7 , 0x1 .3 bbb4ep + 7 , 0x1 .3 bbb6ap + 7 , 0x7 .46 c908p - 24 ,
0x1 .041 c28p - 4 , - 0xd .04045 p - 16 , - 0x8 . fb297p - 8 } , /* 50 */
{ 0x1 .4203 aep + 7 , 0x1 .4203 cap + 7 , 0x1 .4203e6 p + 7 , - 0xb .4f 158 p - 28 ,
- 0x1 .018f 52 p - 4 , 0xc . ccf6fp - 16 , 0x1 .4 d5dp - 4 } , /* 51 */
{ 0x1 .484 c38p + 7 , 0x1 .484 c46p + 7 , 0x1 .484 c56p + 7 , - 0x6 .5 a89c8p - 24 ,
0xf . f155p - 8 , - 0xc .5 d21dp - 16 , - 0xd . aca34p - 8 } , /* 52 */
{ 0x1 .4e94 b8p + 7 , 0x1 .4e94 c4p + 7 , 0x1 .4e94 d4p + 7 , - 0x1 . ef16c8p - 24 ,
- 0xf . cad3fp - 8 , 0xb . d75f8p - 16 , 0x1 . f36732p - 4 } , /* 53 */
{ 0x1 .54 dd36p + 7 , 0x1 .54 dd4p + 7 , 0x1 .54 dd52p + 7 , - 0x6 .1e7 b68p - 24 ,
0xf . a564cp - 8 , - 0xb . ec1cfp - 16 , 0xe . e7421p - 8 } , /* 54 */
{ 0x1 .5 b25aep + 7 , 0x1 .5 b25bep + 7 , 0x1 .5 b25d4p + 7 , - 0xf .8 c858p - 28 ,
- 0xf .80f aep - 8 , 0xb .8 b6c5p - 16 , - 0x5 .835 ed8p - 8 } , /* 55 */
{ 0x1 .616e34 p + 7 , 0x1 .616e3 cp + 7 , 0x1 .616e4 ep + 7 , 0x7 .75 d858p - 24 ,
0xf .5 d8abp - 8 , - 0xb . b3779p - 16 , 0x2 .40 b948p - 4 } , /* 56 */
{ 0x1 .67 b6bp + 7 , 0x1 .67 b6b8p + 7 , 0x1 .67 b6dp + 7 , 0x1 . d78632p - 24 ,
- 0xf .3 b096p - 8 , 0xa . daf89p - 16 , 0x1 . aa8548p - 8 } , /* 57 */
{ 0x1 .6 dff28p + 7 , 0x1 .6 dff36p + 7 , 0x1 .6 dff54p + 7 , 0x3 . b24794p - 24 ,
0xf .196 c7p - 8 , - 0xb .1 afe1p - 16 , - 0x1 .77538 cp - 8 } , /* 58 */
{ 0x1 .7447 a2p + 7 , 0x1 .7447 b2p + 7 , 0x1 .7447 cap + 7 , 0x6 .39 cbc8p - 24 ,
- 0xe . f8aa5p - 8 , 0xa .50 daap - 16 , 0x1 .9592 c2p - 8 } , /* 59 */
{ 0x1 .7 a902p + 7 , 0x1 .7 a903p + 7 , 0x1 .7 a903ep + 7 , - 0x1 .820e3 ap - 24 ,
0xe . d8b9dp - 8 , - 0xa .998 cp - 16 , - 0x2 . c35d78p - 4 } , /* 60 */
{ 0x1 .80 d89ep + 7 , 0x1 .80 d8aep + 7 , 0x1 .80 d8bep + 7 , - 0x2 . c7e038p - 24 ,
- 0xe . b9925p - 8 , 0x9 . ce06p - 16 , - 0x2 .2 b3054p - 4 } , /* 61 */
{ 0x1 .87211 cp + 7 , 0x1 .87212 cp + 7 , 0x1 .872144 p + 7 , 0x6 . ab31c8p - 24 ,
0xe .9 b2bep - 8 , - 0x9 .4 de7p - 16 , - 0x1 .32 cb5ep - 4 } , /* 62 */
{ 0x1 .8 d699ap + 7 , 0x1 .8 d69a8p + 7 , 0x1 .8 d69bp + 7 , 0x4 .4 ef25p - 24 ,
- 0xe .7 d7ecp - 8 , 0x9 . a0f1ep - 16 , 0x1 .6 ac076p - 4 } , /* 63 */
} ;
/* Formula page 5 of https://www.cl.cam.ac.uk/~jrh13/papers/bessel.pdf:
y0 ( x ) ~ sqrt ( 2 / ( pi * x ) ) * beta0 ( x ) * sin ( x - pi / 4 - alpha0 ( x ) )
where beta0 ( x ) = 1 - 1 / ( 16 * x ^ 2 ) + 53 / ( 512 * x ^ 4 )
and alpha0 ( x ) = 1 / ( 8 * x ) - 25 / ( 384 * x ^ 3 ) . */
static float
y0f_asympt ( float x )
{
/* The following code fails to give an error <= 9 ulps in only two cases,
for which we tabulate the correctly - rounded result . */
if ( x = = 0x1 . bfad96p + 7f )
return - 0x7 . f32bdp - 32f ;
if ( x = = 0x1 .2e2 a42p + 17f )
return 0x1 . a48974p - 40f ;
double y = 1.0 / ( double ) x ;
double y2 = y * y ;
double beta0 = 1.0f + y2 * ( - 0x1 p - 4f + 0x1 . a8p - 4 * y2 ) ;
double alpha0 = y * ( 0x2 p - 4 - 0x1 .0 aaaaap - 4 * y2 ) ;
double h ;
int n ;
h = reduce_aux ( x , & n , alpha0 ) ;
/* Now x - pi/4 - alpha0 = h + n*pi/2 mod (2*pi). */
float xr = ( float ) h ;
n = n & 3 ;
float cst = 0xc . c422ap - 4 ; /* sqrt(2/pi) rounded to nearest */
float t = cst / sqrtf ( x ) * ( float ) beta0 ;
if ( n = = 0 )
return t * __sinf ( xr ) ;
else if ( n = = 2 ) /* sin(x+pi) = -sin(x) */
return - t * __sinf ( xr ) ;
else if ( n = = 1 ) /* sin(x+pi/2) = cos(x) */
return t * __cosf ( xr ) ;
else /* sin(x+3pi/2) = -cos(x) */
return - t * __cosf ( xr ) ;
}
/* Special code for x near a root of y0.
z is the value computed by the generic code .
For small x , use a polynomial approximating y0 around its root .
For large x , use an asymptotic formula ( y0f_asympt ) . */
static float
y0f_near_root ( float x , float z )
{
float index_f ;
int index ;
index_f = roundf ( ( x - FIRST_ZERO_Y0 ) / ( float ) M_PI ) ;
if ( index_f > = SMALL_SIZE )
return y0f_asympt ( x ) ;
index = ( int ) index_f ;
const float * p = Py [ index ] ;
float x0 = p [ 0 ] ;
float x1 = p [ 2 ] ;
/* If not in the interval [x0,x1] around xmid, return the value z. */
if ( ! ( x0 < = x & & x < = x1 ) )
return z ;
float xmid = p [ 1 ] ;
float y = x - xmid ;
/* For degree 0 use a degree-5 polynomial, where the coefficients of
degree 4 and 5 are hard - coded . */
float p6 = ( index > 0 ) ? p [ 6 ]
: p [ 6 ] + y * ( - 0x3 . a46c9p - 4 + y * 0x3 .735478 p - 4 ) ;
float res = p [ 3 ] + y * ( p [ 4 ] + y * ( p [ 5 ] + y * p6 ) ) ;
return res ;
}
float
__ieee754_y0f ( float x )
{
@ -124,7 +547,9 @@ __ieee754_y0f(float x)
if ( ix > = 0x7f800000 ) return one / ( x + x * x ) ;
if ( ix = = 0 ) return - 1 / zero ; /* -inf and divide by zero exception. */
if ( hx < 0 ) return zero / ( zero * x ) ;
if ( ix > = 0x40000000 ) { /* |x| >= 2.0 */
if ( ix > = 0x40000000 | | ( 0x3f5340ed < = ix & & ix < = 0x3f77b5e5 ) ) {
/* |x| >= 2.0 or
0x1 . a681dap - 1 < = | x | < = 0x1 . ef6bcap - 1 ( around 1 st zero ) */
/* y0(x) = sqrt(2/(pi*x))*(p0(x)*sin(x0)+q0(x)*cos(x0))
* where x0 = x - pi / 4
* Better formula :
@ -136,6 +561,7 @@ __ieee754_y0f(float x)
* sin ( x ) + - cos ( x ) = - cos ( 2 x ) / ( sin ( x ) - + cos ( x ) )
* to compute the worse one .
*/
SET_RESTORE_ROUNDF ( FE_TONEAREST ) ;
__sincosf ( x , & s , & c ) ;
ss = s - c ;
cc = s + c ;
@ -143,17 +569,26 @@ __ieee754_y0f(float x)
* j0 ( x ) = 1 / sqrt ( pi ) * ( P ( 0 , x ) * cc - Q ( 0 , x ) * ss ) / sqrt ( x )
* y0 ( x ) = 1 / sqrt ( pi ) * ( P ( 0 , x ) * ss + Q ( 0 , x ) * cc ) / sqrt ( x )
*/
if ( ix < 0x7f000000 ) { /* make sure x+x not overflow */
z = - __cosf ( x + x ) ;
if ( ( s * c ) < zero ) cc = z / ss ;
else ss = z / cc ;
}
if ( ix > 0x5c000000 ) z = ( invsqrtpi * ss ) / sqrtf ( x ) ;
else {
u = pzerof ( x ) ; v = qzerof ( x ) ;
z = invsqrtpi * ( u * ss + v * cc ) / sqrtf ( x ) ;
}
return z ;
if ( ix > = 0x7f000000 )
/* x >= 2^127: use asymptotic expansion. */
return y0f_asympt ( x ) ;
/* Now we are sure that x+x cannot overflow. */
z = - __cosf ( x + x ) ;
if ( ( s * c ) < zero ) cc = z / ss ;
else ss = z / cc ;
if ( ix < = 0x5c000000 )
{
u = pzerof ( x ) ; v = qzerof ( x ) ;
ss = u * ss + v * cc ;
}
z = ( invsqrtpi * ss ) / sqrtf ( x ) ;
/* The following threshold is optimal (determined on
aarch64 - linux - gnu ) . */
float threshold = 0x1 . be585ap - 4 ;
if ( fabsf ( ss ) > threshold )
return z ;
else
return y0f_near_root ( x , z ) ;
}
if ( ix < = 0x39800000 ) { /* x < 2**-13 */
return ( u00 + tpi * __ieee754_logf ( x ) ) ;
@ -165,7 +600,7 @@ __ieee754_y0f(float x)
}
libm_alias_finite ( __ieee754_y0f , __y0f )
/* The asymptotic expansions of pzero is
/* The asymptotic expansion of pzero is
* 1 - 9 / 128 s ^ 2 + 11025 / 98304 s ^ 4 - . . . , where s = 1 / x .
* For x > = 2 , We approximate pzero by
* pzero ( x ) = 1 + ( R / S )
@ -257,7 +692,7 @@ pzerof(float x)
}
/* For x >= 8, the asymptotic expansions of qzero is
/* For x >= 8, the asymptotic expansion of qzero is
* - 1 / 8 s + 75 / 1024 s ^ 3 - . . . , where s = 1 / x .
* We approximate pzero by
* qzero ( x ) = s * ( - 1.25 + ( R / S ) )