From 172b4ce7a3d927db3bf71bcc833bcc170dcbae35 Mon Sep 17 00:00:00 2001 From: Alec Murphy Date: Fri, 4 Apr 2025 18:16:29 -0400 Subject: [PATCH] Meta: Add OpenLibm --- src/openlibm/CMakeLists.txt | 576 +++ src/openlibm/LICENSE.md | 115 + src/openlibm/Make.inc | 197 + src/openlibm/Makefile | 137 + src/openlibm/README.md | 71 + src/openlibm/aarch64/Make.files | 1 + src/openlibm/aarch64/fenv.c | 51 + src/openlibm/amd64/Make.files | 7 + src/openlibm/amd64/bsd_asm.h | 110 + src/openlibm/amd64/bsd_fpu.h | 218 + src/openlibm/amd64/bsd_ieeefp.h | 272 + src/openlibm/amd64/e_fmod.S | 56 + src/openlibm/amd64/e_fmod.S.o | Bin 0 -> 872 bytes src/openlibm/amd64/e_fmodf.S | 26 + src/openlibm/amd64/e_fmodf.S.o | Bin 0 -> 872 bytes src/openlibm/amd64/e_fmodl.S | 52 + src/openlibm/amd64/e_fmodl.S.o | Bin 0 -> 848 bytes src/openlibm/amd64/e_remainder.S | 30 + src/openlibm/amd64/e_remainder.S.o | Bin 0 -> 880 bytes src/openlibm/amd64/e_remainderf.S | 29 + src/openlibm/amd64/e_remainderf.S.o | Bin 0 -> 880 bytes src/openlibm/amd64/e_remainderl.S | 35 + src/openlibm/amd64/e_remainderl.S.o | Bin 0 -> 856 bytes src/openlibm/amd64/e_sqrt.S | 40 + src/openlibm/amd64/e_sqrt.S.o | Bin 0 -> 832 bytes src/openlibm/amd64/e_sqrtf.S | 39 + src/openlibm/amd64/e_sqrtf.S.o | Bin 0 -> 832 bytes src/openlibm/amd64/e_sqrtl.S | 46 + src/openlibm/amd64/e_sqrtl.S.o | Bin 0 -> 832 bytes src/openlibm/amd64/fenv.c | 162 + src/openlibm/amd64/fenv.c.o | Bin 0 -> 2336 bytes src/openlibm/amd64/s_llrint.S | 12 + src/openlibm/amd64/s_llrint.S.o | Bin 0 -> 832 bytes src/openlibm/amd64/s_llrintf.S | 12 + src/openlibm/amd64/s_llrintf.S.o | Bin 0 -> 832 bytes src/openlibm/amd64/s_llrintl.S | 45 + src/openlibm/amd64/s_llrintl.S.o | Bin 0 -> 840 bytes src/openlibm/amd64/s_logbl.S | 29 + src/openlibm/amd64/s_logbl.S.o | Bin 0 -> 840 bytes src/openlibm/amd64/s_lrint.S | 44 + src/openlibm/amd64/s_lrint.S.o | Bin 0 -> 832 bytes src/openlibm/amd64/s_lrintf.S | 44 + src/openlibm/amd64/s_lrintf.S.o | Bin 0 -> 832 bytes src/openlibm/amd64/s_lrintl.S | 45 + src/openlibm/amd64/s_lrintl.S.o | Bin 0 -> 840 bytes src/openlibm/amd64/s_remquo.S | 76 + src/openlibm/amd64/s_remquo.S.o | Bin 0 -> 920 bytes src/openlibm/amd64/s_remquof.S | 76 + src/openlibm/amd64/s_remquof.S.o | Bin 0 -> 920 bytes src/openlibm/amd64/s_remquol.S | 81 + src/openlibm/amd64/s_remquol.S.o | Bin 0 -> 896 bytes src/openlibm/amd64/s_rintl.S | 26 + src/openlibm/amd64/s_rintl.S.o | Bin 0 -> 832 bytes src/openlibm/amd64/s_scalbn.S | 55 + src/openlibm/amd64/s_scalbn.S.o | Bin 0 -> 896 bytes src/openlibm/amd64/s_scalbnf.S | 55 + src/openlibm/amd64/s_scalbnf.S.o | Bin 0 -> 896 bytes src/openlibm/amd64/s_scalbnl.S | 40 + src/openlibm/amd64/s_scalbnl.S.o | Bin 0 -> 880 bytes src/openlibm/arm/Make.files | 1 + src/openlibm/arm/fenv.c | 52 + src/openlibm/bsdsrc/Make.files | 1 + src/openlibm/bsdsrc/b_exp.c | 172 + src/openlibm/bsdsrc/b_exp.c.o | Bin 0 -> 2912 bytes src/openlibm/bsdsrc/b_log.c | 466 ++ src/openlibm/bsdsrc/b_log.c.o | Bin 0 -> 5128 bytes src/openlibm/bsdsrc/b_tgamma.c | 319 ++ src/openlibm/bsdsrc/b_tgamma.c.o | Bin 0 -> 7568 bytes src/openlibm/bsdsrc/mathimpl.h | 70 + src/openlibm/docs/CNAME | 1 + src/openlibm/docs/images/arrow-down.png | Bin 0 -> 216 bytes src/openlibm/docs/images/octocat-small.png | Bin 0 -> 357 bytes src/openlibm/docs/index.html | 94 + src/openlibm/docs/javascripts/scale.fix.js | 20 + src/openlibm/docs/params.json | 1 + .../docs/stylesheets/pygment_trac.css | 69 + src/openlibm/docs/stylesheets/styles.css | 423 ++ src/openlibm/i387/Make.files | 21 + src/openlibm/i387/bsd_asm.h | 118 + src/openlibm/i387/bsd_ieeefp.h | 265 + src/openlibm/i387/bsd_npx.h | 160 + src/openlibm/i387/e_exp.S | 76 + src/openlibm/i387/e_fmod.S | 25 + src/openlibm/i387/e_log.S | 21 + src/openlibm/i387/e_log10.S | 21 + src/openlibm/i387/e_log10f.S | 22 + src/openlibm/i387/e_logf.S | 21 + src/openlibm/i387/e_remainder.S | 25 + src/openlibm/i387/e_remainderf.S | 26 + src/openlibm/i387/e_remainderl.S | 25 + src/openlibm/i387/e_sqrt.S | 37 + src/openlibm/i387/e_sqrtf.S | 21 + src/openlibm/i387/e_sqrtl.S | 19 + src/openlibm/i387/fenv.c | 226 + src/openlibm/i387/invtrig.c | 86 + src/openlibm/i387/osx_asm.h | 408 ++ src/openlibm/i387/s_ceil.S | 34 + src/openlibm/i387/s_ceilf.S | 36 + src/openlibm/i387/s_ceill.S | 34 + src/openlibm/i387/s_copysign.S | 25 + src/openlibm/i387/s_copysignf.S | 26 + src/openlibm/i387/s_copysignl.S | 24 + src/openlibm/i387/s_cos.S | 33 + src/openlibm/i387/s_floor.S | 35 + src/openlibm/i387/s_floorf.S | 36 + src/openlibm/i387/s_floorl.S | 34 + src/openlibm/i387/s_llrint.S | 43 + src/openlibm/i387/s_llrintf.S | 43 + src/openlibm/i387/s_llrintl.S | 42 + src/openlibm/i387/s_logb.S | 21 + src/openlibm/i387/s_logbf.S | 22 + src/openlibm/i387/s_logbl.S | 20 + src/openlibm/i387/s_lrint.S | 42 + src/openlibm/i387/s_lrintf.S | 42 + src/openlibm/i387/s_lrintl.S | 41 + src/openlibm/i387/s_remquo.S | 69 + src/openlibm/i387/s_remquof.S | 69 + src/openlibm/i387/s_remquol.S | 69 + src/openlibm/i387/s_rint.S | 20 + src/openlibm/i387/s_rintf.S | 21 + src/openlibm/i387/s_rintl.S | 19 + src/openlibm/i387/s_scalbn.S | 23 + src/openlibm/i387/s_scalbnf.S | 26 + src/openlibm/i387/s_scalbnl.S | 26 + src/openlibm/i387/s_sin.S | 33 + src/openlibm/i387/s_tan.S | 35 + src/openlibm/i387/s_trunc.S | 33 + src/openlibm/i387/s_truncf.S | 33 + src/openlibm/i387/s_truncl.S | 33 + src/openlibm/include/openlibm.h | 8 + src/openlibm/include/openlibm_complex.h | 179 + src/openlibm/include/openlibm_defs.h | 14 + src/openlibm/include/openlibm_fenv.h | 27 + src/openlibm/include/openlibm_fenv_aarch64.h | 247 + src/openlibm/include/openlibm_fenv_amd64.h | 223 + src/openlibm/include/openlibm_fenv_arm.h | 227 + src/openlibm/include/openlibm_fenv_i387.h | 260 + .../include/openlibm_fenv_loongarch64.h | 226 + src/openlibm/include/openlibm_fenv_mips.h | 278 + src/openlibm/include/openlibm_fenv_powerpc.h | 279 + src/openlibm/include/openlibm_fenv_riscv.h | 261 + src/openlibm/include/openlibm_fenv_s390.h | 235 + src/openlibm/include/openlibm_math.h | 493 ++ src/openlibm/ld128/Make.files | 13 + src/openlibm/ld128/e_acoshl.c | 58 + src/openlibm/ld128/e_atanhl.c | 65 + src/openlibm/ld128/e_coshl.c | 105 + src/openlibm/ld128/e_expl.c | 145 + src/openlibm/ld128/e_fmodl.c | 129 + src/openlibm/ld128/e_hypotl.c | 122 + src/openlibm/ld128/e_lgammal_r.c | 1037 ++++ src/openlibm/ld128/e_log10l.c | 255 + src/openlibm/ld128/e_log2l.c | 248 + src/openlibm/ld128/e_logl.c | 283 + src/openlibm/ld128/e_powl.c | 439 ++ src/openlibm/ld128/e_rem_pio2l.h | 144 + src/openlibm/ld128/e_sinhl.c | 104 + src/openlibm/ld128/e_tgammal.c | 39 + src/openlibm/ld128/invtrig.c | 100 + src/openlibm/ld128/invtrig.h | 113 + src/openlibm/ld128/k_cosl.c | 61 + src/openlibm/ld128/k_sinl.c | 59 + src/openlibm/ld128/k_tanl.c | 120 + src/openlibm/ld128/s_asinhl.c | 69 + src/openlibm/ld128/s_ceill.c | 69 + src/openlibm/ld128/s_erfl.c | 926 ++++ src/openlibm/ld128/s_exp2l.c | 431 ++ src/openlibm/ld128/s_expm1l.c | 162 + src/openlibm/ld128/s_floorl.c | 71 + src/openlibm/ld128/s_log1pl.c | 247 + src/openlibm/ld128/s_modfl.c | 73 + src/openlibm/ld128/s_nanl.c | 46 + src/openlibm/ld128/s_nextafterl.c | 72 + src/openlibm/ld128/s_nexttoward.c | 85 + src/openlibm/ld128/s_nexttowardf.c | 65 + src/openlibm/ld128/s_remquol.c | 168 + src/openlibm/ld128/s_tanhl.c | 105 + src/openlibm/ld128/s_truncl.c | 72 + src/openlibm/ld80/Make.files | 13 + src/openlibm/ld80/e_acoshl.c | 57 + src/openlibm/ld80/e_acoshl.c.o | Bin 0 -> 1816 bytes src/openlibm/ld80/e_atanhl.c | 60 + src/openlibm/ld80/e_atanhl.c.o | Bin 0 -> 2032 bytes src/openlibm/ld80/e_coshl.c | 83 + src/openlibm/ld80/e_coshl.c.o | Bin 0 -> 2536 bytes src/openlibm/ld80/e_expl.c | 131 + src/openlibm/ld80/e_expl.c.o | Bin 0 -> 2688 bytes src/openlibm/ld80/e_fmodl.c | 142 + src/openlibm/ld80/e_hypotl.c | 122 + src/openlibm/ld80/e_lgammal_r.c | 425 ++ src/openlibm/ld80/e_lgammal_r.c.o | Bin 0 -> 10040 bytes src/openlibm/ld80/e_log10l.c | 205 + src/openlibm/ld80/e_log10l.c.o | Bin 0 -> 3576 bytes src/openlibm/ld80/e_log2l.c | 199 + src/openlibm/ld80/e_log2l.c.o | Bin 0 -> 3464 bytes src/openlibm/ld80/e_logl.c | 190 + src/openlibm/ld80/e_logl.c.o | Bin 0 -> 3512 bytes src/openlibm/ld80/e_powl.c | 615 +++ src/openlibm/ld80/e_powl.c.o | Bin 0 -> 13376 bytes src/openlibm/ld80/e_rem_pio2l.h | 152 + src/openlibm/ld80/e_sinhl.c | 76 + src/openlibm/ld80/e_sinhl.c.o | Bin 0 -> 2632 bytes src/openlibm/ld80/e_tgammal.c | 313 ++ src/openlibm/ld80/e_tgammal.c.o | Bin 0 -> 6048 bytes src/openlibm/ld80/invtrig.c | 82 + src/openlibm/ld80/invtrig.c.o | Bin 0 -> 2136 bytes src/openlibm/ld80/invtrig.h | 114 + src/openlibm/ld80/k_cosl.c | 78 + src/openlibm/ld80/k_cosl.c.o | Bin 0 -> 2216 bytes src/openlibm/ld80/k_sinl.c | 62 + src/openlibm/ld80/k_sinl.c.o | Bin 0 -> 2368 bytes src/openlibm/ld80/k_tanl.c | 125 + src/openlibm/ld80/k_tanl.c.o | Bin 0 -> 3824 bytes src/openlibm/ld80/s_asinhl.c | 54 + src/openlibm/ld80/s_asinhl.c.o | Bin 0 -> 2144 bytes src/openlibm/ld80/s_ceill.c | 78 + src/openlibm/ld80/s_erfl.c | 430 ++ src/openlibm/ld80/s_erfl.c.o | Bin 0 -> 11504 bytes src/openlibm/ld80/s_exp2l.c | 295 ++ src/openlibm/ld80/s_exp2l.c.o | Bin 0 -> 5120 bytes src/openlibm/ld80/s_expm1l.c | 138 + src/openlibm/ld80/s_expm1l.c.o | Bin 0 -> 3088 bytes src/openlibm/ld80/s_floorl.c | 80 + src/openlibm/ld80/s_log1pl.c | 191 + src/openlibm/ld80/s_log1pl.c.o | Bin 0 -> 3432 bytes src/openlibm/ld80/s_modfl.c | 69 + src/openlibm/ld80/s_nanl.c | 45 + src/openlibm/ld80/s_nanl.c.o | Bin 0 -> 1400 bytes src/openlibm/ld80/s_nextafterl.c | 90 + src/openlibm/ld80/s_nexttoward.c | 86 + src/openlibm/ld80/s_nexttowardf.c | 67 + src/openlibm/ld80/s_remquol.c | 166 + src/openlibm/ld80/s_tanhl.c | 79 + src/openlibm/ld80/s_tanhl.c.o | Bin 0 -> 1968 bytes src/openlibm/ld80/s_truncl.c | 72 + src/openlibm/loongarch64/Make.files | 1 + src/openlibm/loongarch64/fenv.c | 27 + src/openlibm/mips/Make.files | 1 + src/openlibm/mips/fenv-softfloat.h | 184 + src/openlibm/mips/fenv.c | 67 + src/openlibm/openlibm.pc.in | 6 + src/openlibm/powerpc/Make.files | 1 + src/openlibm/powerpc/fenv.c | 47 + src/openlibm/riscv64/Make.files | 1 + src/openlibm/riscv64/fenv.c | 63 + src/openlibm/s390/Make.files | 1 + src/openlibm/s390/fenv.c | 50 + src/openlibm/src/Make.files | 78 + src/openlibm/src/aarch64_fpmath.h | 60 + src/openlibm/src/amd64_fpmath.h | 55 + src/openlibm/src/bsd_cdefs.h | 102 + src/openlibm/src/cdefs-compat.h | 105 + src/openlibm/src/common.c | 7 + src/openlibm/src/common.c.o | Bin 0 -> 1232 bytes src/openlibm/src/e_acos.c | 111 + src/openlibm/src/e_acos.c.o | Bin 0 -> 3904 bytes src/openlibm/src/e_acosf.c | 78 + src/openlibm/src/e_acosf.c.o | Bin 0 -> 2968 bytes src/openlibm/src/e_acosh.c | 68 + src/openlibm/src/e_acosh.c.o | Bin 0 -> 2056 bytes src/openlibm/src/e_acoshf.c | 49 + src/openlibm/src/e_acoshf.c.o | Bin 0 -> 2048 bytes src/openlibm/src/e_acosl.c | 87 + src/openlibm/src/e_acosl.c.o | Bin 0 -> 3696 bytes src/openlibm/src/e_asin.c | 117 + src/openlibm/src/e_asin.c.o | Bin 0 -> 3688 bytes src/openlibm/src/e_asinf.c | 66 + src/openlibm/src/e_asinf.c.o | Bin 0 -> 2752 bytes src/openlibm/src/e_asinl.c | 77 + src/openlibm/src/e_asinl.c.o | Bin 0 -> 3648 bytes src/openlibm/src/e_atan2.c | 129 + src/openlibm/src/e_atan2.c.o | Bin 0 -> 3400 bytes src/openlibm/src/e_atan2f.c | 97 + src/openlibm/src/e_atan2f.c.o | Bin 0 -> 3296 bytes src/openlibm/src/e_atan2l.c | 120 + src/openlibm/src/e_atan2l.c.o | Bin 0 -> 3504 bytes src/openlibm/src/e_atanh.c | 68 + src/openlibm/src/e_atanh.c.o | Bin 0 -> 2128 bytes src/openlibm/src/e_atanhf.c | 46 + src/openlibm/src/e_atanhf.c.o | Bin 0 -> 2048 bytes src/openlibm/src/e_cosh.c | 85 + src/openlibm/src/e_cosh.c.o | Bin 0 -> 2144 bytes src/openlibm/src/e_coshf.c | 60 + src/openlibm/src/e_coshf.c.o | Bin 0 -> 2128 bytes src/openlibm/src/e_exp.c | 171 + src/openlibm/src/e_exp.c.o | Bin 0 -> 3848 bytes src/openlibm/src/e_expf.c | 97 + src/openlibm/src/e_expf.c.o | Bin 0 -> 3336 bytes src/openlibm/src/e_fmod.c | 133 + src/openlibm/src/e_fmodf.c | 105 + src/openlibm/src/e_fmodl.c | 150 + src/openlibm/src/e_hypot.c | 131 + src/openlibm/src/e_hypot.c.o | Bin 0 -> 2672 bytes src/openlibm/src/e_hypotf.c | 84 + src/openlibm/src/e_hypotf.c.o | Bin 0 -> 2512 bytes src/openlibm/src/e_hypotl.c | 124 + src/openlibm/src/e_hypotl.c.o | Bin 0 -> 2552 bytes src/openlibm/src/e_j0.c | 388 ++ src/openlibm/src/e_j0.c.o | Bin 0 -> 13280 bytes src/openlibm/src/e_j0f.c | 337 ++ src/openlibm/src/e_j0f.c.o | Bin 0 -> 11968 bytes src/openlibm/src/e_j1.c | 383 ++ src/openlibm/src/e_j1.c.o | Bin 0 -> 13176 bytes src/openlibm/src/e_j1f.c | 332 ++ src/openlibm/src/e_j1f.c.o | Bin 0 -> 11848 bytes src/openlibm/src/e_jn.c | 271 + src/openlibm/src/e_jn.c.o | Bin 0 -> 5704 bytes src/openlibm/src/e_jnf.c | 200 + src/openlibm/src/e_jnf.c.o | Bin 0 -> 4176 bytes src/openlibm/src/e_lgamma.c | 36 + src/openlibm/src/e_lgamma.c.o | Bin 0 -> 1472 bytes src/openlibm/src/e_lgamma_r.c | 298 ++ src/openlibm/src/e_lgamma_r.c.o | Bin 0 -> 9888 bytes src/openlibm/src/e_lgammaf.c | 37 + src/openlibm/src/e_lgammaf.c.o | Bin 0 -> 1472 bytes src/openlibm/src/e_lgammaf_r.c | 231 + src/openlibm/src/e_lgammaf_r.c.o | Bin 0 -> 9624 bytes src/openlibm/src/e_lgammal.c | 15 + src/openlibm/src/e_lgammal.c.o | Bin 0 -> 1472 bytes src/openlibm/src/e_log.c | 146 + src/openlibm/src/e_log.c.o | Bin 0 -> 3160 bytes src/openlibm/src/e_log10.c | 93 + src/openlibm/src/e_log10.c.o | Bin 0 -> 2896 bytes src/openlibm/src/e_log10f.c | 75 + src/openlibm/src/e_log10f.c.o | Bin 0 -> 2536 bytes src/openlibm/src/e_log2.c | 116 + src/openlibm/src/e_log2.c.o | Bin 0 -> 2760 bytes src/openlibm/src/e_log2f.c | 85 + src/openlibm/src/e_log2f.c.o | Bin 0 -> 2392 bytes src/openlibm/src/e_logf.c | 89 + src/openlibm/src/e_logf.c.o | Bin 0 -> 2840 bytes src/openlibm/src/e_pow.c | 317 ++ src/openlibm/src/e_pow.c.o | Bin 0 -> 6848 bytes src/openlibm/src/e_powf.c | 253 + src/openlibm/src/e_powf.c.o | Bin 0 -> 6536 bytes src/openlibm/src/e_rem_pio2.c | 183 + src/openlibm/src/e_rem_pio2.c.o | Bin 0 -> 3856 bytes src/openlibm/src/e_rem_pio2f.c | 81 + src/openlibm/src/e_rem_pio2f.c.o | Bin 0 -> 2096 bytes src/openlibm/src/e_remainder.c | 79 + src/openlibm/src/e_remainderf.c | 66 + src/openlibm/src/e_remainderl.c | 39 + src/openlibm/src/e_sinh.c | 79 + src/openlibm/src/e_sinh.c.o | Bin 0 -> 2552 bytes src/openlibm/src/e_sinhf.c | 57 + src/openlibm/src/e_sinhf.c.o | Bin 0 -> 2528 bytes src/openlibm/src/e_sqrt.c | 451 ++ src/openlibm/src/e_sqrtf.c | 86 + src/openlibm/src/e_sqrtl.c | 162 + src/openlibm/src/fpmath.h | 124 + src/openlibm/src/i386_fpmath.h | 54 + src/openlibm/src/k_cos.c | 80 + src/openlibm/src/k_cos.c.o | Bin 0 -> 2024 bytes src/openlibm/src/k_cosf.c | 48 + src/openlibm/src/k_cosf.c.o | Bin 0 -> 1776 bytes src/openlibm/src/k_exp.c | 108 + src/openlibm/src/k_exp.c.o | Bin 0 -> 2232 bytes src/openlibm/src/k_expf.c | 87 + src/openlibm/src/k_expf.c.o | Bin 0 -> 2216 bytes src/openlibm/src/k_log.h | 100 + src/openlibm/src/k_logf.h | 39 + src/openlibm/src/k_rem_pio2.c | 444 ++ src/openlibm/src/k_rem_pio2.c.o | Bin 0 -> 10816 bytes src/openlibm/src/k_sin.c | 71 + src/openlibm/src/k_sin.c.o | Bin 0 -> 2008 bytes src/openlibm/src/k_sinf.c | 48 + src/openlibm/src/k_sinf.c.o | Bin 0 -> 1720 bytes src/openlibm/src/k_tan.c | 134 + src/openlibm/src/k_tan.c.o | Bin 0 -> 3048 bytes src/openlibm/src/k_tanf.c | 68 + src/openlibm/src/k_tanf.c.o | Bin 0 -> 1952 bytes src/openlibm/src/loongarch64_fpmath.h | 56 + src/openlibm/src/math_private.h | 375 ++ src/openlibm/src/math_private_openbsd.h | 218 + src/openlibm/src/mips_fpmath.h | 57 + src/openlibm/src/polevll.c | 104 + src/openlibm/src/polevll.c.o | Bin 0 -> 1416 bytes src/openlibm/src/powerpc_fpmath.h | 49 + src/openlibm/src/riscv_fpmath.h | 58 + src/openlibm/src/s390_fpmath.h | 51 + src/openlibm/src/s_asinh.c | 62 + src/openlibm/src/s_asinh.c.o | Bin 0 -> 2480 bytes src/openlibm/src/s_asinhf.c | 49 + src/openlibm/src/s_asinhf.c.o | Bin 0 -> 2448 bytes src/openlibm/src/s_atan.c | 124 + src/openlibm/src/s_atan.c.o | Bin 0 -> 4176 bytes src/openlibm/src/s_atanf.c | 93 + src/openlibm/src/s_atanf.c.o | Bin 0 -> 3768 bytes src/openlibm/src/s_atanl.c | 85 + src/openlibm/src/s_atanl.c.o | Bin 0 -> 2616 bytes src/openlibm/src/s_cabs.c | 32 + src/openlibm/src/s_cabsf.c | 25 + src/openlibm/src/s_cabsl.c | 26 + src/openlibm/src/s_cacos.c | 67 + src/openlibm/src/s_cacos.c.o | Bin 0 -> 1840 bytes src/openlibm/src/s_cacosf.c | 60 + src/openlibm/src/s_cacosf.c.o | Bin 0 -> 1928 bytes src/openlibm/src/s_cacosh.c | 62 + src/openlibm/src/s_cacosh.c.o | Bin 0 -> 1632 bytes src/openlibm/src/s_cacoshf.c | 55 + src/openlibm/src/s_cacoshf.c.o | Bin 0 -> 1696 bytes src/openlibm/src/s_cacoshl.c | 56 + src/openlibm/src/s_cacoshl.c.o | Bin 0 -> 1560 bytes src/openlibm/src/s_cacosl.c | 63 + src/openlibm/src/s_cacosl.c.o | Bin 0 -> 1736 bytes src/openlibm/src/s_carg.c | 40 + src/openlibm/src/s_carg.c.o | Bin 0 -> 1528 bytes src/openlibm/src/s_cargf.c | 40 + src/openlibm/src/s_cargf.c.o | Bin 0 -> 1560 bytes src/openlibm/src/s_cargl.c | 40 + src/openlibm/src/s_cargl.c.o | Bin 0 -> 1536 bytes src/openlibm/src/s_casin.c | 136 + src/openlibm/src/s_casin.c.o | Bin 0 -> 3200 bytes src/openlibm/src/s_casinf.c | 132 + src/openlibm/src/s_casinf.c.o | Bin 0 -> 3248 bytes src/openlibm/src/s_casinh.c | 62 + src/openlibm/src/s_casinh.c.o | Bin 0 -> 1848 bytes src/openlibm/src/s_casinhf.c | 55 + src/openlibm/src/s_casinhf.c.o | Bin 0 -> 1912 bytes src/openlibm/src/s_casinhl.c | 56 + src/openlibm/src/s_casinhl.c.o | Bin 0 -> 1656 bytes src/openlibm/src/s_casinl.c | 130 + src/openlibm/src/s_casinl.c.o | Bin 0 -> 4264 bytes src/openlibm/src/s_catan.c | 133 + src/openlibm/src/s_catan.c.o | Bin 0 -> 2528 bytes src/openlibm/src/s_catanf.c | 124 + src/openlibm/src/s_catanf.c.o | Bin 0 -> 2624 bytes src/openlibm/src/s_catanh.c | 62 + src/openlibm/src/s_catanh.c.o | Bin 0 -> 1848 bytes src/openlibm/src/s_catanhf.c | 55 + src/openlibm/src/s_catanhf.c.o | Bin 0 -> 1912 bytes src/openlibm/src/s_catanhl.c | 56 + src/openlibm/src/s_catanhl.c.o | Bin 0 -> 1656 bytes src/openlibm/src/s_catanl.c | 127 + src/openlibm/src/s_catanl.c.o | Bin 0 -> 2528 bytes src/openlibm/src/s_cbrt.c | 118 + src/openlibm/src/s_cbrt.c.o | Bin 0 -> 2072 bytes src/openlibm/src/s_cbrtf.c | 74 + src/openlibm/src/s_cbrtf.c.o | Bin 0 -> 1672 bytes src/openlibm/src/s_cbrtl.c | 161 + src/openlibm/src/s_cbrtl.c.o | Bin 0 -> 2248 bytes src/openlibm/src/s_ccos.c | 91 + src/openlibm/src/s_ccosf.c | 84 + src/openlibm/src/s_ccosh.c | 155 + src/openlibm/src/s_ccosh.c.o | Bin 0 -> 3952 bytes src/openlibm/src/s_ccoshf.c | 104 + src/openlibm/src/s_ccoshf.c.o | Bin 0 -> 3880 bytes src/openlibm/src/s_ccoshl.c | 59 + src/openlibm/src/s_ccoshl.c.o | Bin 0 -> 1832 bytes src/openlibm/src/s_ccosl.c | 82 + src/openlibm/src/s_ccosl.c.o | Bin 0 -> 2368 bytes src/openlibm/src/s_ceil.c | 77 + src/openlibm/src/s_ceil.c.o | Bin 0 -> 1832 bytes src/openlibm/src/s_ceilf.c | 53 + src/openlibm/src/s_ceilf.c.o | Bin 0 -> 1728 bytes src/openlibm/src/s_ceill.c | 102 + src/openlibm/src/s_ceill.c.o | Bin 0 -> 2056 bytes src/openlibm/src/s_cexp.c | 89 + src/openlibm/src/s_cexp.c.o | Bin 0 -> 2168 bytes src/openlibm/src/s_cexpf.c | 89 + src/openlibm/src/s_cexpf.c.o | Bin 0 -> 2128 bytes src/openlibm/src/s_cexpl.c | 69 + src/openlibm/src/s_cexpl.c.o | Bin 0 -> 1776 bytes src/openlibm/src/s_cimag.c | 37 + src/openlibm/src/s_cimag.c.o | Bin 0 -> 1232 bytes src/openlibm/src/s_cimagf.c | 37 + src/openlibm/src/s_cimagf.c.o | Bin 0 -> 1232 bytes src/openlibm/src/s_cimagl.c | 37 + src/openlibm/src/s_cimagl.c.o | Bin 0 -> 1232 bytes src/openlibm/src/s_clog.c | 79 + src/openlibm/src/s_clog.c.o | Bin 0 -> 1672 bytes src/openlibm/src/s_clogf.c | 72 + src/openlibm/src/s_clogf.c.o | Bin 0 -> 1736 bytes src/openlibm/src/s_clogl.c | 73 + src/openlibm/src/s_clogl.c.o | Bin 0 -> 1736 bytes src/openlibm/src/s_conj.c | 38 + src/openlibm/src/s_conj.c.o | Bin 0 -> 1632 bytes src/openlibm/src/s_conjf.c | 38 + src/openlibm/src/s_conjf.c.o | Bin 0 -> 1680 bytes src/openlibm/src/s_conjl.c | 38 + src/openlibm/src/s_conjl.c.o | Bin 0 -> 1496 bytes src/openlibm/src/s_copysign.c | 34 + src/openlibm/src/s_copysign.c.o | Bin 0 -> 1280 bytes src/openlibm/src/s_copysignf.c | 37 + src/openlibm/src/s_copysignf.c.o | Bin 0 -> 1264 bytes src/openlibm/src/s_copysignl.c | 43 + src/openlibm/src/s_copysignl.c.o | Bin 0 -> 1280 bytes src/openlibm/src/s_cos.c | 89 + src/openlibm/src/s_cos.c.o | Bin 0 -> 2056 bytes src/openlibm/src/s_cosf.c | 85 + src/openlibm/src/s_cosf.c.o | Bin 0 -> 3128 bytes src/openlibm/src/s_cosl.c | 90 + src/openlibm/src/s_cosl.c.o | Bin 0 -> 3760 bytes src/openlibm/src/s_cpow.c | 78 + src/openlibm/src/s_cpow.c.o | Bin 0 -> 2360 bytes src/openlibm/src/s_cpowf.c | 73 + src/openlibm/src/s_cpowf.c.o | Bin 0 -> 2416 bytes src/openlibm/src/s_cpowl.c | 74 + src/openlibm/src/s_cpowl.c.o | Bin 0 -> 2280 bytes src/openlibm/src/s_cproj.c | 47 + src/openlibm/src/s_cproj.c.o | Bin 0 -> 1856 bytes src/openlibm/src/s_cprojf.c | 43 + src/openlibm/src/s_cprojf.c.o | Bin 0 -> 1912 bytes src/openlibm/src/s_cprojl.c | 43 + src/openlibm/src/s_cprojl.c.o | Bin 0 -> 1944 bytes src/openlibm/src/s_creal.c | 37 + src/openlibm/src/s_creal.c.o | Bin 0 -> 1224 bytes src/openlibm/src/s_crealf.c | 37 + src/openlibm/src/s_crealf.c.o | Bin 0 -> 1224 bytes src/openlibm/src/s_creall.c | 37 + src/openlibm/src/s_creall.c.o | Bin 0 -> 1232 bytes src/openlibm/src/s_csin.c | 93 + src/openlibm/src/s_csinf.c | 85 + src/openlibm/src/s_csinh.c | 157 + src/openlibm/src/s_csinh.c.o | Bin 0 -> 4048 bytes src/openlibm/src/s_csinhf.c | 105 + src/openlibm/src/s_csinhf.c.o | Bin 0 -> 4112 bytes src/openlibm/src/s_csinhl.c | 58 + src/openlibm/src/s_csinhl.c.o | Bin 0 -> 1832 bytes src/openlibm/src/s_csinl.c | 84 + src/openlibm/src/s_csinl.c.o | Bin 0 -> 2368 bytes src/openlibm/src/s_csqrt.c | 114 + src/openlibm/src/s_csqrt.c.o | Bin 0 -> 3104 bytes src/openlibm/src/s_csqrtf.c | 90 + src/openlibm/src/s_csqrtf.c.o | Bin 0 -> 3064 bytes src/openlibm/src/s_csqrtl.c | 109 + src/openlibm/src/s_csqrtl.c.o | Bin 0 -> 3384 bytes src/openlibm/src/s_ctan.c | 159 + src/openlibm/src/s_ctanf.c | 148 + src/openlibm/src/s_ctanh.c | 144 + src/openlibm/src/s_ctanh.c.o | Bin 0 -> 3496 bytes src/openlibm/src/s_ctanhf.c | 84 + src/openlibm/src/s_ctanhf.c.o | Bin 0 -> 3576 bytes src/openlibm/src/s_ctanhl.c | 60 + src/openlibm/src/s_ctanhl.c.o | Bin 0 -> 1848 bytes src/openlibm/src/s_ctanl.c | 157 + src/openlibm/src/s_ctanl.c.o | Bin 0 -> 3352 bytes src/openlibm/src/s_erf.c | 307 ++ src/openlibm/src/s_erf.c.o | Bin 0 -> 10160 bytes src/openlibm/src/s_erff.c | 184 + src/openlibm/src/s_erff.c.o | Bin 0 -> 7448 bytes src/openlibm/src/s_exp2.c | 396 ++ src/openlibm/src/s_exp2.c.o | Bin 0 -> 6864 bytes src/openlibm/src/s_exp2f.c | 136 + src/openlibm/src/s_exp2f.c.o | Bin 0 -> 2712 bytes src/openlibm/src/s_expm1.c | 221 + src/openlibm/src/s_expm1.c.o | Bin 0 -> 3952 bytes src/openlibm/src/s_expm1f.c | 123 + src/openlibm/src/s_expm1f.c.o | Bin 0 -> 3832 bytes src/openlibm/src/s_fabs.c | 28 + src/openlibm/src/s_fabs.c.o | Bin 0 -> 1232 bytes src/openlibm/src/s_fabsf.c | 34 + src/openlibm/src/s_fabsf.c.o | Bin 0 -> 1240 bytes src/openlibm/src/s_fabsl.c | 43 + src/openlibm/src/s_fabsl.c.o | Bin 0 -> 1248 bytes src/openlibm/src/s_fdim.c | 48 + src/openlibm/src/s_fdim.c.o | Bin 0 -> 2152 bytes src/openlibm/src/s_floor.c | 78 + src/openlibm/src/s_floor.c.o | Bin 0 -> 1848 bytes src/openlibm/src/s_floorf.c | 62 + src/openlibm/src/s_floorf.c.o | Bin 0 -> 1736 bytes src/openlibm/src/s_floorl.c | 102 + src/openlibm/src/s_floorl.c.o | Bin 0 -> 2064 bytes src/openlibm/src/s_fma.c | 284 ++ src/openlibm/src/s_fma.c.o | Bin 0 -> 3728 bytes src/openlibm/src/s_fmaf.c | 69 + src/openlibm/src/s_fmaf.c.o | Bin 0 -> 1464 bytes src/openlibm/src/s_fmal.c | 269 + src/openlibm/src/s_fmal.c.o | Bin 0 -> 4080 bytes src/openlibm/src/s_fmax.c | 54 + src/openlibm/src/s_fmax.c.o | Bin 0 -> 1376 bytes src/openlibm/src/s_fmaxf.c | 54 + src/openlibm/src/s_fmaxf.c.o | Bin 0 -> 1368 bytes src/openlibm/src/s_fmaxl.c | 56 + src/openlibm/src/s_fmaxl.c.o | Bin 0 -> 1400 bytes src/openlibm/src/s_fmin.c | 54 + src/openlibm/src/s_fmin.c.o | Bin 0 -> 1376 bytes src/openlibm/src/s_fminf.c | 54 + src/openlibm/src/s_fminf.c.o | Bin 0 -> 1368 bytes src/openlibm/src/s_fminl.c | 56 + src/openlibm/src/s_fminl.c.o | Bin 0 -> 1400 bytes src/openlibm/src/s_fpclassify.c | 98 + src/openlibm/src/s_fpclassify.c.o | Bin 0 -> 1680 bytes src/openlibm/src/s_frexp.c | 56 + src/openlibm/src/s_frexp.c.o | Bin 0 -> 1560 bytes src/openlibm/src/s_frexpf.c | 44 + src/openlibm/src/s_frexpf.c.o | Bin 0 -> 1536 bytes src/openlibm/src/s_frexpl.c | 63 + src/openlibm/src/s_frexpl.c.o | Bin 0 -> 1568 bytes src/openlibm/src/s_ilogb.c | 49 + src/openlibm/src/s_ilogb.c.o | Bin 0 -> 1368 bytes src/openlibm/src/s_ilogbf.c | 41 + src/openlibm/src/s_ilogbf.c.o | Bin 0 -> 1304 bytes src/openlibm/src/s_ilogbl.c | 54 + src/openlibm/src/s_ilogbl.c.o | Bin 0 -> 1408 bytes src/openlibm/src/s_isfinite.c | 61 + src/openlibm/src/s_isfinite.c.o | Bin 0 -> 1480 bytes src/openlibm/src/s_isinf.c | 66 + src/openlibm/src/s_isinf.c.o | Bin 0 -> 1528 bytes src/openlibm/src/s_isnan.c | 67 + src/openlibm/src/s_isnan.c.o | Bin 0 -> 1560 bytes src/openlibm/src/s_isnormal.c | 61 + src/openlibm/src/s_isnormal.c.o | Bin 0 -> 1480 bytes src/openlibm/src/s_llrint.c | 9 + src/openlibm/src/s_llrintf.c | 9 + src/openlibm/src/s_llrintl.c | 9 + src/openlibm/src/s_llround.c | 11 + src/openlibm/src/s_llround.c.o | Bin 0 -> 1368 bytes src/openlibm/src/s_llroundf.c | 11 + src/openlibm/src/s_llroundf.c.o | Bin 0 -> 1368 bytes src/openlibm/src/s_llroundl.c | 11 + src/openlibm/src/s_llroundl.c.o | Bin 0 -> 1408 bytes src/openlibm/src/s_log1p.c | 179 + src/openlibm/src/s_log1p.c.o | Bin 0 -> 3376 bytes src/openlibm/src/s_log1pf.c | 114 + src/openlibm/src/s_log1pf.c.o | Bin 0 -> 3232 bytes src/openlibm/src/s_logb.c | 49 + src/openlibm/src/s_logb.c.o | Bin 0 -> 1688 bytes src/openlibm/src/s_logbf.c | 41 + src/openlibm/src/s_logbf.c.o | Bin 0 -> 1664 bytes src/openlibm/src/s_logbl.c | 52 + src/openlibm/src/s_lrint.c | 61 + src/openlibm/src/s_lrintf.c | 9 + src/openlibm/src/s_lrintl.c | 9 + src/openlibm/src/s_lround.c | 69 + src/openlibm/src/s_lround.c.o | Bin 0 -> 1368 bytes src/openlibm/src/s_lroundf.c | 11 + src/openlibm/src/s_lroundf.c.o | Bin 0 -> 1368 bytes src/openlibm/src/s_lroundl.c | 11 + src/openlibm/src/s_lroundl.c.o | Bin 0 -> 1408 bytes src/openlibm/src/s_modf.c | 76 + src/openlibm/src/s_modf.c.o | Bin 0 -> 1456 bytes src/openlibm/src/s_modff.c | 58 + src/openlibm/src/s_modff.c.o | Bin 0 -> 1360 bytes src/openlibm/src/s_modfl.c | 101 + src/openlibm/src/s_modfl.c.o | Bin 0 -> 1784 bytes src/openlibm/src/s_nan.c | 124 + src/openlibm/src/s_nan.c.o | Bin 0 -> 1976 bytes src/openlibm/src/s_nearbyint.c | 56 + src/openlibm/src/s_nearbyint.c.o | Bin 0 -> 1664 bytes src/openlibm/src/s_nextafter.c | 83 + src/openlibm/src/s_nextafter.c.o | Bin 0 -> 1664 bytes src/openlibm/src/s_nextafterf.c | 67 + src/openlibm/src/s_nextafterf.c.o | Bin 0 -> 1448 bytes src/openlibm/src/s_nextafterl.c | 80 + src/openlibm/src/s_nextafterl.c.o | Bin 0 -> 1784 bytes src/openlibm/src/s_nexttoward.c | 72 + src/openlibm/src/s_nexttoward.c.o | Bin 0 -> 1624 bytes src/openlibm/src/s_nexttowardf.c | 61 + src/openlibm/src/s_nexttowardf.c.o | Bin 0 -> 1552 bytes src/openlibm/src/s_remquo.c | 159 + src/openlibm/src/s_remquof.c | 123 + src/openlibm/src/s_remquol.c | 178 + src/openlibm/src/s_rint.c | 92 + src/openlibm/src/s_rint.c.o | Bin 0 -> 1880 bytes src/openlibm/src/s_rintf.c | 53 + src/openlibm/src/s_rintf.c.o | Bin 0 -> 1608 bytes src/openlibm/src/s_rintl.c | 116 + src/openlibm/src/s_round.c | 55 + src/openlibm/src/s_round.c.o | Bin 0 -> 1984 bytes src/openlibm/src/s_roundf.c | 53 + src/openlibm/src/s_roundf.c.o | Bin 0 -> 2024 bytes src/openlibm/src/s_roundl.c | 53 + src/openlibm/src/s_roundl.c.o | Bin 0 -> 1768 bytes src/openlibm/src/s_scalbln.c | 80 + src/openlibm/src/s_scalbln.c.o | Bin 0 -> 1688 bytes src/openlibm/src/s_scalbn.c | 66 + src/openlibm/src/s_scalbnf.c | 57 + src/openlibm/src/s_scalbnl.c | 70 + src/openlibm/src/s_signbit.c | 61 + src/openlibm/src/s_signbit.c.o | Bin 0 -> 1440 bytes src/openlibm/src/s_signgam.c | 7 + src/openlibm/src/s_signgam.c.o | Bin 0 -> 984 bytes src/openlibm/src/s_sin.c | 89 + src/openlibm/src/s_sin.c.o | Bin 0 -> 1920 bytes src/openlibm/src/s_sincos.c | 159 + src/openlibm/src/s_sincos.c.o | Bin 0 -> 3696 bytes src/openlibm/src/s_sincosf.c | 172 + src/openlibm/src/s_sincosf.c.o | Bin 0 -> 5456 bytes src/openlibm/src/s_sincosl.c | 31 + src/openlibm/src/s_sincosl.c.o | Bin 0 -> 1896 bytes src/openlibm/src/s_sinf.c | 85 + src/openlibm/src/s_sinf.c.o | Bin 0 -> 2896 bytes src/openlibm/src/s_sinl.c | 88 + src/openlibm/src/s_sinl.c.o | Bin 0 -> 3736 bytes src/openlibm/src/s_tan.c | 83 + src/openlibm/src/s_tan.c.o | Bin 0 -> 1568 bytes src/openlibm/src/s_tanf.c | 72 + src/openlibm/src/s_tanf.c.o | Bin 0 -> 2352 bytes src/openlibm/src/s_tanh.c | 83 + src/openlibm/src/s_tanh.c.o | Bin 0 -> 2328 bytes src/openlibm/src/s_tanhf.c | 56 + src/openlibm/src/s_tanhf.c.o | Bin 0 -> 2280 bytes src/openlibm/src/s_tanl.c | 90 + src/openlibm/src/s_tanl.c.o | Bin 0 -> 3560 bytes src/openlibm/src/s_tgammaf.c | 45 + src/openlibm/src/s_tgammaf.c.o | Bin 0 -> 1376 bytes src/openlibm/src/s_trunc.c | 67 + src/openlibm/src/s_trunc.c.o | Bin 0 -> 1744 bytes src/openlibm/src/s_truncf.c | 54 + src/openlibm/src/s_truncf.c.o | Bin 0 -> 1600 bytes src/openlibm/src/s_truncl.c | 69 + src/openlibm/src/s_truncl.c.o | Bin 0 -> 1896 bytes src/openlibm/src/types-compat.h | 13 + src/openlibm/src/w_cabs.c | 25 + src/openlibm/src/w_cabs.c.o | Bin 0 -> 1528 bytes src/openlibm/src/w_cabsf.c | 19 + src/openlibm/src/w_cabsf.c.o | Bin 0 -> 1560 bytes src/openlibm/src/w_cabsl.c | 22 + src/openlibm/src/w_cabsl.c.o | Bin 0 -> 1536 bytes src/openlibm/test/.gitignore | 9 + src/openlibm/test/Makefile | 37 + src/openlibm/test/inf_torture.c | 76 + src/openlibm/test/libm-bench.cpp | 144 + src/openlibm/test/libm-test-ulps.h | 254 + src/openlibm/test/libm-test.c | 4537 +++++++++++++++++ src/openlibm/test/test-211.c | 12 + src/openlibm/test/test-double.c | 34 + src/openlibm/test/test-float.c | 34 + src/openlibm/wasm32/Make.files | 0 src/openlibm/wasm32/assert.h | 1 + src/openlibm/wasm32/float.h | 33 + src/openlibm/wasm32/limits.h | 9 + src/openlibm/wasm32/stdint.h | 43 + 724 files changed, 51312 insertions(+) create mode 100755 src/openlibm/CMakeLists.txt create mode 100644 src/openlibm/LICENSE.md create mode 100644 src/openlibm/Make.inc create mode 100644 src/openlibm/Makefile create mode 100644 src/openlibm/README.md create mode 100644 src/openlibm/aarch64/Make.files create mode 100644 src/openlibm/aarch64/fenv.c create mode 100644 src/openlibm/amd64/Make.files create mode 100644 src/openlibm/amd64/bsd_asm.h create mode 100644 src/openlibm/amd64/bsd_fpu.h create mode 100644 src/openlibm/amd64/bsd_ieeefp.h create mode 100644 src/openlibm/amd64/e_fmod.S create mode 100644 src/openlibm/amd64/e_fmod.S.o create mode 100644 src/openlibm/amd64/e_fmodf.S create mode 100644 src/openlibm/amd64/e_fmodf.S.o create mode 100644 src/openlibm/amd64/e_fmodl.S create mode 100644 src/openlibm/amd64/e_fmodl.S.o create mode 100644 src/openlibm/amd64/e_remainder.S create mode 100644 src/openlibm/amd64/e_remainder.S.o create mode 100644 src/openlibm/amd64/e_remainderf.S create mode 100644 src/openlibm/amd64/e_remainderf.S.o create mode 100644 src/openlibm/amd64/e_remainderl.S create mode 100644 src/openlibm/amd64/e_remainderl.S.o create mode 100644 src/openlibm/amd64/e_sqrt.S create mode 100644 src/openlibm/amd64/e_sqrt.S.o create mode 100644 src/openlibm/amd64/e_sqrtf.S create mode 100644 src/openlibm/amd64/e_sqrtf.S.o create mode 100644 src/openlibm/amd64/e_sqrtl.S create mode 100644 src/openlibm/amd64/e_sqrtl.S.o create mode 100644 src/openlibm/amd64/fenv.c create mode 100644 src/openlibm/amd64/fenv.c.o create mode 100644 src/openlibm/amd64/s_llrint.S create mode 100644 src/openlibm/amd64/s_llrint.S.o create mode 100644 src/openlibm/amd64/s_llrintf.S create mode 100644 src/openlibm/amd64/s_llrintf.S.o create mode 100644 src/openlibm/amd64/s_llrintl.S create mode 100644 src/openlibm/amd64/s_llrintl.S.o create mode 100644 src/openlibm/amd64/s_logbl.S create mode 100644 src/openlibm/amd64/s_logbl.S.o create mode 100644 src/openlibm/amd64/s_lrint.S create mode 100644 src/openlibm/amd64/s_lrint.S.o create mode 100644 src/openlibm/amd64/s_lrintf.S create mode 100644 src/openlibm/amd64/s_lrintf.S.o create mode 100644 src/openlibm/amd64/s_lrintl.S create mode 100644 src/openlibm/amd64/s_lrintl.S.o create mode 100644 src/openlibm/amd64/s_remquo.S create mode 100644 src/openlibm/amd64/s_remquo.S.o create mode 100644 src/openlibm/amd64/s_remquof.S create mode 100644 src/openlibm/amd64/s_remquof.S.o create mode 100644 src/openlibm/amd64/s_remquol.S create mode 100644 src/openlibm/amd64/s_remquol.S.o create mode 100644 src/openlibm/amd64/s_rintl.S create mode 100644 src/openlibm/amd64/s_rintl.S.o create mode 100644 src/openlibm/amd64/s_scalbn.S create mode 100644 src/openlibm/amd64/s_scalbn.S.o create mode 100644 src/openlibm/amd64/s_scalbnf.S create mode 100644 src/openlibm/amd64/s_scalbnf.S.o create mode 100644 src/openlibm/amd64/s_scalbnl.S create mode 100644 src/openlibm/amd64/s_scalbnl.S.o create mode 100644 src/openlibm/arm/Make.files create mode 100644 src/openlibm/arm/fenv.c create mode 100644 src/openlibm/bsdsrc/Make.files create mode 100644 src/openlibm/bsdsrc/b_exp.c create mode 100644 src/openlibm/bsdsrc/b_exp.c.o create mode 100644 src/openlibm/bsdsrc/b_log.c create mode 100644 src/openlibm/bsdsrc/b_log.c.o create mode 100644 src/openlibm/bsdsrc/b_tgamma.c create mode 100644 src/openlibm/bsdsrc/b_tgamma.c.o create mode 100644 src/openlibm/bsdsrc/mathimpl.h create mode 100644 src/openlibm/docs/CNAME create mode 100644 src/openlibm/docs/images/arrow-down.png create mode 100644 src/openlibm/docs/images/octocat-small.png create mode 100644 src/openlibm/docs/index.html create mode 100644 src/openlibm/docs/javascripts/scale.fix.js create mode 100644 src/openlibm/docs/params.json create mode 100644 src/openlibm/docs/stylesheets/pygment_trac.css create mode 100644 src/openlibm/docs/stylesheets/styles.css create mode 100644 src/openlibm/i387/Make.files create mode 100644 src/openlibm/i387/bsd_asm.h create mode 100644 src/openlibm/i387/bsd_ieeefp.h create mode 100644 src/openlibm/i387/bsd_npx.h create mode 100644 src/openlibm/i387/e_exp.S create mode 100644 src/openlibm/i387/e_fmod.S create mode 100644 src/openlibm/i387/e_log.S create mode 100644 src/openlibm/i387/e_log10.S create mode 100644 src/openlibm/i387/e_log10f.S create mode 100644 src/openlibm/i387/e_logf.S create mode 100644 src/openlibm/i387/e_remainder.S create mode 100644 src/openlibm/i387/e_remainderf.S create mode 100644 src/openlibm/i387/e_remainderl.S create mode 100644 src/openlibm/i387/e_sqrt.S create mode 100644 src/openlibm/i387/e_sqrtf.S create mode 100644 src/openlibm/i387/e_sqrtl.S create mode 100644 src/openlibm/i387/fenv.c create mode 100644 src/openlibm/i387/invtrig.c create mode 100644 src/openlibm/i387/osx_asm.h create mode 100644 src/openlibm/i387/s_ceil.S create mode 100644 src/openlibm/i387/s_ceilf.S create mode 100644 src/openlibm/i387/s_ceill.S create mode 100644 src/openlibm/i387/s_copysign.S create mode 100644 src/openlibm/i387/s_copysignf.S create mode 100644 src/openlibm/i387/s_copysignl.S create mode 100644 src/openlibm/i387/s_cos.S create mode 100644 src/openlibm/i387/s_floor.S create mode 100644 src/openlibm/i387/s_floorf.S create mode 100644 src/openlibm/i387/s_floorl.S create mode 100644 src/openlibm/i387/s_llrint.S create mode 100644 src/openlibm/i387/s_llrintf.S create mode 100644 src/openlibm/i387/s_llrintl.S create mode 100644 src/openlibm/i387/s_logb.S create mode 100644 src/openlibm/i387/s_logbf.S create mode 100644 src/openlibm/i387/s_logbl.S create mode 100644 src/openlibm/i387/s_lrint.S create mode 100644 src/openlibm/i387/s_lrintf.S create mode 100644 src/openlibm/i387/s_lrintl.S create mode 100644 src/openlibm/i387/s_remquo.S create mode 100644 src/openlibm/i387/s_remquof.S create mode 100644 src/openlibm/i387/s_remquol.S create mode 100644 src/openlibm/i387/s_rint.S create mode 100644 src/openlibm/i387/s_rintf.S create mode 100644 src/openlibm/i387/s_rintl.S create mode 100644 src/openlibm/i387/s_scalbn.S create mode 100644 src/openlibm/i387/s_scalbnf.S create mode 100644 src/openlibm/i387/s_scalbnl.S create mode 100644 src/openlibm/i387/s_sin.S create mode 100644 src/openlibm/i387/s_tan.S create mode 100644 src/openlibm/i387/s_trunc.S create mode 100644 src/openlibm/i387/s_truncf.S create mode 100644 src/openlibm/i387/s_truncl.S create mode 100644 src/openlibm/include/openlibm.h create mode 100644 src/openlibm/include/openlibm_complex.h create mode 100644 src/openlibm/include/openlibm_defs.h create mode 100644 src/openlibm/include/openlibm_fenv.h create mode 100644 src/openlibm/include/openlibm_fenv_aarch64.h create mode 100644 src/openlibm/include/openlibm_fenv_amd64.h create mode 100644 src/openlibm/include/openlibm_fenv_arm.h create mode 100644 src/openlibm/include/openlibm_fenv_i387.h create mode 100644 src/openlibm/include/openlibm_fenv_loongarch64.h create mode 100644 src/openlibm/include/openlibm_fenv_mips.h create mode 100644 src/openlibm/include/openlibm_fenv_powerpc.h create mode 100644 src/openlibm/include/openlibm_fenv_riscv.h create mode 100644 src/openlibm/include/openlibm_fenv_s390.h create mode 100644 src/openlibm/include/openlibm_math.h create mode 100644 src/openlibm/ld128/Make.files create mode 100644 src/openlibm/ld128/e_acoshl.c create mode 100644 src/openlibm/ld128/e_atanhl.c create mode 100644 src/openlibm/ld128/e_coshl.c create mode 100644 src/openlibm/ld128/e_expl.c create mode 100644 src/openlibm/ld128/e_fmodl.c create mode 100644 src/openlibm/ld128/e_hypotl.c create mode 100644 src/openlibm/ld128/e_lgammal_r.c create mode 100644 src/openlibm/ld128/e_log10l.c create mode 100644 src/openlibm/ld128/e_log2l.c create mode 100644 src/openlibm/ld128/e_logl.c create mode 100644 src/openlibm/ld128/e_powl.c create mode 100644 src/openlibm/ld128/e_rem_pio2l.h create mode 100644 src/openlibm/ld128/e_sinhl.c create mode 100644 src/openlibm/ld128/e_tgammal.c create mode 100644 src/openlibm/ld128/invtrig.c create mode 100644 src/openlibm/ld128/invtrig.h create mode 100644 src/openlibm/ld128/k_cosl.c create mode 100644 src/openlibm/ld128/k_sinl.c create mode 100644 src/openlibm/ld128/k_tanl.c create mode 100644 src/openlibm/ld128/s_asinhl.c create mode 100644 src/openlibm/ld128/s_ceill.c create mode 100644 src/openlibm/ld128/s_erfl.c create mode 100644 src/openlibm/ld128/s_exp2l.c create mode 100644 src/openlibm/ld128/s_expm1l.c create mode 100644 src/openlibm/ld128/s_floorl.c create mode 100644 src/openlibm/ld128/s_log1pl.c create mode 100644 src/openlibm/ld128/s_modfl.c create mode 100644 src/openlibm/ld128/s_nanl.c create mode 100644 src/openlibm/ld128/s_nextafterl.c create mode 100644 src/openlibm/ld128/s_nexttoward.c create mode 100644 src/openlibm/ld128/s_nexttowardf.c create mode 100644 src/openlibm/ld128/s_remquol.c create mode 100644 src/openlibm/ld128/s_tanhl.c create mode 100644 src/openlibm/ld128/s_truncl.c create mode 100644 src/openlibm/ld80/Make.files create mode 100644 src/openlibm/ld80/e_acoshl.c create mode 100644 src/openlibm/ld80/e_acoshl.c.o create mode 100644 src/openlibm/ld80/e_atanhl.c create mode 100644 src/openlibm/ld80/e_atanhl.c.o create mode 100644 src/openlibm/ld80/e_coshl.c create mode 100644 src/openlibm/ld80/e_coshl.c.o create mode 100644 src/openlibm/ld80/e_expl.c create mode 100644 src/openlibm/ld80/e_expl.c.o create mode 100644 src/openlibm/ld80/e_fmodl.c create mode 100644 src/openlibm/ld80/e_hypotl.c create mode 100644 src/openlibm/ld80/e_lgammal_r.c create mode 100644 src/openlibm/ld80/e_lgammal_r.c.o create mode 100644 src/openlibm/ld80/e_log10l.c create mode 100644 src/openlibm/ld80/e_log10l.c.o create mode 100644 src/openlibm/ld80/e_log2l.c create mode 100644 src/openlibm/ld80/e_log2l.c.o create mode 100644 src/openlibm/ld80/e_logl.c create mode 100644 src/openlibm/ld80/e_logl.c.o create mode 100644 src/openlibm/ld80/e_powl.c create mode 100644 src/openlibm/ld80/e_powl.c.o create mode 100644 src/openlibm/ld80/e_rem_pio2l.h create mode 100644 src/openlibm/ld80/e_sinhl.c create mode 100644 src/openlibm/ld80/e_sinhl.c.o create mode 100644 src/openlibm/ld80/e_tgammal.c create mode 100644 src/openlibm/ld80/e_tgammal.c.o create mode 100644 src/openlibm/ld80/invtrig.c create mode 100644 src/openlibm/ld80/invtrig.c.o create mode 100644 src/openlibm/ld80/invtrig.h create mode 100644 src/openlibm/ld80/k_cosl.c create mode 100644 src/openlibm/ld80/k_cosl.c.o create mode 100644 src/openlibm/ld80/k_sinl.c create mode 100644 src/openlibm/ld80/k_sinl.c.o create mode 100644 src/openlibm/ld80/k_tanl.c create mode 100644 src/openlibm/ld80/k_tanl.c.o create mode 100644 src/openlibm/ld80/s_asinhl.c create mode 100644 src/openlibm/ld80/s_asinhl.c.o create mode 100644 src/openlibm/ld80/s_ceill.c create mode 100644 src/openlibm/ld80/s_erfl.c create mode 100644 src/openlibm/ld80/s_erfl.c.o create mode 100644 src/openlibm/ld80/s_exp2l.c create mode 100644 src/openlibm/ld80/s_exp2l.c.o create mode 100644 src/openlibm/ld80/s_expm1l.c create mode 100644 src/openlibm/ld80/s_expm1l.c.o create mode 100644 src/openlibm/ld80/s_floorl.c create mode 100644 src/openlibm/ld80/s_log1pl.c create mode 100644 src/openlibm/ld80/s_log1pl.c.o create mode 100644 src/openlibm/ld80/s_modfl.c create mode 100644 src/openlibm/ld80/s_nanl.c create mode 100644 src/openlibm/ld80/s_nanl.c.o create mode 100644 src/openlibm/ld80/s_nextafterl.c create mode 100644 src/openlibm/ld80/s_nexttoward.c create mode 100644 src/openlibm/ld80/s_nexttowardf.c create mode 100644 src/openlibm/ld80/s_remquol.c create mode 100644 src/openlibm/ld80/s_tanhl.c create mode 100644 src/openlibm/ld80/s_tanhl.c.o create mode 100644 src/openlibm/ld80/s_truncl.c create mode 100644 src/openlibm/loongarch64/Make.files create mode 100644 src/openlibm/loongarch64/fenv.c create mode 100644 src/openlibm/mips/Make.files create mode 100644 src/openlibm/mips/fenv-softfloat.h create mode 100644 src/openlibm/mips/fenv.c create mode 100644 src/openlibm/openlibm.pc.in create mode 100644 src/openlibm/powerpc/Make.files create mode 100644 src/openlibm/powerpc/fenv.c create mode 100644 src/openlibm/riscv64/Make.files create mode 100644 src/openlibm/riscv64/fenv.c create mode 100644 src/openlibm/s390/Make.files create mode 100644 src/openlibm/s390/fenv.c create mode 100644 src/openlibm/src/Make.files create mode 100644 src/openlibm/src/aarch64_fpmath.h create mode 100644 src/openlibm/src/amd64_fpmath.h create mode 100644 src/openlibm/src/bsd_cdefs.h create mode 100644 src/openlibm/src/cdefs-compat.h create mode 100644 src/openlibm/src/common.c create mode 100644 src/openlibm/src/common.c.o create mode 100644 src/openlibm/src/e_acos.c create mode 100644 src/openlibm/src/e_acos.c.o create mode 100644 src/openlibm/src/e_acosf.c create mode 100644 src/openlibm/src/e_acosf.c.o create mode 100644 src/openlibm/src/e_acosh.c create mode 100644 src/openlibm/src/e_acosh.c.o create mode 100644 src/openlibm/src/e_acoshf.c create mode 100644 src/openlibm/src/e_acoshf.c.o create mode 100644 src/openlibm/src/e_acosl.c create mode 100644 src/openlibm/src/e_acosl.c.o create mode 100644 src/openlibm/src/e_asin.c create mode 100644 src/openlibm/src/e_asin.c.o create mode 100644 src/openlibm/src/e_asinf.c create mode 100644 src/openlibm/src/e_asinf.c.o create mode 100644 src/openlibm/src/e_asinl.c create mode 100644 src/openlibm/src/e_asinl.c.o create mode 100644 src/openlibm/src/e_atan2.c create mode 100644 src/openlibm/src/e_atan2.c.o create mode 100644 src/openlibm/src/e_atan2f.c create mode 100644 src/openlibm/src/e_atan2f.c.o create mode 100644 src/openlibm/src/e_atan2l.c create mode 100644 src/openlibm/src/e_atan2l.c.o create mode 100644 src/openlibm/src/e_atanh.c create mode 100644 src/openlibm/src/e_atanh.c.o create mode 100644 src/openlibm/src/e_atanhf.c create mode 100644 src/openlibm/src/e_atanhf.c.o create mode 100644 src/openlibm/src/e_cosh.c create mode 100644 src/openlibm/src/e_cosh.c.o create mode 100644 src/openlibm/src/e_coshf.c create mode 100644 src/openlibm/src/e_coshf.c.o create mode 100644 src/openlibm/src/e_exp.c create mode 100644 src/openlibm/src/e_exp.c.o create mode 100644 src/openlibm/src/e_expf.c create mode 100644 src/openlibm/src/e_expf.c.o create mode 100644 src/openlibm/src/e_fmod.c create mode 100644 src/openlibm/src/e_fmodf.c create mode 100644 src/openlibm/src/e_fmodl.c create mode 100644 src/openlibm/src/e_hypot.c create mode 100644 src/openlibm/src/e_hypot.c.o create mode 100644 src/openlibm/src/e_hypotf.c create mode 100644 src/openlibm/src/e_hypotf.c.o create mode 100644 src/openlibm/src/e_hypotl.c create mode 100644 src/openlibm/src/e_hypotl.c.o create mode 100644 src/openlibm/src/e_j0.c create mode 100644 src/openlibm/src/e_j0.c.o create mode 100644 src/openlibm/src/e_j0f.c create mode 100644 src/openlibm/src/e_j0f.c.o create mode 100644 src/openlibm/src/e_j1.c create mode 100644 src/openlibm/src/e_j1.c.o create mode 100644 src/openlibm/src/e_j1f.c create mode 100644 src/openlibm/src/e_j1f.c.o create mode 100644 src/openlibm/src/e_jn.c create mode 100644 src/openlibm/src/e_jn.c.o create mode 100644 src/openlibm/src/e_jnf.c create mode 100644 src/openlibm/src/e_jnf.c.o create mode 100644 src/openlibm/src/e_lgamma.c create mode 100644 src/openlibm/src/e_lgamma.c.o create mode 100644 src/openlibm/src/e_lgamma_r.c create mode 100644 src/openlibm/src/e_lgamma_r.c.o create mode 100644 src/openlibm/src/e_lgammaf.c create mode 100644 src/openlibm/src/e_lgammaf.c.o create mode 100644 src/openlibm/src/e_lgammaf_r.c create mode 100644 src/openlibm/src/e_lgammaf_r.c.o create mode 100644 src/openlibm/src/e_lgammal.c create mode 100644 src/openlibm/src/e_lgammal.c.o create mode 100644 src/openlibm/src/e_log.c create mode 100644 src/openlibm/src/e_log.c.o create mode 100644 src/openlibm/src/e_log10.c create mode 100644 src/openlibm/src/e_log10.c.o create mode 100644 src/openlibm/src/e_log10f.c create mode 100644 src/openlibm/src/e_log10f.c.o create mode 100644 src/openlibm/src/e_log2.c create mode 100644 src/openlibm/src/e_log2.c.o create mode 100644 src/openlibm/src/e_log2f.c create mode 100644 src/openlibm/src/e_log2f.c.o create mode 100644 src/openlibm/src/e_logf.c create mode 100644 src/openlibm/src/e_logf.c.o create mode 100644 src/openlibm/src/e_pow.c create mode 100644 src/openlibm/src/e_pow.c.o create mode 100644 src/openlibm/src/e_powf.c create mode 100644 src/openlibm/src/e_powf.c.o create mode 100644 src/openlibm/src/e_rem_pio2.c create mode 100644 src/openlibm/src/e_rem_pio2.c.o create mode 100644 src/openlibm/src/e_rem_pio2f.c create mode 100644 src/openlibm/src/e_rem_pio2f.c.o create mode 100644 src/openlibm/src/e_remainder.c create mode 100644 src/openlibm/src/e_remainderf.c create mode 100644 src/openlibm/src/e_remainderl.c create mode 100644 src/openlibm/src/e_sinh.c create mode 100644 src/openlibm/src/e_sinh.c.o create mode 100644 src/openlibm/src/e_sinhf.c create mode 100644 src/openlibm/src/e_sinhf.c.o create mode 100644 src/openlibm/src/e_sqrt.c create mode 100644 src/openlibm/src/e_sqrtf.c create mode 100644 src/openlibm/src/e_sqrtl.c create mode 100644 src/openlibm/src/fpmath.h create mode 100644 src/openlibm/src/i386_fpmath.h create mode 100644 src/openlibm/src/k_cos.c create mode 100644 src/openlibm/src/k_cos.c.o create mode 100644 src/openlibm/src/k_cosf.c create mode 100644 src/openlibm/src/k_cosf.c.o create mode 100644 src/openlibm/src/k_exp.c create mode 100644 src/openlibm/src/k_exp.c.o create mode 100644 src/openlibm/src/k_expf.c create mode 100644 src/openlibm/src/k_expf.c.o create mode 100644 src/openlibm/src/k_log.h create mode 100644 src/openlibm/src/k_logf.h create mode 100644 src/openlibm/src/k_rem_pio2.c create mode 100644 src/openlibm/src/k_rem_pio2.c.o create mode 100644 src/openlibm/src/k_sin.c create mode 100644 src/openlibm/src/k_sin.c.o create mode 100644 src/openlibm/src/k_sinf.c create mode 100644 src/openlibm/src/k_sinf.c.o create mode 100644 src/openlibm/src/k_tan.c create mode 100644 src/openlibm/src/k_tan.c.o create mode 100644 src/openlibm/src/k_tanf.c create mode 100644 src/openlibm/src/k_tanf.c.o create mode 100644 src/openlibm/src/loongarch64_fpmath.h create mode 100644 src/openlibm/src/math_private.h create mode 100644 src/openlibm/src/math_private_openbsd.h create mode 100644 src/openlibm/src/mips_fpmath.h create mode 100644 src/openlibm/src/polevll.c create mode 100644 src/openlibm/src/polevll.c.o create mode 100644 src/openlibm/src/powerpc_fpmath.h create mode 100644 src/openlibm/src/riscv_fpmath.h create mode 100644 src/openlibm/src/s390_fpmath.h create mode 100644 src/openlibm/src/s_asinh.c create mode 100644 src/openlibm/src/s_asinh.c.o create mode 100644 src/openlibm/src/s_asinhf.c create mode 100644 src/openlibm/src/s_asinhf.c.o create mode 100644 src/openlibm/src/s_atan.c create mode 100644 src/openlibm/src/s_atan.c.o create mode 100644 src/openlibm/src/s_atanf.c create mode 100644 src/openlibm/src/s_atanf.c.o create mode 100644 src/openlibm/src/s_atanl.c create mode 100644 src/openlibm/src/s_atanl.c.o create mode 100644 src/openlibm/src/s_cabs.c create mode 100644 src/openlibm/src/s_cabsf.c create mode 100644 src/openlibm/src/s_cabsl.c create mode 100644 src/openlibm/src/s_cacos.c create mode 100644 src/openlibm/src/s_cacos.c.o create mode 100644 src/openlibm/src/s_cacosf.c create mode 100644 src/openlibm/src/s_cacosf.c.o create mode 100644 src/openlibm/src/s_cacosh.c create mode 100644 src/openlibm/src/s_cacosh.c.o create mode 100644 src/openlibm/src/s_cacoshf.c create mode 100644 src/openlibm/src/s_cacoshf.c.o create mode 100644 src/openlibm/src/s_cacoshl.c create mode 100644 src/openlibm/src/s_cacoshl.c.o create mode 100644 src/openlibm/src/s_cacosl.c create mode 100644 src/openlibm/src/s_cacosl.c.o create mode 100644 src/openlibm/src/s_carg.c create mode 100644 src/openlibm/src/s_carg.c.o create mode 100644 src/openlibm/src/s_cargf.c create mode 100644 src/openlibm/src/s_cargf.c.o create mode 100644 src/openlibm/src/s_cargl.c create mode 100644 src/openlibm/src/s_cargl.c.o create mode 100644 src/openlibm/src/s_casin.c create mode 100644 src/openlibm/src/s_casin.c.o create mode 100644 src/openlibm/src/s_casinf.c create mode 100644 src/openlibm/src/s_casinf.c.o create mode 100644 src/openlibm/src/s_casinh.c create mode 100644 src/openlibm/src/s_casinh.c.o create mode 100644 src/openlibm/src/s_casinhf.c create mode 100644 src/openlibm/src/s_casinhf.c.o create mode 100644 src/openlibm/src/s_casinhl.c create mode 100644 src/openlibm/src/s_casinhl.c.o create mode 100644 src/openlibm/src/s_casinl.c create mode 100644 src/openlibm/src/s_casinl.c.o create mode 100644 src/openlibm/src/s_catan.c create mode 100644 src/openlibm/src/s_catan.c.o create mode 100644 src/openlibm/src/s_catanf.c create mode 100644 src/openlibm/src/s_catanf.c.o create mode 100644 src/openlibm/src/s_catanh.c create mode 100644 src/openlibm/src/s_catanh.c.o create mode 100644 src/openlibm/src/s_catanhf.c create mode 100644 src/openlibm/src/s_catanhf.c.o create mode 100644 src/openlibm/src/s_catanhl.c create mode 100644 src/openlibm/src/s_catanhl.c.o create mode 100644 src/openlibm/src/s_catanl.c create mode 100644 src/openlibm/src/s_catanl.c.o create mode 100644 src/openlibm/src/s_cbrt.c create mode 100644 src/openlibm/src/s_cbrt.c.o create mode 100644 src/openlibm/src/s_cbrtf.c create mode 100644 src/openlibm/src/s_cbrtf.c.o create mode 100644 src/openlibm/src/s_cbrtl.c create mode 100644 src/openlibm/src/s_cbrtl.c.o create mode 100644 src/openlibm/src/s_ccos.c create mode 100644 src/openlibm/src/s_ccosf.c create mode 100644 src/openlibm/src/s_ccosh.c create mode 100644 src/openlibm/src/s_ccosh.c.o create mode 100644 src/openlibm/src/s_ccoshf.c create mode 100644 src/openlibm/src/s_ccoshf.c.o create mode 100644 src/openlibm/src/s_ccoshl.c create mode 100644 src/openlibm/src/s_ccoshl.c.o create mode 100644 src/openlibm/src/s_ccosl.c create mode 100644 src/openlibm/src/s_ccosl.c.o create mode 100644 src/openlibm/src/s_ceil.c create mode 100644 src/openlibm/src/s_ceil.c.o create mode 100644 src/openlibm/src/s_ceilf.c create mode 100644 src/openlibm/src/s_ceilf.c.o create mode 100644 src/openlibm/src/s_ceill.c create mode 100644 src/openlibm/src/s_ceill.c.o create mode 100644 src/openlibm/src/s_cexp.c create mode 100644 src/openlibm/src/s_cexp.c.o create mode 100644 src/openlibm/src/s_cexpf.c create mode 100644 src/openlibm/src/s_cexpf.c.o create mode 100644 src/openlibm/src/s_cexpl.c create mode 100644 src/openlibm/src/s_cexpl.c.o create mode 100644 src/openlibm/src/s_cimag.c create mode 100644 src/openlibm/src/s_cimag.c.o create mode 100644 src/openlibm/src/s_cimagf.c create mode 100644 src/openlibm/src/s_cimagf.c.o create mode 100644 src/openlibm/src/s_cimagl.c create mode 100644 src/openlibm/src/s_cimagl.c.o create mode 100644 src/openlibm/src/s_clog.c create mode 100644 src/openlibm/src/s_clog.c.o create mode 100644 src/openlibm/src/s_clogf.c create mode 100644 src/openlibm/src/s_clogf.c.o create mode 100644 src/openlibm/src/s_clogl.c create mode 100644 src/openlibm/src/s_clogl.c.o create mode 100644 src/openlibm/src/s_conj.c create mode 100644 src/openlibm/src/s_conj.c.o create mode 100644 src/openlibm/src/s_conjf.c create mode 100644 src/openlibm/src/s_conjf.c.o create mode 100644 src/openlibm/src/s_conjl.c create mode 100644 src/openlibm/src/s_conjl.c.o create mode 100644 src/openlibm/src/s_copysign.c create mode 100644 src/openlibm/src/s_copysign.c.o create mode 100644 src/openlibm/src/s_copysignf.c create mode 100644 src/openlibm/src/s_copysignf.c.o create mode 100644 src/openlibm/src/s_copysignl.c create mode 100644 src/openlibm/src/s_copysignl.c.o create mode 100644 src/openlibm/src/s_cos.c create mode 100644 src/openlibm/src/s_cos.c.o create mode 100644 src/openlibm/src/s_cosf.c create mode 100644 src/openlibm/src/s_cosf.c.o create mode 100644 src/openlibm/src/s_cosl.c create mode 100644 src/openlibm/src/s_cosl.c.o create mode 100644 src/openlibm/src/s_cpow.c create mode 100644 src/openlibm/src/s_cpow.c.o create mode 100644 src/openlibm/src/s_cpowf.c create mode 100644 src/openlibm/src/s_cpowf.c.o create mode 100644 src/openlibm/src/s_cpowl.c create mode 100644 src/openlibm/src/s_cpowl.c.o create mode 100644 src/openlibm/src/s_cproj.c create mode 100644 src/openlibm/src/s_cproj.c.o create mode 100644 src/openlibm/src/s_cprojf.c create mode 100644 src/openlibm/src/s_cprojf.c.o create mode 100644 src/openlibm/src/s_cprojl.c create mode 100644 src/openlibm/src/s_cprojl.c.o create mode 100644 src/openlibm/src/s_creal.c create mode 100644 src/openlibm/src/s_creal.c.o create mode 100644 src/openlibm/src/s_crealf.c create mode 100644 src/openlibm/src/s_crealf.c.o create mode 100644 src/openlibm/src/s_creall.c create mode 100644 src/openlibm/src/s_creall.c.o create mode 100644 src/openlibm/src/s_csin.c create mode 100644 src/openlibm/src/s_csinf.c create mode 100644 src/openlibm/src/s_csinh.c create mode 100644 src/openlibm/src/s_csinh.c.o create mode 100644 src/openlibm/src/s_csinhf.c create mode 100644 src/openlibm/src/s_csinhf.c.o create mode 100644 src/openlibm/src/s_csinhl.c create mode 100644 src/openlibm/src/s_csinhl.c.o create mode 100644 src/openlibm/src/s_csinl.c create mode 100644 src/openlibm/src/s_csinl.c.o create mode 100644 src/openlibm/src/s_csqrt.c create mode 100644 src/openlibm/src/s_csqrt.c.o create mode 100644 src/openlibm/src/s_csqrtf.c create mode 100644 src/openlibm/src/s_csqrtf.c.o create mode 100644 src/openlibm/src/s_csqrtl.c create mode 100644 src/openlibm/src/s_csqrtl.c.o create mode 100644 src/openlibm/src/s_ctan.c create mode 100644 src/openlibm/src/s_ctanf.c create mode 100644 src/openlibm/src/s_ctanh.c create mode 100644 src/openlibm/src/s_ctanh.c.o create mode 100644 src/openlibm/src/s_ctanhf.c create mode 100644 src/openlibm/src/s_ctanhf.c.o create mode 100644 src/openlibm/src/s_ctanhl.c create mode 100644 src/openlibm/src/s_ctanhl.c.o create mode 100644 src/openlibm/src/s_ctanl.c create mode 100644 src/openlibm/src/s_ctanl.c.o create mode 100644 src/openlibm/src/s_erf.c create mode 100644 src/openlibm/src/s_erf.c.o create mode 100644 src/openlibm/src/s_erff.c create mode 100644 src/openlibm/src/s_erff.c.o create mode 100644 src/openlibm/src/s_exp2.c create mode 100644 src/openlibm/src/s_exp2.c.o create mode 100644 src/openlibm/src/s_exp2f.c create mode 100644 src/openlibm/src/s_exp2f.c.o create mode 100644 src/openlibm/src/s_expm1.c create mode 100644 src/openlibm/src/s_expm1.c.o create mode 100644 src/openlibm/src/s_expm1f.c create mode 100644 src/openlibm/src/s_expm1f.c.o create mode 100644 src/openlibm/src/s_fabs.c create mode 100644 src/openlibm/src/s_fabs.c.o create mode 100644 src/openlibm/src/s_fabsf.c create mode 100644 src/openlibm/src/s_fabsf.c.o create mode 100644 src/openlibm/src/s_fabsl.c create mode 100644 src/openlibm/src/s_fabsl.c.o create mode 100644 src/openlibm/src/s_fdim.c create mode 100644 src/openlibm/src/s_fdim.c.o create mode 100644 src/openlibm/src/s_floor.c create mode 100644 src/openlibm/src/s_floor.c.o create mode 100644 src/openlibm/src/s_floorf.c create mode 100644 src/openlibm/src/s_floorf.c.o create mode 100644 src/openlibm/src/s_floorl.c create mode 100644 src/openlibm/src/s_floorl.c.o create mode 100644 src/openlibm/src/s_fma.c create mode 100644 src/openlibm/src/s_fma.c.o create mode 100644 src/openlibm/src/s_fmaf.c create mode 100644 src/openlibm/src/s_fmaf.c.o create mode 100644 src/openlibm/src/s_fmal.c create mode 100644 src/openlibm/src/s_fmal.c.o create mode 100644 src/openlibm/src/s_fmax.c create mode 100644 src/openlibm/src/s_fmax.c.o create mode 100644 src/openlibm/src/s_fmaxf.c create mode 100644 src/openlibm/src/s_fmaxf.c.o create mode 100644 src/openlibm/src/s_fmaxl.c create mode 100644 src/openlibm/src/s_fmaxl.c.o create mode 100644 src/openlibm/src/s_fmin.c create mode 100644 src/openlibm/src/s_fmin.c.o create mode 100644 src/openlibm/src/s_fminf.c create mode 100644 src/openlibm/src/s_fminf.c.o create mode 100644 src/openlibm/src/s_fminl.c create mode 100644 src/openlibm/src/s_fminl.c.o create mode 100644 src/openlibm/src/s_fpclassify.c create mode 100644 src/openlibm/src/s_fpclassify.c.o create mode 100644 src/openlibm/src/s_frexp.c create mode 100644 src/openlibm/src/s_frexp.c.o create mode 100644 src/openlibm/src/s_frexpf.c create mode 100644 src/openlibm/src/s_frexpf.c.o create mode 100644 src/openlibm/src/s_frexpl.c create mode 100644 src/openlibm/src/s_frexpl.c.o create mode 100644 src/openlibm/src/s_ilogb.c create mode 100644 src/openlibm/src/s_ilogb.c.o create mode 100644 src/openlibm/src/s_ilogbf.c create mode 100644 src/openlibm/src/s_ilogbf.c.o create mode 100644 src/openlibm/src/s_ilogbl.c create mode 100644 src/openlibm/src/s_ilogbl.c.o create mode 100644 src/openlibm/src/s_isfinite.c create mode 100644 src/openlibm/src/s_isfinite.c.o create mode 100644 src/openlibm/src/s_isinf.c create mode 100644 src/openlibm/src/s_isinf.c.o create mode 100644 src/openlibm/src/s_isnan.c create mode 100644 src/openlibm/src/s_isnan.c.o create mode 100644 src/openlibm/src/s_isnormal.c create mode 100644 src/openlibm/src/s_isnormal.c.o create mode 100644 src/openlibm/src/s_llrint.c create mode 100644 src/openlibm/src/s_llrintf.c create mode 100644 src/openlibm/src/s_llrintl.c create mode 100644 src/openlibm/src/s_llround.c create mode 100644 src/openlibm/src/s_llround.c.o create mode 100644 src/openlibm/src/s_llroundf.c create mode 100644 src/openlibm/src/s_llroundf.c.o create mode 100644 src/openlibm/src/s_llroundl.c create mode 100644 src/openlibm/src/s_llroundl.c.o create mode 100644 src/openlibm/src/s_log1p.c create mode 100644 src/openlibm/src/s_log1p.c.o create mode 100644 src/openlibm/src/s_log1pf.c create mode 100644 src/openlibm/src/s_log1pf.c.o create mode 100644 src/openlibm/src/s_logb.c create mode 100644 src/openlibm/src/s_logb.c.o create mode 100644 src/openlibm/src/s_logbf.c create mode 100644 src/openlibm/src/s_logbf.c.o create mode 100644 src/openlibm/src/s_logbl.c create mode 100644 src/openlibm/src/s_lrint.c create mode 100644 src/openlibm/src/s_lrintf.c create mode 100644 src/openlibm/src/s_lrintl.c create mode 100644 src/openlibm/src/s_lround.c create mode 100644 src/openlibm/src/s_lround.c.o create mode 100644 src/openlibm/src/s_lroundf.c create mode 100644 src/openlibm/src/s_lroundf.c.o create mode 100644 src/openlibm/src/s_lroundl.c create mode 100644 src/openlibm/src/s_lroundl.c.o create mode 100644 src/openlibm/src/s_modf.c create mode 100644 src/openlibm/src/s_modf.c.o create mode 100644 src/openlibm/src/s_modff.c create mode 100644 src/openlibm/src/s_modff.c.o create mode 100644 src/openlibm/src/s_modfl.c create mode 100644 src/openlibm/src/s_modfl.c.o create mode 100644 src/openlibm/src/s_nan.c create mode 100644 src/openlibm/src/s_nan.c.o create mode 100644 src/openlibm/src/s_nearbyint.c create mode 100644 src/openlibm/src/s_nearbyint.c.o create mode 100644 src/openlibm/src/s_nextafter.c create mode 100644 src/openlibm/src/s_nextafter.c.o create mode 100644 src/openlibm/src/s_nextafterf.c create mode 100644 src/openlibm/src/s_nextafterf.c.o create mode 100644 src/openlibm/src/s_nextafterl.c create mode 100644 src/openlibm/src/s_nextafterl.c.o create mode 100644 src/openlibm/src/s_nexttoward.c create mode 100644 src/openlibm/src/s_nexttoward.c.o create mode 100644 src/openlibm/src/s_nexttowardf.c create mode 100644 src/openlibm/src/s_nexttowardf.c.o create mode 100644 src/openlibm/src/s_remquo.c create mode 100644 src/openlibm/src/s_remquof.c create mode 100644 src/openlibm/src/s_remquol.c create mode 100644 src/openlibm/src/s_rint.c create mode 100644 src/openlibm/src/s_rint.c.o create mode 100644 src/openlibm/src/s_rintf.c create mode 100644 src/openlibm/src/s_rintf.c.o create mode 100644 src/openlibm/src/s_rintl.c create mode 100644 src/openlibm/src/s_round.c create mode 100644 src/openlibm/src/s_round.c.o create mode 100644 src/openlibm/src/s_roundf.c create mode 100644 src/openlibm/src/s_roundf.c.o create mode 100644 src/openlibm/src/s_roundl.c create mode 100644 src/openlibm/src/s_roundl.c.o create mode 100644 src/openlibm/src/s_scalbln.c create mode 100644 src/openlibm/src/s_scalbln.c.o create mode 100644 src/openlibm/src/s_scalbn.c create mode 100644 src/openlibm/src/s_scalbnf.c create mode 100644 src/openlibm/src/s_scalbnl.c create mode 100644 src/openlibm/src/s_signbit.c create mode 100644 src/openlibm/src/s_signbit.c.o create mode 100644 src/openlibm/src/s_signgam.c create mode 100644 src/openlibm/src/s_signgam.c.o create mode 100644 src/openlibm/src/s_sin.c create mode 100644 src/openlibm/src/s_sin.c.o create mode 100644 src/openlibm/src/s_sincos.c create mode 100644 src/openlibm/src/s_sincos.c.o create mode 100644 src/openlibm/src/s_sincosf.c create mode 100644 src/openlibm/src/s_sincosf.c.o create mode 100644 src/openlibm/src/s_sincosl.c create mode 100644 src/openlibm/src/s_sincosl.c.o create mode 100644 src/openlibm/src/s_sinf.c create mode 100644 src/openlibm/src/s_sinf.c.o create mode 100644 src/openlibm/src/s_sinl.c create mode 100644 src/openlibm/src/s_sinl.c.o create mode 100644 src/openlibm/src/s_tan.c create mode 100644 src/openlibm/src/s_tan.c.o create mode 100644 src/openlibm/src/s_tanf.c create mode 100644 src/openlibm/src/s_tanf.c.o create mode 100644 src/openlibm/src/s_tanh.c create mode 100644 src/openlibm/src/s_tanh.c.o create mode 100644 src/openlibm/src/s_tanhf.c create mode 100644 src/openlibm/src/s_tanhf.c.o create mode 100644 src/openlibm/src/s_tanl.c create mode 100644 src/openlibm/src/s_tanl.c.o create mode 100644 src/openlibm/src/s_tgammaf.c create mode 100644 src/openlibm/src/s_tgammaf.c.o create mode 100644 src/openlibm/src/s_trunc.c create mode 100644 src/openlibm/src/s_trunc.c.o create mode 100644 src/openlibm/src/s_truncf.c create mode 100644 src/openlibm/src/s_truncf.c.o create mode 100644 src/openlibm/src/s_truncl.c create mode 100644 src/openlibm/src/s_truncl.c.o create mode 100644 src/openlibm/src/types-compat.h create mode 100644 src/openlibm/src/w_cabs.c create mode 100644 src/openlibm/src/w_cabs.c.o create mode 100644 src/openlibm/src/w_cabsf.c create mode 100644 src/openlibm/src/w_cabsf.c.o create mode 100644 src/openlibm/src/w_cabsl.c create mode 100644 src/openlibm/src/w_cabsl.c.o create mode 100644 src/openlibm/test/.gitignore create mode 100644 src/openlibm/test/Makefile create mode 100644 src/openlibm/test/inf_torture.c create mode 100644 src/openlibm/test/libm-bench.cpp create mode 100644 src/openlibm/test/libm-test-ulps.h create mode 100644 src/openlibm/test/libm-test.c create mode 100644 src/openlibm/test/test-211.c create mode 100644 src/openlibm/test/test-double.c create mode 100644 src/openlibm/test/test-float.c create mode 100644 src/openlibm/wasm32/Make.files create mode 100644 src/openlibm/wasm32/assert.h create mode 100644 src/openlibm/wasm32/float.h create mode 100644 src/openlibm/wasm32/limits.h create mode 100644 src/openlibm/wasm32/stdint.h diff --git a/src/openlibm/CMakeLists.txt b/src/openlibm/CMakeLists.txt new file mode 100755 index 0000000..81045e2 --- /dev/null +++ b/src/openlibm/CMakeLists.txt @@ -0,0 +1,576 @@ +cmake_minimum_required(VERSION 3.25) + +# Get version string from Make.inc +file(READ "${CMAKE_CURRENT_LIST_DIR}/Make.inc" MAKE_FILE) +string(REGEX MATCH "VERSION = ([0-9\.]+)" _ ${MAKE_FILE}) + +project(openlibm + VERSION ${CMAKE_MATCH_1} + LANGUAGES C ASM) + +option(BUILD_SHARED_LIBS "Build using shared libraries" ON) + +add_library("${PROJECT_NAME}") + +# Find the relevant folder depending on the architecture +set(OPENLIBM_ARCH_FOLDER ${CMAKE_SYSTEM_PROCESSOR}) +string(TOLOWER "${OPENLIBM_ARCH_FOLDER}" OPENLIBM_ARCH_FOLDER) + +if(${OPENLIBM_ARCH_FOLDER} STREQUAL "amd64" OR ${OPENLIBM_ARCH_FOLDER} STREQUAL "x86_64") + set(OPENLIBM_ARCH_FOLDER "amd64") +elseif(${OPENLIBM_ARCH_FOLDER} STREQUAL "arm64" OR ${OPENLIBM_ARCH_FOLDER} STREQUAL "aarch64") + set(OPENLIBM_ARCH_FOLDER "aarch64") +elseif(${OPENLIBM_ARCH_FOLDER} STREQUAL "armv7-a") + set(OPENLIBM_ARCH_FOLDER "arm") +elseif(${OPENLIBM_ARCH_FOLDER} STREQUAL "x86" OR ${OPENLIBM_ARCH_FOLDER} STREQUAL "i686") + set(OPENLIBM_ARCH_FOLDER "i387") +elseif(${OPENLIBM_ARCH_FOLDER} STREQUAL "powerpc") + set(OPENLIBM_ARCH_FOLDER "powerpc") +elseif(${OPENLIBM_ARCH_FOLDER} STREQUAL "riscv64") + set(OPENLIBM_ARCH_FOLDER "riscv64") +else() + message(FATAL_ERROR "${PROJECT_NAME} not set up for detected architecture: ${OPENLIBM_ARCH_FOLDER}") +endif() + + +# Compile flags +list(APPEND C_ASM_COMPILE_FLAGS "-ffp-contract=off" "-fno-fast-math" "-fno-rounding-math" "-fno-math-errno") +list(APPEND C_ASM_COMPILE_FLAGS "-fPIC" "-std=c99" "-fno-builtin") +list(APPEND C_ASM_COMPILE_FLAGS "-Wall" "-Wno-implicit-function-declaration") +list(APPEND C_ASM_COMPILE_FLAGS "-DASSEMBLER" "-D__BSD_VISIBLE" "-O3") + +# Compiler-specific compile flags +if("${CMAKE_C_COMPILER_ID}" MATCHES "Clang") + list(APPEND C_ASM_COMPILE_FLAGS "-fno-strict-aliasing" "-ffp-exception-behavior=strict") +elseif("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU") + list(APPEND C_ASM_COMPILE_FLAGS "-fno-gnu89-inline") +else() + message(FATAL_ERROR "${PROJECT_NAME} not set up to be compiled with ${CMAKE_C_COMPILER_ID}") +endif() + +# Architecture-specific compile flags - take advantage of sse on x86 +if(${OPENLIBM_ARCH_FOLDER} STREQUAL "i387") + list(APPEND C_ASM_COMPILE_FLAGS "-march=i686" "-m32" "-msse2" "-mfpmath=sse") +elseif(${OPENLIBM_ARCH_FOLDER} STREQUAL "amd64") + list(APPEND C_ASM_COMPILE_FLAGS "-m64" "-msse2" "-mfpmath=sse") +endif() + +# Suppress warnings if requested +if(OPENLIBM_SUPPRESS_WARNINGS) + list(APPEND C_ASM_COMPILE_FLAGS "-w") +endif() + +# Add compile flags +target_compile_options("${PROJECT_NAME}" PUBLIC ${C_ASM_COMPILE_FLAGS}) + +# Project Source +set(PROJECT_SRC "${CMAKE_CURRENT_SOURCE_DIR}") + +# Common +list(APPEND OPENLIBM_C_SOURCE + # src + "${PROJECT_SRC}/src/common.c" + "${PROJECT_SRC}/src/e_acos.c" + "${PROJECT_SRC}/src/e_acosf.c" + "${PROJECT_SRC}/src/e_acosh.c" + "${PROJECT_SRC}/src/e_acoshf.c" + "${PROJECT_SRC}/src/e_asin.c" + "${PROJECT_SRC}/src/e_asinf.c" + "${PROJECT_SRC}/src/e_atan2.c" + "${PROJECT_SRC}/src/e_atan2f.c" + "${PROJECT_SRC}/src/e_atanh.c" + "${PROJECT_SRC}/src/e_atanhf.c" + "${PROJECT_SRC}/src/e_cosh.c" + "${PROJECT_SRC}/src/e_coshf.c" + "${PROJECT_SRC}/src/e_exp.c" + "${PROJECT_SRC}/src/e_expf.c" + "${PROJECT_SRC}/src/e_fmod.c" + "${PROJECT_SRC}/src/e_fmodf.c" + "${PROJECT_SRC}/src/e_hypot.c" + "${PROJECT_SRC}/src/e_hypotf.c" + "${PROJECT_SRC}/src/e_j0.c" + "${PROJECT_SRC}/src/e_j0f.c" + "${PROJECT_SRC}/src/e_j1.c" + "${PROJECT_SRC}/src/e_j1f.c" + "${PROJECT_SRC}/src/e_jn.c" + "${PROJECT_SRC}/src/e_jnf.c" + "${PROJECT_SRC}/src/e_lgamma.c" + "${PROJECT_SRC}/src/e_lgamma_r.c" + "${PROJECT_SRC}/src/e_lgammaf.c" + "${PROJECT_SRC}/src/e_lgammaf_r.c" + "${PROJECT_SRC}/src/e_log.c" + "${PROJECT_SRC}/src/e_log10.c" + "${PROJECT_SRC}/src/e_log10f.c" + "${PROJECT_SRC}/src/e_log2.c" + "${PROJECT_SRC}/src/e_log2f.c" + "${PROJECT_SRC}/src/e_logf.c" + "${PROJECT_SRC}/src/e_pow.c" + "${PROJECT_SRC}/src/e_powf.c" + "${PROJECT_SRC}/src/e_remainder.c" + "${PROJECT_SRC}/src/e_remainderf.c" + "${PROJECT_SRC}/src/e_rem_pio2.c" + "${PROJECT_SRC}/src/e_rem_pio2f.c" + "${PROJECT_SRC}/src/e_sinh.c" + "${PROJECT_SRC}/src/e_sinhf.c" + "${PROJECT_SRC}/src/e_sqrt.c" + "${PROJECT_SRC}/src/e_sqrtf.c" + "${PROJECT_SRC}/src/k_cos.c" + "${PROJECT_SRC}/src/k_exp.c" + "${PROJECT_SRC}/src/k_expf.c" + "${PROJECT_SRC}/src/k_rem_pio2.c" + "${PROJECT_SRC}/src/k_sin.c" + "${PROJECT_SRC}/src/k_tan.c" + "${PROJECT_SRC}/src/k_cosf.c" + "${PROJECT_SRC}/src/k_sinf.c" + "${PROJECT_SRC}/src/k_tanf.c" + "${PROJECT_SRC}/src/s_asinh.c" + "${PROJECT_SRC}/src/s_asinhf.c" + "${PROJECT_SRC}/src/s_atan.c" + "${PROJECT_SRC}/src/s_atanf.c" + "${PROJECT_SRC}/src/s_carg.c" + "${PROJECT_SRC}/src/s_cargf.c" + "${PROJECT_SRC}/src/s_cbrt.c" + "${PROJECT_SRC}/src/s_cbrtf.c" + "${PROJECT_SRC}/src/s_ceil.c" + "${PROJECT_SRC}/src/s_ceilf.c" + "${PROJECT_SRC}/src/s_copysign.c" + "${PROJECT_SRC}/src/s_copysignf.c" + "${PROJECT_SRC}/src/s_cos.c" + "${PROJECT_SRC}/src/s_cosf.c" + "${PROJECT_SRC}/src/s_csqrt.c" + "${PROJECT_SRC}/src/s_csqrtf.c" + "${PROJECT_SRC}/src/s_erf.c" + "${PROJECT_SRC}/src/s_erff.c" + "${PROJECT_SRC}/src/s_exp2.c" + "${PROJECT_SRC}/src/s_exp2f.c" + "${PROJECT_SRC}/src/s_expm1.c" + "${PROJECT_SRC}/src/s_expm1f.c" + "${PROJECT_SRC}/src/s_fabs.c" + "${PROJECT_SRC}/src/s_fabsf.c" + "${PROJECT_SRC}/src/s_fdim.c" + "${PROJECT_SRC}/src/s_floor.c" + "${PROJECT_SRC}/src/s_floorf.c" + "${PROJECT_SRC}/src/s_fmax.c" + "${PROJECT_SRC}/src/s_fmaxf.c" + "${PROJECT_SRC}/src/s_fmin.c" + "${PROJECT_SRC}/src/s_fminf.c" + "${PROJECT_SRC}/src/s_fpclassify.c" + "${PROJECT_SRC}/src/s_frexp.c" + "${PROJECT_SRC}/src/s_frexpf.c" + "${PROJECT_SRC}/src/s_ilogb.c" + "${PROJECT_SRC}/src/s_ilogbf.c" + "${PROJECT_SRC}/src/s_isinf.c" + "${PROJECT_SRC}/src/s_isfinite.c" + "${PROJECT_SRC}/src/s_isnormal.c" + "${PROJECT_SRC}/src/s_isnan.c" + "${PROJECT_SRC}/src/s_log1p.c" + "${PROJECT_SRC}/src/s_log1pf.c" + "${PROJECT_SRC}/src/s_logb.c" + "${PROJECT_SRC}/src/s_logbf.c" + "${PROJECT_SRC}/src/s_modf.c" + "${PROJECT_SRC}/src/s_modff.c" + "${PROJECT_SRC}/src/s_nextafter.c" + "${PROJECT_SRC}/src/s_nextafterf.c" + "${PROJECT_SRC}/src/s_nexttowardf.c" + "${PROJECT_SRC}/src/s_remquo.c" + "${PROJECT_SRC}/src/s_remquof.c" + "${PROJECT_SRC}/src/s_rint.c" + "${PROJECT_SRC}/src/s_rintf.c" + "${PROJECT_SRC}/src/s_round.c" + "${PROJECT_SRC}/src/s_roundf.c" + "${PROJECT_SRC}/src/s_scalbln.c" + "${PROJECT_SRC}/src/s_scalbn.c" + "${PROJECT_SRC}/src/s_scalbnf.c" + "${PROJECT_SRC}/src/s_signbit.c" + "${PROJECT_SRC}/src/s_signgam.c" + "${PROJECT_SRC}/src/s_sin.c" + "${PROJECT_SRC}/src/s_sincos.c" + "${PROJECT_SRC}/src/s_sinf.c" + "${PROJECT_SRC}/src/s_sincosf.c" + "${PROJECT_SRC}/src/s_tan.c" + "${PROJECT_SRC}/src/s_tanf.c" + "${PROJECT_SRC}/src/s_tanh.c" + "${PROJECT_SRC}/src/s_tanhf.c" + "${PROJECT_SRC}/src/s_tgammaf.c" + "${PROJECT_SRC}/src/s_trunc.c" + "${PROJECT_SRC}/src/s_truncf.c" + "${PROJECT_SRC}/src/s_cpow.c" + "${PROJECT_SRC}/src/s_cpowf.c" + "${PROJECT_SRC}/src/w_cabs.c" + "${PROJECT_SRC}/src/w_cabsf.c" + + "${PROJECT_SRC}/src/s_fma.c" + "${PROJECT_SRC}/src/s_fmaf.c" + "${PROJECT_SRC}/src/s_lrint.c" + "${PROJECT_SRC}/src/s_lrintf.c" + "${PROJECT_SRC}/src/s_lround.c" + "${PROJECT_SRC}/src/s_lroundf.c" + "${PROJECT_SRC}/src/s_llrint.c" + "${PROJECT_SRC}/src/s_llrintf.c" + "${PROJECT_SRC}/src/s_llround.c" + "${PROJECT_SRC}/src/s_llroundf.c" + "${PROJECT_SRC}/src/s_nearbyint.c" + + # C99 complex functions + "${PROJECT_SRC}/src/s_ccosh.c" + "${PROJECT_SRC}/src/s_ccoshf.c" + "${PROJECT_SRC}/src/s_cexp.c" + "${PROJECT_SRC}/src/s_cexpf.c" + "${PROJECT_SRC}/src/s_cimag.c" + "${PROJECT_SRC}/src/s_cimagf.c" + "${PROJECT_SRC}/src/s_conj.c" + "${PROJECT_SRC}/src/s_conjf.c" + "${PROJECT_SRC}/src/s_cproj.c" + "${PROJECT_SRC}/src/s_cprojf.c" + "${PROJECT_SRC}/src/s_creal.c" + "${PROJECT_SRC}/src/s_crealf.c" + "${PROJECT_SRC}/src/s_csinh.c" + "${PROJECT_SRC}/src/s_csinhf.c" + "${PROJECT_SRC}/src/s_ctanh.c" + "${PROJECT_SRC}/src/s_ctanhf.c" + "${PROJECT_SRC}/src/s_cacos.c" + "${PROJECT_SRC}/src/s_cacosf.c" + "${PROJECT_SRC}/src/s_cacosh.c" + "${PROJECT_SRC}/src/s_cacoshf.c" + "${PROJECT_SRC}/src/s_casin.c" + "${PROJECT_SRC}/src/s_casinf.c" + "${PROJECT_SRC}/src/s_casinh.c" + "${PROJECT_SRC}/src/s_casinhf.c" + "${PROJECT_SRC}/src/s_catan.c" + "${PROJECT_SRC}/src/s_catanf.c" + "${PROJECT_SRC}/src/s_catanh.c" + "${PROJECT_SRC}/src/s_catanhf.c" + "${PROJECT_SRC}/src/s_clog.c" + "${PROJECT_SRC}/src/s_clogf.c" + + # bsdsrc + "${PROJECT_SRC}/bsdsrc/b_exp.c" + "${PROJECT_SRC}/bsdsrc/b_log.c" + "${PROJECT_SRC}/bsdsrc/b_tgamma.c" +) + +if(NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Windows") + list(APPEND OPENLIBM_C_SOURCE + "${PROJECT_SRC}/src/s_nan.c" + ) +endif() + +# Determine if long double and double are the same size +include(CheckCSourceCompiles) +check_c_source_compiles(" +#include +#if (LDBL_MANT_DIG == DBL_MANT_DIG) +#error \"long double and double are the same size\" +#endif +int main(void ) { return 0; } +" LONG_DOUBLE_NOT_DOUBLE) + +# Add in long double functions for x86, x64 and aarch64 +if(LONG_DOUBLE_NOT_DOUBLE) + list(APPEND OPENLIBM_C_SOURCE + "${PROJECT_SRC}/src/s_copysignl.c" + "${PROJECT_SRC}/src/s_fabsl.c" + "${PROJECT_SRC}/src/s_llrintl.c" + "${PROJECT_SRC}/src/s_lrintl.c" + "${PROJECT_SRC}/src/s_modfl.c" + + "${PROJECT_SRC}/src/e_acosl.c" + "${PROJECT_SRC}/src/e_asinl.c" + "${PROJECT_SRC}/src/e_atan2l.c" + "${PROJECT_SRC}/src/e_fmodl.c" + "${PROJECT_SRC}/src/s_fmaxl.c" + "${PROJECT_SRC}/src/s_fminl.c" + "${PROJECT_SRC}/src/s_ilogbl.c" + "${PROJECT_SRC}/src/e_hypotl.c" + "${PROJECT_SRC}/src/e_lgammal.c" + "${PROJECT_SRC}/src/e_remainderl.c" + "${PROJECT_SRC}/src/e_sqrtl.c" + "${PROJECT_SRC}/src/s_atanl.c" + "${PROJECT_SRC}/src/s_ceill.c" + "${PROJECT_SRC}/src/s_cosl.c" + "${PROJECT_SRC}/src/s_cprojl.c" + "${PROJECT_SRC}/src/s_csqrtl.c" + "${PROJECT_SRC}/src/s_floorl.c" + "${PROJECT_SRC}/src/s_fmal.c" + "${PROJECT_SRC}/src/s_frexpl.c" + "${PROJECT_SRC}/src/s_logbl.c" + "${PROJECT_SRC}/src/s_nexttoward.c" + "${PROJECT_SRC}/src/s_remquol.c" + "${PROJECT_SRC}/src/s_roundl.c" + "${PROJECT_SRC}/src/s_lroundl.c" + "${PROJECT_SRC}/src/s_llroundl.c" + "${PROJECT_SRC}/src/s_cpowl.c" + "${PROJECT_SRC}/src/s_cargl.c" + "${PROJECT_SRC}/src/s_sinl.c" + "${PROJECT_SRC}/src/s_sincosl.c" + "${PROJECT_SRC}/src/s_tanl.c" + "${PROJECT_SRC}/src/s_truncl.c" + "${PROJECT_SRC}/src/w_cabsl.c" + "${PROJECT_SRC}/src/s_nextafterl.c" + "${PROJECT_SRC}/src/s_rintl.c" + "${PROJECT_SRC}/src/s_scalbnl.c" + "${PROJECT_SRC}/src/polevll.c" + "${PROJECT_SRC}/src/s_casinl.c" + "${PROJECT_SRC}/src/s_ctanl.c" + "${PROJECT_SRC}/src/s_cimagl.c" + "${PROJECT_SRC}/src/s_conjl.c" + "${PROJECT_SRC}/src/s_creall.c" + "${PROJECT_SRC}/src/s_cacoshl.c" + "${PROJECT_SRC}/src/s_catanhl.c" + "${PROJECT_SRC}/src/s_casinhl.c" + "${PROJECT_SRC}/src/s_catanl.c" + "${PROJECT_SRC}/src/s_csinl.c" + "${PROJECT_SRC}/src/s_cacosl.c" + "${PROJECT_SRC}/src/s_cexpl.c" + "${PROJECT_SRC}/src/s_csinhl.c" + "${PROJECT_SRC}/src/s_ccoshl.c" + "${PROJECT_SRC}/src/s_clogl.c" + "${PROJECT_SRC}/src/s_ctanhl.c" + "${PROJECT_SRC}/src/s_ccosl.c" + "${PROJECT_SRC}/src/s_cbrtl.c" + ) +endif() + +if (LONG_DOUBLE_NOT_DOUBLE) + if (${OPENLIBM_ARCH_FOLDER} STREQUAL "i387" OR ${OPENLIBM_ARCH_FOLDER} STREQUAL "amd64") + list(APPEND OPENLIBM_C_SOURCE + # ld80 + "${PROJECT_SRC}/ld80/invtrig.c" + "${PROJECT_SRC}/ld80/e_acoshl.c" + "${PROJECT_SRC}/ld80/e_powl.c" + "${PROJECT_SRC}/ld80/k_tanl.c" + "${PROJECT_SRC}/ld80/s_exp2l.c" + "${PROJECT_SRC}/ld80/e_atanhl.c" + "${PROJECT_SRC}/ld80/e_lgammal_r.c" + "${PROJECT_SRC}/ld80/e_sinhl.c" + "${PROJECT_SRC}/ld80/s_asinhl.c" + "${PROJECT_SRC}/ld80/s_expm1l.c" + "${PROJECT_SRC}/ld80/e_coshl.c" + "${PROJECT_SRC}/ld80/e_log10l.c" + "${PROJECT_SRC}/ld80/e_tgammal.c" + "${PROJECT_SRC}/ld80/e_expl.c" + "${PROJECT_SRC}/ld80/e_log2l.c" + "${PROJECT_SRC}/ld80/k_cosl.c" + "${PROJECT_SRC}/ld80/s_log1pl.c" + "${PROJECT_SRC}/ld80/s_tanhl.c" + "${PROJECT_SRC}/ld80/e_logl.c" + "${PROJECT_SRC}/ld80/k_sinl.c" + "${PROJECT_SRC}/ld80/s_erfl.c" + ) + + if(NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Windows") + list(APPEND OPENLIBM_C_SOURCE + "${PROJECT_SRC}/ld80/s_nanl.c" + ) + endif() + else() + if(${OPENLIBM_ARCH_FOLDER} STREQUAL "aarch64") + list(APPEND OPENLIBM_C_SOURCE + # ld128 + "${PROJECT_SRC}/ld128/invtrig.c" + "${PROJECT_SRC}/ld128/e_acoshl.c" + "${PROJECT_SRC}/ld128/e_powl.c" + "${PROJECT_SRC}/ld128/k_tanl.c" + "${PROJECT_SRC}/ld128/s_exp2l.c" + "${PROJECT_SRC}/ld128/e_atanhl.c" + "${PROJECT_SRC}/ld128/e_lgammal_r.c" + "${PROJECT_SRC}/ld128/e_sinhl.c" + "${PROJECT_SRC}/ld128/s_asinhl.c" + "${PROJECT_SRC}/ld128/s_expm1l.c" + "${PROJECT_SRC}/ld128/e_coshl.c" + "${PROJECT_SRC}/ld128/e_log10l.c" + "${PROJECT_SRC}/ld128/e_tgammal.c" + "${PROJECT_SRC}/ld128/e_expl.c" + "${PROJECT_SRC}/ld128/e_log2l.c" + "${PROJECT_SRC}/ld128/k_cosl.c" + "${PROJECT_SRC}/ld128/s_log1pl.c" + "${PROJECT_SRC}/ld128/s_tanhl.c" + "${PROJECT_SRC}/ld128/e_logl.c" + "${PROJECT_SRC}/ld128/k_sinl.c" + "${PROJECT_SRC}/ld128/s_erfl.c" + ) + + if(NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Windows") + list(APPEND OPENLIBM_C_SOURCE + "${PROJECT_SRC}/ld128/s_nanl.c" + ) + endif() + endif() + endif() +endif() + +# Architecture-specific sources +if (${OPENLIBM_ARCH_FOLDER} STREQUAL "amd64") + list(APPEND OPENLIBM_C_SOURCE + "${PROJECT_SRC}/amd64/fenv.c" + ) + + list(APPEND OPENLIBM_ASM_SOURCE + "${PROJECT_SRC}/amd64/e_remainder.S" + "${PROJECT_SRC}/amd64/e_remainderf.S" + "${PROJECT_SRC}/amd64/e_remainderl.S" + "${PROJECT_SRC}/amd64/e_sqrt.S" + "${PROJECT_SRC}/amd64/e_sqrtf.S" + "${PROJECT_SRC}/amd64/e_sqrtl.S" + "${PROJECT_SRC}/amd64/s_llrint.S" + "${PROJECT_SRC}/amd64/s_llrintf.S" + "${PROJECT_SRC}/amd64/s_llrintl.S" + "${PROJECT_SRC}/amd64/s_logbl.S" + "${PROJECT_SRC}/amd64/s_lrint.S" + "${PROJECT_SRC}/amd64/s_lrintf.S" + "${PROJECT_SRC}/amd64/s_lrintl.S" + "${PROJECT_SRC}/amd64/s_remquo.S" + "${PROJECT_SRC}/amd64/s_remquof.S" + "${PROJECT_SRC}/amd64/s_remquol.S" + "${PROJECT_SRC}/amd64/s_rintl.S" + "${PROJECT_SRC}/amd64/s_scalbn.S" + "${PROJECT_SRC}/amd64/s_scalbnf.S" + "${PROJECT_SRC}/amd64/s_scalbnl.S" + "${PROJECT_SRC}/amd64/e_fmod.S" + "${PROJECT_SRC}/amd64/e_fmodf.S" + "${PROJECT_SRC}/amd64/e_fmodl.S" + ) + +elseif(${OPENLIBM_ARCH_FOLDER} STREQUAL "aarch64") + list(APPEND OPENLIBM_C_SOURCE + "${PROJECT_SRC}/aarch64/fenv.c" + ) + +elseif(${OPENLIBM_ARCH_FOLDER} STREQUAL "arm") + list(APPEND OPENLIBM_C_SOURCE + "${PROJECT_SRC}/${OPENLIBM_ARCH_FOLDER}/fenv.c" + ) + +elseif(${OPENLIBM_ARCH_FOLDER} STREQUAL "i387") + list(APPEND OPENLIBM_C_SOURCE + "${PROJECT_SRC}/i387/fenv.c" + ) + + list(APPEND OPENLIBM_ASM_SOURCE + "${PROJECT_SRC}/i387/e_exp.S" + "${PROJECT_SRC}/i387/e_fmod.S" + "${PROJECT_SRC}/i387/e_log.S" + "${PROJECT_SRC}/i387/e_log10.S" + "${PROJECT_SRC}/i387/e_remainder.S" + "${PROJECT_SRC}/i387/e_sqrt.S" + "${PROJECT_SRC}/i387/s_ceil.S" + "${PROJECT_SRC}/i387/s_copysign.S" + "${PROJECT_SRC}/i387/s_floor.S" + "${PROJECT_SRC}/i387/s_llrint.S" + "${PROJECT_SRC}/i387/s_logb.S" + "${PROJECT_SRC}/i387/s_lrint.S" + "${PROJECT_SRC}/i387/s_remquo.S" + "${PROJECT_SRC}/i387/s_rint.S" + "${PROJECT_SRC}/i387/s_tan.S" + "${PROJECT_SRC}/i387/s_trunc.S" + + # float counterparts + "${PROJECT_SRC}/i387/e_log10f.S" + "${PROJECT_SRC}/i387/e_logf.S" + "${PROJECT_SRC}/i387/e_remainderf.S" + "${PROJECT_SRC}/i387/e_sqrtf.S" + "${PROJECT_SRC}/i387/s_ceilf.S" + "${PROJECT_SRC}/i387/s_copysignf.S" + "${PROJECT_SRC}/i387/s_floorf.S" + "${PROJECT_SRC}/i387/s_llrintf.S" + "${PROJECT_SRC}/i387/s_logbf.S" + "${PROJECT_SRC}/i387/s_lrintf.S" + "${PROJECT_SRC}/i387/s_remquof.S" + "${PROJECT_SRC}/i387/s_rintf.S" + "${PROJECT_SRC}/i387/s_truncf.S" + + # long double counterparts + "${PROJECT_SRC}/i387/e_remainderl.S" + "${PROJECT_SRC}/i387/e_sqrtl.S" + "${PROJECT_SRC}/i387/s_ceill.S" + "${PROJECT_SRC}/i387/s_copysignl.S" + "${PROJECT_SRC}/i387/s_floorl.S" + "${PROJECT_SRC}/i387/s_llrintl.S" + "${PROJECT_SRC}/i387/s_logbl.S" + "${PROJECT_SRC}/i387/s_lrintl.S" + "${PROJECT_SRC}/i387/s_remquol.S" + "${PROJECT_SRC}/i387/s_rintl.S" + "${PROJECT_SRC}/i387/s_truncl.S" + ) + + if(NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Windows") + list(APPEND OPENLIBM_ASM_SOURCE + "${PROJECT_SRC}/i387/s_scalbn.S" + "${PROJECT_SRC}/i387/s_scalbnf.S" + "${PROJECT_SRC}/i387/s_scalbnl.S" + ) + endif() + +elseif(${OPENLIBM_ARCH_FOLDER} STREQUAL "powerpc") + list(APPEND OPENLIBM_C_SOURCE + "${PROJECT_SRC}/powerpc/fenv.c" + ) +elseif(${OPENLIBM_ARCH_FOLDER} STREQUAL "riscv64") + list(APPEND OPENLIBM_C_SOURCE + "${PROJECT_SRC}/riscv64/fenv.c") +else() + message(FATAL_ERROR "${PROJECT_NAME} CMake build is not set up for ${OPENLIBM_ARCH_FOLDER}") +endif() + + +# Filter out C implementation from compilation list if a native implementation exists +foreach(FILE_TO_REMOVE ${OPENLIBM_ASM_SOURCE}) + # Get filename and strip out extension + cmake_path(GET FILE_TO_REMOVE FILENAME FILENAME_TO_REMOVE) + cmake_path(REMOVE_EXTENSION FILENAME_TO_REMOVE OUTPUT_VARIABLE FILENAME_TO_REMOVE) + message(DEBUG "Filename to remove: ${FILENAME_TO_REMOVE}") + + # Go through files and remove one with the same name + foreach(CUR_FILE ${OPENLIBM_C_SOURCE}) + cmake_path(GET CUR_FILE FILENAME CUR_FILENAME) + cmake_path(REMOVE_EXTENSION CUR_FILENAME OUTPUT_VARIABLE CUR_FILENAME) + + if(${CUR_FILENAME} STREQUAL ${FILENAME_TO_REMOVE}) + list(REMOVE_ITEM OPENLIBM_C_SOURCE ${CUR_FILE}) + message(DEBUG "Removed source file from compilation list: ${CUR_FILE}") + break() + endif() + endforeach() +endforeach() + + +# Add sources +target_sources("${PROJECT_NAME}" PRIVATE ${OPENLIBM_C_SOURCE} + ${OPENLIBM_ASM_SOURCE} +) + + +# Include directories +list(APPEND OPENLIBM_INCLUDE_DIRS + "${PROJECT_SRC}" + "${PROJECT_SRC}/include" + "${PROJECT_SRC}/${OPENLIBM_ARCH_FOLDER}" + "${PROJECT_SRC}/src" +) + +if(${OPENLIBM_ARCH_FOLDER} STREQUAL "i387" OR ${OPENLIBM_ARCH_FOLDER} STREQUAL "amd64" OR ${OPENLIBM_ARCH_FOLDER} STREQUAL "powerpc") + list(APPEND OPENLIBM_INCLUDE_DIRS "${PROJECT_SRC}/ld80") +else() + if(${OPENLIBM_ARCH_FOLDER} STREQUAL "aarch64" OR ${OPENLIBM_ARCH_FOLDER} STREQUAL "riscv64") + list(APPEND OPENLIBM_INCLUDE_DIRS "${PROJECT_SRC}/ld128") + endif() +endif() + +target_include_directories("${PROJECT_NAME}" PUBLIC ${OPENLIBM_INCLUDE_DIRS}) + +file(GLOB PUBLIC_HEADERS "*.h" "include/*.h" "${OPENLIBM_ARCH_FOLDER}/*.h" "src/*.h") +set_target_properties("${PROJECT_NAME}" PROPERTIES PUBLIC_HEADER "${PUBLIC_HEADERS}") +install (TARGETS "${PROJECT_NAME}") + +# Can't use configure_file because openlibm.pc.in uses $var instead of CMake configure @var's +# Would rather string replace variables here instead of editing .pc.in, because editing .pc.in +# might build break autotools build. +file(READ "${PROJECT_SRC}/openlibm.pc.in" PC_FILE) +string(REPLACE "\${version}" ${CMAKE_PROJECT_VERSION} PC_FILE ${PC_FILE}) +string(PREPEND PC_FILE "prefix=${CMAKE_INSTALL_PREFIX} +includedir=\${prefix}/${CMAKE_INSTALL_INCLUDEDIR} +libdir=\${prefix}/${CMAKE_INSTALL_LIBDIR}\n +") +file(WRITE "${CMAKE_BINARY_DIR}/${PROJECT_NAME}.pc" ${PC_FILE}) +install(FILES "${CMAKE_BINARY_DIR}/${PROJECT_NAME}.pc" + DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") diff --git a/src/openlibm/LICENSE.md b/src/openlibm/LICENSE.md new file mode 100644 index 0000000..d76019e --- /dev/null +++ b/src/openlibm/LICENSE.md @@ -0,0 +1,115 @@ +## OpenLibm + +OpenLibm contains code that is covered by various licenses. + +The OpenLibm code derives from the FreeBSD msun and OpenBSD libm +implementations, which in turn derives from FDLIBM 5.3. As a result, it +has a number of fixes and updates that have accumulated over the years +in msun, and also optimized assembly versions of many functions. These +improvements are provided under the BSD and ISC licenses. The msun +library also includes work placed under the public domain, which is +noted in the individual files. Further work on making a standalone +OpenLibm library from msun, as part of the Julia project is covered +under the MIT license. The test files, test-double.c and test-float.c +are under the LGPL. + +## Parts copyrighted by the Julia project (MIT License) + +> Copyright (c) 2011-14 The Julia Project. +> https://github.com/JuliaMath/openlibm/graphs/contributors +> +> Permission is hereby granted, free of charge, to any person obtaining +> a copy of this software and associated documentation files (the +> "Software"), to deal in the Software without restriction, including +> without limitation the rights to use, copy, modify, merge, publish, +> distribute, sublicense, and/or sell copies of the Software, and to +> permit persons to whom the Software is furnished to do so, subject to +> the following conditions: +> +> The above copyright notice and this permission notice shall be +> included in all copies or substantial portions of the Software. +> +> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +> EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +> MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +> NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +> LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +> OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +> WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +## Parts copyrighted by Stephen L. Moshier (ISC License) + +> Copyright (c) 2008 Stephen L. Moshier +> +> Permission to use, copy, modify, and distribute this software for any +> purpose with or without fee is hereby granted, provided that the above +> copyright notice and this permission notice appear in all copies. +> +> THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +> WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +> MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +> ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +> WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +> ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +> OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +## FREEBSD MSUN (FreeBSD/2-clause BSD/Simplified BSD License) + +> Copyright 1992-2011 The FreeBSD Project. All rights reserved. +> +> Redistribution and use in source and binary forms, with or without +> modification, are permitted provided that the following conditions are +> met: +> +> 1. Redistributions of source code must retain the above copyright +> notice, this list of conditions and the following disclaimer. +> +> 2. Redistributions in binary form must reproduce the above copyright +> notice, this list of conditions and the following disclaimer in the +> documentation and/or other materials provided with the distribution. +> THIS SOFTWARE IS PROVIDED BY THE FREEBSD PROJECT ``AS IS'' AND ANY +> EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +> IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +> PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FREEBSD PROJECT OR +> CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +> EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +> PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +> PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +> LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +> NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +> SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +> +> The views and conclusions contained in the software and documentation +> are those of the authors and should not be interpreted as representing +> official policies, either expressed or implied, of the FreeBSD +> Project. + +## FDLIBM + +> Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. +> +> Developed at SunPro, a Sun Microsystems, Inc. business. +> Permission to use, copy, modify, and distribute this +> software is freely granted, provided that this notice +> is preserved. + +## Tests + +> Copyright (C) 1997, 1999 Free Software Foundation, Inc. +> This file is part of the GNU C Library. +> Contributed by Andreas Jaeger , 1997. +> +> The GNU C Library is free software; you can redistribute it and/or +> modify it under the terms of the GNU Lesser General Public +> License as published by the Free Software Foundation; either +> version 2.1 of the License, or (at your option) any later version. +> +> The GNU C Library is distributed in the hope that it will be useful, +> but WITHOUT ANY WARRANTY; without even the implied warranty of +> MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +> Lesser General Public License for more details. +> +> You should have received a copy of the GNU Lesser General Public +> License along with the GNU C Library; if not, write to the Free +> Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +> 02111-1307 USA. diff --git a/src/openlibm/Make.inc b/src/openlibm/Make.inc new file mode 100644 index 0000000..7914e82 --- /dev/null +++ b/src/openlibm/Make.inc @@ -0,0 +1,197 @@ +# -*- mode: makefile-gmake -*- +# vi:ft=make + +# Default build rule for any Makefile in this project: all +default: all + +OS := $(shell uname) +# Do not forget to bump SOMINOR when changing VERSION, +# and SOMAJOR when breaking ABI in a backward-incompatible way +VERSION = 0.8.0 +SOMAJOR = 4 +SOMINOR = 0 +DESTDIR = +prefix ?= /usr/local +bindir ?= $(prefix)/bin +libdir ?= $(prefix)/lib +includedir ?= $(prefix)/include + +ifeq ($(OS), FreeBSD) +pkgconfigdir ?= $(prefix)/libdata/pkgconfig +else +pkgconfigdir ?= $(libdir)/pkgconfig +endif + +# Build with Code Coverage +# Only test with Ubuntu + gcc + lcov, may not work for other platform. +# deps: https://github.com/linux-test-project/lcov +# You don't need to set this flag manually, `make coverage` will do it for you. +# Just Run: make clean && make coverage -j +CODE_COVERAGE ?= 0 + +ifneq (,$(findstring $(OS),Darwin FreeBSD OpenBSD)) +USEGCC ?= 0 +USECLANG ?= 1 +endif + +ifneq (,$(findstring CLANG,$(MSYSTEM))) +# In MSYS2 +USEGCC = 0 +USECLANG = 1 +endif + +ifeq ($(ARCH),wasm32) +USECLANG = 1 +USEGCC = 0 +TOOLPREFIX = llvm- +endif + +USEGCC ?= 1 +USECLANG ?= 0 +TOOLPREFIX ?= + +AR := $(TOOLPREFIX)ar + +ifeq ($(USECLANG),1) +USEGCC = 0 +CC = clang +CFLAGS_add += -fno-builtin -fno-strict-aliasing +endif + +ifeq ($(USEGCC),1) +CC := $(TOOLPREFIX)gcc +CFLAGS_add += -fno-gnu89-inline -fno-builtin +endif + +ARCH ?= $(shell $(CC) -dumpmachine | sed "s/\([^-]*\).*$$/\1/") + +ifeq ($(ARCH),mingw32) +$(error "the mingw32 compiler you are using fails the openblas testsuite. please see the Julia README.windows.md document for a replacement") +endif + +# OS-specific stuff +ifeq ($(ARCH),arm64) +override ARCH := aarch64 +endif +ifeq ($(findstring arm,$(ARCH)),arm) +override ARCH := arm +MARCH ?= armv7-a+fp +CFLAGS_add += -mhard-float +endif +ifeq ($(findstring powerpc,$(ARCH)),powerpc) +override ARCH := powerpc +endif +ifeq ($(findstring ppc,$(ARCH)),ppc) +override ARCH := powerpc +endif +ifeq ($(findstring s390,$(ARCH)),s390) +override ARCH := s390 +endif +ifneq ($(filter $(ARCH),i386 i486 i586 i686 i387 i487 i587 i687),) +override ARCH := i387 +MARCH ?= i686 +endif +ifeq ($(ARCH),x86_64) +override ARCH := amd64 +endif +ifeq ($(findstring mips,$(ARCH)),mips) +override ARCH := mips +endif +ifeq ($(findstring riscv64,$(ARCH)),riscv64) +override ARCH := riscv64 +endif +ifeq ($(findstring loongarch64,$(ARCH)),loongarch64) +override ARCH := loongarch64 +endif + +# If CFLAGS does not contain a -O optimization flag, default to -O3 +ifeq ($(findstring -O,$(CFLAGS)),) +CFLAGS_add += -O3 +endif + +ifneq (,$(findstring MINGW,$(OS))) +override OS=WINNT +endif + +#keep these if statements separate +ifeq ($(OS), WINNT) +SHLIB_EXT = dll +SONAME_FLAG = +shlibdir = $(bindir) +else +ifeq ($(OS), Darwin) +SHLIB_EXT = dylib +SONAME_FLAG = -install_name +else +SHLIB_EXT = so +SONAME_FLAG = -soname +endif +CFLAGS_add += -fPIC +shlibdir = $(libdir) +endif + +# Add `-march` to our CFLAGS if it's defined +ifneq ($(MARCH),) +CFLAGS_arch += -march=$(MARCH) +endif + +ifeq ($(ARCH),i387) +CFLAGS_arch += -m32 +SFLAGS_arch += -m32 +LDFLAGS_arch += -m32 +endif + +ifeq ($(ARCH),amd64) +CFLAGS_arch += -m64 +SFLAGS_arch += -m64 +LDFLAGS_arch += -m64 +endif + +ifeq ($(ARCH),wasm32) +CFLAGS_arch += -ffreestanding -nostdlib -nostdinc --target=wasm32-unknown-unknown +endif + +# Add our "arch"-related FLAGS in. We separate arch-related flags out so that +# we can conveniently get at them for targets that don't want the rest of +# *FLAGS_add, such as the testing Makefile targets +CFLAGS_add += $(CFLAGS_arch) +SFLAGS_add += $(SFLAGS_arch) +LDFLAGS_add += $(LDFLAGS_arch) + +CFLAGS_add += -std=c99 -Wall -I$(OPENLIBM_HOME) -I$(OPENLIBM_HOME)/include -I$(OPENLIBM_HOME)/$(ARCH) -I$(OPENLIBM_HOME)/src -DASSEMBLER -D__BSD_VISIBLE -Wno-implicit-function-declaration +ifneq ($(filter $(ARCH),i387 amd64 powerpc),) +CFLAGS_add += -I$(OPENLIBM_HOME)/ld80 +else +ifneq ($(filter $(ARCH),aarch64 riscv64),) +CFLAGS_add += -I$(OPENLIBM_HOME)/ld128 +endif +endif + +ifneq ($(filter $(ARCH),i387 amd64),) +# Determines whether `long double` is the same as `double` on this arch. +# linux x86_64, for instance, `long double` is 80 bits wide, whereas on macOS aarch64, +# `long double` is the same as `double`. +LONG_DOUBLE_NOT_DOUBLE := 1 +else ifeq ($(ARCH), aarch64) +ifeq ($(filter $(OS),Darwin WINNT),) +LONG_DOUBLE_NOT_DOUBLE := 1 +endif +endif + +ifeq ($(CODE_COVERAGE),1) +CFLAGS_add += -g -O0 --coverage +LDFLAGS_add += --coverage +endif # CODE_COVERAGE==1 + + +%.c.o: %.c + $(CC) $(CPPFLAGS) $(CFLAGS) $(CFLAGS_add) -c $< -o $@ + +%.S.o: %.S + $(CC) $(CPPFLAGS) $(SFLAGS) $(SFLAGS_add) $(filter -m% -B% -I% -D%,$(CFLAGS_add)) -c $< -o $@ + + +# Makefile debugging trick: +# call print-VARIABLE to see the runtime value of any variable +print-%: + @echo '$*=$($*)' diff --git a/src/openlibm/Makefile b/src/openlibm/Makefile new file mode 100644 index 0000000..17e03a0 --- /dev/null +++ b/src/openlibm/Makefile @@ -0,0 +1,137 @@ +OPENLIBM_HOME=$(abspath .) +include ./Make.inc + +SUBDIRS = src $(ARCH) bsdsrc +ifeq ($(LONG_DOUBLE_NOT_DOUBLE),1) +# Add ld80 directory on x86 and x64 +ifneq ($(filter $(ARCH),i387 amd64),) +SUBDIRS += ld80 +else +ifneq ($(filter $(ARCH),aarch64),) +SUBDIRS += ld128 +else +endif +endif +endif + +define INC_template +TEST=test +override CUR_SRCS = $(1)_SRCS +include $(1)/Make.files +SRCS += $$(addprefix $(1)/,$$($(1)_SRCS)) +endef + +DIR=test + +$(foreach dir,$(SUBDIRS),$(eval $(call INC_template,$(dir)))) + +DUPLICATE_NAMES = $(filter $(patsubst %.S,%,$($(ARCH)_SRCS)),$(patsubst %.c,%,$(src_SRCS))) +DUPLICATE_SRCS = $(addsuffix .c,$(DUPLICATE_NAMES)) + +OBJS = $(patsubst %.f,%.f.o,\ + $(patsubst %.S,%.S.o,\ + $(patsubst %.c,%.c.o,$(filter-out $(addprefix src/,$(DUPLICATE_SRCS)),$(SRCS))))) + +# If we're on windows, don't do versioned shared libraries. Also, generate an import library +# for the DLL. If we're on OSX, put the version number before the .dylib. Otherwise, +# put it after. +ifeq ($(OS), WINNT) +OLM_MAJOR_MINOR_SHLIB_EXT := $(SHLIB_EXT) +LDFLAGS_add += -Wl,--out-implib,libopenlibm.$(OLM_MAJOR_MINOR_SHLIB_EXT).a +else +ifeq ($(OS), Darwin) +OLM_MAJOR_MINOR_SHLIB_EXT := $(SOMAJOR).$(SOMINOR).$(SHLIB_EXT) +OLM_MAJOR_SHLIB_EXT := $(SOMAJOR).$(SHLIB_EXT) +else +OLM_MAJOR_MINOR_SHLIB_EXT := $(SHLIB_EXT).$(SOMAJOR).$(SOMINOR) +OLM_MAJOR_SHLIB_EXT := $(SHLIB_EXT).$(SOMAJOR) +endif +LDFLAGS_add += -Wl,$(SONAME_FLAG),libopenlibm.$(OLM_MAJOR_SHLIB_EXT) +endif + +.PHONY: all check test clean distclean \ + install install-static install-shared install-pkgconfig install-headers + + +OLM_LIBS := libopenlibm.a +ifneq ($(ARCH), wasm32) +OLM_LIBS += libopenlibm.$(OLM_MAJOR_MINOR_SHLIB_EXT) +endif + +all : $(OLM_LIBS) + +check test: test/test-double test/test-float + test/test-double + test/test-float + +libopenlibm.a: $(OBJS) + $(AR) -rcs libopenlibm.a $(OBJS) + +libopenlibm.$(OLM_MAJOR_MINOR_SHLIB_EXT): $(OBJS) + $(CC) -shared $(OBJS) $(LDFLAGS) $(LDFLAGS_add) -o $@ +ifneq ($(OS),WINNT) + ln -sf $@ libopenlibm.$(OLM_MAJOR_SHLIB_EXT) + ln -sf $@ libopenlibm.$(SHLIB_EXT) +endif + +test/test-double: libopenlibm.$(OLM_MAJOR_MINOR_SHLIB_EXT) + $(MAKE) -C test test-double + +test/test-float: libopenlibm.$(OLM_MAJOR_MINOR_SHLIB_EXT) + $(MAKE) -C test test-float + +COVERAGE_DIR:=cov-html +COVERAGE_FILE:=$(COVERAGE_DIR)/libopenlibm.info +# Gen cov report with: make clean && make coverage -j +coverage: clean-coverage + mkdir $(COVERAGE_DIR) + $(MAKE) test CODE_COVERAGE=1 + lcov -d amd64 -d bsdsrc -d ld80 -d src \ + --rc lcov_branch_coverage=1 --capture --output-file $(COVERAGE_FILE) + genhtml --legend --branch-coverage \ + --title "Openlibm commit `git rev-parse HEAD`" \ + --output-directory $(COVERAGE_DIR)/ \ + $(COVERAGE_FILE) + +# Zero coverage statistics and Delete report +clean-coverage: + -lcov -d amd64 -d bsdsrc -d ld80 -d src --zerocounters + rm -f ./*/*.gcda + rm -rf $(COVERAGE_DIR)/ + +clean: clean-coverage + rm -f aarch64/*.o amd64/*.o arm/*.o bsdsrc/*.o i387/*.o loongarch64/*.o ld80/*.o ld128/*.o src/*.o powerpc/*.o mips/*.o s390/*.o riscv64/*.o + rm -f libopenlibm.a libopenlibm.*$(SHLIB_EXT)* + rm -f ./*/*.gcno + $(MAKE) -C test clean + +openlibm.pc: openlibm.pc.in Make.inc Makefile + echo "version=${VERSION}" > openlibm.pc + echo "libdir=$(DESTDIR)$(libdir)" >> openlibm.pc + echo "includedir=$(DESTDIR)$(includedir)/openlibm" >> openlibm.pc + cat openlibm.pc.in >> openlibm.pc + +install-static: libopenlibm.a + mkdir -p $(DESTDIR)$(libdir) + cp -RpP -f libopenlibm.a $(DESTDIR)$(libdir)/ + +install-shared: libopenlibm.$(OLM_MAJOR_MINOR_SHLIB_EXT) + mkdir -p $(DESTDIR)$(shlibdir) +ifeq ($(OS), WINNT) + mkdir -p $(DESTDIR)$(libdir) + cp -RpP -f libopenlibm.*$(SHLIB_EXT) $(DESTDIR)$(shlibdir)/ + cp -RpP -f libopenlibm.*$(SHLIB_EXT).a $(DESTDIR)$(libdir)/ +else + cp -RpP -f libopenlibm.*$(SHLIB_EXT)* $(DESTDIR)$(shlibdir)/ +endif + +install-pkgconfig: openlibm.pc + mkdir -p $(DESTDIR)$(pkgconfigdir) + cp -RpP -f openlibm.pc $(DESTDIR)$(pkgconfigdir)/ + +install-headers: + mkdir -p $(DESTDIR)$(includedir)/openlibm + cp -RpP -f include/*.h $(DESTDIR)$(includedir)/openlibm + cp -RpP -f src/*.h $(DESTDIR)$(includedir)/openlibm + +install: install-static install-shared install-pkgconfig install-headers diff --git a/src/openlibm/README.md b/src/openlibm/README.md new file mode 100644 index 0000000..d543a3b --- /dev/null +++ b/src/openlibm/README.md @@ -0,0 +1,71 @@ +# OpenLibm + +[![codecov](https://codecov.io/gh/JuliaMath/openlibm/graph/badge.svg?token=eTAdN7d9cg)](https://codecov.io/gh/JuliaMath/openlibm) + +[OpenLibm](https://openlibm.org/) is an effort to have a high quality, portable, standalone +C mathematical library ([`libm`](http://en.wikipedia.org/wiki/libm)). +It can be used standalone in applications and programming language +implementations. + +The project was born out of a need to have a good `libm` for the +[Julia programming language](http://www.julialang.org) that worked +consistently across compilers and operating systems, and in 32-bit and +64-bit environments. + +## Platform support + +OpenLibm builds on Linux, macOS, Windows, FreeBSD, OpenBSD, NetBSD, and +DragonFly BSD. It builds with both GCC and clang. Although largely +tested and widely used on the x86 and x86-64 architectures, OpenLibm +also supports arm, aarch64, ppc64le, mips, wasm32, riscv, s390(x) and +loongarch64. + +## Build instructions + +### GNU Make + +1. Use GNU Make to build OpenLibm. This is `make` on most systems, but `gmake` on BSDs. +2. Use `make USEGCC=1` to build with GCC. This is the default on + Linux and Windows. +3. Use `make USECLANG=1` to build with clang. This is the default on OS X, FreeBSD, + and OpenBSD. +4. Use `make ARCH=wasm32` to build the wasm32 library with clang. +5. Architectures are auto-detected. Use `make ARCH=i386` to force a + build for i386. Other supported architectures are i486, i586, and + i686. GCC 4.8 is the minimum requirement for correct codegen on + older 32-bit architectures. + + +**Cross Build** +Take `riscv64` as example: +1. install `qemu-riscv64-static`, `gcc-riscv64-linux-gnu` +2. Cross build: +```sh +ARCH=riscv64 +TRIPLE=$ARCH-linux-gnu +make ARCH=$ARCH TOOLPREFIX=$TRIPLE- -j +make -C test ARCH=$ARCH TOOLPREFIX=$TRIPLE- -j +``` + +3. Run test with qemu: +```sh +qemu-$ARCH-static -L . -L /usr/$TRIPLE/ test/test-float +qemu-$ARCH-static -L . -L /usr/$TRIPLE/ test/test-double +``` + + +### CMake + +1. Create build directory with `mkdir build` and navigate into it with `cd build`. +2. Run CMake to configure project and generate native build system with `cmake /path/to/openlibm/` +or generate project with build system of choice e.g. `cmake /path/to/openlib/ -G "MinGW Makefiles"`. +3. Build with the build system with `cmake --build .`. + +Default CMake configuration builds a shared library, this can easily be configured using +[BUILD_SHARED_LIBS](https://cmake.org/cmake/help/latest/variable/BUILD_SHARED_LIBS.html) +configuration option. + + +## Acknowledgements + +PowerPC support for openlibm was graciously sponsored by IBM. diff --git a/src/openlibm/aarch64/Make.files b/src/openlibm/aarch64/Make.files new file mode 100644 index 0000000..483a7cc --- /dev/null +++ b/src/openlibm/aarch64/Make.files @@ -0,0 +1 @@ +$(CUR_SRCS) = fenv.c diff --git a/src/openlibm/aarch64/fenv.c b/src/openlibm/aarch64/fenv.c new file mode 100644 index 0000000..8a1ca57 --- /dev/null +++ b/src/openlibm/aarch64/fenv.c @@ -0,0 +1,51 @@ +/*- + * Copyright (c) 2004 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/msun/arm/fenv.c,v 1.3 2011/10/16 05:37:56 das Exp $ + */ + +#include + +#ifdef __GNUC_GNU_INLINE__ +#error "This file must be compiled with C99 'inline' semantics" +#endif + +/* + * Hopefully the system ID byte is immutable, so it's valid to use + * this as a default environment. + */ +const fenv_t __fe_dfl_env = 0; + +extern inline int feclearexcept(int __excepts); +extern inline int fegetexceptflag(fexcept_t *__flagp, int __excepts); +extern inline int fesetexceptflag(const fexcept_t *__flagp, int __excepts); +extern inline int feraiseexcept(int __excepts); +extern inline int fetestexcept(int __excepts); +extern inline int fegetround(void); +extern inline int fesetround(int __round); +extern inline int fegetenv(fenv_t *__envp); +extern inline int feholdexcept(fenv_t *__envp); +extern inline int fesetenv(const fenv_t *__envp); +extern inline int feupdateenv(const fenv_t *__envp); diff --git a/src/openlibm/amd64/Make.files b/src/openlibm/amd64/Make.files new file mode 100644 index 0000000..662071c --- /dev/null +++ b/src/openlibm/amd64/Make.files @@ -0,0 +1,7 @@ +$(CUR_SRCS) = fenv.c e_remainder.S e_remainderf.S e_remainderl.S \ + e_sqrt.S e_sqrtf.S e_sqrtl.S \ + s_llrint.S s_llrintf.S s_llrintl.S \ + s_logbl.S s_lrint.S s_lrintf.S s_lrintl.S \ + s_remquo.S s_remquof.S s_remquol.S \ + s_rintl.S s_scalbn.S s_scalbnf.S s_scalbnl.S \ + e_fmod.S e_fmodf.S e_fmodl.S diff --git a/src/openlibm/amd64/bsd_asm.h b/src/openlibm/amd64/bsd_asm.h new file mode 100644 index 0000000..b9c815b --- /dev/null +++ b/src/openlibm/amd64/bsd_asm.h @@ -0,0 +1,110 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * William Jolitz. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * from: @(#)DEFS.h 5.1 (Berkeley) 4/23/90 + * $FreeBSD: src/sys/amd64/include/asm.h,v 1.18 2007/08/22 04:26:07 jkoshy Exp $ + */ + +#ifndef _BSD_ASM_H_ +#define _BSD_ASM_H_ + +#ifdef __APPLE__ +#include "../i387/osx_asm.h" +#define CNAME(x) EXT(x) +#else +#include "bsd_cdefs.h" + +#ifdef PIC +#define PIC_PLT(x) x@PLT +#define PIC_GOT(x) x@GOTPCREL(%rip) +#else +#define PIC_PLT(x) x +#define PIC_GOT(x) x +#endif + +/* + * CNAME and HIDENAME manage the relationship between symbol names in C + * and the equivalent assembly language names. CNAME is given a name as + * it would be used in a C program. It expands to the equivalent assembly + * language name. HIDENAME is given an assembly-language name, and expands + * to a possibly-modified form that will be invisible to C programs. + */ +#define CNAME(csym) csym +#define HIDENAME(asmsym) .asmsym + +#define _START_ENTRY .p2align 4,0x90 + +#if defined(__ELF__) +#define _ENTRY(x) .text; _START_ENTRY; \ + .globl CNAME(x); .type CNAME(x),@function; CNAME(x): +#define END(x) .size x, . - x + +#elif defined(_WIN32) +#ifndef _MSC_VER +#define END(x) .end +#define _START_ENTRY_WIN .text; _START_ENTRY +#else +#define END(x) end +#define _START_ENTRY_WIN .code; _START_ENTRY +#endif +#define _ENTRY(x) _START_ENTRY_WIN; \ + .globl CNAME(x); .section .drectve; .ascii " -export:", #x; \ + .section .text; .def CNAME(x); .scl 2; .type 32; .endef; CNAME(x): +#endif + +#ifdef PROF +#define ALTENTRY(x) _ENTRY(x); \ + pushq %rbp; movq %rsp,%rbp; \ + call PIC_PLT(HIDENAME(mcount)); \ + popq %rbp; \ + jmp 9f +#define ENTRY(x) _ENTRY(x); \ + pushq %rbp; movq %rsp,%rbp; \ + call PIC_PLT(HIDENAME(mcount)); \ + popq %rbp; \ + 9: +#else +#define ALTENTRY(x) _ENTRY(x) +#define ENTRY(x) _ENTRY(x) +#endif + + +#define RCSID(x) .text; .asciz x + +#undef __FBSDID +#if !defined(lint) && !defined(STRIP_FBSDID) +#define __FBSDID(s) .ident s +#else +#define __FBSDID(s) /* nothing */ +#endif /* not lint and not STRIP_FBSDID */ + +#endif +#endif /* !_BSD_ASM_H_ */ diff --git a/src/openlibm/amd64/bsd_fpu.h b/src/openlibm/amd64/bsd_fpu.h new file mode 100644 index 0000000..513b345 --- /dev/null +++ b/src/openlibm/amd64/bsd_fpu.h @@ -0,0 +1,218 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * William Jolitz. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * from: @(#)npx.h 5.3 (Berkeley) 1/18/91 + * $FreeBSD: src/sys/x86/include/fpu.h,v 1.1 2012/03/16 20:24:30 tijl Exp $ + */ + +/* + * Floating Point Data Structures and Constants + * W. Jolitz 1/90 + */ + +#ifndef _BSD_FPU_H_ +#define _BSD_FPU_H_ + +#include "types-compat.h" + +/* Environment information of floating point unit. */ +struct env87 { + int32_t en_cw; /* control word (16bits) */ + int32_t en_sw; /* status word (16bits) */ + int32_t en_tw; /* tag word (16bits) */ + int32_t en_fip; /* fp instruction pointer */ + uint16_t en_fcs; /* fp code segment selector */ + uint16_t en_opcode; /* opcode last executed (11 bits) */ + int32_t en_foo; /* fp operand offset */ + int32_t en_fos; /* fp operand segment selector */ +}; + +/* Contents of each x87 floating point accumulator. */ +struct fpacc87 { + uint8_t fp_bytes[10]; +}; + +/* Floating point context. (i386 fnsave/frstor) */ +struct save87 { + struct env87 sv_env; /* floating point control/status */ + struct fpacc87 sv_ac[8]; /* accumulator contents, 0-7 */ + uint8_t sv_pad0[4]; /* saved status word (now unused) */ + /* + * Bogus padding for emulators. Emulators should use their own + * struct and arrange to store into this struct (ending here) + * before it is inspected for ptracing or for core dumps. Some + * emulators overwrite the whole struct. We have no good way of + * knowing how much padding to leave. Leave just enough for the + * GPL emulator's i387_union (176 bytes total). + */ + uint8_t sv_pad[64]; /* padding; used by emulators */ +}; + +/* Contents of each SSE extended accumulator. */ +struct xmmacc { + uint8_t xmm_bytes[16]; +}; + +/* Contents of the upper 16 bytes of each AVX extended accumulator. */ +struct ymmacc { + uint8_t ymm_bytes[16]; +}; + +/* Rename structs below depending on machine architecture. */ +#ifdef __i386__ +#define __envxmm32 envxmm +#else +#define __envxmm32 envxmm32 +#define __envxmm64 envxmm +#endif + +struct __envxmm32 { + uint16_t en_cw; /* control word (16bits) */ + uint16_t en_sw; /* status word (16bits) */ + uint16_t en_tw; /* tag word (16bits) */ + uint16_t en_opcode; /* opcode last executed (11 bits) */ + uint32_t en_fip; /* fp instruction pointer */ + uint16_t en_fcs; /* fp code segment selector */ + uint16_t en_pad0; /* padding */ + uint32_t en_foo; /* fp operand offset */ + uint16_t en_fos; /* fp operand segment selector */ + uint16_t en_pad1; /* padding */ + uint32_t en_mxcsr; /* SSE control/status register */ + uint32_t en_mxcsr_mask; /* valid bits in mxcsr */ +}; + +struct __envxmm64 { + uint16_t en_cw; /* control word (16bits) */ + uint16_t en_sw; /* status word (16bits) */ + uint8_t en_tw; /* tag word (8bits) */ + uint8_t en_zero; + uint16_t en_opcode; /* opcode last executed (11 bits ) */ + uint64_t en_rip; /* fp instruction pointer */ + uint64_t en_rdp; /* fp operand pointer */ + uint32_t en_mxcsr; /* SSE control/status register */ + uint32_t en_mxcsr_mask; /* valid bits in mxcsr */ +}; + +/* Floating point context. (i386 fxsave/fxrstor) */ +struct savexmm { + struct __envxmm32 sv_env; + struct { + struct fpacc87 fp_acc; + uint8_t fp_pad[6]; /* padding */ + } sv_fp[8]; + struct xmmacc sv_xmm[8]; + uint8_t sv_pad[224]; +} __attribute__ ((aligned(16))); + +#ifdef __i386__ +union savefpu { + struct save87 sv_87; + struct savexmm sv_xmm; +}; +#else +/* Floating point context. (amd64 fxsave/fxrstor) */ +struct savefpu { + struct __envxmm64 sv_env; + struct { + struct fpacc87 fp_acc; + uint8_t fp_pad[6]; /* padding */ + } sv_fp[8]; + struct xmmacc sv_xmm[16]; + uint8_t sv_pad[96]; +} __attribute__ ((aligned(16))); +#endif + +struct xstate_hdr { + uint64_t xstate_bv; + uint8_t xstate_rsrv0[16]; + uint8_t xstate_rsrv[40]; +}; + +struct savexmm_xstate { + struct xstate_hdr sx_hd; + struct ymmacc sx_ymm[16]; +}; + +struct savexmm_ymm { + struct __envxmm32 sv_env; + struct { + struct fpacc87 fp_acc; + int8_t fp_pad[6]; /* padding */ + } sv_fp[8]; + struct xmmacc sv_xmm[16]; + uint8_t sv_pad[96]; + struct savexmm_xstate sv_xstate; +} __attribute__ ((aligned(16))); + +struct savefpu_xstate { + struct xstate_hdr sx_hd; + struct ymmacc sx_ymm[16]; +}; + +struct savefpu_ymm { + struct __envxmm64 sv_env; + struct { + struct fpacc87 fp_acc; + int8_t fp_pad[6]; /* padding */ + } sv_fp[8]; + struct xmmacc sv_xmm[16]; + uint8_t sv_pad[96]; + struct savefpu_xstate sv_xstate; +} __attribute__ ((aligned(64))); + +#undef __envxmm32 +#undef __envxmm64 + +/* + * The hardware default control word for i387's and later coprocessors is + * 0x37F, giving: + * + * round to nearest + * 64-bit precision + * all exceptions masked. + * + * FreeBSD/i386 uses 53 bit precision for things like fadd/fsub/fsqrt etc + * because of the difference between memory and fpu register stack arguments. + * If its using an intermediate fpu register, it has 80/64 bits to work + * with. If it uses memory, it has 64/53 bits to work with. However, + * gcc is aware of this and goes to a fair bit of trouble to make the + * best use of it. + * + * This is mostly academic for AMD64, because the ABI prefers the use + * SSE2 based math. For FreeBSD/amd64, we go with the default settings. + */ +#define __INITIAL_FPUCW__ 0x037F +#define __INITIAL_FPUCW_I386__ 0x127F +#define __INITIAL_NPXCW__ __INITIAL_FPUCW_I386__ +#define __INITIAL_MXCSR__ 0x1F80 +#define __INITIAL_MXCSR_MASK__ 0xFFBF + +#endif /* !_BSD_FPU_H_ */ diff --git a/src/openlibm/amd64/bsd_ieeefp.h b/src/openlibm/amd64/bsd_ieeefp.h new file mode 100644 index 0000000..6103d50 --- /dev/null +++ b/src/openlibm/amd64/bsd_ieeefp.h @@ -0,0 +1,272 @@ +/*- + * Copyright (c) 2003 Peter Wemm. + * Copyright (c) 1990 Andrew Moore, Talke Studio + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * from: @(#) ieeefp.h 1.0 (Berkeley) 9/23/93 + * $FreeBSD: src/sys/amd64/include/ieeefp.h,v 1.14 2005/04/12 23:12:00 jhb Exp $ + */ + +/* + * IEEE floating point type and constant definitions. + */ + +#ifndef _BSD_IEEEFP_H_ +#define _BSD_IEEEFP_H_ + +/* + * FP rounding modes + */ +typedef enum { + FP_RN=0, /* round to nearest */ + FP_RM, /* round down to minus infinity */ + FP_RP, /* round up to plus infinity */ + FP_RZ /* truncate */ +} fp_rnd_t; + +/* + * FP precision modes + */ +typedef enum { + FP_PS=0, /* 24 bit (single-precision) */ + FP_PRS, /* reserved */ + FP_PD, /* 53 bit (double-precision) */ + FP_PE /* 64 bit (extended-precision) */ +} fp_prec_t; + +#define fp_except_t int + +/* + * FP exception masks + */ +#define FP_X_INV 0x01 /* invalid operation */ +#define FP_X_DNML 0x02 /* denormal */ +#define FP_X_DZ 0x04 /* zero divide */ +#define FP_X_OFL 0x08 /* overflow */ +#define FP_X_UFL 0x10 /* underflow */ +#define FP_X_IMP 0x20 /* (im)precision */ +#define FP_X_STK 0x40 /* stack fault */ + +/* + * FP registers + */ +#define FP_MSKS_REG 0 /* exception masks */ +#define FP_PRC_REG 0 /* precision */ +#define FP_RND_REG 0 /* direction */ +#define FP_STKY_REG 1 /* sticky flags */ + +/* + * FP register bit field masks + */ +#define FP_MSKS_FLD 0x3f /* exception masks field */ +#define FP_PRC_FLD 0x300 /* precision control field */ +#define FP_RND_FLD 0xc00 /* round control field */ +#define FP_STKY_FLD 0x3f /* sticky flags field */ + +/* + * SSE mxcsr register bit field masks + */ +#define SSE_STKY_FLD 0x3f /* exception flags */ +#define SSE_DAZ_FLD 0x40 /* Denormals are zero */ +#define SSE_MSKS_FLD 0x1f80 /* exception masks field */ +#define SSE_RND_FLD 0x6000 /* rounding control */ +#define SSE_FZ_FLD 0x8000 /* flush to zero on underflow */ + +/* + * FP register bit field offsets + */ +#define FP_MSKS_OFF 0 /* exception masks offset */ +#define FP_PRC_OFF 8 /* precision control offset */ +#define FP_RND_OFF 10 /* round control offset */ +#define FP_STKY_OFF 0 /* sticky flags offset */ + +/* + * SSE mxcsr register bit field offsets + */ +#define SSE_STKY_OFF 0 /* exception flags offset */ +#define SSE_DAZ_OFF 6 /* DAZ exception mask offset */ +#define SSE_MSKS_OFF 7 /* other exception masks offset */ +#define SSE_RND_OFF 13 /* rounding control offset */ +#define SSE_FZ_OFF 15 /* flush to zero offset */ + +#if (defined(__GNUCLIKE_ASM) && defined(__CC_SUPPORTS___INLINE__)) || defined(_WIN32) \ + && !defined(__cplusplus) + +#define __fldenv(addr) __asm __volatile("fldenv %0" : : "m" (*(addr))) +#define __fnstenv(addr) __asm __volatile("fnstenv %0" : "=m" (*(addr))) +#define __fldcw(addr) __asm __volatile("fldcw %0" : : "m" (*(addr))) +#define __fnstcw(addr) __asm __volatile("fnstcw %0" : "=m" (*(addr))) +#define __fnstsw(addr) __asm __volatile("fnstsw %0" : "=m" (*(addr))) +#define __ldmxcsr(addr) __asm __volatile("ldmxcsr %0" : : "m" (*(addr))) +#define __stmxcsr(addr) __asm __volatile("stmxcsr %0" : "=m" (*(addr))) + +/* + * General notes about conflicting SSE vs FP status bits. + * This code assumes that software will not fiddle with the control + * bits of the SSE and x87 in such a way to get them out of sync and + * still expect this to work. Break this at your peril. + * Because I based this on the i386 port, the x87 state is used for + * the fpget*() functions, and is shadowed into the SSE state for + * the fpset*() functions. For dual source fpget*() functions, I + * merge the two together. I think. + */ + +/* Set rounding control */ +static __inline__ fp_rnd_t +__fpgetround(void) +{ + unsigned short _cw; + + __fnstcw(&_cw); + return ((_cw & FP_RND_FLD) >> FP_RND_OFF); +} + +static __inline__ fp_rnd_t +__fpsetround(fp_rnd_t _m) +{ + unsigned short _cw; + unsigned int _mxcsr; + fp_rnd_t _p; + + __fnstcw(&_cw); + _p = (_cw & FP_RND_FLD) >> FP_RND_OFF; + _cw &= ~FP_RND_FLD; + _cw |= (_m << FP_RND_OFF) & FP_RND_FLD; + __fldcw(&_cw); + __stmxcsr(&_mxcsr); + _mxcsr &= ~SSE_RND_FLD; + _mxcsr |= (_m << SSE_RND_OFF) & SSE_RND_FLD; + __ldmxcsr(&_mxcsr); + return (_p); +} + +/* + * Set precision for fadd/fsub/fsqrt etc x87 instructions + * There is no equivalent SSE mode or control. + */ +static __inline__ fp_prec_t +__fpgetprec(void) +{ + unsigned short _cw; + + __fnstcw(&_cw); + return ((_cw & FP_PRC_FLD) >> FP_PRC_OFF); +} + +static __inline__ fp_prec_t +__fpsetprec(fp_rnd_t _m) +{ + unsigned short _cw; + fp_prec_t _p; + + __fnstcw(&_cw); + _p = (_cw & FP_PRC_FLD) >> FP_PRC_OFF; + _cw &= ~FP_PRC_FLD; + _cw |= (_m << FP_PRC_OFF) & FP_PRC_FLD; + __fldcw(&_cw); + return (_p); +} + +/* + * Look at the exception masks + * Note that x87 masks are inverse of the fp*() functions + * API. ie: mask = 1 means disable for x87 and SSE, but + * for the fp*() api, mask = 1 means enabled. + */ +static __inline__ fp_except_t +__fpgetmask(void) +{ + unsigned short _cw; + + __fnstcw(&_cw); + return ((~_cw) & FP_MSKS_FLD); +} + +static __inline__ fp_except_t +__fpsetmask(fp_except_t _m) +{ + unsigned short _cw; + unsigned int _mxcsr; + fp_except_t _p; + + __fnstcw(&_cw); + _p = (~_cw) & FP_MSKS_FLD; + _cw &= ~FP_MSKS_FLD; + _cw |= (~_m) & FP_MSKS_FLD; + __fldcw(&_cw); + __stmxcsr(&_mxcsr); + /* XXX should we clear non-ieee SSE_DAZ_FLD and SSE_FZ_FLD ? */ + _mxcsr &= ~SSE_MSKS_FLD; + _mxcsr |= ((~_m) << SSE_MSKS_OFF) & SSE_MSKS_FLD; + __ldmxcsr(&_mxcsr); + return (_p); +} + +/* See which sticky exceptions are pending, and reset them */ +static __inline__ fp_except_t +__fpgetsticky(void) +{ + unsigned short _sw; + unsigned int _mxcsr; + fp_except_t _ex; + + __fnstsw(&_sw); + _ex = _sw & FP_STKY_FLD; + __stmxcsr(&_mxcsr); + _ex |= _mxcsr & SSE_STKY_FLD; + return (_ex); +} + +#endif /* __GNUCLIKE_ASM && __CC_SUPPORTS___INLINE__ && !__cplusplus */ + +#if !defined(__IEEEFP_NOINLINES__) && !defined(__cplusplus) \ + && defined(__GNUCLIKE_ASM) && defined(__CC_SUPPORTS___INLINE__) + +#define fpgetround() __fpgetround() +#define fpsetround(_m) __fpsetround(_m) +#define fpgetprec() __fpgetprec() +#define fpsetprec(_m) __fpsetprec(_m) +#define fpgetmask() __fpgetmask() +#define fpsetmask(_m) __fpsetmask(_m) +#define fpgetsticky() __fpgetsticky() + +/* Suppress prototypes in the MI header. */ +#define _IEEEFP_INLINED_ 1 + +#else /* !__IEEEFP_NOINLINES__ && !__cplusplus && __GNUCLIKE_ASM + && __CC_SUPPORTS___INLINE__ */ + +/* Augment the userland declarations */ +__BEGIN_DECLS +extern fp_prec_t fpgetprec(void); +extern fp_prec_t fpsetprec(fp_prec_t); +__END_DECLS + +#endif /* !__IEEEFP_NOINLINES__ && !__cplusplus && __GNUCLIKE_ASM + && __CC_SUPPORTS___INLINE__ */ + +#endif /* !_BSD_IEEEFP_H_ */ diff --git a/src/openlibm/amd64/e_fmod.S b/src/openlibm/amd64/e_fmod.S new file mode 100644 index 0000000..d2c8ecd --- /dev/null +++ b/src/openlibm/amd64/e_fmod.S @@ -0,0 +1,56 @@ +/* + * Copyright (c) 1993,94 Winning Strategies, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Winning Strategies, Inc. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Based on the i387 version written by: + * J.T. Conklin (jtc@wimsey.com), Winning Strategies, Inc. + */ + +#include + +ENTRY(fmod) + movsd %xmm0,-8(%rsp) + movsd %xmm1,-16(%rsp) + fldl -16(%rsp) + fldl -8(%rsp) +1: fprem + fstsw %ax + testw $0x400,%ax + jne 1b + fstpl -8(%rsp) + movsd -8(%rsp),%xmm0 + fstp %st + ret +END(fmod) + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/amd64/e_fmod.S.o b/src/openlibm/amd64/e_fmod.S.o new file mode 100644 index 0000000000000000000000000000000000000000..0a7b0688e7c19385a803bc9acf0e684115f9dede GIT binary patch literal 872 zcmb<-^>JfjWMqH=Mg}_u1P><4z@UL7=l~XWVBlonVEDu@=%VuD6ThI3%7?oyVEp6e zkJqEDQ_`3JeSktPBhc?tY;RObm<%Kw>cC8KHbm zkYYR-q+STgr8+RRX}S3+3=De3mANH}Nep_$B}EWA1I8*zttes8OGzwAWY9}0E@sfn z%P&dQbN36?EiOq+&W7^S^Gfv!it-Cmi%KeCMpHsdGcbT%%Z6qMBrF*i;O>XY3qWZY zr3lr}3=@FTIZzs%0)-E+b}RNurn|)Fo857;Q}bz z07}CskXvDF5Dl^$T`x#{0f=B=V1Vfd*#S}u(=P#)2c;);zk{SMfCvT#2K0CVnE{mo XQ-WB+4kU36L@+Qg_(N$Jg{~g}qclGw literal 0 HcmV?d00001 diff --git a/src/openlibm/amd64/e_fmodf.S b/src/openlibm/amd64/e_fmodf.S new file mode 100644 index 0000000..b045e73 --- /dev/null +++ b/src/openlibm/amd64/e_fmodf.S @@ -0,0 +1,26 @@ +/* + * Based on the i387 version written by J.T. Conklin . + * Public domain. + */ + +#include + +ENTRY(fmodf) + movss %xmm0,-4(%rsp) + movss %xmm1,-8(%rsp) + flds -8(%rsp) + flds -4(%rsp) +1: fprem + fstsw %ax + testw $0x400,%ax + jne 1b + fstps -4(%rsp) + movss -4(%rsp),%xmm0 + fstp %st + ret +END(fmodf) + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/amd64/e_fmodf.S.o b/src/openlibm/amd64/e_fmodf.S.o new file mode 100644 index 0000000000000000000000000000000000000000..e9438eba68d30d6aab0af1cc59c1d9e7a8613092 GIT binary patch literal 872 zcmb<-^>JfjWMqH=Mg}_u1P><4z@UL7=l~XWVBlonVED{0=%VuHGrypZ%8#2aVEpIi zkJqEDQ_`3JeSktPBhc?tY;RObm<%Kw>cC8KHbm zkYYR-q+STgr8+RRX}S3+X$%Z{#g(}wiAfB4#U(`$Is?WkNv$Yh&`U`yNo3GVDlTTw z%gZlG)pPd?)h#YbOwNY#)ALI83X1XzQj1C|VP;c6OEWNlUCV}M1|%#Q7~t-Q$_qeg z7^Mi+&kPfQ(m7BXodSgqvY0vp0|N&G0|UAGLGD906J$QI_S-NpFt9T)Fff5MA>jfj z+W<<#D3DuWY!D5y8(l9*d;y4HU|@jh2iXBq3)3$Fl?SCKbiae7E`SKA+n`J^1u_H7 YfD(dO!VV;L9YioNF!)1h7=^AM0M^Vuq5uE@ literal 0 HcmV?d00001 diff --git a/src/openlibm/amd64/e_fmodl.S b/src/openlibm/amd64/e_fmodl.S new file mode 100644 index 0000000..cab539d --- /dev/null +++ b/src/openlibm/amd64/e_fmodl.S @@ -0,0 +1,52 @@ +/* + * Copyright (c) 1993,94 Winning Strategies, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Winning Strategies, Inc. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Based on the i387 version written by: + * J.T. Conklin (jtc@wimsey.com), Winning Strategies, Inc. + */ + +#include + +ENTRY(fmodl) + fldt 24(%rsp) + fldt 8(%rsp) +1: fprem + fstsw %ax + testw $0x400,%ax + jne 1b + fstp %st(1) + ret +END(fmodl) + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/amd64/e_fmodl.S.o b/src/openlibm/amd64/e_fmodl.S.o new file mode 100644 index 0000000000000000000000000000000000000000..2dbbcc6d08ad2209e7f0b99908d922cd5b7288d1 GIT binary patch literal 848 zcmb<-^>JfjWMqH=Mg}_u1P><4z#xDm=l~XWVBlonV7Q&5B5^xMh2!Rr+4mo$tz=*+ z{d)K2VFm^k1_lNN1_lOJ1_lOqzfcAy2F3#*F|bw!1_nkbAIVsl6bcQJ7eaE87)&-T zH$NqZfkCghGPfi#i9xTpqzFQ1z*r@z6(tOMDTyVC40=h$#SD6R`6a1(?tY=V#U+W! z*-(CZUa4L|QGP*cQAs7tYzk;;u-_OM*wD;?gc$<^-2G5_0VoZl6ruW=VFFM(3`(O@ zpzuK!Q)ggc;9y{2AXmQ*)P7_$L2P2}w_#vlU}s=pU;=4E!Vyrm0hESOAh*KUAR6Q! zbiE+)4iLe>zyQ+^vIC?Rre6Xo&xytFAgLW70_rv>6HI~305hP3AP)Weq4NGv8b+b( F2LMF=GkpL6 literal 0 HcmV?d00001 diff --git a/src/openlibm/amd64/e_remainder.S b/src/openlibm/amd64/e_remainder.S new file mode 100644 index 0000000..a0b4900 --- /dev/null +++ b/src/openlibm/amd64/e_remainder.S @@ -0,0 +1,30 @@ +/* + * Based on the i387 version written by: + * J.T. Conklin (jtc@netbsd.org) + * Public domain. + */ + +#include + +//RCSID("from: FreeBSD: src/lib/msun/i387/e_remainder.S,v 1.8 2005/02/04 14:08:32 das Exp") +//__FBSDID("$FreeBSD: src/lib/msun/amd64/e_remainder.S,v 1.2 2011/01/07 16:13:12 kib Exp $") + +ENTRY(remainder) + movsd %xmm0,-8(%rsp) + movsd %xmm1,-16(%rsp) + fldl -16(%rsp) + fldl -8(%rsp) +1: fprem1 + fstsw %ax + testw $0x400,%ax + jne 1b + fstpl -8(%rsp) + movsd -8(%rsp),%xmm0 + fstp %st + ret + + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/amd64/e_remainder.S.o b/src/openlibm/amd64/e_remainder.S.o new file mode 100644 index 0000000000000000000000000000000000000000..1a76bd11288716b470f5a12f4e0064547765bbe9 GIT binary patch literal 880 zcmb<-^>JfjWMqH=Mg}_u1P><4z+iwR=l~XWVBlonVEDu@=%VuD6ThI3%7?oyVEp6e z*V*?Uq^)FNDgAmk1|%uqqVnVJjl&>qEDQ_`3JeSktPBhc?tY;RObm<%Kw>cC8KHb` zkYYR-q+SS{ON&x-6EpKtQi~WE^olEUOA?b9^omQ0Aan+dRgzj!!l0LuSdz$~msDKL zpqH0llB(zK7phxal9-$g<)`PB>J=2_7o--IRN`?9DN@o53}9EYp=pAIDFcHJnz#TO zUlFRG8BII~jSu63!U@I((drBg3>*v$4CLwuxewh;kh#R#Z^OXAz|O$Hzy#8SgbSc- z11JrnKyHPxK{Uv2biE+)1t5ZffdQr;WCutsOuqzFo)e4TK~fh$1Oo#Ddb$Id0hIz% Tf;jZw2Fo%q_(N$Jg{~g}=IB8g literal 0 HcmV?d00001 diff --git a/src/openlibm/amd64/e_remainderf.S b/src/openlibm/amd64/e_remainderf.S new file mode 100644 index 0000000..c63e97e --- /dev/null +++ b/src/openlibm/amd64/e_remainderf.S @@ -0,0 +1,29 @@ +/* + * Based on the i387 version written by J.T. Conklin . + * Public domain. + */ + +#include + +//RCSID("from: $NetBSD: e_remainderf.S,v 1.2 1995/05/08 23:49:47 jtc Exp $") +//__FBSDID("$FreeBSD: src/lib/msun/amd64/e_remainderf.S,v 1.2 2011/01/07 16:13:12 kib Exp $") + +ENTRY(remainderf) + movss %xmm0,-4(%rsp) + movss %xmm1,-8(%rsp) + flds -8(%rsp) + flds -4(%rsp) +1: fprem1 + fstsw %ax + testw $0x400,%ax + jne 1b + fstps -4(%rsp) + movss -4(%rsp),%xmm0 + fstp %st + ret + + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/amd64/e_remainderf.S.o b/src/openlibm/amd64/e_remainderf.S.o new file mode 100644 index 0000000000000000000000000000000000000000..111b1cdf53c1d85eb503ed93326056323ff493bc GIT binary patch literal 880 zcmb<-^>JfjWMqH=Mg}_u1P><4z+iwR=l~XWVBlonVED{0=%VuHGrypZ%8#2aVEpIi z*V*?Uq^)FNDgAmg1|%uqqVnhNjl&>qEDQ_`3JeSktPBhc?tY;RObm<%Kw>cC8KHb` zkYYR-q+SS{ON&x-6EpKtQj5|U81#xOb4wDF81#xuiXe0bj8&3aQNo~?l30?+pqEr! z%%GQ-Uy`cl?iZ?CT#}fa4dtijmFg7~ + +//__FBSDID("$FreeBSD: src/lib/msun/amd64/e_remainderl.S,v 1.2 2011/01/07 16:13:12 kib Exp $") + +ENTRY(remainderl) +#ifndef _WIN64 + fldt 24(%rsp) + fldt 8(%rsp) +#else + fldt (%r8) + fldt (%rdx) +#endif +1: fprem1 + fstsw %ax + testw $0x400,%ax + jne 1b + fstp %st(1) +#ifdef _WIN64 + mov %rcx,%rax + movq $0x0,0x8(%rcx) + fstpt (%rcx) +#endif + ret + + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/amd64/e_remainderl.S.o b/src/openlibm/amd64/e_remainderl.S.o new file mode 100644 index 0000000000000000000000000000000000000000..237c515b7c1a7cc7a9f9482a7e78a56764dec5cd GIT binary patch literal 856 zcmb<-^>JfjWMqH=Mg}_u1P><4z#xGn=l~XWVBlonV7Q&5B5^xMh2!Se+4mo$tz=*+ z{d)K2VFm^k1_lNN1_lOJ1_lOqzfcAy2F3#*F_nV7{IP(L(>EaI|c?ZG;skmz9LjVdiaE)se^Gr;RIuY zXmth#1`Y-W26FZ5KgGsfFp6fXZ`X@jFOr2Z&%`VBmq$FbZS_j18g%ap*q+l4M|D@Q2bc H3SB<{Ytl7} literal 0 HcmV?d00001 diff --git a/src/openlibm/amd64/e_sqrt.S b/src/openlibm/amd64/e_sqrt.S new file mode 100644 index 0000000..a44e41f --- /dev/null +++ b/src/openlibm/amd64/e_sqrt.S @@ -0,0 +1,40 @@ +/*- + * Copyright (c) 2005 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +//__FBSDID("$FreeBSD: src/lib/msun/amd64/e_sqrt.S,v 1.4 2011/01/07 16:13:12 kib Exp $") + +ENTRY(sqrt) + sqrtsd %xmm0, %xmm0 + ret +END(sqrt) + + + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/amd64/e_sqrt.S.o b/src/openlibm/amd64/e_sqrt.S.o new file mode 100644 index 0000000000000000000000000000000000000000..404cde293a97eece60032e3b471820867534650c GIT binary patch literal 832 zcmb<-^>JfjWMqH=Mg}_u1P><4z<@0102X#&;AG%n_{1N0;4lLN0}BHKg8~Bs11kdq zgS%fS0}}(|0gxEXEJi4w6Ra0E0a7o7WEsdju8fh;9}%wb?)P=xAdMiX~MW7#l=`{DZC+Bwhg`7#J8}`ayPp)WY;jK;=Q{ p3El4?sTClCfq?-%UO;9*rNERRmaqd!tOF4Y3=IBI8b+b(2LP_^DOCUf literal 0 HcmV?d00001 diff --git a/src/openlibm/amd64/e_sqrtf.S b/src/openlibm/amd64/e_sqrtf.S new file mode 100644 index 0000000..f74175b --- /dev/null +++ b/src/openlibm/amd64/e_sqrtf.S @@ -0,0 +1,39 @@ +/*- + * Copyright (c) 2005 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +//__FBSDID("$FreeBSD: src/lib/msun/amd64/e_sqrtf.S,v 1.3 2011/01/07 16:13:12 kib Exp $") + +ENTRY(sqrtf) + sqrtss %xmm0, %xmm0 + ret +END(sqrtf) + + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/amd64/e_sqrtf.S.o b/src/openlibm/amd64/e_sqrtf.S.o new file mode 100644 index 0000000000000000000000000000000000000000..fb9648f357989b7330627d8023788e23809dcc8a GIT binary patch literal 832 zcmb<-^>JfjWMqH=Mg}_u1P><4z<@0102X#&;AG%n_{<-8;4lLN0}BHKg8~Bs11kdq zgS%fS0}}(|0gxEXEJi4w6Ra0E0a7o7WEsdju*p32EF2vA_$!U zW0j;rFsQL`30#(C6!=6HI~305hP3AeOKLNv#JF3=9nZP#Q*|>jwayf+@ZL literal 0 HcmV?d00001 diff --git a/src/openlibm/amd64/e_sqrtl.S b/src/openlibm/amd64/e_sqrtl.S new file mode 100644 index 0000000..6e7eac0 --- /dev/null +++ b/src/openlibm/amd64/e_sqrtl.S @@ -0,0 +1,46 @@ +/*- + * Copyright (c) 2008 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +//__FBSDID("$FreeBSD: src/lib/msun/amd64/e_sqrtl.S,v 1.2 2011/01/07 16:13:12 kib Exp $") + +ENTRY(sqrtl) +#ifndef _WIN64 + fldt 8(%rsp) + fsqrt +#else + fldt (%rdx) + fsqrt + mov %rcx,%rax + movq $0x0,0x8(%rcx) + fstpt (%rcx) +#endif + ret + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/amd64/e_sqrtl.S.o b/src/openlibm/amd64/e_sqrtl.S.o new file mode 100644 index 0000000000000000000000000000000000000000..975f31719ab55f999156c9d610dd0b6b758d59f7 GIT binary patch literal 832 zcmb<-^>JfjWMqH=Mg}_u1P><4z<@0102X#&;AG%nxSgZIar4(<1{MYe1_cHN237_J z26w+u1||l^10XT5Qm}RiAFJ6gMPPLd3_{43!Q_eyi%N1B81#xOb4wDF81#xuiXe0b zj8&3aQNo~?l30?+pqEr!%%GQ-Uy`cl?iZ?CT#}fa4dtijmFg7~ Z6HI~305hP3AP)WOq4NGv8b+b(2LL5GD)9gS literal 0 HcmV?d00001 diff --git a/src/openlibm/amd64/fenv.c b/src/openlibm/amd64/fenv.c new file mode 100644 index 0000000..ddf7dba --- /dev/null +++ b/src/openlibm/amd64/fenv.c @@ -0,0 +1,162 @@ +/*- + * Copyright (c) 2004-2005 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/msun/amd64/fenv.c,v 1.8 2011/10/21 06:25:31 das Exp $ + */ + +#include "bsd_fpu.h" +#include "math_private.h" + +#ifdef _WIN32 +#define __fenv_static OLM_DLLEXPORT +#endif +#include + +#ifdef __GNUC_GNU_INLINE__ +#error "This file must be compiled with C99 'inline' semantics" +#endif + +const fenv_t __fe_dfl_env = { + { 0xffff0000 | __INITIAL_FPUCW__, + 0xffff0000, + 0xffffffff, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff } + }, + __INITIAL_MXCSR__ +}; + +extern inline OLM_DLLEXPORT int feclearexcept(int __excepts); +extern inline OLM_DLLEXPORT int fegetexceptflag(fexcept_t *__flagp, int __excepts); + +OLM_DLLEXPORT int +fesetexceptflag(const fexcept_t *flagp, int excepts) +{ + fenv_t env; + + __fnstenv(&env.__x87); + env.__x87.__status &= ~excepts; + env.__x87.__status |= *flagp & excepts; + __fldenv(env.__x87); + + __stmxcsr(&env.__mxcsr); + env.__mxcsr &= ~excepts; + env.__mxcsr |= *flagp & excepts; + __ldmxcsr(env.__mxcsr); + + return (0); +} + +OLM_DLLEXPORT int +feraiseexcept(int excepts) +{ + fexcept_t ex = excepts; + + fesetexceptflag(&ex, excepts); + __fwait(); + return (0); +} + +extern inline OLM_DLLEXPORT int fetestexcept(int __excepts); +extern inline OLM_DLLEXPORT int fegetround(void); +extern inline OLM_DLLEXPORT int fesetround(int __round); + +OLM_DLLEXPORT int +fegetenv(fenv_t *envp) +{ + + __fnstenv(&envp->__x87); + __stmxcsr(&envp->__mxcsr); + /* + * fnstenv masks all exceptions, so we need to restore the + * control word to avoid this side effect. + */ + __fldcw(envp->__x87.__control); + return (0); +} + +OLM_DLLEXPORT int +feholdexcept(fenv_t *envp) +{ + uint32_t mxcsr; + + __stmxcsr(&mxcsr); + __fnstenv(&envp->__x87); + __fnclex(); + envp->__mxcsr = mxcsr; + mxcsr &= ~FE_ALL_EXCEPT; + mxcsr |= FE_ALL_EXCEPT << _SSE_EMASK_SHIFT; + __ldmxcsr(mxcsr); + return (0); +} + +extern inline OLM_DLLEXPORT int fesetenv(const fenv_t *__envp); + +OLM_DLLEXPORT int +feupdateenv(const fenv_t *envp) +{ + uint32_t mxcsr; + uint16_t status; + + __fnstsw(&status); + __stmxcsr(&mxcsr); + fesetenv(envp); + feraiseexcept((mxcsr | status) & FE_ALL_EXCEPT); + return (0); +} + +int +feenableexcept(int mask) +{ + uint32_t mxcsr, omask; + uint16_t control; + + mask &= FE_ALL_EXCEPT; + __fnstcw(&control); + __stmxcsr(&mxcsr); + omask = ~(control | mxcsr >> _SSE_EMASK_SHIFT) & FE_ALL_EXCEPT; + control &= ~mask; + __fldcw(control); + mxcsr &= ~(mask << _SSE_EMASK_SHIFT); + __ldmxcsr(mxcsr); + return (omask); +} + +int +fedisableexcept(int mask) +{ + uint32_t mxcsr, omask; + uint16_t control; + + mask &= FE_ALL_EXCEPT; + __fnstcw(&control); + __stmxcsr(&mxcsr); + omask = ~(control | mxcsr >> _SSE_EMASK_SHIFT) & FE_ALL_EXCEPT; + control |= mask; + __fldcw(control); + mxcsr |= mask << _SSE_EMASK_SHIFT; + __ldmxcsr(mxcsr); + return (omask); +} diff --git a/src/openlibm/amd64/fenv.c.o b/src/openlibm/amd64/fenv.c.o new file mode 100644 index 0000000000000000000000000000000000000000..53db099fd77c04d972de0b4518d252ff44753e1d GIT binary patch literal 2336 zcmb<-^>JfjWMqH=Mg}_u1P><4z_5T7!FB*M9T@l+co{lB-7HbL(e0yhr}G2paEzsWU|7&dn5+8~p2HRK6&?sC?o4(CMP`g@0X$$```}hxz4Oz@~UKzme$t zm)2RM!spRjqr&$BBs$yhfJgHYiNpNz3^&dB*Tu`+)CX&EVPF6m_vfbh?MK}%Dt|iN zWttxx;BAm+VCZyF`2#ZhkKuvCX=!>e<0pX3_vrj}|3T+*kXD|XO8o1BWVmZoc$%Nv zgDr#G)c~@(`MLeg8kJulwSV}xhp7DO{0Xw@`$ffzX`MbQzi#HJ{5trY{rh#r7tF6V zQ1Jy&^~EX{kktnZ>CP5r(wX^wg5nyfTKg)QtR`6u4+OSrpOzY*l9m$>QVX&-5JWIQ(it-Y1H&J1%KiU;ACfpIy}`s`?qyWMBa2Vo+QnS;MdZY7r=Wkj2sYmQejLf5Oxrfa(Y3Z +//__FBSDID("$FreeBSD: src/lib/msun/amd64/s_llrint.S,v 1.3 2011/02/04 21:54:06 kib Exp $") + +ENTRY(llrint) + cvtsd2si %xmm0, %rax + ret +END(llrint) + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/amd64/s_llrint.S.o b/src/openlibm/amd64/s_llrint.S.o new file mode 100644 index 0000000000000000000000000000000000000000..d57508a5397fc78634c243cf94e4b466c17d22de GIT binary patch literal 832 zcmb<-^>JfjWMqH=Mg}_u1P><4z<@0102X#&;AG%n_~gN_d*Cnw0}BHKg8~Bs11kdq zgS%fS0}}(|0gxEXEJi4w6Ra0E0a7o7WEmSwX--a2W?l&cgI;lEZb@PigI;k-5rocw zu}V@aN*MG~5=#;p^pc8;8T9hV@fy@9ipoAcnumeeL01*rf4E|6WMxpBm0Qb`>O#lD@ literal 0 HcmV?d00001 diff --git a/src/openlibm/amd64/s_llrintf.S b/src/openlibm/amd64/s_llrintf.S new file mode 100644 index 0000000..f5d39b3 --- /dev/null +++ b/src/openlibm/amd64/s_llrintf.S @@ -0,0 +1,12 @@ +#include +//__FBSDID("$FreeBSD: src/lib/msun/amd64/s_llrintf.S,v 1.3 2011/02/04 21:54:06 kib Exp $") + +ENTRY(llrintf) + cvtss2si %xmm0, %rax + ret +END(llrintf) + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/amd64/s_llrintf.S.o b/src/openlibm/amd64/s_llrintf.S.o new file mode 100644 index 0000000000000000000000000000000000000000..5c1d07c69866056b87a28d56fb0690c1124eeb7e GIT binary patch literal 832 zcmb<-^>JfjWMqH=Mg}_u1P><4z<@0102X#&;AG%n`0T;2d*Cnw0}BHKg8~Bs11kdq zgS%fS0}}(|0gxEXEJi4w6Ra0E0a7o7WEmSwX--a2W?o4e1A|_1Wo}7g5`$iGNfCt3 zfU!zaD@qvjQW8rN8T68hiy8Ft@=H?n-2Fmzi%Sxdv!VR-yi&b_qWpr?qLNCO>15N= z(4c|46KWD9j2IZu#RZ`9FiH`spBW|qrQM)3It2p<;CHWS1q z)_xlX1_pKp1_maOCM4_uWg9?g7zJ`Gj18he{z2CZ60ZOe3=9k~{UAF)YGL{%pz@&f rgzk5c)Cv&6z`y{Khcdww$P6$8N(f>JJCM{y5W&E};18u?6uN!@=A0_F literal 0 HcmV?d00001 diff --git a/src/openlibm/amd64/s_llrintl.S b/src/openlibm/amd64/s_llrintl.S new file mode 100644 index 0000000..12f2d33 --- /dev/null +++ b/src/openlibm/amd64/s_llrintl.S @@ -0,0 +1,45 @@ +/*- + * Copyright (c) 2005 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +//__FBSDID("$FreeBSD: src/lib/msun/amd64/s_llrintl.S,v 1.2 2011/01/07 16:13:12 kib Exp $"); + +ENTRY(llrintl) +#ifndef _WIN64 + fldt 8(%rsp) +#else + fldt (%rcx) +#endif + subq $8,%rsp + fistpll (%rsp) + popq %rax + ret + + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/amd64/s_llrintl.S.o b/src/openlibm/amd64/s_llrintl.S.o new file mode 100644 index 0000000000000000000000000000000000000000..6d895e49693e6e6d7a7cfeba6c0515b799e4c092 GIT binary patch literal 840 zcmb<-^>JfjWMqH=Mg}_u1P><4z`%hd=l~XWVBlonV7Q&5!r{^UhU31CO2lCX1_l-e z1_lKN1_o9J1_pP(PzELj#seTRuoeae21Y0!$vBu43JsDM!se2koTALUk{kvGz2eH; zlEfqiz2cH02%Q0Am84dbFzBTumLxLhB^4Jl=;h^?r0Ti*h3XcUBqnD=`RRG3dId%K z1*t_Pl_++T!;uF2je&s;O*15{7#Mib#0Aj!ictN`XyU$Td>9uLJ}@?jR%c*f;9y{2 zAXmQ*)P9gz$e39BZ5S9B*cliYn2 +//__FBSDID("$FreeBSD: src/lib/msun/amd64/s_logbl.S,v 1.4 2011/01/07 16:13:12 kib Exp $") + +ENTRY(logbl) +#ifndef _WIN64 + fldt 8(%rsp) +#else + fldt (%rdx) +#endif + fxtract + fstp %st +#ifdef _WIN64 + mov %rcx,%rax + movq $0x0,0x8(%rcx) + fstpt (%rcx) +#endif + ret + + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/amd64/s_logbl.S.o b/src/openlibm/amd64/s_logbl.S.o new file mode 100644 index 0000000000000000000000000000000000000000..e1d9969a4e4d77cdd0c06931bf9f1c62c13ebfda GIT binary patch literal 840 zcmb<-^>JfjWMqH=Mg}_u1P><4z`%hd=l~XWVBlonV7Q&5!g2G<-5ZC&Vhju{3=9kk z3=9mc3=9nJexVFZ42%arVo+%YMkpW2IG7X)4U!ka=8~NJ^rRdH2EF3S+>*p32EF2v zA_$!UW0j;rFsQL`30#(C6y>P zlgE)}U;w+84NW^FtQZ(L(ZmJN_=-^d%xL1CXnYtK6h1IEh*oD{VBlb2U?5k&4%B{- zS;&}J`)wE)7}yyY7?_YXGcYg&K=}qx8b*QK3S)z4kbltig2Wp@1Oo#DOh3pDkXo32 t38*|Me9`?5lG*?wpl*XQ!4$|0Fat^mVhKBt)OHZTz`)=SrC}7hegHW_EUEwi literal 0 HcmV?d00001 diff --git a/src/openlibm/amd64/s_lrint.S b/src/openlibm/amd64/s_lrint.S new file mode 100644 index 0000000..9e1b917 --- /dev/null +++ b/src/openlibm/amd64/s_lrint.S @@ -0,0 +1,44 @@ +/*- + * Copyright (c) 2005 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +//__FBSDID("$FreeBSD: src/lib/msun/amd64/s_lrint.S,v 1.3 2011/01/07 16:13:12 kib Exp $") + +ENTRY(lrint) +#ifndef _WIN64 + cvtsd2si %xmm0, %rax +#else + cvtsd2si %xmm0, %eax +#endif + ret +END(lrint) + + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/amd64/s_lrint.S.o b/src/openlibm/amd64/s_lrint.S.o new file mode 100644 index 0000000000000000000000000000000000000000..1d965f0df4d01d70f6cd6df785780fc104c7dbff GIT binary patch literal 832 zcmb<-^>JfjWMqH=Mg}_u1P><4z<@0102X#&;AG%n_~gN_d*Cnw0}BHKg8~Bs11kdq zgS%fS0}}(|0gxEXEJi4w6Ra0E0a7o7WEmSwX--jQUI_z(UU6k^Nn#R%UU5kggwBAm zN>VFI81zySOA;CMl8TEN^z!mcQuW;ZLUoHv5|gu`{Pet1y@I0rg4CjtN|@Oc(9+PL zfx8oG79@-q7|_K9pz<(E5vrdVCIF?~pfoxK3Lj)Kbp{3o4h9AWa`o##?MF5f#3t5$ z8wLgjb_NCpCXgm1>;YvPKxr5Sax07tqCx&a*9#J_01*rf3^4s5J3wk-`X!+9p!9_9 ncaYQy5CL@?lnJIlW`G$`LJ&*Xfuz=h2nGfQe<%&3(DefV{6#6> literal 0 HcmV?d00001 diff --git a/src/openlibm/amd64/s_lrintf.S b/src/openlibm/amd64/s_lrintf.S new file mode 100644 index 0000000..8e0b0c2 --- /dev/null +++ b/src/openlibm/amd64/s_lrintf.S @@ -0,0 +1,44 @@ +/*- + * Copyright (c) 2005 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +//__FBSDID("$FreeBSD: src/lib/msun/amd64/s_lrintf.S,v 1.3 2011/01/07 16:13:12 kib Exp $") + +ENTRY(lrintf) +#ifndef _WIN64 + cvtss2si %xmm0, %rax +#else + cvtss2si %xmm0, %eax +#endif + ret +END(lrintf) + + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/amd64/s_lrintf.S.o b/src/openlibm/amd64/s_lrintf.S.o new file mode 100644 index 0000000000000000000000000000000000000000..4ecf447b755bee91d0427eb49329ab1cf947725c GIT binary patch literal 832 zcmb<-^>JfjWMqH=Mg}_u1P><4z<@0102X#&;AG%n`0T;2d*Cnw0}BHKg8~Bs11kdq zgS%fS0}}(|0gxEXEJi4w6Ra0E0a7o7WEmSwX--jQUP&4QgI;lEZb@PigI;k-5rocw zu}V@aN*MG~5=#;p^pc8;8T9hV@fy@9ipoAcnumeeL01*rf4E|6WMxpBm0PA!rNB{r; literal 0 HcmV?d00001 diff --git a/src/openlibm/amd64/s_lrintl.S b/src/openlibm/amd64/s_lrintl.S new file mode 100644 index 0000000..288c0bb --- /dev/null +++ b/src/openlibm/amd64/s_lrintl.S @@ -0,0 +1,45 @@ +/*- + * Copyright (c) 2008 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +//__FBSDID("$FreeBSD: src/lib/msun/amd64/s_lrintl.S,v 1.2 2011/01/07 16:13:12 kib Exp $"); + +ENTRY(lrintl) +#ifndef _WIN64 + fldt 8(%rsp) +#else + fldt (%rcx) +#endif + subq $8,%rsp + fistpll (%rsp) + popq %rax + ret + + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/amd64/s_lrintl.S.o b/src/openlibm/amd64/s_lrintl.S.o new file mode 100644 index 0000000000000000000000000000000000000000..f2dab094ebe5e4acf374c0a9d858e331233de6b5 GIT binary patch literal 840 zcmb<-^>JfjWMqH=Mg}_u1P><4z`%hd=l~XWVBlonV7Q&5!r{^UhU31CO2lCX1_l-e z1_lKN1_o9J1_pP(PzELj#seTRuoeae21Y0!$vBu43JsDM!se2kqRhOK90mrx;>z5T z#3Tm2;*uf=odIK&q*jzL=%pli;8>bd)c>K2zICTBzW>3OAk1x5J< zsYNA~C{~ljkp}yXfq@N8HzceW7iFgA!*XJBC9U|?V% zSHBL_evnznm{|L57#JAX85kItkTo+fFa$vP22dJCf!qpXgJ_U{(Dj1E8$bjD0|QJy t$PSQNn0^VUJSP^vgQPZq2x! + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Based on public-domain remainder routine by J.T. Conklin . + */ + +#include +//__FBSDID("$FreeBSD: src/lib/msun/amd64/s_remquo.S,v 1.3 2011/01/07 16:13:12 kib Exp $"); + +ENTRY(remquo) + movsd %xmm0,-8(%rsp) + movsd %xmm1,-16(%rsp) + fldl -16(%rsp) + fldl -8(%rsp) +1: fprem1 + fstsw %ax + btw $10,%ax + jc 1b + fstp %st(1) +/* Extract the three low-order bits of the quotient from C0,C3,C1. */ + shrl $6,%eax + movl %eax,%ecx + andl $0x108,%eax + rorl $7,%eax + orl %eax,%ecx + roll $4,%eax + orl %ecx,%eax + andl $7,%eax +/* Negate the quotient bits if x*y<0. Avoid using an unpredictable branch. */ + movl -12(%rsp),%ecx + xorl -4(%rsp),%ecx + sarl $16,%ecx + sarl $16,%ecx + xorl %ecx,%eax + andl $1,%ecx + addl %ecx,%eax +/* Store the quotient and return. */ +#ifndef _WIN64 + movl %eax,(%rdi) +#else + movl %eax,(%r8) +#endif + fstpl -8(%rsp) + movsd -8(%rsp),%xmm0 + ret +END(remquo) + + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/amd64/s_remquo.S.o b/src/openlibm/amd64/s_remquo.S.o new file mode 100644 index 0000000000000000000000000000000000000000..e4149ae032cecf86227f0a231c25250b7590d473 GIT binary patch literal 920 zcmb<-^>JfjWMqH=Mg}_u1P><4zz~5X=l~XWVBlonVEDu@=%VuD6ThI3%7?oyVEp6e z*V*?Ur19^1z*Y3+?#+WQ*g6lYaxgM596Z6!dGO!?7S0pR57@hXRK6JdsQfwjQ{doF z0mBo`4;dLxbh6)#0huP?qVnS~*cKKB1_lKN1_o9J1_pP(PzELj#seTRm~$ARd~UF6 z+yqFy5R%WLVM>cqa|=uJ85s16D|1T{lNj`hONtmbT2aEFmy%eL$e@>0T+E=C zmtT^q=k6D(TU?TuoDJot=auRe6y+DB7L`=O3@4wKW?%rjmJQ7aNZ2zlz}*j(7l6_* zN)f7`872UwXG3Xp3KTxbV(JVG3>*v$4CLz9f!dF3CWuX}{Wc5?4D1XH3``(RNO%F1 zZ2+ZV6v(YGHi!oK2VE~n`~rwzU|@jh2iXBq3)3$FmFL9bcd!&lF*Izzd?*1GhVmE~ T1aasG + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Based on public-domain remainder routine by J.T. Conklin . + */ + +#include +//__FBSDID("$FreeBSD: src/lib/msun/amd64/s_remquof.S,v 1.3 2011/01/07 16:13:12 kib Exp $"); + +ENTRY(remquof) + movss %xmm0,-4(%rsp) + movss %xmm1,-8(%rsp) + flds -8(%rsp) + flds -4(%rsp) +1: fprem1 + fstsw %ax + btw $10,%ax + jc 1b + fstp %st(1) +/* Extract the three low-order bits of the quotient from C0,C3,C1. */ + shrl $6,%eax + movl %eax,%ecx + andl $0x108,%eax + rorl $7,%eax + orl %eax,%ecx + roll $4,%eax + orl %ecx,%eax + andl $7,%eax +/* Negate the quotient bits if x*y<0. Avoid using an unpredictable branch. */ + movl -8(%rsp),%ecx + xorl -4(%rsp),%ecx + sarl $16,%ecx + sarl $16,%ecx + xorl %ecx,%eax + andl $1,%ecx + addl %ecx,%eax +/* Store the quotient and return. */ +#ifndef _WIN64 + movl %eax,(%rdi) +#else + movl %eax,(%r8) +#endif + fstps -4(%rsp) + movss -4(%rsp),%xmm0 + ret +END(remquof) + + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/amd64/s_remquof.S.o b/src/openlibm/amd64/s_remquof.S.o new file mode 100644 index 0000000000000000000000000000000000000000..e33de630efb7207bc78562d01221b0d691081a7b GIT binary patch literal 920 zcmb<-^>JfjWMqH=Mg}_u1P><4zz~5X=l~XWVBlonVED{0=%VuHGrypZ%8#2aVEpIi z*V*?Ur19^1z*Y3+?#+WQ*g6lYaxgM596Z6!dGO!?7S0pR57@hXRDKxysQfwjQ{doF z0mBo`4;dLxbh6)!0huP?qVnf3*cKKB1_lKN1_o9J1_pP(PzELj#seTRm~$ARd~UF6 z+yqFy5R%WLVM>cqa|=uJ(-;`^iYs$V5|bG8ic5+hbOwx7l3G#1pqG+ZlE|Q!R9wuU zmzQ6Xs^{((s#{!=n4Aser{|UG6%^$cq!yJ_!b~TdmS$i8yOs^j1W4F3Fu>gpl^1~0 zFiH`spBW|qrDsEFbP5zc$YSaY3=A9$3=HJz*MZuPY$k|Jto=3&3=HfH3=B*lO-OhF zlx+Z|VHC)%FgAz=`3GGuNc;kbU|?W?=?B>XQVY{B0hQ;(;&-qVNHGHg14tgshZ0a> aD35_b5QlzFs6v0ZN(cig4B;>^FaQ7o8&#G7 literal 0 HcmV?d00001 diff --git a/src/openlibm/amd64/s_remquol.S b/src/openlibm/amd64/s_remquol.S new file mode 100644 index 0000000..344e1fb --- /dev/null +++ b/src/openlibm/amd64/s_remquol.S @@ -0,0 +1,81 @@ +/*- + * Copyright (c) 2005-2008 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Based on public-domain remainder routine by J.T. Conklin . + */ + +#include +//__FBSDID("$FreeBSD: src/lib/msun/amd64/s_remquol.S,v 1.2 2011/01/07 16:13:12 kib Exp $"); + +ENTRY(remquol) +#ifndef _WIN64 + fldt 24(%rsp) + fldt 8(%rsp) +#else + fldt (%r8) + fldt (%rdx) + mov %rcx,%r8 +#endif +1: fprem1 + fstsw %ax + btw $10,%ax + jc 1b + fstp %st(1) +/* Extract the three low-order bits of the quotient from C0,C3,C1. */ + shrl $6,%eax + movl %eax,%ecx + andl $0x108,%eax + rorl $7,%eax + orl %eax,%ecx + roll $4,%eax + orl %ecx,%eax + andl $7,%eax +/* Negate the quotient bits if x*y<0. Avoid using an unpredictable branch. */ + movl 32(%rsp),%ecx + xorl 16(%rsp),%ecx + movsx %cx,%ecx + sarl $16,%ecx + sarl $16,%ecx + xorl %ecx,%eax + andl $1,%ecx + addl %ecx,%eax +/* Store the quotient and return. */ +#ifndef _WIN64 + movl %eax,(%rdi) +#else + movl %eax,(%r9) + mov %r8,%rax + movq $0x0,0x8(%r8) + fstpt (%r8) +#endif + ret + + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/amd64/s_remquol.S.o b/src/openlibm/amd64/s_remquol.S.o new file mode 100644 index 0000000000000000000000000000000000000000..e2b9898074f1f121fe23121c3fab1de4c2902d16 GIT binary patch literal 896 zcmb<-^>JfjWMqH=Mg}_u1P><4z~F!+=l~XWVBlonV7Q&5B5^xMh2!Se+4mo$@$Y)T zRrKZV&4Vx4IuELHFfuS4Ji*R+@ZbR!&J)cK*t>mH6pVdT1o-!#Jor=K;7&zYHnd^ehveJ zUU6k^Nn#R%UU5kggwBAmN>VFI81zySOA;CMl8TEN^z!mcQuW;ZLUoHv5|gu`{Pet1 zy@I0rg4CjtO56@1QbwAA0qj~fH1&`$W?=9@6Bj_^D?;_7hf4>VIv5ueJ}@?jR%c*f z;9y{2AXmQ*)P9gz$e39BZ5S9B*cliYn2 + +ENTRY(rintl) +#ifndef _WIN64 + fldt 8(%rsp) + frndint +#else + fldt (%rdx) + frndint + mov %rcx,%rax + movq $0x0,0x8(%rcx) + fstpt (%rcx) +#endif + ret + + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/amd64/s_rintl.S.o b/src/openlibm/amd64/s_rintl.S.o new file mode 100644 index 0000000000000000000000000000000000000000..710ab3eaad1558d511b2184f1a727e159e25b24e GIT binary patch literal 832 zcmb<-^>JfjWMqH=Mg}_u1P><4z<@0102X#&;AG%nxSgZIar4h%1{MYe1_cHN237_J z26w+u1||l^10XT5Qm}RiAFJ6gMPPLd3_{43!Q_fE^Gb3U81#xOb4wDF81#xuiXe0b zj8&3aQNo~?l30?+pqEr!%%GQ-Uy`cl?iZ?CT#}fa4dtijmFg7~ Z6HI~305hP3AP)WOq4NGv8b+b(2LK6_D&_zH literal 0 HcmV?d00001 diff --git a/src/openlibm/amd64/s_scalbn.S b/src/openlibm/amd64/s_scalbn.S new file mode 100644 index 0000000..9d4152b --- /dev/null +++ b/src/openlibm/amd64/s_scalbn.S @@ -0,0 +1,55 @@ +/*- + * Copyright (c) 2005 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +//__FBSDID("$FreeBSD: src/lib/msun/amd64/s_scalbn.S,v 1.3 2011/01/07 16:13:12 kib Exp $") + +ENTRY(scalbn) + movsd %xmm0,-8(%rsp) +#ifndef _WIN64 + movl %edi,-12(%rsp) +#else + movl %edx,-12(%rsp) +#endif + fildl -12(%rsp) + fldl -8(%rsp) + fscale + fstp %st(1) + fstpl -8(%rsp) + movsd -8(%rsp),%xmm0 + ret +#ifndef _WIN64 +END(scalbn) +.globl CNAME(ldexp) +#else +.globl CNAME(ldexp); .section .drectve; .ascii " -export:ldexp" +#endif +.set CNAME(ldexp),CNAME(scalbn) + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/amd64/s_scalbn.S.o b/src/openlibm/amd64/s_scalbn.S.o new file mode 100644 index 0000000000000000000000000000000000000000..e7b994ac90302e67cbb16cdd23d963d0d0b804f7 GIT binary patch literal 896 zcmb<-^>JfjWMqH=Mg}_u1P><4z~F!+=l~XWVBlonVEDu@=%VtYvqt61Z5NdTAD{RITvUD>2CHRYU}0cjP+(wSU}a!naQ6#kU}9iA01|^4%LwIjLe=A< zK>@p literal 0 HcmV?d00001 diff --git a/src/openlibm/amd64/s_scalbnf.S b/src/openlibm/amd64/s_scalbnf.S new file mode 100644 index 0000000..75b4bb2 --- /dev/null +++ b/src/openlibm/amd64/s_scalbnf.S @@ -0,0 +1,55 @@ +/*- + * Copyright (c) 2005 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +//__FBSDID("$FreeBSD: src/lib/msun/amd64/s_scalbnf.S,v 1.4 2011/01/07 16:13:12 kib Exp $") + +ENTRY(scalbnf) + movss %xmm0,-8(%rsp) +#ifndef _WIN64 + movl %edi,-4(%rsp) +#else + movl %edx,-4(%rsp) +#endif + fildl -4(%rsp) + flds -8(%rsp) + fscale + fstp %st(1) + fstps -8(%rsp) + movss -8(%rsp),%xmm0 + ret +#ifndef _WIN64 +END(scalbnf) +.globl CNAME(ldexpf) +#else +.globl CNAME(ldexpf); .section .drectve; .ascii " -export:ldexpf" +#endif +.set CNAME(ldexpf),CNAME(scalbnf) + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/amd64/s_scalbnf.S.o b/src/openlibm/amd64/s_scalbnf.S.o new file mode 100644 index 0000000000000000000000000000000000000000..25ab656b0bb011376068c51d104e782d9f238ec2 GIT binary patch literal 896 zcmb<-^>JfjWMqH=Mg}_u1P><4z~F!+=l~XWVBlonVED{0=%VtYvqt65Z5Ne4H(gYI z-28j@=FJ$DAD{UJTvUD>2CHRYU}0cjP+(wSU}a!naQ6#kU}9iA01|^4%LwIjLe=A< zK1_lQ7@CKOyl>$?OSi%k@@c~3IFfjN-X&8mB9{|a~J{bT2 literal 0 HcmV?d00001 diff --git a/src/openlibm/amd64/s_scalbnl.S b/src/openlibm/amd64/s_scalbnl.S new file mode 100644 index 0000000..fa0d2bf --- /dev/null +++ b/src/openlibm/amd64/s_scalbnl.S @@ -0,0 +1,40 @@ +/* + * Based on code written by J.T. Conklin . + * Public domain. + */ + +#include +//__FBSDID("$FreeBSD: src/lib/msun/amd64/s_scalbnl.S,v 1.3 2011/01/07 16:13:12 kib Exp $") +/* //RCSID("$NetBSD: s_scalbnf.S,v 1.4 1999/01/02 05:15:40 kristerw Exp $") */ + +ENTRY(scalbnl) +#ifndef _WIN64 + movl %edi,-4(%rsp) + fildl -4(%rsp) + fldt 8(%rsp) +#else + mov %r8,%rax + movl %eax,-4(%rsp) + fildl -4(%rsp) + fldt (%rdx) +#endif + fscale + fstp %st(1) +#ifdef _WIN64 + mov %rcx,%rax + movq $0x0,0x8(%rcx) + fstpt (%rcx) +#endif + ret +#ifndef _WIN64 +END(scalbnl) +.globl CNAME(ldexpl) +#else +.globl CNAME(ldexpl); .section .drectve; .ascii " -export:ldexpl" +#endif +.set CNAME(ldexpl),CNAME(scalbnl) + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/amd64/s_scalbnl.S.o b/src/openlibm/amd64/s_scalbnl.S.o new file mode 100644 index 0000000000000000000000000000000000000000..722a416f0bad65b6fb5fc07392258fa3193470c6 GIT binary patch literal 880 zcmb<-^>JfjWMqH=Mg}_u1P><4z+iwR=l~XWVBlonVCbw-`E%Pv<J=2_7o--IR6;GMfRbil0Q-gw%?wDGGBCjW2a^_nF`%>} zR6jG652FHM3^W=Pe#k=V3=9k$3=9n9>eqqVk8CE0O|1Pk3=9nH3=9lRAWcX(0?Iak z(l83-Ru~&ZgZzW87bM;RA{ZDLJfJkl4v<=yehH{JDBYm@9VB%DL@+Qgpocfe45$>C V0>uwD{SUyh3=IBI8b+b(2LRUDHE;j` literal 0 HcmV?d00001 diff --git a/src/openlibm/arm/Make.files b/src/openlibm/arm/Make.files new file mode 100644 index 0000000..483a7cc --- /dev/null +++ b/src/openlibm/arm/Make.files @@ -0,0 +1 @@ +$(CUR_SRCS) = fenv.c diff --git a/src/openlibm/arm/fenv.c b/src/openlibm/arm/fenv.c new file mode 100644 index 0000000..c9abf14 --- /dev/null +++ b/src/openlibm/arm/fenv.c @@ -0,0 +1,52 @@ +/*- + * Copyright (c) 2004 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/msun/arm/fenv.c,v 1.3 2011/10/16 05:37:56 das Exp $ + */ + +#define __fenv_static +#include + +#ifdef __GNUC_GNU_INLINE__ +#error "This file must be compiled with C99 'inline' semantics" +#endif + +/* + * Hopefully the system ID byte is immutable, so it's valid to use + * this as a default environment. + */ +const fenv_t __fe_dfl_env = 0; + +extern inline int feclearexcept(int __excepts); +extern inline int fegetexceptflag(fexcept_t *__flagp, int __excepts); +extern inline int fesetexceptflag(const fexcept_t *__flagp, int __excepts); +extern inline int feraiseexcept(int __excepts); +extern inline int fetestexcept(int __excepts); +extern inline int fegetround(void); +extern inline int fesetround(int __round); +extern inline int fegetenv(fenv_t *__envp); +extern inline int feholdexcept(fenv_t *__envp); +extern inline int fesetenv(const fenv_t *__envp); +extern inline int feupdateenv(const fenv_t *__envp); diff --git a/src/openlibm/bsdsrc/Make.files b/src/openlibm/bsdsrc/Make.files new file mode 100644 index 0000000..6777fe2 --- /dev/null +++ b/src/openlibm/bsdsrc/Make.files @@ -0,0 +1 @@ +$(CUR_SRCS) += b_exp.c b_log.c b_tgamma.c diff --git a/src/openlibm/bsdsrc/b_exp.c b/src/openlibm/bsdsrc/b_exp.c new file mode 100644 index 0000000..6af8dd7 --- /dev/null +++ b/src/openlibm/bsdsrc/b_exp.c @@ -0,0 +1,172 @@ +/* + * Copyright (c) 1985, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* @(#)exp.c 8.1 (Berkeley) 6/4/93 */ +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/bsdsrc/b_exp.c,v 1.9 2011/10/16 05:37:20 das Exp $"); + +#include + +/* EXP(X) + * RETURN THE EXPONENTIAL OF X + * DOUBLE PRECISION (IEEE 53 bits, VAX D FORMAT 56 BITS) + * CODED IN C BY K.C. NG, 1/19/85; + * REVISED BY K.C. NG on 2/6/85, 2/15/85, 3/7/85, 3/24/85, 4/16/85, 6/14/86. + * + * Required system supported functions: + * scalb(x,n) + * copysign(x,y) + * finite(x) + * + * Method: + * 1. Argument Reduction: given the input x, find r and integer k such + * that + * x = k*ln2 + r, |r| <= 0.5*ln2 . + * r will be represented as r := z+c for better accuracy. + * + * 2. Compute exp(r) by + * + * exp(r) = 1 + r + r*R1/(2-R1), + * where + * R1 = x - x^2*(p1+x^2*(p2+x^2*(p3+x^2*(p4+p5*x^2)))). + * + * 3. exp(x) = 2^k * exp(r) . + * + * Special cases: + * exp(INF) is INF, exp(NaN) is NaN; + * exp(-INF)= 0; + * for finite argument, only exp(0)=1 is exact. + * + * Accuracy: + * exp(x) returns the exponential of x nearly rounded. In a test run + * with 1,156,000 random arguments on a VAX, the maximum observed + * error was 0.869 ulps (units in the last place). + */ + +#include "mathimpl.h" + +static const double p1 = 0x1.555555555553ep-3; +static const double p2 = -0x1.6c16c16bebd93p-9; +static const double p3 = 0x1.1566aaf25de2cp-14; +static const double p4 = -0x1.bbd41c5d26bf1p-20; +static const double p5 = 0x1.6376972bea4d0p-25; +static const double ln2hi = 0x1.62e42fee00000p-1; +static const double ln2lo = 0x1.a39ef35793c76p-33; +static const double lnhuge = 0x1.6602b15b7ecf2p9; +static const double lntiny = -0x1.77af8ebeae354p9; +static const double invln2 = 0x1.71547652b82fep0; + +#if 0 +OLM_DLLEXPORT double exp(x) +double x; +{ + double z,hi,lo,c; + int k; + +#if !defined(vax)&&!defined(tahoe) + if(x!=x) return(x); /* x is NaN */ +#endif /* !defined(vax)&&!defined(tahoe) */ + if( x <= lnhuge ) { + if( x >= lntiny ) { + + /* argument reduction : x --> x - k*ln2 */ + + k=invln2*x+copysign(0.5,x); /* k=NINT(x/ln2) */ + + /* express x-k*ln2 as hi-lo and let x=hi-lo rounded */ + + hi=x-k*ln2hi; + x=hi-(lo=k*ln2lo); + + /* return 2^k*[1+x+x*c/(2+c)] */ + z=x*x; + c= x - z*(p1+z*(p2+z*(p3+z*(p4+z*p5)))); + return scalb(1.0+(hi-(lo-(x*c)/(2.0-c))),k); + + } + /* end of x > lntiny */ + + else + /* exp(-big#) underflows to zero */ + if(finite(x)) return(scalb(1.0,-5000)); + + /* exp(-INF) is zero */ + else return(0.0); + } + /* end of x < lnhuge */ + + else + /* exp(INF) is INF, exp(+big#) overflows to INF */ + return( finite(x) ? scalb(1.0,5000) : x); +} +#endif + +/* returns exp(r = x + c) for |c| < |x| with no overlap. */ + +double __exp__D(x, c) +double x, c; +{ + double z,hi,lo; + int k; + + if (x != x) /* x is NaN */ + return(x); + if ( x <= lnhuge ) { + if ( x >= lntiny ) { + + /* argument reduction : x --> x - k*ln2 */ + z = invln2*x; + k = z + copysign(.5, x); + + /* express (x+c)-k*ln2 as hi-lo and let x=hi-lo rounded */ + + hi=(x-k*ln2hi); /* Exact. */ + x= hi - (lo = k*ln2lo-c); + /* return 2^k*[1+x+x*c/(2+c)] */ + z=x*x; + c= x - z*(p1+z*(p2+z*(p3+z*(p4+z*p5)))); + c = (x*c)/(2.0-c); + + return scalbn(1.+(hi-(lo - c)), k); + } + /* end of x > lntiny */ + + else + /* exp(-big#) underflows to zero */ + if(isfinite(x)) return(scalbn(1.0,-5000)); + + /* exp(-INF) is zero */ + else return(0.0); + } + /* end of x < lnhuge */ + + else + /* exp(INF) is INF, exp(+big#) overflows to INF */ + return( isfinite(x) ? scalbn(1.0,5000) : x); +} diff --git a/src/openlibm/bsdsrc/b_exp.c.o b/src/openlibm/bsdsrc/b_exp.c.o new file mode 100644 index 0000000000000000000000000000000000000000..5cf3f86e2f407e8dd50e7ae03d4f71c9ab803e8a GIT binary patch literal 2912 zcmb<-^>JfjWMqH=Mg}_u1P><4!0><_!FB*M9T@l+cp1|8^$w)*Yh2*(GGb(4@MwOc z@rhr66{H}IU;hw)lL{jPLmI!nC`hDODUDy_&; z$D~a-%rD;nX7Otr0{al=FM$vhj@ARE`XIF+J%`iyX?7u8N^a|n6->h+JR_5=T#v{T(hzuSZCW?*<=&%p5DpOfA* z`!btK)AyFIY%eU?SCnag8Qh(ntrRre{X#Vr3{CWm^b8e@42(<-3=ItwG=fr76g(13pc1;~nhXpq3=9kk z3=9k)N4xulGB7bP9sr5K(jX(0&k1oTg9wyntO{aatPo(7=3(cUz{tR$!@$5G1C?6_ z(j3HRP|C%};mOVPl#e5r&mfVDkHeiikc*GQpF5C`1F95*0%>Jo`1l_~f`Ng78B5N9 zxC`WZR2_U^E-M4NMZ!>V0WggqB*08o1_%x2fC*VJ$qEi5FcV5BfoWC-4KR%$)WJ+v z1_LmSAVA>*3S|p~5SV2MCRt$-2Pkz6A)nvBFsR9If$?T5tbmr&;U$=^%#OR85%RhgA9w0cVUQ+&n!;M%*!lEWk}91 zs4UJ*&toV~PRvQl138j`fk6yPGlA0!1H+&H5CDrOkT@uP!^DlD>Oo?H3<&ihP;roY zQ0juIk3kY=LsDN26$hCkgd{!}Dh@ISRD{FKS&JkNN~19Gok-%Kv<(x#i6qX2Wd2hm zac(5>k4WM?NaBBy#6jgT%zQym#$#Y$0J#&CcVOb63Ie1BB+idyPB2tG$iK+pRst1A zS3d=ZxD`|!WDY2A!t8CrA-)KQIH(MRxf5hJhz-Vi#g(}wiAfB4#U(`$Is?WkO3g{s zD@m;=VbDuSEJ-sbIUQK!E%O@-ir`AsYuR@EKtF7AA+DccmF1 zWjsthOkDsdQ8O?w`~Vrwz`y`XJ0K<~ErQg*%0V>-25>3C3=%}b&p?Wi_%J5AFsR%E znMtmGQ27Wl6O^Z5c7W&?AVCHOh71q~34`ncabdI_)cxq?aR4-t=z|m^VW_cSKZAtb zq545=WLyu`k1Pga!}NpLAPg!`LHQnCc>`1c-CZzugY<%MKGc4wa*z-hZ-5Fw%6G63 zm_XN`g(LnwK#pQyfY*1R_y?6YF#WLj2l)qT71(?j@dGOO0HlC{fdN#;fYKhievp~y maSt-%1}MWbFfbH>I7k?399#rcwqVnr0Cj&QTqT5ot{(uZn$fiY literal 0 HcmV?d00001 diff --git a/src/openlibm/bsdsrc/b_log.c b/src/openlibm/bsdsrc/b_log.c new file mode 100644 index 0000000..c20d290 --- /dev/null +++ b/src/openlibm/bsdsrc/b_log.c @@ -0,0 +1,466 @@ +/* + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* @(#)log.c 8.2 (Berkeley) 11/30/93 */ +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/bsdsrc/b_log.c,v 1.9 2008/02/22 02:26:51 das Exp $"); + +#include + +#include "mathimpl.h" + +/* Table-driven natural logarithm. + * + * This code was derived, with minor modifications, from: + * Peter Tang, "Table-Driven Implementation of the + * Logarithm in IEEE Floating-Point arithmetic." ACM Trans. + * Math Software, vol 16. no 4, pp 378-400, Dec 1990). + * + * Calculates log(2^m*F*(1+f/F)), |f/j| <= 1/256, + * where F = j/128 for j an integer in [0, 128]. + * + * log(2^m) = log2_hi*m + log2_tail*m + * since m is an integer, the dominant term is exact. + * m has at most 10 digits (for subnormal numbers), + * and log2_hi has 11 trailing zero bits. + * + * log(F) = logF_hi[j] + logF_lo[j] is in tabular form in log_table.h + * logF_hi[] + 512 is exact. + * + * log(1+f/F) = 2*f/(2*F + f) + 1/12 * (2*f/(2*F + f))**3 + ... + * the leading term is calculated to extra precision in two + * parts, the larger of which adds exactly to the dominant + * m and F terms. + * There are two cases: + * 1. when m, j are non-zero (m | j), use absolute + * precision for the leading term. + * 2. when m = j = 0, |1-x| < 1/256, and log(x) ~= (x-1). + * In this case, use a relative precision of 24 bits. + * (This is done differently in the original paper) + * + * Special cases: + * 0 return signalling -Inf + * neg return signalling NaN + * +Inf return +Inf +*/ + +#define N 128 + +/* Table of log(Fj) = logF_head[j] + logF_tail[j], for Fj = 1+j/128. + * Used for generation of extend precision logarithms. + * The constant 35184372088832 is 2^45, so the divide is exact. + * It ensures correct reading of logF_head, even for inaccurate + * decimal-to-binary conversion routines. (Everybody gets the + * right answer for integers less than 2^53.) + * Values for log(F) were generated using error < 10^-57 absolute + * with the bc -l package. +*/ +static double A1 = .08333333333333178827; +static double A2 = .01250000000377174923; +static double A3 = .002232139987919447809; +static double A4 = .0004348877777076145742; + +static double logF_head[N+1] = { + 0., + .007782140442060381246, + .015504186535963526694, + .023167059281547608406, + .030771658666765233647, + .038318864302141264488, + .045809536031242714670, + .053244514518837604555, + .060624621816486978786, + .067950661908525944454, + .075223421237524235039, + .082443669210988446138, + .089612158689760690322, + .096729626458454731618, + .103796793681567578460, + .110814366340264314203, + .117783035656430001836, + .124703478501032805070, + .131576357788617315236, + .138402322859292326029, + .145182009844575077295, + .151916042025732167530, + .158605030176659056451, + .165249572895390883786, + .171850256926518341060, + .178407657472689606947, + .184922338493834104156, + .191394852999565046047, + .197825743329758552135, + .204215541428766300668, + .210564769107350002741, + .216873938300523150246, + .223143551314024080056, + .229374101064877322642, + .235566071312860003672, + .241719936886966024758, + .247836163904594286577, + .253915209980732470285, + .259957524436686071567, + .265963548496984003577, + .271933715484010463114, + .277868451003087102435, + .283768173130738432519, + .289633292582948342896, + .295464212893421063199, + .301261330578199704177, + .307025035294827830512, + .312755710004239517729, + .318453731118097493890, + .324119468654316733591, + .329753286372579168528, + .335355541920762334484, + .340926586970454081892, + .346466767346100823488, + .351976423156884266063, + .357455888922231679316, + .362905493689140712376, + .368325561158599157352, + .373716409793814818840, + .379078352934811846353, + .384411698910298582632, + .389716751140440464951, + .394993808240542421117, + .400243164127459749579, + .405465108107819105498, + .410659924985338875558, + .415827895143593195825, + .420969294644237379543, + .426084395310681429691, + .431173464818130014464, + .436236766774527495726, + .441274560805140936281, + .446287102628048160113, + .451274644139630254358, + .456237433481874177232, + .461175715122408291790, + .466089729924533457960, + .470979715219073113985, + .475845904869856894947, + .480688529345570714212, + .485507815781602403149, + .490303988045525329653, + .495077266798034543171, + .499827869556611403822, + .504556010751912253908, + .509261901790523552335, + .513945751101346104405, + .518607764208354637958, + .523248143765158602036, + .527867089620485785417, + .532464798869114019908, + .537041465897345915436, + .541597282432121573947, + .546132437597407260909, + .550647117952394182793, + .555141507540611200965, + .559615787935399566777, + .564070138285387656651, + .568504735352689749561, + .572919753562018740922, + .577315365035246941260, + .581691739635061821900, + .586049045003164792433, + .590387446602107957005, + .594707107746216934174, + .599008189645246602594, + .603290851438941899687, + .607555250224322662688, + .611801541106615331955, + .616029877215623855590, + .620240409751204424537, + .624433288012369303032, + .628608659422752680256, + .632766669570628437213, + .636907462236194987781, + .641031179420679109171, + .645137961373620782978, + .649227946625615004450, + .653301272011958644725, + .657358072709030238911, + .661398482245203922502, + .665422632544505177065, + .669430653942981734871, + .673422675212350441142, + .677398823590920073911, + .681359224807238206267, + .685304003098281100392, + .689233281238557538017, + .693147180560117703862 +}; + +static double logF_tail[N+1] = { + 0., + -.00000000000000543229938420049, + .00000000000000172745674997061, + -.00000000000001323017818229233, + -.00000000000001154527628289872, + -.00000000000000466529469958300, + .00000000000005148849572685810, + -.00000000000002532168943117445, + -.00000000000005213620639136504, + -.00000000000001819506003016881, + .00000000000006329065958724544, + .00000000000008614512936087814, + -.00000000000007355770219435028, + .00000000000009638067658552277, + .00000000000007598636597194141, + .00000000000002579999128306990, + -.00000000000004654729747598444, + -.00000000000007556920687451336, + .00000000000010195735223708472, + -.00000000000017319034406422306, + -.00000000000007718001336828098, + .00000000000010980754099855238, + -.00000000000002047235780046195, + -.00000000000008372091099235912, + .00000000000014088127937111135, + .00000000000012869017157588257, + .00000000000017788850778198106, + .00000000000006440856150696891, + .00000000000016132822667240822, + -.00000000000007540916511956188, + -.00000000000000036507188831790, + .00000000000009120937249914984, + .00000000000018567570959796010, + -.00000000000003149265065191483, + -.00000000000009309459495196889, + .00000000000017914338601329117, + -.00000000000001302979717330866, + .00000000000023097385217586939, + .00000000000023999540484211737, + .00000000000015393776174455408, + -.00000000000036870428315837678, + .00000000000036920375082080089, + -.00000000000009383417223663699, + .00000000000009433398189512690, + .00000000000041481318704258568, + -.00000000000003792316480209314, + .00000000000008403156304792424, + -.00000000000034262934348285429, + .00000000000043712191957429145, + -.00000000000010475750058776541, + -.00000000000011118671389559323, + .00000000000037549577257259853, + .00000000000013912841212197565, + .00000000000010775743037572640, + .00000000000029391859187648000, + -.00000000000042790509060060774, + .00000000000022774076114039555, + .00000000000010849569622967912, + -.00000000000023073801945705758, + .00000000000015761203773969435, + .00000000000003345710269544082, + -.00000000000041525158063436123, + .00000000000032655698896907146, + -.00000000000044704265010452446, + .00000000000034527647952039772, + -.00000000000007048962392109746, + .00000000000011776978751369214, + -.00000000000010774341461609578, + .00000000000021863343293215910, + .00000000000024132639491333131, + .00000000000039057462209830700, + -.00000000000026570679203560751, + .00000000000037135141919592021, + -.00000000000017166921336082431, + -.00000000000028658285157914353, + -.00000000000023812542263446809, + .00000000000006576659768580062, + -.00000000000028210143846181267, + .00000000000010701931762114254, + .00000000000018119346366441110, + .00000000000009840465278232627, + -.00000000000033149150282752542, + -.00000000000018302857356041668, + -.00000000000016207400156744949, + .00000000000048303314949553201, + -.00000000000071560553172382115, + .00000000000088821239518571855, + -.00000000000030900580513238244, + -.00000000000061076551972851496, + .00000000000035659969663347830, + .00000000000035782396591276383, + -.00000000000046226087001544578, + .00000000000062279762917225156, + .00000000000072838947272065741, + .00000000000026809646615211673, + -.00000000000010960825046059278, + .00000000000002311949383800537, + -.00000000000058469058005299247, + -.00000000000002103748251144494, + -.00000000000023323182945587408, + -.00000000000042333694288141916, + -.00000000000043933937969737844, + .00000000000041341647073835565, + .00000000000006841763641591466, + .00000000000047585534004430641, + .00000000000083679678674757695, + -.00000000000085763734646658640, + .00000000000021913281229340092, + -.00000000000062242842536431148, + -.00000000000010983594325438430, + .00000000000065310431377633651, + -.00000000000047580199021710769, + -.00000000000037854251265457040, + .00000000000040939233218678664, + .00000000000087424383914858291, + .00000000000025218188456842882, + -.00000000000003608131360422557, + -.00000000000050518555924280902, + .00000000000078699403323355317, + -.00000000000067020876961949060, + .00000000000016108575753932458, + .00000000000058527188436251509, + -.00000000000035246757297904791, + -.00000000000018372084495629058, + .00000000000088606689813494916, + .00000000000066486268071468700, + .00000000000063831615170646519, + .00000000000025144230728376072, + -.00000000000017239444525614834 +}; + +#if 0 +OLM_DLLEXPORT double +#ifdef _ANSI_SOURCE +log(double x) +#else +log(x) double x; +#endif +{ + int m, j; + double F, f, g, q, u, u2, v, zero = 0.0, one = 1.0; + volatile double u1; + + /* Catch special cases */ + if (x <= 0) + if (x == zero) /* log(0) = -Inf */ + return (-one/zero); + else /* log(neg) = NaN */ + return (zero/zero); + else if (!finite(x)) + return (x+x); /* x = NaN, Inf */ + + /* Argument reduction: 1 <= g < 2; x/2^m = g; */ + /* y = F*(1 + f/F) for |f| <= 2^-8 */ + + m = logb(x); + g = ldexp(x, -m); + if (m == -1022) { + j = logb(g), m += j; + g = ldexp(g, -j); + } + j = N*(g-1) + .5; + F = (1.0/N) * j + 1; /* F*128 is an integer in [128, 512] */ + f = g - F; + + /* Approximate expansion for log(1+f/F) ~= u + q */ + g = 1/(2*F+f); + u = 2*f*g; + v = u*u; + q = u*v*(A1 + v*(A2 + v*(A3 + v*A4))); + + /* case 1: u1 = u rounded to 2^-43 absolute. Since u < 2^-8, + * u1 has at most 35 bits, and F*u1 is exact, as F has < 8 bits. + * It also adds exactly to |m*log2_hi + log_F_head[j] | < 750 + */ + if (m | j) + u1 = u + 513, u1 -= 513; + + /* case 2: |1-x| < 1/256. The m- and j- dependent terms are zero; + * u1 = u to 24 bits. + */ + else + u1 = u, TRUNC(u1); + u2 = (2.0*(f - F*u1) - u1*f) * g; + /* u1 + u2 = 2f/(2F+f) to extra precision. */ + + /* log(x) = log(2^m*F*(1+f/F)) = */ + /* (m*log2_hi+logF_head[j]+u1) + (m*log2_lo+logF_tail[j]+q); */ + /* (exact) + (tiny) */ + + u1 += m*logF_head[N] + logF_head[j]; /* exact */ + u2 = (u2 + logF_tail[j]) + q; /* tiny */ + u2 += logF_tail[N]*m; + return (u1 + u2); +} +#endif + +/* + * Extra precision variant, returning struct {double a, b;}; + * log(x) = a+b to 63 bits, with a rounded to 26 bits. + */ +struct Double +#ifdef _ANSI_SOURCE +__log__D(double x) +#else +__log__D(x) double x; +#endif +{ + int m, j; + double F, f, g, q, u, v, u2; + volatile double u1; + struct Double r; + + /* Argument reduction: 1 <= g < 2; x/2^m = g; */ + /* y = F*(1 + f/F) for |f| <= 2^-8 */ + + m = logb(x); + g = ldexp(x, -m); + if (m == -1022) { + j = logb(g), m += j; + g = ldexp(g, -j); + } + j = N*(g-1) + .5; + F = (1.0/N) * j + 1; + f = g - F; + + g = 1/(2*F+f); + u = 2*f*g; + v = u*u; + q = u*v*(A1 + v*(A2 + v*(A3 + v*A4))); + if (m | j) + u1 = u + 513, u1 -= 513; + else + u1 = u, TRUNC(u1); + u2 = (2.0*(f - F*u1) - u1*f) * g; + + u1 += m*logF_head[N] + logF_head[j]; + + u2 += logF_tail[j]; u2 += q; + u2 += logF_tail[N]*m; + r.a = u1 + u2; /* Only difference is here */ + TRUNC(r.a); + r.b = (u1 - r.a) + u2; + return (r); +} diff --git a/src/openlibm/bsdsrc/b_log.c.o b/src/openlibm/bsdsrc/b_log.c.o new file mode 100644 index 0000000000000000000000000000000000000000..34ad487cc049c4cf515e15e85d3b0371ac04f3d0 GIT binary patch literal 5128 zcmb<-^>JfjWMqH=Mg}_u1P><4z~CW(U^{@B4h;MZdse`Mn%G7hDWa`NV&&O5c&WA|No!(BVVQQYh3umA9?r_zW~&*n5&=oBQAa7 zkGYV>{~qMI!yspV;ulB(SrB>S6MuxvA*flO_#;FPed3R}^NBy=)F*xcumzv^BQJd7 z7mNWZ7jOZQ5f?x4M;rpjfx;(#0T&ez>7$~M=D}Zg2t=G{e8j-O@WVs#ga_vZk4~5Z zi8K%XyaS*3V@^PHc{Cp}hz418m|vd3V;{mF$essz7G&l{5OJ&VA;jQM9-OB zUOxZ#|3AOH0|VGOXi4G+DAs!CgHi!fvUvI7?|)E$gY3hNGyY6F!Cd}h&&*|)ztzay zw~ndYD^S)vbJ7Jv+pLT}^-OyUTOqeJ>69%dd(*VGtof>7Z97Nn5_f8{sV(ci z_=s>GSzBv{4_Z1VT6@{j)?EyBHQn3z<&oamO*Xbt(|`ZG7Vok5kF5Kb^qr=A_jKvb zE`MQXYgJ*Ic#ubYuSL)w^Ia3n_p)<6Dn4=9+159vETmV)$u>(j`>`~qr|oYhAqNFT zBU{T-1IMy0Znj+W?@T;vX}b4g|5^KFzg>G|gywz@USnzdS?-4F8bvQ#sf<&*C+cL~9|zdZ40E(MT;*!puVs<^ z=VRnvhtj@dzkfyACUL(0T9#?G_k*y{rK(;l+g7QQI&%zSZ6`Jyz2Y0Gy7z+V^*u7n z&271x-hOtHiP*c@yqdfAP@JvGjag?W)!6PmSi^PuhPVA*-c#FVh2%upK9Q4=UO2_s zc1Bmt-n}7qwxR<2oQ|vuvDJK@^QKrPZtw44pGR}p0&HK&XNG_1w6pb=i1L|j6R`Kt zX^pZ;dTzFj97inHURAQ4rZw$FqeblAT9LaxyMBe)?hw8hW>OlzH@~cR+b8b`+oQ^< zyaCsZ_r|@NKS64;gYAmz?+kYb+wHv^db?KgsGn`8|Hl5v-vPF3%w^lYS4Z2nZn5*} z*%Y)F5`Iy(%d%Fma%y_)6)`baoTnACS2%Xby7dPG_LfYVHRE@ak!|*_0;k6}gZF;g z)BCMg-p=;f@;f{A8a!=%j_?(o-DGX+d3f@!dBNd(wasQM@HynUH+^#ag^=@Zd+TE} z=N$W&U|ag%j(L`D=H7`G)5856@@*Nfc^&B87rOV1OGdh9ZR%d#y{E6f6_2zPH@kWK zw{E1Z#j`vA);K5ZownGxf91a<|;|SJ`_`NqD;7vBbTuVKX+&*^q7fb;(haEmP9>hVN0jzjL*ltxLC)=*sCS zwv#VfAFn+dv3E=_ue^Vrq**)uTQF`W2jzdb|4 zg_^qS2kaRd^sj1dKWNXupztGT>LGiE204X4g@^4K8cyeE`yR1pII!^XQ?;Y^3=PW* z4E`UrXE-4Fod4P}dxir7Or5Kb+cO+cNL^5W!k)q5%bcj7llBY;9?9=fK4s5vpuz9t z=Tr6!4Z0<5hfdowG|W2wz5k3o!vX(n#h9~D_nfn5aJX}N?FSGYmn*UJygkE#EmKq- zF4!|P6hBf~e8HZ#t9I8{qy&>#qA{dj^NhP@iR&?HLZVwHdHnv1f3QIn0GmCV3;j;qV1YJ!vXD8eGfqN?r+yEuiG;? z+>Kv4>AF3`fhOx8udai_>()i58}Gce4W^=8g3dxi#gBh8N>`b_nAm)rIX43not%mC5L z=lZ_BZO?Gv?DFfjcc9^S$DV#y&(KgK z)uD3Fo}uAdqEiWocDpq5@I8A5hV}9NLig<%914CZC*HSbV5sbmSP!BjIQ0JBw`Vx8 zbZL<41A7LCm2>ZVKd@&wAQNL(1mcJL=g$Dqs!xjcfy6JidOiX1b?1HNd}zLUENK`p`e~xsU7_8eHDKJOGk^Vpj45MEe_GXMb$Zz#wEPtPP^) z&eiaHY|r4}zE!*sM2B5|Fc~Dy;MKAX#4pTZy7}0iq2Xdn^luRD_M%_*i9N%CpO5C- zKY^x)C-w{tuPz2RgZLX_e=K=o&%khYedRF_f4ks~=OB5;Gs2utLHS5cSL>-gL&MB; z74N6^3=CVY{>%pP&u(4Y1ENiR9M*!wbM9_4g1_lNW zC@svuzyK15SppLW@tMKC1hEhp+{|TQLkK`wN?@9efdfn<2z4-%jRC290T$5#lWYtU zU>ZRff|+dKFa|TBgc+D-W6%K82*Mi7WMeP@(+C2RK-d^85JF&9!V6bP#%F*Aoj&&SySL>PhyBM@N>B1}MpDTpuw5#}Jm0z_DX2txygc#xU#@h%{v zk{EJQQY#8TZUA8(5WxUR$3hGY41Yjfng9R)D4b(nY{R6R(X z9m$+XBymt$fT_=k;Fm0K$!SlBym0@ z^LaoShymg+P+pdS<_9e#aegHA5lG@7^)T~uk;Fl1940Og3K%TmY=tC_9L}IJ1>{ta zGzf#(V60bMnOl;W#GqGPQUswhV639loJ75n)QS=Yy_Cd~Lei9VQdgB4Gl|}dXN|h3xFb(fq`KL$Z!S*22h#+ zF+ph$Bo8ZJ)WGE&0|PTi5DB-V1U5nfWCnuAzyK<*KxUGwA5^Y^%tW_t0aQQ(WH^$A zpzuQCGFU?056ZL1;wM0vhJk@00$C7LzC-yiW8I+o(aT8%Q08J_V9hw6v%VKlnhcm@UrP&onhE=(Ci08~G^yI}5yDJ+M&A64&8skblta2D$A3)cyw`1q=)fpt460Dg0sjL1i9#+5zcb k0Mfv~zyK>BL1G{bH4elCW00BH^dEq_zY(koL7?jg035@PH~;_u literal 0 HcmV?d00001 diff --git a/src/openlibm/bsdsrc/b_tgamma.c b/src/openlibm/bsdsrc/b_tgamma.c new file mode 100644 index 0000000..f3871de --- /dev/null +++ b/src/openlibm/bsdsrc/b_tgamma.c @@ -0,0 +1,319 @@ +/*- + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* @(#)gamma.c 8.1 (Berkeley) 6/4/93 */ +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/bsdsrc/b_tgamma.c,v 1.10 2008/02/22 02:26:51 das Exp $"); + +/* + * This code by P. McIlroy, Oct 1992; + * + * The financial support of UUNET Communications Services is greatfully + * acknowledged. + */ + +#include +#include + +#include "mathimpl.h" + +/* METHOD: + * x < 0: Use reflection formula, G(x) = pi/(sin(pi*x)*x*G(x)) + * At negative integers, return NaN and raise invalid. + * + * x < 6.5: + * Use argument reduction G(x+1) = xG(x) to reach the + * range [1.066124,2.066124]. Use a rational + * approximation centered at the minimum (x0+1) to + * ensure monotonicity. + * + * x >= 6.5: Use the asymptotic approximation (Stirling's formula) + * adjusted for equal-ripples: + * + * log(G(x)) ~= (x-.5)*(log(x)-1) + .5(log(2*pi)-1) + 1/x*P(1/(x*x)) + * + * Keep extra precision in multiplying (x-.5)(log(x)-1), to + * avoid premature round-off. + * + * Special values: + * -Inf: return NaN and raise invalid; + * negative integer: return NaN and raise invalid; + * other x ~< 177.79: return +-0 and raise underflow; + * +-0: return +-Inf and raise divide-by-zero; + * finite x ~> 171.63: return +Inf and raise overflow; + * +Inf: return +Inf; + * NaN: return NaN. + * + * Accuracy: tgamma(x) is accurate to within + * x > 0: error provably < 0.9ulp. + * Maximum observed in 1,000,000 trials was .87ulp. + * x < 0: + * Maximum observed error < 4ulp in 1,000,000 trials. + */ + +static double neg_gam(double); +static double small_gam(double); +static double smaller_gam(double); +static struct Double large_gam(double); +static struct Double ratfun_gam(double, double); + +/* + * Rational approximation, A0 + x*x*P(x)/Q(x), on the interval + * [1.066.., 2.066..] accurate to 4.25e-19. + */ +#define LEFT -.3955078125 /* left boundary for rat. approx */ +#define x0 .461632144968362356785 /* xmin - 1 */ + +#define a0_hi 0.88560319441088874992 +#define a0_lo -.00000000000000004996427036469019695 +#define P0 6.21389571821820863029017800727e-01 +#define P1 2.65757198651533466104979197553e-01 +#define P2 5.53859446429917461063308081748e-03 +#define P3 1.38456698304096573887145282811e-03 +#define P4 2.40659950032711365819348969808e-03 +#define Q0 1.45019531250000000000000000000e+00 +#define Q1 1.06258521948016171343454061571e+00 +#define Q2 -2.07474561943859936441469926649e-01 +#define Q3 -1.46734131782005422506287573015e-01 +#define Q4 3.07878176156175520361557573779e-02 +#define Q5 5.12449347980666221336054633184e-03 +#define Q6 -1.76012741431666995019222898833e-03 +#define Q7 9.35021023573788935372153030556e-05 +#define Q8 6.13275507472443958924745652239e-06 +/* + * Constants for large x approximation (x in [6, Inf]) + * (Accurate to 2.8*10^-19 absolute) + */ +#define lns2pi_hi 0.418945312500000 +#define lns2pi_lo -.000006779295327258219670263595 +#define Pa0 8.33333333333333148296162562474e-02 +#define Pa1 -2.77777777774548123579378966497e-03 +#define Pa2 7.93650778754435631476282786423e-04 +#define Pa3 -5.95235082566672847950717262222e-04 +#define Pa4 8.41428560346653702135821806252e-04 +#define Pa5 -1.89773526463879200348872089421e-03 +#define Pa6 5.69394463439411649408050664078e-03 +#define Pa7 -1.44705562421428915453880392761e-02 + +static const double zero = 0., one = 1.0, tiny = 1e-300; + +OLM_DLLEXPORT double +tgamma(x) + double x; +{ + struct Double u; + + if (isgreaterequal(x, 6)) { + if(x > 171.63) + return (x / zero); + u = large_gam(x); + return(__exp__D(u.a, u.b)); + } else if (isgreaterequal(x, 1.0 + LEFT + x0)) + return (small_gam(x)); + else if (isgreater(x, 1.e-17)) + return (smaller_gam(x)); + else if (isgreater(x, -1.e-17)) { + if (x != 0.0) + u.a = one - tiny; /* raise inexact */ + return (one/x); + } else if (!isfinite(x)) + return (x - x); /* x is NaN or -Inf */ + else + return (neg_gam(x)); +} +/* + * Accurate to max(ulp(1/128) absolute, 2^-66 relative) error. + */ +static struct Double +large_gam(x) + double x; +{ + double z, p; + struct Double t, u, v; + + z = one/(x*x); + p = Pa0+z*(Pa1+z*(Pa2+z*(Pa3+z*(Pa4+z*(Pa5+z*(Pa6+z*Pa7)))))); + p = p/x; + + u = __log__D(x); + u.a -= one; + v.a = (x -= .5); + TRUNC(v.a); + v.b = x - v.a; + t.a = v.a*u.a; /* t = (x-.5)*(log(x)-1) */ + t.b = v.b*u.a + x*u.b; + /* return t.a + t.b + lns2pi_hi + lns2pi_lo + p */ + t.b += lns2pi_lo; t.b += p; + u.a = lns2pi_hi + t.b; u.a += t.a; + u.b = t.a - u.a; + u.b += lns2pi_hi; u.b += t.b; + return (u); +} +/* + * Good to < 1 ulp. (provably .90 ulp; .87 ulp on 1,000,000 runs.) + * It also has correct monotonicity. + */ +static double +small_gam(x) + double x; +{ + double y, ym1, t; + struct Double yy, r; + y = x - one; + ym1 = y - one; + if (y <= 1.0 + (LEFT + x0)) { + yy = ratfun_gam(y - x0, 0); + return (yy.a + yy.b); + } + r.a = y; + TRUNC(r.a); + yy.a = r.a - one; + y = ym1; + yy.b = r.b = y - yy.a; + /* Argument reduction: G(x+1) = x*G(x) */ + for (ym1 = y-one; ym1 > LEFT + x0; y = ym1--, yy.a--) { + t = r.a*yy.a; + r.b = r.a*yy.b + y*r.b; + r.a = t; + TRUNC(r.a); + r.b += (t - r.a); + } + /* Return r*tgamma(y). */ + yy = ratfun_gam(y - x0, 0); + y = r.b*(yy.a + yy.b) + r.a*yy.b; + y += yy.a*r.a; + return (y); +} +/* + * Good on (0, 1+x0+LEFT]. Accurate to 1ulp. + */ +static double +smaller_gam(x) + double x; +{ + double t, d; + struct Double r, xx; + if (x < x0 + LEFT) { + t = x, TRUNC(t); + d = (t+x)*(x-t); + t *= t; + xx.a = (t + x), TRUNC(xx.a); + xx.b = x - xx.a; xx.b += t; xx.b += d; + t = (one-x0); t += x; + d = (one-x0); d -= t; d += x; + x = xx.a + xx.b; + } else { + xx.a = x, TRUNC(xx.a); + xx.b = x - xx.a; + t = x - x0; + d = (-x0 -t); d += x; + } + r = ratfun_gam(t, d); + d = r.a/x, TRUNC(d); + r.a -= d*xx.a; r.a -= d*xx.b; r.a += r.b; + return (d + r.a/x); +} +/* + * returns (z+c)^2 * P(z)/Q(z) + a0 + */ +static struct Double +ratfun_gam(z, c) + double z, c; +{ + double p, q; + struct Double r, t; + + q = Q0 +z*(Q1+z*(Q2+z*(Q3+z*(Q4+z*(Q5+z*(Q6+z*(Q7+z*Q8))))))); + p = P0 + z*(P1 + z*(P2 + z*(P3 + z*P4))); + + /* return r.a + r.b = a0 + (z+c)^2*p/q, with r.a truncated to 26 bits. */ + p = p/q; + t.a = z, TRUNC(t.a); /* t ~= z + c */ + t.b = (z - t.a) + c; + t.b *= (t.a + z); + q = (t.a *= t.a); /* t = (z+c)^2 */ + TRUNC(t.a); + t.b += (q - t.a); + r.a = p, TRUNC(r.a); /* r = P/Q */ + r.b = p - r.a; + t.b = t.b*p + t.a*r.b + a0_lo; + t.a *= r.a; /* t = (z+c)^2*(P/Q) */ + r.a = t.a + a0_hi, TRUNC(r.a); + r.b = ((a0_hi-r.a) + t.a) + t.b; + return (r); /* r = a0 + t */ +} + +static double +neg_gam(x) + double x; +{ + int sgn = 1; + struct Double lg, lsine; + double y, z; + + y = ceil(x); + if (y == x) /* Negative integer. */ + return ((x - x) / zero); + z = y - x; + if (z > 0.5) + z = one - z; + y = 0.5 * y; + if (y == ceil(y)) + sgn = -1; + if (z < .25) + z = sin(M_PI*z); + else + z = cos(M_PI*(0.5-z)); + /* Special case: G(1-x) = Inf; G(x) may be nonzero. */ + if (x < -170) { + if (x < -190) + return ((double)sgn*tiny*tiny); + y = one - x; /* exact: 128 < |x| < 255 */ + lg = large_gam(y); + lsine = __log__D(M_PI/z); /* = TRUNC(log(u)) + small */ + lg.a -= lsine.a; /* exact (opposite signs) */ + lg.b -= lsine.b; + y = -(lg.a + lg.b); + z = (y + lg.a) + lg.b; + y = __exp__D(y, z); + if (sgn < 0) y = -y; + return (y); + } + y = one-x; + if (one-y == x) + y = tgamma(y); + else /* 1-x is inexact */ + y = -x*tgamma(-x); + if (sgn < 0) y = -y; + return (M_PI / (y*z)); +} + +#if (LDBL_MANT_DIG == 53) +openlibm_weak_reference(tgamma, tgammal); +#endif diff --git a/src/openlibm/bsdsrc/b_tgamma.c.o b/src/openlibm/bsdsrc/b_tgamma.c.o new file mode 100644 index 0000000000000000000000000000000000000000..594b208a6d17ad9d70d6962e8337d6f4ea17da4c GIT binary patch literal 7568 zcmb<-^>JfjWMqH=Mg}_u1P><4z;Hnl!FB*M9T@l-_!vI%3&?`FY5W=&Ja&Ru|NsC0 z|A}9~7R3I`%D}+z!$a|u2j`(Q5B|JI9-Sd7FVbB2HLiSe z;g19n5Pw1S<{;^Pg`^jv&4WMh)h8GJn5&=o1!GhoHiF0!l^Y<-KsMBUXnX{*@`MNH z1(1~=JUU%eZh)*j2D0*Knj^o)flvGq$3O84y1)%_;TQ0MnZmCD3al%i_+yTw`S91B zKsNCcf5gEwAO5@(U{gOi^2hxA#26CmQyC;rI8pZH_$ed3S2`-wl| z#wY$5Xp{+nZHzd5IBfzro}1rjeBu}2g~V0l0dOpHeBzHg@rfT6gOLZ3V(uVP%uyg7 zcjyzpAd5;Gzs8{#5W59JR5(8I$B2S>h}4(Hukqp&e~d0j6znzua4ZX?@oRkg#4iw| zBJhbn@?sjl##2!ELm~k=v_Rp10~AsMpZH@wf8vjPjFifced3Qi`iVc{0?gh|{1GB5 z9?eHIK<@g)A945-f5eeb{4o#G_%+Ua;*U7}i9h1hVSf1*kaHMA9092%rEc4fRw-V4i{&^H1W4jVPs%{@yfJd;SSdLi9hZT z+`bpy|Nj363%>-}KLH$qu+S4xX*~dPHGiuq69WTC)hGU#Lm-<$_JR^J!zccjD{1`t zx6=4EPJQB!Im6%liy7o9!4MS#aHxXF5EX+oevOZa82H3501kan_=3~-g*1MRgYYm0 zrBP5i_uB|o*FXA+Kjsc7&_N0RSvlWJGZqF0a5#XR`N@$#@=O}P#$~W7 zNB+pmpsaBZ9K|4K)TkJIaslOM15kQC4ax=J?EDLEF^Z+2Y;gG#e*`EcoB&z)2oyI^ z4___sg(X^0th^BU{r`U&zs5yy%scW&o(4JQFo?JUieFF$d+GWQT=Ib<&Sv`v0G3? z>hJ&m;CT7O53(GTv_A0*h^VCT>s_c~<8RpuPM#p^V{WDK>x0XY zGEg>z78)_9)A%)RBK#^C0?L$vF`(=mc>7a(v4k1OFpbn_)I1Dp1M1>;_972#X3mju@ zHV|EiIBa_d_R9MM2*+w2{=^R|-y#pb4ElozhY%G7aE<_xJ}L?*@o)G)+c@e7L`x@afe@i`~|Ys0aPA=;{;Z+d;K45Yl>q+9epHA^{447py-) zz7zm+1zkXC73@GkA5emggD0sJuuO;w$7lXJaGD3z1E2U~Kt&9wy?u$JwTBZ#URazvAZhl`q|vx7+4q>7!(*77(fZe-7l1ZiGlF|NDO8$Bb3hx zHk^S$1WGej1u-yI2rx?XuyagcWMB|rU|^7e%7IE85L1GIfx!U8U|?Xd02%1PXTU7X z$j8CJzyOK}AE=xa8v_G_BcDJslLucw0vDfvBOiwwcM*i)%k2qaxN*mG@d>!{aky|p z^FHl8E`@k%wlCI z0MiIU2h3z;0Qnirgc62eniU*wU?!9>1JkSwps)iop@cPCtahzB!S z86v?CG=kU+X0kHe0MiHp+*M^@Ww?M40<-pmNmhmjU>ZRj z1v6P0z=brJ4Ixg0DOQFLU>ZSO1T$F~IH2ht%w=F;xDIBpGAN*l--U{!XR*gn@gHCs zL4aHH46FfCSs6UQG(;_k zwU;Nobh|J+8i+R{~(Ejn%gjO zA&>#k@E1ceM-E9GRHwt#Yaxk)>ROn%8Im|?$Pgy(gd`4%YnZqnlDIUIy-`Twpmq^V zeHxNDsD%v^uYih!+FqbG6HL4fDh{ILkj$S05`g*_IUHUgiOVCY|A!0nQ+H?b%gRDLjNgUM1f|(PGB#vwj8z_@AK-$kHNam|U z#X;sH$Cn|JII{a4k;IYJ$3w+I-at0L3n~sWUlYmRMM&aWNa98A%*F!Sr2a-5)xQT!YJE(f(a4?68gWL&f8^g@^ zgNlRPsgGoS4w5)>xRoG@BZos9R2*bJsErLXe;HI9-Td89agcgs_uPPrgVZCtpB+?K zL(>Ct{*{J`gVZCt-v=rVGT#WvU*S-3boHyD=^tG^C@+JGR*-rS2C+dHlx9FQNDPEw z{TSqW1SAe?r!eRhSLT)^CNbz0mlQ$h3>d2@H78N8B(i;8>bd)c>K2zICTBzW>3OAk1x5JS0 zQ#0bziV|}nodl4x$;P1Y096stAZ3bF^99N_&mP?-V}hej7jD;TdrvllGLz<}OdW&q_mkeTG_2c=bz{ZQw^ ztYO#ywLbtP2^VF6_e()`f`mZ>86YL-`WZlt3kFC(AEXY3Vc`d(L4A6Veo!8OsR7Xf zQ2n4h0OG?iNG*sBqeHQT2}s@^svpEg#xQ*_F;Ef$6+NJ|4HE;=4p9B*?t=Lnqy~gR z{Ya3R==uww`eE%MkXjH%*AMEiVoN^^pvD9P1H2y%N985o`4FWO`o82JsA5i-> yp!E@`?FRA-x_(eJqo*B^eg#lt4AlPzSpX7%Vl*xTNEtT$9#HqUL-oNZbo~G|cojYX literal 0 HcmV?d00001 diff --git a/src/openlibm/bsdsrc/mathimpl.h b/src/openlibm/bsdsrc/mathimpl.h new file mode 100644 index 0000000..983c4eb --- /dev/null +++ b/src/openlibm/bsdsrc/mathimpl.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)mathimpl.h 8.1 (Berkeley) 6/4/93 + * $FreeBSD: src/lib/msun/bsdsrc/mathimpl.h,v 1.7 2005/11/18 05:03:12 bde Exp $ + */ + +#ifndef _MATHIMPL_H_ +#define _MATHIMPL_H_ + +#include "cdefs-compat.h" +#include "math_private.h" + +/* + * TRUNC() is a macro that sets the trailing 27 bits in the mantissa of an + * IEEE double variable to zero. It must be expression-like for syntactic + * reasons, and we implement this expression using an inline function + * instead of a pure macro to avoid depending on the gcc feature of + * statement-expressions. + */ +#define TRUNC(d) (_b_trunc(&(d))) + +static __inline void +_b_trunc(volatile double *_dp) +{ + //VBS + //u_int32_t _lw; + u_int32_t _lw; + + GET_LOW_WORD(_lw, *_dp); + SET_LOW_WORD(*_dp, _lw & 0xf8000000); +} + +struct Double { + double a; + double b; +}; + +/* + * Functions internal to the math package, yet not static. + */ +double __exp__D(double, double); +struct Double __log__D(double); + +#endif /* !_MATHIMPL_H_ */ diff --git a/src/openlibm/docs/CNAME b/src/openlibm/docs/CNAME new file mode 100644 index 0000000..60f23f5 --- /dev/null +++ b/src/openlibm/docs/CNAME @@ -0,0 +1 @@ +openlibm.org \ No newline at end of file diff --git a/src/openlibm/docs/images/arrow-down.png b/src/openlibm/docs/images/arrow-down.png new file mode 100644 index 0000000000000000000000000000000000000000..5c55c6a8c9edfaa47379862d770304c36c3ac7ff GIT binary patch literal 216 zcmeAS@N?(olHy`uVBq!ia0y~yVBle3U=ZeDV_;xd^7YM11_p-to-U3d8WWQf99S70 z?liP9OB6Kz*l|OEak-aXLAnp@B)^ zAHxw|2OS2{;)Wzv4SR+TeTI*WY!WjJlW+B1Umy2p{o1uZ^))m;2x@$}fA1V$&(o(* z|2O}rtK0Yg{2aTV_5b(n-TzQ(x_)%kgX`zt|96x~Vd&}Q-Cz6p6@N@}c=~bfny!f- zUk0oHcbJF^NCD_Kw}M8!!zuvrV8qE9q)xNFihfaxM{Y3?bfHZ zCVP!iQd7m=-PBZCYWweo`<4 P0|SGntDnm{r-UW|P-vTT literal 0 HcmV?d00001 diff --git a/src/openlibm/docs/index.html b/src/openlibm/docs/index.html new file mode 100644 index 0000000..5c84d7e --- /dev/null +++ b/src/openlibm/docs/index.html @@ -0,0 +1,94 @@ + + + + + + OpenLibm + + + + + + + +
+
+

OpenLibm

+

A high quality system independent, portable, open source libm implementation

+ + + +

This project is maintained by the Julia Project

+ + +
+
+

+OpenLibm

+ +

OpenLibm is an effort to have a high quality, portable, standalone +C mathematical library (libm). +It can be used standalone in applications and programming language +implementations.

+ +

The project was born out of a need to have a good libm for the +Julia programming langage that worked +consistently across compilers and operating systems, and in 32-bit and +64-bit environments.

+ +

+History

+ +

The OpenLibm code derives from the FreeBSD +msun and OpenBSD +libm +implementations, which in turn derive from FDLIBM +5.3. Over and above that, OpenLibm itself has received a number of patches to make it platform independent and portable.

+ +

+Platform support

+ +

OpenLibm builds on Linux, macOS, Windows, FreeBSD, OpenBSD, NetBSD, and +DragonFly BSD. It builds with both GCC and clang. OpenLibm supports x86, amd64, +arm, aarch64, riscv64, ppc64le, mips, wasm32, s390(x), and loongarch64. + +

+Other relevant projects

+ +
    +
  1. MUSL The libm library in the musl-libc project
  2. +
  3. FDLIBM: Freely Distributable Math Library
  4. +
  5. FreeBSD msun: FreeBSD's math library
  6. +
  7. CRlibm: Correctly Rounded mathematical library
  8. +
  9. MUSL
  10. +
  11. CORE-MATH Project
  12. +
+ +

+Acknowledgements

+ +

PowerPC support for OpenLibm was graciously sponsored by IBM. + + +

+ +
+ + + + + + diff --git a/src/openlibm/docs/javascripts/scale.fix.js b/src/openlibm/docs/javascripts/scale.fix.js new file mode 100644 index 0000000..08716c0 --- /dev/null +++ b/src/openlibm/docs/javascripts/scale.fix.js @@ -0,0 +1,20 @@ +fixScale = function(doc) { + + var addEvent = 'addEventListener', + type = 'gesturestart', + qsa = 'querySelectorAll', + scales = [1, 1], + meta = qsa in doc ? doc[qsa]('meta[name=viewport]') : []; + + function fix() { + meta.content = 'width=device-width,minimum-scale=' + scales[0] + ',maximum-scale=' + scales[1]; + doc.removeEventListener(type, fix, true); + } + + if ((meta = meta[meta.length - 1]) && addEvent in doc) { + fix(); + scales = [.25, 1.6]; + doc[addEvent](type, fix, true); + } + +}; \ No newline at end of file diff --git a/src/openlibm/docs/params.json b/src/openlibm/docs/params.json new file mode 100644 index 0000000..cd0a5ed --- /dev/null +++ b/src/openlibm/docs/params.json @@ -0,0 +1 @@ +{"name":"OpenLibm","tagline":"A high quality system independent, portable, open source libm implementation","body":"## OpenLibm\r\n\r\n[OpenLibm](http://www.openlibm.org) is an effort to have a high quality, portable, standalone\r\nC mathematical library ([`libm`](http://en.wikipedia.org/wiki/libm)).\r\nIt can be used standalone in applications and programming language\r\nimplementations.\r\n\r\nThe project was born out of a need to have a good `libm` for the\r\n[Julia programming langage](http://www.julialang.org) that worked\r\nconsistently across compilers and operating systems, and in 32-bit and\r\n64-bit environments.\r\n\r\n### History\r\n\r\nThe OpenLibm code derives from the [FreeBSD\r\nmsun](http://svnweb.freebsd.org/base/head/lib/msun/) and [OpenBSD\r\nlibm](http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/lib/libm/src/)\r\nimplementations, which in turn derives from [FDLIBM\r\n5.3](http://www.netlib.org/fdlibm/). As a result, it includes a number\r\nof fixes and updates to FDLIBM that have accumulated over the years in\r\n`msun`, and optimized versions of many functions.\r\n\r\n### Platform support\r\n\r\nOpenLibm builds on Linux, Mac OS X, and Windows, and with little\r\neffort, should build on FreeBSD as well. It builds with both GCC and\r\nclang. Although largely tested on x86, it also includes experimental\r\nsupport for ARM. The original `msun` also includes support for mips,\r\nsparc64, powerpc, ia64, and alpha. These are present in the OpenLibm\r\nsource tree, but no attempt has been made to build any of these.\r\n\r\n### Build instructions\r\n\r\n1. `make` or `make USEGCC=1` to build with GCC. This is the default on\r\n Linux and Windows.\r\n2. `make USECLANG=1` to build with clang. This is the default on OS X.\r\n","google":"UA-28835595-4","note":"Don't delete this file! It's used internally to help with page regeneration."} \ No newline at end of file diff --git a/src/openlibm/docs/stylesheets/pygment_trac.css b/src/openlibm/docs/stylesheets/pygment_trac.css new file mode 100644 index 0000000..c6a6452 --- /dev/null +++ b/src/openlibm/docs/stylesheets/pygment_trac.css @@ -0,0 +1,69 @@ +.highlight { background: #ffffff; } +.highlight .c { color: #999988; font-style: italic } /* Comment */ +.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ +.highlight .k { font-weight: bold } /* Keyword */ +.highlight .o { font-weight: bold } /* Operator */ +.highlight .cm { color: #999988; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #999999; font-weight: bold } /* Comment.Preproc */ +.highlight .c1 { color: #999988; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */ +.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ +.highlight .gd .x { color: #000000; background-color: #ffaaaa } /* Generic.Deleted.Specific */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .gr { color: #aa0000 } /* Generic.Error */ +.highlight .gh { color: #999999 } /* Generic.Heading */ +.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ +.highlight .gi .x { color: #000000; background-color: #aaffaa } /* Generic.Inserted.Specific */ +.highlight .go { color: #888888 } /* Generic.Output */ +.highlight .gp { color: #555555 } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold; } /* Generic.Subheading */ +.highlight .gt { color: #aa0000 } /* Generic.Traceback */ +.highlight .kc { font-weight: bold } /* Keyword.Constant */ +.highlight .kd { font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { font-weight: bold } /* Keyword.Pseudo */ +.highlight .kr { font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #445588; font-weight: bold } /* Keyword.Type */ +.highlight .m { color: #009999 } /* Literal.Number */ +.highlight .s { color: #d14 } /* Literal.String */ +.highlight .na { color: #008080 } /* Name.Attribute */ +.highlight .nb { color: #0086B3 } /* Name.Builtin */ +.highlight .nc { color: #445588; font-weight: bold } /* Name.Class */ +.highlight .no { color: #008080 } /* Name.Constant */ +.highlight .ni { color: #800080 } /* Name.Entity */ +.highlight .ne { color: #990000; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #990000; font-weight: bold } /* Name.Function */ +.highlight .nn { color: #555555 } /* Name.Namespace */ +.highlight .nt { color: #000080 } /* Name.Tag */ +.highlight .nv { color: #008080 } /* Name.Variable */ +.highlight .ow { font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mf { color: #009999 } /* Literal.Number.Float */ +.highlight .mh { color: #009999 } /* Literal.Number.Hex */ +.highlight .mi { color: #009999 } /* Literal.Number.Integer */ +.highlight .mo { color: #009999 } /* Literal.Number.Oct */ +.highlight .sb { color: #d14 } /* Literal.String.Backtick */ +.highlight .sc { color: #d14 } /* Literal.String.Char */ +.highlight .sd { color: #d14 } /* Literal.String.Doc */ +.highlight .s2 { color: #d14 } /* Literal.String.Double */ +.highlight .se { color: #d14 } /* Literal.String.Escape */ +.highlight .sh { color: #d14 } /* Literal.String.Heredoc */ +.highlight .si { color: #d14 } /* Literal.String.Interpol */ +.highlight .sx { color: #d14 } /* Literal.String.Other */ +.highlight .sr { color: #009926 } /* Literal.String.Regex */ +.highlight .s1 { color: #d14 } /* Literal.String.Single */ +.highlight .ss { color: #990073 } /* Literal.String.Symbol */ +.highlight .bp { color: #999999 } /* Name.Builtin.Pseudo */ +.highlight .vc { color: #008080 } /* Name.Variable.Class */ +.highlight .vg { color: #008080 } /* Name.Variable.Global */ +.highlight .vi { color: #008080 } /* Name.Variable.Instance */ +.highlight .il { color: #009999 } /* Literal.Number.Integer.Long */ + +.type-csharp .highlight .k { color: #0000FF } +.type-csharp .highlight .kt { color: #0000FF } +.type-csharp .highlight .nf { color: #000000; font-weight: normal } +.type-csharp .highlight .nc { color: #2B91AF } +.type-csharp .highlight .nn { color: #000000 } +.type-csharp .highlight .s { color: #A31515 } +.type-csharp .highlight .sc { color: #A31515 } diff --git a/src/openlibm/docs/stylesheets/styles.css b/src/openlibm/docs/stylesheets/styles.css new file mode 100644 index 0000000..647f08d --- /dev/null +++ b/src/openlibm/docs/stylesheets/styles.css @@ -0,0 +1,423 @@ +@import url(https://fonts.googleapis.com/css?family=Arvo:400,700,400italic); + +/* MeyerWeb Reset */ + +html, body, div, span, applet, object, iframe, +h1, h2, h3, h4, h5, h6, p, blockquote, pre, +a, abbr, acronym, address, big, cite, code, +del, dfn, em, img, ins, kbd, q, s, samp, +small, strike, strong, sub, sup, tt, var, +b, u, i, center, +dl, dt, dd, ol, ul, li, +fieldset, form, label, legend, +table, caption, tbody, tfoot, thead, tr, th, td, +article, aside, canvas, details, embed, +figure, figcaption, footer, header, hgroup, +menu, nav, output, ruby, section, summary, +time, mark, audio, video { + margin: 0; + padding: 0; + border: 0; + font: inherit; + vertical-align: baseline; +} + + +/* Base text styles */ + +body { + padding:10px 50px 0 0; + font-family:"Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 14px; + color: #232323; + background-color: #FBFAF7; + margin: 0; + line-height: 1.8em; + -webkit-font-smoothing: antialiased; + +} + +h1, h2, h3, h4, h5, h6 { + color:#232323; + margin:36px 0 10px; +} + +p, ul, ol, table, dl { + margin:0 0 22px; +} + +h1, h2, h3 { + font-family: Arvo, Monaco, serif; + line-height:1.3; + font-weight: normal; +} + +h1,h2, h3 { + display: block; + border-bottom: 1px solid #ccc; + padding-bottom: 5px; +} + +h1 { + font-size: 30px; +} + +h2 { + font-size: 24px; +} + +h3 { + font-size: 18px; +} + +h4, h5, h6 { + font-family: Arvo, Monaco, serif; + font-weight: 700; +} + +a { + color:#C30000; + font-weight:200; + text-decoration:none; +} + +a:hover { + text-decoration: underline; +} + +a small { + font-size: 12px; +} + +em { + font-style: italic; +} + +strong { + font-weight:700; +} + +ul { + list-style-position: inside; + list-style: disc; + padding-left: 25px; +} + +ol { + list-style-position: inside; + list-style: decimal; + padding-left: 25px; +} + +blockquote { + margin: 0; + padding: 0 0 0 20px; + font-style: italic; +} + +dl, dt, dd, dl p { + font-color: #444; +} + +dl dt { + font-weight: bold; +} + +dl dd { + padding-left: 20px; + font-style: italic; +} + +dl p { + padding-left: 20px; + font-style: italic; +} + +hr { + border:0; + background:#ccc; + height:1px; + margin:0 0 24px; +} + +/* Images */ + +img { + position: relative; + margin: 0 auto; + max-width: 650px; + padding: 5px; + margin: 10px 0 32px 0; + border: 1px solid #ccc; +} + +p img { + display: inline; + margin: 0; + padding: 0; + vertical-align: middle; + text-align: center; + border: none; +} + +/* Code blocks */ + +code, pre { + font-family: Monaco, "Bitstream Vera Sans Mono", "Lucida Console", Terminal, monospace; + color:#000; + font-size:14px; +} + +pre { + padding: 4px 12px; + background: #FDFEFB; + border-radius:4px; + border:1px solid #D7D8C8; + overflow: auto; + overflow-y: hidden; + margin-bottom: 32px; +} + + +/* Tables */ + +table { + width:100%; +} + +table { + border: 1px solid #ccc; + margin-bottom: 32px; + text-align: left; + } + +th { + font-family: 'Arvo', Helvetica, Arial, sans-serif; + font-size: 18px; + font-weight: normal; + padding: 10px; + background: #232323; + color: #FDFEFB; + } + +td { + padding: 10px; + background: #ccc; + } + + +/* Wrapper */ +.wrapper { + width:960px; +} + + +/* Header */ + +header { + background-color: #171717; + color: #FDFDFB; + width:170px; + float:left; + position:fixed; + border: 1px solid #000; + -webkit-border-top-right-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + -moz-border-radius-topright: 4px; + -moz-border-radius-bottomright: 4px; + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; + padding: 34px 25px 22px 50px; + margin: 30px 25px 0 0; + -webkit-font-smoothing: antialiased; +} + +p.header { + font-size: 16px; +} + +h1.header { + font-family: Arvo, sans-serif; + font-size: 30px; + font-weight: 300; + line-height: 1.3em; + border-bottom: none; + margin-top: 0; +} + + +h1.header, a.header, a.name, header a{ + color: #fff; +} + +a.header { + text-decoration: underline; +} + +a.name { + white-space: nowrap; +} + +header ul { + list-style:none; + padding:0; +} + +header li { + list-style-type: none; + width:132px; + height:15px; + margin-bottom: 12px; + line-height: 1em; + padding: 6px 6px 6px 7px; + + background: #AF0011; + background: -moz-linear-gradient(top, #AF0011 0%, #820011 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f8f8f8), color-stop(100%,#dddddd)); + background: -webkit-linear-gradient(top, #AF0011 0%,#820011 100%); + background: -o-linear-gradient(top, #AF0011 0%,#820011 100%); + background: -ms-linear-gradient(top, #AF0011 0%,#820011 100%); + background: linear-gradient(top, #AF0011 0%,#820011 100%); + + border-radius:4px; + border:1px solid #0D0D0D; + + -webkit-box-shadow: inset 0px 1px 1px 0 rgba(233,2,38, 1); + box-shadow: inset 0px 1px 1px 0 rgba(233,2,38, 1); + +} + +header li:hover { + background: #C3001D; + background: -moz-linear-gradient(top, #C3001D 0%, #950119 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f8f8f8), color-stop(100%,#dddddd)); + background: -webkit-linear-gradient(top, #C3001D 0%,#950119 100%); + background: -o-linear-gradient(top, #C3001D 0%,#950119 100%); + background: -ms-linear-gradient(top, #C3001D 0%,#950119 100%); + background: linear-gradient(top, #C3001D 0%,#950119 100%); +} + +a.buttons { + -webkit-font-smoothing: antialiased; + background: url(../images/arrow-down.png) no-repeat; + font-weight: normal; + text-shadow: rgba(0, 0, 0, 0.4) 0 -1px 0; + padding: 2px 2px 2px 22px; + height: 30px; +} + +a.github { + background: url(../images/octocat-small.png) no-repeat 1px; +} + +a.buttons:hover { + color: #fff; + text-decoration: none; +} + + +/* Section - for main page content */ + +section { + width:650px; + float:right; + padding-bottom:50px; +} + + +/* Footer */ + +footer { + width:170px; + float:left; + position:fixed; + bottom:10px; + padding-left: 50px; +} + +@media print, screen and (max-width: 960px) { + + div.wrapper { + width:auto; + margin:0; + } + + header, section, footer { + float:none; + position:static; + width:auto; + } + + footer { + border-top: 1px solid #ccc; + margin:0 84px 0 50px; + padding:0; + } + + header { + padding-right:320px; + } + + section { + padding:20px 84px 20px 50px; + margin:0 0 20px; + } + + header a small { + display:inline; + } + + header ul { + position:absolute; + right:130px; + top:84px; + } +} + +@media print, screen and (max-width: 720px) { + body { + word-wrap:break-word; + } + + header { + padding:10px 20px 0; + margin-right: 0; + } + + section { + padding:10px 0 10px 20px; + margin:0 0 30px; + } + + footer { + margin: 0 0 0 30px; + } + + header ul, header p.view { + position:static; + } +} + +@media print, screen and (max-width: 480px) { + + header ul li.download { + display:none; + } + + footer { + margin: 0 0 0 20px; + } + + footer a{ + display:block; + } + +} + +@media print { + body { + padding:0.4in; + font-size:12pt; + color:#444; + } +} \ No newline at end of file diff --git a/src/openlibm/i387/Make.files b/src/openlibm/i387/Make.files new file mode 100644 index 0000000..369c541 --- /dev/null +++ b/src/openlibm/i387/Make.files @@ -0,0 +1,21 @@ +$(CUR_SRCS) = e_exp.S e_fmod.S e_log.S e_log10.S \ + e_remainder.S e_sqrt.S s_ceil.S s_copysign.S \ + s_floor.S s_llrint.S s_logb.S s_lrint.S \ + s_remquo.S s_rint.S s_tan.S s_trunc.S + +ifneq ($(OS), WINNT) +$(CUR_SRCS) += s_scalbn.S s_scalbnf.S s_scalbnl.S +endif + +# float counterparts +$(CUR_SRCS)+= e_log10f.S e_logf.S e_remainderf.S \ + e_sqrtf.S s_ceilf.S s_copysignf.S s_floorf.S \ + s_llrintf.S s_logbf.S s_lrintf.S \ + s_remquof.S s_rintf.S s_truncf.S + +# long double counterparts +$(CUR_SRCS)+= e_remainderl.S e_sqrtl.S s_ceill.S s_copysignl.S \ + s_floorl.S s_llrintl.S \ + s_logbl.S s_lrintl.S s_remquol.S s_rintl.S s_truncl.S + +$(CUR_SRCS)+= fenv.c diff --git a/src/openlibm/i387/bsd_asm.h b/src/openlibm/i387/bsd_asm.h new file mode 100644 index 0000000..93ac617 --- /dev/null +++ b/src/openlibm/i387/bsd_asm.h @@ -0,0 +1,118 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * William Jolitz. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * from: @(#)DEFS.h 5.1 (Berkeley) 4/23/90 + * $FreeBSD: src/sys/i386/include/asm.h,v 1.14 2007/08/22 04:26:07 jkoshy Exp $ + */ + +#ifndef _MACHINE_ASM_H_ +#define _MACHINE_ASM_H_ + +#if defined(__APPLE__) +#include "osx_asm.h" +#define CNAME(x) EXT(x) +#else +#include "cdefs-compat.h" + +#ifdef PIC +#define PIC_PROLOGUE \ + pushl %ebx; \ + call 1f; \ +1: \ + popl %ebx; \ + addl $_GLOBAL_OFFSET_TABLE_+[.-1b],%ebx +#define PIC_EPILOGUE \ + popl %ebx +#define PIC_PLT(x) x@PLT +#define PIC_GOT(x) x@GOT(%ebx) +#else +#define PIC_PROLOGUE +#define PIC_EPILOGUE +#define PIC_PLT(x) x +#define PIC_GOT(x) x +#endif + +/* + * CNAME and HIDENAME manage the relationship between symbol names in C + * and the equivalent assembly language names. CNAME is given a name as + * it would be used in a C program. It expands to the equivalent assembly + * language name. HIDENAME is given an assembly-language name, and expands + * to a possibly-modified form that will be invisible to C programs. + */ + + +/* XXX should use .p2align 4,0x90 for -m486. */ +#define _START_ENTRY .p2align 2,0x90 + +#if defined(__ELF__) +#define CNAME(csym) csym +#define HIDENAME(asmsym) .asmsym +#define _ENTRY(x) .text; _START_ENTRY; \ + .globl CNAME(x); .type CNAME(x),@function; CNAME(x): +#define END(x) .size x, . - x +#elif defined(_WIN32) +#ifndef _MSC_VER +#define END(x) .end +#define _START_ENTRY_WIN .text; _START_ENTRY +#else +#define END(x) end +#define _START_ENTRY_WIN .code; _START_ENTRY +#endif +#define CNAME(csym) _##csym +#define HIDENAME(asmsym) .asmsym +#define _ENTRY(x) _START_ENTRY_WIN; \ + .globl CNAME(x); .section .drectve; .ascii " -export:", #x; \ + .section .text; .def CNAME(x); .scl 2; .type 32; .endef; CNAME(x): +#endif + +#ifdef PROF +#define ALTENTRY(x) _ENTRY(x); \ + pushl %ebp; movl %esp,%ebp; \ + call PIC_PLT(HIDENAME(mcount)); \ + popl %ebp; \ + jmp 9f +#define ENTRY(x) _ENTRY(x); \ + pushl %ebp; movl %esp,%ebp; \ + call PIC_PLT(HIDENAME(mcount)); \ + popl %ebp; \ + 9: +#else +#define ALTENTRY(x) _ENTRY(x) +#define ENTRY(x) _ENTRY(x) +#endif + +#define RCSID(x) .text; .asciz x + +#undef __FBSDID +#define __FBSDID(s) /* nothing */ + +#endif +#endif /* !_MACHINE_ASM_H_ */ diff --git a/src/openlibm/i387/bsd_ieeefp.h b/src/openlibm/i387/bsd_ieeefp.h new file mode 100644 index 0000000..79c7bf3 --- /dev/null +++ b/src/openlibm/i387/bsd_ieeefp.h @@ -0,0 +1,265 @@ +/*- + * Copyright (c) 2003 Peter Wemm. + * Copyright (c) 1990 Andrew Moore, Talke Studio + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * from: @(#) ieeefp.h 1.0 (Berkeley) 9/23/93 + * $FreeBSD$ + */ + +#ifndef _MACHINE_IEEEFP_H_ +#define _MACHINE_IEEEFP_H_ + +/* + * Deprecated historical FPU control interface + * + * IEEE floating point type, constant and function definitions. + * XXX: FP*FLD and FP*OFF are undocumented pollution. + */ + +/* VBS + +#ifndef _SYS_CDEFS_H_ +#error this file needs sys/cdefs.h as a prerequisite +#endif + +*/ + +/* + * Rounding modes. + */ +typedef enum { + FP_RN=0, /* round to nearest */ + FP_RM, /* round down towards minus infinity */ + FP_RP, /* round up towards plus infinity */ + FP_RZ /* truncate */ +} fp_rnd_t; + +/* + * Precision (i.e., rounding precision) modes. + */ +typedef enum { + FP_PS=0, /* 24 bit (single-precision) */ + FP_PRS, /* reserved */ + FP_PD, /* 53 bit (double-precision) */ + FP_PE /* 64 bit (extended-precision) */ +} fp_prec_t; + +#define fp_except_t int + +/* + * Exception bit masks. + */ +#define FP_X_INV 0x01 /* invalid operation */ +#define FP_X_DNML 0x02 /* denormal */ +#define FP_X_DZ 0x04 /* zero divide */ +#define FP_X_OFL 0x08 /* overflow */ +#define FP_X_UFL 0x10 /* underflow */ +#define FP_X_IMP 0x20 /* (im)precision */ +#define FP_X_STK 0x40 /* stack fault */ + +/* + * FPU control word bit-field masks. + */ +#define FP_MSKS_FLD 0x3f /* exception masks field */ +#define FP_PRC_FLD 0x300 /* precision control field */ +#define FP_RND_FLD 0xc00 /* rounding control field */ + +/* + * FPU status word bit-field masks. + */ +#define FP_STKY_FLD 0x3f /* sticky flags field */ + +/* + * FPU control word bit-field offsets (shift counts). + */ +#define FP_MSKS_OFF 0 /* exception masks offset */ +#define FP_PRC_OFF 8 /* precision control offset */ +#define FP_RND_OFF 10 /* rounding control offset */ + +/* + * FPU status word bit-field offsets (shift counts). + */ +#define FP_STKY_OFF 0 /* sticky flags offset */ + +//VBS +//#ifdef __GNUCLIKE_ASM + +#define __fldcw(addr) __asm __volatile("fldcw %0" : : "m" (*(addr))) +#define __fldenv(addr) __asm __volatile("fldenv %0" : : "m" (*(addr))) +#define __fnclex() __asm __volatile("fnclex") +#define __fnstcw(addr) __asm __volatile("fnstcw %0" : "=m" (*(addr))) +#define __fnstenv(addr) __asm __volatile("fnstenv %0" : "=m" (*(addr))) +#define __fnstsw(addr) __asm __volatile("fnstsw %0" : "=m" (*(addr))) + +/* + * Load the control word. Be careful not to trap if there is a currently + * unmasked exception (ones that will become freshly unmasked are not a + * problem). This case must be handled by a save/restore of the + * environment or even of the full x87 state. Accessing the environment + * is very inefficient, so only do it when necessary. + */ +static __inline void +__fnldcw(unsigned short _cw, unsigned short _newcw) +{ + struct { + unsigned _cw; + unsigned _other[6]; + } _env; + unsigned short _sw; + + if ((_cw & FP_MSKS_FLD) != FP_MSKS_FLD) { + __fnstsw(&_sw); + if (((_sw & ~_cw) & FP_STKY_FLD) != 0) { + __fnstenv(&_env); + _env._cw = _newcw; + __fldenv(&_env); + return; + } + } + __fldcw(&_newcw); +} + +static __inline fp_rnd_t +fpgetround(void) +{ + unsigned short _cw; + + __fnstcw(&_cw); + return ((fp_rnd_t)((_cw & FP_RND_FLD) >> FP_RND_OFF)); +} + +static __inline fp_rnd_t +fpsetround(fp_rnd_t _m) +{ + fp_rnd_t _p; + unsigned short _cw, _newcw; + + __fnstcw(&_cw); + _p = (fp_rnd_t)((_cw & FP_RND_FLD) >> FP_RND_OFF); + _newcw = _cw & ~FP_RND_FLD; + _newcw |= (_m << FP_RND_OFF) & FP_RND_FLD; + __fnldcw(_cw, _newcw); + return (_p); +} + +//static __inline fp_prec_t +OLM_DLLEXPORT fp_prec_t +fpgetprec(void) +{ + unsigned short _cw; + + __fnstcw(&_cw); + return ((fp_prec_t)((_cw & FP_PRC_FLD) >> FP_PRC_OFF)); +} + +//static __inline fp_prec_t +OLM_DLLEXPORT fp_prec_t +fpsetprec(fp_prec_t _m) +{ + fp_prec_t _p; + unsigned short _cw, _newcw; + + __fnstcw(&_cw); + _p = (fp_prec_t)((_cw & FP_PRC_FLD) >> FP_PRC_OFF); + _newcw = _cw & ~FP_PRC_FLD; + _newcw |= (_m << FP_PRC_OFF) & FP_PRC_FLD; + __fnldcw(_cw, _newcw); + return (_p); +} + +/* + * Get or set the exception mask. + * Note that the x87 mask bits are inverted by the API -- a mask bit of 1 + * means disable for x87 and SSE, but for fp*mask() it means enable. + */ + +static __inline fp_except_t +fpgetmask(void) +{ + unsigned short _cw; + + __fnstcw(&_cw); + return ((~_cw & FP_MSKS_FLD) >> FP_MSKS_OFF); +} + +static __inline fp_except_t +fpsetmask(fp_except_t _m) +{ + fp_except_t _p; + unsigned short _cw, _newcw; + + __fnstcw(&_cw); + _p = (~_cw & FP_MSKS_FLD) >> FP_MSKS_OFF; + _newcw = _cw & ~FP_MSKS_FLD; + _newcw |= (~_m << FP_MSKS_OFF) & FP_MSKS_FLD; + __fnldcw(_cw, _newcw); + return (_p); +} + +static __inline fp_except_t +fpgetsticky(void) +{ + unsigned _ex; + unsigned short _sw; + + __fnstsw(&_sw); + _ex = (_sw & FP_STKY_FLD) >> FP_STKY_OFF; + return ((fp_except_t)_ex); +} + +static __inline fp_except_t +fpresetsticky(fp_except_t _m) +{ + struct { + unsigned _cw; + unsigned _sw; + unsigned _other[5]; + } _env; + fp_except_t _p; + + _m &= FP_STKY_FLD >> FP_STKY_OFF; + _p = fpgetsticky(); + if ((_p & ~_m) == _p) + return (_p); + if ((_p & ~_m) == 0) { + __fnclex(); + return (_p); + } + __fnstenv(&_env); + _env._sw &= ~_m; + __fldenv(&_env); + return (_p); +} + +//#endif /* __GNUCLIKE_ASM */ + +#endif /* !_MACHINE_IEEEFP_H_ */ diff --git a/src/openlibm/i387/bsd_npx.h b/src/openlibm/i387/bsd_npx.h new file mode 100644 index 0000000..78c5cbe --- /dev/null +++ b/src/openlibm/i387/bsd_npx.h @@ -0,0 +1,160 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * William Jolitz. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * from: @(#)npx.h 5.3 (Berkeley) 1/18/91 + * $FreeBSD: src/sys/i386/include/npx.h,v 1.29.2.1 2006/07/01 00:57:55 davidxu Exp $ + */ + +/* + * 287/387 NPX Coprocessor Data Structures and Constants + * W. Jolitz 1/90 + */ + +#ifndef _MACHINE_NPX_H_ +#define _MACHINE_NPX_H_ + +/* Environment information of floating point unit */ +struct env87 { + long en_cw; /* control word (16bits) */ + long en_sw; /* status word (16bits) */ + long en_tw; /* tag word (16bits) */ + long en_fip; /* floating point instruction pointer */ + unsigned short en_fcs; /* floating code segment selector */ + unsigned short en_opcode; /* opcode last executed (11 bits ) */ + long en_foo; /* floating operand offset */ + long en_fos; /* floating operand segment selector */ +}; + +/* Contents of each floating point accumulator */ +struct fpacc87 { +#ifdef dontdef /* too unportable */ + unsigned long fp_mantlo; /* mantissa low (31:0) */ + unsigned long fp_manthi; /* mantissa high (63:32) */ + int fp_exp:15; /* exponent */ + int fp_sgn:1; /* mantissa sign */ +#else + unsigned char fp_bytes[10]; +#endif +}; + +/* Floating point context */ +struct save87 { + struct env87 sv_env; /* floating point control/status */ + struct fpacc87 sv_ac[8]; /* accumulator contents, 0-7 */ + unsigned char sv_pad0[4]; /* padding for (now unused) saved status word */ + /* + * Bogus padding for emulators. Emulators should use their own + * struct and arrange to store into this struct (ending here) + * before it is inspected for ptracing or for core dumps. Some + * emulators overwrite the whole struct. We have no good way of + * knowing how much padding to leave. Leave just enough for the + * GPL emulator's i387_union (176 bytes total). + */ + unsigned char sv_pad[64]; /* padding; used by emulators */ +}; + +struct envxmm { + uint16_t en_cw; /* control word (16bits) */ + uint16_t en_sw; /* status word (16bits) */ + uint16_t en_tw; /* tag word (16bits) */ + uint16_t en_opcode; /* opcode last executed (11 bits ) */ + uint32_t en_fip; /* floating point instruction pointer */ + uint16_t en_fcs; /* floating code segment selector */ + uint16_t en_pad0; /* padding */ + uint32_t en_foo; /* floating operand offset */ + uint16_t en_fos; /* floating operand segment selector */ + uint16_t en_pad1; /* padding */ + uint32_t en_mxcsr; /* SSE sontorol/status register */ + uint32_t en_mxcsr_mask; /* valid bits in mxcsr */ +}; + +/* Contents of each SSE extended accumulator */ +struct xmmacc { + unsigned char xmm_bytes[16]; +}; + +struct savexmm { + struct envxmm sv_env; + struct { + struct fpacc87 fp_acc; + unsigned char fp_pad[6]; /* padding */ + } sv_fp[8]; + struct xmmacc sv_xmm[8]; + unsigned char sv_pad[224]; +} __attribute__((__aligned__(16))); + +union savefpu { + struct save87 sv_87; + struct savexmm sv_xmm; +}; + +/* + * The hardware default control word for i387's and later coprocessors is + * 0x37F, giving: + * + * round to nearest + * 64-bit precision + * all exceptions masked. + * + * We modify the affine mode bit and precision bits in this to give: + * + * affine mode for 287's (if they work at all) (1 in bitfield 1<<12) + * 53-bit precision (2 in bitfield 3<<8) + * + * 64-bit precision often gives bad results with high level languages + * because it makes the results of calculations depend on whether + * intermediate values are stored in memory or in FPU registers. + */ +#define __INITIAL_NPXCW__ 0x127F +#define __INITIAL_MXCSR__ 0x1F80 + +#ifdef _KERNEL + +#define IO_NPX 0x0F0 /* Numeric Coprocessor */ +#define IO_NPXSIZE 16 /* 80387/80487 NPX registers */ + +#define IRQ_NPX 13 + +/* full reset on some systems, NOP on others */ +#define npx_full_reset() outb(IO_NPX + 1, 0) + +int npxdna(void); +void npxdrop(void); +void npxexit(struct thread *td); +int npxformat(void); +int npxgetregs(struct thread *td, union savefpu *addr); +void npxinit(unsigned short control); +void npxsave(union savefpu *addr); +void npxsetregs(struct thread *td, union savefpu *addr); +int npxtrap(void); +#endif + +#endif /* !_MACHINE_NPX_H_ */ \ No newline at end of file diff --git a/src/openlibm/i387/e_exp.S b/src/openlibm/i387/e_exp.S new file mode 100644 index 0000000..0f03f9e --- /dev/null +++ b/src/openlibm/i387/e_exp.S @@ -0,0 +1,76 @@ +/* + * Written by: + * J.T. Conklin (jtc@netbsd.org) + * Public domain. + */ + +#include + +/* e^x = 2^(x * log2(e)) */ + +ENTRY(exp) + /* + * If x is +-Inf, then the subtraction would give Inf-Inf = NaN. + * Avoid this. Also avoid it if x is NaN for convenience. + */ + movl 8(%esp),%eax + andl $0x7fffffff,%eax + cmpl $0x7ff00000,%eax + jae x_Inf_or_NaN + + fldl 4(%esp) + + /* + * Extended precision is needed to reduce the maximum error from + * hundreds of ulps to less than 1 ulp. Switch to it if necessary. + * We may as well set the rounding mode to to-nearest and mask traps + * if we switch. + */ + fstcw 4(%esp) + movl 4(%esp),%eax + andl $0x0300,%eax + cmpl $0x0300,%eax /* RC == 0 && PC == 3? */ + je 1f /* jump if mode is good */ + movl $0x137f,8(%esp) + fldcw 8(%esp) +1: + fldl2e + fmulp /* x * log2(e) */ + fst %st(1) + frndint /* int(x * log2(e)) */ + fst %st(2) + fsubrp /* fract(x * log2(e)) */ + f2xm1 /* 2^(fract(x * log2(e))) - 1 */ + fld1 + faddp /* 2^(fract(x * log2(e))) */ + fscale /* e^x */ + fstp %st(1) + je 1f + fldcw 4(%esp) +1: + ret + +x_Inf_or_NaN: + /* + * Return 0 if x is -Inf. Otherwise just return x; when x is Inf + * this gives Inf, and when x is a NaN this gives the same result + * as (x + x) (x quieted). + */ + cmpl $0xfff00000,8(%esp) + jne x_not_minus_Inf + cmpl $0,4(%esp) + jne x_not_minus_Inf + fldz + ret + +x_not_minus_Inf: + fldl 4(%esp) + ret +END(exp) + + // + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/i387/e_fmod.S b/src/openlibm/i387/e_fmod.S new file mode 100644 index 0000000..44e52e5 --- /dev/null +++ b/src/openlibm/i387/e_fmod.S @@ -0,0 +1,25 @@ +/* + * Written by: + * J.T. Conklin (jtc@netbsd.org) + * Public domain. + */ + +#include +//__FBSDID("$FreeBSD: src/lib/msun/i387/e_fmod.S,v 1.11 2011/01/07 16:13:12 kib Exp $") + +ENTRY(fmod) + fldl 12(%esp) + fldl 4(%esp) +1: fprem + fstsw %ax + sahf + jp 1b + fstp %st(1) + ret +END(fmod) + + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/i387/e_log.S b/src/openlibm/i387/e_log.S new file mode 100644 index 0000000..ebd6ae7 --- /dev/null +++ b/src/openlibm/i387/e_log.S @@ -0,0 +1,21 @@ +/* + * Written by: + * J.T. Conklin (jtc@netbsd.org) + * Public domain. + */ + +#include +//__FBSDID("$FreeBSD: src/lib/msun/i387/e_log.S,v 1.10 2011/01/07 16:13:12 kib Exp $") + +ENTRY(log) + fldln2 + fldl 4(%esp) + fyl2x + ret +END(log) + + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/i387/e_log10.S b/src/openlibm/i387/e_log10.S new file mode 100644 index 0000000..b559a74 --- /dev/null +++ b/src/openlibm/i387/e_log10.S @@ -0,0 +1,21 @@ +/* + * Written by: + * J.T. Conklin (jtc@netbsd.org) + * Public domain. + */ + +#include +//__FBSDID("$FreeBSD: src/lib/msun/i387/e_log10.S,v 1.10 2011/01/07 16:13:12 kib Exp $") + +ENTRY(log10) + fldlg2 + fldl 4(%esp) + fyl2x + ret +END(log10) + + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/i387/e_log10f.S b/src/openlibm/i387/e_log10f.S new file mode 100644 index 0000000..afdf1b0 --- /dev/null +++ b/src/openlibm/i387/e_log10f.S @@ -0,0 +1,22 @@ +/* + * Written by J.T. Conklin . + * Public domain. + */ + +#include + +//__FBSDID("$FreeBSD: src/lib/msun/i387/e_log10f.S,v 1.4 2011/01/07 16:13:12 kib Exp $"); +/* RCSID("$NetBSD: e_log10f.S,v 1.1 1996/07/03 16:50:22 jtc Exp $") */ + +ENTRY(log10f) + fldlg2 + flds 4(%esp) + fyl2x + ret +END(log10f) + + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/i387/e_logf.S b/src/openlibm/i387/e_logf.S new file mode 100644 index 0000000..af06fd8 --- /dev/null +++ b/src/openlibm/i387/e_logf.S @@ -0,0 +1,21 @@ +/* + * Written by J.T. Conklin . + * Public domain. + */ + +#include + +//__FBSDID("$FreeBSD: src/lib/msun/i387/e_logf.S,v 1.3 2011/01/07 16:13:12 kib Exp $"); +/* RCSID("$NetBSD: e_logf.S,v 1.2 1996/07/06 00:15:45 jtc Exp $") */ + +ENTRY(logf) + fldln2 + flds 4(%esp) + fyl2x + ret + + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/i387/e_remainder.S b/src/openlibm/i387/e_remainder.S new file mode 100644 index 0000000..2aa3113 --- /dev/null +++ b/src/openlibm/i387/e_remainder.S @@ -0,0 +1,25 @@ +/* + * Written by: + * J.T. Conklin (jtc@netbsd.org) + * Public domain. + */ + +#include +//__FBSDID("$FreeBSD: src/lib/msun/i387/e_remainder.S,v 1.11 2011/01/07 16:13:12 kib Exp $") + +ENTRY(remainder) + fldl 12(%esp) + fldl 4(%esp) +1: fprem1 + fstsw %ax + sahf + jp 1b + fstp %st(1) + ret +END(remainder) + + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/i387/e_remainderf.S b/src/openlibm/i387/e_remainderf.S new file mode 100644 index 0000000..2b7b597 --- /dev/null +++ b/src/openlibm/i387/e_remainderf.S @@ -0,0 +1,26 @@ +/* + * Written by J.T. Conklin . + * Public domain. + */ + +#include + +//__FBSDID("$FreeBSD: src/lib/msun/i387/e_remainderf.S,v 1.4 2011/01/07 16:13:12 kib Exp $"); +/* RCSID("$NetBSD: e_remainderf.S,v 1.2 1995/05/08 23:49:47 jtc Exp $") */ + +ENTRY(remainderf) + flds 8(%esp) + flds 4(%esp) +1: fprem1 + fstsw %ax + sahf + jp 1b + fstp %st(1) + ret +END(remainderf) + + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/i387/e_remainderl.S b/src/openlibm/i387/e_remainderl.S new file mode 100644 index 0000000..04d460b --- /dev/null +++ b/src/openlibm/i387/e_remainderl.S @@ -0,0 +1,25 @@ +/* + * Written by: + * J.T. Conklin (jtc@netbsd.org) + * Public domain. + */ + +#include + +//__FBSDID("$FreeBSD: src/lib/msun/i387/e_remainderl.S,v 1.2 2011/01/07 16:13:12 kib Exp $") + +ENTRY(remainderl) + fldt 16(%esp) + fldt 4(%esp) +1: fprem1 + fstsw %ax + sahf + jp 1b + fstp %st(1) + ret + + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/i387/e_sqrt.S b/src/openlibm/i387/e_sqrt.S new file mode 100644 index 0000000..5cd45b0 --- /dev/null +++ b/src/openlibm/i387/e_sqrt.S @@ -0,0 +1,37 @@ +/* + * Written by: + * J.T. Conklin (jtc@netbsd.org) + * Public domain. + */ + +#include +//__FBSDID("$FreeBSD: src/lib/msun/i387/e_sqrt.S,v 1.10 2011/01/07 16:13:12 kib Exp $") + +ENTRY(sqrt) + pushl %ebp + movl %esp,%ebp + subl $8,%esp + + fstcw -4(%ebp) /* store fpu control word */ + movw -4(%ebp),%dx + andw $0xfeff,%dx /* Set precision field to 64 bits (53 bit mantissa). + We assume it's set to 0b11 (extended precision), + so zeroing out the low bit of the precision field, + will correctly set the precision */ + movw %dx,-8(%ebp) + fldcw -8(%ebp) /* load modfied control word */ + + fldl 8(%ebp) + fsqrt + + fldcw -4(%ebp) /* restore original control word */ + + leave + ret +END(sqrt) + + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/i387/e_sqrtf.S b/src/openlibm/i387/e_sqrtf.S new file mode 100644 index 0000000..05fb77f --- /dev/null +++ b/src/openlibm/i387/e_sqrtf.S @@ -0,0 +1,21 @@ +/* + * Written by J.T. Conklin . + * Public domain. + */ + +#include + +//__FBSDID("$FreeBSD: src/lib/msun/i387/e_sqrtf.S,v 1.4 2011/01/07 16:13:12 kib Exp $"); +/* RCSID("$NetBSD: e_sqrtf.S,v 1.2 1995/05/08 23:50:14 jtc Exp $") */ + +ENTRY(sqrtf) + flds 4(%esp) + fsqrt + ret +END(sqrtf) + + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/i387/e_sqrtl.S b/src/openlibm/i387/e_sqrtl.S new file mode 100644 index 0000000..5317f95 --- /dev/null +++ b/src/openlibm/i387/e_sqrtl.S @@ -0,0 +1,19 @@ +/* + * Written by: + * J.T. Conklin (jtc@netbsd.org) + * Public domain. + */ + +#include +//__FBSDID("$FreeBSD: src/lib/msun/i387/e_sqrtl.S,v 1.3 2011/01/07 16:13:12 kib Exp $") + +ENTRY(sqrtl) + fldt 4(%esp) + fsqrt + ret + + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/i387/fenv.c b/src/openlibm/i387/fenv.c new file mode 100644 index 0000000..6afe766 --- /dev/null +++ b/src/openlibm/i387/fenv.c @@ -0,0 +1,226 @@ +/*- + * Copyright (c) 2004-2005 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/msun/i387/fenv.c,v 1.8 2011/10/21 06:25:31 das Exp $ + */ + +#include "cdefs-compat.h" +#include "types-compat.h" +#include "math_private.h" +#include "i387/bsd_npx.h" + +#define __fenv_static +#include + +#ifdef __GNUC_GNU_INLINE__ +#error "This file must be compiled with C99 'inline' semantics" +#endif + +const fenv_t __fe_dfl_env = { + __INITIAL_NPXCW__, + 0x0000, + 0x0000, + 0x1f80, + 0xffffffff, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff } +}; + +enum __sse_support __has_sse = +#ifdef __SSE__ + __SSE_YES; +#else + __SSE_UNK; +#endif + +#define getfl(x) __asm __volatile("pushfl\n\tpopl %0" : "=mr" (*(x))) +#define setfl(x) __asm __volatile("pushl %0\n\tpopfl" : : "g" (x)) +#define cpuid_dx(x) __asm __volatile("pushl %%ebx\n\tmovl $1, %%eax\n\t" \ + "cpuid\n\tpopl %%ebx" \ + : "=d" (*(x)) : : "eax", "ecx") + +/* + * Test for SSE support on this processor. We need to do this because + * we need to use ldmxcsr/stmxcsr to get correct results if any part + * of the program was compiled to use SSE floating-point, but we can't + * use SSE on older processors. + */ +int +__test_sse(void) +{ + int flag, nflag; + int dx_features; + + /* Am I a 486? */ + getfl(&flag); + nflag = flag ^ 0x200000; + setfl(nflag); + getfl(&nflag); + if (flag != nflag) { + /* Not a 486, so CPUID should work. */ + cpuid_dx(&dx_features); + if (dx_features & 0x2000000) { + __has_sse = __SSE_YES; + return (1); + } + } + __has_sse = __SSE_NO; + return (0); +} + +extern inline OLM_DLLEXPORT int feclearexcept(int __excepts); +extern inline OLM_DLLEXPORT int fegetexceptflag(fexcept_t *__flagp, int __excepts); + +OLM_DLLEXPORT int +fesetexceptflag(const fexcept_t *flagp, int excepts) +{ + fenv_t env; + uint32_t mxcsr; + + __fnstenv(&env); + env.__status &= ~excepts; + env.__status |= *flagp & excepts; + __fldenv(env); + + if (__HAS_SSE()) { + __stmxcsr(&mxcsr); + mxcsr &= ~excepts; + mxcsr |= *flagp & excepts; + __ldmxcsr(mxcsr); + } + + return (0); +} + +OLM_DLLEXPORT int +feraiseexcept(int excepts) +{ + fexcept_t ex = excepts; + + fesetexceptflag(&ex, excepts); + __fwait(); + return (0); +} + +extern inline OLM_DLLEXPORT int fetestexcept(int __excepts); +extern inline OLM_DLLEXPORT int fegetround(void); +extern inline OLM_DLLEXPORT int fesetround(int __round); + +int +fegetenv(fenv_t *envp) +{ + uint32_t mxcsr; + + __fnstenv(envp); + /* + * fnstenv masks all exceptions, so we need to restore + * the old control word to avoid this side effect. + */ + __fldcw(envp->__control); + if (__HAS_SSE()) { + __stmxcsr(&mxcsr); + __set_mxcsr(*envp, mxcsr); + } + return (0); +} + +int +feholdexcept(fenv_t *envp) +{ + uint32_t mxcsr; + + __fnstenv(envp); + __fnclex(); + if (__HAS_SSE()) { + __stmxcsr(&mxcsr); + __set_mxcsr(*envp, mxcsr); + mxcsr &= ~FE_ALL_EXCEPT; + mxcsr |= FE_ALL_EXCEPT << _SSE_EMASK_SHIFT; + __ldmxcsr(mxcsr); + } + return (0); +} + +extern inline OLM_DLLEXPORT int fesetenv(const fenv_t *__envp); + +OLM_DLLEXPORT int +feupdateenv(const fenv_t *envp) +{ + uint32_t mxcsr; + uint16_t status; + + __fnstsw(&status); + if (__HAS_SSE()) + __stmxcsr(&mxcsr); + else + mxcsr = 0; + fesetenv(envp); + feraiseexcept((mxcsr | status) & FE_ALL_EXCEPT); + return (0); +} + +int +feenableexcept(int mask) +{ + uint32_t mxcsr, omask; + uint16_t control; + + mask &= FE_ALL_EXCEPT; + __fnstcw(&control); + if (__HAS_SSE()) + __stmxcsr(&mxcsr); + else + mxcsr = 0; + omask = ~(control | mxcsr >> _SSE_EMASK_SHIFT) & FE_ALL_EXCEPT; + control &= ~mask; + __fldcw(control); + if (__HAS_SSE()) { + mxcsr &= ~(mask << _SSE_EMASK_SHIFT); + __ldmxcsr(mxcsr); + } + return (omask); +} + +int +fedisableexcept(int mask) +{ + uint32_t mxcsr, omask; + uint16_t control; + + mask &= FE_ALL_EXCEPT; + __fnstcw(&control); + if (__HAS_SSE()) + __stmxcsr(&mxcsr); + else + mxcsr = 0; + omask = ~(control | mxcsr >> _SSE_EMASK_SHIFT) & FE_ALL_EXCEPT; + control |= mask; + __fldcw(control); + if (__HAS_SSE()) { + mxcsr |= mask << _SSE_EMASK_SHIFT; + __ldmxcsr(mxcsr); + } + return (omask); +} diff --git a/src/openlibm/i387/invtrig.c b/src/openlibm/i387/invtrig.c new file mode 100644 index 0000000..4afd832 --- /dev/null +++ b/src/openlibm/i387/invtrig.c @@ -0,0 +1,86 @@ +/*- + * Copyright (c) 2008 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +//__FBSDID("$FreeBSD: src/lib/msun/i387/invtrig.c,v 1.1 2008/08/02 03:56:22 das Exp $"); + +#include + +#define STRUCT_DECLS +#include "invtrig.h" + +/* + * asinl() and acosl() + */ +const LONGDOUBLE +pS0 = { 0xaaaaaaaaaaaaaaa8ULL, 0x3ffcU }, /* 1.66666666666666666631e-01L */ +pS1 = { 0xd5271b6699b48bfaULL, 0xbffdU }, /* -4.16313987993683104320e-01L */ +pS2 = { 0xbcf67ca9e9f669cfULL, 0x3ffdU }, /* 3.69068046323246813704e-01L */ +pS3 = { 0x8b7baa3d15f9830dULL, 0xbffcU }, /* -1.36213932016738603108e-01L */ +pS4 = { 0x92154b093a3bff1cULL, 0x3ff9U }, /* 1.78324189708471965733e-02L */ +pS5 = { 0xe5dd76401964508cULL, 0xbff2U }, /* -2.19216428382605211588e-04L */ +pS6 = { 0xee69c5b0fdb76951ULL, 0xbfedU }, /* -7.10526623669075243183e-06L */ +qS1 = { 0xbcaa2159c01436a0ULL, 0xc000U }, /* -2.94788392796209867269e+00L */ +qS2 = { 0xd17a73d1e1564c29ULL, 0x4000U }, /* 3.27309890266528636716e+00L */ +qS3 = { 0xd767e411c9cf4c2cULL, 0xbfffU }, /* -1.68285799854822427013e+00L */ +qS4 = { 0xc809c0dfb9b0d0b7ULL, 0x3ffdU }, /* 3.90699412641738801874e-01L */ +qS5 = { 0x80c3a2197c8ced57ULL, 0xbffaU }; /* -3.14365703596053263322e-02L */ + +/* + * atanl() + */ +const LONGDOUBLE atanhi[] = { + { 0xed63382b0dda7b45ULL, 0x3ffdU }, /* 4.63647609000806116202e-01L */ + { 0xc90fdaa22168c235ULL, 0x3ffeU }, /* 7.85398163397448309628e-01L */ + { 0xfb985e940fb4d900ULL, 0x3ffeU }, /* 9.82793723247329067960e-01L */ + { 0xc90fdaa22168c235ULL, 0x3fffU }, /* 1.57079632679489661926e+00L */ +}; + +const LONGDOUBLE atanlo[] = { + { 0xdfc88bd978751a07ULL, 0x3fbcU }, /* 1.18469937025062860669e-20L */ + { 0xece675d1fc8f8cbbULL, 0xbfbcU }, /* -1.25413940316708300586e-20L */ + { 0xf10f5e197793c283ULL, 0x3fbdU }, /* 2.55232234165405176172e-20L */ + { 0xece675d1fc8f8cbbULL, 0xbfbdU }, /* -2.50827880633416601173e-20L */ +}; + +const LONGDOUBLE aT[] = { + { 0xaaaaaaaaaaaaaa9fULL, 0x3ffdU }, /* 3.33333333333333333017e-01L */ + { 0xcccccccccccc62bcULL, 0xbffcU }, /* -1.99999999999999632011e-01L */ + { 0x9249249248b81e3fULL, 0x3ffcU }, /* 1.42857142857046531280e-01L */ + { 0xe38e38e3316f3de5ULL, 0xbffbU }, /* -1.11111111100562372733e-01L */ + { 0xba2e8b8dc280726aULL, 0x3ffbU }, /* 9.09090902935647302252e-02L */ + { 0x9d89d5b4c6847ec4ULL, 0xbffbU }, /* -7.69230552476207730353e-02L */ + { 0x8888461d3099c677ULL, 0x3ffbU }, /* 6.66661718042406260546e-02L */ + { 0xf0e8ee0f5328dc29ULL, 0xbffaU }, /* -5.88158892835030888692e-02L */ + { 0xd73ea84d24bae54aULL, 0x3ffaU }, /* 5.25499891539726639379e-02L */ + { 0xc08fa381dcd9213aULL, 0xbffaU }, /* -4.70119845393155721494e-02L */ + { 0xa54a26f4095f2a3aULL, 0x3ffaU }, /* 4.03539201366454414072e-02L */ + { 0xeea2d8d059ef3ad6ULL, 0xbff9U }, /* -2.91303858419364158725e-02L */ + { 0xcc82292ab894b051ULL, 0x3ff8U }, /* 1.24822046299269234080e-02L */ +}; + +const LONGDOUBLE +pi_lo = { 0xece675d1fc8f8cbbULL, 0xbfbeU }; /* -5.01655761266833202345e-20L */ diff --git a/src/openlibm/i387/osx_asm.h b/src/openlibm/i387/osx_asm.h new file mode 100644 index 0000000..284224c --- /dev/null +++ b/src/openlibm/i387/osx_asm.h @@ -0,0 +1,408 @@ +/* + * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ + +#ifndef _I386_ASM_H_ +#define _I386_ASM_H_ + +#ifdef _KERNEL +#include +#endif /* _KERNEL */ + +#ifdef MACH_KERNEL +#include +#else /* !MACH_KERNEL */ +#define MACH_KDB 0 +#endif /* !MACH_KERNEL */ + + +#if defined(MACH_KERNEL) || defined(_KERNEL) +#include +#endif /* MACH_KERNEL || _KERNEL */ + +#if defined(__i386__) + +#define S_PC (%esp) +#define S_ARG0 4(%esp) +#define S_ARG1 8(%esp) +#define S_ARG2 12(%esp) +#define S_ARG3 16(%esp) +#define S_ARG4 20(%esp) + +#define FRAME pushl %ebp; movl %esp, %ebp +#define EMARF leave + +#define B_LINK (%ebp) +#define B_PC 4(%ebp) +#define B_ARG0 8(%ebp) +#define B_ARG1 12(%ebp) +#define B_ARG2 16(%ebp) +#define B_ARG3 20(%ebp) + +#elif defined(__x86_64__) + +#define S_PC (%rsp) + +#define FRAME pushq %rbp; movq %rsp, %rbp +#define EMARF leave + +#define B_LINK (%rbp) +#define B_PC 8(%rbp) + +#else +#error unsupported architecture +#endif + +/* There is another definition of ALIGN for .c sources */ +#ifdef ASSEMBLER +#define ALIGN 4,0x90 +#endif /* ASSEMBLER */ + +#ifndef FALIGN +#define FALIGN ALIGN +#endif + +#define LB(x,n) n +#if __STDC__ +#ifndef __NO_UNDERSCORES__ +#define LCL(x) L ## x +#define EXT(x) _ ## x +#define LEXT(x) _ ## x ## : +#else +#define LCL(x) .L ## x +#define EXT(x) x +#define LEXT(x) x ## : +#endif +#define LBc(x,n) n ## : +#define LBb(x,n) n ## b +#define LBf(x,n) n ## f +#else /* __STDC__ */ +#ifndef __NO_UNDERSCORES__ +#define LCL(x) L/**/x +#define EXT(x) _/**/x +#define LEXT(x) _/**/x/**/: +#else /* __NO_UNDERSCORES__ */ +#define LCL(x) .L/**/x +#define EXT(x) x +#define LEXT(x) x/**/: +#endif /* __NO_UNDERSCORES__ */ +#define LBc(x,n) n/**/: +#define LBb(x,n) n/**/b +#define LBf(x,n) n/**/f +#endif /* __STDC__ */ + +#define SVC .byte 0x9a; .long 0; .word 0x7 + +#define RPC_SVC .byte 0x9a; .long 0; .word 0xf + +#define String .asciz +#define Value .word +#define Times(a,b) (a*b) +#define Divide(a,b) (a/b) + +#define INB inb %dx, %al +#define OUTB outb %al, %dx +#define INL inl %dx, %eax +#define OUTL outl %eax, %dx + +#define data16 .byte 0x66 +#define addr16 .byte 0x67 + +#if !GPROF +#define MCOUNT + +#elif defined(__SHARED__) +#define MCOUNT ; .data;\ + .align ALIGN;\ + LBc(x, 8) .long 0;\ + .text;\ + Gpush;\ + Gload;\ + leal Gotoff(LBb(x,8)),%edx;\ + Egaddr(%eax,_mcount_ptr);\ + Gpop;\ + call *(%eax); + +#else /* !GPROF, !__SHARED__ */ +#define MCOUNT ; call mcount; +#endif /* GPROF */ + +#ifdef __ELF__ +#define ELF_FUNC(x) .type x,@function +#define ELF_DATA(x) .type x,@object +#define ELF_SIZE(x,s) .size x,s +#else +#define ELF_FUNC(x) +#define ELF_DATA(x) +#define ELF_SIZE(x,s) +#endif + +#define Entry(x) .globl EXT(x); ELF_FUNC(EXT(x)); .align FALIGN; LEXT(x) +#define ENTRY(x) Entry(x) MCOUNT +#define ENTRY2(x,y) .globl EXT(x); .globl EXT(y); \ + ELF_FUNC(EXT(x)); ELF_FUNC(EXT(y)); \ + .align FALIGN; LEXT(x); LEXT(y) \ + MCOUNT +#if __STDC__ +#define ASENTRY(x) .globl x; .align FALIGN; x ## : ELF_FUNC(x) MCOUNT +#else +#define ASENTRY(x) .globl x; .align FALIGN; x: ELF_FUNC(x) MCOUNT +#endif /* __STDC__ */ + +#define DATA(x) .globl EXT(x); ELF_DATA(EXT(x)); .align ALIGN; LEXT(x) + +#define End(x) ELF_SIZE(x,.-x) +#define END(x) End(EXT(x)) +#define ENDDATA(x) END(x) +#define Enddata(x) End(x) + +/* + * ELF shared library accessor macros. + * Gpush saves the %ebx register used for the GOT address + * Gpop pops %ebx if we need a GOT + * Gload loads %ebx with the GOT address if shared libraries are used + * Gcall calls an external function. + * Gotoff allows you to reference local labels. + * Gotoff2 allows you to reference local labels with an index reg. + * Gotoff3 allows you to reference local labels with an index reg & size. + * Gaddr loads up a register with an address of an external item. + * Gstack is the number of bytes that Gpush pushes on the stack. + * + * Varients of the above with E or L prefixes do EXT(name) or LCL(name) + * respectively. + */ + +#ifndef __SHARED__ +#define Gpush +#define Gpop +#define Gload +#define Gcall(func) call func +#define Gotoff(lab) lab +#define Gotoff2(l,r) l(r) +#define Gotoff3(l,r,s) l(,r,s) +#define Gaddr(to,lab) movl $lab,to +#define Gcmp(lab,reg) cmpl $lab,reg +#define Gmemload(lab,reg) movl lab,reg +#define Gmemstore(reg,lab,tmp) movl reg,lab +#define Gstack 0 + +#else +#ifdef __ELF__ /* ELF shared libraries */ +#define Gpush pushl %ebx +#define Gpop popl %ebx +#define Gload call 9f; 9: popl %ebx; addl $_GLOBAL_OFFSET_TABLE_+[.-9b],%ebx +#define Gcall(func) call EXT(func)@PLT +#define Gotoff(lab) lab@GOTOFF(%ebx) +#define Gotoff2(l,r) l@GOTOFF(%ebx,r) +#define Gotoff3(l,r,s) l@GOTOFF(%ebx,r,s) +#define Gaddr(to,lab) movl lab@GOT(%ebx),to +#define Gcmp(lab,reg) cmpl reg,lab@GOT(%ebx) +#define Gmemload(lab,reg) movl lab@GOT(%ebx),reg; movl (reg),reg +#define Gmemstore(reg,lab,tmp) movl lab@GOT(%ebx),tmp; movl reg,(tmp) +#define Gstack 4 + +#else /* ROSE shared libraries */ +#define Gpush +#define Gpop +#define Gload +#define Gcall(func) call *9f; .data; .align ALIGN; 9: .long func; .text +#define Gotoff(lab) lab +#define Gotoff2(l,r) l(r) +#define Gotoff3(l,r,s) l(,r,s) +#define Gaddr(to,lab) movl 9f,to; .data; .align ALIGN; 9: .long lab; .text +#define Gcmp(lab,reg) cmpl reg,9f; .data; .align ALIGN; 9: .long lab; .text +#define Gmemload(lab,reg) movl 9f,reg; movl (reg),reg; .data; .align ALIGN; 9: .long lab; .text +#define Gmemstore(reg,lab,tmp) movl 9f,tmp; movl reg,(tmp); .data; .align ALIGN; 9: .long lab; .text +#define Gstack 0 +#endif /* __ELF__ */ +#endif /* __SHARED__ */ + +/* Egotoff is not provided, since external symbols should not use @GOTOFF + relocations. */ +#define Egcall(func) Gcall(EXT(func)) +#define Egaddr(to,lab) Gaddr(to,EXT(lab)) +#define Egcmp(lab,reg) Gcmp(EXT(lab),reg) +#define Egmemload(lab,reg) Gmemload(EXT(lab),reg) +#define Egmemstore(reg,lab,tmp) Gmemstore(reg,EXT(lab),tmp) + +#define Lgotoff(lab) Gotoff(LCL(lab)) +#define Lgotoff2(l,r) Gotoff2(LCL(l),r) +#define Lgotoff3(l,r,s) Gotoff3(LCL(l),r,s) +#define Lgcmp(lab,reg) Gcmp(LCL(lab),reg) +#define Lgmemload(lab,reg) movl Lgotoff(lab),reg +#define Lgmemstore(reg,lab,tmp) movl reg,Lgotoff(lab) + +#ifdef ASSEMBLER +#if MACH_KDB +#include +/* + * This pseudo-assembler line is added so that there will be at least + * one N_SO entry in the symbol stable to define the current file name. + */ +#endif /* MACH_KDB */ + +#else /* NOT ASSEMBLER */ + +/* These defines are here for .c files that wish to reference global symbols + * within __asm__ statements. + */ +#ifndef __NO_UNDERSCORES__ +#define CC_SYM_PREFIX "_" +#else +#define CC_SYM_PREFIX "" +#endif /* __NO_UNDERSCORES__ */ +#endif /* ASSEMBLER */ + +/* + * The following macros make calls into C code. + * They dynamically align the stack to 16 bytes. + */ +#if defined(__i386__) +/* + * Arguments are moved (not pushed) onto the correctly aligned stack. + * NOTE: ESI is destroyed in the process, and hence cannot + * be directly used as a parameter. Users of this macro must + * independently preserve ESI (a non-volatile) if the routine is + * intended to be called from C, for instance. + */ + +#define CCALL(fn) \ + movl %esp, %esi ;\ + andl $0xFFFFFFF0, %esp ;\ + call EXT(fn) ;\ + movl %esi, %esp + +#define CCALL1(fn, arg1) \ + movl %esp, %esi ;\ + subl $4, %esp ;\ + andl $0xFFFFFFF0, %esp ;\ + movl arg1, (%esp) ;\ + call EXT(fn) ;\ + movl %esi, %esp + +#define CCALL2(fn, arg1, arg2) \ + movl %esp, %esi ;\ + subl $8, %esp ;\ + andl $0xFFFFFFF0, %esp ;\ + movl arg2, 4(%esp) ;\ + movl arg1, (%esp) ;\ + call EXT(fn) ;\ + movl %esi, %esp + +/* This variant exists to permit adjustment of the stack by "dtrace" */ +#define CCALL1WITHSP(fn, arg1) \ + movl %esp, %esi ;\ + subl $12, %esp ;\ + andl $0xFFFFFFF0, %esp ;\ + movl %esi, 8(%esp) ;\ + leal 8(%esp), %esi ;\ + movl %esi, 4(%esp) ;\ + movl arg1, (%esp) ;\ + call EXT(fn) ;\ + movl 8(%esp), %esp + +/* + * CCALL5 is used for callee functions with 3 arguments but + * where arg2 (a3:a2) and arg3 (a5:a4) are 64-bit values. + */ +#define CCALL5(fn, a1, a2, a3, a4, a5) \ + movl %esp, %esi ;\ + subl $20, %esp ;\ + andl $0xFFFFFFF0, %esp ;\ + movl a5, 16(%esp) ;\ + movl a4, 12(%esp) ;\ + movl a3, 8(%esp) ;\ + movl a2, 4(%esp) ;\ + movl a1, (%esp) ;\ + call EXT(fn) ;\ + movl %esi, %esp + +#elif defined(__x86_64__) + +/* This variant exists to permit adjustment of the stack by "dtrace" */ +#define CCALLWITHSP(fn) \ + mov %rsp, %r12 ;\ + sub $8, %rsp ;\ + and $0xFFFFFFFFFFFFFFF0, %rsp ;\ + mov %r12, (%rsp) ;\ + leaq (%rsp), %rsi ;\ + call EXT(fn) ;\ + mov (%rsp), %rsp + +#define CCALL(fn) \ + mov %rsp, %r12 ;\ + and $0xFFFFFFFFFFFFFFF0, %rsp ;\ + call EXT(fn) ;\ + mov %r12, %rsp + +#define CCALL1(fn, arg1) \ + mov arg1, %rdi ;\ + CCALL(fn) + +#define CCALL2(fn, arg1, arg2) \ + mov arg1, %rdi ;\ + CCALL(fn) + +#define CCALL3(fn, arg1, arg2, arg3) \ + mov arg1, %rdi ;\ + mov arg2, %rsi ;\ + mov arg3, %rdx ;\ + CCALL(fn) + +#else +#error unsupported architecture +#endif + +#endif /* _I386_ASM_H_ */ diff --git a/src/openlibm/i387/s_ceil.S b/src/openlibm/i387/s_ceil.S new file mode 100644 index 0000000..80de70a --- /dev/null +++ b/src/openlibm/i387/s_ceil.S @@ -0,0 +1,34 @@ +/* + * Written by: + * J.T. Conklin (jtc@netbsd.org) + * Public domain. + */ + +#include + +ENTRY(ceil) + pushl %ebp + movl %esp,%ebp + subl $8,%esp + + fstcw -4(%ebp) /* store fpu control word */ + movw -4(%ebp),%dx + orw $0x0800,%dx /* round towards +oo */ + andw $0xfbff,%dx + movw %dx,-8(%ebp) + fldcw -8(%ebp) /* load modfied control word */ + + fldl 8(%ebp); /* round */ + frndint + + fldcw -4(%ebp) /* restore original control word */ + + leave + ret +END(ceil) + + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/i387/s_ceilf.S b/src/openlibm/i387/s_ceilf.S new file mode 100644 index 0000000..7ea898a --- /dev/null +++ b/src/openlibm/i387/s_ceilf.S @@ -0,0 +1,36 @@ +/* + * Written by J.T. Conklin . + * Public domain. + */ + +#include + +//__FBSDID("$FreeBSD: src/lib/msun/i387/s_ceilf.S,v 1.4 2011/01/07 16:13:12 kib Exp $"); +/* RCSID("$NetBSD: s_ceilf.S,v 1.3 1995/05/08 23:52:44 jtc Exp $") */ + +ENTRY(ceilf) + pushl %ebp + movl %esp,%ebp + subl $8,%esp + + fstcw -4(%ebp) /* store fpu control word */ + movw -4(%ebp),%dx + orw $0x0800,%dx /* round towards +oo */ + andw $0xfbff,%dx + movw %dx,-8(%ebp) + fldcw -8(%ebp) /* load modfied control word */ + + flds 8(%ebp); /* round */ + frndint + + fldcw -4(%ebp) /* restore original control word */ + + leave + ret +END(ceilf) + + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/i387/s_ceill.S b/src/openlibm/i387/s_ceill.S new file mode 100644 index 0000000..838edd1 --- /dev/null +++ b/src/openlibm/i387/s_ceill.S @@ -0,0 +1,34 @@ +/* + * Based on code written by J.T. Conklin . + * Public domain. + */ + +#include +//__FBSDID("$FreeBSD: src/lib/msun/i387/s_ceill.S,v 1.3 2011/01/07 16:13:12 kib Exp $") + +ENTRY(ceill) + pushl %ebp + movl %esp,%ebp + subl $8,%esp + + fstcw -4(%ebp) /* store fpu control word */ + movw -4(%ebp),%dx + orw $0x0800,%dx /* round towards +oo */ + andw $0xfbff,%dx + movw %dx,-8(%ebp) + fldcw -8(%ebp) /* load modfied control word */ + + fldt 8(%ebp) /* round */ + frndint + + fldcw -4(%ebp) /* restore original control word */ + + leave + ret +END(ceill) + + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/i387/s_copysign.S b/src/openlibm/i387/s_copysign.S new file mode 100644 index 0000000..4386747 --- /dev/null +++ b/src/openlibm/i387/s_copysign.S @@ -0,0 +1,25 @@ +/* + * Written by: + * J.T. Conklin (jtc@netbsd.org) + * Public domain. + */ + +#include +//__FBSDID("$FreeBSD: src/lib/msun/i387/s_copysign.S,v 1.9 2011/01/07 16:13:12 kib Exp $") + +ENTRY(copysign) + movl 16(%esp),%edx + andl $0x80000000,%edx + movl 8(%esp),%eax + andl $0x7fffffff,%eax + orl %edx,%eax + movl %eax,8(%esp) + fldl 4(%esp) + ret +END(copysign) + + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/i387/s_copysignf.S b/src/openlibm/i387/s_copysignf.S new file mode 100644 index 0000000..5d0169b --- /dev/null +++ b/src/openlibm/i387/s_copysignf.S @@ -0,0 +1,26 @@ +/* + * Written by J.T. Conklin . + * Public domain. + */ + +#include + +//__FBSDID("$FreeBSD: src/lib/msun/i387/s_copysignf.S,v 1.3 2011/01/07 16:13:12 kib Exp $"); +/* RCSID("$NetBSD: s_copysignf.S,v 1.3 1995/05/08 23:53:25 jtc Exp $") */ + +ENTRY(copysignf) + movl 8(%esp),%edx + andl $0x80000000,%edx + movl 4(%esp),%eax + andl $0x7fffffff,%eax + orl %edx,%eax + movl %eax,4(%esp) + flds 4(%esp) + ret +END(copysignf) + + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/i387/s_copysignl.S b/src/openlibm/i387/s_copysignl.S new file mode 100644 index 0000000..1a9a06a --- /dev/null +++ b/src/openlibm/i387/s_copysignl.S @@ -0,0 +1,24 @@ +/* + * Based on code written by J.T. Conklin . + * Public domain. + */ + +#include +//__FBSDID("$FreeBSD: src/lib/msun/i387/s_copysignl.S,v 1.3 2011/01/07 16:13:12 kib Exp $") + +ENTRY(copysignl) + movl 24(%esp),%edx + andl $0x8000,%edx + movl 12(%esp),%eax + andl $0x7fff,%eax + orl %edx,%eax + movl %eax,12(%esp) + fldt 4(%esp) + ret +END(copysignl) + + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/i387/s_cos.S b/src/openlibm/i387/s_cos.S new file mode 100644 index 0000000..4e29ec3 --- /dev/null +++ b/src/openlibm/i387/s_cos.S @@ -0,0 +1,33 @@ +/* + * Written by: + * J.T. Conklin (jtc@netbsd.org) + * Public domain. + */ + +#include +//__FBSDID("$FreeBSD: src/lib/msun/i387/s_cos.S,v 1.9 2011/01/07 16:13:12 kib Exp $") + +ENTRY(cos) + fldl 4(%esp) + fcos + fnstsw %ax + andw $0x400,%ax + jnz 1f + ret +1: fldpi + fadd %st(0) + fxch %st(1) +2: fprem1 + fnstsw %ax + andw $0x400,%ax + jnz 2b + fstp %st(1) + fcos + ret +END(cos) + + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/i387/s_floor.S b/src/openlibm/i387/s_floor.S new file mode 100644 index 0000000..13097eb --- /dev/null +++ b/src/openlibm/i387/s_floor.S @@ -0,0 +1,35 @@ +/* + * Written by: + * J.T. Conklin (jtc@netbsd.org) + * Public domain. + */ + +#include +//__FBSDID("$FreeBSD: src/lib/msun/i387/s_floor.S,v 1.10 2011/01/07 16:13:12 kib Exp $") + +ENTRY(floor) + pushl %ebp + movl %esp,%ebp + subl $8,%esp + + fstcw -4(%ebp) /* store fpu control word */ + movw -4(%ebp),%dx + orw $0x0400,%dx /* round towards -oo */ + andw $0xf7ff,%dx + movw %dx,-8(%ebp) + fldcw -8(%ebp) /* load modfied control word */ + + fldl 8(%ebp); /* round */ + frndint + + fldcw -4(%ebp) /* restore original control word */ + + leave + ret +END(floor) + + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/i387/s_floorf.S b/src/openlibm/i387/s_floorf.S new file mode 100644 index 0000000..c3a4e09 --- /dev/null +++ b/src/openlibm/i387/s_floorf.S @@ -0,0 +1,36 @@ +/* + * Written by J.T. Conklin . + * Public domain. + */ + +#include + +//__FBSDID("$FreeBSD: src/lib/msun/i387/s_floorf.S,v 1.4 2011/01/07 16:13:12 kib Exp $"); +/* RCSID("$NetBSD: s_floorf.S,v 1.3 1995/05/09 00:04:32 jtc Exp $") */ + +ENTRY(floorf) + pushl %ebp + movl %esp,%ebp + subl $8,%esp + + fstcw -4(%ebp) /* store fpu control word */ + movw -4(%ebp),%dx + orw $0x0400,%dx /* round towards -oo */ + andw $0xf7ff,%dx + movw %dx,-8(%ebp) + fldcw -8(%ebp) /* load modfied control word */ + + flds 8(%ebp); /* round */ + frndint + + fldcw -4(%ebp) /* restore original control word */ + + leave + ret +END(floorf) + + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/i387/s_floorl.S b/src/openlibm/i387/s_floorl.S new file mode 100644 index 0000000..949116f --- /dev/null +++ b/src/openlibm/i387/s_floorl.S @@ -0,0 +1,34 @@ +/* + * Based on code written by J.T. Conklin . + * Public domain. + */ + +#include +//__FBSDID("$FreeBSD: src/lib/msun/i387/s_floorl.S,v 1.3 2011/01/07 16:13:12 kib Exp $") + +ENTRY(floorl) + pushl %ebp + movl %esp,%ebp + subl $8,%esp + + fstcw -4(%ebp) /* store fpu control word */ + movw -4(%ebp),%dx + orw $0x0400,%dx /* round towards -oo */ + andw $0xf7ff,%dx + movw %dx,-8(%ebp) + fldcw -8(%ebp) /* load modfied control word */ + + fldt 8(%ebp) /* round */ + frndint + + fldcw -4(%ebp) /* restore original control word */ + + leave + ret +END(floorl) + + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/i387/s_llrint.S b/src/openlibm/i387/s_llrint.S new file mode 100644 index 0000000..97c292e --- /dev/null +++ b/src/openlibm/i387/s_llrint.S @@ -0,0 +1,43 @@ +/*- + * Copyright (c) 2005 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +//__FBSDID("$FreeBSD: src/lib/msun/i387/s_llrint.S,v 1.3 2011/01/07 16:13:12 kib Exp $"); + +ENTRY(llrint) + fldl 4(%esp) + subl $8,%esp + fistpll (%esp) + popl %eax + popl %edx + ret +END(llrint) + + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/i387/s_llrintf.S b/src/openlibm/i387/s_llrintf.S new file mode 100644 index 0000000..447e77a --- /dev/null +++ b/src/openlibm/i387/s_llrintf.S @@ -0,0 +1,43 @@ +/*- + * Copyright (c) 2005 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +//__FBSDID("$FreeBSD: src/lib/msun/i387/s_llrintf.S,v 1.3 2011/01/07 16:13:12 kib Exp $") + +ENTRY(llrintf) + flds 4(%esp) + subl $8,%esp + fistpll (%esp) + popl %eax + popl %edx + ret +END(llrintf) + + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/i387/s_llrintl.S b/src/openlibm/i387/s_llrintl.S new file mode 100644 index 0000000..ad6a7c9 --- /dev/null +++ b/src/openlibm/i387/s_llrintl.S @@ -0,0 +1,42 @@ +/*- + * Copyright (c) 2005 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +//__FBSDID("$FreeBSD: src/lib/msun/i387/s_llrintl.S,v 1.2 2011/01/07 16:13:12 kib Exp $"); + +ENTRY(llrintl) + fldt 4(%esp) + subl $8,%esp + fistpll (%esp) + popl %eax + popl %edx + ret + + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/i387/s_logb.S b/src/openlibm/i387/s_logb.S new file mode 100644 index 0000000..d0fc5d6 --- /dev/null +++ b/src/openlibm/i387/s_logb.S @@ -0,0 +1,21 @@ +/* + * Written by: + * J.T. Conklin (jtc@netbsd.org) + * Public domain. + */ + +#include +//__FBSDID("$FreeBSD: src/lib/msun/i387/s_logb.S,v 1.10 2011/01/07 16:13:12 kib Exp $") + +ENTRY(logb) + fldl 4(%esp) + fxtract + fstp %st + ret +END(logb) + + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/i387/s_logbf.S b/src/openlibm/i387/s_logbf.S new file mode 100644 index 0000000..3e3568c --- /dev/null +++ b/src/openlibm/i387/s_logbf.S @@ -0,0 +1,22 @@ +/* + * Written by J.T. Conklin . + * Public domain. + */ + +#include + +//__FBSDID("$FreeBSD: src/lib/msun/i387/s_logbf.S,v 1.3 2011/01/07 16:13:12 kib Exp $"); +/* RCSID("$NetBSD: s_logbf.S,v 1.3 1995/05/09 00:15:12 jtc Exp $") */ + +ENTRY(logbf) + flds 4(%esp) + fxtract + fstp %st + ret +END(logbf) + + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/i387/s_logbl.S b/src/openlibm/i387/s_logbl.S new file mode 100644 index 0000000..6d2de64 --- /dev/null +++ b/src/openlibm/i387/s_logbl.S @@ -0,0 +1,20 @@ +/* + * Written by: + * J.T. Conklin (jtc@netbsd.org) + * Public domain. + */ + +#include +//__FBSDID("$FreeBSD: src/lib/msun/i387/s_logbl.S,v 1.3 2011/01/07 16:13:12 kib Exp $") + +ENTRY(logbl) + fldt 4(%esp) + fxtract + fstp %st + ret + + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/i387/s_lrint.S b/src/openlibm/i387/s_lrint.S new file mode 100644 index 0000000..1e12539 --- /dev/null +++ b/src/openlibm/i387/s_lrint.S @@ -0,0 +1,42 @@ +/*- + * Copyright (c) 2005 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +//__FBSDID("$FreeBSD: src/lib/msun/i387/s_lrint.S,v 1.3 2011/01/07 16:13:12 kib Exp $"); + +ENTRY(lrint) + fldl 4(%esp) + subl $4,%esp + fistpl (%esp) + popl %eax + ret +END(lrint) + + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/i387/s_lrintf.S b/src/openlibm/i387/s_lrintf.S new file mode 100644 index 0000000..b588c1a --- /dev/null +++ b/src/openlibm/i387/s_lrintf.S @@ -0,0 +1,42 @@ +/*- + * Copyright (c) 2005 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +//__FBSDID("$FreeBSD: src/lib/msun/i387/s_lrintf.S,v 1.3 2011/01/07 16:13:12 kib Exp $") + +ENTRY(lrintf) + flds 4(%esp) + subl $4,%esp + fistpl (%esp) + popl %eax + ret +END(lrintf) + + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/i387/s_lrintl.S b/src/openlibm/i387/s_lrintl.S new file mode 100644 index 0000000..94cc6cb --- /dev/null +++ b/src/openlibm/i387/s_lrintl.S @@ -0,0 +1,41 @@ +/*- + * Copyright (c) 2008 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +//__FBSDID("$FreeBSD: src/lib/msun/i387/s_lrintl.S,v 1.2 2011/01/07 16:13:12 kib Exp $"); + +ENTRY(lrintl) + fldt 4(%esp) + subl $4,%esp + fistpl (%esp) + popl %eax + ret + + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/i387/s_remquo.S b/src/openlibm/i387/s_remquo.S new file mode 100644 index 0000000..78a588d --- /dev/null +++ b/src/openlibm/i387/s_remquo.S @@ -0,0 +1,69 @@ +/*- + * Copyright (c) 2005 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Based on public-domain remainder routine by J.T. Conklin . + */ + +#include +//__FBSDID("$FreeBSD: src/lib/msun/i387/s_remquo.S,v 1.3 2011/01/07 16:13:12 kib Exp $"); + +ENTRY(remquo) + fldl 12(%esp) + fldl 4(%esp) +1: fprem1 + fstsw %ax + sahf + jp 1b + fstp %st(1) +/* Extract the three low-order bits of the quotient from C0,C3,C1. */ + shrl $6,%eax + movl %eax,%ecx + andl $0x108,%eax + rorl $7,%eax + orl %eax,%ecx + roll $4,%eax + orl %ecx,%eax + andl $7,%eax +/* Negate the quotient bits if x*y<0. Avoid using an unpredictable branch. */ + movl 16(%esp),%ecx + xorl 8(%esp),%ecx + sarl $16,%ecx + sarl $16,%ecx + xorl %ecx,%eax + andl $1,%ecx + addl %ecx,%eax +/* Store the quotient and return. */ + movl 20(%esp),%ecx + movl %eax,(%ecx) + ret +END(remquo) + + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/i387/s_remquof.S b/src/openlibm/i387/s_remquof.S new file mode 100644 index 0000000..8f532c3 --- /dev/null +++ b/src/openlibm/i387/s_remquof.S @@ -0,0 +1,69 @@ +/*- + * Copyright (c) 2005 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Based on public-domain remainder routine by J.T. Conklin . + */ + +#include +//__FBSDID("$FreeBSD: src/lib/msun/i387/s_remquof.S,v 1.3 2011/01/07 16:13:12 kib Exp $"); + +ENTRY(remquof) + flds 8(%esp) + flds 4(%esp) +1: fprem1 + fstsw %ax + sahf + jp 1b + fstp %st(1) +/* Extract the three low-order bits of the quotient from C0,C3,C1. */ + shrl $6,%eax + movl %eax,%ecx + andl $0x108,%eax + rorl $7,%eax + orl %eax,%ecx + roll $4,%eax + orl %ecx,%eax + andl $7,%eax +/* Negate the quotient bits if x*y<0. Avoid using an unpredictable branch. */ + movl 8(%esp),%ecx + xorl 4(%esp),%ecx + sarl $16,%ecx + sarl $16,%ecx + xorl %ecx,%eax + andl $1,%ecx + addl %ecx,%eax +/* Store the quotient and return. */ + movl 12(%esp),%ecx + movl %eax,(%ecx) + ret +END(remquof) + + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/i387/s_remquol.S b/src/openlibm/i387/s_remquol.S new file mode 100644 index 0000000..b89563c --- /dev/null +++ b/src/openlibm/i387/s_remquol.S @@ -0,0 +1,69 @@ +/*- + * Copyright (c) 2005-2008 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Based on public-domain remainder routine by J.T. Conklin . + */ + +#include +//__FBSDID("$FreeBSD: src/lib/msun/i387/s_remquol.S,v 1.2 2011/01/07 16:13:12 kib Exp $"); + +ENTRY(remquol) + fldt 16(%esp) + fldt 4(%esp) +1: fprem1 + fstsw %ax + sahf + jp 1b + fstp %st(1) +/* Extract the three low-order bits of the quotient from C0,C3,C1. */ + shrl $6,%eax + movl %eax,%ecx + andl $0x108,%eax + rorl $7,%eax + orl %eax,%ecx + roll $4,%eax + orl %ecx,%eax + andl $7,%eax +/* Negate the quotient bits if x*y<0. Avoid using an unpredictable branch. */ + movl 24(%esp),%ecx + xorl 12(%esp),%ecx + movsx %cx,%ecx + sarl $16,%ecx + sarl $16,%ecx + xorl %ecx,%eax + andl $1,%ecx + addl %ecx,%eax +/* Store the quotient and return. */ + movl 28(%esp),%ecx + movl %eax,(%ecx) + ret + + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/i387/s_rint.S b/src/openlibm/i387/s_rint.S new file mode 100644 index 0000000..a8109cd --- /dev/null +++ b/src/openlibm/i387/s_rint.S @@ -0,0 +1,20 @@ +/* + * Written by: + * J.T. Conklin (jtc@netbsd.org) + * Public domain. + */ + +#include +//__FBSDID("$FreeBSD: src/lib/msun/i387/s_rint.S,v 1.9 2011/01/07 16:13:12 kib Exp $") + +ENTRY(rint) + fldl 4(%esp) + frndint + ret +END(rint) + + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/i387/s_rintf.S b/src/openlibm/i387/s_rintf.S new file mode 100644 index 0000000..184a16f --- /dev/null +++ b/src/openlibm/i387/s_rintf.S @@ -0,0 +1,21 @@ +/* + * Written by J.T. Conklin . + * Public domain. + */ + +#include + +//__FBSDID("$FreeBSD: src/lib/msun/i387/s_rintf.S,v 1.3 2011/01/07 16:13:12 kib Exp $"); +/* RCSID("$NetBSD: s_rintf.S,v 1.3 1995/05/09 00:17:22 jtc Exp $") */ + +ENTRY(rintf) + flds 4(%esp) + frndint + ret +END(rintf) + + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/i387/s_rintl.S b/src/openlibm/i387/s_rintl.S new file mode 100644 index 0000000..8727322 --- /dev/null +++ b/src/openlibm/i387/s_rintl.S @@ -0,0 +1,19 @@ +/* + * Written by: + * J.T. Conklin (jtc@netbsd.org) + * Public domain. + */ + +#include +//__FBSDID("$FreeBSD: src/lib/msun/i387/s_rintl.S,v 1.3 2011/01/07 16:13:12 kib Exp $") + +ENTRY(rintl) + fldt 4(%esp) + frndint + ret + + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/i387/s_scalbn.S b/src/openlibm/i387/s_scalbn.S new file mode 100644 index 0000000..d690ff1 --- /dev/null +++ b/src/openlibm/i387/s_scalbn.S @@ -0,0 +1,23 @@ +/* + * Written by: + * J.T. Conklin (jtc@netbsd.org) + * Public domain. + */ + +#include +//__FBSDID("$FreeBSD: src/lib/msun/i387/s_scalbn.S,v 1.10 2011/01/07 16:13:12 kib Exp $") + +ENTRY(scalbn) + fildl 12(%esp) + fldl 4(%esp) + fscale + fstp %st(1) + ret +END(scalbn) + +.globl CNAME(ldexp) +.set CNAME(ldexp),CNAME(scalbn) +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/i387/s_scalbnf.S b/src/openlibm/i387/s_scalbnf.S new file mode 100644 index 0000000..7f4a2bc --- /dev/null +++ b/src/openlibm/i387/s_scalbnf.S @@ -0,0 +1,26 @@ +/* + * Written by J.T. Conklin . + * Public domain. + */ + +#include + +//__FBSDID("$FreeBSD: src/lib/msun/i387/s_scalbnf.S,v 1.4 2011/01/07 16:13:12 kib Exp $"); +/* RCSID("$NetBSD: s_scalbnf.S,v 1.4 1999/01/02 05:15:40 kristerw Exp $") */ + +ENTRY(scalbnf) + fildl 8(%esp) + flds 4(%esp) + fscale + fstp %st(1) /* bug fix for fp stack overflow */ + ret +END(scalbnf) + +.globl CNAME(ldexpf) +.set CNAME(ldexpf),CNAME(scalbnf) + + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/i387/s_scalbnl.S b/src/openlibm/i387/s_scalbnl.S new file mode 100644 index 0000000..5d359eb --- /dev/null +++ b/src/openlibm/i387/s_scalbnl.S @@ -0,0 +1,26 @@ +/* + * Written by J.T. Conklin . + * Public domain. + */ + +#include + +//__FBSDID("$FreeBSD: src/lib/msun/i387/s_scalbnl.S,v 1.3 2011/01/07 16:13:12 kib Exp $"); +/* RCSID("$NetBSD: s_scalbnf.S,v 1.4 1999/01/02 05:15:40 kristerw Exp $") */ + +ENTRY(scalbnl) + fildl 16(%esp) + fldt 4(%esp) + fscale + fstp %st(1) + ret +END(scalbnl) + +.globl CNAME(ldexpl) +.set CNAME(ldexpl),CNAME(scalbnl) + + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/i387/s_sin.S b/src/openlibm/i387/s_sin.S new file mode 100644 index 0000000..6b71455 --- /dev/null +++ b/src/openlibm/i387/s_sin.S @@ -0,0 +1,33 @@ +/* + * Written by: + * J.T. Conklin (jtc@netbsd.org) + * Public domain. + */ + +#include +//__FBSDID("$FreeBSD: src/lib/msun/i387/s_sin.S,v 1.9 2011/01/07 16:13:12 kib Exp $") + +ENTRY(sin) + fldl 4(%esp) + fsin + fnstsw %ax + andw $0x400,%ax + jnz 1f + ret +1: fldpi + fadd %st(0) + fxch %st(1) +2: fprem1 + fnstsw %ax + andw $0x400,%ax + jnz 2b + fstp %st(1) + fsin + ret +END(sin) + + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/i387/s_tan.S b/src/openlibm/i387/s_tan.S new file mode 100644 index 0000000..7b25c3a --- /dev/null +++ b/src/openlibm/i387/s_tan.S @@ -0,0 +1,35 @@ +/* + * Written by: + * J.T. Conklin (jtc@netbsd.org) + * Public domain. + */ + +#include +//__FBSDID("$FreeBSD: src/lib/msun/i387/s_tan.S,v 1.9 2011/01/07 16:13:12 kib Exp $") + +ENTRY(tan) + fldl 4(%esp) + fptan + fnstsw %ax + andw $0x400,%ax + jnz 1f + fstp %st(0) + ret +1: fldpi + fadd %st(0) + fxch %st(1) +2: fprem1 + fstsw %ax + andw $0x400,%ax + jnz 2b + fstp %st(1) + fptan + fstp %st(0) + ret +END(tan) + + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/i387/s_trunc.S b/src/openlibm/i387/s_trunc.S new file mode 100644 index 0000000..5422770 --- /dev/null +++ b/src/openlibm/i387/s_trunc.S @@ -0,0 +1,33 @@ +/* + * Based on code written by J.T. Conklin . + * Public domain. + */ + +#include +//__FBSDID("$FreeBSD: src/lib/msun/i387/s_trunc.S,v 1.3 2011/01/07 16:13:12 kib Exp $") + +ENTRY(trunc) + pushl %ebp + movl %esp,%ebp + subl $8,%esp + + fstcw -4(%ebp) /* store fpu control word */ + movw -4(%ebp),%dx + orw $0x0c00,%dx /* round towards -oo */ + movw %dx,-8(%ebp) + fldcw -8(%ebp) /* load modfied control word */ + + fldl 8(%ebp) /* round */ + frndint + + fldcw -4(%ebp) /* restore original control word */ + + leave + ret +END(trunc) + + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/i387/s_truncf.S b/src/openlibm/i387/s_truncf.S new file mode 100644 index 0000000..c9d32bb --- /dev/null +++ b/src/openlibm/i387/s_truncf.S @@ -0,0 +1,33 @@ +/* + * Based on code written by J.T. Conklin . + * Public domain. + */ + +#include +//__FBSDID("$FreeBSD: src/lib/msun/i387/s_truncf.S,v 1.4 2011/01/07 16:13:12 kib Exp $") + +ENTRY(truncf) + pushl %ebp + movl %esp,%ebp + subl $8,%esp + + fstcw -4(%ebp) /* store fpu control word */ + movw -4(%ebp),%dx + orw $0x0c00,%dx /* round towards -oo */ + movw %dx,-8(%ebp) + fldcw -8(%ebp) /* load modfied control word */ + + flds 8(%ebp) /* round */ + frndint + + fldcw -4(%ebp) /* restore original control word */ + + leave + ret +END(truncf) + + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/i387/s_truncl.S b/src/openlibm/i387/s_truncl.S new file mode 100644 index 0000000..7152638 --- /dev/null +++ b/src/openlibm/i387/s_truncl.S @@ -0,0 +1,33 @@ +/* + * Based on code written by J.T. Conklin . + * Public domain. + */ + +#include +//__FBSDID("$FreeBSD: src/lib/msun/i387/s_truncl.S,v 1.3 2011/01/07 16:13:12 kib Exp $") + +ENTRY(truncl) + pushl %ebp + movl %esp,%ebp + subl $8,%esp + + fstcw -4(%ebp) /* store fpu control word */ + movw -4(%ebp),%dx + orw $0x0c00,%dx /* round towards -oo */ + movw %dx,-8(%ebp) + fldcw -8(%ebp) /* load modfied control word */ + + fldt 8(%ebp) /* round */ + frndint + + fldcw -4(%ebp) /* restore original control word */ + + leave + ret +END(truncl) + + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/src/openlibm/include/openlibm.h b/src/openlibm/include/openlibm.h new file mode 100644 index 0000000..d851945 --- /dev/null +++ b/src/openlibm/include/openlibm.h @@ -0,0 +1,8 @@ +#ifndef OPENLIBM_H +#define OPENLIBM_H + +#include +#include +#include + +#endif /* !OPENLIBM_H */ diff --git a/src/openlibm/include/openlibm_complex.h b/src/openlibm/include/openlibm_complex.h new file mode 100644 index 0000000..7afc992 --- /dev/null +++ b/src/openlibm/include/openlibm_complex.h @@ -0,0 +1,179 @@ +/* $OpenBSD: complex.h,v 1.5 2014/03/16 18:38:30 guenther Exp $ */ +/* + * Copyright (c) 2008 Martynas Venckus + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef OPENLIBM_USE_HOST_COMPLEX_H +#include +#else /* !OPENLIBM_USE_HOST_COMPLEX_H */ + +#ifndef OPENLIBM_COMPLEX_H +#define OPENLIBM_COMPLEX_H + +#define complex _Complex + +#define _Complex_I 1.0fi +#define I _Complex_I + +/* + * Macros that can be used to construct complex values. + * + * The C99 standard intends x+I*y to be used for this, but x+I*y is + * currently unusable in general since gcc introduces many overflow, + * underflow, sign and efficiency bugs by rewriting I*y as + * (0.0+I)*(y+0.0*I) and laboriously computing the full complex product. + * In particular, I*Inf is corrupted to NaN+I*Inf, and I*-0 is corrupted + * to -0.0+I*0.0. + * + * In C11, a CMPLX(x,y) macro was added to circumvent this limitation, + * and gcc 4.7 added a __builtin_complex feature to simplify implementation + * of CMPLX in libc, so we can take advantage of these features if they + * are available. Clang simply allows complex values to be constructed + * using a compound literal. + * + * If __builtin_complex is not available, resort to using inline + * functions instead. These can unfortunately not be used to construct + * compile-time constants. + * + * C99 specifies that complex numbers have the same representation as + * an array of two elements, where the first element is the real part + * and the second element is the imaginary part. + */ + +#ifdef __clang__ +# define CMPLXF(x, y) ((float complex){x, y}) +# define CMPLX(x, y) ((double complex){x, y}) +# define CMPLXL(x, y) ((long double complex){x, y}) +#elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) && !defined(__INTEL_COMPILER) +# define CMPLXF(x,y) __builtin_complex ((float) (x), (float) (y)) +# define CMPLX(x,y) __builtin_complex ((double) (x), (double) (y)) +# define CMPLXL(x,y) __builtin_complex ((long double) (x), (long double) (y)) +#else +static inline float complex +CMPLXF(float x, float y) +{ + union { + float a[2]; + float complex f; + } z = {{ x, y }}; + + return (z.f); +} + +static inline double complex +CMPLX(double x, double y) +{ + union { + double a[2]; + double complex f; + } z = {{ x, y }}; + + return (z.f); +} + +static inline long double complex +CMPLXL(long double x, long double y) +{ + union { + long double a[2]; + long double complex f; + } z = {{ x, y }}; + + return (z.f); +} +#endif + +/* + * Double versions of C99 functions + */ +double complex cacos(double complex); +double complex casin(double complex); +double complex catan(double complex); +double complex ccos(double complex); +double complex csin(double complex); +double complex ctan(double complex); +double complex cacosh(double complex); +double complex casinh(double complex); +double complex catanh(double complex); +double complex ccosh(double complex); +double complex csinh(double complex); +double complex ctanh(double complex); +double complex cexp(double complex); +double complex clog(double complex); +double cabs(double complex); +double complex cpow(double complex, double complex); +double complex csqrt(double complex); +double carg(double complex); +double cimag(double complex); +double complex conj(double complex); +double complex cproj(double complex); +double creal(double complex); + +/* + * Float versions of C99 functions + */ +float complex cacosf(float complex); +float complex casinf(float complex); +float complex catanf(float complex); +float complex ccosf(float complex); +float complex csinf(float complex); +float complex ctanf(float complex); +float complex cacoshf(float complex); +float complex casinhf(float complex); +float complex catanhf(float complex); +float complex ccoshf(float complex); +float complex csinhf(float complex); +float complex ctanhf(float complex); +float complex cexpf(float complex); +float complex clogf(float complex); +float cabsf(float complex); +float complex cpowf(float complex, float complex); +float complex csqrtf(float complex); +float cargf(float complex); +float cimagf(float complex); +float complex conjf(float complex); +float complex cprojf(float complex); +float crealf(float complex); + +/* + * Long double versions of C99 functions + */ +long double complex cacosl(long double complex); +long double complex casinl(long double complex); +long double complex catanl(long double complex); +long double complex ccosl(long double complex); +long double complex csinl(long double complex); +long double complex ctanl(long double complex); +long double complex cacoshl(long double complex); +long double complex casinhl(long double complex); +long double complex catanhl(long double complex); +long double complex ccoshl(long double complex); +long double complex csinhl(long double complex); +long double complex ctanhl(long double complex); +long double complex cexpl(long double complex); +long double complex clogl(long double complex); +long double cabsl(long double complex); +long double complex cpowl(long double complex, + long double complex); +long double complex csqrtl(long double complex); +long double cargl(long double complex); +long double cimagl(long double complex); +long double complex conjl(long double complex); +long double complex cprojl(long double complex); +long double creall(long double complex); + +#endif /* !OPENLIBM_COMPLEX_H */ + +#endif /* OPENLIBM_USE_HOST_COMPLEX_H */ diff --git a/src/openlibm/include/openlibm_defs.h b/src/openlibm/include/openlibm_defs.h new file mode 100644 index 0000000..8a6fa6b --- /dev/null +++ b/src/openlibm/include/openlibm_defs.h @@ -0,0 +1,14 @@ +#ifndef OPENLIBM_DEFS_H_ +#define OPENLIBM_DEFS_H_ + +#ifdef _WIN32 +# ifdef IMPORT_EXPORTS +# define OLM_DLLEXPORT __declspec(dllimport) +# else +# define OLM_DLLEXPORT __declspec(dllexport) +# endif +#else +#define OLM_DLLEXPORT __attribute__ ((visibility("default"))) +#endif + +#endif // OPENLIBM_DEFS_H_ diff --git a/src/openlibm/include/openlibm_fenv.h b/src/openlibm/include/openlibm_fenv.h new file mode 100644 index 0000000..35a5586 --- /dev/null +++ b/src/openlibm/include/openlibm_fenv.h @@ -0,0 +1,27 @@ +#ifdef OPENLIBM_USE_HOST_FENV_H +#include +#else /* !OPENLIBM_USE_HOST_FENV_H */ + +#if defined(__aarch64__) +#include +#elif defined(__arm__) +#include +#elif defined(__x86_64__) +#include +#elif defined(__i386__) +#include +#elif defined(__powerpc__) || defined(__POWERPC__) +#include +#elif defined(__mips__) +#include +#elif defined(__s390__) +#include +#elif defined(__riscv) +#include +#elif defined(__loongarch64) +#include +#else +#error "Unsupported platform" +#endif + +#endif /* OPENLIBM_USE_HOST_FENV_H */ diff --git a/src/openlibm/include/openlibm_fenv_aarch64.h b/src/openlibm/include/openlibm_fenv_aarch64.h new file mode 100644 index 0000000..c7cb712 --- /dev/null +++ b/src/openlibm/include/openlibm_fenv_aarch64.h @@ -0,0 +1,247 @@ +/*- + * Copyright (c) 2004-2005 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _FENV_H_ +#define _FENV_H_ + +#include + +#include "cdefs-compat.h" + +#ifndef __fenv_static +#define __fenv_static static +#endif + +/* The high 32 bits contain fpcr, low 32 contain fpsr. */ +typedef __uint64_t fenv_t; +typedef __uint64_t fexcept_t; + +/* Exception flags */ +#define FE_INVALID 0x00000001 +#define FE_DIVBYZERO 0x00000002 +#define FE_OVERFLOW 0x00000004 +#define FE_UNDERFLOW 0x00000008 +#define FE_INEXACT 0x00000010 +#define FE_ALL_EXCEPT (FE_DIVBYZERO | FE_INEXACT | \ + FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW) + +/* + * Rounding modes + * + * We can't just use the hardware bit values here, because that would + * make FE_UPWARD and FE_DOWNWARD negative, which is not allowed. + */ +#define FE_TONEAREST 0x0 +#define FE_UPWARD 0x1 +#define FE_DOWNWARD 0x2 +#define FE_TOWARDZERO 0x3 +#define _ROUND_MASK (FE_TONEAREST | FE_DOWNWARD | \ + FE_UPWARD | FE_TOWARDZERO) +#define _ROUND_SHIFT 22 + +__BEGIN_DECLS + +/* Default floating-point environment */ +extern const fenv_t __fe_dfl_env; +#define FE_DFL_ENV (&__fe_dfl_env) + +/* We need to be able to map status flag positions to mask flag positions */ +#define _FPUSW_SHIFT 8 +#define _ENABLE_MASK (FE_ALL_EXCEPT << _FPUSW_SHIFT) + +#define __mrs_fpcr(__r) __asm __volatile("mrs %0, fpcr" : "=r" (__r)) +#define __msr_fpcr(__r) __asm __volatile("msr fpcr, %0" : : "r" (__r)) + +#define __mrs_fpsr(__r) __asm __volatile("mrs %0, fpsr" : "=r" (__r)) +#define __msr_fpsr(__r) __asm __volatile("msr fpsr, %0" : : "r" (__r)) + + +__fenv_static inline int +feclearexcept(int __excepts) +{ + fexcept_t __r; + + __mrs_fpsr(__r); + __r &= ~__excepts; + __msr_fpsr(__r); + return (0); +} + +__fenv_static inline int +fegetexceptflag(fexcept_t *__flagp, int __excepts) +{ + fexcept_t __r; + + __mrs_fpsr(__r); + *__flagp = __r & __excepts; + return (0); +} + +__fenv_static inline int +fesetexceptflag(const fexcept_t *__flagp, int __excepts) +{ + fexcept_t __r; + + __mrs_fpsr(__r); + __r &= ~__excepts; + __r |= *__flagp & __excepts; + __msr_fpsr(__r); + return (0); +} + +__fenv_static inline int +feraiseexcept(int __excepts) +{ + fexcept_t __r; + + __mrs_fpsr(__r); + __r |= __excepts; + __msr_fpsr(__r); + return (0); +} + +__fenv_static inline int +fetestexcept(int __excepts) +{ + fexcept_t __r; + + __mrs_fpsr(__r); + return (__r & __excepts); +} + +__fenv_static inline int +fegetround(void) +{ + fenv_t __r; + + __mrs_fpcr(__r); + return ((__r >> _ROUND_SHIFT) & _ROUND_MASK); +} + +__fenv_static inline int +fesetround(int __round) +{ + fenv_t __r; + + if (__round & ~_ROUND_MASK) + return (-1); + __mrs_fpcr(__r); + __r &= ~(_ROUND_MASK << _ROUND_SHIFT); + __r |= __round << _ROUND_SHIFT; + __msr_fpcr(__r); + return (0); +} + +__fenv_static inline int +fegetenv(fenv_t *__envp) +{ + __uint64_t fpcr; + __uint64_t fpsr; + + __mrs_fpcr(fpcr); + __mrs_fpsr(fpsr); + *__envp = fpsr | (fpcr << 32); + + return (0); +} + +__fenv_static inline int +feholdexcept(fenv_t *__envp) +{ + fenv_t __r; + + __mrs_fpcr(__r); + *__envp = __r << 32; + __r &= ~(_ENABLE_MASK); + __msr_fpcr(__r); + + __mrs_fpsr(__r); + *__envp |= (__uint32_t)__r; + __r &= ~(_ENABLE_MASK); + __msr_fpsr(__r); + return (0); +} + +__fenv_static inline int +fesetenv(const fenv_t *__envp) +{ + + __msr_fpcr((*__envp) >> 32); + __msr_fpsr((fenv_t)(__uint32_t)*__envp); + return (0); +} + +__fenv_static inline int +feupdateenv(const fenv_t *__envp) +{ + fexcept_t __r; + + __mrs_fpsr(__r); + fesetenv(__envp); + feraiseexcept(__r & FE_ALL_EXCEPT); + return (0); +} + +#if __BSD_VISIBLE + +/* We currently provide no external definitions of the functions below. */ + +static inline int +feenableexcept(int __mask) +{ + fenv_t __old_r, __new_r; + + __mrs_fpcr(__old_r); + __new_r = __old_r | ((__mask & FE_ALL_EXCEPT) << _FPUSW_SHIFT); + __msr_fpcr(__new_r); + return ((__old_r >> _FPUSW_SHIFT) & FE_ALL_EXCEPT); +} + +static inline int +fedisableexcept(int __mask) +{ + fenv_t __old_r, __new_r; + + __mrs_fpcr(__old_r); + __new_r = __old_r & ~((__mask & FE_ALL_EXCEPT) << _FPUSW_SHIFT); + __msr_fpcr(__new_r); + return ((__old_r >> _FPUSW_SHIFT) & FE_ALL_EXCEPT); +} + +static inline int +fegetexcept(void) +{ + fenv_t __r; + + __mrs_fpcr(__r); + return ((__r & _ENABLE_MASK) >> _FPUSW_SHIFT); +} + +#endif /* __BSD_VISIBLE */ + +__END_DECLS + +#endif /* !_FENV_H_ */ diff --git a/src/openlibm/include/openlibm_fenv_amd64.h b/src/openlibm/include/openlibm_fenv_amd64.h new file mode 100644 index 0000000..c6db210 --- /dev/null +++ b/src/openlibm/include/openlibm_fenv_amd64.h @@ -0,0 +1,223 @@ +/*- + * Copyright (c) 2004-2005 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/msun/amd64/fenv.h,v 1.8 2011/10/10 15:43:09 das Exp $ + */ + +#ifndef _FENV_H_ +#define _FENV_H_ + +#include +#include "cdefs-compat.h" +#include "types-compat.h" + +#ifndef __fenv_static +#define __fenv_static static +#endif + +typedef struct { + struct { + uint32_t __control; + uint32_t __status; + uint32_t __tag; + char __other[16]; + } __x87; + uint32_t __mxcsr; +} fenv_t; + +typedef uint16_t fexcept_t; + +/* Exception flags */ +#define FE_INVALID 0x01 +#define FE_DENORMAL 0x02 +#define FE_DIVBYZERO 0x04 +#define FE_OVERFLOW 0x08 +#define FE_UNDERFLOW 0x10 +#define FE_INEXACT 0x20 +#define FE_ALL_EXCEPT (FE_DIVBYZERO | FE_DENORMAL | FE_INEXACT | \ + FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW) + +/* Rounding modes */ +#define FE_TONEAREST 0x0000 +#define FE_DOWNWARD 0x0400 +#define FE_UPWARD 0x0800 +#define FE_TOWARDZERO 0x0c00 +#define _ROUND_MASK (FE_TONEAREST | FE_DOWNWARD | \ + FE_UPWARD | FE_TOWARDZERO) + +/* + * As compared to the x87 control word, the SSE unit's control word + * has the rounding control bits offset by 3 and the exception mask + * bits offset by 7. + */ +#define _SSE_ROUND_SHIFT 3 +#define _SSE_EMASK_SHIFT 7 + +__BEGIN_DECLS + +/* Default floating-point environment */ +extern const fenv_t __fe_dfl_env; +#define FE_DFL_ENV (&__fe_dfl_env) + +#define __fldcw(__cw) __asm __volatile("fldcw %0" : : "m" (__cw)) +#define __fldenv(__env) __asm __volatile("fldenv %0" : : "m" (__env)) +#define __fldenvx(__env) __asm __volatile("fldenv %0" : : "m" (__env) \ + : "st", "st(1)", "st(2)", "st(3)", "st(4)", \ + "st(5)", "st(6)", "st(7)") +#define __fnclex() __asm __volatile("fnclex") +#define __fnstenv(__env) __asm __volatile("fnstenv %0" : "=m" (*(__env))) +#define __fnstcw(__cw) __asm __volatile("fnstcw %0" : "=m" (*(__cw))) +#define __fnstsw(__sw) __asm __volatile("fnstsw %0" : "=am" (*(__sw))) +#define __fwait() __asm __volatile("fwait") +#define __ldmxcsr(__csr) __asm __volatile("ldmxcsr %0" : : "m" (__csr)) +#define __stmxcsr(__csr) __asm __volatile("stmxcsr %0" : "=m" (*(__csr))) + +__fenv_static __attribute__((always_inline)) inline int +feclearexcept(int __excepts) +{ + fenv_t __env; + + if (__excepts == FE_ALL_EXCEPT) { + __fnclex(); + } else { + __fnstenv(&__env.__x87); + __env.__x87.__status &= ~__excepts; + __fldenv(__env.__x87); + } + __stmxcsr(&__env.__mxcsr); + __env.__mxcsr &= ~__excepts; + __ldmxcsr(__env.__mxcsr); + return (0); +} + +__fenv_static inline int +fegetexceptflag(fexcept_t *__flagp, int __excepts) +{ + uint32_t __mxcsr; + uint16_t __status; + + __stmxcsr(&__mxcsr); + __fnstsw(&__status); + *__flagp = (__mxcsr | __status) & __excepts; + return (0); +} + +OLM_DLLEXPORT int fesetexceptflag(const fexcept_t *__flagp, int __excepts); +OLM_DLLEXPORT int feraiseexcept(int __excepts); + +__fenv_static __attribute__((always_inline)) inline int +fetestexcept(int __excepts) +{ + uint32_t __mxcsr; + uint16_t __status; + + __stmxcsr(&__mxcsr); + __fnstsw(&__status); + return ((__status | __mxcsr) & __excepts); +} + +__fenv_static inline int +fegetround(void) +{ + uint16_t __control; + + /* + * We assume that the x87 and the SSE unit agree on the + * rounding mode. Reading the control word on the x87 turns + * out to be about 5 times faster than reading it on the SSE + * unit on an Opteron 244. + */ + __fnstcw(&__control); + return (__control & _ROUND_MASK); +} + +__fenv_static inline int +fesetround(int __round) +{ + uint32_t __mxcsr; + uint16_t __control; + + if (__round & ~_ROUND_MASK) + return (-1); + + __fnstcw(&__control); + __control &= ~_ROUND_MASK; + __control |= __round; + __fldcw(__control); + + __stmxcsr(&__mxcsr); + __mxcsr &= ~(_ROUND_MASK << _SSE_ROUND_SHIFT); + __mxcsr |= __round << _SSE_ROUND_SHIFT; + __ldmxcsr(__mxcsr); + + return (0); +} + +OLM_DLLEXPORT int fegetenv(fenv_t *__envp); +OLM_DLLEXPORT int feholdexcept(fenv_t *__envp); + +__fenv_static inline int +fesetenv(const fenv_t *__envp) +{ + + /* + * XXX Using fldenvx() instead of fldenv() tells the compiler that this + * instruction clobbers the i387 register stack. This happens because + * we restore the tag word from the saved environment. Normally, this + * would happen anyway and we wouldn't care, because the ABI allows + * function calls to clobber the i387 regs. However, fesetenv() is + * inlined, so we need to be more careful. + */ + __fldenvx(__envp->__x87); + __ldmxcsr(__envp->__mxcsr); + return (0); +} + +OLM_DLLEXPORT int feupdateenv(const fenv_t *__envp); + +#if __BSD_VISIBLE + +OLM_DLLEXPORT int feenableexcept(int __mask); +OLM_DLLEXPORT int fedisableexcept(int __mask); + +/* We currently provide no external definition of fegetexcept(). */ +static inline int +fegetexcept(void) +{ + uint16_t __control; + + /* + * We assume that the masks for the x87 and the SSE unit are + * the same. + */ + __fnstcw(&__control); + return (~__control & FE_ALL_EXCEPT); +} + +#endif /* __BSD_VISIBLE */ + +__END_DECLS + +#endif /* !_FENV_H_ */ diff --git a/src/openlibm/include/openlibm_fenv_arm.h b/src/openlibm/include/openlibm_fenv_arm.h new file mode 100644 index 0000000..8223a01 --- /dev/null +++ b/src/openlibm/include/openlibm_fenv_arm.h @@ -0,0 +1,227 @@ +/*- + * Copyright (c) 2004-2005 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/msun/arm/fenv.h,v 1.6 2011/10/10 15:43:09 das Exp $ + */ + +#ifndef _FENV_H_ +#define _FENV_H_ + +#include + +#include "cdefs-compat.h" + +#ifndef __fenv_static +#define __fenv_static static +#endif + +typedef uint32_t fenv_t; +typedef uint32_t fexcept_t; + +/* Exception flags */ +#define FE_INVALID 0x0001 +#define FE_DIVBYZERO 0x0002 +#define FE_OVERFLOW 0x0004 +#define FE_UNDERFLOW 0x0008 +#define FE_INEXACT 0x0010 +#define FE_ALL_EXCEPT (FE_DIVBYZERO | FE_INEXACT | \ + FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW) + +/* Rounding modes */ +#define FE_TONEAREST 0x0000 +#define FE_TOWARDZERO 0x0001 +#define FE_UPWARD 0x0002 +#define FE_DOWNWARD 0x0003 +#define _ROUND_MASK (FE_TONEAREST | FE_DOWNWARD | \ + FE_UPWARD | FE_TOWARDZERO) +__BEGIN_DECLS + +/* Default floating-point environment */ +extern const fenv_t __fe_dfl_env; +#define FE_DFL_ENV (&__fe_dfl_env) + +/* We need to be able to map status flag positions to mask flag positions */ +#define _FPUSW_SHIFT 16 +#define _ENABLE_MASK (FE_ALL_EXCEPT << _FPUSW_SHIFT) + +/* Test for hardware support for ARM floating point operations, explicitly +checking for float and double support, see "ARM C Language Extensions", 6.5.1 */ +#if defined(__ARM_FP) && (__ARM_FP & 0x0C) != 0 +#define __rfs(__fpsr) __asm __volatile("vmrs %0,fpscr" : "=&r" (*(__fpsr))) +#define __wfs(__fpsr) __asm __volatile("vmsr fpscr,%0" : : "r" (__fpsr)) +#else +#define __rfs(__fpsr) (*(__fpsr) = 0) +#define __wfs(__fpsr) +#endif + +__fenv_static inline int +feclearexcept(int __excepts) +{ + fexcept_t __fpsr; + + __rfs(&__fpsr); + __fpsr &= ~__excepts; + __wfs(__fpsr); + return (0); +} + +__fenv_static inline int +fegetexceptflag(fexcept_t *__flagp, int __excepts) +{ + fexcept_t __fpsr; + + __rfs(&__fpsr); + *__flagp = __fpsr & __excepts; + return (0); +} + +__fenv_static inline int +fesetexceptflag(const fexcept_t *__flagp, int __excepts) +{ + fexcept_t __fpsr; + + __rfs(&__fpsr); + __fpsr &= ~__excepts; + __fpsr |= *__flagp & __excepts; + __wfs(__fpsr); + return (0); +} + +__fenv_static inline int +feraiseexcept(int __excepts) +{ + fexcept_t __ex = __excepts; + + fesetexceptflag(&__ex, __excepts); /* XXX */ + return (0); +} + +__fenv_static inline int +fetestexcept(int __excepts) +{ + fexcept_t __fpsr; + + __rfs(&__fpsr); + return (__fpsr & __excepts); +} + +__fenv_static inline int +fegetround(void) +{ + + /* + * Apparently, the rounding mode is specified as part of the + * instruction format on ARM, so the dynamic rounding mode is + * indeterminate. Some FPUs may differ. + */ + return (-1); +} + +__fenv_static inline int +fesetround(int __round) +{ + + return (-1); +} + +__fenv_static inline int +fegetenv(fenv_t *__envp) +{ + + __rfs(__envp); + return (0); +} + +__fenv_static inline int +feholdexcept(fenv_t *__envp) +{ + fenv_t __env; + + __rfs(&__env); + *__envp = __env; + __env &= ~(FE_ALL_EXCEPT | _ENABLE_MASK); + __wfs(__env); + return (0); +} + +__fenv_static inline int +fesetenv(const fenv_t *__envp) +{ + + __wfs(*__envp); + return (0); +} + +__fenv_static inline int +feupdateenv(const fenv_t *__envp) +{ + fexcept_t __fpsr; + + __rfs(&__fpsr); + __wfs(*__envp); + feraiseexcept(__fpsr & FE_ALL_EXCEPT); + return (0); +} + +#if __BSD_VISIBLE + +/* We currently provide no external definitions of the functions below. */ + +static inline int +feenableexcept(int __mask) +{ + fenv_t __old_fpsr, __new_fpsr; + + __rfs(&__old_fpsr); + __new_fpsr = __old_fpsr | (__mask & FE_ALL_EXCEPT) << _FPUSW_SHIFT; + __wfs(__new_fpsr); + return ((__old_fpsr >> _FPUSW_SHIFT) & FE_ALL_EXCEPT); +} + +static inline int +fedisableexcept(int __mask) +{ + fenv_t __old_fpsr, __new_fpsr; + + __rfs(&__old_fpsr); + __new_fpsr = __old_fpsr & ~((__mask & FE_ALL_EXCEPT) << _FPUSW_SHIFT); + __wfs(__new_fpsr); + return ((__old_fpsr >> _FPUSW_SHIFT) & FE_ALL_EXCEPT); +} + +static inline int +fegetexcept(void) +{ + fenv_t __fpsr; + + __rfs(&__fpsr); + return ((__fpsr & _ENABLE_MASK) >> _FPUSW_SHIFT); +} + +#endif /* __BSD_VISIBLE */ + +__END_DECLS + +#endif /* !_FENV_H_ */ diff --git a/src/openlibm/include/openlibm_fenv_i387.h b/src/openlibm/include/openlibm_fenv_i387.h new file mode 100644 index 0000000..ec4eb87 --- /dev/null +++ b/src/openlibm/include/openlibm_fenv_i387.h @@ -0,0 +1,260 @@ +/*- + * Copyright (c) 2004-2005 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/msun/i387/fenv.h,v 1.8 2011/10/10 15:43:09 das Exp $ + */ + +#ifndef _FENV_H_ +#define _FENV_H_ + +#include "openlibm_defs.h" +#include "cdefs-compat.h" +#include "types-compat.h" + +#ifndef __fenv_static +#define __fenv_static static +#endif + +/* + * To preserve binary compatibility with FreeBSD 5.3, we pack the + * mxcsr into some reserved fields, rather than changing sizeof(fenv_t). + */ +typedef struct { + uint16_t __control; + uint16_t __mxcsr_hi; + uint16_t __status; + uint16_t __mxcsr_lo; + uint32_t __tag; + char __other[16]; +} fenv_t; + +#define __get_mxcsr(env) (((env).__mxcsr_hi << 16) | \ + ((env).__mxcsr_lo)) +#define __set_mxcsr(env, x) do { \ + (env).__mxcsr_hi = (uint32_t)(x) >> 16; \ + (env).__mxcsr_lo = (uint16_t)(x); \ +} while (0) + +typedef uint16_t fexcept_t; + +/* Exception flags */ +#define FE_INVALID 0x01 +#define FE_DENORMAL 0x02 +#define FE_DIVBYZERO 0x04 +#define FE_OVERFLOW 0x08 +#define FE_UNDERFLOW 0x10 +#define FE_INEXACT 0x20 +#define FE_ALL_EXCEPT (FE_DIVBYZERO | FE_DENORMAL | FE_INEXACT | \ + FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW) + +/* Rounding modes */ +#define FE_TONEAREST 0x0000 +#define FE_DOWNWARD 0x0400 +#define FE_UPWARD 0x0800 +#define FE_TOWARDZERO 0x0c00 +#define _ROUND_MASK (FE_TONEAREST | FE_DOWNWARD | \ + FE_UPWARD | FE_TOWARDZERO) + +/* + * As compared to the x87 control word, the SSE unit's control word + * has the rounding control bits offset by 3 and the exception mask + * bits offset by 7. + */ +#define _SSE_ROUND_SHIFT 3 +#define _SSE_EMASK_SHIFT 7 + +__BEGIN_DECLS + +/* After testing for SSE support once, we cache the result in __has_sse. */ +enum __sse_support { __SSE_YES, __SSE_NO, __SSE_UNK }; +OLM_DLLEXPORT extern enum __sse_support __has_sse; +OLM_DLLEXPORT int __test_sse(void); +#ifdef __SSE__ +#define __HAS_SSE() 1 +#else +#define __HAS_SSE() (__has_sse == __SSE_YES || \ + (__has_sse == __SSE_UNK && __test_sse())) +#endif + +/* Default floating-point environment */ +OLM_DLLEXPORT extern const fenv_t __fe_dfl_env; +#define FE_DFL_ENV (&__fe_dfl_env) + +#define __fldcw(__cw) __asm __volatile("fldcw %0" : : "m" (__cw)) +#define __fldenv(__env) __asm __volatile("fldenv %0" : : "m" (__env)) +#define __fldenvx(__env) __asm __volatile("fldenv %0" : : "m" (__env) \ + : "st", "st(1)", "st(2)", "st(3)", "st(4)", \ + "st(5)", "st(6)", "st(7)") +#define __fnclex() __asm __volatile("fnclex") +#define __fnstenv(__env) __asm __volatile("fnstenv %0" : "=m" (*(__env))) +#define __fnstcw(__cw) __asm __volatile("fnstcw %0" : "=m" (*(__cw))) +#define __fnstsw(__sw) __asm __volatile("fnstsw %0" : "=am" (*(__sw))) +#define __fwait() __asm __volatile("fwait") +#define __ldmxcsr(__csr) __asm __volatile("ldmxcsr %0" : : "m" (__csr)) +#define __stmxcsr(__csr) __asm __volatile("stmxcsr %0" : "=m" (*(__csr))) + +__fenv_static inline int +feclearexcept(int __excepts) +{ + fenv_t __env; + uint32_t __mxcsr; + + if (__excepts == FE_ALL_EXCEPT) { + __fnclex(); + } else { + __fnstenv(&__env); + __env.__status &= ~__excepts; + __fldenv(__env); + } + if (__HAS_SSE()) { + __stmxcsr(&__mxcsr); + __mxcsr &= ~__excepts; + __ldmxcsr(__mxcsr); + } + return (0); +} + +__fenv_static inline int +fegetexceptflag(fexcept_t *__flagp, int __excepts) +{ + uint32_t __mxcsr; + uint16_t __status; + + __fnstsw(&__status); + if (__HAS_SSE()) + __stmxcsr(&__mxcsr); + else + __mxcsr = 0; + *__flagp = (__mxcsr | __status) & __excepts; + return (0); +} + +OLM_DLLEXPORT int fesetexceptflag(const fexcept_t *__flagp, int __excepts); +OLM_DLLEXPORT int feraiseexcept(int __excepts); + +__fenv_static inline int +fetestexcept(int __excepts) +{ + uint32_t __mxcsr; + uint16_t __status; + + __fnstsw(&__status); + if (__HAS_SSE()) + __stmxcsr(&__mxcsr); + else + __mxcsr = 0; + return ((__status | __mxcsr) & __excepts); +} + +__fenv_static inline int +fegetround(void) +{ + uint16_t __control; + + /* + * We assume that the x87 and the SSE unit agree on the + * rounding mode. Reading the control word on the x87 turns + * out to be about 5 times faster than reading it on the SSE + * unit on an Opteron 244. + */ + __fnstcw(&__control); + return (__control & _ROUND_MASK); +} + +__fenv_static inline int +fesetround(int __round) +{ + uint32_t __mxcsr; + uint16_t __control; + + if (__round & ~_ROUND_MASK) + return (-1); + + __fnstcw(&__control); + __control &= ~_ROUND_MASK; + __control |= __round; + __fldcw(__control); + + if (__HAS_SSE()) { + __stmxcsr(&__mxcsr); + __mxcsr &= ~(_ROUND_MASK << _SSE_ROUND_SHIFT); + __mxcsr |= __round << _SSE_ROUND_SHIFT; + __ldmxcsr(__mxcsr); + } + + return (0); +} + +OLM_DLLEXPORT int fegetenv(fenv_t *__envp); +OLM_DLLEXPORT int feholdexcept(fenv_t *__envp); + +__fenv_static inline int +fesetenv(const fenv_t *__envp) +{ + fenv_t __env = *__envp; + uint32_t __mxcsr; + + __mxcsr = __get_mxcsr(__env); + __set_mxcsr(__env, 0xffffffff); + /* + * XXX Using fldenvx() instead of fldenv() tells the compiler that this + * instruction clobbers the i387 register stack. This happens because + * we restore the tag word from the saved environment. Normally, this + * would happen anyway and we wouldn't care, because the ABI allows + * function calls to clobber the i387 regs. However, fesetenv() is + * inlined, so we need to be more careful. + */ + __fldenvx(__env); + if (__HAS_SSE()) + __ldmxcsr(__mxcsr); + return (0); +} + +OLM_DLLEXPORT int feupdateenv(const fenv_t *__envp); + +#if __BSD_VISIBLE + +OLM_DLLEXPORT int feenableexcept(int __mask); +OLM_DLLEXPORT int fedisableexcept(int __mask); + +/* We currently provide no external definition of fegetexcept(). */ +static inline int +fegetexcept(void) +{ + uint16_t __control; + + /* + * We assume that the masks for the x87 and the SSE unit are + * the same. + */ + __fnstcw(&__control); + return (~__control & FE_ALL_EXCEPT); +} + +#endif /* __BSD_VISIBLE */ + +__END_DECLS + +#endif /* !_FENV_H_ */ diff --git a/src/openlibm/include/openlibm_fenv_loongarch64.h b/src/openlibm/include/openlibm_fenv_loongarch64.h new file mode 100644 index 0000000..cfaf020 --- /dev/null +++ b/src/openlibm/include/openlibm_fenv_loongarch64.h @@ -0,0 +1,226 @@ +/*- + * Copyright (c) 2023 Yifan An + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _FENV_H_ +#define _FENV_H_ + +#include +#include "cdefs-compat.h" + +#ifndef __fenv_static +#define __fenv_static static +#endif + +typedef uint32_t fenv_t; +typedef uint32_t fexcept_t; + +/* Exception flags */ +#define FE_INVALID 0x100000 +#define FE_DIVBYZERO 0x080000 +#define FE_OVERFLOW 0x040000 +#define FE_UNDERFLOW 0x020000 +#define FE_INEXACT 0x010000 +#define FE_ALL_EXCEPT (FE_DIVBYZERO | FE_INEXACT | \ + FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW) + +/* Rounding modes */ +#define FE_TONEAREST 0x0000 +#define FE_TOWARDZERO 0x0100 +#define FE_DOWNWARD 0x0200 +#define FE_UPWARD 0x0300 +#define _ROUND_MASK (FE_TONEAREST | FE_DOWNWARD | \ + FE_UPWARD | FE_TOWARDZERO) + +__BEGIN_DECLS + +/* Default floating-point environment */ +extern const fenv_t __fe_dfl_env; +#define FE_DFL_ENV (&__fe_dfl_env) + +#define _FPU_MASK_V 0x10 +#define _FPU_MASK_Z 0x08 +#define _FPU_MASK_O 0x04 +#define _FPU_MASK_U 0x02 +#define _FPU_MASK_I 0x01 + +#define _FPUSW_SHIFT 16 +#define _ENABLE_MASK (_FPU_MASK_V | _FPU_MASK_Z | _FPU_MASK_O | _FPU_MASK_U | _FPU_MASK_I) + +#define __rfs(__fpsr) __asm __volatile("movfcsr2gr %0,$r0" : "=r"(__fpsr)) +#define __wfs(__fpsr) __asm __volatile("movgr2fcsr $r0,%0" : : "r"(__fpsr)) + +__fenv_static inline int +feclearexcept(int __excepts) +{ + fexcept_t __fpsr; + + __rfs(__fpsr); + __fpsr &= ~__excepts; + __wfs(__fpsr); + return (0); +} + +__fenv_static inline int +fegetexceptflag(fexcept_t *__flagp, int __excepts) +{ + fexcept_t __fpsr; + + __rfs(__fpsr); + *__flagp = __fpsr & __excepts; + return (0); +} + +__fenv_static inline int +fesetexceptflag(const fexcept_t *__flagp, int __excepts) +{ + fexcept_t __fpsr; + + __rfs(__fpsr); + __fpsr &= ~__excepts; + __fpsr |= *__flagp & __excepts; + __wfs(__fpsr); + return (0); +} + +__fenv_static inline int +feraiseexcept(int __excepts) +{ + fexcept_t __ex = __excepts; + + fesetexceptflag(&__ex, __excepts); /* XXX */ + return (0); +} + +__fenv_static inline int +fetestexcept(int __excepts) +{ + fexcept_t __fpsr; + + __rfs(__fpsr); + return (__fpsr & __excepts); +} + +__fenv_static inline int +fegetround(void) +{ + fexcept_t __fpsr; + + __rfs(__fpsr); + return __fpsr & _ROUND_MASK; +} + +__fenv_static inline int +fesetround(int __round) +{ + fexcept_t __fpsr; + if ((__round & ~_ROUND_MASK) != 0) + return 1; + + __rfs(__fpsr); + __fpsr &= ~_ROUND_MASK; + __fpsr |= __round; + __wfs(__fpsr); + + return (0); +} + +__fenv_static inline int +fegetenv(fenv_t *__envp) +{ + __rfs(*__envp); + return (0); +} + +__fenv_static inline int +feholdexcept(fenv_t *__envp) +{ + fenv_t __env; + + __rfs(__env); + *__envp = __env; + __env &= ~(FE_ALL_EXCEPT | _FPU_MASK_V | _FPU_MASK_Z | _FPU_MASK_O | _FPU_MASK_U | _FPU_MASK_I); + __wfs(__env); + return (0); +} + +__fenv_static inline int +fesetenv(const fenv_t *__envp) +{ + __wfs(*__envp); + return (0); +} + +__fenv_static inline int +feupdateenv(const fenv_t *__envp) +{ + fexcept_t __fpsr; + + __rfs(__fpsr); + __wfs(*__envp); + feraiseexcept(__fpsr & FE_ALL_EXCEPT); + return (0); +} + +#if __BSD_VISIBLE + +static inline int +feenableexcept(int __mask) +{ + fenv_t __old_fpsr, __new_fpsr; + + __rfs(__new_fpsr); + __old_fpsr = (__new_fpsr & _ENABLE_MASK) << _FPUSW_SHIFT; + __new_fpsr |= (__mask & FE_ALL_EXCEPT) >> _FPUSW_SHIFT; + __wfs(__new_fpsr); + return __old_fpsr; +} + +static inline int +fedisableexcept(int __mask) +{ + fenv_t __old_fpsr, __new_fpsr; + + __rfs(__new_fpsr); + __old_fpsr = (__new_fpsr & _ENABLE_MASK) << _FPUSW_SHIFT; + __new_fpsr &= ~((__mask & FE_ALL_EXCEPT) >> _FPUSW_SHIFT); + __wfs(__new_fpsr); + return __old_fpsr; +} + +static inline int +fegetexcept(void) +{ + fenv_t __fpsr; + + __rfs(__fpsr); + return ((__fpsr & _ENABLE_MASK) << _FPUSW_SHIFT); +} + +#endif /* __BSD_VISIBLE */ + +__END_DECLS + +#endif /* !_FENV_H_ */ \ No newline at end of file diff --git a/src/openlibm/include/openlibm_fenv_mips.h b/src/openlibm/include/openlibm_fenv_mips.h new file mode 100644 index 0000000..980252f --- /dev/null +++ b/src/openlibm/include/openlibm_fenv_mips.h @@ -0,0 +1,278 @@ +/*- + * Copyright (c) 2004-2005 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _FENV_H_ +#define _FENV_H_ + +#include +#include "cdefs-compat.h" + +#ifndef __fenv_static +#define __fenv_static static +#endif + +typedef uint32_t fenv_t; +typedef uint32_t fexcept_t; + +/* Exception flags */ +#ifdef __mips_soft_float +#define _FPUSW_SHIFT 16 +#define FE_INVALID 0x0001 +#define FE_DIVBYZERO 0x0002 +#define FE_OVERFLOW 0x0004 +#define FE_UNDERFLOW 0x0008 +#define FE_INEXACT 0x0010 +#else +#define _FCSR_CAUSE_SHIFT 10 +#define FE_INVALID 0x0040 +#define FE_DIVBYZERO 0x0020 +#define FE_OVERFLOW 0x0010 +#define FE_UNDERFLOW 0x0008 +#define FE_INEXACT 0x0004 +#endif +#define FE_ALL_EXCEPT (FE_DIVBYZERO | FE_INEXACT | \ + FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW) + +/* Rounding modes */ +#define FE_TONEAREST 0x0000 +#define FE_TOWARDZERO 0x0001 +#define FE_UPWARD 0x0002 +#define FE_DOWNWARD 0x0003 +#define _ROUND_MASK (FE_TONEAREST | FE_DOWNWARD | \ + FE_UPWARD | FE_TOWARDZERO) +__BEGIN_DECLS + +/* Default floating-point environment */ +extern const fenv_t __fe_dfl_env; +#define FE_DFL_ENV (&__fe_dfl_env) + +/* We need to be able to map status flag positions to mask flag positions */ +#define _ENABLE_SHIFT 5 +#define _ENABLE_MASK (FE_ALL_EXCEPT << _ENABLE_SHIFT) + +#ifndef __mips_soft_float +#define __cfc1(__fcsr) __asm __volatile("cfc1 %0, $31" : "=r" (__fcsr)) +#define __ctc1(__fcsr) __asm __volatile("ctc1 %0, $31" :: "r" (__fcsr)) +#endif + +#ifdef __mips_soft_float +int feclearexcept(int __excepts); +int fegetexceptflag(fexcept_t *__flagp, int __excepts); +int fesetexceptflag(const fexcept_t *__flagp, int __excepts); +int feraiseexcept(int __excepts); +int fetestexcept(int __excepts); +int fegetround(void); +int fesetround(int __round); +int fegetenv(fenv_t *__envp); +int feholdexcept(fenv_t *__envp); +int fesetenv(const fenv_t *__envp); +int feupdateenv(const fenv_t *__envp); +#else +__fenv_static inline int +feclearexcept(int __excepts) +{ + fexcept_t fcsr; + + __excepts &= FE_ALL_EXCEPT; + __cfc1(fcsr); + fcsr &= ~(__excepts | (__excepts << _FCSR_CAUSE_SHIFT)); + __ctc1(fcsr); + + return (0); +} + +__fenv_static inline int +fegetexceptflag(fexcept_t *__flagp, int __excepts) +{ + fexcept_t fcsr; + + __excepts &= FE_ALL_EXCEPT; + __cfc1(fcsr); + *__flagp = fcsr & __excepts; + + return (0); +} + +__fenv_static inline int +fesetexceptflag(const fexcept_t *__flagp, int __excepts) +{ + fexcept_t fcsr; + + __excepts &= FE_ALL_EXCEPT; + __cfc1(fcsr); + fcsr &= ~__excepts; + fcsr |= *__flagp & __excepts; + __ctc1(fcsr); + + return (0); +} + +__fenv_static inline int +feraiseexcept(int __excepts) +{ + fexcept_t fcsr; + + __excepts &= FE_ALL_EXCEPT; + __cfc1(fcsr); + fcsr |= __excepts | (__excepts << _FCSR_CAUSE_SHIFT); + __ctc1(fcsr); + + return (0); +} + +__fenv_static inline int +fetestexcept(int __excepts) +{ + fexcept_t fcsr; + + __excepts &= FE_ALL_EXCEPT; + __cfc1(fcsr); + + return (fcsr & __excepts); +} + +__fenv_static inline int +fegetround(void) +{ + fexcept_t fcsr; + + __cfc1(fcsr); + + return (fcsr & _ROUND_MASK); +} + +__fenv_static inline int +fesetround(int __round) +{ + fexcept_t fcsr; + + if (__round & ~_ROUND_MASK) + return (-1); + + __cfc1(fcsr); + fcsr &= ~_ROUND_MASK; + fcsr |= __round; + __ctc1(fcsr); + + return (0); +} + +__fenv_static inline int +fegetenv(fenv_t *__envp) +{ + + __cfc1(*__envp); + + return (0); +} + +__fenv_static inline int +feholdexcept(fenv_t *__envp) +{ + fexcept_t fcsr; + + __cfc1(fcsr); + *__envp = fcsr; + fcsr &= ~(FE_ALL_EXCEPT | _ENABLE_MASK); + __ctc1(fcsr); + + return (0); +} + +__fenv_static inline int +fesetenv(const fenv_t *__envp) +{ + + __ctc1(*__envp); + + return (0); +} + +__fenv_static inline int +feupdateenv(const fenv_t *__envp) +{ + fexcept_t fcsr; + + __cfc1(fcsr); + fesetenv(__envp); + feraiseexcept(fcsr); + + return (0); +} +#endif /* !__mips_soft_float */ + +#if __BSD_VISIBLE + +/* We currently provide no external definitions of the functions below. */ + +#ifdef __mips_soft_float +int feenableexcept(int __mask); +int fedisableexcept(int __mask); +int fegetexcept(void); +#else +static inline int +feenableexcept(int __mask) +{ + fenv_t __old_fcsr, __new_fcsr; + + __cfc1(__old_fcsr); + __new_fcsr = __old_fcsr | (__mask & FE_ALL_EXCEPT) << _ENABLE_SHIFT; + __ctc1(__new_fcsr); + + return ((__old_fcsr >> _ENABLE_SHIFT) & FE_ALL_EXCEPT); +} + +static inline int +fedisableexcept(int __mask) +{ + fenv_t __old_fcsr, __new_fcsr; + + __cfc1(__old_fcsr); + __new_fcsr = __old_fcsr & ~((__mask & FE_ALL_EXCEPT) << _ENABLE_SHIFT); + __ctc1(__new_fcsr); + + return ((__old_fcsr >> _ENABLE_SHIFT) & FE_ALL_EXCEPT); +} + +static inline int +fegetexcept(void) +{ + fexcept_t fcsr; + + __cfc1(fcsr); + + return ((fcsr & _ENABLE_MASK) >> _ENABLE_SHIFT); +} + +#endif /* !__mips_soft_float */ + +#endif /* __BSD_VISIBLE */ + +__END_DECLS + +#endif /* !_FENV_H_ */ diff --git a/src/openlibm/include/openlibm_fenv_powerpc.h b/src/openlibm/include/openlibm_fenv_powerpc.h new file mode 100644 index 0000000..232ea83 --- /dev/null +++ b/src/openlibm/include/openlibm_fenv_powerpc.h @@ -0,0 +1,279 @@ +/*- + * Copyright (c) 2004-2005 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _FENV_H_ +#define _FENV_H_ + +#include + +#ifndef __fenv_static +#define __fenv_static static +#endif + +typedef __uint32_t fenv_t; +typedef __uint32_t fexcept_t; + +/* Exception flags */ +#define FE_INEXACT 0x02000000 +#define FE_DIVBYZERO 0x04000000 +#define FE_UNDERFLOW 0x08000000 +#define FE_OVERFLOW 0x10000000 +#define FE_INVALID 0x20000000 /* all types of invalid FP ops */ + +/* + * The PowerPC architecture has extra invalid flags that indicate the + * specific type of invalid operation occurred. These flags may be + * tested, set, and cleared---but not masked---separately. All of + * these bits are cleared when FE_INVALID is cleared, but only + * FE_VXSOFT is set when FE_INVALID is explicitly set in software. + */ +#define FE_VXCVI 0x00000100 /* invalid integer convert */ +#define FE_VXSQRT 0x00000200 /* square root of a negative */ +#define FE_VXSOFT 0x00000400 /* software-requested exception */ +#define FE_VXVC 0x00080000 /* ordered comparison involving NaN */ +#define FE_VXIMZ 0x00100000 /* inf * 0 */ +#define FE_VXZDZ 0x00200000 /* 0 / 0 */ +#define FE_VXIDI 0x00400000 /* inf / inf */ +#define FE_VXISI 0x00800000 /* inf - inf */ +#define FE_VXSNAN 0x01000000 /* operation on a signalling NaN */ +#define FE_ALL_INVALID (FE_VXCVI | FE_VXSQRT | FE_VXSOFT | FE_VXVC | \ + FE_VXIMZ | FE_VXZDZ | FE_VXIDI | FE_VXISI | \ + FE_VXSNAN | FE_INVALID) +#define FE_ALL_EXCEPT (FE_DIVBYZERO | FE_INEXACT | \ + FE_ALL_INVALID | FE_OVERFLOW | FE_UNDERFLOW) + +/* Rounding modes */ +#define FE_TONEAREST 0x0000 +#define FE_TOWARDZERO 0x0001 +#define FE_UPWARD 0x0002 +#define FE_DOWNWARD 0x0003 +#define _ROUND_MASK (FE_TONEAREST | FE_DOWNWARD | \ + FE_UPWARD | FE_TOWARDZERO) + +__BEGIN_DECLS + +/* Default floating-point environment */ +extern const fenv_t __fe_dfl_env; +#define FE_DFL_ENV (&__fe_dfl_env) + +/* We need to be able to map status flag positions to mask flag positions */ +#define _FPUSW_SHIFT 22 +#define _ENABLE_MASK ((FE_DIVBYZERO | FE_INEXACT | FE_INVALID | \ + FE_OVERFLOW | FE_UNDERFLOW) >> _FPUSW_SHIFT) + +#ifndef _SOFT_FLOAT +#define __mffs(__env) __asm __volatile("mffs %0" : "=f" (*(__env))) +#define __mtfsf(__env) __asm __volatile("mtfsf 255,%0" : : "f" (__env)) +#else +#define __mffs(__env) +#define __mtfsf(__env) +#endif + +union __fpscr { + double __d; + struct { +#if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) + fenv_t __reg; + __uint32_t __junk; +#else + __uint32_t __junk; + fenv_t __reg; +#endif + } __bits; +}; + +__fenv_static inline int +feclearexcept(int __excepts) +{ + union __fpscr __r; + + if (__excepts & FE_INVALID) + __excepts |= FE_ALL_INVALID; + __mffs(&__r.__d); + __r.__bits.__reg &= ~__excepts; + __mtfsf(__r.__d); + return (0); +} + +__fenv_static inline int +fegetexceptflag(fexcept_t *__flagp, int __excepts) +{ + union __fpscr __r; + + __mffs(&__r.__d); + *__flagp = __r.__bits.__reg & __excepts; + return (0); +} + +__fenv_static inline int +fesetexceptflag(const fexcept_t *__flagp, int __excepts) +{ + union __fpscr __r; + + if (__excepts & FE_INVALID) + __excepts |= FE_ALL_EXCEPT; + __mffs(&__r.__d); + __r.__bits.__reg &= ~__excepts; + __r.__bits.__reg |= *__flagp & __excepts; + __mtfsf(__r.__d); + return (0); +} + +__fenv_static inline int +feraiseexcept(int __excepts) +{ + union __fpscr __r; + + if (__excepts & FE_INVALID) + __excepts |= FE_VXSOFT; + __mffs(&__r.__d); + __r.__bits.__reg |= __excepts; + __mtfsf(__r.__d); + return (0); +} + +__fenv_static inline int +fetestexcept(int __excepts) +{ + union __fpscr __r; + + __mffs(&__r.__d); + return (__r.__bits.__reg & __excepts); +} + +__fenv_static inline int +fegetround(void) +{ + union __fpscr __r; + + __mffs(&__r.__d); + return (__r.__bits.__reg & _ROUND_MASK); +} + +__fenv_static inline int +fesetround(int __round) +{ + union __fpscr __r; + + if (__round & ~_ROUND_MASK) + return (-1); + __mffs(&__r.__d); + __r.__bits.__reg &= ~_ROUND_MASK; + __r.__bits.__reg |= __round; + __mtfsf(__r.__d); + return (0); +} + +__fenv_static inline int +fegetenv(fenv_t *__envp) +{ + union __fpscr __r; + + __mffs(&__r.__d); + *__envp = __r.__bits.__reg; + return (0); +} + +__fenv_static inline int +feholdexcept(fenv_t *__envp) +{ + union __fpscr __r; + + __mffs(&__r.__d); + *__envp = __r.__d; + __r.__bits.__reg &= ~(FE_ALL_EXCEPT | _ENABLE_MASK); + __mtfsf(__r.__d); + return (0); +} + +__fenv_static inline int +fesetenv(const fenv_t *__envp) +{ + union __fpscr __r; + + __r.__bits.__reg = *__envp; + __mtfsf(__r.__d); + return (0); +} + +__fenv_static inline int +feupdateenv(const fenv_t *__envp) +{ + union __fpscr __r; + + __mffs(&__r.__d); + __r.__bits.__reg &= FE_ALL_EXCEPT; + __r.__bits.__reg |= *__envp; + __mtfsf(__r.__d); + return (0); +} + +#if __BSD_VISIBLE + +/* We currently provide no external definitions of the functions below. */ + +static inline int +feenableexcept(int __mask) +{ + union __fpscr __r; + fenv_t __oldmask; + + __mffs(&__r.__d); + __oldmask = __r.__bits.__reg; + __r.__bits.__reg |= (__mask & FE_ALL_EXCEPT) >> _FPUSW_SHIFT; + __mtfsf(__r.__d); + return ((__oldmask & _ENABLE_MASK) << _FPUSW_SHIFT); +} + +static inline int +fedisableexcept(int __mask) +{ + union __fpscr __r; + fenv_t __oldmask; + + __mffs(&__r.__d); + __oldmask = __r.__bits.__reg; + __r.__bits.__reg &= ~((__mask & FE_ALL_EXCEPT) >> _FPUSW_SHIFT); + __mtfsf(__r.__d); + return ((__oldmask & _ENABLE_MASK) << _FPUSW_SHIFT); +} + +static inline int +fegetexcept(void) +{ + union __fpscr __r; + + __mffs(&__r.__d); + return ((__r.__bits.__reg & _ENABLE_MASK) << _FPUSW_SHIFT); +} + +#endif /* __BSD_VISIBLE */ + +__END_DECLS + +#endif /* !_FENV_H_ */ diff --git a/src/openlibm/include/openlibm_fenv_riscv.h b/src/openlibm/include/openlibm_fenv_riscv.h new file mode 100644 index 0000000..e8ce78e --- /dev/null +++ b/src/openlibm/include/openlibm_fenv_riscv.h @@ -0,0 +1,261 @@ +/*- + * Copyright (c) 2004-2005 David Schultz + * Copyright (c) 2015-2016 Ruslan Bukin + * All rights reserved. + * + * Portions of this software were developed by SRI International and the + * University of Cambridge Computer Laboratory under DARPA/AFRL contract + * FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme. + * + * Portions of this software were developed by the University of Cambridge + * Computer Laboratory as part of the CTSRD Project, with support from the + * UK Higher Education Innovation Fund (HEIF). + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: head/lib/msun/riscv/fenv.h 332792 2018-04-19 20:36:15Z brooks $ + */ + +#ifndef _FENV_H_ +#define _FENV_H_ + +#include +#include "cdefs-compat.h" + +#ifndef __fenv_static +#define __fenv_static static +#endif + +typedef uint64_t fenv_t; +typedef uint64_t fexcept_t; + +/* Exception flags */ +#define FE_INVALID 0x0010 +#define FE_DIVBYZERO 0x0008 +#define FE_OVERFLOW 0x0004 +#define FE_UNDERFLOW 0x0002 +#define FE_INEXACT 0x0001 +#define FE_ALL_EXCEPT (FE_DIVBYZERO | FE_INEXACT | \ + FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW) + +/* + * RISC-V Rounding modes + */ +#define _ROUND_SHIFT 5 +#define FE_TONEAREST (0x00 << _ROUND_SHIFT) +#define FE_TOWARDZERO (0x01 << _ROUND_SHIFT) +#define FE_DOWNWARD (0x02 << _ROUND_SHIFT) +#define FE_UPWARD (0x03 << _ROUND_SHIFT) +#define _ROUND_MASK (FE_TONEAREST | FE_DOWNWARD | \ + FE_UPWARD | FE_TOWARDZERO) + +__BEGIN_DECLS + +/* Default floating-point environment */ +extern const fenv_t __fe_dfl_env; +#define FE_DFL_ENV (&__fe_dfl_env) + +#if !defined(__riscv_float_abi_soft) && !defined(__riscv_float_abi_double) +#if defined(__riscv_float_abi_single) +#error single precision floating point ABI not supported +#else +#error compiler did not set soft/hard float macros +#endif +#endif + +#ifndef __riscv_float_abi_soft +#define __rfs(__fcsr) __asm __volatile("csrr %0, fcsr" : "=r" (__fcsr)) +#define __wfs(__fcsr) __asm __volatile("csrw fcsr, %0" :: "r" (__fcsr)) +#endif + +#ifdef __riscv_float_abi_soft +int feclearexcept(int __excepts); +int fegetexceptflag(fexcept_t *__flagp, int __excepts); +int fesetexceptflag(const fexcept_t *__flagp, int __excepts); +int feraiseexcept(int __excepts); +int fetestexcept(int __excepts); +int fegetround(void); +int fesetround(int __round); +int fegetenv(fenv_t *__envp); +int feholdexcept(fenv_t *__envp); +int fesetenv(const fenv_t *__envp); +int feupdateenv(const fenv_t *__envp); +#else +__fenv_static inline int +feclearexcept(int __excepts) +{ + + __asm __volatile("csrc fflags, %0" :: "r"(__excepts)); + + return (0); +} + +__fenv_static inline int +fegetexceptflag(fexcept_t *__flagp, int __excepts) +{ + fexcept_t __fcsr; + + __rfs(__fcsr); + *__flagp = __fcsr & __excepts; + + return (0); +} + +__fenv_static inline int +fesetexceptflag(const fexcept_t *__flagp, int __excepts) +{ + fexcept_t __fcsr; + + __fcsr = *__flagp; + __asm __volatile("csrc fflags, %0" :: "r"(__excepts)); + __asm __volatile("csrs fflags, %0" :: "r"(__fcsr & __excepts)); + + return (0); +} + +__fenv_static inline int +feraiseexcept(int __excepts) +{ + + __asm __volatile("csrs fflags, %0" :: "r"(__excepts)); + + return (0); +} + +__fenv_static inline int +fetestexcept(int __excepts) +{ + fexcept_t __fcsr; + + __rfs(__fcsr); + + return (__fcsr & __excepts); +} + +__fenv_static inline int +fegetround(void) +{ + fexcept_t __fcsr; + + __rfs(__fcsr); + + return (__fcsr & _ROUND_MASK); +} + +__fenv_static inline int +fesetround(int __round) +{ + fexcept_t __fcsr; + + if (__round & ~_ROUND_MASK) + return (-1); + + __rfs(__fcsr); + __fcsr &= ~_ROUND_MASK; + __fcsr |= __round; + __wfs(__fcsr); + + return (0); +} + +__fenv_static inline int +fegetenv(fenv_t *__envp) +{ + + __rfs(*__envp); + + return (0); +} + +__fenv_static inline int +feholdexcept(fenv_t *__envp) +{ + + /* No exception traps. */ + + return (-1); +} + +__fenv_static inline int +fesetenv(const fenv_t *__envp) +{ + + __wfs(*__envp); + + return (0); +} + +__fenv_static inline int +feupdateenv(const fenv_t *__envp) +{ + fexcept_t __fcsr; + + __rfs(__fcsr); + __wfs(*__envp); + feraiseexcept(__fcsr & FE_ALL_EXCEPT); + + return (0); +} +#endif /* !__riscv_float_abi_soft */ + +#if __BSD_VISIBLE + +/* We currently provide no external definitions of the functions below. */ + +#ifdef __riscv_float_abi_soft +int feenableexcept(int __mask); +int fedisableexcept(int __mask); +int fegetexcept(void); +#else +static inline int +feenableexcept(int __mask) +{ + + /* No exception traps. */ + + return (-1); +} + +static inline int +fedisableexcept(int __mask) +{ + + /* No exception traps. */ + + return (0); +} + +static inline int +fegetexcept(void) +{ + + /* No exception traps. */ + + return (0); +} +#endif /* !__riscv_float_abi_soft */ + +#endif /* __BSD_VISIBLE */ + +__END_DECLS + +#endif /* !_FENV_H_ */ diff --git a/src/openlibm/include/openlibm_fenv_s390.h b/src/openlibm/include/openlibm_fenv_s390.h new file mode 100644 index 0000000..84ef080 --- /dev/null +++ b/src/openlibm/include/openlibm_fenv_s390.h @@ -0,0 +1,235 @@ +/*- + * Copyright (c) 2016 Dan Horák + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _FENV_H_ +#define _FENV_H_ + +#include + +#ifndef __fenv_static +#define __fenv_static static +#endif + +typedef __uint32_t fenv_t; +typedef __uint32_t fexcept_t; + +/* Exception flags */ +#define FE_INEXACT 0x080000 +#define FE_UNDERFLOW 0x100000 +#define FE_OVERFLOW 0x200000 +#define FE_DIVBYZERO 0x400000 +#define FE_INVALID 0x800000 /* all types of invalid FP ops */ + +#define FE_ALL_EXCEPT (FE_INVALID | FE_DIVBYZERO | FE_INEXACT | FE_OVERFLOW | FE_UNDERFLOW) + +/* Rounding modes */ +#define FE_TONEAREST 0x0000 +#define FE_TOWARDZERO 0x0001 +#define FE_UPWARD 0x0002 +#define FE_DOWNWARD 0x0003 +#define _ROUND_MASK (FE_TONEAREST | FE_DOWNWARD | \ + FE_UPWARD | FE_TOWARDZERO) + +__BEGIN_DECLS + +/* Default floating-point environment */ +extern const fenv_t __fe_dfl_env; +#define FE_DFL_ENV (&__fe_dfl_env) + +/* We need to be able to map status flag positions to mask flag positions */ +#define _FPC_EXC_MASK_SHIFT 8 +#define _ENABLE_MASK ((FE_DIVBYZERO | FE_INEXACT | FE_INVALID | \ + FE_OVERFLOW | FE_UNDERFLOW) << _FPC_EXC_MASK_SHIFT) + +/* Macros for accessing the hardware control word. */ +#define _FPU_GETCW(cw) __asm__ __volatile__ ("efpc %0,0" : "=d" (cw)) +#define _FPU_SETCW(cw) __asm__ __volatile__ ("sfpc %0,0" : : "d" (cw)) + +__fenv_static inline int +feclearexcept(int __excepts) +{ + fexcept_t __r; + + if (__excepts & FE_INVALID) + __excepts |= FE_ALL_EXCEPT; + _FPU_GETCW(__r); + __r &= ~__excepts; + _FPU_SETCW(__r); + return (0); +} + +__fenv_static inline int +fegetexceptflag(fexcept_t *__flagp, int __excepts) +{ + fexcept_t __r; + + _FPU_GETCW(__r); + *__flagp = __r & __excepts; + return (0); +} + +__fenv_static inline int +fesetexceptflag(const fexcept_t *__flagp, int __excepts) +{ + fexcept_t __r; + + if (__excepts & FE_INVALID) + __excepts |= FE_ALL_EXCEPT; + _FPU_GETCW(__r); + __r &= ~__excepts; + __r |= *__flagp & __excepts; + _FPU_SETCW(__r); + return (0); +} + +__fenv_static inline int +feraiseexcept(int __excepts) +{ + fexcept_t __r; + + _FPU_GETCW(__r); + __r |= __excepts; + _FPU_SETCW(__r); + return (0); +} + +__fenv_static inline int +fetestexcept(int __excepts) +{ + fexcept_t __r; + + _FPU_GETCW(__r); + return (__r & __excepts); +} + +__fenv_static inline int +fegetround(void) +{ + fexcept_t __r; + + _FPU_GETCW(__r); + return (__r & _ROUND_MASK); +} + +__fenv_static inline int +fesetround(int __round) +{ + fexcept_t __r; + + if (__round & ~_ROUND_MASK) + return (-1); + + _FPU_GETCW(__r); + __r &= ~_ROUND_MASK; + __r |= __round; + _FPU_SETCW(__r); + return (0); +} + +__fenv_static inline int +fegetenv(fenv_t *__envp) +{ + _FPU_GETCW(*__envp); + return (0); +} + +__fenv_static inline int +feholdexcept(fenv_t *__envp) +{ + fexcept_t __r; + + _FPU_GETCW(__r); + *__envp = __r; + __r &= ~(FE_ALL_EXCEPT | _ENABLE_MASK); + _FPU_SETCW(__r); + return (0); +} + +__fenv_static inline int +fesetenv(const fenv_t *__envp) +{ + _FPU_SETCW(*__envp); + return (0); +} + +__fenv_static inline int +feupdateenv(const fenv_t *__envp) +{ + fexcept_t __r; + + _FPU_GETCW(__r); + __r &= FE_ALL_EXCEPT; + __r |= *__envp; + _FPU_SETCW(__r); + return (0); +} + +#if __BSD_VISIBLE + +/* We currently provide no external definitions of the functions below. */ + +static inline int +feenableexcept(int __mask) +{ + fenv_t __r; + fenv_t __oldmask; + + _FPU_GETCW(__r); + __oldmask = __r; + __r |= (__mask & FE_ALL_EXCEPT) << _FPC_EXC_MASK_SHIFT; + _FPU_SETCW(__r); + return ((__oldmask & _ENABLE_MASK) >> _FPC_EXC_MASK_SHIFT); +} + +static inline int +fedisableexcept(int __mask) +{ + fenv_t __r; + fenv_t __oldmask; + + _FPU_GETCW(__r); + __oldmask = __r; + __r &= ~((__mask & FE_ALL_EXCEPT) << _FPC_EXC_MASK_SHIFT); + _FPU_SETCW(__r); + return ((__oldmask & _ENABLE_MASK) >> _FPC_EXC_MASK_SHIFT); +} + +static inline int +fegetexcept(void) +{ + fexcept_t __r; + + _FPU_GETCW(__r); + return (__r & (_ENABLE_MASK >> _FPC_EXC_MASK_SHIFT)); +} + +#endif /* __BSD_VISIBLE */ + +__END_DECLS + +#endif /* !_FENV_H_ */ diff --git a/src/openlibm/include/openlibm_math.h b/src/openlibm/include/openlibm_math.h new file mode 100644 index 0000000..701ad70 --- /dev/null +++ b/src/openlibm/include/openlibm_math.h @@ -0,0 +1,493 @@ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * from: @(#)fdlibm.h 5.1 93/09/24 + * $FreeBSD: src/lib/msun/src/openlibm.h,v 1.82 2011/11/12 19:55:48 theraven Exp $ + */ + +#ifdef OPENLIBM_USE_HOST_MATH_H +#include +#else /* !OPENLIBM_USE_HOST_MATH_H */ + +#include + +#ifndef OPENLIBM_MATH_H +#define OPENLIBM_MATH_H + +#if (defined(_WIN32) || defined (_MSC_VER)) && !defined(__WIN32__) + #define __WIN32__ +#endif + +#if !defined(__arm__) && !defined(__wasm__) +#define OLM_LONG_DOUBLE +#endif + +#ifndef __pure2 +#define __pure2 +#endif + +/* + * ANSI/POSIX + */ +extern const union __infinity_un { + unsigned char __uc[8]; + double __ud; +} __infinity; + +extern const union __nan_un { + unsigned char __uc[sizeof(float)]; + float __uf; +} __nan; + +/* VBS +#if __GNUC_PREREQ__(3, 3) || (defined(__INTEL_COMPILER) && __INTEL_COMPILER >= 800) +#define __MATH_BUILTIN_CONSTANTS +#endif + +#if __GNUC_PREREQ__(3, 0) && !defined(__INTEL_COMPILER) +#define __MATH_BUILTIN_RELOPS +#endif +*/ + +//VBS begin +#define __MATH_BUILTIN_CONSTANTS +#define __MATH_BUILTIN_RELOPS +#ifndef __ISO_C_VISIBLE +#define __ISO_C_VISIBLE 1999 +#endif +//VBS end + +#ifdef __MATH_BUILTIN_CONSTANTS +#define HUGE_VAL __builtin_huge_val() +#else +#define HUGE_VAL (__infinity.__ud) +#endif + +#if __ISO_C_VISIBLE >= 1999 +#define FP_ILOGB0 (-INT_MAX) +#define FP_ILOGBNAN INT_MAX + +#ifdef __MATH_BUILTIN_CONSTANTS +#define HUGE_VALF __builtin_huge_valf() +#define HUGE_VALL __builtin_huge_vall() +#define INFINITY __builtin_inff() +#define NAN __builtin_nanf("") +#else +#define HUGE_VALF (float)HUGE_VAL +#define HUGE_VALL (long double)HUGE_VAL +#define INFINITY HUGE_VALF +#define NAN (__nan.__uf) +#endif /* __MATH_BUILTIN_CONSTANTS */ + +#define MATH_ERRNO 1 +#define MATH_ERREXCEPT 2 +#define math_errhandling MATH_ERREXCEPT + +#define FP_FAST_FMAF 1 +#ifdef __ia64__ +#define FP_FAST_FMA 1 +#define FP_FAST_FMAL 1 +#endif + +/* Symbolic constants to classify floating point numbers. */ +#define FP_INFINITE 0x01 +#define FP_NAN 0x02 +#define FP_NORMAL 0x04 +#define FP_SUBNORMAL 0x08 +#define FP_ZERO 0x10 +#define fpclassify(x) \ + ((sizeof (x) == sizeof (float)) ? __fpclassifyf(x) \ + : (sizeof (x) == sizeof (double)) ? __fpclassifyd(x) \ + : __fpclassifyl(x)) + +#define isfinite(x) \ + ((sizeof (x) == sizeof (float)) ? __isfinitef(x) \ + : (sizeof (x) == sizeof (double)) ? __isfinite(x) \ + : __isfinitel(x)) +#define isinf(x) \ + ((sizeof (x) == sizeof (float)) ? __isinff(x) \ + : (sizeof (x) == sizeof (double)) ? isinf(x) \ + : __isinfl(x)) +#define isnan(x) \ + ((sizeof (x) == sizeof (float)) ? __isnanf(x) \ + : (sizeof (x) == sizeof (double)) ? isnan(x) \ + : __isnanl(x)) +#define isnormal(x) \ + ((sizeof (x) == sizeof (float)) ? __isnormalf(x) \ + : (sizeof (x) == sizeof (double)) ? __isnormal(x) \ + : __isnormall(x)) + +#ifdef __MATH_BUILTIN_RELOPS +#define isgreater(x, y) __builtin_isgreater((x), (y)) +#define isgreaterequal(x, y) __builtin_isgreaterequal((x), (y)) +#define isless(x, y) __builtin_isless((x), (y)) +#define islessequal(x, y) __builtin_islessequal((x), (y)) +#define islessgreater(x, y) __builtin_islessgreater((x), (y)) +#define isunordered(x, y) __builtin_isunordered((x), (y)) +#else +#define isgreater(x, y) (!isunordered((x), (y)) && (x) > (y)) +#define isgreaterequal(x, y) (!isunordered((x), (y)) && (x) >= (y)) +#define isless(x, y) (!isunordered((x), (y)) && (x) < (y)) +#define islessequal(x, y) (!isunordered((x), (y)) && (x) <= (y)) +#define islessgreater(x, y) (!isunordered((x), (y)) && \ + ((x) > (y) || (y) > (x))) +#define isunordered(x, y) (isnan(x) || isnan(y)) +#endif /* __MATH_BUILTIN_RELOPS */ + +#define signbit(x) \ + ((sizeof (x) == sizeof (float)) ? __signbitf(x) \ + : (sizeof (x) == sizeof (double)) ? __signbit(x) \ + : __signbitl(x)) + +//VBS +//typedef __double_t double_t; +//typedef __float_t float_t; +#endif /* __ISO_C_VISIBLE >= 1999 */ + +/* + * XOPEN/SVID + */ +#if __BSD_VISIBLE || __XSI_VISIBLE +#define M_E 2.7182818284590452354 /* e */ +#define M_LOG2E 1.4426950408889634074 /* log 2e */ +#define M_LOG10E 0.43429448190325182765 /* log 10e */ +#define M_LN2 0.69314718055994530942 /* log e2 */ +#define M_LN10 2.30258509299404568402 /* log e10 */ +#define M_PI 3.14159265358979323846 /* pi */ +#define M_PI_2 1.57079632679489661923 /* pi/2 */ +#define M_PI_4 0.78539816339744830962 /* pi/4 */ +#define M_1_PI 0.31830988618379067154 /* 1/pi */ +#define M_2_PI 0.63661977236758134308 /* 2/pi */ +#define M_2_SQRTPI 1.12837916709551257390 /* 2/sqrt(pi) */ +#define M_SQRT2 1.41421356237309504880 /* sqrt(2) */ +#define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */ + +#define MAXFLOAT ((float)3.40282346638528860e+38) + +#ifndef OPENLIBM_ONLY_THREAD_SAFE +OLM_DLLEXPORT extern int signgam; +#endif +#endif /* __BSD_VISIBLE || __XSI_VISIBLE */ + +#if __BSD_VISIBLE +#if 0 +/* Old value from 4.4BSD-Lite openlibm.h; this is probably better. */ +#define HUGE HUGE_VAL +#else +#define HUGE MAXFLOAT +#endif +#endif /* __BSD_VISIBLE */ + +/* + * Most of these functions depend on the rounding mode and have the side + * effect of raising floating-point exceptions, so they are not declared + * as __pure2. In C99, FENV_ACCESS affects the purity of these functions. + */ + +#if defined(__cplusplus) +extern "C" { +#endif +/* Symbol present when OpenLibm is used. */ +int isopenlibm(void); + +/* + * ANSI/POSIX + */ +OLM_DLLEXPORT int __fpclassifyd(double) __pure2; +OLM_DLLEXPORT int __fpclassifyf(float) __pure2; +OLM_DLLEXPORT int __fpclassifyl(long double) __pure2; +OLM_DLLEXPORT int __isfinitef(float) __pure2; +OLM_DLLEXPORT int __isfinite(double) __pure2; +OLM_DLLEXPORT int __isfinitel(long double) __pure2; +OLM_DLLEXPORT int __isinff(float) __pure2; +OLM_DLLEXPORT int __isinfl(long double) __pure2; +OLM_DLLEXPORT int __isnanf(float) __pure2; +OLM_DLLEXPORT int __isnanl(long double) __pure2; +OLM_DLLEXPORT int __isnormalf(float) __pure2; +OLM_DLLEXPORT int __isnormal(double) __pure2; +OLM_DLLEXPORT int __isnormall(long double) __pure2; +OLM_DLLEXPORT int __signbit(double) __pure2; +OLM_DLLEXPORT int __signbitf(float) __pure2; +OLM_DLLEXPORT int __signbitl(long double) __pure2; + +OLM_DLLEXPORT double acos(double); +OLM_DLLEXPORT double asin(double); +OLM_DLLEXPORT double atan(double); +OLM_DLLEXPORT double atan2(double, double); +OLM_DLLEXPORT double cos(double); +OLM_DLLEXPORT double sin(double); +OLM_DLLEXPORT double tan(double); + +OLM_DLLEXPORT double cosh(double); +OLM_DLLEXPORT double sinh(double); +OLM_DLLEXPORT double tanh(double); + +OLM_DLLEXPORT double exp(double); +OLM_DLLEXPORT double frexp(double, int *); /* fundamentally !__pure2 */ +OLM_DLLEXPORT double ldexp(double, int); +OLM_DLLEXPORT double log(double); +OLM_DLLEXPORT double log10(double); +OLM_DLLEXPORT double modf(double, double *); /* fundamentally !__pure2 */ + +OLM_DLLEXPORT double pow(double, double); +OLM_DLLEXPORT double sqrt(double); + +OLM_DLLEXPORT double ceil(double); +OLM_DLLEXPORT double fabs(double) __pure2; +OLM_DLLEXPORT double floor(double); +OLM_DLLEXPORT double fmod(double, double); + +/* + * These functions are not in C90. + */ +#if __BSD_VISIBLE || __ISO_C_VISIBLE >= 1999 || __XSI_VISIBLE +OLM_DLLEXPORT double acosh(double); +OLM_DLLEXPORT double asinh(double); +OLM_DLLEXPORT double atanh(double); +OLM_DLLEXPORT double cbrt(double); +OLM_DLLEXPORT double erf(double); +OLM_DLLEXPORT double erfc(double); +OLM_DLLEXPORT double exp2(double); +OLM_DLLEXPORT double expm1(double); +OLM_DLLEXPORT double fma(double, double, double); +OLM_DLLEXPORT double hypot(double, double); +OLM_DLLEXPORT int ilogb(double) __pure2; +OLM_DLLEXPORT int (isinf)(double) __pure2; +OLM_DLLEXPORT int (isnan)(double) __pure2; +OLM_DLLEXPORT double lgamma(double); +OLM_DLLEXPORT long long llrint(double); +OLM_DLLEXPORT long long llround(double); +OLM_DLLEXPORT double log1p(double); +OLM_DLLEXPORT double log2(double); +OLM_DLLEXPORT double logb(double); +OLM_DLLEXPORT long lrint(double); +OLM_DLLEXPORT long lround(double); +OLM_DLLEXPORT double nan(const char *) __pure2; +OLM_DLLEXPORT double nextafter(double, double); +OLM_DLLEXPORT double remainder(double, double); +OLM_DLLEXPORT double remquo(double, double, int *); +OLM_DLLEXPORT double rint(double); +#endif /* __BSD_VISIBLE || __ISO_C_VISIBLE >= 1999 || __XSI_VISIBLE */ + +#if __BSD_VISIBLE || __XSI_VISIBLE +OLM_DLLEXPORT double j0(double); +OLM_DLLEXPORT double j1(double); +OLM_DLLEXPORT double jn(int, double); +OLM_DLLEXPORT double y0(double); +OLM_DLLEXPORT double y1(double); +OLM_DLLEXPORT double yn(int, double); +#endif /* __BSD_VISIBLE || __XSI_VISIBLE */ + +#if __BSD_VISIBLE || __ISO_C_VISIBLE >= 1999 +OLM_DLLEXPORT double copysign(double, double) __pure2; +OLM_DLLEXPORT double fdim(double, double); +OLM_DLLEXPORT double fmax(double, double) __pure2; +OLM_DLLEXPORT double fmin(double, double) __pure2; +OLM_DLLEXPORT double nearbyint(double); +OLM_DLLEXPORT double round(double); +OLM_DLLEXPORT double scalbln(double, long); +OLM_DLLEXPORT double scalbn(double, int); +OLM_DLLEXPORT double tgamma(double); +OLM_DLLEXPORT double trunc(double); +#endif + +/* + * BSD math library entry points + */ +#if __BSD_VISIBLE +OLM_DLLEXPORT int isinff(float) __pure2; +OLM_DLLEXPORT int isnanf(float) __pure2; + +/* + * Reentrant version of lgamma; passes signgam back by reference as the + * second argument; user must allocate space for signgam. + */ +OLM_DLLEXPORT double lgamma_r(double, int *); + +/* + * Single sine/cosine function. + */ +OLM_DLLEXPORT void sincos(double, double *, double *); +#endif /* __BSD_VISIBLE */ + +/* float versions of ANSI/POSIX functions */ +#if __ISO_C_VISIBLE >= 1999 +OLM_DLLEXPORT float acosf(float); +OLM_DLLEXPORT float asinf(float); +OLM_DLLEXPORT float atanf(float); +OLM_DLLEXPORT float atan2f(float, float); +OLM_DLLEXPORT float cosf(float); +OLM_DLLEXPORT float sinf(float); +OLM_DLLEXPORT float tanf(float); + +OLM_DLLEXPORT float coshf(float); +OLM_DLLEXPORT float sinhf(float); +OLM_DLLEXPORT float tanhf(float); + +OLM_DLLEXPORT float exp2f(float); +OLM_DLLEXPORT float expf(float); +OLM_DLLEXPORT float expm1f(float); +OLM_DLLEXPORT float frexpf(float, int *); /* fundamentally !__pure2 */ +OLM_DLLEXPORT int ilogbf(float) __pure2; +OLM_DLLEXPORT float ldexpf(float, int); +OLM_DLLEXPORT float log10f(float); +OLM_DLLEXPORT float log1pf(float); +OLM_DLLEXPORT float log2f(float); +OLM_DLLEXPORT float logf(float); +OLM_DLLEXPORT float modff(float, float *); /* fundamentally !__pure2 */ + +OLM_DLLEXPORT float powf(float, float); +OLM_DLLEXPORT float sqrtf(float); + +OLM_DLLEXPORT float ceilf(float); +OLM_DLLEXPORT float fabsf(float) __pure2; +OLM_DLLEXPORT float floorf(float); +OLM_DLLEXPORT float fmodf(float, float); +OLM_DLLEXPORT float roundf(float); + +OLM_DLLEXPORT float erff(float); +OLM_DLLEXPORT float erfcf(float); +OLM_DLLEXPORT float hypotf(float, float); +OLM_DLLEXPORT float lgammaf(float); +OLM_DLLEXPORT float tgammaf(float); + +OLM_DLLEXPORT float acoshf(float); +OLM_DLLEXPORT float asinhf(float); +OLM_DLLEXPORT float atanhf(float); +OLM_DLLEXPORT float cbrtf(float); +OLM_DLLEXPORT float logbf(float); +OLM_DLLEXPORT float copysignf(float, float) __pure2; +OLM_DLLEXPORT long long llrintf(float); +OLM_DLLEXPORT long long llroundf(float); +OLM_DLLEXPORT long lrintf(float); +OLM_DLLEXPORT long lroundf(float); +OLM_DLLEXPORT float nanf(const char *) __pure2; +OLM_DLLEXPORT float nearbyintf(float); +OLM_DLLEXPORT float nextafterf(float, float); +OLM_DLLEXPORT float remainderf(float, float); +OLM_DLLEXPORT float remquof(float, float, int *); +OLM_DLLEXPORT float rintf(float); +OLM_DLLEXPORT float scalblnf(float, long); +OLM_DLLEXPORT float scalbnf(float, int); +OLM_DLLEXPORT float truncf(float); + +OLM_DLLEXPORT float fdimf(float, float); +OLM_DLLEXPORT float fmaf(float, float, float); +OLM_DLLEXPORT float fmaxf(float, float) __pure2; +OLM_DLLEXPORT float fminf(float, float) __pure2; +#endif + +/* + * float versions of BSD math library entry points + */ +#if __BSD_VISIBLE +OLM_DLLEXPORT float dremf(float, float); +OLM_DLLEXPORT float j0f(float); +OLM_DLLEXPORT float j1f(float); +OLM_DLLEXPORT float jnf(int, float); +OLM_DLLEXPORT float y0f(float); +OLM_DLLEXPORT float y1f(float); +OLM_DLLEXPORT float ynf(int, float); + +/* + * Float versions of reentrant version of lgamma; passes signgam back by + * reference as the second argument; user must allocate space for signgam. + */ +OLM_DLLEXPORT float lgammaf_r(float, int *); + +/* + * Single sine/cosine function. + */ +OLM_DLLEXPORT void sincosf(float, float *, float *); +#endif /* __BSD_VISIBLE */ + +/* + * long double versions of ISO/POSIX math functions + */ +#if __ISO_C_VISIBLE >= 1999 +OLM_DLLEXPORT long double acoshl(long double); +OLM_DLLEXPORT long double acosl(long double); +OLM_DLLEXPORT long double asinhl(long double); +OLM_DLLEXPORT long double asinl(long double); +OLM_DLLEXPORT long double atan2l(long double, long double); +OLM_DLLEXPORT long double atanhl(long double); +OLM_DLLEXPORT long double atanl(long double); +OLM_DLLEXPORT long double cbrtl(long double); +OLM_DLLEXPORT long double ceill(long double); +OLM_DLLEXPORT long double copysignl(long double, long double) __pure2; +OLM_DLLEXPORT long double coshl(long double); +OLM_DLLEXPORT long double cosl(long double); +OLM_DLLEXPORT long double erfcl(long double); +OLM_DLLEXPORT long double erfl(long double); +OLM_DLLEXPORT long double exp2l(long double); +OLM_DLLEXPORT long double expl(long double); +OLM_DLLEXPORT long double expm1l(long double); +OLM_DLLEXPORT long double fabsl(long double) __pure2; +OLM_DLLEXPORT long double fdiml(long double, long double); +OLM_DLLEXPORT long double floorl(long double); +OLM_DLLEXPORT long double fmal(long double, long double, long double); +OLM_DLLEXPORT long double fmaxl(long double, long double) __pure2; +OLM_DLLEXPORT long double fminl(long double, long double) __pure2; +OLM_DLLEXPORT long double fmodl(long double, long double); +OLM_DLLEXPORT long double frexpl(long double value, int *); /* fundamentally !__pure2 */ +OLM_DLLEXPORT long double hypotl(long double, long double); +OLM_DLLEXPORT int ilogbl(long double) __pure2; +OLM_DLLEXPORT long double ldexpl(long double, int); +OLM_DLLEXPORT long double lgammal(long double); +OLM_DLLEXPORT long long llrintl(long double); +OLM_DLLEXPORT long long llroundl(long double); +OLM_DLLEXPORT long double log10l(long double); +OLM_DLLEXPORT long double log1pl(long double); +OLM_DLLEXPORT long double log2l(long double); +OLM_DLLEXPORT long double logbl(long double); +OLM_DLLEXPORT long double logl(long double); +OLM_DLLEXPORT long lrintl(long double); +OLM_DLLEXPORT long lroundl(long double); +OLM_DLLEXPORT long double modfl(long double, long double *); /* fundamentally !__pure2 */ +OLM_DLLEXPORT long double nanl(const char *) __pure2; +OLM_DLLEXPORT long double nearbyintl(long double); +OLM_DLLEXPORT long double nextafterl(long double, long double); +OLM_DLLEXPORT double nexttoward(double, long double); +OLM_DLLEXPORT float nexttowardf(float, long double); +OLM_DLLEXPORT long double nexttowardl(long double, long double); +OLM_DLLEXPORT long double powl(long double, long double); +OLM_DLLEXPORT long double remainderl(long double, long double); +OLM_DLLEXPORT long double remquol(long double, long double, int *); +OLM_DLLEXPORT long double rintl(long double); +OLM_DLLEXPORT long double roundl(long double); +OLM_DLLEXPORT long double scalblnl(long double, long); +OLM_DLLEXPORT long double scalbnl(long double, int); +OLM_DLLEXPORT long double sinhl(long double); +OLM_DLLEXPORT long double sinl(long double); +OLM_DLLEXPORT long double sqrtl(long double); +OLM_DLLEXPORT long double tanhl(long double); +OLM_DLLEXPORT long double tanl(long double); +OLM_DLLEXPORT long double tgammal(long double); +OLM_DLLEXPORT long double truncl(long double); +#endif /* __ISO_C_VISIBLE >= 1999 */ + +/* Reentrant version of lgammal. */ +#if __BSD_VISIBLE +OLM_DLLEXPORT long double lgammal_r(long double, int *); + +/* + * Single sine/cosine function. + */ +OLM_DLLEXPORT void sincosl(long double, long double *, long double *); +#endif /* __BSD_VISIBLE */ + +#if defined(__cplusplus) +} +#endif +#endif /* !OPENLIBM_MATH_H */ + +#endif /* OPENLIBM_USE_HOST_MATH_H */ diff --git a/src/openlibm/ld128/Make.files b/src/openlibm/ld128/Make.files new file mode 100644 index 0000000..1198cfb --- /dev/null +++ b/src/openlibm/ld128/Make.files @@ -0,0 +1,13 @@ +$(CUR_SRCS) += invtrig.c \ + e_acoshl.c e_powl.c k_tanl.c s_exp2l.c \ + e_atanhl.c e_lgammal_r.c e_sinhl.c s_asinhl.c s_expm1l.c \ + e_coshl.c e_log10l.c e_tgammal.c \ + e_expl.c e_log2l.c k_cosl.c s_log1pl.c s_tanhl.c \ + e_logl.c k_sinl.c s_erfl.c + +# s_remquol.c e_fmodl.c s_truncl.c +# e_hypotl.c s_floorl.c s_nextafterl.c s_ceill.c s_modfl.c + +ifneq ($(OS), WINNT) +$(CUR_SRCS) += s_nanl.c +endif diff --git a/src/openlibm/ld128/e_acoshl.c b/src/openlibm/ld128/e_acoshl.c new file mode 100644 index 0000000..e7cfd03 --- /dev/null +++ b/src/openlibm/ld128/e_acoshl.c @@ -0,0 +1,58 @@ +/* @(#)e_acosh.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* acoshl(x) + * Method : + * Based on + * acoshl(x) = logl [ x + sqrtl(x*x-1) ] + * we have + * acoshl(x) := logl(x)+ln2, if x is large; else + * acoshl(x) := logl(2x-1/(sqrtl(x*x-1)+x)) if x>2; else + * acoshl(x) := log1pl(t+sqrtl(2.0*t+t*t)); where t=x-1. + * + * Special cases: + * acoshl(x) is NaN with signal if x<1. + * acoshl(NaN) is NaN without signal. + */ + +#include + +#include "math_private.h" + +static const long double +one = 1.0, +ln2 = 0.6931471805599453094172321214581766L; + +long double +acoshl(long double x) +{ + long double t; + u_int64_t lx; + int64_t hx; + GET_LDOUBLE_WORDS64(hx,lx,x); + if(hx<0x3fff000000000000LL) { /* x < 1 */ + return (x-x)/(x-x); + } else if(hx >=0x4035000000000000LL) { /* x > 2**54 */ + if(hx >=0x7fff000000000000LL) { /* x is inf of NaN */ + return x+x; + } else + return logl(x)+ln2; /* acoshl(huge)=logl(2x) */ + } else if(((hx-0x3fff000000000000LL)|lx)==0) { + return 0.0L; /* acosh(1) = 0 */ + } else if (hx > 0x4000000000000000LL) { /* 2**28 > x > 2 */ + t=x*x; + return logl(2.0L*x-one/(x+sqrtl(t-one))); + } else { /* 1=0.5 + * 1 2x x + * atanhl(x) = --- * log(1 + -------) = 0.5 * log1p(2 * --------) + * 2 1 - x 1 - x + * + * For x<0.5 + * atanhl(x) = 0.5*log1pl(2x+2x*x/(1-x)) + * + * Special cases: + * atanhl(x) is NaN if |x| > 1 with signal; + * atanhl(NaN) is that NaN with no signal; + * atanhl(+-1) is +-INF with signal. + * + */ + +#include + +#include "math_private.h" + +static const long double one = 1.0L, huge = 1e4900L; + +static const long double zero = 0.0L; + +long double +atanhl(long double x) +{ + long double t; + u_int32_t jx, ix; + ieee_quad_shape_type u; + + u.value = x; + jx = u.parts32.mswhi; + ix = jx & 0x7fffffff; + u.parts32.mswhi = ix; + if (ix >= 0x3fff0000) /* |x| >= 1.0 or infinity or NaN */ + { + if (u.value == one) + return x/zero; + else + return (x-x)/(x-x); + } + if(ix<0x3fc60000 && (huge+x)>zero) return x; /* x < 2^-57 */ + + if(ix<0x3ffe0000) { /* x < 0.5 */ + t = u.value+u.value; + t = 0.5*log1pl(t+t*u.value/(one-u.value)); + } else + t = 0.5*log1pl((u.value+u.value)/(one-u.value)); + if(jx & 0x80000000) return -t; else return t; +} diff --git a/src/openlibm/ld128/e_coshl.c b/src/openlibm/ld128/e_coshl.c new file mode 100644 index 0000000..955c378 --- /dev/null +++ b/src/openlibm/ld128/e_coshl.c @@ -0,0 +1,105 @@ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * Copyright (c) 2008 Stephen L. Moshier + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* coshl(x) + * Method : + * mathematically coshl(x) if defined to be (exp(x)+exp(-x))/2 + * 1. Replace x by |x| (coshl(x) = coshl(-x)). + * 2. + * [ exp(x) - 1 ]^2 + * 0 <= x <= ln2/2 : coshl(x) := 1 + ------------------- + * 2*exp(x) + * + * exp(x) + 1/exp(x) + * ln2/2 <= x <= 22 : coshl(x) := ------------------- + * 2 + * 22 <= x <= lnovft : coshl(x) := expl(x)/2 + * lnovft <= x <= ln2ovft: coshl(x) := expl(x/2)/2 * expl(x/2) + * ln2ovft < x : coshl(x) := huge*huge (overflow) + * + * Special cases: + * coshl(x) is |x| if x is +INF, -INF, or NaN. + * only coshl(0)=1 is exact for finite x. + */ + +#include + +#include "math_private.h" + +static const long double one = 1.0, half = 0.5, huge = 1.0e4900L, +ovf_thresh = 1.1357216553474703894801348310092223067821E4L; + +long double +coshl(long double x) +{ + long double t, w; + int32_t ex; + ieee_quad_shape_type u; + + u.value = x; + ex = u.parts32.mswhi & 0x7fffffff; + + /* Absolute value of x. */ + u.parts32.mswhi = ex; + + /* x is INF or NaN */ + if (ex >= 0x7fff0000) + return x * x; + + /* |x| in [0,0.5*ln2], return 1+expm1l(|x|)^2/(2*expl(|x|)) */ + if (ex < 0x3ffd62e4) /* 0.3465728759765625 */ + { + t = expm1l (u.value); + w = one + t; + if (ex < 0x3fb80000) /* |x| < 2^-116 */ + return w; /* cosh(tiny) = 1 */ + + return one + (t * t) / (w + w); + } + + /* |x| in [0.5*ln2,40], return (exp(|x|)+1/exp(|x|)/2; */ + if (ex < 0x40044000) + { + t = expl (u.value); + return half * t + half / t; + } + + /* |x| in [22, ln(maxdouble)] return half*exp(|x|) */ + if (ex <= 0x400c62e3) /* 11356.375 */ + return half * expl (u.value); + + /* |x| in [log(maxdouble), overflowthresold] */ + if (u.value <= ovf_thresh) + { + w = expl (half * u.value); + t = half * w; + return t * w; + } + + /* |x| > overflowthresold, cosh(x) overflow */ + return huge * huge; +} diff --git a/src/openlibm/ld128/e_expl.c b/src/openlibm/ld128/e_expl.c new file mode 100644 index 0000000..24c7b50 --- /dev/null +++ b/src/openlibm/ld128/e_expl.c @@ -0,0 +1,145 @@ +/* $OpenBSD: e_expl.c,v 1.3 2013/11/12 20:35:18 martynas Exp $ */ + +/* + * Copyright (c) 2008 Stephen L. Moshier + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* expl.c + * + * Exponential function, 128-bit long double precision + * + * + * + * SYNOPSIS: + * + * long double x, y, expl(); + * + * y = expl( x ); + * + * + * + * DESCRIPTION: + * + * Returns e (2.71828...) raised to the x power. + * + * Range reduction is accomplished by separating the argument + * into an integer k and fraction f such that + * + * x k f + * e = 2 e. + * + * A Pade' form of degree 2/3 is used to approximate exp(f) - 1 + * in the basic range [-0.5 ln 2, 0.5 ln 2]. + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE +-MAXLOG 100,000 2.6e-34 8.6e-35 + * + * + * Error amplification in the exponential function can be + * a serious matter. The error propagation involves + * exp( X(1+delta) ) = exp(X) ( 1 + X*delta + ... ), + * which shows that a 1 lsb error in representing X produces + * a relative error of X times 1 lsb in the function. + * While the routine gives an accurate result for arguments + * that are exactly represented by a long double precision + * computer number, the result contains amplified roundoff + * error for large arguments not exactly represented. + * + * + * ERROR MESSAGES: + * + * message condition value returned + * exp underflow x < MINLOG 0.0 + * exp overflow x > MAXLOG MAXNUM + * + */ + +/* Exponential function */ + +#include +#include + +#include "math_private.h" + +/* Pade' coefficients for exp(x) - 1 + Theoretical peak relative error = 2.2e-37, + relative peak error spread = 9.2e-38 + */ +static long double P[5] = { + 3.279723985560247033712687707263393506266E-10L, + 6.141506007208645008909088812338454698548E-7L, + 2.708775201978218837374512615596512792224E-4L, + 3.508710990737834361215404761139478627390E-2L, + 9.999999999999999999999999999999999998502E-1L +}; +static long double Q[6] = { + 2.980756652081995192255342779918052538681E-12L, + 1.771372078166251484503904874657985291164E-8L, + 1.504792651814944826817779302637284053660E-5L, + 3.611828913847589925056132680618007270344E-3L, + 2.368408864814233538909747618894558968880E-1L, + 2.000000000000000000000000000000000000150E0L +}; +/* C1 + C2 = ln 2 */ +static const long double C1 = -6.93145751953125E-1L; +static const long double C2 = -1.428606820309417232121458176568075500134E-6L; + +static const long double LOG2EL = 1.442695040888963407359924681001892137426646L; +static const long double MAXLOGL = 1.1356523406294143949491931077970764891253E4L; +static const long double MINLOGL = -1.143276959615573793352782661133116431383730e4L; +static const long double huge = 0x1p10000L; +#if 0 /* XXX Prevent gcc from erroneously constant folding this. */ +static const long double twom10000 = 0x1p-10000L; +#else +static volatile long double twom10000 = 0x1p-10000L; +#endif + +long double +expl(long double x) +{ +long double px, xx; +int n; + +if( x > MAXLOGL) + return (huge*huge); /* overflow */ + +if( x < MINLOGL ) + return (twom10000*twom10000); /* underflow */ + +/* Express e**x = e**g 2**n + * = e**g e**( n loge(2) ) + * = e**( g + n loge(2) ) + */ +px = floorl( LOG2EL * x + 0.5L ); /* floor() truncates toward -infinity. */ +n = px; +x += px * C1; +x += px * C2; +/* rational approximation for exponential + * of the fractional part: + * e**x = 1 + 2x P(x**2)/( Q(x**2) - P(x**2) ) + */ +xx = x * x; +px = x * __polevll( xx, P, 4 ); +xx = __polevll( xx, Q, 5 ); +x = px/( xx - px ); +x = 1.0L + x + x; + +x = ldexpl( x, n ); +return(x); +} diff --git a/src/openlibm/ld128/e_fmodl.c b/src/openlibm/ld128/e_fmodl.c new file mode 100644 index 0000000..698fa3a --- /dev/null +++ b/src/openlibm/ld128/e_fmodl.c @@ -0,0 +1,129 @@ +/* @(#)e_fmod.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * fmodl(x,y) + * Return x mod y in exact arithmetic + * Method: shift and subtract + */ + +#include + +#include "math_private.h" + +static const long double one = 1.0, Zero[] = {0.0, -0.0,}; + +long double +fmodl(long double x, long double y) +{ + int64_t n,hx,hy,hz,ix,iy,sx,i; + u_int64_t lx,ly,lz; + + GET_LDOUBLE_WORDS64(hx,lx,x); + GET_LDOUBLE_WORDS64(hy,ly,y); + sx = hx&0x8000000000000000ULL; /* sign of x */ + hx ^=sx; /* |x| */ + hy &= 0x7fffffffffffffffLL; /* |y| */ + + /* purge off exception values */ + if((hy|ly)==0||(hx>=0x7fff000000000000LL)|| /* y=0,or x not finite */ + ((hy|((ly|-ly)>>63))>0x7fff000000000000LL)) /* or y is NaN */ + return (x*y)/(x*y); + if(hx<=hy) { + if((hx>63]; /* |x|=|y| return x*0*/ + } + + /* determine ix = ilogb(x) */ + if(hx<0x0001000000000000LL) { /* subnormal x */ + if(hx==0) { + for (ix = -16431, i=lx; i>0; i<<=1) ix -=1; + } else { + for (ix = -16382, i=hx<<15; i>0; i<<=1) ix -=1; + } + } else ix = (hx>>48)-0x3fff; + + /* determine iy = ilogb(y) */ + if(hy<0x0001000000000000LL) { /* subnormal y */ + if(hy==0) { + for (iy = -16431, i=ly; i>0; i<<=1) iy -=1; + } else { + for (iy = -16382, i=hy<<15; i>0; i<<=1) iy -=1; + } + } else iy = (hy>>48)-0x3fff; + + /* set up {hx,lx}, {hy,ly} and align y to x */ + if(ix >= -16382) + hx = 0x0001000000000000LL|(0x0000ffffffffffffLL&hx); + else { /* subnormal x, shift x to normal */ + n = -16382-ix; + if(n<=63) { + hx = (hx<>(64-n)); + lx <<= n; + } else { + hx = lx<<(n-64); + lx = 0; + } + } + if(iy >= -16382) + hy = 0x0001000000000000LL|(0x0000ffffffffffffLL&hy); + else { /* subnormal y, shift y to normal */ + n = -16382-iy; + if(n<=63) { + hy = (hy<>(64-n)); + ly <<= n; + } else { + hy = ly<<(n-64); + ly = 0; + } + } + + /* fix point fmod */ + n = ix - iy; + while(n--) { + hz=hx-hy;lz=lx-ly; if(lx>63); lx = lx+lx;} + else { + if((hz|lz)==0) /* return sign(x)*0 */ + return Zero[(u_int64_t)sx>>63]; + hx = hz+hz+(lz>>63); lx = lz+lz; + } + } + hz=hx-hy;lz=lx-ly; if(lx=0) {hx=hz;lx=lz;} + + /* convert back to floating value and restore the sign */ + if((hx|lx)==0) /* return sign(x)*0 */ + return Zero[(u_int64_t)sx>>63]; + while(hx<0x0001000000000000LL) { /* normalize x */ + hx = hx+hx+(lx>>63); lx = lx+lx; + iy -= 1; + } + if(iy>= -16382) { /* normalize output */ + hx = ((hx-0x0001000000000000LL)|((iy+16383)<<48)); + SET_LDOUBLE_WORDS64(x,hx|sx,lx); + } else { /* subnormal output */ + n = -16382 - iy; + if(n<=48) { + lx = (lx>>n)|((u_int64_t)hx<<(64-n)); + hx >>= n; + } else if (n<=63) { + lx = (hx<<(64-n))|(lx>>n); hx = sx; + } else { + lx = hx>>(n-64); hx = sx; + } + SET_LDOUBLE_WORDS64(x,hx|sx,lx); + x *= one; /* create necessary signal */ + } + return x; /* exact output */ +} diff --git a/src/openlibm/ld128/e_hypotl.c b/src/openlibm/ld128/e_hypotl.c new file mode 100644 index 0000000..1cdf3d8 --- /dev/null +++ b/src/openlibm/ld128/e_hypotl.c @@ -0,0 +1,122 @@ +/* @(#)e_hypot.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* hypotl(x,y) + * + * Method : + * If (assume round-to-nearest) z=x*x+y*y + * has error less than sqrtl(2)/2 ulp, than + * sqrtl(z) has error less than 1 ulp (exercise). + * + * So, compute sqrtl(x*x+y*y) with some care as + * follows to get the error below 1 ulp: + * + * Assume x>y>0; + * (if possible, set rounding to round-to-nearest) + * 1. if x > 2y use + * x1*x1+(y*y+(x2*(x+x1))) for x*x+y*y + * where x1 = x with lower 64 bits cleared, x2 = x-x1; else + * 2. if x <= 2y use + * t1*yy1+((x-y)*(x-y)+(t1*y2+t2*y)) + * where t1 = 2x with lower 64 bits cleared, t2 = 2x-t1, + * yy1= y with lower 64 bits chopped, y2 = y-yy1. + * + * NOTE: scaling may be necessary if some argument is too + * large or too tiny + * + * Special cases: + * hypotl(x,y) is INF if x or y is +INF or -INF; else + * hypotl(x,y) is NAN if x or y is NAN. + * + * Accuracy: + * hypotl(x,y) returns sqrtl(x^2+y^2) with error less + * than 1 ulps (units in the last place) + */ + +#include + +#include "math_private.h" + +long double +hypotl(long double x, long double y) +{ + long double a,b,t1,t2,yy1,y2,w; + int64_t j,k,ha,hb; + + GET_LDOUBLE_MSW64(ha,x); + ha &= 0x7fffffffffffffffLL; + GET_LDOUBLE_MSW64(hb,y); + hb &= 0x7fffffffffffffffLL; + if(hb > ha) {a=y;b=x;j=ha; ha=hb;hb=j;} else {a=x;b=y;} + SET_LDOUBLE_MSW64(a,ha); /* a <- |a| */ + SET_LDOUBLE_MSW64(b,hb); /* b <- |b| */ + if((ha-hb)>0x78000000000000LL) {return a+b;} /* x/y > 2**120 */ + k=0; + if(ha > 0x5f3f000000000000LL) { /* a>2**8000 */ + if(ha >= 0x7fff000000000000LL) { /* Inf or NaN */ + u_int64_t low; + w = a+b; /* for sNaN */ + GET_LDOUBLE_LSW64(low,a); + if(((ha&0xffffffffffffLL)|low)==0) w = a; + GET_LDOUBLE_LSW64(low,b); + if(((hb^0x7fff000000000000LL)|low)==0) w = b; + return w; + } + /* scale a and b by 2**-9600 */ + ha -= 0x2580000000000000LL; + hb -= 0x2580000000000000LL; k += 9600; + SET_LDOUBLE_MSW64(a,ha); + SET_LDOUBLE_MSW64(b,hb); + } + if(hb < 0x20bf000000000000LL) { /* b < 2**-8000 */ + if(hb <= 0x0000ffffffffffffLL) { /* subnormal b or 0 */ + u_int64_t low; + GET_LDOUBLE_LSW64(low,b); + if((hb|low)==0) return a; + t1=0; + SET_LDOUBLE_MSW64(t1,0x7ffd000000000000LL); /* t1=2^16382 */ + b *= t1; + a *= t1; + k -= 16382; + } else { /* scale a and b by 2^9600 */ + ha += 0x2580000000000000LL; /* a *= 2^9600 */ + hb += 0x2580000000000000LL; /* b *= 2^9600 */ + k -= 9600; + SET_LDOUBLE_MSW64(a,ha); + SET_LDOUBLE_MSW64(b,hb); + } + } + /* medium size a and b */ + w = a-b; + if (w>b) { + t1 = 0; + SET_LDOUBLE_MSW64(t1,ha); + t2 = a-t1; + w = sqrtl(t1*t1-(b*(-b)-t2*(a+t1))); + } else { + a = a+a; + yy1 = 0; + SET_LDOUBLE_MSW64(yy1,hb); + y2 = b - yy1; + t1 = 0; + SET_LDOUBLE_MSW64(t1,ha+0x0001000000000000LL); + t2 = a - t1; + w = sqrtl(t1*yy1-(w*(-w)-(t1*y2+t2*b))); + } + if(k!=0) { + u_int64_t high; + t1 = 1.0L; + GET_LDOUBLE_MSW64(high,t1); + SET_LDOUBLE_MSW64(t1,high+(k<<48)); + return t1*w; + } else return w; +} diff --git a/src/openlibm/ld128/e_lgammal_r.c b/src/openlibm/ld128/e_lgammal_r.c new file mode 100644 index 0000000..dd8ea5d --- /dev/null +++ b/src/openlibm/ld128/e_lgammal_r.c @@ -0,0 +1,1037 @@ +/* $OpenBSD: e_lgammal.c,v 1.3 2011/07/09 05:29:06 martynas Exp $ */ + +/* + * Copyright (c) 2008 Stephen L. Moshier + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* lgammal_r + * + * Natural logarithm of gamma function + * + * + * + * SYNOPSIS: + * + * long double x, y, lgammal_r(); + * int signgam; + * + * y = lgammal_r(x, &signgam); + * + * + * + * DESCRIPTION: + * + * Returns the base e (2.718...) logarithm of the absolute + * value of the gamma function of the argument. + * The sign (+1 or -1) of the gamma function is returned through signgamp. + * + * The positive domain is partitioned into numerous segments for approximation. + * For x > 10, + * log gamma(x) = (x - 0.5) log(x) - x + log sqrt(2 pi) + 1/x R(1/x^2) + * Near the minimum at x = x0 = 1.46... the approximation is + * log gamma(x0 + z) = log gamma(x0) + z^2 P(z)/Q(z) + * for small z. + * Elsewhere between 0 and 10, + * log gamma(n + z) = log gamma(n) + z P(z)/Q(z) + * for various selected n and small z. + * + * The cosecant reflection formula is employed for negative arguments. + * + * + * + * ACCURACY: + * + * + * arithmetic domain # trials peak rms + * Relative error: + * IEEE 10, 30 100000 3.9e-34 9.8e-35 + * IEEE 0, 10 100000 3.8e-34 5.3e-35 + * Absolute error: + * IEEE -10, 0 100000 8.0e-34 8.0e-35 + * IEEE -30, -10 100000 4.4e-34 1.0e-34 + * IEEE -100, 100 100000 1.0e-34 + * + * The absolute error criterion is the same as relative error + * when the function magnitude is greater than one but it is absolute + * when the magnitude is less than one. + * + */ + +#include + +#include "math_private.h" + +static const long double PIL = 3.1415926535897932384626433832795028841972E0L; +static const long double MAXLGM = 1.0485738685148938358098967157129705071571E4928L; +static const long double one = 1.0L; +static const long double huge = 1.0e4000L; + +/* log gamma(x) = ( x - 0.5 ) * log(x) - x + LS2PI + 1/x P(1/x^2) + 1/x <= 0.0741 (x >= 13.495...) + Peak relative error 1.5e-36 */ +static const long double ls2pi = 9.1893853320467274178032973640561763986140E-1L; +#define NRASY 12 +static const long double RASY[NRASY + 1] = +{ + 8.333333333333333333333333333310437112111E-2L, + -2.777777777777777777777774789556228296902E-3L, + 7.936507936507936507795933938448586499183E-4L, + -5.952380952380952041799269756378148574045E-4L, + 8.417508417507928904209891117498524452523E-4L, + -1.917526917481263997778542329739806086290E-3L, + 6.410256381217852504446848671499409919280E-3L, + -2.955064066900961649768101034477363301626E-2L, + 1.796402955865634243663453415388336954675E-1L, + -1.391522089007758553455753477688592767741E0L, + 1.326130089598399157988112385013829305510E1L, + -1.420412699593782497803472576479997819149E2L, + 1.218058922427762808938869872528846787020E3L +}; + + +/* log gamma(x+13) = log gamma(13) + x P(x)/Q(x) + -0.5 <= x <= 0.5 + 12.5 <= x+13 <= 13.5 + Peak relative error 1.1e-36 */ +static const long double lgam13a = 1.9987213134765625E1L; +static const long double lgam13b = 1.3608962611495173623870550785125024484248E-6L; +#define NRN13 7 +static const long double RN13[NRN13 + 1] = +{ + 8.591478354823578150238226576156275285700E11L, + 2.347931159756482741018258864137297157668E11L, + 2.555408396679352028680662433943000804616E10L, + 1.408581709264464345480765758902967123937E9L, + 4.126759849752613822953004114044451046321E7L, + 6.133298899622688505854211579222889943778E5L, + 3.929248056293651597987893340755876578072E3L, + 6.850783280018706668924952057996075215223E0L +}; +#define NRD13 6 +static const long double RD13[NRD13 + 1] = +{ + 3.401225382297342302296607039352935541669E11L, + 8.756765276918037910363513243563234551784E10L, + 8.873913342866613213078554180987647243903E9L, + 4.483797255342763263361893016049310017973E8L, + 1.178186288833066430952276702931512870676E7L, + 1.519928623743264797939103740132278337476E5L, + 7.989298844938119228411117593338850892311E2L + /* 1.0E0L */ +}; + + +/* log gamma(x+12) = log gamma(12) + x P(x)/Q(x) + -0.5 <= x <= 0.5 + 11.5 <= x+12 <= 12.5 + Peak relative error 4.1e-36 */ +static const long double lgam12a = 1.75023040771484375E1L; +static const long double lgam12b = 3.7687254483392876529072161996717039575982E-6L; +#define NRN12 7 +static const long double RN12[NRN12 + 1] = +{ + 4.709859662695606986110997348630997559137E11L, + 1.398713878079497115037857470168777995230E11L, + 1.654654931821564315970930093932954900867E10L, + 9.916279414876676861193649489207282144036E8L, + 3.159604070526036074112008954113411389879E7L, + 5.109099197547205212294747623977502492861E5L, + 3.563054878276102790183396740969279826988E3L, + 6.769610657004672719224614163196946862747E0L +}; +#define NRD12 6 +static const long double RD12[NRD12 + 1] = +{ + 1.928167007860968063912467318985802726613E11L, + 5.383198282277806237247492369072266389233E10L, + 5.915693215338294477444809323037871058363E9L, + 3.241438287570196713148310560147925781342E8L, + 9.236680081763754597872713592701048455890E6L, + 1.292246897881650919242713651166596478850E5L, + 7.366532445427159272584194816076600211171E2L + /* 1.0E0L */ +}; + + +/* log gamma(x+11) = log gamma(11) + x P(x)/Q(x) + -0.5 <= x <= 0.5 + 10.5 <= x+11 <= 11.5 + Peak relative error 1.8e-35 */ +static const long double lgam11a = 1.5104400634765625E1L; +static const long double lgam11b = 1.1938309890295225709329251070371882250744E-5L; +#define NRN11 7 +static const long double RN11[NRN11 + 1] = +{ + 2.446960438029415837384622675816736622795E11L, + 7.955444974446413315803799763901729640350E10L, + 1.030555327949159293591618473447420338444E10L, + 6.765022131195302709153994345470493334946E8L, + 2.361892792609204855279723576041468347494E7L, + 4.186623629779479136428005806072176490125E5L, + 3.202506022088912768601325534149383594049E3L, + 6.681356101133728289358838690666225691363E0L +}; +#define NRD11 6 +static const long double RD11[NRD11 + 1] = +{ + 1.040483786179428590683912396379079477432E11L, + 3.172251138489229497223696648369823779729E10L, + 3.806961885984850433709295832245848084614E9L, + 2.278070344022934913730015420611609620171E8L, + 7.089478198662651683977290023829391596481E6L, + 1.083246385105903533237139380509590158658E5L, + 6.744420991491385145885727942219463243597E2L + /* 1.0E0L */ +}; + + +/* log gamma(x+10) = log gamma(10) + x P(x)/Q(x) + -0.5 <= x <= 0.5 + 9.5 <= x+10 <= 10.5 + Peak relative error 5.4e-37 */ +static const long double lgam10a = 1.280181884765625E1L; +static const long double lgam10b = 8.6324252196112077178745667061642811492557E-6L; +#define NRN10 7 +static const long double RN10[NRN10 + 1] = +{ + -1.239059737177249934158597996648808363783E14L, + -4.725899566371458992365624673357356908719E13L, + -7.283906268647083312042059082837754850808E12L, + -5.802855515464011422171165179767478794637E11L, + -2.532349691157548788382820303182745897298E10L, + -5.884260178023777312587193693477072061820E8L, + -6.437774864512125749845840472131829114906E6L, + -2.350975266781548931856017239843273049384E4L +}; +#define NRD10 7 +static const long double RD10[NRD10 + 1] = +{ + -5.502645997581822567468347817182347679552E13L, + -1.970266640239849804162284805400136473801E13L, + -2.819677689615038489384974042561531409392E12L, + -2.056105863694742752589691183194061265094E11L, + -8.053670086493258693186307810815819662078E9L, + -1.632090155573373286153427982504851867131E8L, + -1.483575879240631280658077826889223634921E6L, + -4.002806669713232271615885826373550502510E3L + /* 1.0E0L */ +}; + + +/* log gamma(x+9) = log gamma(9) + x P(x)/Q(x) + -0.5 <= x <= 0.5 + 8.5 <= x+9 <= 9.5 + Peak relative error 3.6e-36 */ +static const long double lgam9a = 1.06045989990234375E1L; +static const long double lgam9b = 3.9037218127284172274007216547549861681400E-6L; +#define NRN9 7 +static const long double RN9[NRN9 + 1] = +{ + -4.936332264202687973364500998984608306189E13L, + -2.101372682623700967335206138517766274855E13L, + -3.615893404644823888655732817505129444195E12L, + -3.217104993800878891194322691860075472926E11L, + -1.568465330337375725685439173603032921399E10L, + -4.073317518162025744377629219101510217761E8L, + -4.983232096406156139324846656819246974500E6L, + -2.036280038903695980912289722995505277253E4L +}; +#define NRD9 7 +static const long double RD9[NRD9 + 1] = +{ + -2.306006080437656357167128541231915480393E13L, + -9.183606842453274924895648863832233799950E12L, + -1.461857965935942962087907301194381010380E12L, + -1.185728254682789754150068652663124298303E11L, + -5.166285094703468567389566085480783070037E9L, + -1.164573656694603024184768200787835094317E8L, + -1.177343939483908678474886454113163527909E6L, + -3.529391059783109732159524500029157638736E3L + /* 1.0E0L */ +}; + + +/* log gamma(x+8) = log gamma(8) + x P(x)/Q(x) + -0.5 <= x <= 0.5 + 7.5 <= x+8 <= 8.5 + Peak relative error 2.4e-37 */ +static const long double lgam8a = 8.525146484375E0L; +static const long double lgam8b = 1.4876690414300165531036347125050759667737E-5L; +#define NRN8 8 +static const long double RN8[NRN8 + 1] = +{ + 6.600775438203423546565361176829139703289E11L, + 3.406361267593790705240802723914281025800E11L, + 7.222460928505293914746983300555538432830E10L, + 8.102984106025088123058747466840656458342E9L, + 5.157620015986282905232150979772409345927E8L, + 1.851445288272645829028129389609068641517E7L, + 3.489261702223124354745894067468953756656E5L, + 2.892095396706665774434217489775617756014E3L, + 6.596977510622195827183948478627058738034E0L +}; +#define NRD8 7 +static const long double RD8[NRD8 + 1] = +{ + 3.274776546520735414638114828622673016920E11L, + 1.581811207929065544043963828487733970107E11L, + 3.108725655667825188135393076860104546416E10L, + 3.193055010502912617128480163681842165730E9L, + 1.830871482669835106357529710116211541839E8L, + 5.790862854275238129848491555068073485086E6L, + 9.305213264307921522842678835618803553589E4L, + 6.216974105861848386918949336819572333622E2L + /* 1.0E0L */ +}; + + +/* log gamma(x+7) = log gamma(7) + x P(x)/Q(x) + -0.5 <= x <= 0.5 + 6.5 <= x+7 <= 7.5 + Peak relative error 3.2e-36 */ +static const long double lgam7a = 6.5792388916015625E0L; +static const long double lgam7b = 1.2320408538495060178292903945321122583007E-5L; +#define NRN7 8 +static const long double RN7[NRN7 + 1] = +{ + 2.065019306969459407636744543358209942213E11L, + 1.226919919023736909889724951708796532847E11L, + 2.996157990374348596472241776917953749106E10L, + 3.873001919306801037344727168434909521030E9L, + 2.841575255593761593270885753992732145094E8L, + 1.176342515359431913664715324652399565551E7L, + 2.558097039684188723597519300356028511547E5L, + 2.448525238332609439023786244782810774702E3L, + 6.460280377802030953041566617300902020435E0L +}; +#define NRD7 7 +static const long double RD7[NRD7 + 1] = +{ + 1.102646614598516998880874785339049304483E11L, + 6.099297512712715445879759589407189290040E10L, + 1.372898136289611312713283201112060238351E10L, + 1.615306270420293159907951633566635172343E9L, + 1.061114435798489135996614242842561967459E8L, + 3.845638971184305248268608902030718674691E6L, + 7.081730675423444975703917836972720495507E4L, + 5.423122582741398226693137276201344096370E2L + /* 1.0E0L */ +}; + + +/* log gamma(x+6) = log gamma(6) + x P(x)/Q(x) + -0.5 <= x <= 0.5 + 5.5 <= x+6 <= 6.5 + Peak relative error 6.2e-37 */ +static const long double lgam6a = 4.7874908447265625E0L; +static const long double lgam6b = 8.9805548349424770093452324304839959231517E-7L; +#define NRN6 8 +static const long double RN6[NRN6 + 1] = +{ + -3.538412754670746879119162116819571823643E13L, + -2.613432593406849155765698121483394257148E13L, + -8.020670732770461579558867891923784753062E12L, + -1.322227822931250045347591780332435433420E12L, + -1.262809382777272476572558806855377129513E11L, + -7.015006277027660872284922325741197022467E9L, + -2.149320689089020841076532186783055727299E8L, + -3.167210585700002703820077565539658995316E6L, + -1.576834867378554185210279285358586385266E4L +}; +#define NRD6 8 +static const long double RD6[NRD6 + 1] = +{ + -2.073955870771283609792355579558899389085E13L, + -1.421592856111673959642750863283919318175E13L, + -4.012134994918353924219048850264207074949E12L, + -6.013361045800992316498238470888523722431E11L, + -5.145382510136622274784240527039643430628E10L, + -2.510575820013409711678540476918249524123E9L, + -6.564058379709759600836745035871373240904E7L, + -7.861511116647120540275354855221373571536E5L, + -2.821943442729620524365661338459579270561E3L + /* 1.0E0L */ +}; + + +/* log gamma(x+5) = log gamma(5) + x P(x)/Q(x) + -0.5 <= x <= 0.5 + 4.5 <= x+5 <= 5.5 + Peak relative error 3.4e-37 */ +static const long double lgam5a = 3.17803955078125E0L; +static const long double lgam5b = 1.4279566695619646941601297055408873990961E-5L; +#define NRN5 9 +static const long double RN5[NRN5 + 1] = +{ + 2.010952885441805899580403215533972172098E11L, + 1.916132681242540921354921906708215338584E11L, + 7.679102403710581712903937970163206882492E10L, + 1.680514903671382470108010973615268125169E10L, + 2.181011222911537259440775283277711588410E9L, + 1.705361119398837808244780667539728356096E8L, + 7.792391565652481864976147945997033946360E6L, + 1.910741381027985291688667214472560023819E5L, + 2.088138241893612679762260077783794329559E3L, + 6.330318119566998299106803922739066556550E0L +}; +#define NRD5 8 +static const long double RD5[NRD5 + 1] = +{ + 1.335189758138651840605141370223112376176E11L, + 1.174130445739492885895466097516530211283E11L, + 4.308006619274572338118732154886328519910E10L, + 8.547402888692578655814445003283720677468E9L, + 9.934628078575618309542580800421370730906E8L, + 6.847107420092173812998096295422311820672E7L, + 2.698552646016599923609773122139463150403E6L, + 5.526516251532464176412113632726150253215E4L, + 4.772343321713697385780533022595450486932E2L + /* 1.0E0L */ +}; + + +/* log gamma(x+4) = log gamma(4) + x P(x)/Q(x) + -0.5 <= x <= 0.5 + 3.5 <= x+4 <= 4.5 + Peak relative error 6.7e-37 */ +static const long double lgam4a = 1.791748046875E0L; +static const long double lgam4b = 1.1422353055000812477358380702272722990692E-5L; +#define NRN4 9 +static const long double RN4[NRN4 + 1] = +{ + -1.026583408246155508572442242188887829208E13L, + -1.306476685384622809290193031208776258809E13L, + -7.051088602207062164232806511992978915508E12L, + -2.100849457735620004967624442027793656108E12L, + -3.767473790774546963588549871673843260569E11L, + -4.156387497364909963498394522336575984206E10L, + -2.764021460668011732047778992419118757746E9L, + -1.036617204107109779944986471142938641399E8L, + -1.895730886640349026257780896972598305443E6L, + -1.180509051468390914200720003907727988201E4L +}; +#define NRD4 9 +static const long double RD4[NRD4 + 1] = +{ + -8.172669122056002077809119378047536240889E12L, + -9.477592426087986751343695251801814226960E12L, + -4.629448850139318158743900253637212801682E12L, + -1.237965465892012573255370078308035272942E12L, + -1.971624313506929845158062177061297598956E11L, + -1.905434843346570533229942397763361493610E10L, + -1.089409357680461419743730978512856675984E9L, + -3.416703082301143192939774401370222822430E7L, + -4.981791914177103793218433195857635265295E5L, + -2.192507743896742751483055798411231453733E3L + /* 1.0E0L */ +}; + + +/* log gamma(x+3) = log gamma(3) + x P(x)/Q(x) + -0.25 <= x <= 0.5 + 2.75 <= x+3 <= 3.5 + Peak relative error 6.0e-37 */ +static const long double lgam3a = 6.93145751953125E-1L; +static const long double lgam3b = 1.4286068203094172321214581765680755001344E-6L; + +#define NRN3 9 +static const long double RN3[NRN3 + 1] = +{ + -4.813901815114776281494823863935820876670E11L, + -8.425592975288250400493910291066881992620E11L, + -6.228685507402467503655405482985516909157E11L, + -2.531972054436786351403749276956707260499E11L, + -6.170200796658926701311867484296426831687E10L, + -9.211477458528156048231908798456365081135E9L, + -8.251806236175037114064561038908691305583E8L, + -4.147886355917831049939930101151160447495E7L, + -1.010851868928346082547075956946476932162E6L, + -8.333374463411801009783402800801201603736E3L +}; +#define NRD3 9 +static const long double RD3[NRD3 + 1] = +{ + -5.216713843111675050627304523368029262450E11L, + -8.014292925418308759369583419234079164391E11L, + -5.180106858220030014546267824392678611990E11L, + -1.830406975497439003897734969120997840011E11L, + -3.845274631904879621945745960119924118925E10L, + -4.891033385370523863288908070309417710903E9L, + -3.670172254411328640353855768698287474282E8L, + -1.505316381525727713026364396635522516989E7L, + -2.856327162923716881454613540575964890347E5L, + -1.622140448015769906847567212766206894547E3L + /* 1.0E0L */ +}; + + +/* log gamma(x+2.5) = log gamma(2.5) + x P(x)/Q(x) + -0.125 <= x <= 0.25 + 2.375 <= x+2.5 <= 2.75 */ +static const long double lgam2r5a = 2.8466796875E-1L; +static const long double lgam2r5b = 1.4901722919159632494669682701924320137696E-5L; +#define NRN2r5 8 +static const long double RN2r5[NRN2r5 + 1] = +{ + -4.676454313888335499356699817678862233205E9L, + -9.361888347911187924389905984624216340639E9L, + -7.695353600835685037920815799526540237703E9L, + -3.364370100981509060441853085968900734521E9L, + -8.449902011848163568670361316804900559863E8L, + -1.225249050950801905108001246436783022179E8L, + -9.732972931077110161639900388121650470926E6L, + -3.695711763932153505623248207576425983573E5L, + -4.717341584067827676530426007495274711306E3L +}; +#define NRD2r5 8 +static const long double RD2r5[NRD2r5 + 1] = +{ + -6.650657966618993679456019224416926875619E9L, + -1.099511409330635807899718829033488771623E10L, + -7.482546968307837168164311101447116903148E9L, + -2.702967190056506495988922973755870557217E9L, + -5.570008176482922704972943389590409280950E8L, + -6.536934032192792470926310043166993233231E7L, + -4.101991193844953082400035444146067511725E6L, + -1.174082735875715802334430481065526664020E5L, + -9.932840389994157592102947657277692978511E2L + /* 1.0E0L */ +}; + + +/* log gamma(x+2) = x P(x)/Q(x) + -0.125 <= x <= +0.375 + 1.875 <= x+2 <= 2.375 + Peak relative error 4.6e-36 */ +#define NRN2 9 +static const long double RN2[NRN2 + 1] = +{ + -3.716661929737318153526921358113793421524E9L, + -1.138816715030710406922819131397532331321E10L, + -1.421017419363526524544402598734013569950E10L, + -9.510432842542519665483662502132010331451E9L, + -3.747528562099410197957514973274474767329E9L, + -8.923565763363912474488712255317033616626E8L, + -1.261396653700237624185350402781338231697E8L, + -9.918402520255661797735331317081425749014E6L, + -3.753996255897143855113273724233104768831E5L, + -4.778761333044147141559311805999540765612E3L +}; +#define NRD2 9 +static const long double RD2[NRD2 + 1] = +{ + -8.790916836764308497770359421351673950111E9L, + -2.023108608053212516399197678553737477486E10L, + -1.958067901852022239294231785363504458367E10L, + -1.035515043621003101254252481625188704529E10L, + -3.253884432621336737640841276619272224476E9L, + -6.186383531162456814954947669274235815544E8L, + -6.932557847749518463038934953605969951466E7L, + -4.240731768287359608773351626528479703758E6L, + -1.197343995089189188078944689846348116630E5L, + -1.004622911670588064824904487064114090920E3L +/* 1.0E0 */ +}; + + +/* log gamma(x+1.75) = log gamma(1.75) + x P(x)/Q(x) + -0.125 <= x <= +0.125 + 1.625 <= x+1.75 <= 1.875 + Peak relative error 9.2e-37 */ +static const long double lgam1r75a = -8.441162109375E-2L; +static const long double lgam1r75b = 1.0500073264444042213965868602268256157604E-5L; +#define NRN1r75 8 +static const long double RN1r75[NRN1r75 + 1] = +{ + -5.221061693929833937710891646275798251513E7L, + -2.052466337474314812817883030472496436993E8L, + -2.952718275974940270675670705084125640069E8L, + -2.132294039648116684922965964126389017840E8L, + -8.554103077186505960591321962207519908489E7L, + -1.940250901348870867323943119132071960050E7L, + -2.379394147112756860769336400290402208435E6L, + -1.384060879999526222029386539622255797389E5L, + -2.698453601378319296159355612094598695530E3L +}; +#define NRD1r75 8 +static const long double RD1r75[NRD1r75 + 1] = +{ + -2.109754689501705828789976311354395393605E8L, + -5.036651829232895725959911504899241062286E8L, + -4.954234699418689764943486770327295098084E8L, + -2.589558042412676610775157783898195339410E8L, + -7.731476117252958268044969614034776883031E7L, + -1.316721702252481296030801191240867486965E7L, + -1.201296501404876774861190604303728810836E6L, + -5.007966406976106636109459072523610273928E4L, + -6.155817990560743422008969155276229018209E2L + /* 1.0E0L */ +}; + + +/* log gamma(x+x0) = y0 + x^2 P(x)/Q(x) + -0.0867 <= x <= +0.1634 + 1.374932... <= x+x0 <= 1.625032... + Peak relative error 4.0e-36 */ +static const long double x0a = 1.4616241455078125L; +static const long double x0b = 7.9994605498412626595423257213002588621246E-6L; +static const long double y0a = -1.21490478515625E-1L; +static const long double y0b = 4.1879797753919044854428223084178486438269E-6L; +#define NRN1r5 8 +static const long double RN1r5[NRN1r5 + 1] = +{ + 6.827103657233705798067415468881313128066E5L, + 1.910041815932269464714909706705242148108E6L, + 2.194344176925978377083808566251427771951E6L, + 1.332921400100891472195055269688876427962E6L, + 4.589080973377307211815655093824787123508E5L, + 8.900334161263456942727083580232613796141E4L, + 9.053840838306019753209127312097612455236E3L, + 4.053367147553353374151852319743594873771E2L, + 5.040631576303952022968949605613514584950E0L +}; +#define NRD1r5 8 +static const long double RD1r5[NRD1r5 + 1] = +{ + 1.411036368843183477558773688484699813355E6L, + 4.378121767236251950226362443134306184849E6L, + 5.682322855631723455425929877581697918168E6L, + 3.999065731556977782435009349967042222375E6L, + 1.653651390456781293163585493620758410333E6L, + 4.067774359067489605179546964969435858311E5L, + 5.741463295366557346748361781768833633256E4L, + 4.226404539738182992856094681115746692030E3L, + 1.316980975410327975566999780608618774469E2L, + /* 1.0E0L */ +}; + + +/* log gamma(x+1.25) = log gamma(1.25) + x P(x)/Q(x) + -.125 <= x <= +.125 + 1.125 <= x+1.25 <= 1.375 + Peak relative error = 4.9e-36 */ +static const long double lgam1r25a = -9.82818603515625E-2L; +static const long double lgam1r25b = 1.0023929749338536146197303364159774377296E-5L; +#define NRN1r25 9 +static const long double RN1r25[NRN1r25 + 1] = +{ + -9.054787275312026472896002240379580536760E4L, + -8.685076892989927640126560802094680794471E4L, + 2.797898965448019916967849727279076547109E5L, + 6.175520827134342734546868356396008898299E5L, + 5.179626599589134831538516906517372619641E5L, + 2.253076616239043944538380039205558242161E5L, + 5.312653119599957228630544772499197307195E4L, + 6.434329437514083776052669599834938898255E3L, + 3.385414416983114598582554037612347549220E2L, + 4.907821957946273805080625052510832015792E0L +}; +#define NRD1r25 8 +static const long double RD1r25[NRD1r25 + 1] = +{ + 3.980939377333448005389084785896660309000E5L, + 1.429634893085231519692365775184490465542E6L, + 2.145438946455476062850151428438668234336E6L, + 1.743786661358280837020848127465970357893E6L, + 8.316364251289743923178092656080441655273E5L, + 2.355732939106812496699621491135458324294E5L, + 3.822267399625696880571810137601310855419E4L, + 3.228463206479133236028576845538387620856E3L, + 1.152133170470059555646301189220117965514E2L + /* 1.0E0L */ +}; + + +/* log gamma(x + 1) = x P(x)/Q(x) + 0.0 <= x <= +0.125 + 1.0 <= x+1 <= 1.125 + Peak relative error 1.1e-35 */ +#define NRN1 8 +static const long double RN1[NRN1 + 1] = +{ + -9.987560186094800756471055681088744738818E3L, + -2.506039379419574361949680225279376329742E4L, + -1.386770737662176516403363873617457652991E4L, + 1.439445846078103202928677244188837130744E4L, + 2.159612048879650471489449668295139990693E4L, + 1.047439813638144485276023138173676047079E4L, + 2.250316398054332592560412486630769139961E3L, + 1.958510425467720733041971651126443864041E2L, + 4.516830313569454663374271993200291219855E0L +}; +#define NRD1 7 +static const long double RD1[NRD1 + 1] = +{ + 1.730299573175751778863269333703788214547E4L, + 6.807080914851328611903744668028014678148E4L, + 1.090071629101496938655806063184092302439E5L, + 9.124354356415154289343303999616003884080E4L, + 4.262071638655772404431164427024003253954E4L, + 1.096981664067373953673982635805821283581E4L, + 1.431229503796575892151252708527595787588E3L, + 7.734110684303689320830401788262295992921E1L + /* 1.0E0 */ +}; + + +/* log gamma(x + 1) = x P(x)/Q(x) + -0.125 <= x <= 0 + 0.875 <= x+1 <= 1.0 + Peak relative error 7.0e-37 */ +#define NRNr9 8 +static const long double RNr9[NRNr9 + 1] = +{ + 4.441379198241760069548832023257571176884E5L, + 1.273072988367176540909122090089580368732E6L, + 9.732422305818501557502584486510048387724E5L, + -5.040539994443998275271644292272870348684E5L, + -1.208719055525609446357448132109723786736E6L, + -7.434275365370936547146540554419058907156E5L, + -2.075642969983377738209203358199008185741E5L, + -2.565534860781128618589288075109372218042E4L, + -1.032901669542994124131223797515913955938E3L, +}; +#define NRDr9 8 +static const long double RDr9[NRDr9 + 1] = +{ + -7.694488331323118759486182246005193998007E5L, + -3.301918855321234414232308938454112213751E6L, + -5.856830900232338906742924836032279404702E6L, + -5.540672519616151584486240871424021377540E6L, + -3.006530901041386626148342989181721176919E6L, + -9.350378280513062139466966374330795935163E5L, + -1.566179100031063346901755685375732739511E5L, + -1.205016539620260779274902967231510804992E4L, + -2.724583156305709733221564484006088794284E2L +/* 1.0E0 */ +}; + + +/* Evaluate P[n] x^n + P[n-1] x^(n-1) + ... + P[0] */ + +static long double +neval (long double x, const long double *p, int n) +{ + long double y; + + p += n; + y = *p--; + do + { + y = y * x + *p--; + } + while (--n > 0); + return y; +} + + +/* Evaluate x^n+1 + P[n] x^(n) + P[n-1] x^(n-1) + ... + P[0] */ + +static long double +deval (long double x, const long double *p, int n) +{ + long double y; + + p += n; + y = x + *p--; + do + { + y = y * x + *p--; + } + while (--n > 0); + return y; +} + + +long double +lgammal_r(long double x, int *signgamp) +{ + long double p, q, w, z, nx; + int i, nn; + + *signgamp = 1; + + if (!isfinite (x)) + return x * x; + + if (x == 0.0L) + { + if (signbit (x)) + *signgamp = -1; + return one / fabsl (x); + } + + if (x < 0.0L) + { + q = -x; + p = floorl (q); + if (p == q) + return (one / (p - p)); + i = p; + if ((i & 1) == 0) + *signgamp = -1; + else + *signgamp = 1; + z = q - p; + if (z > 0.5L) + { + p += 1.0L; + z = p - q; + } + z = q * sinl (PIL * z); + if (z == 0.0L) + return (*signgamp * huge * huge); + w = lgammal (q); + z = logl (PIL / z) - w; + return (z); + } + + if (x < 13.5L) + { + p = 0.0L; + nx = floorl (x + 0.5L); + nn = nx; + switch (nn) + { + case 0: + /* log gamma (x + 1) = log(x) + log gamma(x) */ + if (x <= 0.125) + { + p = x * neval (x, RN1, NRN1) / deval (x, RD1, NRD1); + } + else if (x <= 0.375) + { + z = x - 0.25L; + p = z * neval (z, RN1r25, NRN1r25) / deval (z, RD1r25, NRD1r25); + p += lgam1r25b; + p += lgam1r25a; + } + else if (x <= 0.625) + { + z = x + (1.0L - x0a); + z = z - x0b; + p = neval (z, RN1r5, NRN1r5) / deval (z, RD1r5, NRD1r5); + p = p * z * z; + p = p + y0b; + p = p + y0a; + } + else if (x <= 0.875) + { + z = x - 0.75L; + p = z * neval (z, RN1r75, NRN1r75) / deval (z, RD1r75, NRD1r75); + p += lgam1r75b; + p += lgam1r75a; + } + else + { + z = x - 1.0L; + p = z * neval (z, RN2, NRN2) / deval (z, RD2, NRD2); + } + p = p - logl (x); + break; + + case 1: + if (x < 0.875L) + { + if (x <= 0.625) + { + z = x + (1.0L - x0a); + z = z - x0b; + p = neval (z, RN1r5, NRN1r5) / deval (z, RD1r5, NRD1r5); + p = p * z * z; + p = p + y0b; + p = p + y0a; + } + else if (x <= 0.875) + { + z = x - 0.75L; + p = z * neval (z, RN1r75, NRN1r75) + / deval (z, RD1r75, NRD1r75); + p += lgam1r75b; + p += lgam1r75a; + } + else + { + z = x - 1.0L; + p = z * neval (z, RN2, NRN2) / deval (z, RD2, NRD2); + } + p = p - logl (x); + } + else if (x < 1.0L) + { + z = x - 1.0L; + p = z * neval (z, RNr9, NRNr9) / deval (z, RDr9, NRDr9); + } + else if (x == 1.0L) + p = 0.0L; + else if (x <= 1.125L) + { + z = x - 1.0L; + p = z * neval (z, RN1, NRN1) / deval (z, RD1, NRD1); + } + else if (x <= 1.375) + { + z = x - 1.25L; + p = z * neval (z, RN1r25, NRN1r25) / deval (z, RD1r25, NRD1r25); + p += lgam1r25b; + p += lgam1r25a; + } + else + { + /* 1.375 <= x+x0 <= 1.625 */ + z = x - x0a; + z = z - x0b; + p = neval (z, RN1r5, NRN1r5) / deval (z, RD1r5, NRD1r5); + p = p * z * z; + p = p + y0b; + p = p + y0a; + } + break; + + case 2: + if (x < 1.625L) + { + z = x - x0a; + z = z - x0b; + p = neval (z, RN1r5, NRN1r5) / deval (z, RD1r5, NRD1r5); + p = p * z * z; + p = p + y0b; + p = p + y0a; + } + else if (x < 1.875L) + { + z = x - 1.75L; + p = z * neval (z, RN1r75, NRN1r75) / deval (z, RD1r75, NRD1r75); + p += lgam1r75b; + p += lgam1r75a; + } + else if (x == 2.0L) + p = 0.0L; + else if (x < 2.375L) + { + z = x - 2.0L; + p = z * neval (z, RN2, NRN2) / deval (z, RD2, NRD2); + } + else + { + z = x - 2.5L; + p = z * neval (z, RN2r5, NRN2r5) / deval (z, RD2r5, NRD2r5); + p += lgam2r5b; + p += lgam2r5a; + } + break; + + case 3: + if (x < 2.75) + { + z = x - 2.5L; + p = z * neval (z, RN2r5, NRN2r5) / deval (z, RD2r5, NRD2r5); + p += lgam2r5b; + p += lgam2r5a; + } + else + { + z = x - 3.0L; + p = z * neval (z, RN3, NRN3) / deval (z, RD3, NRD3); + p += lgam3b; + p += lgam3a; + } + break; + + case 4: + z = x - 4.0L; + p = z * neval (z, RN4, NRN4) / deval (z, RD4, NRD4); + p += lgam4b; + p += lgam4a; + break; + + case 5: + z = x - 5.0L; + p = z * neval (z, RN5, NRN5) / deval (z, RD5, NRD5); + p += lgam5b; + p += lgam5a; + break; + + case 6: + z = x - 6.0L; + p = z * neval (z, RN6, NRN6) / deval (z, RD6, NRD6); + p += lgam6b; + p += lgam6a; + break; + + case 7: + z = x - 7.0L; + p = z * neval (z, RN7, NRN7) / deval (z, RD7, NRD7); + p += lgam7b; + p += lgam7a; + break; + + case 8: + z = x - 8.0L; + p = z * neval (z, RN8, NRN8) / deval (z, RD8, NRD8); + p += lgam8b; + p += lgam8a; + break; + + case 9: + z = x - 9.0L; + p = z * neval (z, RN9, NRN9) / deval (z, RD9, NRD9); + p += lgam9b; + p += lgam9a; + break; + + case 10: + z = x - 10.0L; + p = z * neval (z, RN10, NRN10) / deval (z, RD10, NRD10); + p += lgam10b; + p += lgam10a; + break; + + case 11: + z = x - 11.0L; + p = z * neval (z, RN11, NRN11) / deval (z, RD11, NRD11); + p += lgam11b; + p += lgam11a; + break; + + case 12: + z = x - 12.0L; + p = z * neval (z, RN12, NRN12) / deval (z, RD12, NRD12); + p += lgam12b; + p += lgam12a; + break; + + case 13: + z = x - 13.0L; + p = z * neval (z, RN13, NRN13) / deval (z, RD13, NRD13); + p += lgam13b; + p += lgam13a; + break; + } + return p; + } + + if (x > MAXLGM) + return (*signgamp * huge * huge); + + q = ls2pi - x; + q = (x - 0.5L) * logl (x) + q; + if (x > 1.0e18L) + return (q); + + p = 1.0L / (x * x); + q += neval (p, RASY, NRASY) / x; + return (q); +} diff --git a/src/openlibm/ld128/e_log10l.c b/src/openlibm/ld128/e_log10l.c new file mode 100644 index 0000000..9448101 --- /dev/null +++ b/src/openlibm/ld128/e_log10l.c @@ -0,0 +1,255 @@ +/* $OpenBSD: e_log10l.c,v 1.1 2011/07/06 00:02:42 martynas Exp $ */ + +/* + * Copyright (c) 2008 Stephen L. Moshier + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* log10l.c + * + * Common logarithm, 128-bit long double precision + * + * + * + * SYNOPSIS: + * + * long double x, y, log10l(); + * + * y = log10l( x ); + * + * + * + * DESCRIPTION: + * + * Returns the base 10 logarithm of x. + * + * The argument is separated into its exponent and fractional + * parts. If the exponent is between -1 and +1, the logarithm + * of the fraction is approximated by + * + * log(1+x) = x - 0.5 x^2 + x^3 P(x)/Q(x). + * + * Otherwise, setting z = 2(x-1)/x+1), + * + * log(x) = z + z^3 P(z)/Q(z). + * + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE 0.5, 2.0 30000 2.3e-34 4.9e-35 + * IEEE exp(+-10000) 30000 1.0e-34 4.1e-35 + * + * In the tests over the interval exp(+-10000), the logarithms + * of the random arguments were uniformly distributed over + * [-10000, +10000]. + * + */ + +#include + +#include "math_private.h" + +/* Coefficients for ln(1+x) = x - x**2/2 + x**3 P(x)/Q(x) + * 1/sqrt(2) <= x < sqrt(2) + * Theoretical peak relative error = 5.3e-37, + * relative peak error spread = 2.3e-14 + */ +static const long double P[13] = +{ + 1.313572404063446165910279910527789794488E4L, + 7.771154681358524243729929227226708890930E4L, + 2.014652742082537582487669938141683759923E5L, + 3.007007295140399532324943111654767187848E5L, + 2.854829159639697837788887080758954924001E5L, + 1.797628303815655343403735250238293741397E5L, + 7.594356839258970405033155585486712125861E4L, + 2.128857716871515081352991964243375186031E4L, + 3.824952356185897735160588078446136783779E3L, + 4.114517881637811823002128927449878962058E2L, + 2.321125933898420063925789532045674660756E1L, + 4.998469661968096229986658302195402690910E-1L, + 1.538612243596254322971797716843006400388E-6L +}; +static const long double Q[12] = +{ + 3.940717212190338497730839731583397586124E4L, + 2.626900195321832660448791748036714883242E5L, + 7.777690340007566932935753241556479363645E5L, + 1.347518538384329112529391120390701166528E6L, + 1.514882452993549494932585972882995548426E6L, + 1.158019977462989115839826904108208787040E6L, + 6.132189329546557743179177159925690841200E5L, + 2.248234257620569139969141618556349415120E5L, + 5.605842085972455027590989944010492125825E4L, + 9.147150349299596453976674231612674085381E3L, + 9.104928120962988414618126155557301584078E2L, + 4.839208193348159620282142911143429644326E1L +/* 1.000000000000000000000000000000000000000E0L, */ +}; + +/* Coefficients for log(x) = z + z^3 P(z^2)/Q(z^2), + * where z = 2(x-1)/(x+1) + * 1/sqrt(2) <= x < sqrt(2) + * Theoretical peak relative error = 1.1e-35, + * relative peak error spread 1.1e-9 + */ +static const long double R[6] = +{ + 1.418134209872192732479751274970992665513E5L, + -8.977257995689735303686582344659576526998E4L, + 2.048819892795278657810231591630928516206E4L, + -2.024301798136027039250415126250455056397E3L, + 8.057002716646055371965756206836056074715E1L, + -8.828896441624934385266096344596648080902E-1L +}; +static const long double S[6] = +{ + 1.701761051846631278975701529965589676574E6L, + -1.332535117259762928288745111081235577029E6L, + 4.001557694070773974936904547424676279307E5L, + -5.748542087379434595104154610899551484314E4L, + 3.998526750980007367835804959888064681098E3L, + -1.186359407982897997337150403816839480438E2L +/* 1.000000000000000000000000000000000000000E0L, */ +}; + +static const long double +/* log10(2) */ +L102A = 0.3125L, +L102B = -1.14700043360188047862611052755069732318101185E-2L, +/* log10(e) */ +L10EA = 0.5L, +L10EB = -6.570551809674817234887108108339491770560299E-2L, +/* sqrt(2)/2 */ +SQRTH = 7.071067811865475244008443621048490392848359E-1L; + + + +/* Evaluate P[n] x^n + P[n-1] x^(n-1) + ... + P[0] */ + +static long double +neval (long double x, const long double *p, int n) +{ + long double y; + + p += n; + y = *p--; + do + { + y = y * x + *p--; + } + while (--n > 0); + return y; +} + + +/* Evaluate x^n+1 + P[n] x^(n) + P[n-1] x^(n-1) + ... + P[0] */ + +static long double +deval (long double x, const long double *p, int n) +{ + long double y; + + p += n; + y = x + *p--; + do + { + y = y * x + *p--; + } + while (--n > 0); + return y; +} + + + +long double +log10l(long double x) +{ + long double z; + long double y; + int e; + int64_t hx, lx; + +/* Test for domain */ + GET_LDOUBLE_WORDS64 (hx, lx, x); + if (((hx & 0x7fffffffffffffffLL) | lx) == 0) + return (-1.0L / (x - x)); + if (hx < 0) + return (x - x) / (x - x); + if (hx >= 0x7fff000000000000LL) + return (x + x); + +/* separate mantissa from exponent */ + +/* Note, frexp is used so that denormal numbers + * will be handled properly. + */ + x = frexpl (x, &e); + + +/* logarithm using log(x) = z + z**3 P(z)/Q(z), + * where z = 2(x-1)/x+1) + */ + if ((e > 2) || (e < -2)) + { + if (x < SQRTH) + { /* 2( 2x-1 )/( 2x+1 ) */ + e -= 1; + z = x - 0.5L; + y = 0.5L * z + 0.5L; + } + else + { /* 2 (x-1)/(x+1) */ + z = x - 0.5L; + z -= 0.5L; + y = 0.5L * x + 0.5L; + } + x = z / y; + z = x * x; + y = x * (z * neval (z, R, 5) / deval (z, S, 5)); + goto done; + } + + +/* logarithm using log(1+x) = x - .5x**2 + x**3 P(x)/Q(x) */ + + if (x < SQRTH) + { + e -= 1; + x = 2.0 * x - 1.0L; /* 2x - 1 */ + } + else + { + x = x - 1.0L; + } + z = x * x; + y = x * (z * neval (x, P, 12) / deval (x, Q, 11)); + y = y - 0.5 * z; + +done: + + /* Multiply log of fraction by log10(e) + * and base 2 exponent by log10(2). + */ + z = y * L10EB; + z += x * L10EB; + z += e * L102B; + z += y * L10EA; + z += x * L10EA; + z += e * L102A; + return (z); +} diff --git a/src/openlibm/ld128/e_log2l.c b/src/openlibm/ld128/e_log2l.c new file mode 100644 index 0000000..2ce4d94 --- /dev/null +++ b/src/openlibm/ld128/e_log2l.c @@ -0,0 +1,248 @@ +/* $OpenBSD: e_log2l.c,v 1.1 2011/07/06 00:02:42 martynas Exp $ */ + +/* + * Copyright (c) 2008 Stephen L. Moshier + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* log2l.c + * Base 2 logarithm, 128-bit long double precision + * + * + * + * SYNOPSIS: + * + * long double x, y, log2l(); + * + * y = log2l( x ); + * + * + * + * DESCRIPTION: + * + * Returns the base 2 logarithm of x. + * + * The argument is separated into its exponent and fractional + * parts. If the exponent is between -1 and +1, the (natural) + * logarithm of the fraction is approximated by + * + * log(1+x) = x - 0.5 x^2 + x^3 P(x)/Q(x). + * + * Otherwise, setting z = 2(x-1)/x+1), + * + * log(x) = z + z^3 P(z)/Q(z). + * + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE 0.5, 2.0 100,000 2.6e-34 4.9e-35 + * IEEE exp(+-10000) 100,000 9.6e-35 4.0e-35 + * + * In the tests over the interval exp(+-10000), the logarithms + * of the random arguments were uniformly distributed over + * [-10000, +10000]. + * + */ + +#include + +#include "math_private.h" + +/* Coefficients for ln(1+x) = x - x**2/2 + x**3 P(x)/Q(x) + * 1/sqrt(2) <= x < sqrt(2) + * Theoretical peak relative error = 5.3e-37, + * relative peak error spread = 2.3e-14 + */ +static const long double P[13] = +{ + 1.313572404063446165910279910527789794488E4L, + 7.771154681358524243729929227226708890930E4L, + 2.014652742082537582487669938141683759923E5L, + 3.007007295140399532324943111654767187848E5L, + 2.854829159639697837788887080758954924001E5L, + 1.797628303815655343403735250238293741397E5L, + 7.594356839258970405033155585486712125861E4L, + 2.128857716871515081352991964243375186031E4L, + 3.824952356185897735160588078446136783779E3L, + 4.114517881637811823002128927449878962058E2L, + 2.321125933898420063925789532045674660756E1L, + 4.998469661968096229986658302195402690910E-1L, + 1.538612243596254322971797716843006400388E-6L +}; +static const long double Q[12] = +{ + 3.940717212190338497730839731583397586124E4L, + 2.626900195321832660448791748036714883242E5L, + 7.777690340007566932935753241556479363645E5L, + 1.347518538384329112529391120390701166528E6L, + 1.514882452993549494932585972882995548426E6L, + 1.158019977462989115839826904108208787040E6L, + 6.132189329546557743179177159925690841200E5L, + 2.248234257620569139969141618556349415120E5L, + 5.605842085972455027590989944010492125825E4L, + 9.147150349299596453976674231612674085381E3L, + 9.104928120962988414618126155557301584078E2L, + 4.839208193348159620282142911143429644326E1L +/* 1.000000000000000000000000000000000000000E0L, */ +}; + +/* Coefficients for log(x) = z + z^3 P(z^2)/Q(z^2), + * where z = 2(x-1)/(x+1) + * 1/sqrt(2) <= x < sqrt(2) + * Theoretical peak relative error = 1.1e-35, + * relative peak error spread 1.1e-9 + */ +static const long double R[6] = +{ + 1.418134209872192732479751274970992665513E5L, + -8.977257995689735303686582344659576526998E4L, + 2.048819892795278657810231591630928516206E4L, + -2.024301798136027039250415126250455056397E3L, + 8.057002716646055371965756206836056074715E1L, + -8.828896441624934385266096344596648080902E-1L +}; +static const long double S[6] = +{ + 1.701761051846631278975701529965589676574E6L, + -1.332535117259762928288745111081235577029E6L, + 4.001557694070773974936904547424676279307E5L, + -5.748542087379434595104154610899551484314E4L, + 3.998526750980007367835804959888064681098E3L, + -1.186359407982897997337150403816839480438E2L +/* 1.000000000000000000000000000000000000000E0L, */ +}; + +static const long double +/* log2(e) - 1 */ +LOG2EA = 4.4269504088896340735992468100189213742664595E-1L, +/* sqrt(2)/2 */ +SQRTH = 7.071067811865475244008443621048490392848359E-1L; + + +/* Evaluate P[n] x^n + P[n-1] x^(n-1) + ... + P[0] */ + +static long double +neval (long double x, const long double *p, int n) +{ + long double y; + + p += n; + y = *p--; + do + { + y = y * x + *p--; + } + while (--n > 0); + return y; +} + + +/* Evaluate x^n+1 + P[n] x^(n) + P[n-1] x^(n-1) + ... + P[0] */ + +static long double +deval (long double x, const long double *p, int n) +{ + long double y; + + p += n; + y = x + *p--; + do + { + y = y * x + *p--; + } + while (--n > 0); + return y; +} + + + +long double +log2l(long double x) +{ + long double z; + long double y; + int e; + int64_t hx, lx; + +/* Test for domain */ + GET_LDOUBLE_WORDS64 (hx, lx, x); + if (((hx & 0x7fffffffffffffffLL) | lx) == 0) + return (-1.0L / (x - x)); + if (hx < 0) + return (x - x) / (x - x); + if (hx >= 0x7fff000000000000LL) + return (x + x); + +/* separate mantissa from exponent */ + +/* Note, frexp is used so that denormal numbers + * will be handled properly. + */ + x = frexpl (x, &e); + + +/* logarithm using log(x) = z + z**3 P(z)/Q(z), + * where z = 2(x-1)/x+1) + */ + if ((e > 2) || (e < -2)) + { + if (x < SQRTH) + { /* 2( 2x-1 )/( 2x+1 ) */ + e -= 1; + z = x - 0.5L; + y = 0.5L * z + 0.5L; + } + else + { /* 2 (x-1)/(x+1) */ + z = x - 0.5L; + z -= 0.5L; + y = 0.5L * x + 0.5L; + } + x = z / y; + z = x * x; + y = x * (z * neval (z, R, 5) / deval (z, S, 5)); + goto done; + } + + +/* logarithm using log(1+x) = x - .5x**2 + x**3 P(x)/Q(x) */ + + if (x < SQRTH) + { + e -= 1; + x = 2.0 * x - 1.0L; /* 2x - 1 */ + } + else + { + x = x - 1.0L; + } + z = x * x; + y = x * (z * neval (x, P, 12) / deval (x, Q, 11)); + y = y - 0.5 * z; + +done: + +/* Multiply log of fraction by log2(e) + * and base 2 exponent by 1 + */ + z = y * LOG2EA; + z += x * LOG2EA; + z += y; + z += x; + z += e; + return (z); +} diff --git a/src/openlibm/ld128/e_logl.c b/src/openlibm/ld128/e_logl.c new file mode 100644 index 0000000..f6da91f --- /dev/null +++ b/src/openlibm/ld128/e_logl.c @@ -0,0 +1,283 @@ +/* $OpenBSD: e_logl.c,v 1.1 2011/07/06 00:02:42 martynas Exp $ */ + +/* + * Copyright (c) 2008 Stephen L. Moshier + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* logl.c + * + * Natural logarithm for 128-bit long double precision. + * + * + * + * SYNOPSIS: + * + * long double x, y, logl(); + * + * y = logl( x ); + * + * + * + * DESCRIPTION: + * + * Returns the base e (2.718...) logarithm of x. + * + * The argument is separated into its exponent and fractional + * parts. Use of a lookup table increases the speed of the routine. + * The program uses logarithms tabulated at intervals of 1/128 to + * cover the domain from approximately 0.7 to 1.4. + * + * On the interval [-1/128, +1/128] the logarithm of 1+x is approximated by + * log(1+x) = x - 0.5 x^2 + x^3 P(x) . + * + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE 0.875, 1.125 100000 1.2e-34 4.1e-35 + * IEEE 0.125, 8 100000 1.2e-34 4.1e-35 + * + * + * WARNING: + * + * This program uses integer operations on bit fields of floating-point + * numbers. It does not work with data structures other than the + * structure assumed. + * + */ + +#include + +#include "math_private.h" + +/* log(1+x) = x - .5 x^2 + x^3 l(x) + -.0078125 <= x <= +.0078125 + peak relative error 1.2e-37 */ +static const long double +l3 = 3.333333333333333333333333333333336096926E-1L, +l4 = -2.499999999999999999999999999486853077002E-1L, +l5 = 1.999999999999999999999999998515277861905E-1L, +l6 = -1.666666666666666666666798448356171665678E-1L, +l7 = 1.428571428571428571428808945895490721564E-1L, +l8 = -1.249999999999999987884655626377588149000E-1L, +l9 = 1.111111111111111093947834982832456459186E-1L, +l10 = -1.000000000000532974938900317952530453248E-1L, +l11 = 9.090909090915566247008015301349979892689E-2L, +l12 = -8.333333211818065121250921925397567745734E-2L, +l13 = 7.692307559897661630807048686258659316091E-2L, +l14 = -7.144242754190814657241902218399056829264E-2L, +l15 = 6.668057591071739754844678883223432347481E-2L; + +/* Lookup table of ln(t) - (t-1) + t = 0.5 + (k+26)/128) + k = 0, ..., 91 */ +static const long double logtbl[92] = { +-5.5345593589352099112142921677820359632418E-2L, +-5.2108257402767124761784665198737642086148E-2L, +-4.8991686870576856279407775480686721935120E-2L, +-4.5993270766361228596215288742353061431071E-2L, +-4.3110481649613269682442058976885699556950E-2L, +-4.0340872319076331310838085093194799765520E-2L, +-3.7682072451780927439219005993827431503510E-2L, +-3.5131785416234343803903228503274262719586E-2L, +-3.2687785249045246292687241862699949178831E-2L, +-3.0347913785027239068190798397055267411813E-2L, +-2.8110077931525797884641940838507561326298E-2L, +-2.5972247078357715036426583294246819637618E-2L, +-2.3932450635346084858612873953407168217307E-2L, +-2.1988775689981395152022535153795155900240E-2L, +-2.0139364778244501615441044267387667496733E-2L, +-1.8382413762093794819267536615342902718324E-2L, +-1.6716169807550022358923589720001638093023E-2L, +-1.5138929457710992616226033183958974965355E-2L, +-1.3649036795397472900424896523305726435029E-2L, +-1.2244881690473465543308397998034325468152E-2L, +-1.0924898127200937840689817557742469105693E-2L, +-9.6875626072830301572839422532631079809328E-3L, +-8.5313926245226231463436209313499745894157E-3L, +-7.4549452072765973384933565912143044991706E-3L, +-6.4568155251217050991200599386801665681310E-3L, +-5.5356355563671005131126851708522185605193E-3L, +-4.6900728132525199028885749289712348829878E-3L, +-3.9188291218610470766469347968659624282519E-3L, +-3.2206394539524058873423550293617843896540E-3L, +-2.5942708080877805657374888909297113032132E-3L, +-2.0385211375711716729239156839929281289086E-3L, +-1.5522183228760777967376942769773768850872E-3L, +-1.1342191863606077520036253234446621373191E-3L, +-7.8340854719967065861624024730268350459991E-4L, +-4.9869831458030115699628274852562992756174E-4L, +-2.7902661731604211834685052867305795169688E-4L, +-1.2335696813916860754951146082826952093496E-4L, +-3.0677461025892873184042490943581654591817E-5L, +#define ZERO logtbl[38] + 0.0000000000000000000000000000000000000000E0L, +-3.0359557945051052537099938863236321874198E-5L, +-1.2081346403474584914595395755316412213151E-4L, +-2.7044071846562177120083903771008342059094E-4L, +-4.7834133324631162897179240322783590830326E-4L, +-7.4363569786340080624467487620270965403695E-4L, +-1.0654639687057968333207323853366578860679E-3L, +-1.4429854811877171341298062134712230604279E-3L, +-1.8753781835651574193938679595797367137975E-3L, +-2.3618380914922506054347222273705859653658E-3L, +-2.9015787624124743013946600163375853631299E-3L, +-3.4938307889254087318399313316921940859043E-3L, +-4.1378413103128673800485306215154712148146E-3L, +-4.8328735414488877044289435125365629849599E-3L, +-5.5782063183564351739381962360253116934243E-3L, +-6.3731336597098858051938306767880719015261E-3L, +-7.2169643436165454612058905294782949315193E-3L, +-8.1090214990427641365934846191367315083867E-3L, +-9.0486422112807274112838713105168375482480E-3L, +-1.0035177140880864314674126398350812606841E-2L, +-1.1067990155502102718064936259435676477423E-2L, +-1.2146457974158024928196575103115488672416E-2L, +-1.3269969823361415906628825374158424754308E-2L, +-1.4437927104692837124388550722759686270765E-2L, +-1.5649743073340777659901053944852735064621E-2L, +-1.6904842527181702880599758489058031645317E-2L, +-1.8202661505988007336096407340750378994209E-2L, +-1.9542647000370545390701192438691126552961E-2L, +-2.0924256670080119637427928803038530924742E-2L, +-2.2346958571309108496179613803760727786257E-2L, +-2.3810230892650362330447187267648486279460E-2L, +-2.5313561699385640380910474255652501521033E-2L, +-2.6856448685790244233704909690165496625399E-2L, +-2.8438398935154170008519274953860128449036E-2L, +-3.0058928687233090922411781058956589863039E-2L, +-3.1717563112854831855692484086486099896614E-2L, +-3.3413836095418743219397234253475252001090E-2L, +-3.5147290019036555862676702093393332533702E-2L, +-3.6917475563073933027920505457688955423688E-2L, +-3.8723951502862058660874073462456610731178E-2L, +-4.0566284516358241168330505467000838017425E-2L, +-4.2444048996543693813649967076598766917965E-2L, +-4.4356826869355401653098777649745233339196E-2L, +-4.6304207416957323121106944474331029996141E-2L, +-4.8285787106164123613318093945035804818364E-2L, +-5.0301169421838218987124461766244507342648E-2L, +-5.2349964705088137924875459464622098310997E-2L, +-5.4431789996103111613753440311680967840214E-2L, +-5.6546268881465384189752786409400404404794E-2L, +-5.8693031345788023909329239565012647817664E-2L, +-6.0871713627532018185577188079210189048340E-2L, +-6.3081958078862169742820420185833800925568E-2L, +-6.5323413029406789694910800219643791556918E-2L, +-6.7595732653791419081537811574227049288168E-2L +}; + +/* ln(2) = ln2a + ln2b with extended precision. */ +static const long double + ln2a = 6.93145751953125e-1L, + ln2b = 1.4286068203094172321214581765680755001344E-6L; + +long double +logl(long double x) +{ + long double z, y, w; + ieee_quad_shape_type u, t; + unsigned int m; + int k, e; + + u.value = x; + m = u.parts32.mswhi; + + /* Check for IEEE special cases. */ + k = m & 0x7fffffff; + /* log(0) = -infinity. */ + if ((k | u.parts32.mswlo | u.parts32.lswhi | u.parts32.lswlo) == 0) + { + return -0.5L / ZERO; + } + /* log ( x < 0 ) = NaN */ + if (m & 0x80000000) + { + return (x - x) / ZERO; + } + /* log (infinity or NaN) */ + if (k >= 0x7fff0000) + { + return x + x; + } + + /* Extract exponent and reduce domain to 0.703125 <= u < 1.40625 */ + e = (int) (m >> 16) - (int) 0x3ffe; + m &= 0xffff; + u.parts32.mswhi = m | 0x3ffe0000; + m |= 0x10000; + /* Find lookup table index k from high order bits of the significand. */ + if (m < 0x16800) + { + k = (m - 0xff00) >> 9; + /* t is the argument 0.5 + (k+26)/128 + of the nearest item to u in the lookup table. */ + t.parts32.mswhi = 0x3fff0000 + (k << 9); + t.parts32.mswlo = 0; + t.parts32.lswhi = 0; + t.parts32.lswlo = 0; + u.parts32.mswhi += 0x10000; + e -= 1; + k += 64; + } + else + { + k = (m - 0xfe00) >> 10; + t.parts32.mswhi = 0x3ffe0000 + (k << 10); + t.parts32.mswlo = 0; + t.parts32.lswhi = 0; + t.parts32.lswlo = 0; + } + /* On this interval the table is not used due to cancellation error. */ + if ((x <= 1.0078125L) && (x >= 0.9921875L)) + { + z = x - 1.0L; + k = 64; + t.value = 1.0L; + e = 0; + } + else + { + /* log(u) = log( t u/t ) = log(t) + log(u/t) + log(t) is tabulated in the lookup table. + Express log(u/t) = log(1+z), where z = u/t - 1 = (u-t)/t. + cf. Cody & Waite. */ + z = (u.value - t.value) / t.value; + } + /* Series expansion of log(1+z). */ + w = z * z; + y = ((((((((((((l15 * z + + l14) * z + + l13) * z + + l12) * z + + l11) * z + + l10) * z + + l9) * z + + l8) * z + + l7) * z + + l6) * z + + l5) * z + + l4) * z + + l3) * z * w; + y -= 0.5 * w; + y += e * ln2b; /* Base 2 exponent offset times ln(2). */ + y += z; + y += logtbl[k-26]; /* log(t) - (t-1) */ + y += (t.value - 1.0L); + y += e * ln2a; + return y; +} diff --git a/src/openlibm/ld128/e_powl.c b/src/openlibm/ld128/e_powl.c new file mode 100644 index 0000000..430b261 --- /dev/null +++ b/src/openlibm/ld128/e_powl.c @@ -0,0 +1,439 @@ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * Copyright (c) 2008 Stephen L. Moshier + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* powl(x,y) return x**y + * + * n + * Method: Let x = 2 * (1+f) + * 1. Compute and return log2(x) in two pieces: + * log2(x) = w1 + w2, + * where w1 has 113-53 = 60 bit trailing zeros. + * 2. Perform y*log2(x) = n+y' by simulating muti-precision + * arithmetic, where |y'|<=0.5. + * 3. Return x**y = 2**n*exp(y'*log2) + * + * Special cases: + * 1. (anything) ** 0 is 1 + * 2. (anything) ** 1 is itself + * 3. (anything) ** NAN is NAN + * 4. NAN ** (anything except 0) is NAN + * 5. +-(|x| > 1) ** +INF is +INF + * 6. +-(|x| > 1) ** -INF is +0 + * 7. +-(|x| < 1) ** +INF is +0 + * 8. +-(|x| < 1) ** -INF is +INF + * 9. +-1 ** +-INF is NAN + * 10. +0 ** (+anything except 0, NAN) is +0 + * 11. -0 ** (+anything except 0, NAN, odd integer) is +0 + * 12. +0 ** (-anything except 0, NAN) is +INF + * 13. -0 ** (-anything except 0, NAN, odd integer) is +INF + * 14. -0 ** (odd integer) = -( +0 ** (odd integer) ) + * 15. +INF ** (+anything except 0,NAN) is +INF + * 16. +INF ** (-anything except 0,NAN) is +0 + * 17. -INF ** (anything) = -0 ** (-anything) + * 18. (-anything) ** (integer) is (-1)**(integer)*(+anything**integer) + * 19. (-anything except 0 and inf) ** (non-integer) is NAN + * + */ + +#include + +#include "math_private.h" + +static const long double bp[] = { + 1.0L, + 1.5L, +}; + +/* log_2(1.5) */ +static const long double dp_h[] = { + 0.0, + 5.8496250072115607565592654282227158546448E-1L +}; + +/* Low part of log_2(1.5) */ +static const long double dp_l[] = { + 0.0, + 1.0579781240112554492329533686862998106046E-16L +}; + +static const long double zero = 0.0L, + one = 1.0L, + two = 2.0L, + two113 = 1.0384593717069655257060992658440192E34L, + huge = 1.0e3000L, + tiny = 1.0e-3000L; + +/* 3/2 log x = 3 z + z^3 + z^3 (z^2 R(z^2)) + z = (x-1)/(x+1) + 1 <= x <= 1.25 + Peak relative error 2.3e-37 */ +static const long double LN[] = +{ + -3.0779177200290054398792536829702930623200E1L, + 6.5135778082209159921251824580292116201640E1L, + -4.6312921812152436921591152809994014413540E1L, + 1.2510208195629420304615674658258363295208E1L, + -9.9266909031921425609179910128531667336670E-1L +}; +static const long double LD[] = +{ + -5.129862866715009066465422805058933131960E1L, + 1.452015077564081884387441590064272782044E2L, + -1.524043275549860505277434040464085593165E2L, + 7.236063513651544224319663428634139768808E1L, + -1.494198912340228235853027849917095580053E1L + /* 1.0E0 */ +}; + +/* exp(x) = 1 + x - x / (1 - 2 / (x - x^2 R(x^2))) + 0 <= x <= 0.5 + Peak relative error 5.7e-38 */ +static const long double PN[] = +{ + 5.081801691915377692446852383385968225675E8L, + 9.360895299872484512023336636427675327355E6L, + 4.213701282274196030811629773097579432957E4L, + 5.201006511142748908655720086041570288182E1L, + 9.088368420359444263703202925095675982530E-3L, +}; +static const long double PD[] = +{ + 3.049081015149226615468111430031590411682E9L, + 1.069833887183886839966085436512368982758E8L, + 8.259257717868875207333991924545445705394E5L, + 1.872583833284143212651746812884298360922E3L, + /* 1.0E0 */ +}; + +static const long double + /* ln 2 */ + lg2 = 6.9314718055994530941723212145817656807550E-1L, + lg2_h = 6.9314718055994528622676398299518041312695E-1L, + lg2_l = 2.3190468138462996154948554638754786504121E-17L, + ovt = 8.0085662595372944372e-0017L, + /* 2/(3*log(2)) */ + cp = 9.6179669392597560490661645400126142495110E-1L, + cp_h = 9.6179669392597555432899980587535537779331E-1L, + cp_l = 5.0577616648125906047157785230014751039424E-17L; + +long double +powl(long double x, long double y) +{ + long double z, ax, z_h, z_l, p_h, p_l; + long double yy1, t1, t2, r, s, t, u, v, w; + long double s2, s_h, s_l, t_h, t_l; + int32_t i, j, k, yisint, n; + u_int32_t ix, iy; + int32_t hx, hy; + ieee_quad_shape_type o, p, q; + + p.value = x; + hx = p.parts32.mswhi; + ix = hx & 0x7fffffff; + + q.value = y; + hy = q.parts32.mswhi; + iy = hy & 0x7fffffff; + + + /* y==zero: x**0 = 1 */ + if ((iy | q.parts32.mswlo | q.parts32.lswhi | q.parts32.lswlo) == 0) + return one; + + /* 1.0**y = 1; -1.0**+-Inf = 1 */ + if (x == one) + return one; + if (x == -1.0L && iy == 0x7fff0000 + && (q.parts32.mswlo | q.parts32.lswhi | q.parts32.lswlo) == 0) + return one; + + /* +-NaN return x+y */ + if ((ix > 0x7fff0000) + || ((ix == 0x7fff0000) + && ((p.parts32.mswlo | p.parts32.lswhi | p.parts32.lswlo) != 0)) + || (iy > 0x7fff0000) + || ((iy == 0x7fff0000) + && ((q.parts32.mswlo | q.parts32.lswhi | q.parts32.lswlo) != 0))) + return x + y; + + /* determine if y is an odd int when x < 0 + * yisint = 0 ... y is not an integer + * yisint = 1 ... y is an odd int + * yisint = 2 ... y is an even int + */ + yisint = 0; + if (hx < 0) + { + if (iy >= 0x40700000) /* 2^113 */ + yisint = 2; /* even integer y */ + else if (iy >= 0x3fff0000) /* 1.0 */ + { + if (floorl (y) == y) + { + z = 0.5 * y; + if (floorl (z) == z) + yisint = 2; + else + yisint = 1; + } + } + } + + /* special value of y */ + if ((q.parts32.mswlo | q.parts32.lswhi | q.parts32.lswlo) == 0) + { + if (iy == 0x7fff0000) /* y is +-inf */ + { + if (((ix - 0x3fff0000) | p.parts32.mswlo | p.parts32.lswhi | + p.parts32.lswlo) == 0) + return y - y; /* +-1**inf is NaN */ + else if (ix >= 0x3fff0000) /* (|x|>1)**+-inf = inf,0 */ + return (hy >= 0) ? y : zero; + else /* (|x|<1)**-,+inf = inf,0 */ + return (hy < 0) ? -y : zero; + } + if (iy == 0x3fff0000) + { /* y is +-1 */ + if (hy < 0) + return one / x; + else + return x; + } + if (hy == 0x40000000) + return x * x; /* y is 2 */ + if (hy == 0x3ffe0000) + { /* y is 0.5 */ + if (hx >= 0) /* x >= +0 */ + return sqrtl (x); + } + } + + ax = fabsl (x); + /* special value of x */ + if ((p.parts32.mswlo | p.parts32.lswhi | p.parts32.lswlo) == 0) + { + if (ix == 0x7fff0000 || ix == 0 || ix == 0x3fff0000) + { + z = ax; /*x is +-0,+-inf,+-1 */ + if (hy < 0) + z = one / z; /* z = (1/|x|) */ + if (hx < 0) + { + if (((ix - 0x3fff0000) | yisint) == 0) + { + z = (z - z) / (z - z); /* (-1)**non-int is NaN */ + } + else if (yisint == 1) + z = -z; /* (x<0)**odd = -(|x|**odd) */ + } + return z; + } + } + + /* (x<0)**(non-int) is NaN */ + if (((((u_int32_t) hx >> 31) - 1) | yisint) == 0) + return (x - x) / (x - x); + + /* |y| is huge. + 2^-16495 = 1/2 of smallest representable value. + If (1 - 1/131072)^y underflows, y > 1.4986e9 */ + if (iy > 0x401d654b) + { + /* if (1 - 2^-113)^y underflows, y > 1.1873e38 */ + if (iy > 0x407d654b) + { + if (ix <= 0x3ffeffff) + return (hy < 0) ? huge * huge : tiny * tiny; + if (ix >= 0x3fff0000) + return (hy > 0) ? huge * huge : tiny * tiny; + } + /* over/underflow if x is not close to one */ + if (ix < 0x3ffeffff) + return (hy < 0) ? huge * huge : tiny * tiny; + if (ix > 0x3fff0000) + return (hy > 0) ? huge * huge : tiny * tiny; + } + + n = 0; + /* take care subnormal number */ + if (ix < 0x00010000) + { + ax *= two113; + n -= 113; + o.value = ax; + ix = o.parts32.mswhi; + } + n += ((ix) >> 16) - 0x3fff; + j = ix & 0x0000ffff; + /* determine interval */ + ix = j | 0x3fff0000; /* normalize ix */ + if (j <= 0x3988) + k = 0; /* |x|> 31) - 1) | (yisint - 1)) == 0) + s = -one; /* (-ve)**(odd int) */ + + /* split up y into yy1+y2 and compute (yy1+y2)*(t1+t2) */ + yy1 = y; + o.value = yy1; + o.parts32.lswlo = 0; + o.parts32.lswhi &= 0xf8000000; + yy1 = o.value; + p_l = (y - yy1) * t1 + y * t2; + p_h = yy1 * t1; + z = p_l + p_h; + o.value = z; + j = o.parts32.mswhi; + if (j >= 0x400d0000) /* z >= 16384 */ + { + /* if z > 16384 */ + if (((j - 0x400d0000) | o.parts32.mswlo | o.parts32.lswhi | + o.parts32.lswlo) != 0) + return s * huge * huge; /* overflow */ + else + { + if (p_l + ovt > z - p_h) + return s * huge * huge; /* overflow */ + } + } + else if ((j & 0x7fffffff) >= 0x400d01b9) /* z <= -16495 */ + { + /* z < -16495 */ + if (((j - 0xc00d01bc) | o.parts32.mswlo | o.parts32.lswhi | + o.parts32.lswlo) + != 0) + return s * tiny * tiny; /* underflow */ + else + { + if (p_l <= z - p_h) + return s * tiny * tiny; /* underflow */ + } + } + /* compute 2**(p_h+p_l) */ + i = j & 0x7fffffff; + k = (i >> 16) - 0x3fff; + n = 0; + if (i > 0x3ffe0000) + { /* if |z| > 0.5, set n = [z+0.5] */ + n = floorl (z + 0.5L); + t = n; + p_h -= t; + } + t = p_l + p_h; + o.value = t; + o.parts32.lswlo = 0; + o.parts32.lswhi &= 0xf8000000; + t = o.value; + u = t * lg2_h; + v = (p_l - (t - p_h)) * lg2 + t * lg2_l; + z = u + v; + w = v - (z - u); + /* exp(z) */ + t = z * z; + u = PN[0] + t * (PN[1] + t * (PN[2] + t * (PN[3] + t * PN[4]))); + v = PD[0] + t * (PD[1] + t * (PD[2] + t * (PD[3] + t))); + t1 = z - t * u / v; + r = (z * t1) / (t1 - two) - (w + z * w); + z = one - (r - z); + o.value = z; + j = o.parts32.mswhi; + j += (n << 16); + if ((j >> 16) <= 0) + z = scalbnl (z, n); /* subnormal output */ + else + { + o.parts32.mswhi = j; + z = o.value; + } + return s * z; +} diff --git a/src/openlibm/ld128/e_rem_pio2l.h b/src/openlibm/ld128/e_rem_pio2l.h new file mode 100644 index 0000000..5224245 --- /dev/null +++ b/src/openlibm/ld128/e_rem_pio2l.h @@ -0,0 +1,144 @@ +/* From: @(#)e_rem_pio2.c 1.4 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * Copyright (c) 2008 Steven G. Kargl, David Schultz, Bruce D. Evans. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + * + * Optimized by Bruce D. Evans. + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/ld128/e_rem_pio2l.h,v 1.2 2011/05/30 19:41:28 kargl Exp $"); + +/* ld128 version of __ieee754_rem_pio2l(x,y) + * + * return the remainder of x rem pi/2 in y[0]+y[1] + * use __kernel_rem_pio2() + */ + +#include +#include + +#include "math_private.h" +#include "fpmath.h" + +#define BIAS (LDBL_MAX_EXP - 1) + +/* + * XXX need to verify that nonzero integer multiples of pi/2 within the + * range get no closer to a long double than 2**-140, or that + * ilogb(x) + ilogb(min_delta) < 45 - -140. + */ +/* + * invpio2: 113 bits of 2/pi + * pio2_1: first 68 bits of pi/2 + * pio2_1t: pi/2 - pio2_1 + * pio2_2: second 68 bits of pi/2 + * pio2_2t: pi/2 - (pio2_1+pio2_2) + * pio2_3: third 68 bits of pi/2 + * pio2_3t: pi/2 - (pio2_1+pio2_2+pio2_3) + */ + +static const double +zero = 0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */ +two24 = 1.67772160000000000000e+07; /* 0x41700000, 0x00000000 */ + +static const long double +invpio2 = 6.3661977236758134307553505349005747e-01L, /* 0x145f306dc9c882a53f84eafa3ea6a.0p-113 */ +pio2_1 = 1.5707963267948966192292994253909555e+00L, /* 0x1921fb54442d18469800000000000.0p-112 */ +pio2_1t = 2.0222662487959507323996846200947577e-21L, /* 0x13198a2e03707344a4093822299f3.0p-181 */ +pio2_2 = 2.0222662487959507323994779168837751e-21L, /* 0x13198a2e03707344a400000000000.0p-181 */ +pio2_2t = 2.0670321098263988236496903051604844e-43L, /* 0x127044533e63a0105df531d89cd91.0p-254 */ +pio2_3 = 2.0670321098263988236499468110329591e-43L, /* 0x127044533e63a0105e00000000000.0p-254 */ +pio2_3t = -2.5650587247459238361625433492959285e-65L; /* -0x159c4ec64ddaeb5f78671cbfb2210.0p-327 */ + +//VBS +//static inline __always_inline int +//__ieee754_rem_pio2l(long double x, long double *y) + +static inline int +__ieee754_rem_pio2l(long double x, long double *y) +{ + union IEEEl2bits u,u1; + long double z,w,t,r,fn; + double tx[5],ty[3]; + int64_t n; + int e0,ex,i,j,nx; + int16_t expsign; + + u.e = x; + expsign = u.xbits.expsign; + ex = expsign & 0x7fff; + if (ex < BIAS + 45 || ex == BIAS + 45 && + u.bits.manh < 0x921fb54442d1LL) { + /* |x| ~< 2^45*(pi/2), medium size */ + /* Use a specialized rint() to get fn. Assume round-to-nearest. */ + fn = x*invpio2+0x1.8p112; + fn = fn-0x1.8p112; +#ifdef HAVE_EFFICIENT_I64RINT + n = i64rint(fn); +#else + n = fn; +#endif + r = x-fn*pio2_1; + w = fn*pio2_1t; /* 1st round good to 180 bit */ + { + union IEEEl2bits u2; + int ex1; + j = ex; + y[0] = r-w; + u2.e = y[0]; + ex1 = u2.xbits.expsign & 0x7fff; + i = j-ex1; + if(i>51) { /* 2nd iteration needed, good to 248 */ + t = r; + w = fn*pio2_2; + r = t-w; + w = fn*pio2_2t-((t-r)-w); + y[0] = r-w; + u2.e = y[0]; + ex1 = u2.xbits.expsign & 0x7fff; + i = j-ex1; + if(i>119) { /* 3rd iteration need, 316 bits acc */ + t = r; /* will cover all possible cases */ + w = fn*pio2_3; + r = t-w; + w = fn*pio2_3t-((t-r)-w); + y[0] = r-w; + } + } + } + y[1] = (r-y[0])-w; + return n; + } + /* + * all other (large) arguments + */ + if(ex==0x7fff) { /* x is inf or NaN */ + y[0]=y[1]=x-x; return 0; + } + /* set z = scalbn(|x|,ilogb(x)-23) */ + u1.e = x; + e0 = ex - BIAS - 23; /* e0 = ilogb(|x|)-23; */ + u1.xbits.expsign = ex - e0; + z = u1.e; + for(i=0;i<4;i++) { + tx[i] = (double)((int32_t)(z)); + z = (z-tx[i])*two24; + } + tx[4] = z; + nx = 5; + while(tx[nx-1]==zero) nx--; /* skip zero term */ + n = __kernel_rem_pio2(tx,ty,e0,nx,3); + t = (long double)ty[2] + ty[1]; + r = t + ty[0]; + w = ty[0] - (r - t); + if(expsign<0) {y[0] = -r; y[1] = -w; return -n;} + y[0] = r; y[1] = w; return n; +} diff --git a/src/openlibm/ld128/e_sinhl.c b/src/openlibm/ld128/e_sinhl.c new file mode 100644 index 0000000..3bfdb5d --- /dev/null +++ b/src/openlibm/ld128/e_sinhl.c @@ -0,0 +1,104 @@ +/* @(#)e_sinh.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * Copyright (c) 2008 Stephen L. Moshier + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* sinhl(x) + * Method : + * mathematically sinh(x) if defined to be (exp(x)-exp(-x))/2 + * 1. Replace x by |x| (sinhl(-x) = -sinhl(x)). + * 2. + * E + E/(E+1) + * 0 <= x <= 25 : sinhl(x) := --------------, E=expm1l(x) + * 2 + * + * 25 <= x <= lnovft : sinhl(x) := expl(x)/2 + * lnovft <= x <= ln2ovft: sinhl(x) := expl(x/2)/2 * expl(x/2) + * ln2ovft < x : sinhl(x) := x*shuge (overflow) + * + * Special cases: + * sinhl(x) is |x| if x is +INF, -INF, or NaN. + * only sinhl(0)=0 is exact for finite x. + */ + +#include + +#include "math_private.h" + +static const long double one = 1.0, shuge = 1.0e4931L, +ovf_thresh = 1.1357216553474703894801348310092223067821E4L; + +long double +sinhl(long double x) +{ + long double t, w, h; + u_int32_t jx, ix; + ieee_quad_shape_type u; + + /* Words of |x|. */ + u.value = x; + jx = u.parts32.mswhi; + ix = jx & 0x7fffffff; + + /* x is INF or NaN */ + if (ix >= 0x7fff0000) + return x + x; + + h = 0.5; + if (jx & 0x80000000) + h = -h; + + /* Absolute value of x. */ + u.parts32.mswhi = ix; + + /* |x| in [0,40], return sign(x)*0.5*(E+E/(E+1))) */ + if (ix <= 0x40044000) + { + if (ix < 0x3fc60000) /* |x| < 2^-57 */ + if (shuge + x > one) + return x; /* sinh(tiny) = tiny with inexact */ + t = expm1l (u.value); + if (ix < 0x3fff0000) + return h * (2.0 * t - t * t / (t + one)); + return h * (t + t / (t + one)); + } + + /* |x| in [40, log(maxdouble)] return 0.5*exp(|x|) */ + if (ix <= 0x400c62e3) /* 11356.375 */ + return h * expl (u.value); + + /* |x| in [log(maxdouble), overflowthreshold] + Overflow threshold is log(2 * maxdouble). */ + if (u.value <= ovf_thresh) + { + w = expl (0.5 * u.value); + t = h * w; + return t * w; + } + + /* |x| > overflowthreshold, sinhl(x) overflow */ + return x * shuge; +} diff --git a/src/openlibm/ld128/e_tgammal.c b/src/openlibm/ld128/e_tgammal.c new file mode 100644 index 0000000..6c78c24 --- /dev/null +++ b/src/openlibm/ld128/e_tgammal.c @@ -0,0 +1,39 @@ +/* $OpenBSD: e_tgammal.c,v 1.1 2011/07/06 00:02:42 martynas Exp $ */ + +/* + * Copyright (c) 2011 Martynas Venckus + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include "math_private.h" + +long double +tgammal(long double x) +{ + int64_t i0,i1; + + GET_LDOUBLE_WORDS64(i0,i1,x); + if (((i0&0x7fffffffffffffffLL)|i1) == 0) + return (1.0/x); + + if (i0<0 && (u_int64_t)i0<0xffff000000000000ULL && rintl(x)==x) + return (x-x)/(x-x); + + if (i0==0xffff000000000000ULL && i1==0) + return (x-x); + + return expl(lgammal(x)); +} diff --git a/src/openlibm/ld128/invtrig.c b/src/openlibm/ld128/invtrig.c new file mode 100644 index 0000000..5a869c2 --- /dev/null +++ b/src/openlibm/ld128/invtrig.c @@ -0,0 +1,100 @@ +/*- + * Copyright (c) 2008 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/ld128/invtrig.c,v 1.1 2008/07/31 22:41:26 das Exp $"); + +#include "ld128/invtrig.h" + +/* + * asinl() and acosl() + */ +const long double +pS0 = 1.66666666666666666666666666666700314e-01L, +pS1 = -7.32816946414566252574527475428622708e-01L, +pS2 = 1.34215708714992334609030036562143589e+00L, +pS3 = -1.32483151677116409805070261790752040e+00L, +pS4 = 7.61206183613632558824485341162121989e-01L, +pS5 = -2.56165783329023486777386833928147375e-01L, +pS6 = 4.80718586374448793411019434585413855e-02L, +pS7 = -4.42523267167024279410230886239774718e-03L, +pS8 = 1.44551535183911458253205638280410064e-04L, +pS9 = -2.10558957916600254061591040482706179e-07L, +qS1 = -4.84690167848739751544716485245697428e+00L, +qS2 = 9.96619113536172610135016921140206980e+00L, +qS3 = -1.13177895428973036660836798461641458e+01L, +qS4 = 7.74004374389488266169304117714658761e+00L, +qS5 = -3.25871986053534084709023539900339905e+00L, +qS6 = 8.27830318881232209752469022352928864e-01L, +qS7 = -1.18768052702942805423330715206348004e-01L, +qS8 = 8.32600764660522313269101537926539470e-03L, +qS9 = -1.99407384882605586705979504567947007e-04L; + +/* + * atanl() + */ +const long double atanhi[] = { + 4.63647609000806116214256231461214397e-01L, + 7.85398163397448309615660845819875699e-01L, + 9.82793723247329067985710611014666038e-01L, + 1.57079632679489661923132169163975140e+00L, +}; + +const long double atanlo[] = { + 4.89509642257333492668618435220297706e-36L, + 2.16795253253094525619926100651083806e-35L, + -2.31288434538183565909319952098066272e-35L, + 4.33590506506189051239852201302167613e-35L, +}; + +const long double aT[] = { + 3.33333333333333333333333333333333125e-01L, + -1.99999999999999999999999999999180430e-01L, + 1.42857142857142857142857142125269827e-01L, + -1.11111111111111111111110834490810169e-01L, + 9.09090909090909090908522355708623681e-02L, + -7.69230769230769230696553844935357021e-02L, + 6.66666666666666660390096773046256096e-02L, + -5.88235294117646671706582985209643694e-02L, + 5.26315789473666478515847092020327506e-02L, + -4.76190476189855517021024424991436144e-02L, + 4.34782608678695085948531993458097026e-02L, + -3.99999999632663469330634215991142368e-02L, + 3.70370363987423702891250829918659723e-02L, + -3.44827496515048090726669907612335954e-02L, + 3.22579620681420149871973710852268528e-02L, + -3.03020767654269261041647570626778067e-02L, + 2.85641979882534783223403715930946138e-02L, + -2.69824879726738568189929461383741323e-02L, + 2.54194698498808542954187110873675769e-02L, + -2.35083879708189059926183138130183215e-02L, + 2.04832358998165364349957325067131428e-02L, + -1.54489555488544397858507248612362957e-02L, + 8.64492360989278761493037861575248038e-03L, + -2.58521121597609872727919154569765469e-03L, +}; + +const long double pi_lo = 8.67181013012378102479704402604335225e-35L; diff --git a/src/openlibm/ld128/invtrig.h b/src/openlibm/ld128/invtrig.h new file mode 100644 index 0000000..c85a615 --- /dev/null +++ b/src/openlibm/ld128/invtrig.h @@ -0,0 +1,113 @@ +/*- + * Copyright (c) 2008 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/msun/ld128/invtrig.h,v 1.1 2008/07/31 22:41:26 das Exp $ + */ + +#include + +#include "fpmath.h" + +#define BIAS (LDBL_MAX_EXP - 1) +#define MANH_SIZE (LDBL_MANH_SIZE + 1) + +/* Approximation thresholds. */ +#define ASIN_LINEAR (BIAS - 56) /* 2**-56 */ +#define ACOS_CONST (BIAS - 113) /* 2**-113 */ +#define ATAN_CONST (BIAS + 113) /* 2**113 */ +#define ATAN_LINEAR (BIAS - 56) /* 2**-56 */ + +/* 0.95 */ +#define THRESH ((0xe666666666666666ULL>>(64-(MANH_SIZE-1)))|LDBL_NBIT) + +/* Constants shared by the long double inverse trig functions. */ +#define pS0 _ItL_pS0 +#define pS1 _ItL_pS1 +#define pS2 _ItL_pS2 +#define pS3 _ItL_pS3 +#define pS4 _ItL_pS4 +#define pS5 _ItL_pS5 +#define pS6 _ItL_pS6 +#define pS7 _ItL_pS7 +#define pS8 _ItL_pS8 +#define pS9 _ItL_pS9 +#define qS1 _ItL_qS1 +#define qS2 _ItL_qS2 +#define qS3 _ItL_qS3 +#define qS4 _ItL_qS4 +#define qS5 _ItL_qS5 +#define qS6 _ItL_qS6 +#define qS7 _ItL_qS7 +#define qS8 _ItL_qS8 +#define qS9 _ItL_qS9 +#define atanhi _ItL_atanhi +#define atanlo _ItL_atanlo +#define aT _ItL_aT +#define pi_lo _ItL_pi_lo + +#define pio2_hi atanhi[3] +#define pio2_lo atanlo[3] +#define pio4_hi atanhi[1] + +/* Constants shared by the long double inverse trig functions. */ +extern const long double pS0, pS1, pS2, pS3, pS4, pS5, pS6, pS7, pS8, pS9; +extern const long double qS1, qS2, qS3, qS4, qS5, qS6, qS7, qS8, qS9; +extern const long double atanhi[], atanlo[], aT[]; +extern const long double pi_lo; + +static inline long double +P(long double x) +{ + + return (x * (pS0 + x * (pS1 + x * (pS2 + x * (pS3 + x * \ + (pS4 + x * (pS5 + x * (pS6 + x * (pS7 + x * (pS8 + x * \ + pS9)))))))))); +} + +static inline long double +Q(long double x) +{ + + return (1.0 + x * (qS1 + x * (qS2 + x * (qS3 + x * (qS4 + x * \ + (qS5 + x * (qS6 + x * (qS7 + x * (qS8 + x * qS9))))))))); +} + +static inline long double +T_even(long double x) +{ + + return (aT[0] + x * (aT[2] + x * (aT[4] + x * (aT[6] + x * \ + (aT[8] + x * (aT[10] + x * (aT[12] + x * (aT[14] + x * \ + (aT[16] + x * (aT[18] + x * (aT[20] + x * aT[22]))))))))))); +} + +static inline long double +T_odd(long double x) +{ + + return (aT[1] + x * (aT[3] + x * (aT[5] + x * (aT[7] + x * \ + (aT[9] + x * (aT[11] + x * (aT[13] + x * (aT[15] + x * \ + (aT[17] + x * (aT[19] + x * (aT[21] + x * aT[23]))))))))))); +} diff --git a/src/openlibm/ld128/k_cosl.c b/src/openlibm/ld128/k_cosl.c new file mode 100644 index 0000000..37666dc --- /dev/null +++ b/src/openlibm/ld128/k_cosl.c @@ -0,0 +1,61 @@ +/* From: @(#)k_cos.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * Copyright (c) 2008 Steven G. Kargl, David Schultz, Bruce D. Evans. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/ld128/k_cosl.c,v 1.1 2008/02/17 07:32:31 das Exp $"); + +/* + * ld128 version of k_cos.c. See ../src/k_cos.c for most comments. + */ + +#include "math_private.h" + +/* + * Domain [-0.7854, 0.7854], range ~[-1.80e-37, 1.79e-37]: + * |cos(x) - c(x))| < 2**-122.0 + * + * 113-bit precision requires more care than 64-bit precision, since + * simple methods give a minimax polynomial with coefficient for x^2 + * that is 1 ulp below 0.5, but we want it to be precisely 0.5. See + * ../ld80/k_cosl.c for more details. + */ +static const double +one = 1.0; + +static const long double +C1 = 0.04166666666666666666666666666666658424671L, +C2 = -0.001388888888888888888888888888863490893732L, +C3 = 0.00002480158730158730158730158600795304914210L, +C4 = -0.2755731922398589065255474947078934284324e-6L, +C5 = 0.2087675698786809897659225313136400793948e-8L, +C6 = -0.1147074559772972315817149986812031204775e-10L, +C7 = 0.4779477332386808976875457937252120293400e-13L; + +static const double +C8 = -0.1561920696721507929516718307820958119868e-15, +C9 = 0.4110317413744594971475941557607804508039e-18, +C10 = -0.8896592467191938803288521958313920156409e-21, +C11 = 0.1601061435794535138244346256065192782581e-23; + +long double +__kernel_cosl(long double x, long double y) +{ + long double hz,z,r,w; + + z = x*x; + r = z*(C1+z*(C2+z*(C3+z*(C4+z*(C5+z*(C6+z*(C7+ + z*(C8+z*(C9+z*(C10+z*C11)))))))))); + hz = 0.5*z; + w = one-hz; + return w + (((one-w)-hz) + (z*r-x*y)); +} diff --git a/src/openlibm/ld128/k_sinl.c b/src/openlibm/ld128/k_sinl.c new file mode 100644 index 0000000..1079159 --- /dev/null +++ b/src/openlibm/ld128/k_sinl.c @@ -0,0 +1,59 @@ +/* From: @(#)k_sin.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * Copyright (c) 2008 Steven G. Kargl, David Schultz, Bruce D. Evans. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/ld128/k_sinl.c,v 1.1 2008/02/17 07:32:31 das Exp $"); + +/* + * ld128 version of k_sin.c. See ../src/k_sin.c for most comments. + */ + +#include "math_private.h" + +static const double +half = 0.5; + +/* + * Domain [-0.7854, 0.7854], range ~[-1.53e-37, 1.659e-37] + * |sin(x)/x - s(x)| < 2**-122.1 + * + * See ../ld80/k_cosl.c for more details about the polynomial. + */ +static const long double +S1 = -0.16666666666666666666666666666666666606732416116558L, +S2 = 0.0083333333333333333333333333333331135404851288270047L, +S3 = -0.00019841269841269841269841269839935785325638310428717L, +S4 = 0.27557319223985890652557316053039946268333231205686e-5L, +S5 = -0.25052108385441718775048214826384312253862930064745e-7L, +S6 = 0.16059043836821614596571832194524392581082444805729e-9L, +S7 = -0.76471637318198151807063387954939213287488216303768e-12L, +S8 = 0.28114572543451292625024967174638477283187397621303e-14L; + +static const double +S9 = -0.82206352458348947812512122163446202498005154296863e-17, +S10 = 0.19572940011906109418080609928334380560135358385256e-19, +S11 = -0.38680813379701966970673724299207480965452616911420e-22, +S12 = 0.64038150078671872796678569586315881020659912139412e-25; + +long double +__kernel_sinl(long double x, long double y, int iy) +{ + long double z,r,v; + + z = x*x; + v = z*x; + r = S2+z*(S3+z*(S4+z*(S5+z*(S6+z*(S7+z*(S8+ + z*(S9+z*(S10+z*(S11+z*S12))))))))); + if(iy==0) return x+v*(S1+z*r); + else return x-((z*(half*y-v*r)-y)-v*S1); +} diff --git a/src/openlibm/ld128/k_tanl.c b/src/openlibm/ld128/k_tanl.c new file mode 100644 index 0000000..7255076 --- /dev/null +++ b/src/openlibm/ld128/k_tanl.c @@ -0,0 +1,120 @@ +/* From: @(#)k_tan.c 1.5 04/04/22 SMI */ + +/* + * ==================================================== + * Copyright 2004 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2008 Steven G. Kargl, David Schultz, Bruce D. Evans. + * + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/ld128/k_tanl.c,v 1.1 2008/02/17 07:32:31 das Exp $"); + +/* + * ld128 version of k_tan.c. See ../src/k_tan.c for most comments. + */ + +#include + +#include "math_private.h" + +/* + * Domain [-0.67434, 0.67434], range ~[-3.37e-36, 1.982e-37] + * |tan(x)/x - t(x)| < 2**-117.8 (XXX should be ~1e-37) + * + * See ../ld80/k_cosl.c for more details about the polynomial. + */ +static const long double +T3 = 0x1.5555555555555555555555555553p-2L, +T5 = 0x1.1111111111111111111111111eb5p-3L, +T7 = 0x1.ba1ba1ba1ba1ba1ba1ba1b694cd6p-5L, +T9 = 0x1.664f4882c10f9f32d6bbe09d8bcdp-6L, +T11 = 0x1.226e355e6c23c8f5b4f5762322eep-7L, +T13 = 0x1.d6d3d0e157ddfb5fed8e84e27b37p-9L, +T15 = 0x1.7da36452b75e2b5fce9ee7c2c92ep-10L, +T17 = 0x1.355824803674477dfcf726649efep-11L, +T19 = 0x1.f57d7734d1656e0aceb716f614c2p-13L, +T21 = 0x1.967e18afcb180ed942dfdc518d6cp-14L, +T23 = 0x1.497d8eea21e95bc7e2aa79b9f2cdp-15L, +T25 = 0x1.0b132d39f055c81be49eff7afd50p-16L, +T27 = 0x1.b0f72d33eff7bfa2fbc1059d90b6p-18L, +T29 = 0x1.5ef2daf21d1113df38d0fbc00267p-19L, +T31 = 0x1.1c77d6eac0234988cdaa04c96626p-20L, +T33 = 0x1.cd2a5a292b180e0bdd701057dfe3p-22L, +T35 = 0x1.75c7357d0298c01a31d0a6f7d518p-23L, +T37 = 0x1.2f3190f4718a9a520f98f50081fcp-24L, +pio4 = 0x1.921fb54442d18469898cc51701b8p-1L, +pio4lo = 0x1.cd129024e088a67cc74020bbea60p-116L; + +static const double +T39 = 0.000000028443389121318352, /* 0x1e8a7592977938.0p-78 */ +T41 = 0.000000011981013102001973, /* 0x19baa1b1223219.0p-79 */ +T43 = 0.0000000038303578044958070, /* 0x107385dfb24529.0p-80 */ +T45 = 0.0000000034664378216909893, /* 0x1dc6c702a05262.0p-81 */ +T47 = -0.0000000015090641701997785, /* -0x19ecef3569ebb6.0p-82 */ +T49 = 0.0000000029449552300483952, /* 0x194c0668da786a.0p-81 */ +T51 = -0.0000000022006995706097711, /* -0x12e763b8845268.0p-81 */ +T53 = 0.0000000015468200913196612, /* 0x1a92fc98c29554.0p-82 */ +T55 = -0.00000000061311613386849674, /* -0x151106cbc779a9.0p-83 */ +T57 = 1.4912469681508012e-10; /* 0x147edbdba6f43a.0p-85 */ + +long double +__kernel_tanl(long double x, long double y, int iy) { + long double z, r, v, w, s; + long double osign; + int i; + + iy = (iy == 1 ? -1 : 1); /* XXX recover original interface */ + osign = (x >= 0 ? 1.0 : -1.0); /* XXX slow, probably wrong for -0 */ + if (fabsl(x) >= 0.67434) { + if (x < 0) { + x = -x; + y = -y; + } + z = pio4 - x; + w = pio4lo - y; + x = z + w; + y = 0.0; + i = 1; + } else + i = 0; + z = x * x; + w = z * z; + r = T5 + w * (T9 + w * (T13 + w * (T17 + w * (T21 + + w * (T25 + w * (T29 + w * (T33 + + w * (T37 + w * (T41 + w * (T45 + w * (T49 + w * (T53 + + w * T57)))))))))))); + v = z * (T7 + w * (T11 + w * (T15 + w * (T19 + w * (T23 + + w * (T27 + w * (T31 + w * (T35 + + w * (T39 + w * (T43 + w * (T47 + w * (T51 + w * T55)))))))))))); + s = z * x; + r = y + z * (s * (r + v) + y); + r += T3 * s; + w = x + r; + if (i == 1) { + v = (long double) iy; + return osign * + (v - 2.0 * (x - (w * w / (w + v) - r))); + } + if (iy == 1) + return w; + else { + /* + * if allow error up to 2 ulp, simply return + * -1.0 / (x+r) here + */ + /* compute -1.0 / (x+r) accurately */ + long double a, t; + z = w; + z = z + 0x1p32 - 0x1p32; + v = r - (z - x); /* z+v = r+x */ + t = a = -1.0 / w; /* a = -1.0/w */ + t = t + 0x1p32 - 0x1p32; + s = 1.0 + t * z; + return t + a * (s + t * v); + } +} diff --git a/src/openlibm/ld128/s_asinhl.c b/src/openlibm/ld128/s_asinhl.c new file mode 100644 index 0000000..29791e8 --- /dev/null +++ b/src/openlibm/ld128/s_asinhl.c @@ -0,0 +1,69 @@ +/* @(#)s_asinh.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* asinhl(x) + * Method : + * Based on + * asinhl(x) = signl(x) * logl [ |x| + sqrtl(x*x+1) ] + * we have + * asinhl(x) := x if 1+x*x=1, + * := signl(x)*(logl(x)+ln2)) for large |x|, else + * := signl(x)*logl(2|x|+1/(|x|+sqrtl(x*x+1))) if|x|>2, else + * := signl(x)*log1pl(|x| + x^2/(1 + sqrtl(1+x^2))) + */ + +#include + +#include "math_private.h" + +static const long double + one = 1.0L, + ln2 = 6.931471805599453094172321214581765681e-1L, + huge = 1.0e+4900L; + +long double +asinhl(long double x) +{ + long double t, w; + int32_t ix, sign; + ieee_quad_shape_type u; + + u.value = x; + sign = u.parts32.mswhi; + ix = sign & 0x7fffffff; + if (ix == 0x7fff0000) + return x + x; /* x is inf or NaN */ + if (ix < 0x3fc70000) + { /* |x| < 2^ -56 */ + if (huge + x > one) + return x; /* return x inexact except 0 */ + } + u.parts32.mswhi = ix; + if (ix > 0x40350000) + { /* |x| > 2 ^ 54 */ + w = logl (u.value) + ln2; + } + else if (ix >0x40000000) + { /* 2^ 54 > |x| > 2.0 */ + t = u.value; + w = logl (2.0 * t + one / (sqrtl (x * x + one) + t)); + } + else + { /* 2.0 > |x| > 2 ^ -56 */ + t = x * x; + w = log1pl (u.value + t / (one + sqrtl (one + t))); + } + if (sign & 0x80000000) + return -w; + else + return w; +} diff --git a/src/openlibm/ld128/s_ceill.c b/src/openlibm/ld128/s_ceill.c new file mode 100644 index 0000000..719e7fc --- /dev/null +++ b/src/openlibm/ld128/s_ceill.c @@ -0,0 +1,69 @@ +/* @(#)s_ceil.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * ceill(x) + * Return x rounded toward -inf to integral value + * Method: + * Bit twiddling. + * Exception: + * Inexact flag raised if x not equal to ceil(x). + */ + +#include + +#include "math_private.h" + +static const long double huge = 1.0e4930L; + +long double +ceill(long double x) +{ + int64_t i0,i1,jj0; + u_int64_t i,j; + GET_LDOUBLE_WORDS64(i0,i1,x); + jj0 = ((i0>>48)&0x7fff)-0x3fff; + if(jj0<48) { + if(jj0<0) { /* raise inexact if x != 0 */ + if(huge+x>0.0) {/* return 0*sign(x) if |x|<1 */ + if(i0<0) {i0=0x8000000000000000ULL;i1=0;} + else if((i0|i1)!=0) { i0=0x3fff000000000000ULL;i1=0;} + } + } else { + i = (0x0000ffffffffffffULL)>>jj0; + if(((i0&i)|i1)==0) return x; /* x is integral */ + if(huge+x>0.0) { /* raise inexact flag */ + if(i0>0) i0 += (0x0001000000000000LL)>>jj0; + i0 &= (~i); i1=0; + } + } + } else if (jj0>111) { + if(jj0==0x4000) return x+x; /* inf or NaN */ + else return x; /* x is integral */ + } else { + i = -1ULL>>(jj0-48); + if((i1&i)==0) return x; /* x is integral */ + if(huge+x>0.0) { /* raise inexact flag */ + if(i0>0) { + if(jj0==48) i0+=1; + else { + j = i1+(1LL<<(112-jj0)); + if(j + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* double erf(double x) + * double erfc(double x) + * x + * 2 |\ + * erf(x) = --------- | exp(-t*t)dt + * sqrt(pi) \| + * 0 + * + * erfc(x) = 1-erf(x) + * Note that + * erf(-x) = -erf(x) + * erfc(-x) = 2 - erfc(x) + * + * Method: + * 1. erf(x) = x + x*R(x^2) for |x| in [0, 7/8] + * Remark. The formula is derived by noting + * erf(x) = (2/sqrt(pi))*(x - x^3/3 + x^5/10 - x^7/42 + ....) + * and that + * 2/sqrt(pi) = 1.128379167095512573896158903121545171688 + * is close to one. + * + * 1a. erf(x) = 1 - erfc(x), for |x| > 1.0 + * erfc(x) = 1 - erf(x) if |x| < 1/4 + * + * 2. For |x| in [7/8, 1], let s = |x| - 1, and + * c = 0.84506291151 rounded to single (24 bits) + * erf(s + c) = sign(x) * (c + P1(s)/Q1(s)) + * Remark: here we use the taylor series expansion at x=1. + * erf(1+s) = erf(1) + s*Poly(s) + * = 0.845.. + P1(s)/Q1(s) + * Note that |P1/Q1|< 0.078 for x in [0.84375,1.25] + * + * 3. For x in [1/4, 5/4], + * erfc(s + const) = erfc(const) + s P1(s)/Q1(s) + * for const = 1/4, 3/8, ..., 9/8 + * and 0 <= s <= 1/8 . + * + * 4. For x in [5/4, 107], + * erfc(x) = (1/x)*exp(-x*x-0.5625 + R(z)) + * z=1/x^2 + * The interval is partitioned into several segments + * of width 1/8 in 1/x. + * + * Note1: + * To compute exp(-x*x-0.5625+R/S), let s be a single + * precision number and s := x; then + * -x*x = -s*s + (s-x)*(s+x) + * exp(-x*x-0.5626+R/S) = + * exp(-s*s-0.5625)*exp((s-x)*(s+x)+R/S); + * Note2: + * Here 4 and 5 make use of the asymptotic series + * exp(-x*x) + * erfc(x) ~ ---------- * ( 1 + Poly(1/x^2) ) + * x*sqrt(pi) + * + * 5. For inf > x >= 107 + * erf(x) = sign(x) *(1 - tiny) (raise inexact) + * erfc(x) = tiny*tiny (raise underflow) if x > 0 + * = 2 - tiny if x<0 + * + * 7. Special case: + * erf(0) = 0, erf(inf) = 1, erf(-inf) = -1, + * erfc(0) = 1, erfc(inf) = 0, erfc(-inf) = 2, + * erfc/erf(NaN) is NaN + */ + +#include + +#include "math_private.h" + +/* Evaluate P[n] x^n + P[n-1] x^(n-1) + ... + P[0] */ + +static long double +neval (long double x, const long double *p, int n) +{ + long double y; + + p += n; + y = *p--; + do + { + y = y * x + *p--; + } + while (--n > 0); + return y; +} + + +/* Evaluate x^n+1 + P[n] x^(n) + P[n-1] x^(n-1) + ... + P[0] */ + +static long double +deval (long double x, const long double *p, int n) +{ + long double y; + + p += n; + y = x + *p--; + do + { + y = y * x + *p--; + } + while (--n > 0); + return y; +} + + + +static const long double +tiny = 1e-4931L, + one = 1.0L, + two = 2.0L, + /* 2/sqrt(pi) - 1 */ + efx = 1.2837916709551257389615890312154517168810E-1L, + /* 8 * (2/sqrt(pi) - 1) */ + efx8 = 1.0270333367641005911692712249723613735048E0L; + + +/* erf(x) = x + x R(x^2) + 0 <= x <= 7/8 + Peak relative error 1.8e-35 */ +#define NTN1 8 +static const long double TN1[NTN1 + 1] = +{ + -3.858252324254637124543172907442106422373E10L, + 9.580319248590464682316366876952214879858E10L, + 1.302170519734879977595901236693040544854E10L, + 2.922956950426397417800321486727032845006E9L, + 1.764317520783319397868923218385468729799E8L, + 1.573436014601118630105796794840834145120E7L, + 4.028077380105721388745632295157816229289E5L, + 1.644056806467289066852135096352853491530E4L, + 3.390868480059991640235675479463287886081E1L +}; +#define NTD1 8 +static const long double TD1[NTD1 + 1] = +{ + -3.005357030696532927149885530689529032152E11L, + -1.342602283126282827411658673839982164042E11L, + -2.777153893355340961288511024443668743399E10L, + -3.483826391033531996955620074072768276974E9L, + -2.906321047071299585682722511260895227921E8L, + -1.653347985722154162439387878512427542691E7L, + -6.245520581562848778466500301865173123136E5L, + -1.402124304177498828590239373389110545142E4L, + -1.209368072473510674493129989468348633579E2L +/* 1.0E0 */ +}; + + +/* erf(z+1) = erf_const + P(z)/Q(z) + -.125 <= z <= 0 + Peak relative error 7.3e-36 */ +static const long double erf_const = 0.845062911510467529296875L; +#define NTN2 8 +static const long double TN2[NTN2 + 1] = +{ + -4.088889697077485301010486931817357000235E1L, + 7.157046430681808553842307502826960051036E3L, + -2.191561912574409865550015485451373731780E3L, + 2.180174916555316874988981177654057337219E3L, + 2.848578658049670668231333682379720943455E2L, + 1.630362490952512836762810462174798925274E2L, + 6.317712353961866974143739396865293596895E0L, + 2.450441034183492434655586496522857578066E1L, + 5.127662277706787664956025545897050896203E-1L +}; +#define NTD2 8 +static const long double TD2[NTD2 + 1] = +{ + 1.731026445926834008273768924015161048885E4L, + 1.209682239007990370796112604286048173750E4L, + 1.160950290217993641320602282462976163857E4L, + 5.394294645127126577825507169061355698157E3L, + 2.791239340533632669442158497532521776093E3L, + 8.989365571337319032943005387378993827684E2L, + 2.974016493766349409725385710897298069677E2L, + 6.148192754590376378740261072533527271947E1L, + 1.178502892490738445655468927408440847480E1L + /* 1.0E0 */ +}; + + +/* erfc(x + 0.25) = erfc(0.25) + x R(x) + 0 <= x < 0.125 + Peak relative error 1.4e-35 */ +#define NRNr13 8 +static const long double RNr13[NRNr13 + 1] = +{ + -2.353707097641280550282633036456457014829E3L, + 3.871159656228743599994116143079870279866E2L, + -3.888105134258266192210485617504098426679E2L, + -2.129998539120061668038806696199343094971E1L, + -8.125462263594034672468446317145384108734E1L, + 8.151549093983505810118308635926270319660E0L, + -5.033362032729207310462422357772568553670E0L, + -4.253956621135136090295893547735851168471E-2L, + -8.098602878463854789780108161581050357814E-2L +}; +#define NRDr13 7 +static const long double RDr13[NRDr13 + 1] = +{ + 2.220448796306693503549505450626652881752E3L, + 1.899133258779578688791041599040951431383E2L, + 1.061906712284961110196427571557149268454E3L, + 7.497086072306967965180978101974566760042E1L, + 2.146796115662672795876463568170441327274E2L, + 1.120156008362573736664338015952284925592E1L, + 2.211014952075052616409845051695042741074E1L, + 6.469655675326150785692908453094054988938E-1L + /* 1.0E0 */ +}; +/* erfc(0.25) = C13a + C13b to extra precision. */ +static const long double C13a = 0.723663330078125L; +static const long double C13b = 1.0279753638067014931732235184287934646022E-5L; + + +/* erfc(x + 0.375) = erfc(0.375) + x R(x) + 0 <= x < 0.125 + Peak relative error 1.2e-35 */ +#define NRNr14 8 +static const long double RNr14[NRNr14 + 1] = +{ + -2.446164016404426277577283038988918202456E3L, + 6.718753324496563913392217011618096698140E2L, + -4.581631138049836157425391886957389240794E2L, + -2.382844088987092233033215402335026078208E1L, + -7.119237852400600507927038680970936336458E1L, + 1.313609646108420136332418282286454287146E1L, + -6.188608702082264389155862490056401365834E0L, + -2.787116601106678287277373011101132659279E-2L, + -2.230395570574153963203348263549700967918E-2L +}; +#define NRDr14 7 +static const long double RDr14[NRDr14 + 1] = +{ + 2.495187439241869732696223349840963702875E3L, + 2.503549449872925580011284635695738412162E2L, + 1.159033560988895481698051531263861842461E3L, + 9.493751466542304491261487998684383688622E1L, + 2.276214929562354328261422263078480321204E2L, + 1.367697521219069280358984081407807931847E1L, + 2.276988395995528495055594829206582732682E1L, + 7.647745753648996559837591812375456641163E-1L + /* 1.0E0 */ +}; +/* erfc(0.375) = C14a + C14b to extra precision. */ +static const long double C14a = 0.5958709716796875L; +static const long double C14b = 1.2118885490201676174914080878232469565953E-5L; + +/* erfc(x + 0.5) = erfc(0.5) + x R(x) + 0 <= x < 0.125 + Peak relative error 4.7e-36 */ +#define NRNr15 8 +static const long double RNr15[NRNr15 + 1] = +{ + -2.624212418011181487924855581955853461925E3L, + 8.473828904647825181073831556439301342756E2L, + -5.286207458628380765099405359607331669027E2L, + -3.895781234155315729088407259045269652318E1L, + -6.200857908065163618041240848728398496256E1L, + 1.469324610346924001393137895116129204737E1L, + -6.961356525370658572800674953305625578903E0L, + 5.145724386641163809595512876629030548495E-3L, + 1.990253655948179713415957791776180406812E-2L +}; +#define NRDr15 7 +static const long double RDr15[NRDr15 + 1] = +{ + 2.986190760847974943034021764693341524962E3L, + 5.288262758961073066335410218650047725985E2L, + 1.363649178071006978355113026427856008978E3L, + 1.921707975649915894241864988942255320833E2L, + 2.588651100651029023069013885900085533226E2L, + 2.628752920321455606558942309396855629459E1L, + 2.455649035885114308978333741080991380610E1L, + 1.378826653595128464383127836412100939126E0L + /* 1.0E0 */ +}; +/* erfc(0.5) = C15a + C15b to extra precision. */ +static const long double C15a = 0.4794921875L; +static const long double C15b = 7.9346869534623172533461080354712635484242E-6L; + +/* erfc(x + 0.625) = erfc(0.625) + x R(x) + 0 <= x < 0.125 + Peak relative error 5.1e-36 */ +#define NRNr16 8 +static const long double RNr16[NRNr16 + 1] = +{ + -2.347887943200680563784690094002722906820E3L, + 8.008590660692105004780722726421020136482E2L, + -5.257363310384119728760181252132311447963E2L, + -4.471737717857801230450290232600243795637E1L, + -4.849540386452573306708795324759300320304E1L, + 1.140885264677134679275986782978655952843E1L, + -6.731591085460269447926746876983786152300E0L, + 1.370831653033047440345050025876085121231E-1L, + 2.022958279982138755020825717073966576670E-2L, +}; +#define NRDr16 7 +static const long double RDr16[NRDr16 + 1] = +{ + 3.075166170024837215399323264868308087281E3L, + 8.730468942160798031608053127270430036627E2L, + 1.458472799166340479742581949088453244767E3L, + 3.230423687568019709453130785873540386217E2L, + 2.804009872719893612081109617983169474655E2L, + 4.465334221323222943418085830026979293091E1L, + 2.612723259683205928103787842214809134746E1L, + 2.341526751185244109722204018543276124997E0L, + /* 1.0E0 */ +}; +/* erfc(0.625) = C16a + C16b to extra precision. */ +static const long double C16a = 0.3767547607421875L; +static const long double C16b = 4.3570693945275513594941232097252997287766E-6L; + +/* erfc(x + 0.75) = erfc(0.75) + x R(x) + 0 <= x < 0.125 + Peak relative error 1.7e-35 */ +#define NRNr17 8 +static const long double RNr17[NRNr17 + 1] = +{ + -1.767068734220277728233364375724380366826E3L, + 6.693746645665242832426891888805363898707E2L, + -4.746224241837275958126060307406616817753E2L, + -2.274160637728782675145666064841883803196E1L, + -3.541232266140939050094370552538987982637E1L, + 6.988950514747052676394491563585179503865E0L, + -5.807687216836540830881352383529281215100E0L, + 3.631915988567346438830283503729569443642E-1L, + -1.488945487149634820537348176770282391202E-2L +}; +#define NRDr17 7 +static const long double RDr17[NRDr17 + 1] = +{ + 2.748457523498150741964464942246913394647E3L, + 1.020213390713477686776037331757871252652E3L, + 1.388857635935432621972601695296561952738E3L, + 3.903363681143817750895999579637315491087E2L, + 2.784568344378139499217928969529219886578E2L, + 5.555800830216764702779238020065345401144E1L, + 2.646215470959050279430447295801291168941E1L, + 2.984905282103517497081766758550112011265E0L, + /* 1.0E0 */ +}; +/* erfc(0.75) = C17a + C17b to extra precision. */ +static const long double C17a = 0.2888336181640625L; +static const long double C17b = 1.0748182422368401062165408589222625794046E-5L; + + +/* erfc(x + 0.875) = erfc(0.875) + x R(x) + 0 <= x < 0.125 + Peak relative error 2.2e-35 */ +#define NRNr18 8 +static const long double RNr18[NRNr18 + 1] = +{ + -1.342044899087593397419622771847219619588E3L, + 6.127221294229172997509252330961641850598E2L, + -4.519821356522291185621206350470820610727E2L, + 1.223275177825128732497510264197915160235E1L, + -2.730789571382971355625020710543532867692E1L, + 4.045181204921538886880171727755445395862E0L, + -4.925146477876592723401384464691452700539E0L, + 5.933878036611279244654299924101068088582E-1L, + -5.557645435858916025452563379795159124753E-2L +}; +#define NRDr18 7 +static const long double RDr18[NRDr18 + 1] = +{ + 2.557518000661700588758505116291983092951E3L, + 1.070171433382888994954602511991940418588E3L, + 1.344842834423493081054489613250688918709E3L, + 4.161144478449381901208660598266288188426E2L, + 2.763670252219855198052378138756906980422E2L, + 5.998153487868943708236273854747564557632E1L, + 2.657695108438628847733050476209037025318E1L, + 3.252140524394421868923289114410336976512E0L, + /* 1.0E0 */ +}; +/* erfc(0.875) = C18a + C18b to extra precision. */ +static const long double C18a = 0.215911865234375L; +static const long double C18b = 1.3073705765341685464282101150637224028267E-5L; + +/* erfc(x + 1.0) = erfc(1.0) + x R(x) + 0 <= x < 0.125 + Peak relative error 1.6e-35 */ +#define NRNr19 8 +static const long double RNr19[NRNr19 + 1] = +{ + -1.139180936454157193495882956565663294826E3L, + 6.134903129086899737514712477207945973616E2L, + -4.628909024715329562325555164720732868263E2L, + 4.165702387210732352564932347500364010833E1L, + -2.286979913515229747204101330405771801610E1L, + 1.870695256449872743066783202326943667722E0L, + -4.177486601273105752879868187237000032364E0L, + 7.533980372789646140112424811291782526263E-1L, + -8.629945436917752003058064731308767664446E-2L +}; +#define NRDr19 7 +static const long double RDr19[NRDr19 + 1] = +{ + 2.744303447981132701432716278363418643778E3L, + 1.266396359526187065222528050591302171471E3L, + 1.466739461422073351497972255511919814273E3L, + 4.868710570759693955597496520298058147162E2L, + 2.993694301559756046478189634131722579643E2L, + 6.868976819510254139741559102693828237440E1L, + 2.801505816247677193480190483913753613630E1L, + 3.604439909194350263552750347742663954481E0L, + /* 1.0E0 */ +}; +/* erfc(1.0) = C19a + C19b to extra precision. */ +static const long double C19a = 0.15728759765625L; +static const long double C19b = 1.1609394035130658779364917390740703933002E-5L; + +/* erfc(x + 1.125) = erfc(1.125) + x R(x) + 0 <= x < 0.125 + Peak relative error 3.6e-36 */ +#define NRNr20 8 +static const long double RNr20[NRNr20 + 1] = +{ + -9.652706916457973956366721379612508047640E2L, + 5.577066396050932776683469951773643880634E2L, + -4.406335508848496713572223098693575485978E2L, + 5.202893466490242733570232680736966655434E1L, + -1.931311847665757913322495948705563937159E1L, + -9.364318268748287664267341457164918090611E-2L, + -3.306390351286352764891355375882586201069E0L, + 7.573806045289044647727613003096916516475E-1L, + -9.611744011489092894027478899545635991213E-2L +}; +#define NRDr20 7 +static const long double RDr20[NRDr20 + 1] = +{ + 3.032829629520142564106649167182428189014E3L, + 1.659648470721967719961167083684972196891E3L, + 1.703545128657284619402511356932569292535E3L, + 6.393465677731598872500200253155257708763E2L, + 3.489131397281030947405287112726059221934E2L, + 8.848641738570783406484348434387611713070E1L, + 3.132269062552392974833215844236160958502E1L, + 4.430131663290563523933419966185230513168E0L + /* 1.0E0 */ +}; +/* erfc(1.125) = C20a + C20b to extra precision. */ +static const long double C20a = 0.111602783203125L; +static const long double C20b = 8.9850951672359304215530728365232161564636E-6L; + +/* erfc(1/x) = 1/x exp (-1/x^2 - 0.5625 + R(1/x^2)) + 7/8 <= 1/x < 1 + Peak relative error 1.4e-35 */ +#define NRNr8 9 +static const long double RNr8[NRNr8 + 1] = +{ + 3.587451489255356250759834295199296936784E1L, + 5.406249749087340431871378009874875889602E2L, + 2.931301290625250886238822286506381194157E3L, + 7.359254185241795584113047248898753470923E3L, + 9.201031849810636104112101947312492532314E3L, + 5.749697096193191467751650366613289284777E3L, + 1.710415234419860825710780802678697889231E3L, + 2.150753982543378580859546706243022719599E2L, + 8.740953582272147335100537849981160931197E0L, + 4.876422978828717219629814794707963640913E-2L +}; +#define NRDr8 8 +static const long double RDr8[NRDr8 + 1] = +{ + 6.358593134096908350929496535931630140282E1L, + 9.900253816552450073757174323424051765523E2L, + 5.642928777856801020545245437089490805186E3L, + 1.524195375199570868195152698617273739609E4L, + 2.113829644500006749947332935305800887345E4L, + 1.526438562626465706267943737310282977138E4L, + 5.561370922149241457131421914140039411782E3L, + 9.394035530179705051609070428036834496942E2L, + 6.147019596150394577984175188032707343615E1L + /* 1.0E0 */ +}; + +/* erfc(1/x) = 1/x exp (-1/x^2 - 0.5625 + R(1/x^2)) + 0.75 <= 1/x <= 0.875 + Peak relative error 2.0e-36 */ +#define NRNr7 9 +static const long double RNr7[NRNr7 + 1] = +{ + 1.686222193385987690785945787708644476545E1L, + 1.178224543567604215602418571310612066594E3L, + 1.764550584290149466653899886088166091093E4L, + 1.073758321890334822002849369898232811561E5L, + 3.132840749205943137619839114451290324371E5L, + 4.607864939974100224615527007793867585915E5L, + 3.389781820105852303125270837910972384510E5L, + 1.174042187110565202875011358512564753399E5L, + 1.660013606011167144046604892622504338313E4L, + 6.700393957480661937695573729183733234400E2L +}; +#define NRDr7 9 +static const long double RDr7[NRDr7 + 1] = +{ +-1.709305024718358874701575813642933561169E3L, +-3.280033887481333199580464617020514788369E4L, +-2.345284228022521885093072363418750835214E5L, +-8.086758123097763971926711729242327554917E5L, +-1.456900414510108718402423999575992450138E6L, +-1.391654264881255068392389037292702041855E6L, +-6.842360801869939983674527468509852583855E5L, +-1.597430214446573566179675395199807533371E5L, +-1.488876130609876681421645314851760773480E4L, +-3.511762950935060301403599443436465645703E2L + /* 1.0E0 */ +}; + +/* erfc(1/x) = 1/x exp(-1/x^2 - 0.5625 + R(1/x^2)) + 5/8 <= 1/x < 3/4 + Peak relative error 1.9e-35 */ +#define NRNr6 9 +static const long double RNr6[NRNr6 + 1] = +{ + 1.642076876176834390623842732352935761108E0L, + 1.207150003611117689000664385596211076662E2L, + 2.119260779316389904742873816462800103939E3L, + 1.562942227734663441801452930916044224174E4L, + 5.656779189549710079988084081145693580479E4L, + 1.052166241021481691922831746350942786299E5L, + 9.949798524786000595621602790068349165758E4L, + 4.491790734080265043407035220188849562856E4L, + 8.377074098301530326270432059434791287601E3L, + 4.506934806567986810091824791963991057083E2L +}; +#define NRDr6 9 +static const long double RDr6[NRDr6 + 1] = +{ +-1.664557643928263091879301304019826629067E2L, +-3.800035902507656624590531122291160668452E3L, +-3.277028191591734928360050685359277076056E4L, +-1.381359471502885446400589109566587443987E5L, +-3.082204287382581873532528989283748656546E5L, +-3.691071488256738343008271448234631037095E5L, +-2.300482443038349815750714219117566715043E5L, +-6.873955300927636236692803579555752171530E4L, +-8.262158817978334142081581542749986845399E3L, +-2.517122254384430859629423488157361983661E2L + /* 1.00 */ +}; + +/* erfc(1/x) = 1/x exp(-1/x^2 - 0.5625 + R(1/x^2)) + 1/2 <= 1/x < 5/8 + Peak relative error 4.6e-36 */ +#define NRNr5 10 +static const long double RNr5[NRNr5 + 1] = +{ +-3.332258927455285458355550878136506961608E-3L, +-2.697100758900280402659586595884478660721E-1L, +-6.083328551139621521416618424949137195536E0L, +-6.119863528983308012970821226810162441263E1L, +-3.176535282475593173248810678636522589861E2L, +-8.933395175080560925809992467187963260693E2L, +-1.360019508488475978060917477620199499560E3L, +-1.075075579828188621541398761300910213280E3L, +-4.017346561586014822824459436695197089916E2L, +-5.857581368145266249509589726077645791341E1L, +-2.077715925587834606379119585995758954399E0L +}; +#define NRDr5 9 +static const long double RDr5[NRDr5 + 1] = +{ + 3.377879570417399341550710467744693125385E-1L, + 1.021963322742390735430008860602594456187E1L, + 1.200847646592942095192766255154827011939E2L, + 7.118915528142927104078182863387116942836E2L, + 2.318159380062066469386544552429625026238E3L, + 4.238729853534009221025582008928765281620E3L, + 4.279114907284825886266493994833515580782E3L, + 2.257277186663261531053293222591851737504E3L, + 5.570475501285054293371908382916063822957E2L, + 5.142189243856288981145786492585432443560E1L + /* 1.0E0 */ +}; + +/* erfc(1/x) = 1/x exp(-1/x^2 - 0.5625 + R(1/x^2)) + 3/8 <= 1/x < 1/2 + Peak relative error 2.0e-36 */ +#define NRNr4 10 +static const long double RNr4[NRNr4 + 1] = +{ + 3.258530712024527835089319075288494524465E-3L, + 2.987056016877277929720231688689431056567E-1L, + 8.738729089340199750734409156830371528862E0L, + 1.207211160148647782396337792426311125923E2L, + 8.997558632489032902250523945248208224445E2L, + 3.798025197699757225978410230530640879762E3L, + 9.113203668683080975637043118209210146846E3L, + 1.203285891339933238608683715194034900149E4L, + 8.100647057919140328536743641735339740855E3L, + 2.383888249907144945837976899822927411769E3L, + 2.127493573166454249221983582495245662319E2L +}; +#define NRDr4 10 +static const long double RDr4[NRDr4 + 1] = +{ +-3.303141981514540274165450687270180479586E-1L, +-1.353768629363605300707949368917687066724E1L, +-2.206127630303621521950193783894598987033E2L, +-1.861800338758066696514480386180875607204E3L, +-8.889048775872605708249140016201753255599E3L, +-2.465888106627948210478692168261494857089E4L, +-3.934642211710774494879042116768390014289E4L, +-3.455077258242252974937480623730228841003E4L, +-1.524083977439690284820586063729912653196E4L, +-2.810541887397984804237552337349093953857E3L, +-1.343929553541159933824901621702567066156E2L + /* 1.0E0 */ +}; + +/* erfc(1/x) = 1/x exp(-1/x^2 - 0.5625 + R(1/x^2)) + 1/4 <= 1/x < 3/8 + Peak relative error 8.4e-37 */ +#define NRNr3 11 +static const long double RNr3[NRNr3 + 1] = +{ +-1.952401126551202208698629992497306292987E-6L, +-2.130881743066372952515162564941682716125E-4L, +-8.376493958090190943737529486107282224387E-3L, +-1.650592646560987700661598877522831234791E-1L, +-1.839290818933317338111364667708678163199E0L, +-1.216278715570882422410442318517814388470E1L, +-4.818759344462360427612133632533779091386E1L, +-1.120994661297476876804405329172164436784E2L, +-1.452850765662319264191141091859300126931E2L, +-9.485207851128957108648038238656777241333E1L, +-2.563663855025796641216191848818620020073E1L, +-1.787995944187565676837847610706317833247E0L +}; +#define NRDr3 10 +static const long double RDr3[NRDr3 + 1] = +{ + 1.979130686770349481460559711878399476903E-4L, + 1.156941716128488266238105813374635099057E-2L, + 2.752657634309886336431266395637285974292E-1L, + 3.482245457248318787349778336603569327521E0L, + 2.569347069372696358578399521203959253162E1L, + 1.142279000180457419740314694631879921561E2L, + 3.056503977190564294341422623108332700840E2L, + 4.780844020923794821656358157128719184422E2L, + 4.105972727212554277496256802312730410518E2L, + 1.724072188063746970865027817017067646246E2L, + 2.815939183464818198705278118326590370435E1L + /* 1.0E0 */ +}; + +/* erfc(1/x) = 1/x exp(-1/x^2 - 0.5625 + R(1/x^2)) + 1/8 <= 1/x < 1/4 + Peak relative error 1.5e-36 */ +#define NRNr2 11 +static const long double RNr2[NRNr2 + 1] = +{ +-2.638914383420287212401687401284326363787E-8L, +-3.479198370260633977258201271399116766619E-6L, +-1.783985295335697686382487087502222519983E-4L, +-4.777876933122576014266349277217559356276E-3L, +-7.450634738987325004070761301045014986520E-2L, +-7.068318854874733315971973707247467326619E-1L, +-4.113919921935944795764071670806867038732E0L, +-1.440447573226906222417767283691888875082E1L, +-2.883484031530718428417168042141288943905E1L, +-2.990886974328476387277797361464279931446E1L, +-1.325283914915104866248279787536128997331E1L, +-1.572436106228070195510230310658206154374E0L +}; +#define NRDr2 10 +static const long double RDr2[NRDr2 + 1] = +{ + 2.675042728136731923554119302571867799673E-6L, + 2.170997868451812708585443282998329996268E-4L, + 7.249969752687540289422684951196241427445E-3L, + 1.302040375859768674620410563307838448508E-1L, + 1.380202483082910888897654537144485285549E0L, + 8.926594113174165352623847870299170069350E0L, + 3.521089584782616472372909095331572607185E1L, + 8.233547427533181375185259050330809105570E1L, + 1.072971579885803033079469639073292840135E2L, + 6.943803113337964469736022094105143158033E1L, + 1.775695341031607738233608307835017282662E1L + /* 1.0E0 */ +}; + +/* erfc(1/x) = 1/x exp(-1/x^2 - 0.5625 + R(1/x^2)) + 1/128 <= 1/x < 1/8 + Peak relative error 2.2e-36 */ +#define NRNr1 9 +static const long double RNr1[NRNr1 + 1] = +{ +-4.250780883202361946697751475473042685782E-8L, +-5.375777053288612282487696975623206383019E-6L, +-2.573645949220896816208565944117382460452E-4L, +-6.199032928113542080263152610799113086319E-3L, +-8.262721198693404060380104048479916247786E-2L, +-6.242615227257324746371284637695778043982E-1L, +-2.609874739199595400225113299437099626386E0L, +-5.581967563336676737146358534602770006970E0L, +-5.124398923356022609707490956634280573882E0L, +-1.290865243944292370661544030414667556649E0L +}; +#define NRDr1 8 +static const long double RDr1[NRDr1 + 1] = +{ + 4.308976661749509034845251315983612976224E-6L, + 3.265390126432780184125233455960049294580E-4L, + 9.811328839187040701901866531796570418691E-3L, + 1.511222515036021033410078631914783519649E-1L, + 1.289264341917429958858379585970225092274E0L, + 6.147640356182230769548007536914983522270E0L, + 1.573966871337739784518246317003956180750E1L, + 1.955534123435095067199574045529218238263E1L, + 9.472613121363135472247929109615785855865E0L + /* 1.0E0 */ +}; + + +long double +erfl(long double x) +{ + long double a, y, z; + int32_t i, ix, sign; + ieee_quad_shape_type u; + + u.value = x; + sign = u.parts32.mswhi; + ix = sign & 0x7fffffff; + + if (ix >= 0x7fff0000) + { /* erf(nan)=nan */ + i = ((sign & 0xffff0000) >> 31) << 1; + return (long double) (1 - i) + one / x; /* erf(+-inf)=+-1 */ + } + + if (ix >= 0x3fff0000) /* |x| >= 1.0 */ + { + y = erfcl (x); + return (one - y); + /* return (one - erfcl (x)); */ + } + u.parts32.mswhi = ix; + a = u.value; + z = x * x; + if (ix < 0x3ffec000) /* a < 0.875 */ + { + if (ix < 0x3fc60000) /* |x|<2**-57 */ + { + if (ix < 0x00080000) + return 0.125 * (8.0 * x + efx8 * x); /*avoid underflow */ + return x + efx * x; + } + y = a + a * neval (z, TN1, NTN1) / deval (z, TD1, NTD1); + } + else + { + a = a - one; + y = erf_const + neval (a, TN2, NTN2) / deval (a, TD2, NTD2); + } + + if (sign & 0x80000000) /* x < 0 */ + y = -y; + return( y ); +} + +long double +erfcl(long double x) +{ + long double y, z, p, r; + int32_t i, ix, sign; + ieee_quad_shape_type u; + + u.value = x; + sign = u.parts32.mswhi; + ix = sign & 0x7fffffff; + u.parts32.mswhi = ix; + + if (ix >= 0x7fff0000) + { /* erfc(nan)=nan */ + /* erfc(+-inf)=0,2 */ + return (long double) (((u_int32_t) sign >> 31) << 1) + one / x; + } + + if (ix < 0x3ffd0000) /* |x| <1/4 */ + { + if (ix < 0x3f8d0000) /* |x|<2**-114 */ + return one - x; + return one - erfl (x); + } + if (ix < 0x3fff4000) /* 1.25 */ + { + x = u.value; + i = 8.0 * x; + switch (i) + { + case 2: + z = x - 0.25L; + y = C13b + z * neval (z, RNr13, NRNr13) / deval (z, RDr13, NRDr13); + y += C13a; + break; + case 3: + z = x - 0.375L; + y = C14b + z * neval (z, RNr14, NRNr14) / deval (z, RDr14, NRDr14); + y += C14a; + break; + case 4: + z = x - 0.5L; + y = C15b + z * neval (z, RNr15, NRNr15) / deval (z, RDr15, NRDr15); + y += C15a; + break; + case 5: + z = x - 0.625L; + y = C16b + z * neval (z, RNr16, NRNr16) / deval (z, RDr16, NRDr16); + y += C16a; + break; + case 6: + z = x - 0.75L; + y = C17b + z * neval (z, RNr17, NRNr17) / deval (z, RDr17, NRDr17); + y += C17a; + break; + case 7: + z = x - 0.875L; + y = C18b + z * neval (z, RNr18, NRNr18) / deval (z, RDr18, NRDr18); + y += C18a; + break; + case 8: + z = x - 1.0L; + y = C19b + z * neval (z, RNr19, NRNr19) / deval (z, RDr19, NRDr19); + y += C19a; + break; + case 9: + z = x - 1.125L; + y = C20b + z * neval (z, RNr20, NRNr20) / deval (z, RDr20, NRDr20); + y += C20a; + break; + } + if (sign & 0x80000000) + y = 2.0L - y; + return y; + } + /* 1.25 < |x| < 107 */ + if (ix < 0x4005ac00) + { + /* x < -9 */ + if ((ix >= 0x40022000) && (sign & 0x80000000)) + return two - tiny; + + x = fabsl (x); + z = one / (x * x); + i = 8.0 / x; + switch (i) + { + default: + case 0: + p = neval (z, RNr1, NRNr1) / deval (z, RDr1, NRDr1); + break; + case 1: + p = neval (z, RNr2, NRNr2) / deval (z, RDr2, NRDr2); + break; + case 2: + p = neval (z, RNr3, NRNr3) / deval (z, RDr3, NRDr3); + break; + case 3: + p = neval (z, RNr4, NRNr4) / deval (z, RDr4, NRDr4); + break; + case 4: + p = neval (z, RNr5, NRNr5) / deval (z, RDr5, NRDr5); + break; + case 5: + p = neval (z, RNr6, NRNr6) / deval (z, RDr6, NRDr6); + break; + case 6: + p = neval (z, RNr7, NRNr7) / deval (z, RDr7, NRDr7); + break; + case 7: + p = neval (z, RNr8, NRNr8) / deval (z, RDr8, NRDr8); + break; + } + u.value = x; + u.parts32.lswlo = 0; + u.parts32.lswhi &= 0xfe000000; + z = u.value; + r = expl (-z * z - 0.5625) * + expl ((z - x) * (z + x) + p); + if ((sign & 0x80000000) == 0) + return r / x; + else + return two - r / x; + } + else + { + if ((sign & 0x80000000) == 0) + return tiny * tiny; + else + return two - tiny; + } +} diff --git a/src/openlibm/ld128/s_exp2l.c b/src/openlibm/ld128/s_exp2l.c new file mode 100644 index 0000000..c5f997f --- /dev/null +++ b/src/openlibm/ld128/s_exp2l.c @@ -0,0 +1,431 @@ +/*- + * Copyright (c) 2005-2008 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/ld128/s_exp2l.c,v 1.3 2008/02/13 10:44:44 bde Exp $"); + +#include +#include +#include + +#include "fpmath.h" +#include "math_private.h" + +#define TBLBITS 7 +#define TBLSIZE (1 << TBLBITS) + +#define BIAS (LDBL_MAX_EXP - 1) +#define EXPMASK (BIAS + LDBL_MAX_EXP) + +#if 0 /* XXX Prevent gcc from erroneously constant folding this. */ +static const long double twom10000 = 0x1p-10000L; +#else +static volatile long double twom10000 = 0x1p-10000L; +#endif + +static const long double + huge = 0x1p10000L, + P1 = 0x1.62e42fefa39ef35793c7673007e6p-1L, + P2 = 0x1.ebfbdff82c58ea86f16b06ec9736p-3L, + P3 = 0x1.c6b08d704a0bf8b33a762bad3459p-5L, + P4 = 0x1.3b2ab6fba4e7729ccbbe0b4f3fc2p-7L, + P5 = 0x1.5d87fe78a67311071dee13fd11d9p-10L, + P6 = 0x1.430912f86c7876f4b663b23c5fe5p-13L; + +static const double + P7 = 0x1.ffcbfc588b041p-17, + P8 = 0x1.62c0223a5c7c7p-20, + P9 = 0x1.b52541ff59713p-24, + P10 = 0x1.e4cf56a391e22p-28, + redux = 0x1.8p112 / TBLSIZE; + +static const long double tbl[TBLSIZE] = { + 0x1.6a09e667f3bcc908b2fb1366dfeap-1L, + 0x1.6c012750bdabeed76a99800f4edep-1L, + 0x1.6dfb23c651a2ef220e2cbe1bc0d4p-1L, + 0x1.6ff7df9519483cf87e1b4f3e1e98p-1L, + 0x1.71f75e8ec5f73dd2370f2ef0b148p-1L, + 0x1.73f9a48a58173bd5c9a4e68ab074p-1L, + 0x1.75feb564267c8bf6e9aa33a489a8p-1L, + 0x1.780694fde5d3f619ae02808592a4p-1L, + 0x1.7a11473eb0186d7d51023f6ccb1ap-1L, + 0x1.7c1ed0130c1327c49334459378dep-1L, + 0x1.7e2f336cf4e62105d02ba1579756p-1L, + 0x1.80427543e1a11b60de67649a3842p-1L, + 0x1.82589994cce128acf88afab34928p-1L, + 0x1.8471a4623c7acce52f6b97c6444cp-1L, + 0x1.868d99b4492ec80e41d90ac2556ap-1L, + 0x1.88ac7d98a669966530bcdf2d4cc0p-1L, + 0x1.8ace5422aa0db5ba7c55a192c648p-1L, + 0x1.8cf3216b5448bef2aa1cd161c57ap-1L, + 0x1.8f1ae991577362b982745c72eddap-1L, + 0x1.9145b0b91ffc588a61b469f6b6a0p-1L, + 0x1.93737b0cdc5e4f4501c3f2540ae8p-1L, + 0x1.95a44cbc8520ee9b483695a0e7fep-1L, + 0x1.97d829fde4e4f8b9e920f91e8eb6p-1L, + 0x1.9a0f170ca07b9ba3109b8c467844p-1L, + 0x1.9c49182a3f0901c7c46b071f28dep-1L, + 0x1.9e86319e323231824ca78e64c462p-1L, + 0x1.a0c667b5de564b29ada8b8cabbacp-1L, + 0x1.a309bec4a2d3358c171f770db1f4p-1L, + 0x1.a5503b23e255c8b424491caf88ccp-1L, + 0x1.a799e1330b3586f2dfb2b158f31ep-1L, + 0x1.a9e6b5579fdbf43eb243bdff53a2p-1L, + 0x1.ac36bbfd3f379c0db966a3126988p-1L, + 0x1.ae89f995ad3ad5e8734d17731c80p-1L, + 0x1.b0e07298db66590842acdfc6fb4ep-1L, + 0x1.b33a2b84f15faf6bfd0e7bd941b0p-1L, + 0x1.b59728de559398e3881111648738p-1L, + 0x1.b7f76f2fb5e46eaa7b081ab53ff6p-1L, + 0x1.ba5b030a10649840cb3c6af5b74cp-1L, + 0x1.bcc1e904bc1d2247ba0f45b3d06cp-1L, + 0x1.bf2c25bd71e088408d7025190cd0p-1L, + 0x1.c199bdd85529c2220cb12a0916bap-1L, + 0x1.c40ab5fffd07a6d14df820f17deap-1L, + 0x1.c67f12e57d14b4a2137fd20f2a26p-1L, + 0x1.c8f6d9406e7b511acbc48805c3f6p-1L, + 0x1.cb720dcef90691503cbd1e949d0ap-1L, + 0x1.cdf0b555dc3f9c44f8958fac4f12p-1L, + 0x1.d072d4a07897b8d0f22f21a13792p-1L, + 0x1.d2f87080d89f18ade123989ea50ep-1L, + 0x1.d5818dcfba48725da05aeb66dff8p-1L, + 0x1.d80e316c98397bb84f9d048807a0p-1L, + 0x1.da9e603db3285708c01a5b6d480cp-1L, + 0x1.dd321f301b4604b695de3c0630c0p-1L, + 0x1.dfc97337b9b5eb968cac39ed284cp-1L, + 0x1.e264614f5a128a12761fa17adc74p-1L, + 0x1.e502ee78b3ff6273d130153992d0p-1L, + 0x1.e7a51fbc74c834b548b2832378a4p-1L, + 0x1.ea4afa2a490d9858f73a18f5dab4p-1L, + 0x1.ecf482d8e67f08db0312fb949d50p-1L, + 0x1.efa1bee615a27771fd21a92dabb6p-1L, + 0x1.f252b376bba974e8696fc3638f24p-1L, + 0x1.f50765b6e4540674f84b762861a6p-1L, + 0x1.f7bfdad9cbe138913b4bfe72bd78p-1L, + 0x1.fa7c1819e90d82e90a7e74b26360p-1L, + 0x1.fd3c22b8f71f10975ba4b32bd006p-1L, + 0x1.0000000000000000000000000000p+0L, + 0x1.0163da9fb33356d84a66ae336e98p+0L, + 0x1.02c9a3e778060ee6f7caca4f7a18p+0L, + 0x1.04315e86e7f84bd738f9a20da442p+0L, + 0x1.059b0d31585743ae7c548eb68c6ap+0L, + 0x1.0706b29ddf6ddc6dc403a9d87b1ep+0L, + 0x1.0874518759bc808c35f25d942856p+0L, + 0x1.09e3ecac6f3834521e060c584d5cp+0L, + 0x1.0b5586cf9890f6298b92b7184200p+0L, + 0x1.0cc922b7247f7407b705b893dbdep+0L, + 0x1.0e3ec32d3d1a2020742e4f8af794p+0L, + 0x1.0fb66affed31af232091dd8a169ep+0L, + 0x1.11301d0125b50a4ebbf1aed9321cp+0L, + 0x1.12abdc06c31cbfb92bad324d6f84p+0L, + 0x1.1429aaea92ddfb34101943b2588ep+0L, + 0x1.15a98c8a58e512480d573dd562aep+0L, + 0x1.172b83c7d517adcdf7c8c50eb162p+0L, + 0x1.18af9388c8de9bbbf70b9a3c269cp+0L, + 0x1.1a35beb6fcb753cb698f692d2038p+0L, + 0x1.1bbe084045cd39ab1e72b442810ep+0L, + 0x1.1d4873168b9aa7805b8028990be8p+0L, + 0x1.1ed5022fcd91cb8819ff61121fbep+0L, + 0x1.2063b88628cd63b8eeb0295093f6p+0L, + 0x1.21f49917ddc962552fd29294bc20p+0L, + 0x1.2387a6e75623866c1fadb1c159c0p+0L, + 0x1.251ce4fb2a63f3582ab7de9e9562p+0L, + 0x1.26b4565e27cdd257a673281d3068p+0L, + 0x1.284dfe1f5638096cf15cf03c9fa0p+0L, + 0x1.29e9df51fdee12c25d15f5a25022p+0L, + 0x1.2b87fd0dad98ffddea46538fca24p+0L, + 0x1.2d285a6e4030b40091d536d0733ep+0L, + 0x1.2ecafa93e2f5611ca0f45d5239a4p+0L, + 0x1.306fe0a31b7152de8d5a463063bep+0L, + 0x1.32170fc4cd8313539cf1c3009330p+0L, + 0x1.33c08b26416ff4c9c8610d96680ep+0L, + 0x1.356c55f929ff0c94623476373be4p+0L, + 0x1.371a7373aa9caa7145502f45452ap+0L, + 0x1.38cae6d05d86585a9cb0d9bed530p+0L, + 0x1.3a7db34e59ff6ea1bc9299e0a1fep+0L, + 0x1.3c32dc313a8e484001f228b58cf0p+0L, + 0x1.3dea64c12342235b41223e13d7eep+0L, + 0x1.3fa4504ac801ba0bf701aa417b9cp+0L, + 0x1.4160a21f72e29f84325b8f3dbacap+0L, + 0x1.431f5d950a896dc704439410b628p+0L, + 0x1.44e086061892d03136f409df0724p+0L, + 0x1.46a41ed1d005772512f459229f0ap+0L, + 0x1.486a2b5c13cd013c1a3b69062f26p+0L, + 0x1.4a32af0d7d3de672d8bcf46f99b4p+0L, + 0x1.4bfdad5362a271d4397afec42e36p+0L, + 0x1.4dcb299fddd0d63b36ef1a9e19dep+0L, + 0x1.4f9b2769d2ca6ad33d8b69aa0b8cp+0L, + 0x1.516daa2cf6641c112f52c84d6066p+0L, + 0x1.5342b569d4f81df0a83c49d86bf4p+0L, + 0x1.551a4ca5d920ec52ec620243540cp+0L, + 0x1.56f4736b527da66ecb004764e61ep+0L, + 0x1.58d12d497c7fd252bc2b7343d554p+0L, + 0x1.5ab07dd48542958c93015191e9a8p+0L, + 0x1.5c9268a5946b701c4b1b81697ed4p+0L, + 0x1.5e76f15ad21486e9be4c20399d12p+0L, + 0x1.605e1b976dc08b076f592a487066p+0L, + 0x1.6247eb03a5584b1f0fa06fd2d9eap+0L, + 0x1.6434634ccc31fc76f8714c4ee122p+0L, + 0x1.66238825522249127d9e29b92ea2p+0L, + 0x1.68155d44ca973081c57227b9f69ep+0L, +}; + +static const float eps[TBLSIZE] = { + -0x1.5c50p-101, + -0x1.5d00p-106, + 0x1.8e90p-102, + -0x1.5340p-103, + 0x1.1bd0p-102, + -0x1.4600p-105, + -0x1.7a40p-104, + 0x1.d590p-102, + -0x1.d590p-101, + 0x1.b100p-103, + -0x1.0d80p-105, + 0x1.6b00p-103, + -0x1.9f00p-105, + 0x1.c400p-103, + 0x1.e120p-103, + -0x1.c100p-104, + -0x1.9d20p-103, + 0x1.a800p-108, + 0x1.4c00p-106, + -0x1.9500p-106, + 0x1.6900p-105, + -0x1.29d0p-100, + 0x1.4c60p-103, + 0x1.13a0p-102, + -0x1.5b60p-103, + -0x1.1c40p-103, + 0x1.db80p-102, + 0x1.91a0p-102, + 0x1.dc00p-105, + 0x1.44c0p-104, + 0x1.9710p-102, + 0x1.8760p-103, + -0x1.a720p-103, + 0x1.ed20p-103, + -0x1.49c0p-102, + -0x1.e000p-111, + 0x1.86a0p-103, + 0x1.2b40p-103, + -0x1.b400p-108, + 0x1.1280p-99, + -0x1.02d8p-102, + -0x1.e3d0p-103, + -0x1.b080p-105, + -0x1.f100p-107, + -0x1.16c0p-105, + -0x1.1190p-103, + -0x1.a7d2p-100, + 0x1.3450p-103, + -0x1.67c0p-105, + 0x1.4b80p-104, + -0x1.c4e0p-103, + 0x1.6000p-108, + -0x1.3f60p-105, + 0x1.93f0p-104, + 0x1.5fe0p-105, + 0x1.6f80p-107, + -0x1.7600p-106, + 0x1.21e0p-106, + -0x1.3a40p-106, + -0x1.40c0p-104, + -0x1.9860p-105, + -0x1.5d40p-108, + -0x1.1d70p-106, + 0x1.2760p-105, + 0x0.0000p+0, + 0x1.21e2p-104, + -0x1.9520p-108, + -0x1.5720p-106, + -0x1.4810p-106, + -0x1.be00p-109, + 0x1.0080p-105, + -0x1.5780p-108, + -0x1.d460p-105, + -0x1.6140p-105, + 0x1.4630p-104, + 0x1.ad50p-103, + 0x1.82e0p-105, + 0x1.1d3cp-101, + 0x1.6100p-107, + 0x1.ec30p-104, + 0x1.f200p-108, + 0x1.0b40p-103, + 0x1.3660p-102, + 0x1.d9d0p-103, + -0x1.02d0p-102, + 0x1.b070p-103, + 0x1.b9c0p-104, + -0x1.01c0p-103, + -0x1.dfe0p-103, + 0x1.1b60p-104, + -0x1.ae94p-101, + -0x1.3340p-104, + 0x1.b3d8p-102, + -0x1.6e40p-105, + -0x1.3670p-103, + 0x1.c140p-104, + 0x1.1840p-101, + 0x1.1ab0p-102, + -0x1.a400p-104, + 0x1.1f00p-104, + -0x1.7180p-103, + 0x1.4ce0p-102, + 0x1.9200p-107, + -0x1.54c0p-103, + 0x1.1b80p-105, + -0x1.1828p-101, + 0x1.5720p-102, + -0x1.a060p-100, + 0x1.9160p-102, + 0x1.a280p-104, + 0x1.3400p-107, + 0x1.2b20p-102, + 0x1.7800p-108, + 0x1.cfd0p-101, + 0x1.2ef0p-102, + -0x1.2760p-99, + 0x1.b380p-104, + 0x1.0048p-101, + -0x1.60b0p-102, + 0x1.a1ccp-100, + -0x1.a640p-104, + -0x1.08a0p-101, + 0x1.7e60p-102, + 0x1.22c0p-103, + -0x1.7200p-106, + 0x1.f0f0p-102, + 0x1.eb4ep-99, + 0x1.c6e0p-103, +}; + +/* + * exp2l(x): compute the base 2 exponential of x + * + * Accuracy: Peak error < 0.502 ulp. + * + * Method: (accurate tables) + * + * Reduce x: + * x = 2**k + y, for integer k and |y| <= 1/2. + * Thus we have exp2(x) = 2**k * exp2(y). + * + * Reduce y: + * y = i/TBLSIZE + z - eps[i] for integer i near y * TBLSIZE. + * Thus we have exp2(y) = exp2(i/TBLSIZE) * exp2(z - eps[i]), + * with |z - eps[i]| <= 2**-8 + 2**-98 for the table used. + * + * We compute exp2(i/TBLSIZE) via table lookup and exp2(z - eps[i]) via + * a degree-10 minimax polynomial with maximum error under 2**-120. + * The values in exp2t[] and eps[] are chosen such that + * exp2t[i] = exp2(i/TBLSIZE + eps[i]), and eps[i] is a small offset such + * that exp2t[i] is accurate to 2**-122. + * + * Note that the range of i is +-TBLSIZE/2, so we actually index the tables + * by i0 = i + TBLSIZE/2. + * + * This method is due to Gal, with many details due to Gal and Bachelis: + * + * Gal, S. and Bachelis, B. An Accurate Elementary Mathematical Library + * for the IEEE Floating Point Standard. TOMS 17(1), 26-46 (1991). + */ +OLM_DLLEXPORT long double +exp2l(long double x) +{ + union IEEEl2bits u, v; + long double r, t, twopk, twopkp10000, z; + uint32_t hx, ix, i0; + int k; + + u.e = x; + + /* Filter out exceptional cases. */ + hx = u.xbits.expsign; + ix = hx & EXPMASK; + if (ix >= BIAS + 14) { /* |x| >= 16384 */ + if (ix == BIAS + LDBL_MAX_EXP) { + if (u.xbits.manh != 0 + || u.xbits.manl != 0 + || (hx & 0x8000) == 0) + return (x + x); /* x is NaN or +Inf */ + else + return (0.0); /* x is -Inf */ + } + if (x >= 16384) + return (huge * huge); /* overflow */ + if (x <= -16495) + return (twom10000 * twom10000); /* underflow */ + } else if (ix <= BIAS - 115) { /* |x| < 0x1p-115 */ + return (1.0 + x); + } + + /* + * Reduce x, computing z, i0, and k. The low bits of x + redux + * contain the 16-bit integer part of the exponent (k) followed by + * TBLBITS fractional bits (i0). We use bit tricks to extract these + * as integers, then set z to the remainder. + * + * Example: Suppose x is 0xabc.123456p0 and TBLBITS is 8. + * Then the low-order word of x + redux is 0x000abc12, + * We split this into k = 0xabc and i0 = 0x12 (adjusted to + * index into the table), then we compute z = 0x0.003456p0. + * + * XXX If the exponent is negative, the computation of k depends on + * '>>' doing sign extension. + */ + u.e = x + redux; + i0 = (u.bits.manl & 0xffffffff) + TBLSIZE / 2; + k = (int)i0 >> TBLBITS; + i0 = i0 & (TBLSIZE - 1); + u.e -= redux; + z = x - u.e; + v.xbits.manh = 0; + v.xbits.manl = 0; + if (k >= LDBL_MIN_EXP) { + v.xbits.expsign = LDBL_MAX_EXP - 1 + k; + twopk = v.e; + } else { + v.xbits.expsign = LDBL_MAX_EXP - 1 + k + 10000; + twopkp10000 = v.e; + } + + /* Compute r = exp2(y) = exp2t[i0] * p(z - eps[i]). */ + t = tbl[i0]; /* exp2t[i0] */ + z -= eps[i0]; /* eps[i0] */ + r = t + t * z * (P1 + z * (P2 + z * (P3 + z * (P4 + z * (P5 + z * (P6 + + z * (P7 + z * (P8 + z * (P9 + z * P10))))))))); + + /* Scale by 2**k. */ + if(k >= LDBL_MIN_EXP) { + if (k == LDBL_MAX_EXP) + return (r * 2.0 * 0x1p16383L); + return (r * twopk); + } else { + return (r * twopkp10000 * twom10000); + } +} diff --git a/src/openlibm/ld128/s_expm1l.c b/src/openlibm/ld128/s_expm1l.c new file mode 100644 index 0000000..1c22696 --- /dev/null +++ b/src/openlibm/ld128/s_expm1l.c @@ -0,0 +1,162 @@ +/* $OpenBSD: s_expm1l.c,v 1.1 2011/07/06 00:02:42 martynas Exp $ */ + +/* + * Copyright (c) 2008 Stephen L. Moshier + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* expm1l.c + * + * Exponential function, minus 1 + * 128-bit long double precision + * + * + * + * SYNOPSIS: + * + * long double x, y, expm1l(); + * + * y = expm1l( x ); + * + * + * + * DESCRIPTION: + * + * Returns e (2.71828...) raised to the x power, minus one. + * + * Range reduction is accomplished by separating the argument + * into an integer k and fraction f such that + * + * x k f + * e = 2 e. + * + * An expansion x + .5 x^2 + x^3 R(x) approximates exp(f) - 1 + * in the basic range [-0.5 ln 2, 0.5 ln 2]. + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE -79,+MAXLOG 100,000 1.7e-34 4.5e-35 + * + */ + +#include +#include + +#include "math_private.h" + +/* exp(x) - 1 = x + 0.5 x^2 + x^3 P(x)/Q(x) + -.5 ln 2 < x < .5 ln 2 + Theoretical peak relative error = 8.1e-36 */ + +static const long double + P0 = 2.943520915569954073888921213330863757240E8L, + P1 = -5.722847283900608941516165725053359168840E7L, + P2 = 8.944630806357575461578107295909719817253E6L, + P3 = -7.212432713558031519943281748462837065308E5L, + P4 = 4.578962475841642634225390068461943438441E4L, + P5 = -1.716772506388927649032068540558788106762E3L, + P6 = 4.401308817383362136048032038528753151144E1L, + P7 = -4.888737542888633647784737721812546636240E-1L, + Q0 = 1.766112549341972444333352727998584753865E9L, + Q1 = -7.848989743695296475743081255027098295771E8L, + Q2 = 1.615869009634292424463780387327037251069E8L, + Q3 = -2.019684072836541751428967854947019415698E7L, + Q4 = 1.682912729190313538934190635536631941751E6L, + Q5 = -9.615511549171441430850103489315371768998E4L, + Q6 = 3.697714952261803935521187272204485251835E3L, + Q7 = -8.802340681794263968892934703309274564037E1L, + /* Q8 = 1.000000000000000000000000000000000000000E0 */ +/* C1 + C2 = ln 2 */ + + C1 = 6.93145751953125E-1L, + C2 = 1.428606820309417232121458176568075500134E-6L, +/* ln (2^16384 * (1 - 2^-113)) */ + maxlog = 1.1356523406294143949491931077970764891253E4L, +/* ln 2^-114 */ + minarg = -7.9018778583833765273564461846232128760607E1L, big = 1e4932L; + + +long double +expm1l(long double x) +{ + long double px, qx, xx; + int32_t ix, sign; + ieee_quad_shape_type u; + int k; + + /* Detect infinity and NaN. */ + u.value = x; + ix = u.parts32.mswhi; + sign = ix & 0x80000000; + ix &= 0x7fffffff; + if (ix >= 0x7fff0000) + { + /* Infinity. */ + if (((ix & 0xffff) | u.parts32.mswlo | u.parts32.lswhi | + u.parts32.lswlo) == 0) + { + if (sign) + return -1.0L; + else + return x; + } + /* NaN. No invalid exception. */ + return x; + } + + /* expm1(+- 0) = +- 0. */ + if ((ix == 0) && (u.parts32.mswlo | u.parts32.lswhi | u.parts32.lswlo) == 0) + return x; + + /* Overflow. */ + if (x > maxlog) + return (big * big); + + /* Minimum value. */ + if (x < minarg) + return (4.0/big - 1.0L); + + /* Express x = ln 2 (k + remainder), remainder not exceeding 1/2. */ + xx = C1 + C2; /* ln 2. */ + px = floorl (0.5 + x / xx); + k = px; + /* remainder times ln 2 */ + x -= px * C1; + x -= px * C2; + + /* Approximate exp(remainder ln 2). */ + px = (((((((P7 * x + + P6) * x + + P5) * x + P4) * x + P3) * x + P2) * x + P1) * x + P0) * x; + + qx = (((((((x + + Q7) * x + + Q6) * x + Q5) * x + Q4) * x + Q3) * x + Q2) * x + Q1) * x + Q0; + + xx = x * x; + qx = x + (0.5 * xx + xx * px / qx); + + /* exp(x) = exp(k ln 2) exp(remainder ln 2) = 2^k exp(remainder ln 2). + + We have qx = exp(remainder ln 2) - 1, so + exp(x) - 1 = 2^k (qx + 1) - 1 + = 2^k qx + 2^k - 1. */ + + px = ldexpl (1.0L, k); + x = px * qx + (px - 1.0); + return x; +} diff --git a/src/openlibm/ld128/s_floorl.c b/src/openlibm/ld128/s_floorl.c new file mode 100644 index 0000000..f00dcfa --- /dev/null +++ b/src/openlibm/ld128/s_floorl.c @@ -0,0 +1,71 @@ +/* @(#)s_floor.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * floorl(x) + * Return x rounded toward -inf to integral value + * Method: + * Bit twiddling. + * Exception: + * Inexact flag raised if x not equal to floor(x). + */ + +#include + +#include "math_private.h" + +static const long double huge = 1.0e4930L; + +long double +floorl(long double x) +{ + int64_t i0,i1,jj0; + u_int64_t i,j; + GET_LDOUBLE_WORDS64(i0,i1,x); + jj0 = ((i0>>48)&0x7fff)-0x3fff; + if(jj0<48) { + if(jj0<0) { /* raise inexact if x != 0 */ + if(huge+x>0.0) { + if(i0>=0) + return 0.0L; + else if(((i0&0x7fffffffffffffffLL)|i1)!=0) + return -1.0L; + } + } else { + i = (0x0000ffffffffffffULL)>>jj0; + if(((i0&i)|i1)==0) return x; /* x is integral */ + if(huge+x>0.0) { /* raise inexact flag */ + if(i0<0) i0 += (0x0001000000000000LL)>>jj0; + i0 &= (~i); i1=0; + } + } + } else if (jj0>111) { + if(jj0==0x4000) return x+x; /* inf or NaN */ + else return x; /* x is integral */ + } else { + i = -1ULL>>(jj0-48); + if((i1&i)==0) return x; /* x is integral */ + if(huge+x>0.0) { /* raise inexact flag */ + if(i0<0) { + if(jj0==48) i0+=1; + else { + j = i1+(1LL<<(112-jj0)); + if(j + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* log1pl.c + * + * Relative error logarithm + * Natural logarithm of 1+x, 128-bit long double precision + * + * + * + * SYNOPSIS: + * + * long double x, y, log1pl(); + * + * y = log1pl( x ); + * + * + * + * DESCRIPTION: + * + * Returns the base e (2.718...) logarithm of 1+x. + * + * The argument 1+x is separated into its exponent and fractional + * parts. If the exponent is between -1 and +1, the logarithm + * of the fraction is approximated by + * + * log(1+x) = x - 0.5 x^2 + x^3 P(x)/Q(x). + * + * Otherwise, setting z = 2(w-1)/(w+1), + * + * log(w) = z + z^3 P(z)/Q(z). + * + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE -1, 8 100000 1.9e-34 4.3e-35 + */ + +#include + +#include "math_private.h" + +/* Coefficients for log(1+x) = x - x^2 / 2 + x^3 P(x)/Q(x) + * 1/sqrt(2) <= 1+x < sqrt(2) + * Theoretical peak relative error = 5.3e-37, + * relative peak error spread = 2.3e-14 + */ +static const long double + P12 = 1.538612243596254322971797716843006400388E-6L, + P11 = 4.998469661968096229986658302195402690910E-1L, + P10 = 2.321125933898420063925789532045674660756E1L, + P9 = 4.114517881637811823002128927449878962058E2L, + P8 = 3.824952356185897735160588078446136783779E3L, + P7 = 2.128857716871515081352991964243375186031E4L, + P6 = 7.594356839258970405033155585486712125861E4L, + P5 = 1.797628303815655343403735250238293741397E5L, + P4 = 2.854829159639697837788887080758954924001E5L, + P3 = 3.007007295140399532324943111654767187848E5L, + P2 = 2.014652742082537582487669938141683759923E5L, + P1 = 7.771154681358524243729929227226708890930E4L, + P0 = 1.313572404063446165910279910527789794488E4L, + /* Q12 = 1.000000000000000000000000000000000000000E0L, */ + Q11 = 4.839208193348159620282142911143429644326E1L, + Q10 = 9.104928120962988414618126155557301584078E2L, + Q9 = 9.147150349299596453976674231612674085381E3L, + Q8 = 5.605842085972455027590989944010492125825E4L, + Q7 = 2.248234257620569139969141618556349415120E5L, + Q6 = 6.132189329546557743179177159925690841200E5L, + Q5 = 1.158019977462989115839826904108208787040E6L, + Q4 = 1.514882452993549494932585972882995548426E6L, + Q3 = 1.347518538384329112529391120390701166528E6L, + Q2 = 7.777690340007566932935753241556479363645E5L, + Q1 = 2.626900195321832660448791748036714883242E5L, + Q0 = 3.940717212190338497730839731583397586124E4L; + +/* Coefficients for log(x) = z + z^3 P(z^2)/Q(z^2), + * where z = 2(x-1)/(x+1) + * 1/sqrt(2) <= x < sqrt(2) + * Theoretical peak relative error = 1.1e-35, + * relative peak error spread 1.1e-9 + */ +static const long double + R5 = -8.828896441624934385266096344596648080902E-1L, + R4 = 8.057002716646055371965756206836056074715E1L, + R3 = -2.024301798136027039250415126250455056397E3L, + R2 = 2.048819892795278657810231591630928516206E4L, + R1 = -8.977257995689735303686582344659576526998E4L, + R0 = 1.418134209872192732479751274970992665513E5L, + /* S6 = 1.000000000000000000000000000000000000000E0L, */ + S5 = -1.186359407982897997337150403816839480438E2L, + S4 = 3.998526750980007367835804959888064681098E3L, + S3 = -5.748542087379434595104154610899551484314E4L, + S2 = 4.001557694070773974936904547424676279307E5L, + S1 = -1.332535117259762928288745111081235577029E6L, + S0 = 1.701761051846631278975701529965589676574E6L; + +/* C1 + C2 = ln 2 */ +static const long double C1 = 6.93145751953125E-1L; +static const long double C2 = 1.428606820309417232121458176568075500134E-6L; + +static const long double sqrth = 0.7071067811865475244008443621048490392848L; +/* ln (2^16384 * (1 - 2^-113)) */ +static const long double zero = 0.0L; + +long double +log1pl(long double xm1) +{ + long double x, y, z, r, s; + ieee_quad_shape_type u; + int32_t hx; + int e; + + /* Test for NaN or infinity input. */ + u.value = xm1; + hx = u.parts32.mswhi; + if (hx >= 0x7fff0000) + return xm1; + + /* log1p(+- 0) = +- 0. */ + if (((hx & 0x7fffffff) == 0) + && (u.parts32.mswlo | u.parts32.lswhi | u.parts32.lswlo) == 0) + return xm1; + + x = xm1 + 1.0L; + + /* log1p(-1) = -inf */ + if (x <= 0.0L) + { + if (x == 0.0L) + return (-1.0L / (x - x)); + else + return (zero / (x - x)); + } + + /* Separate mantissa from exponent. */ + + /* Use frexp used so that denormal numbers will be handled properly. */ + x = frexpl (x, &e); + + /* Logarithm using log(x) = z + z^3 P(z^2)/Q(z^2), + where z = 2(x-1)/x+1). */ + if ((e > 2) || (e < -2)) + { + if (x < sqrth) + { /* 2( 2x-1 )/( 2x+1 ) */ + e -= 1; + z = x - 0.5L; + y = 0.5L * z + 0.5L; + } + else + { /* 2 (x-1)/(x+1) */ + z = x - 0.5L; + z -= 0.5L; + y = 0.5L * x + 0.5L; + } + x = z / y; + z = x * x; + r = ((((R5 * z + + R4) * z + + R3) * z + + R2) * z + + R1) * z + + R0; + s = (((((z + + S5) * z + + S4) * z + + S3) * z + + S2) * z + + S1) * z + + S0; + z = x * (z * r / s); + z = z + e * C2; + z = z + x; + z = z + e * C1; + return (z); + } + + + /* Logarithm using log(1+x) = x - .5x^2 + x^3 P(x)/Q(x). */ + + if (x < sqrth) + { + e -= 1; + if (e != 0) + x = 2.0L * x - 1.0L; /* 2x - 1 */ + else + x = xm1; + } + else + { + if (e != 0) + x = x - 1.0L; + else + x = xm1; + } + z = x * x; + r = (((((((((((P12 * x + + P11) * x + + P10) * x + + P9) * x + + P8) * x + + P7) * x + + P6) * x + + P5) * x + + P4) * x + + P3) * x + + P2) * x + + P1) * x + + P0; + s = (((((((((((x + + Q11) * x + + Q10) * x + + Q9) * x + + Q8) * x + + Q7) * x + + Q6) * x + + Q5) * x + + Q4) * x + + Q3) * x + + Q2) * x + + Q1) * x + + Q0; + y = x * (z * r / s); + y = y + e * C2; + z = y - 0.5L * z; + z = z + x; + z = z + e * C1; + return (z); +} diff --git a/src/openlibm/ld128/s_modfl.c b/src/openlibm/ld128/s_modfl.c new file mode 100644 index 0000000..bd18cba --- /dev/null +++ b/src/openlibm/ld128/s_modfl.c @@ -0,0 +1,73 @@ +/* @(#)s_modf.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * modfl(long double x, long double *iptr) + * return fraction part of x, and return x's integral part in *iptr. + * Method: + * Bit twiddling. + * + * Exception: + * No exception. + */ + +#include + +#include "math_private.h" + +static const long double one = 1.0; + +long double +modfl(long double x, long double *iptr) +{ + int64_t i0,i1,jj0; + u_int64_t i; + GET_LDOUBLE_WORDS64(i0,i1,x); + jj0 = ((i0>>48)&0x7fff)-0x3fff; /* exponent of x */ + if(jj0<48) { /* integer part in high x */ + if(jj0<0) { /* |x|<1 */ + /* *iptr = +-0 */ + SET_LDOUBLE_WORDS64(*iptr,i0&0x8000000000000000ULL,0); + return x; + } else { + i = (0x0000ffffffffffffLL)>>jj0; + if(((i0&i)|i1)==0) { /* x is integral */ + *iptr = x; + /* return +-0 */ + SET_LDOUBLE_WORDS64(x,i0&0x8000000000000000ULL,0); + return x; + } else { + SET_LDOUBLE_WORDS64(*iptr,i0&(~i),0); + return x - *iptr; + } + } + } else if (jj0>111) { /* no fraction part */ + *iptr = x*one; + /* We must handle NaNs separately. */ + if (jj0 == 0x4000 && ((i0 & 0x0000ffffffffffffLL) | i1)) + return x*one; + /* return +-0 */ + SET_LDOUBLE_WORDS64(x,i0&0x8000000000000000ULL,0); + return x; + } else { /* fraction part in low x */ + i = -1ULL>>(jj0-48); + if((i1&i)==0) { /* x is integral */ + *iptr = x; + /* return +-0 */ + SET_LDOUBLE_WORDS64(x,i0&0x8000000000000000ULL,0); + return x; + } else { + SET_LDOUBLE_WORDS64(*iptr,i0,i1&(~i)); + return x - *iptr; + } + } +} diff --git a/src/openlibm/ld128/s_nanl.c b/src/openlibm/ld128/s_nanl.c new file mode 100644 index 0000000..4dcdb4e --- /dev/null +++ b/src/openlibm/ld128/s_nanl.c @@ -0,0 +1,46 @@ +/*- + * Copyright (c) 2007 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/msun/ld128/s_nanl.c,v 1.3 2008/03/02 20:16:55 das Exp $ + */ + +#include + +#include "fpmath.h" +#include "math_private.h" + +OLM_DLLEXPORT long double +nanl(const char *s) +{ + union { + union IEEEl2bits ieee; + uint32_t bits[4]; + } u; + + __scan_nan(u.bits, 4, s); + u.ieee.bits.exp = 0x7fff; + u.ieee.bits.manh |= 1ULL << 47; /* make it a quiet NaN */ + return (u.ieee.e); +} diff --git a/src/openlibm/ld128/s_nextafterl.c b/src/openlibm/ld128/s_nextafterl.c new file mode 100644 index 0000000..af667a0 --- /dev/null +++ b/src/openlibm/ld128/s_nextafterl.c @@ -0,0 +1,72 @@ +/* @(#)s_nextafter.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* IEEE functions + * nextafterl(x,y) + * return the next machine floating-point number of x in the + * direction toward y. + * Special cases: + */ + +#include + +#include "math_private.h" + +long double +nextafterl(long double x, long double y) +{ + int64_t hx,hy,ix,iy; + u_int64_t lx,ly; + + GET_LDOUBLE_WORDS64(hx,lx,x); + GET_LDOUBLE_WORDS64(hy,ly,y); + ix = hx&0x7fffffffffffffffLL; /* |x| */ + iy = hy&0x7fffffffffffffffLL; /* |y| */ + + if(((ix>=0x7fff000000000000LL)&&((ix-0x7fff000000000000LL)|lx)!=0) || /* x is nan */ + ((iy>=0x7fff000000000000LL)&&((iy-0x7fff000000000000LL)|ly)!=0)) /* y is nan */ + return x+y; + if(x==y) return y; /* x=y, return y */ + if((ix|lx)==0) { /* x == 0 */ + volatile long double u; + SET_LDOUBLE_WORDS64(x,hy&0x8000000000000000ULL,1);/* return +-minsubnormal */ + u = x; + u = u * u; /* raise underflow flag */ + return x; + } + if(hx>=0) { /* x > 0 */ + if(hx>hy||((hx==hy)&&(lx>ly))) { /* x > y, x -= ulp */ + if(lx==0) hx--; + lx--; + } else { /* x < y, x += ulp */ + lx++; + if(lx==0) hx++; + } + } else { /* x < 0 */ + if(hy>=0||hx>hy||((hx==hy)&&(lx>ly))){/* x < y, x -= ulp */ + if(lx==0) hx--; + lx--; + } else { /* x > y, x += ulp */ + lx++; + if(lx==0) hx++; + } + } + hy = hx&0x7fff000000000000LL; + if(hy==0x7fff000000000000LL) return x+x;/* overflow */ + if(hy==0) { + volatile long double u = x*x; /* underflow */ + } + SET_LDOUBLE_WORDS64(x,hx,lx); + return x; +} + +__strong_alias(nexttowardl, nextafterl); diff --git a/src/openlibm/ld128/s_nexttoward.c b/src/openlibm/ld128/s_nexttoward.c new file mode 100644 index 0000000..a9ff797 --- /dev/null +++ b/src/openlibm/ld128/s_nexttoward.c @@ -0,0 +1,85 @@ +/* @(#)s_nextafter.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* IEEE functions + * nexttoward(x,y) + * return the next machine floating-point number of x in the + * direction toward y. + * Special cases: + */ + +#include +#include + +#include "math_private.h" + +double +nexttoward(double x, long double y) +{ + int32_t hx,ix; + int64_t hy,iy; + u_int32_t lx; + u_int64_t ly; + + EXTRACT_WORDS(hx,lx,x); + GET_LDOUBLE_WORDS64(hy,ly,y); + ix = hx&0x7fffffff; /* |x| */ + iy = hy&0x7fffffffffffffffLL; /* |y| */ + + if(((ix>=0x7ff00000)&&((ix-0x7ff00000)|lx)!=0) || /* x is nan */ + ((iy>=0x7fff000000000000LL)&&((iy-0x7fff000000000000LL)|ly)!=0)) + /* y is nan */ + return x+y; + if((long double) x==y) return y; /* x=y, return y */ + if((ix|lx)==0) { /* x == 0 */ + volatile double u; + INSERT_WORDS(x,(u_int32_t)((hy>>32)&0x80000000),1);/* return +-minsub */ + u = x; + u = u * u; /* raise underflow flag */ + return x; + } + if(hx>=0) { /* x > 0 */ + if (hy<0||(ix>>20)>(iy>>48)-0x3c00 + || ((ix>>20)==(iy>>48)-0x3c00 + && (((((int64_t)hx)<<28)|(lx>>4))>(hy&0x0000ffffffffffffLL) + || (((((int64_t)hx)<<28)|(lx>>4))==(hy&0x0000ffffffffffffLL) + && (lx&0xf)>(ly>>60))))) { /* x > y, x -= ulp */ + if(lx==0) hx -= 1; + lx -= 1; + } else { /* x < y, x += ulp */ + lx += 1; + if(lx==0) hx += 1; + } + } else { /* x < 0 */ + if (hy>=0||(ix>>20)>(iy>>48)-0x3c00 + || ((ix>>20)==(iy>>48)-0x3c00 + && (((((int64_t)hx)<<28)|(lx>>4))>(hy&0x0000ffffffffffffLL) + || (((((int64_t)hx)<<28)|(lx>>4))==(hy&0x0000ffffffffffffLL) + && (lx&0xf)>(ly>>60))))) { /* x < y, x -= ulp */ + if(lx==0) hx -= 1; + lx -= 1; + } else { /* x > y, x += ulp */ + lx += 1; + if(lx==0) hx += 1; + } + } + hy = hx&0x7ff00000; + if(hy>=0x7ff00000) { + x = x+x; /* overflow */ + return x; + } + if(hy<0x00100000) { + volatile double u = x*x; /* underflow */ + } + INSERT_WORDS(x,hx,lx); + return x; +} diff --git a/src/openlibm/ld128/s_nexttowardf.c b/src/openlibm/ld128/s_nexttowardf.c new file mode 100644 index 0000000..61387ac --- /dev/null +++ b/src/openlibm/ld128/s_nexttowardf.c @@ -0,0 +1,65 @@ +/* @(#)s_nextafter.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include + +#include "math_private.h" + +float +nexttowardf(float x, long double y) +{ + int32_t hx,ix; + int64_t hy,iy; + u_int64_t ly; + + GET_FLOAT_WORD(hx,x); + GET_LDOUBLE_WORDS64(hy,ly,y); + ix = hx&0x7fffffff; /* |x| */ + iy = hy&0x7fffffffffffffffLL; /* |y| */ + + if((ix>0x7f800000) || /* x is nan */ + ((iy>=0x7fff000000000000LL)&&((iy-0x7fff000000000000LL)|ly)!=0)) + /* y is nan */ + return x+y; + if((long double) x==y) return y; /* x=y, return y */ + if(ix==0) { /* x == 0 */ + volatile float u; + SET_FLOAT_WORD(x,(u_int32_t)((hy>>32)&0x80000000)|1);/* return +-minsub*/ + u = x; + u = u * u; /* raise underflow flag */ + return x; + } + if(hx>=0) { /* x > 0 */ + if(hy<0||(ix>>23)>(iy>>48)-0x3f80 + || ((ix>>23)==(iy>>48)-0x3f80 + && (ix&0x7fffff)>((hy>>25)&0x7fffff))) {/* x > y, x -= ulp */ + hx -= 1; + } else { /* x < y, x += ulp */ + hx += 1; + } + } else { /* x < 0 */ + if(hy>=0||(ix>>23)>(iy>>48)-0x3f80 + || ((ix>>23)==(iy>>48)-0x3f80 + && (ix&0x7fffff)>((hy>>25)&0x7fffff))) {/* x < y, x -= ulp */ + hx -= 1; + } else { /* x > y, x += ulp */ + hx += 1; + } + } + hy = hx&0x7f800000; + if(hy>=0x7f800000) return x+x; /* overflow */ + if(hy<0x00800000) { + volatile float u = x*x; /* underflow */ + } + SET_FLOAT_WORD(x,hx); + return x; +} diff --git a/src/openlibm/ld128/s_remquol.c b/src/openlibm/ld128/s_remquol.c new file mode 100644 index 0000000..f56ce4f --- /dev/null +++ b/src/openlibm/ld128/s_remquol.c @@ -0,0 +1,168 @@ +/* @(#)e_fmod.c 1.3 95/01/18 */ +/*- + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include +#include + +#include +#include +#include + +#include "math_private.h" + +#define BIAS (LDBL_MAX_EXP - 1) + +/* + * These macros add and remove an explicit integer bit in front of the + * fractional mantissa, if the architecture doesn't have such a bit by + * default already. + */ +#ifdef LDBL_IMPLICIT_NBIT +#define LDBL_NBIT 0 +#define SET_NBIT(hx) ((hx) | (1ULL << LDBL_MANH_SIZE)) +#define HFRAC_BITS (EXT_FRACHBITS + EXT_FRACHMBITS) +#else +#define LDBL_NBIT 0x80000000 +#define SET_NBIT(hx) (hx) +#define HFRAC_BITS (EXT_FRACHBITS + EXT_FRACHMBITS - 1) +#endif + +#define MANL_SHIFT (EXT_FRACLMBITS + EXT_FRACLBITS - 1) + +static const long double Zero[] = {0.0L, -0.0L}; + +/* + * Return the IEEE remainder and set *quo to the last n bits of the + * quotient, rounded to the nearest integer. We choose n=31 because + * we wind up computing all the integer bits of the quotient anyway as + * a side-effect of computing the remainder by the shift and subtract + * method. In practice, this is far more bits than are needed to use + * remquo in reduction algorithms. + * + * Assumptions: + * - The low part of the mantissa fits in a manl_t exactly. + * - The high part of the mantissa fits in an int64_t with enough room + * for an explicit integer bit in front of the fractional bits. + */ +long double +remquol(long double x, long double y, int *quo) +{ + int64_t hx,hz,hy,_hx; + uint64_t lx,ly,lz; + uint64_t sx,sxy; + int ix,iy,n,q; + + GET_LDOUBLE_WORDS64(hx,lx,x); + GET_LDOUBLE_WORDS64(hy,ly,y); + sx = (hx>>48)&0x8000; + sxy = sx ^ ((hy>>48)&0x8000); + hx &= 0x7fffffffffffffffLL; /* |x| */ + hy &= 0x7fffffffffffffffLL; /* |y| */ + SET_LDOUBLE_WORDS64(x,hx,lx); + SET_LDOUBLE_WORDS64(y,hy,ly); + + /* purge off exception values */ + if((hy|ly)==0 || /* y=0 */ + ((hx>>48) == BIAS + LDBL_MAX_EXP) || /* or x not finite */ + ((hy>>48) == BIAS + LDBL_MAX_EXP && + (((hy&0x0000ffffffffffffLL)&~LDBL_NBIT)|ly)!=0)) /* or y is NaN */ + return (x*y)/(x*y); + if((hx>>48)<=(hy>>48)) { + if(((hx>>48)<(hy>>48)) || + ((hx&0x0000ffffffffffffLL)<=(hy&0x0000ffffffffffffLL) && + ((hx&0x0000ffffffffffffLL)<(hy&0x0000ffffffffffffLL) || + lx>48) == 0) { /* subnormal x */ + x *= 0x1.0p512; + GET_LDOUBLE_WORDS64(hx,lx,x); + ix = (hx>>48) - (BIAS + 512); + } else { + ix = (hx>>48) - BIAS; + } + + /* determine iy = ilogb(y) */ + if((hy>>48) == 0) { /* subnormal y */ + y *= 0x1.0p512; + GET_LDOUBLE_WORDS64(hy,ly,y); + iy = (hy>>48) - (BIAS + 512); + } else { + iy = (hy>>48) - BIAS; + } + + /* set up {hx,lx}, {hy,ly} and align y to x */ + _hx = SET_NBIT(hx) & 0x0000ffffffffffffLL; + hy = SET_NBIT(hy); + + /* fix point fmod */ + n = ix - iy; + q = 0; + + while(n--) { + hz=_hx-hy;lz=lx-ly; if(lx>MANL_SHIFT); lx = lx+lx;} + else {_hx = hz+hz+(lz>>MANL_SHIFT); lx = lz+lz; q++;} + q <<= 1; + } + hz=_hx-hy;lz=lx-ly; if(lx=0) {_hx=hz;lx=lz;q++;} + + /* convert back to floating value and restore the sign */ + if((_hx|lx)==0) { /* return sign(x)*0 */ + *quo = (sxy ? -q : q); + return Zero[sx!=0]; + } + while(_hx<(1ULL<>MANL_SHIFT); lx = lx+lx; + iy -= 1; + } + hx = (hx&0xffff000000000000LL) | (_hx&0x0000ffffffffffffLL); + if (iy < LDBL_MIN_EXP) { + hx = (hx&0x0000ffffffffffffLL) | (uint64_t)(iy + BIAS + 512)<<48; + SET_LDOUBLE_WORDS64(x,hx,lx); + x *= 0x1p-512; + GET_LDOUBLE_WORDS64(hx,lx,x); + } else { + hx = (hx&0x0000ffffffffffffLL) | (uint64_t)(iy + BIAS)<<48; + } + hx &= 0x7fffffffffffffffLL; + SET_LDOUBLE_WORDS64(x,hx,lx); +fixup: + y = fabsl(y); + if (y < LDBL_MIN * 2) { + if (x+x>y || (x+x==y && (q & 1))) { + q++; + x-=y; + } + } else if (x>0.5*y || (x==0.5*y && (q & 1))) { + q++; + x-=y; + } + + GET_LDOUBLE_MSW64(hx,x); + hx ^= sx; + SET_LDOUBLE_MSW64(x,hx); + + q &= 0x7fffffff; + *quo = (sxy ? -q : q); + return x; +} diff --git a/src/openlibm/ld128/s_tanhl.c b/src/openlibm/ld128/s_tanhl.c new file mode 100644 index 0000000..f8e6291 --- /dev/null +++ b/src/openlibm/ld128/s_tanhl.c @@ -0,0 +1,105 @@ +/* @(#)s_tanh.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * Copyright (c) 2008 Stephen L. Moshier + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* tanhl(x) + * Return the Hyperbolic Tangent of x + * + * Method : + * x -x + * e - e + * 0. tanhl(x) is defined to be ----------- + * x -x + * e + e + * 1. reduce x to non-negative by tanhl(-x) = -tanhl(x). + * 2. 0 <= x <= 2**-57 : tanhl(x) := x*(one+x) + * -t + * 2**-57 < x <= 1 : tanhl(x) := -----; t = expm1l(-2x) + * t + 2 + * 2 + * 1 <= x <= 40.0 : tanhl(x) := 1- ----- ; t=expm1l(2x) + * t + 2 + * 40.0 < x <= INF : tanhl(x) := 1. + * + * Special cases: + * tanhl(NaN) is NaN; + * only tanhl(0)=0 is exact for finite argument. + */ + +#include + +#include "math_private.h" + +static const long double one = 1.0, two = 2.0, tiny = 1.0e-4900L; + +long double +tanhl(long double x) +{ + long double t, z; + u_int32_t jx, ix; + ieee_quad_shape_type u; + + /* Words of |x|. */ + u.value = x; + jx = u.parts32.mswhi; + ix = jx & 0x7fffffff; + /* x is INF or NaN */ + if (ix >= 0x7fff0000) + { + /* for NaN it's not important which branch: tanhl(NaN) = NaN */ + if (jx & 0x80000000) + return one / x - one; /* tanhl(-inf)= -1; */ + else + return one / x + one; /* tanhl(+inf)=+1 */ + } + + /* |x| < 40 */ + if (ix < 0x40044000) + { + if (u.value == 0) + return x; /* x == +- 0 */ + if (ix < 0x3fc60000) /* |x| < 2^-57 */ + return x * (one + tiny); /* tanh(small) = small */ + u.parts32.mswhi = ix; /* Absolute value of x. */ + if (ix >= 0x3fff0000) + { /* |x| >= 1 */ + t = expm1l (two * u.value); + z = one - two / (t + two); + } + else + { + t = expm1l (-two * u.value); + z = -t / (t + two); + } + /* |x| > 40, return +-1 */ + } + else + { + z = one - tiny; /* raised inexact flag */ + } + return (jx & 0x80000000) ? -z : z; +} diff --git a/src/openlibm/ld128/s_truncl.c b/src/openlibm/ld128/s_truncl.c new file mode 100644 index 0000000..a0d8bd5 --- /dev/null +++ b/src/openlibm/ld128/s_truncl.c @@ -0,0 +1,72 @@ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + * + * From: @(#)s_floor.c 5.1 93/09/24 + */ + +/* + * truncl(x) + * Return x rounded toward 0 to integral value + * Method: + * Bit twiddling. + * Exception: + * Inexact flag raised if x not equal to truncl(x). + */ + +#include +#include + +#include +#include +#include + +#include "math_private.h" + +#ifdef LDBL_IMPLICIT_NBIT +#define MANH_SIZE (EXT_FRACHBITS + EXT_FRACHMBITS + 1) +#else +#define MANH_SIZE (EXT_FRACHBITS + EXT_FRACHMBITS) +#endif + +static const long double huge = 1.0e300; +static const float zero[] = { 0.0, -0.0 }; + +long double +truncl(long double x) +{ + int e; + int64_t ix0, ix1; + + GET_LDOUBLE_WORDS64(ix0,ix1,x); + e = ((ix0>>48)&0x7fff) - LDBL_MAX_EXP + 1; + + if (e < MANH_SIZE - 1) { + if (e < 0) { /* raise inexact if x != 0 */ + if (huge + x > 0.0) + return (zero[((ix0>>48)&0x8000)!=0]); + } else { + uint64_t m = ((1llu << MANH_SIZE) - 1) >> (e + 1); + if (((ix0 & m) | ix1) == 0) + return (x); /* x is integral */ + if (huge + x > 0.0) { /* raise inexact flag */ + ix0 &= ~m; + ix1 = 0; + } + } + } else if (e < LDBL_MANT_DIG - 1) { + uint64_t m = (uint64_t)-1 >> (64 - LDBL_MANT_DIG + e + 1); + if ((ix1 & m) == 0) + return (x); /* x is integral */ + if (huge + x > 0.0) /* raise inexact flag */ + ix1 &= ~m; + } + SET_LDOUBLE_WORDS64(x,ix0,ix1); + return (x); +} diff --git a/src/openlibm/ld80/Make.files b/src/openlibm/ld80/Make.files new file mode 100644 index 0000000..1198cfb --- /dev/null +++ b/src/openlibm/ld80/Make.files @@ -0,0 +1,13 @@ +$(CUR_SRCS) += invtrig.c \ + e_acoshl.c e_powl.c k_tanl.c s_exp2l.c \ + e_atanhl.c e_lgammal_r.c e_sinhl.c s_asinhl.c s_expm1l.c \ + e_coshl.c e_log10l.c e_tgammal.c \ + e_expl.c e_log2l.c k_cosl.c s_log1pl.c s_tanhl.c \ + e_logl.c k_sinl.c s_erfl.c + +# s_remquol.c e_fmodl.c s_truncl.c +# e_hypotl.c s_floorl.c s_nextafterl.c s_ceill.c s_modfl.c + +ifneq ($(OS), WINNT) +$(CUR_SRCS) += s_nanl.c +endif diff --git a/src/openlibm/ld80/e_acoshl.c b/src/openlibm/ld80/e_acoshl.c new file mode 100644 index 0000000..35758bb --- /dev/null +++ b/src/openlibm/ld80/e_acoshl.c @@ -0,0 +1,57 @@ +/* @(#)e_acosh.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* acoshl(x) + * Method : + * Based on + * acoshl(x) = logl [ x + sqrtl(x*x-1) ] + * we have + * acoshl(x) := logl(x)+ln2, if x is large; else + * acoshl(x) := logl(2x-1/(sqrtl(x*x-1)+x)) if x>2; else + * acoshl(x) := log1pl(t+sqrtl(2.0*t+t*t)); where t=x-1. + * + * Special cases: + * acoshl(x) is NaN with signal if x<1. + * acoshl(NaN) is NaN without signal. + */ + +#include + +#include "math_private.h" + +static const long double +one = 1.0, +ln2 = 6.931471805599453094287e-01L; /* 0x3FFE, 0xB17217F7, 0xD1CF79AC */ + +long double +acoshl(long double x) +{ + long double t; + u_int32_t se,i0,i1; + GET_LDOUBLE_WORDS(se,i0,i1,x); + if(se<0x3fff || se & 0x8000) { /* x < 1 */ + return (x-x)/(x-x); + } else if(se >=0x401d) { /* x > 2**30 */ + if(se >=0x7fff) { /* x is inf of NaN */ + return x+x; + } else + return logl(x)+ln2; /* acoshl(huge)=logl(2x) */ + } else if(((se-0x3fff)|i0|i1)==0) { + return 0.0; /* acosh(1) = 0 */ + } else if (se > 0x4000) { /* 2**28 > x > 2 */ + t=x*x; + return logl(2.0*x-one/(x+sqrtl(t-one))); + } else { /* 1JfjWMqH=Mg}_u1P><4z;J^Z!FB*M9T<2Sco;mI-)P*j9tU43aDL*vSdwVV0Me5MR{Tcb=7AdrZr7+N+&pma!|E?Hm<>dk1g6xcBjPj*7y)hqr4~96XwjSiA&Drh)DMU!uYR!eI3gQ8(X$EWdZ~ z@XdEG!~g&PpT;lW0#eLy^MyzA8v(F^4{sj0aq#BB8>eobx?KaZ0M$AaOBmdpovjo! z-2Fl|6%0-EjPwi@j0}uS4Gawp6f}ZTQxrTBOP~_E=9&x)3@i)`3H#OG@EkU|pjTW{1fervtfJJMM7@&KiV_CBl*E!m2EC->Vg|kB z{M_8syb=bzy!?_>J$JuQ-QtqO=hsNicDc zHRyJO%D?l6u1_o{h1_qFk==wRK;!tI9Y6DciDqIA@0NDp&K}bOy`ZGY5F)%QI M3kir)Fo~`o0A)1$;{X5v literal 0 HcmV?d00001 diff --git a/src/openlibm/ld80/e_atanhl.c b/src/openlibm/ld80/e_atanhl.c new file mode 100644 index 0000000..6d13a5c --- /dev/null +++ b/src/openlibm/ld80/e_atanhl.c @@ -0,0 +1,60 @@ +/* @(#)e_atanh.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* atanhl(x) + * Method : + * 1.Reduced x to positive by atanh(-x) = -atanh(x) + * 2.For x>=0.5 + * 1 2x x + * atanhl(x) = --- * log(1 + -------) = 0.5 * log1p(2 * --------) + * 2 1 - x 1 - x + * + * For x<0.5 + * atanhl(x) = 0.5*log1pl(2x+2x*x/(1-x)) + * + * Special cases: + * atanhl(x) is NaN if |x| > 1 with signal; + * atanhl(NaN) is that NaN with no signal; + * atanhl(+-1) is +-INF with signal. + * + */ + +#include + +#include "math_private.h" + +static const long double one = 1.0, huge = 1e4900L; + +static const long double zero = 0.0; + +long double +atanhl(long double x) +{ + long double t; + int32_t ix; + u_int32_t se,i0,i1; + GET_LDOUBLE_WORDS(se,i0,i1,x); + ix = se&0x7fff; + if ((ix+((((i0&0x7fffffff)|i1)|(-((i0&0x7fffffff)|i1)))>>31))>0x3fff) + /* |x|>1 */ + return (x-x)/(x-x); + if(ix==0x3fff) + return x/zero; + if(ix<0x3fe3&&(huge+x)>zero) return x; /* x<2**-28 */ + SET_LDOUBLE_EXP(x,ix); + if(ix<0x3ffe) { /* x < 0.5 */ + t = x+x; + t = 0.5*log1pl(t+t*x/(one-x)); + } else + t = 0.5*log1pl((x+x)/(one-x)); + if(se<=0x7fff) return t; else return -t; +} diff --git a/src/openlibm/ld80/e_atanhl.c.o b/src/openlibm/ld80/e_atanhl.c.o new file mode 100644 index 0000000000000000000000000000000000000000..8302cde1f6b10ec9366b1d2cb678948af7206df2 GIT binary patch literal 2032 zcmb<-^>JfjWMqH=Mg}_u1P><4z+k|FU^{@B4h;MZd8$i_(~zI@!|ja#z+7E|F7pf)Oq3i4bBUlw+_CLZ+!H>o`He!g6)5M1_u82qYMlT zX^lVs+w-?vf-oQ1*G1pXQBk;UqmtI?qr!1pN9E>$8wYQ`xbY~h@#jDL(%ieZZl1jN z6J+mg8ECbb!l>!;b!tn7wHc4hIDUAoL zkPS>C6M|q4$hTkyoDgGRU=Ttw2kZw11_oIM1_lARDkMf~d}2vrUPg{yGJ~FvvoVM; zWPk`UvCJcJX`MJ5Nc_j>bdHE%&dhULqy2T}l$=OhTdS0nsK~a7|YEelg zgC5xM)QtGFqQu-(uuCW+K>h=z2~b!d8w4p+7#Lvj2a`jOLum#`oWRt>)JcFMgMope z0xAGXM<9DRpnM4^t;WCrPAyR7P*DbkJdk2I55Yhe)?r{^0GUayenY7JLI^9stOBS- z=>CQAVYEFC{S8q4pmYW{5K6%KFxm&I-vBBPqgtT)^+WDUCAAoD$-f-68A1_lODjRY#KVD5+M=Y*CUP-SrH1602XTm-@Z d*#}`kNKiQlbt*&vO0Iwk!pbM8Fg)I1d;q@WAzA + +#include "math_private.h" + +static const long double one = 1.0, half=0.5, huge = 1.0e4900L; + +long double +coshl(long double x) +{ + long double t,w; + int32_t ex; + u_int32_t mx,lx; + + /* High word of |x|. */ + GET_LDOUBLE_WORDS(ex,mx,lx,x); + ex &= 0x7fff; + + /* x is INF or NaN */ + if(ex==0x7fff) return x*x; + + /* |x| in [0,0.5*ln2], return 1+expm1l(|x|)^2/(2*expl(|x|)) */ + if(ex < 0x3ffd || (ex == 0x3ffd && mx < 0xb17217f7u)) { + t = expm1l(fabsl(x)); + w = one+t; + if (ex<0x3fbc) return w; /* cosh(tiny) = 1 */ + return one+(t*t)/(w+w); + } + + /* |x| in [0.5*ln2,22], return (exp(|x|)+1/exp(|x|)/2; */ + if (ex < 0x4003 || (ex == 0x4003 && mx < 0xb0000000u)) { + t = expl(fabsl(x)); + return half*t+half/t; + } + + /* |x| in [22, ln(maxdouble)] return half*exp(|x|) */ + if (ex < 0x400c || (ex == 0x400c && mx < 0xb1700000u)) + return half*expl(fabsl(x)); + + /* |x| in [log(maxdouble), log(2*maxdouble)) */ + if (ex == 0x400c && (mx < 0xb174ddc0u + || (mx == 0xb174ddc0u && lx < 0x31aec0ebu))) + { + w = expl(half*fabsl(x)); + t = half*w; + return t*w; + } + + /* |x| >= log(2*maxdouble), cosh(x) overflow */ + return huge*huge; +} diff --git a/src/openlibm/ld80/e_coshl.c.o b/src/openlibm/ld80/e_coshl.c.o new file mode 100644 index 0000000000000000000000000000000000000000..c6b76c3504006c4b1fc430da178f10746e47e08e GIT binary patch literal 2536 zcmb<-^>JfjWMqH=Mg}_u1P><4z@Wi~U^{@B4h;MZdX^oHn*QYi9{$J1E za*2U~A+7QEAAA13=?n}E9^Eb~0v-onD5N$1{%c=qZ~INWXk)p>{}L4m5PktN%cJ>? zz-=29DEo-Q%@;Qg-aPr5m0zCW=E)l;Zk~+3ap2z1n=kGiJe=0}o5`V$FRk%6vqNc- z?f?J(*OzC53<6=O0ceIDxXB8#B>K*&dmlk2@XNa}Fo2YUFm^33ZX8T&{Jq=0zTxi8 z=)?T-4h*+*R0N`LoB-L+4Y8lcq14Fs|Ns1r<<=mBKp3lGH+aFeA5H_?ds`RG1DOQo zr#1fOaVULhyZ>&<#xh~s19wX{mfi-3neD3s>kP}!gUkhCu-OowfP(AZNt6IP5DhW- z-l=;h4>K?@*n?~V;e$)eBh^_Zt(#I0;=yslKbQ)4XJ;z~4R^m#O$9>}JtI9s1tS9^ zQv*Xo0|kws)D#7e#1g24uDK=y0}BHKg8~Bs11Lz{{X!X-7#I(L#9$^fLiw;XBm$LS ztO{aatPo(7=3(cUz{tQ*!@$5G1C^TsQtZel(9BfLC*i`U;K^s;!zU2L#mC{v9f>63 z$;HRv%k6?B;>X3u;mYmG#mC`{qSBp|o%8ej&T5CF4~G7Xr|z#s~y*%%=5U=Em&VqjnpLNXs5CeW}(R}0dh z#=wAK21p!~ys)WfNR3amXaW(`IMj*nN0W8drmY7tW!;o50kZTC0azKVL zFfcemX;2)qGcYjx`40iUNaCO{g^Bkei6g6@g(S|2WX>|EI1>W{12dBNL8v&oy=Rfc zk?rLJMH~YpeInZ{g(Qw_uL@Kg-CiRkagg0Ge`P_%L1M_}7eK|)&8dTmgVZD2+YJ>5 zsRyMRnE9YQ1@an59E3q^FxD%s%q>YwV$drtDT2@$Fji4&PNH5(YDEcyUP@v~B7^&&^HED`C*f%P&dQbN36?EiOq+&W7^S^Gfv!it-Cm zi%KdP^uUIvX2hozCFZ7rT|yB7@*l|S=s5yXmoPBE(mTu&^fW9Dja!&{m^uYe05dQ! zWPl83U|`^3U;yVLP}%^gkpK}43=E+B0#X7>V^AS5bp<2{W}y=3!a58L3?MVf)o%!O zmk_Eo3^4nl-hj)(_%PZIhyDjphl0Wvt{JIpfQ6$ERKEeTA`lyz*z`ecBn&kc9F`#A zP^f+o8yV|E^&^Xc*f9MdHVA`~5GdcED>r}&pt}nc)*yW_Tnn`ysvIWFkN_2!0T+QV z(Dhf~NIxB*Ovu2%081yJ^uq;>YmiAWagcwYR)K`!_y<(*15^Z5*@MzJ%zl`DP#J)p lc0gKQKn0CJ93%{~4~fel2rVCx#X#%@Q1`ckI7k>>KL7-Rp)~*i literal 0 HcmV?d00001 diff --git a/src/openlibm/ld80/e_expl.c b/src/openlibm/ld80/e_expl.c new file mode 100644 index 0000000..db0d1ca --- /dev/null +++ b/src/openlibm/ld80/e_expl.c @@ -0,0 +1,131 @@ +/* $OpenBSD: e_expl.c,v 1.3 2013/11/12 20:35:19 martynas Exp $ */ + +/* + * Copyright (c) 2008 Stephen L. Moshier + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* expl.c + * + * Exponential function, long double precision + * + * + * + * SYNOPSIS: + * + * long double x, y, expl(); + * + * y = expl( x ); + * + * + * + * DESCRIPTION: + * + * Returns e (2.71828...) raised to the x power. + * + * Range reduction is accomplished by separating the argument + * into an integer k and fraction f such that + * + * x k f + * e = 2 e. + * + * A Pade' form of degree 2/3 is used to approximate exp(f) - 1 + * in the basic range [-0.5 ln 2, 0.5 ln 2]. + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE +-10000 50000 1.12e-19 2.81e-20 + * + * + * Error amplification in the exponential function can be + * a serious matter. The error propagation involves + * exp( X(1+delta) ) = exp(X) ( 1 + X*delta + ... ), + * which shows that a 1 lsb error in representing X produces + * a relative error of X times 1 lsb in the function. + * While the routine gives an accurate result for arguments + * that are exactly represented by a long double precision + * computer number, the result contains amplified roundoff + * error for large arguments not exactly represented. + * + * + * ERROR MESSAGES: + * + * message condition value returned + * exp underflow x < MINLOG 0.0 + * exp overflow x > MAXLOG MAXNUM + * + */ + +/* Exponential function */ + +#include + +#include "math_private.h" + +static long double P[3] = { + 1.2617719307481059087798E-4L, + 3.0299440770744196129956E-2L, + 9.9999999999999999991025E-1L, +}; +static long double Q[4] = { + 3.0019850513866445504159E-6L, + 2.5244834034968410419224E-3L, + 2.2726554820815502876593E-1L, + 2.0000000000000000000897E0L, +}; +static const long double C1 = 6.9314575195312500000000E-1L; +static const long double C2 = 1.4286068203094172321215E-6L; +static const long double MAXLOGL = 1.1356523406294143949492E4L; +static const long double MINLOGL = -1.13994985314888605586758E4L; +static const long double LOG2EL = 1.4426950408889634073599E0L; + +long double +expl(long double x) +{ +long double px, xx; +int n; + +if( isnan(x) ) + return(x); +if( x > MAXLOGL) + return( INFINITY ); + +if( x < MINLOGL ) + return(0.0L); + +/* Express e**x = e**g 2**n + * = e**g e**( n loge(2) ) + * = e**( g + n loge(2) ) + */ +px = floorl( LOG2EL * x + 0.5L ); /* floor() truncates toward -infinity. */ +n = px; +x -= px * C1; +x -= px * C2; + + +/* rational approximation for exponential + * of the fractional part: + * e**x = 1 + 2x P(x**2)/( Q(x**2) - P(x**2) ) + */ +xx = x * x; +px = x * __polevll( xx, P, 2 ); +x = px/( __polevll( xx, Q, 3 ) - px ); +x = 1.0L + ldexpl( x, 1 ); + +x = ldexpl( x, n ); +return(x); +} diff --git a/src/openlibm/ld80/e_expl.c.o b/src/openlibm/ld80/e_expl.c.o new file mode 100644 index 0000000000000000000000000000000000000000..871b53a73f2952d58a82ededad1a6ff385814551 GIT binary patch literal 2688 zcmb<-^>JfjWMqH=Mg}_u1P><4z;J*K!FB*M9T@l-_!vBz-$dNbQAxOY;I@s*?HUz< z7a+;VxZ64^tq1s9Ss57^ZtH@CZl1jT@$OCj_Qwn`k^3L{+ut%UFx-6Q(fmf>-pL!R zAa%EGRKP}n#P%^UFfe%Z+JeMy9=O2^qHpJ@DBODpG4sZ$o2PEqs5snvc=N!GlQ&P^ zu2E5dIm7^L3P|-nW`rsCz-l6*K;kf)Zs({7fNa|j^7oyW_ddcTZq}&8-F$KH;O!h0 z2mb9YDsc^Gc+xsuRAO%CsKnfkQBk;=qY~F$qoQ!TMy0@``AEh~kOR~B_;+**3_jXgxb?*CTT6=w^VeuMHK&SSPe z;R*d*s4cec83-~QKN)eH;_?#|9u3L5Ty zp_&SYCVEDCh6+XoMy3Xah6V~6L8&PU9*HGT30-qd1_l-e1_lKN1_n@Ixch}NFflM5 z0EvOZ8e{__ln;s{5MKmDFfcGMRs}IIRtPXk^RRPFU}RvhVPIg8fy!BeG`sL61oK5W z@&y#~C4}%5Fh%lZI6_!Xd>r0<0X|%O94_20VA6w+1F98+0vW}^@bN!}1Oo#DGuE5{ z5{J1Kp^FRTW(H&24OJG#vlNu5rhPo$qEinFcV71 zf@xL;bPpvcrY+92qF0w9L5X`3_1)97;XV+GQ}YdiYIip zgVej>P|uJWpIT9nqnFGOz!1ow=i_VyB8)+VDTpuw5#}JmfFV9Uvp6p?FNYy5CqKU^ zhao<`AU`LyEGLH{Ck12($Q~gO!2n5jpz`7mB>DeWg^Ghp6i}$c#Lbb!*%=rZVB)?= z;-IjFiHAbPL1`EihcNL}s5r=cQ0f4M14t+rL@+QgfW$eG%&$Ze2c;dDIkTbSAoKZ= z)USq$gUkV$4^zJ%DvqxH29h`^K49u)KnWh|9&RM_`Jmz;bCA`8@-E0Iki8%bVuP_> zab<2vViJR1aY+$`&VaFsQgagZN>VFI81zySOA;CMl8TEN^osI99KGb?5))*Op&5f- za(-@ZYF-J0US57ls-C-FsBUpdVsbW=pPpB$S5TB+kXlqy$)E=|JT)Uettc@U7U*CH zkw<|12l6^7O(2^9Ee;uA`2Z#d3L6+3L`y@{8caP%41_O$0+NA&Apm4J0|Nu39AJRw zQ%HVhU{C{>51=vyqzi!?p!y0BLSPoiyPm>7tLdJA3-+2PO+PVfv2@Ny8O7ldKq2cvzU`eEfINDT-ZKogrjh=YV- z?uXH!{0L(sDPxF->PHp>vC-9nk`O50qbpB<3ZT0S6xJYfV7M0QeyDPoFvA3>Km=R_ z!a&zwfg}AWKocY^oq*y2R8GM3!^A=Ufm#Kz07|}q3eEs2U|?VXm4zTP(Dj4LB=occ oGNJ(*(Xet5BnHAz<3LO>76jLmU?vJ-0d;>niYNn84Fiz?08E#Wr~m)} literal 0 HcmV?d00001 diff --git a/src/openlibm/ld80/e_fmodl.c b/src/openlibm/ld80/e_fmodl.c new file mode 100644 index 0000000..ec792e3 --- /dev/null +++ b/src/openlibm/ld80/e_fmodl.c @@ -0,0 +1,142 @@ +/* @(#)e_fmod.c 1.3 95/01/18 */ +/*- + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include +//#include + +#include +#include +#include + +#include "math_private.h" + +#define BIAS (LDBL_MAX_EXP - 1) + +/* + * These macros add and remove an explicit integer bit in front of the + * fractional mantissa, if the architecture doesn't have such a bit by + * default already. + */ +#ifdef LDBL_IMPLICIT_NBIT +#define LDBL_NBIT 0 +#define SET_NBIT(hx) ((hx) | (1ULL << LDBL_MANH_SIZE)) +#define HFRAC_BITS EXT_FRACHBITS +#else +#define LDBL_NBIT 0x80000000 +#define SET_NBIT(hx) (hx) +#define HFRAC_BITS (EXT_FRACHBITS - 1) +#endif + +#define MANL_SHIFT (EXT_FRACLBITS - 1) + +static const long double one = 1.0, Zero[] = {0.0, -0.0,}; + +/* + * fmodl(x,y) + * Return x mod y in exact arithmetic + * Method: shift and subtract + * + * Assumptions: + * - The low part of the mantissa fits in a manl_t exactly. + * - The high part of the mantissa fits in an int64_t with enough room + * for an explicit integer bit in front of the fractional bits. + */ +long double +fmodl(long double x, long double y) +{ + union { + long double e; + struct ieee_ext bits; + } ux, uy; + int64_t hx,hz; /* We need a carry bit even if LDBL_MANH_SIZE is 32. */ + uint32_t hy; + uint32_t lx,ly,lz; + int ix,iy,n,sx; + + ux.e = x; + uy.e = y; + sx = ux.bits.ext_sign; + + /* purge off exception values */ + if((uy.bits.ext_exp|uy.bits.ext_frach|uy.bits.ext_fracl)==0 || /* y=0 */ + (ux.bits.ext_exp == BIAS + LDBL_MAX_EXP) || /* or x not finite */ + (uy.bits.ext_exp == BIAS + LDBL_MAX_EXP && + ((uy.bits.ext_frach&~LDBL_NBIT)|uy.bits.ext_fracl)!=0)) /* or y is NaN */ + return (x*y)/(x*y); + if(ux.bits.ext_exp<=uy.bits.ext_exp) { + if((ux.bits.ext_exp>MANL_SHIFT); lx = lx+lx;} + else { + if ((hz|lz)==0) /* return sign(x)*0 */ + return Zero[sx]; + hx = hz+hz+(lz>>MANL_SHIFT); lx = lz+lz; + } + } + hz=hx-hy;lz=lx-ly; if(lx=0) {hx=hz;lx=lz;} + + /* convert back to floating value and restore the sign */ + if((hx|lx)==0) /* return sign(x)*0 */ + return Zero[sx]; + while(hx<(1ULL<>MANL_SHIFT); lx = lx+lx; + iy -= 1; + } + ux.bits.ext_frach = hx; /* The mantissa is truncated here if needed. */ + ux.bits.ext_fracl = lx; + if (iy < LDBL_MIN_EXP) { + ux.bits.ext_exp = iy + (BIAS + 512); + ux.e *= 0x1p-512; + } else { + ux.bits.ext_exp = iy + BIAS; + } + x = ux.e * one; /* create necessary signal */ + return x; /* exact output */ +} diff --git a/src/openlibm/ld80/e_hypotl.c b/src/openlibm/ld80/e_hypotl.c new file mode 100644 index 0000000..e6faa22 --- /dev/null +++ b/src/openlibm/ld80/e_hypotl.c @@ -0,0 +1,122 @@ +/* @(#)e_hypot.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* hypotl(x,y) + * + * Method : + * If (assume round-to-nearest) z=x*x+y*y + * has error less than sqrt(2)/2 ulp, than + * sqrt(z) has error less than 1 ulp (exercise). + * + * So, compute sqrt(x*x+y*y) with some care as + * follows to get the error below 1 ulp: + * + * Assume x>y>0; + * (if possible, set rounding to round-to-nearest) + * 1. if x > 2y use + * x1*x1+(y*y+(x2*(x+x1))) for x*x+y*y + * where x1 = x with lower 32 bits cleared, x2 = x-x1; else + * 2. if x <= 2y use + * t1*yy1+((x-y)*(x-y)+(t1*y2+t2*y)) + * where t1 = 2x with lower 32 bits cleared, t2 = 2x-t1, + * yy1= y with lower 32 bits chopped, y2 = y-yy1. + * + * NOTE: scaling may be necessary if some argument is too + * large or too tiny + * + * Special cases: + * hypot(x,y) is INF if x or y is +INF or -INF; else + * hypot(x,y) is NAN if x or y is NAN. + * + * Accuracy: + * hypot(x,y) returns sqrt(x^2+y^2) with error less + * than 1 ulps (units in the last place) + */ + +#include + +#include "math_private.h" + +long double +hypotl(long double x, long double y) +{ + long double a,b,t1,t2,yy1,y2,w; + u_int32_t j,k,ea,eb; + + GET_LDOUBLE_EXP(ea,x); + ea &= 0x7fff; + GET_LDOUBLE_EXP(eb,y); + eb &= 0x7fff; + if(eb > ea) {a=y;b=x;j=ea; ea=eb;eb=j;} else {a=x;b=y;} + SET_LDOUBLE_EXP(a,ea); /* a <- |a| */ + SET_LDOUBLE_EXP(b,eb); /* b <- |b| */ + if((ea-eb)>0x46) {return a+b;} /* x/y > 2**70 */ + k=0; + if(ea > 0x5f3f) { /* a>2**8000 */ + if(ea == 0x7fff) { /* Inf or NaN */ + u_int32_t es,high,low; + w = a+b; /* for sNaN */ + GET_LDOUBLE_WORDS(es,high,low,a); + if(((high&0x7fffffff)|low)==0) w = a; + GET_LDOUBLE_WORDS(es,high,low,b); + if(((eb^0x7fff)|(high&0x7fffffff)|low)==0) w = b; + return w; + } + /* scale a and b by 2**-9600 */ + ea -= 0x2580; eb -= 0x2580; k += 9600; + SET_LDOUBLE_EXP(a,ea); + SET_LDOUBLE_EXP(b,eb); + } + if(eb < 0x20bf) { /* b < 2**-8000 */ + if(eb == 0) { /* subnormal b or 0 */ + u_int32_t es,high,low; + GET_LDOUBLE_WORDS(es,high,low,b); + if((high|low)==0) return a; + SET_LDOUBLE_WORDS(t1, 0x7ffd, 0, 0); /* t1=2^16382 */ + b *= t1; + a *= t1; + k -= 16382; + } else { /* scale a and b by 2^9600 */ + ea += 0x2580; /* a *= 2^9600 */ + eb += 0x2580; /* b *= 2^9600 */ + k -= 9600; + SET_LDOUBLE_EXP(a,ea); + SET_LDOUBLE_EXP(b,eb); + } + } + /* medium size a and b */ + w = a-b; + if (w>b) { + u_int32_t high; + GET_LDOUBLE_MSW(high,a); + SET_LDOUBLE_WORDS(t1,ea,high,0); + t2 = a-t1; + w = sqrtl(t1*t1-(b*(-b)-t2*(a+t1))); + } else { + u_int32_t high; + GET_LDOUBLE_MSW(high,b); + a = a+a; + SET_LDOUBLE_WORDS(yy1,eb,high,0); + y2 = b - yy1; + GET_LDOUBLE_MSW(high,a); + SET_LDOUBLE_WORDS(t1,ea+1,high,0); + t2 = a - t1; + w = sqrtl(t1*yy1-(w*(-w)-(t1*y2+t2*b))); + } + if(k!=0) { + u_int32_t es; + t1 = 1.0; + GET_LDOUBLE_EXP(es,t1); + SET_LDOUBLE_EXP(t1,es+k); + return t1*w; + } else return w; +} diff --git a/src/openlibm/ld80/e_lgammal_r.c b/src/openlibm/ld80/e_lgammal_r.c new file mode 100644 index 0000000..0af5420 --- /dev/null +++ b/src/openlibm/ld80/e_lgammal_r.c @@ -0,0 +1,425 @@ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * Copyright (c) 2008 Stephen L. Moshier + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* lgammal_r(x, signgamp) + * Reentrant version of the logarithm of the Gamma function + * with user provide pointer for the sign of Gamma(x). + * + * Method: + * 1. Argument Reduction for 0 < x <= 8 + * Since gamma(1+s)=s*gamma(s), for x in [0,8], we may + * reduce x to a number in [1.5,2.5] by + * lgamma(1+s) = log(s) + lgamma(s) + * for example, + * lgamma(7.3) = log(6.3) + lgamma(6.3) + * = log(6.3*5.3) + lgamma(5.3) + * = log(6.3*5.3*4.3*3.3*2.3) + lgamma(2.3) + * 2. Polynomial approximation of lgamma around its + * minimun ymin=1.461632144968362245 to maintain monotonicity. + * On [ymin-0.23, ymin+0.27] (i.e., [1.23164,1.73163]), use + * Let z = x-ymin; + * lgamma(x) = -1.214862905358496078218 + z^2*poly(z) + * 2. Rational approximation in the primary interval [2,3] + * We use the following approximation: + * s = x-2.0; + * lgamma(x) = 0.5*s + s*P(s)/Q(s) + * Our algorithms are based on the following observation + * + * zeta(2)-1 2 zeta(3)-1 3 + * lgamma(2+s) = s*(1-Euler) + --------- * s - --------- * s + ... + * 2 3 + * + * where Euler = 0.5771... is the Euler constant, which is very + * close to 0.5. + * + * 3. For x>=8, we have + * lgamma(x)~(x-0.5)log(x)-x+0.5*log(2pi)+1/(12x)-1/(360x**3)+.... + * (better formula: + * lgamma(x)~(x-0.5)*(log(x)-1)-.5*(log(2pi)-1) + ...) + * Let z = 1/x, then we approximation + * f(z) = lgamma(x) - (x-0.5)(log(x)-1) + * by + * 3 5 11 + * w = w0 + w1*z + w2*z + w3*z + ... + w6*z + * + * 4. For negative x, since (G is gamma function) + * -x*G(-x)*G(x) = pi/sin(pi*x), + * we have + * G(x) = pi/(sin(pi*x)*(-x)*G(-x)) + * since G(-x) is positive, sign(G(x)) = sign(sin(pi*x)) for x<0 + * Hence, for x<0, signgam = sign(sin(pi*x)) and + * lgamma(x) = log(|Gamma(x)|) + * = log(pi/(|x*sin(pi*x)|)) - lgamma(-x); + * Note: one should avoid compute pi*(-x) directly in the + * computation of sin(pi*(-x)). + * + * 5. Special Cases + * lgamma(2+s) ~ s*(1-Euler) for tiny s + * lgamma(1)=lgamma(2)=0 + * lgamma(x) ~ -log(x) for tiny x + * lgamma(0) = lgamma(inf) = inf + * lgamma(-integer) = +-inf + * + */ + +#include + +#include "math_private.h" + +static const long double + half = 0.5L, + one = 1.0L, + pi = 3.14159265358979323846264L, + two63 = 9.223372036854775808e18L, + + /* lgam(1+x) = 0.5 x + x a(x)/b(x) + -0.268402099609375 <= x <= 0 + peak relative error 6.6e-22 */ + a0 = -6.343246574721079391729402781192128239938E2L, + a1 = 1.856560238672465796768677717168371401378E3L, + a2 = 2.404733102163746263689288466865843408429E3L, + a3 = 8.804188795790383497379532868917517596322E2L, + a4 = 1.135361354097447729740103745999661157426E2L, + a5 = 3.766956539107615557608581581190400021285E0L, + + b0 = 8.214973713960928795704317259806842490498E3L, + b1 = 1.026343508841367384879065363925870888012E4L, + b2 = 4.553337477045763320522762343132210919277E3L, + b3 = 8.506975785032585797446253359230031874803E2L, + b4 = 6.042447899703295436820744186992189445813E1L, + /* b5 = 1.000000000000000000000000000000000000000E0 */ + + + tc = 1.4616321449683623412626595423257213284682E0L, + tf = -1.2148629053584961146050602565082954242826E-1,/* double precision */ +/* tt = (tail of tf), i.e. tf + tt has extended precision. */ + tt = 3.3649914684731379602768989080467587736363E-18L, + /* lgam ( 1.4616321449683623412626595423257213284682E0 ) = +-1.2148629053584960809551455717769158215135617312999903886372437313313530E-1 */ + + /* lgam (x + tc) = tf + tt + x g(x)/h(x) + - 0.230003726999612341262659542325721328468 <= x + <= 0.2699962730003876587373404576742786715318 + peak relative error 2.1e-21 */ + g0 = 3.645529916721223331888305293534095553827E-18L, + g1 = 5.126654642791082497002594216163574795690E3L, + g2 = 8.828603575854624811911631336122070070327E3L, + g3 = 5.464186426932117031234820886525701595203E3L, + g4 = 1.455427403530884193180776558102868592293E3L, + g5 = 1.541735456969245924860307497029155838446E2L, + g6 = 4.335498275274822298341872707453445815118E0L, + + h0 = 1.059584930106085509696730443974495979641E4L, + h1 = 2.147921653490043010629481226937850618860E4L, + h2 = 1.643014770044524804175197151958100656728E4L, + h3 = 5.869021995186925517228323497501767586078E3L, + h4 = 9.764244777714344488787381271643502742293E2L, + h5 = 6.442485441570592541741092969581997002349E1L, + /* h6 = 1.000000000000000000000000000000000000000E0 */ + + + /* lgam (x+1) = -0.5 x + x u(x)/v(x) + -0.100006103515625 <= x <= 0.231639862060546875 + peak relative error 1.3e-21 */ + u0 = -8.886217500092090678492242071879342025627E1L, + u1 = 6.840109978129177639438792958320783599310E2L, + u2 = 2.042626104514127267855588786511809932433E3L, + u3 = 1.911723903442667422201651063009856064275E3L, + u4 = 7.447065275665887457628865263491667767695E2L, + u5 = 1.132256494121790736268471016493103952637E2L, + u6 = 4.484398885516614191003094714505960972894E0L, + + v0 = 1.150830924194461522996462401210374632929E3L, + v1 = 3.399692260848747447377972081399737098610E3L, + v2 = 3.786631705644460255229513563657226008015E3L, + v3 = 1.966450123004478374557778781564114347876E3L, + v4 = 4.741359068914069299837355438370682773122E2L, + v5 = 4.508989649747184050907206782117647852364E1L, + /* v6 = 1.000000000000000000000000000000000000000E0 */ + + + /* lgam (x+2) = .5 x + x s(x)/r(x) + 0 <= x <= 1 + peak relative error 7.2e-22 */ + s0 = 1.454726263410661942989109455292824853344E6L, + s1 = -3.901428390086348447890408306153378922752E6L, + s2 = -6.573568698209374121847873064292963089438E6L, + s3 = -3.319055881485044417245964508099095984643E6L, + s4 = -7.094891568758439227560184618114707107977E5L, + s5 = -6.263426646464505837422314539808112478303E4L, + s6 = -1.684926520999477529949915657519454051529E3L, + + r0 = -1.883978160734303518163008696712983134698E7L, + r1 = -2.815206082812062064902202753264922306830E7L, + r2 = -1.600245495251915899081846093343626358398E7L, + r3 = -4.310526301881305003489257052083370058799E6L, + r4 = -5.563807682263923279438235987186184968542E5L, + r5 = -3.027734654434169996032905158145259713083E4L, + r6 = -4.501995652861105629217250715790764371267E2L, + /* r6 = 1.000000000000000000000000000000000000000E0 */ + + +/* lgam(x) = ( x - 0.5 ) * log(x) - x + LS2PI + 1/x w(1/x^2) + x >= 8 + Peak relative error 1.51e-21 + w0 = LS2PI - 0.5 */ + w0 = 4.189385332046727417803e-1L, + w1 = 8.333333333333331447505E-2L, + w2 = -2.777777777750349603440E-3L, + w3 = 7.936507795855070755671E-4L, + w4 = -5.952345851765688514613E-4L, + w5 = 8.412723297322498080632E-4L, + w6 = -1.880801938119376907179E-3L, + w7 = 4.885026142432270781165E-3L; + +static const long double zero = 0.0L; + +static long double +sin_pi(long double x) +{ + long double y, z; + int n, ix; + u_int32_t se, i0, i1; + + GET_LDOUBLE_WORDS (se, i0, i1, x); + ix = se & 0x7fff; + ix = (ix << 16) | (i0 >> 16); + if (ix < 0x3ffd8000) /* 0.25 */ + return sinl (pi * x); + y = -x; /* x is assume negative */ + + /* + * argument reduction, make sure inexact flag not raised if input + * is an integer + */ + z = floorl (y); + if (z != y) + { /* inexact anyway */ + y *= 0.5; + y = 2.0*(y - floorl(y)); /* y = |x| mod 2.0 */ + n = (int) (y*4.0); + } + else + { + if (ix >= 0x403f8000) /* 2^64 */ + { + y = zero; n = 0; /* y must be even */ + } + else + { + if (ix < 0x403e8000) /* 2^63 */ + z = y + two63; /* exact */ + GET_LDOUBLE_WORDS (se, i0, i1, z); + n = i1 & 1; + y = n; + n <<= 2; + } + } + + switch (n) + { + case 0: + y = sinl (pi * y); + break; + case 1: + case 2: + y = cosl (pi * (half - y)); + break; + case 3: + case 4: + y = sinl (pi * (one - y)); + break; + case 5: + case 6: + y = -cosl (pi * (y - 1.5)); + break; + default: + y = sinl (pi * (y - 2.0)); + break; + } + return -y; +} + + +long double +lgammal_r(long double x, int *signgamp) +{ + long double t, y, z, nadj, p, p1, p2, q, r, w; + int i, ix; + u_int32_t se, i0, i1; + + *signgamp = 1; + GET_LDOUBLE_WORDS (se, i0, i1, x); + ix = se & 0x7fff; + + if ((ix | i0 | i1) == 0) + { + if (se & 0x8000) + *signgamp = -1; + return one / fabsl (x); + } + + ix = (ix << 16) | (i0 >> 16); + + /* purge off +-inf, NaN, +-0, and negative arguments */ + if (ix >= 0x7fff0000) + return x * x; + + if (ix < 0x3fc08000) /* 2^-63 */ + { /* |x|<2**-63, return -log(|x|) */ + if (se & 0x8000) + { + *signgamp = -1; + return -logl (-x); + } + else + return -logl (x); + } + if (se & 0x8000) + { + t = sin_pi (x); + if (t == zero) + return one / fabsl (t); /* -integer */ + nadj = logl (pi / fabsl (t * x)); + if (t < zero) + *signgamp = -1; + x = -x; + } + + /* purge off 1 and 2 */ + if ((((ix - 0x3fff8000) | i0 | i1) == 0) + || (((ix - 0x40008000) | i0 | i1) == 0)) + r = 0; + else if (ix < 0x40008000) /* 2.0 */ + { + /* x < 2.0 */ + if (ix <= 0x3ffee666) /* 8.99993896484375e-1 */ + { + /* lgamma(x) = lgamma(x+1) - log(x) */ + r = -logl (x); + if (ix >= 0x3ffebb4a) /* 7.31597900390625e-1 */ + { + y = x - one; + i = 0; + } + else if (ix >= 0x3ffced33)/* 2.31639862060546875e-1 */ + { + y = x - (tc - one); + i = 1; + } + else + { + /* x < 0.23 */ + y = x; + i = 2; + } + } + else + { + r = zero; + if (ix >= 0x3fffdda6) /* 1.73162841796875 */ + { + /* [1.7316,2] */ + y = x - 2.0; + i = 0; + } + else if (ix >= 0x3fff9da6)/* 1.23162841796875 */ + { + /* [1.23,1.73] */ + y = x - tc; + i = 1; + } + else + { + /* [0.9, 1.23] */ + y = x - one; + i = 2; + } + } + switch (i) + { + case 0: + p1 = a0 + y * (a1 + y * (a2 + y * (a3 + y * (a4 + y * a5)))); + p2 = b0 + y * (b1 + y * (b2 + y * (b3 + y * (b4 + y)))); + r += half * y + y * p1/p2; + break; + case 1: + p1 = g0 + y * (g1 + y * (g2 + y * (g3 + y * (g4 + y * (g5 + y * g6))))); + p2 = h0 + y * (h1 + y * (h2 + y * (h3 + y * (h4 + y * (h5 + y))))); + p = tt + y * p1/p2; + r += (tf + p); + break; + case 2: + p1 = y * (u0 + y * (u1 + y * (u2 + y * (u3 + y * (u4 + y * (u5 + y * u6)))))); + p2 = v0 + y * (v1 + y * (v2 + y * (v3 + y * (v4 + y * (v5 + y))))); + r += (-half * y + p1 / p2); + } + } + else if (ix < 0x40028000) /* 8.0 */ + { + /* x < 8.0 */ + i = (int) x; + t = zero; + y = x - (double) i; + p = y * + (s0 + y * (s1 + y * (s2 + y * (s3 + y * (s4 + y * (s5 + y * s6)))))); + q = r0 + y * (r1 + y * (r2 + y * (r3 + y * (r4 + y * (r5 + y * (r6 + y)))))); + r = half * y + p / q; + z = one; /* lgamma(1+s) = log(s) + lgamma(s) */ + switch (i) + { + case 7: + z *= (y + 6.0); /* FALLTHRU */ + case 6: + z *= (y + 5.0); /* FALLTHRU */ + case 5: + z *= (y + 4.0); /* FALLTHRU */ + case 4: + z *= (y + 3.0); /* FALLTHRU */ + case 3: + z *= (y + 2.0); /* FALLTHRU */ + r += logl (z); + break; + } + } + else if (ix < 0x40418000) /* 2^66 */ + { + /* 8.0 <= x < 2**66 */ + t = logl (x); + z = one / x; + y = z * z; + w = w0 + z * (w1 + + y * (w2 + y * (w3 + y * (w4 + y * (w5 + y * (w6 + y * w7)))))); + r = (x - half) * (t - one) + w; + } + else + /* 2**66 <= x <= inf */ + r = x * (logl (x) - one); + if (se & 0x8000) + r = nadj - r; + return r; +} diff --git a/src/openlibm/ld80/e_lgammal_r.c.o b/src/openlibm/ld80/e_lgammal_r.c.o new file mode 100644 index 0000000000000000000000000000000000000000..dbe9fed0a5a7a29a0f4bfef4251758864a3a0eeb GIT binary patch literal 10040 zcmb<-^>JfjWMqH=Mg}_u1P><4z_3FJ!FB*M9TJCjbe?eOeB^QPg+k+_|Md(EoCiCvah@xQKKMxB;0uAy%bbTBfB*mgufE){ z@%R7w1NP;GcW;1ZLsU3|0>Ggi?-+6O!OI2z{{O#w z1LXI=_WW%@j1WJ1bk?XCcr?Ee==4#sxcT7bf!j7Jw`)`sz#4BJxLuI{L~HY#B2;~gWqc~n4l3fz2f z^WDvpAe*b$_*+DoAdc_!Q2}cL>9)9W^5#j9b78tcrrmsf?<0bLM4{V9Mc}rM%FTE8 zKi<7j#tkxB0}^hC^iuKn|9=n4h%P6gPa0()9oCU0+9ReorF0cA`0f4m-_!f#yEgeB9jAudkP~1!_68MJCIHM z+g()b8qV;fb-Jk7+&pkIN5$s0jLOX%6}#IkD%~t9%`cemy@VvE8z&+3y_Y1j4#ITY zcm+$Q_uvVZc-Fn2HxEJ+?7`+AEd1?WfB*mY=oJMeN{?igCJ)97{~z3Zar4j(aLID- zBv#gGP`rWS3q-?I!h#Ky_Tn8Q?i~a%Zk~Mkp0Z2sL%u(^V9it*} zGe^a*+eJkHl0+OMn}4u4Mu9Q_IMws_O=kpU-R2jp%|96V+annn7$A-W*$z&@pwtV> zo3Mz8jDx4&{6GKyH~wBa7gSodfJzcbM$b`6xc89k@)AqANuy@M|g|N8&`wv7s?0s>)hNH+fV-2KlUT#r1st)s%<77xmWpi}_z#mSqeUNZms z{~x3rguz;FzPR@i6rT}M_fA4$FzXknRK58E9%}av+n(Zq{({+?;U(;{}YsGjNbmS=WmPu|NlQE znn2FG_wXhtxR3n(|NrjIm*2nt{|_oZuw#1$h6YfRC7yxdfIR~P1Bkt!f#HAy1H%Fb z1_lQQ28ILmFs(=49>1Q&6aD5dNF@UUL*eg_Tcr+*?fwttuZenP_3(n|N3baj3=BV( zYpR7e2t8&6naaSxV6oKN`^`D2I~-8H;hK4&CwF;I_4t^{2Ncddy$7=_3nN{=kh2KZT`huE6AF7lmr6Z}#frhRSoN=v{2z8@qr9%2!J{ z?kf5;x&g+YzB`ZgVcMQ9MyR}v$nqt%xjM7hpnTqMS=wG}-)@Du$Jxsz{cP>QRWS2i zg+HF;&-&B}Gp|)#C}yjT=>nL10=tQ34PSlRQE2!Scyi8aX}j3~3y)RmJr|Z}Nq>R4 ze~T>31#aDp?J)gU9(SkA_l{}cg}SG3%Jh|Y^Uf`Y@z)0>>#k4jUkbDT1ee)bwWNy~KF{k|G}q zykIkTS@nevYW|Z=b`zR}%-0G*`TM>xFKM%%a!LfsxB9-RI+bzG2~jBj?3U9-{TJom z!Q{70<|&spnzB(CD$m=v@Jm#;+qhPlKbr$+?}1R6g1rZLNyf(P4tZP z3>AzFj7$v-4Gk1Df>KiyJQ7Qw61wJ^3=Av`3=9ek3=E(~io0JZ0}}(|0gxD|0|c^z z5z1!84?D*MMh1pI3=9l1P`OSH1_lNXK7k%4M?Q&WW*5E$ zrXaoy7rp{Fz6?jc1Q#wo31>b5Cq52WZXYf_2}dy7lN+MOoiD?QFToA2#*LdvhSbL}p49wuzKsAgX%w=a#0n-Qq+}>nhXAnRLfmu>uk^>yK zU?!9R#We#12ZI5W52Mt;3=UXz0Oo-R9T365!4LqZ5rh$#$-$5SrV)e%n90FV0HzUy z9hk|%0PeJb*$~17OmQ$w0MiJ<3(VwTSOBIG1jHR23>y$aU{)BI|hd^NCb1(89+%D%!CqYV48!WfeFlj6FFcO2g3w3@gk`B0yOaosQ3mn@j9sZ0W@() zE1iSk0-AUiRQ&@qaY%S^FnmB0p9WRW0L!poJ_ExXFwMarfF`~ODz1Pgz5*(4fF`~U zD(-+Lz6B~CfF`~REY1!u8^Bx!253C7gUcV77>GU!A{f{)((P%exCEF+5EsEr4u%9Y zd#^*q3(&;xLd6@<#2-V&C!mSHgo-af6MqjC-+(6m6)JuJP5d`h`~sRdWXOtx;Q^XB zJE-7bU}xX~>q8JcU~vwN{4NL;zkpB*W{E?^AAorXLKZ6i0U-otDMQ84izZE|xB!?2 zD+Lq!U_J+f0+OU>YIb4CZq%d;rr3@lG(G zgMk4pzxPAM1<=H&Ld6x(#Aidr4ba3FLd6}>#FsF` z5NQO~3sw$RXA0(OrI8ATNOI z1=Tq)@falapy7F#cp8#8ACmd7@)%?esLcvfUxlO|l<#2TZAjvRNakFEii5%)Ih?sc z21CO?5J`O?R2)PJA&GZ^1fc4Jki<_Qi6h6?4J2`7dn2LsGsr#2=B$Q_gR}`FnZFrH z9Morm`FAgpIH>Io6F-h5E{0^zMI>=?B=Orw;-EGW%$%o4;*v<}-y?~G`UWudKas?x zk<>GTJjwt`pP+snOg%4>xGa)-aU^j$BymL~ad{+hZ6t9}p9E&UIg&VXdhkRN2RRw0 zJ_bo#5y|{CByrG`A547#lDIOG`ZgqSg<_IB)gZgGLaTz3WbtLzzA&F}si5nn^Ya)qTA&F}tiMt?) zYa@yKA&G~+P44^_28g6<> z?v#XzgUk;`61ReigUr`Q68At72la_z<_92&8zQNXLJ|k{fnn-Xki?CV)aN0In;?l- zAc>nIi8mpMn<0t!Ac>nJiBCfk2lc&S?pc5&Zi%FR6_U6WlK2)Racd;;eMsUqNa81u z#BGtpFCmG8`us5Wyo8E_;srVV%YZ65Ecqf5Dh`S-P!fQdQv?+UnS)#oZ$=VFj`s^t zagaHnp)!~`caX$ELwqptXGr3XNdEeOB<_SH{tHRm8A+T4R7peACuocVW*p3 z2EF2vA_$!UV-=<5B#hz-J^Iv*62F!dlY5Dow}Di|0T3_y)a1_lOD zTMlFoEZ(5f44}FRBo3;RLHc0$BupVp07`?@LYZI+RF{C1lB*w7MuN-)r6I6^P~r^8 zP^9r{s4&KO6R2#*=KlszV}gN!0WyvU@js{>f*Q*J^FOGJ1KAI1bHeNZ(GQ>sL3J^R z55pk4Kx`Nd%5&KC3qZsD16shq;txhgGBAL9$>{bofEw!zppgxbZ3ql?7JS?jG~Nla zA5`}tR537cK=p&_N@Q`6S`Z&b=R@rWi6LWisD5NI5F4fs#0Fu|ge9m5MUOuVsD2E0 zfixlE=}`O8^=Cl!!}?h;EinJX_>-Vz6ngsq0gZoHJcH6d$Vixem^jEk=yrq5ZUA+P z7#J8HfIP + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* log10l.c + * + * Common logarithm, long double precision + * + * + * + * SYNOPSIS: + * + * long double x, y, log10l(); + * + * y = log10l( x ); + * + * + * + * DESCRIPTION: + * + * Returns the base 10 logarithm of x. + * + * The argument is separated into its exponent and fractional + * parts. If the exponent is between -1 and +1, the logarithm + * of the fraction is approximated by + * + * log(1+x) = x - 0.5 x**2 + x**3 P(x)/Q(x). + * + * Otherwise, setting z = 2(x-1)/x+1), + * + * log(x) = z + z**3 P(z)/Q(z). + * + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE 0.5, 2.0 30000 9.0e-20 2.6e-20 + * IEEE exp(+-10000) 30000 6.0e-20 2.3e-20 + * + * In the tests over the interval exp(+-10000), the logarithms + * of the random arguments were uniformly distributed over + * [-10000, +10000]. + * + * ERROR MESSAGES: + * + * log singularity: x = 0; returns MINLOG + * log domain: x < 0; returns MINLOG + */ + +#include + +#include "math_private.h" + +/* Coefficients for log(1+x) = x - x**2/2 + x**3 P(x)/Q(x) + * 1/sqrt(2) <= x < sqrt(2) + * Theoretical peak relative error = 6.2e-22 + */ +static long double P[] = { + 4.9962495940332550844739E-1L, + 1.0767376367209449010438E1L, + 7.7671073698359539859595E1L, + 2.5620629828144409632571E2L, + 4.2401812743503691187826E2L, + 3.4258224542413922935104E2L, + 1.0747524399916215149070E2L, +}; +static long double Q[] = { +/* 1.0000000000000000000000E0,*/ + 2.3479774160285863271658E1L, + 1.9444210022760132894510E2L, + 7.7952888181207260646090E2L, + 1.6911722418503949084863E3L, + 2.0307734695595183428202E3L, + 1.2695660352705325274404E3L, + 3.2242573199748645407652E2L, +}; + +/* Coefficients for log(x) = z + z^3 P(z^2)/Q(z^2), + * where z = 2(x-1)/(x+1) + * 1/sqrt(2) <= x < sqrt(2) + * Theoretical peak relative error = 6.16e-22 + */ + +static long double R[4] = { + 1.9757429581415468984296E-3L, +-7.1990767473014147232598E-1L, + 1.0777257190312272158094E1L, +-3.5717684488096787370998E1L, +}; +static long double S[4] = { +/* 1.00000000000000000000E0L,*/ +-2.6201045551331104417768E1L, + 1.9361891836232102174846E2L, +-4.2861221385716144629696E2L, +}; +/* log10(2) */ +#define L102A 0.3125L +#define L102B -1.1470004336018804786261e-2L +/* log10(e) */ +#define L10EA 0.5L +#define L10EB -6.5705518096748172348871e-2L + +#define SQRTH 0.70710678118654752440L + +long double +log10l(long double x) +{ +long double y; +volatile long double z; +int e; + +if( isnan(x) ) + return(x); +/* Test for domain */ +if( x <= 0.0L ) + { + if( x == 0.0L ) + return (-1.0L / (x - x)); + else + return (x - x) / (x - x); + } +if( x == INFINITY ) + return(INFINITY); +/* separate mantissa from exponent */ + +/* Note, frexp is used so that denormal numbers + * will be handled properly. + */ +x = frexpl( x, &e ); + + +/* logarithm using log(x) = z + z**3 P(z)/Q(z), + * where z = 2(x-1)/x+1) + */ +if( (e > 2) || (e < -2) ) +{ +if( x < SQRTH ) + { /* 2( 2x-1 )/( 2x+1 ) */ + e -= 1; + z = x - 0.5L; + y = 0.5L * z + 0.5L; + } +else + { /* 2 (x-1)/(x+1) */ + z = x - 0.5L; + z -= 0.5L; + y = 0.5L * x + 0.5L; + } +x = z / y; +z = x*x; +y = x * ( z * __polevll( z, R, 3 ) / __p1evll( z, S, 3 ) ); +goto done; +} + + +/* logarithm using log(1+x) = x - .5x**2 + x**3 P(x)/Q(x) */ + +if( x < SQRTH ) + { + e -= 1; + x = ldexpl( x, 1 ) - 1.0L; /* 2x - 1 */ + } +else + { + x = x - 1.0L; + } +z = x*x; +y = x * ( z * __polevll( x, P, 6 ) / __p1evll( x, Q, 7 ) ); +y = y - ldexpl( z, -1 ); /* -0.5x^2 + ... */ + +done: + +/* Multiply log of fraction by log10(e) + * and base 2 exponent by log10(2). + * + * ***CAUTION*** + * + * This sequence of operations is critical and it may + * be horribly defeated by some compiler optimizers. + */ +z = y * (L10EB); +z += x * (L10EB); +z += e * (L102B); +z += y * (L10EA); +z += x * (L10EA); +z += e * (L102A); + +return( z ); +} diff --git a/src/openlibm/ld80/e_log10l.c.o b/src/openlibm/ld80/e_log10l.c.o new file mode 100644 index 0000000000000000000000000000000000000000..33d679bbd1507e0de371d4f22f4022685cb2ddf7 GIT binary patch literal 3576 zcmb<-^>JfjWMqH=Mg}_u1P><4z+l0JU^{@B4h;MZd<-7VZ!&J@s1)3`QF#Fpc8rd? zouiV_dZ1L|=DXV;i{gNYTv)_dXuxmu~P3=9l6PI~m(g5+=4s07?RaN9=Zc8!Vv z*wMFhR06>2*cliYpsMbjyj`PWa63mu0j5>~rq*Ep|NsC0-}?xXyaQ2IqoM%vc0?4+ zdAD;^1R~?^J%o53#Dh5Q=HVM49S*m1R2*)eym9K@!P_+|4!2!YY(OFqHE>aonlm>} z-#c>iG*}ggfASto514m@7vv?VDLE<*pm00PFVAq}1DG`dV*kwpHxJ!-1Tp>o7ykA> z1_lP0i8mgCSa(j{J9INfMF->xa8NKK1;xjk2X36a339grDDXhRh2&32&>^dbsLWAG zKvJau4le_b<|7JsPTq7;(Ybl@<;#En|3l;V?(Lf=Z=M3V1muF|7mS@QDmFJx-aB~n zpj*WYGo{u(Bzc}AU&x2$_{ua5<4o|V4Z{;QL(?Pi9`pAeQ}uGTF)1hapx%VbI8 zn-33hK;=`T{lXcWQ!jHu`LW9`Svw!N@fXHdw0`yftIVc(Fn&x3$MvK-vxV$X^$=Gf z$fAEr=XPE{_x~@{{T16y_zHF0;qL8z6?pu|wD8%iQ2p!wF=hQumui5S7nL3K>3<;8 z6&U}VW!Zd|cCXbizNIvGiC*yMYcTx`3=Q=R3=H-R3=8Z)u4qZQ_tW?@%hrET`&V1W zDM!zp(DoY|e(!h~+Y;8l+5H2`XK;6Rwo=e=_Y2ijFf`FK(lb;rGB7eVFf=q!&;8Cj51r%67zBx(uz_m3UV0Y z;|ub0Qp<9{EJH9OCj~46@&-7bK@3n@=VxGG_yekv{{R243KC>sU;rgyP*}mlOQGT* z^`J0^iT6XrLFze?%vp~l4oYQzp!|bS8f1 z6C^H-WR4P49Aplt$pKTZgCx$4q&@&i9F+E9>YI?nK~*G7d=Zj3via+f#F4|{0g^b# zUp7$x{DF#t+>aa%0w9M&!ylv`X0H-d9HbsO99odXk;4I0rh%*iNrNzm4aR!KmANH} zNep_$B}EWA1I8*!%}LZNNv$Yh&`U`yNo3GVDlTTwE6N9P^pcB9OprN-W(<1C`MJ5N zc_j>bdHE%&dhULqy2T}l$=OhTdS0nsK~a7|YEelggC5xM)QtGFqQu-(uuCW+K>h;- zA$o}cD}P}57-k75&BE9qTABe;_QTYJ#6Wlls0qiwzyOOkP?`YQ1Ih~^c?l4~z`&pe zF5f_9C{zGSJ%9#w0Z0>63`Bw43!-6Ihk*fH7J=dzCI+GdKoJaLpkXxQ7!0BIgVF-B zQkZ^_yOG6V#=>Y&eolp53&m+1fxTt`axpI zct2D>vKWXB(+6UMFenLuq6!+^AR#aYSKbT^4CwBH#UEG^0|P@X)P8jRAE5Tb>N%Kt zbo~`L($5S~=4W7FfTa^qJb=mxn0}Zz$Uo?IgX}7RR*kUq2P%6&buYSpkTvLO2c$m$ l6etV~49Or45(e3a#AN`LIoR}X02$1{z|fAY7#dc{LI7Q?tE>P3 literal 0 HcmV?d00001 diff --git a/src/openlibm/ld80/e_log2l.c b/src/openlibm/ld80/e_log2l.c new file mode 100644 index 0000000..6ff6fe9 --- /dev/null +++ b/src/openlibm/ld80/e_log2l.c @@ -0,0 +1,199 @@ +/* $OpenBSD: e_log2l.c,v 1.2 2013/11/12 20:35:19 martynas Exp $ */ + +/* + * Copyright (c) 2008 Stephen L. Moshier + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* log2l.c + * + * Base 2 logarithm, long double precision + * + * + * + * SYNOPSIS: + * + * long double x, y, log2l(); + * + * y = log2l( x ); + * + * + * + * DESCRIPTION: + * + * Returns the base 2 logarithm of x. + * + * The argument is separated into its exponent and fractional + * parts. If the exponent is between -1 and +1, the (natural) + * logarithm of the fraction is approximated by + * + * log(1+x) = x - 0.5 x**2 + x**3 P(x)/Q(x). + * + * Otherwise, setting z = 2(x-1)/x+1), + * + * log(x) = z + z**3 P(z)/Q(z). + * + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE 0.5, 2.0 30000 9.8e-20 2.7e-20 + * IEEE exp(+-10000) 70000 5.4e-20 2.3e-20 + * + * In the tests over the interval exp(+-10000), the logarithms + * of the random arguments were uniformly distributed over + * [-10000, +10000]. + * + * ERROR MESSAGES: + * + * log singularity: x = 0; returns -INFINITY + * log domain: x < 0; returns NAN + */ + +#include + +#include "math_private.h" + +/* Coefficients for ln(1+x) = x - x**2/2 + x**3 P(x)/Q(x) + * 1/sqrt(2) <= x < sqrt(2) + * Theoretical peak relative error = 6.2e-22 + */ +static long double P[] = { + 4.9962495940332550844739E-1L, + 1.0767376367209449010438E1L, + 7.7671073698359539859595E1L, + 2.5620629828144409632571E2L, + 4.2401812743503691187826E2L, + 3.4258224542413922935104E2L, + 1.0747524399916215149070E2L, +}; +static long double Q[] = { +/* 1.0000000000000000000000E0,*/ + 2.3479774160285863271658E1L, + 1.9444210022760132894510E2L, + 7.7952888181207260646090E2L, + 1.6911722418503949084863E3L, + 2.0307734695595183428202E3L, + 1.2695660352705325274404E3L, + 3.2242573199748645407652E2L, +}; + +/* Coefficients for log(x) = z + z^3 P(z^2)/Q(z^2), + * where z = 2(x-1)/(x+1) + * 1/sqrt(2) <= x < sqrt(2) + * Theoretical peak relative error = 6.16e-22 + */ +static long double R[4] = { + 1.9757429581415468984296E-3L, +-7.1990767473014147232598E-1L, + 1.0777257190312272158094E1L, +-3.5717684488096787370998E1L, +}; +static long double S[4] = { +/* 1.00000000000000000000E0L,*/ +-2.6201045551331104417768E1L, + 1.9361891836232102174846E2L, +-4.2861221385716144629696E2L, +}; +/* log2(e) - 1 */ +#define LOG2EA 4.4269504088896340735992e-1L + +#define SQRTH 0.70710678118654752440L + +long double +log2l(long double x) +{ +volatile long double z; +long double y; +int e; + +if( isnan(x) ) + return(x); +if( x == INFINITY ) + return(x); +/* Test for domain */ +if( x <= 0.0L ) + { + if( x == 0.0L ) + return( -INFINITY ); + else + return( NAN ); + } + +/* separate mantissa from exponent */ + +/* Note, frexp is used so that denormal numbers + * will be handled properly. + */ +x = frexpl( x, &e ); + + +/* logarithm using log(x) = z + z**3 P(z)/Q(z), + * where z = 2(x-1)/x+1) + */ +if( (e > 2) || (e < -2) ) +{ +if( x < SQRTH ) + { /* 2( 2x-1 )/( 2x+1 ) */ + e -= 1; + z = x - 0.5L; + y = 0.5L * z + 0.5L; + } +else + { /* 2 (x-1)/(x+1) */ + z = x - 0.5L; + z -= 0.5L; + y = 0.5L * x + 0.5L; + } +x = z / y; +z = x*x; +y = x * ( z * __polevll( z, R, 3 ) / __p1evll( z, S, 3 ) ); +goto done; +} + + +/* logarithm using log(1+x) = x - .5x**2 + x**3 P(x)/Q(x) */ + +if( x < SQRTH ) + { + e -= 1; + x = ldexpl( x, 1 ) - 1.0L; /* 2x - 1 */ + } +else + { + x = x - 1.0L; + } +z = x*x; +y = x * ( z * __polevll( x, P, 6 ) / __p1evll( x, Q, 7 ) ); +y = y - ldexpl( z, -1 ); /* -0.5x^2 + ... */ + +done: + +/* Multiply log of fraction by log2(e) + * and base 2 exponent by 1 + * + * ***CAUTION*** + * + * This sequence of operations is critical and it may + * be horribly defeated by some compiler optimizers. + */ +z = y * LOG2EA; +z += x * LOG2EA; +z += y; +z += x; +z += e; +return( z ); +} diff --git a/src/openlibm/ld80/e_log2l.c.o b/src/openlibm/ld80/e_log2l.c.o new file mode 100644 index 0000000000000000000000000000000000000000..4b67c6d4c2b6ca45ceaf5348bcd818619d779bc1 GIT binary patch literal 3464 zcmb<-^>JfjWMqH=Mg}_u1P><4z;J>S!FB*M9T@l-_!vBz-$dNbQAxOMqw)eI>=+$& zJ4Yp;^+2iGO;(V=&6BrZ-o07HR3dis-R+M>`ZrJBe|h&tm3XNrMBbzMh{xeHJ%0HX zkZJ}bL4J7`28O#gJbG(XbUd2h2*9l9c2Ti$jC73Z4Pa{i#lqkIl7WHYwk}Bb{g3?Z zlNlKpZoatp^5y}Mo_%Z#3=B6;di2_Y85kI# zs_vbl@0?7VCG7 z9V!n|g&@D=Dg8_?uWtNi4-xw-`cta^p7)M_`yu>k-M#)cOY_$-LCrJje7t4di+g=6 zQ1h(x)%IVVd~G)~RQ`mp6mzw1;USp)b6qA&8sB_)hyyC08toU(*qnNq6UvWWcFEfL zz>U8!zM}Q3|6gS`&4ck{LO8A`)tN11hpLCT3PBeAQ#!Zv`nmsqq3*BPZo*fn;|_Ok z_p89;Kcxl8ndKVO6C zXJBaf&%kh?o`IpEo`HeEz9r?}Pvg%lTmM1re}5>xVCkC`k6`X$aCdgLQqXYs3)NIG zG|@BCGgL4#FfuhTG&E4q2ue*+@JK9yO6ZzvGBB_(Ffb@EFff4126w+u1||l^10XR_ zx&Zl_5y}T8LJ(gBL@+QgFjfUIFjfdKO7pODOkiYSh+$x0kb%niFflMNxbP+T@kKcD z1r%}dad>lkaq)4uaeIRWo%jM$_!2Vs3YeVuG9395e8K9N{J8iyyts?_5(@YVa`*xY z`4WQoBAoaFpr&G{K<;E=_=q*FGGi?{85o!uV7@_^$qn)oNE~D!0|P?=REifW4$9LY zA(%KnR2&-33@};{Dh^T$!Z2}R5Ql-4fdfn<2njF~6#8HWoR9^xSi$iFWp#x^JGVp+D1YyX)z#xPaKHxZGU|=w3V8Ac~qzmK^bhAO??l{y3 z;t-F*AT!h`{=njthao<`AU`LyECJdk=W1_lP0cs^7dWIiaoVB(!nagcgYT7!wNL=p$3%0E#4 zZYT{h2b88@>d!;PLFRze*FgEtp)^Rn5R!ZNpy?ST4oZVCa}=QBAag)z114UCBo0dZ zF!35Bab)+eLJ|kL#|G+-V^DFBy~ysr1r-O`3sMg={|!_eq#oJ*HXwxzka7ye{ZM;A z(jW}wGBD^BSLT)^CNbz0mlQ$h3>d2@H78N8B(i;8>bd)c>K2zICTBzW>3OAk1x5JS0Q#0bz ziV|~E;jST@0VASR3sh3W^1A>(|geq=Ea8>SD$24PSV0!0-xxIsc-TmaRN?k-SRgB3uDTB!Z# z`WHa;S3uRlD0KZGd5}`{^rHbP1Q{3@VCe)@c7V!1n0}Zz$Uo?IgY1%kR&@_R3K$p| zKxGUc0|UHXgy{!agPwLk`hP$(L?VcTgrUa4ML=Z^HvJADgBchY+Tki840Qbfi!gDR literal 0 HcmV?d00001 diff --git a/src/openlibm/ld80/e_logl.c b/src/openlibm/ld80/e_logl.c new file mode 100644 index 0000000..4722014 --- /dev/null +++ b/src/openlibm/ld80/e_logl.c @@ -0,0 +1,190 @@ +/* $OpenBSD: e_logl.c,v 1.3 2013/11/12 20:35:19 martynas Exp $ */ + +/* + * Copyright (c) 2008 Stephen L. Moshier + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* logl.c + * + * Natural logarithm, long double precision + * + * + * + * SYNOPSIS: + * + * long double x, y, logl(); + * + * y = logl( x ); + * + * + * + * DESCRIPTION: + * + * Returns the base e (2.718...) logarithm of x. + * + * The argument is separated into its exponent and fractional + * parts. If the exponent is between -1 and +1, the logarithm + * of the fraction is approximated by + * + * log(1+x) = x - 0.5 x**2 + x**3 P(x)/Q(x). + * + * Otherwise, setting z = 2(x-1)/x+1), + * + * log(x) = z + z**3 P(z)/Q(z). + * + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE 0.5, 2.0 150000 8.71e-20 2.75e-20 + * IEEE exp(+-10000) 100000 5.39e-20 2.34e-20 + * + * In the tests over the interval exp(+-10000), the logarithms + * of the random arguments were uniformly distributed over + * [-10000, +10000]. + * + * ERROR MESSAGES: + * + * log singularity: x = 0; returns -INFINITY + * log domain: x < 0; returns NAN + */ + +#include + +#include "math_private.h" + +/* Coefficients for log(1+x) = x - x**2/2 + x**3 P(x)/Q(x) + * 1/sqrt(2) <= x < sqrt(2) + * Theoretical peak relative error = 2.32e-20 + */ +static long double P[] = { + 4.5270000862445199635215E-5L, + 4.9854102823193375972212E-1L, + 6.5787325942061044846969E0L, + 2.9911919328553073277375E1L, + 6.0949667980987787057556E1L, + 5.7112963590585538103336E1L, + 2.0039553499201281259648E1L, +}; +static long double Q[] = { +/* 1.0000000000000000000000E0,*/ + 1.5062909083469192043167E1L, + 8.3047565967967209469434E1L, + 2.2176239823732856465394E2L, + 3.0909872225312059774938E2L, + 2.1642788614495947685003E2L, + 6.0118660497603843919306E1L, +}; + +/* Coefficients for log(x) = z + z^3 P(z^2)/Q(z^2), + * where z = 2(x-1)/(x+1) + * 1/sqrt(2) <= x < sqrt(2) + * Theoretical peak relative error = 6.16e-22 + */ + +static long double R[4] = { + 1.9757429581415468984296E-3L, +-7.1990767473014147232598E-1L, + 1.0777257190312272158094E1L, +-3.5717684488096787370998E1L, +}; +static long double S[4] = { +/* 1.00000000000000000000E0L,*/ +-2.6201045551331104417768E1L, + 1.9361891836232102174846E2L, +-4.2861221385716144629696E2L, +}; +static const long double C1 = 6.9314575195312500000000E-1L; +static const long double C2 = 1.4286068203094172321215E-6L; + +#define SQRTH 0.70710678118654752440L + +long double +logl(long double x) +{ +long double y, z; +int e; + +if( isnan(x) ) + return(x); +if( x == INFINITY ) + return(x); +/* Test for domain */ +if( x <= 0.0L ) + { + if( x == 0.0L ) + return( -INFINITY ); + else + return( NAN ); + } + +/* separate mantissa from exponent */ + +/* Note, frexp is used so that denormal numbers + * will be handled properly. + */ +x = frexpl( x, &e ); + +/* logarithm using log(x) = z + z**3 P(z)/Q(z), + * where z = 2(x-1)/x+1) + */ +if( (e > 2) || (e < -2) ) +{ +if( x < SQRTH ) + { /* 2( 2x-1 )/( 2x+1 ) */ + e -= 1; + z = x - 0.5L; + y = 0.5L * z + 0.5L; + } +else + { /* 2 (x-1)/(x+1) */ + z = x - 0.5L; + z -= 0.5L; + y = 0.5L * x + 0.5L; + } +x = z / y; +z = x*x; +z = x * ( z * __polevll( z, R, 3 ) / __p1evll( z, S, 3 ) ); +z = z + e * C2; +z = z + x; +z = z + e * C1; +return( z ); +} + + +/* logarithm using log(1+x) = x - .5x**2 + x**3 P(x)/Q(x) */ + +if( x < SQRTH ) + { + e -= 1; + x = ldexpl( x, 1 ) - 1.0L; /* 2x - 1 */ + } +else + { + x = x - 1.0L; + } +z = x*x; +y = x * ( z * __polevll( x, P, 6 ) / __p1evll( x, Q, 6 ) ); +y = y + e * C2; +z = y - ldexpl( z, -1 ); /* y - 0.5 * z */ +/* Note, the sum of above terms does not exceed x/4, + * so it contributes at most about 1/4 lsb to the error. + */ +z = z + x; +z = z + e * C1; /* This sum has an error of 1/2 lsb. */ +return( z ); +} diff --git a/src/openlibm/ld80/e_logl.c.o b/src/openlibm/ld80/e_logl.c.o new file mode 100644 index 0000000000000000000000000000000000000000..e2f9a9e377b76a0c98abe3724a58484507caf672 GIT binary patch literal 3512 zcmb<-^>JfjWMqH=Mg}_u1P><4!0>|;!FB*M9T@l-_!vBz-$dNbQAxOMqw)eI>=@}7 zbvs8Tp!Gnh+D%rF$jy_tU*5f0#Z)48^WE)_MS3?+-hX-bMwM8p2t?ka`H08iG=BLO zkYWZTF@AX$28O#gJbG(XY&@FZ2*9l9c2V((cZ}!_U~2xw!ry*~fq~(+E=cqJkNoX9 zj0_AnU)+0n^8iT8J~jphh8rh6dTl}Sw`)`cZXUR8qjI}OMFH&E+c_!%aCJ~s_fFof zQE|APqhbJ4YXDR0u>b%6|NrlO1WDe3D05MXfmnX;_FHzwDVVFLJ zdk;Zc?j5}CqT&;AgBRqOD3HJJ9X!l0-vHu5{C)G_jfW89?tkWQ?*KXe;muPwPTo6s z?vxSEDi2YGAiv}({Y);eZv18s5&J9pQ>y=-_l|%2A^d6Gz5X^!^Vcvz%`@tJyk*^s zdwncW^S1B!*!X1)<42gh;hrU&6Qd-Su|n0qS$FGsyUyXeF!$WkcJ+9-sAm>CR9?Z5 z+5J;z?hTl{d$EdSIZ?v zsQSBJ=Tc+lc)w?c@?BeIB_1w4^BHE|>c$H;yVevxf${hINSw)G3|s(H&%n^|pMl{( zJp)5SJp%)SJwuTp)Fw!Hw4~hoY5bXG>p!TdoPXTe>b`yZUqkr}?#|9u3L5Typ_&SY zCVEDCh6+XoMy3Xah6V~6L8&PU9*HGT30-qd1_l-e1_lKN1_n@8clQfrU}9iA01^YG z2at`7P(CQ(g7_jJf`Ng7u_}mxu|j}RnuncZ0wV)M3$WIK+3=g0}1yGs?Dh|%%3=9kj zP;ow}I5e6WV6*^K9I6a1E(8`}W#9nQ2tpjp1cg4B0Vg0~$qJ4ixF7=qgCdv%Di*;E zIH3k+u`z(`2Q#6BHkf9`5I2B|gZu|(LJ3m_1_mLda0ACB0|SE<0|SN`AT7=~#JzBc zhu{#8#Uaj+8lRJ&o}-t{5Wo<~5X2D7py%Uk1R@MTgdvD91rcT-!W=}HFo1M0#K&hA z=OyOlFr*cwRutqg#K#xp=cJb9fLVrMMotP?2ILP|IDpbVC=CCAYKs5=|I2|S85kHq zNg5P)FmXF1aZuF?6AwZX2c;>Pcs^7dWWFE+0|QJPR7ZfMK<0BJiLU?&LhS{m);m!C zE+`E$2b88@=A46ygUkV`uYvNPL1~bBVI=ceK^X^XKFIGdbL61nAoZZU4ih(pii6At z)qgN?FC=kLo`8vmAc-UUs|-mT&M=!a!!~~gRXvUzIoS&PUnpeW0mzQ6Xs^{((s#{!= zn4Aser{|UG6%^$cq!yJ_GU$N~PtAx=D@x2w1-pbI0^~nXkf4_&uyPER?_rjJ@&t?x zqNSl>22&3b17Qz#5XrzG01Y%y9DwWrzpSsYHVa7=p`bP+14z!$_EZP+EYAfoM=VL#9FbALK+( zS_O&2@CT^<=&He + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* powl.c + * + * Power function, long double precision + * + * + * + * SYNOPSIS: + * + * long double x, y, z, powl(); + * + * z = powl( x, y ); + * + * + * + * DESCRIPTION: + * + * Computes x raised to the yth power. Analytically, + * + * x**y = exp( y log(x) ). + * + * Following Cody and Waite, this program uses a lookup table + * of 2**-i/32 and pseudo extended precision arithmetic to + * obtain several extra bits of accuracy in both the logarithm + * and the exponential. + * + * + * + * ACCURACY: + * + * The relative error of pow(x,y) can be estimated + * by y dl ln(2), where dl is the absolute error of + * the internally computed base 2 logarithm. At the ends + * of the approximation interval the logarithm equal 1/32 + * and its relative error is about 1 lsb = 1.1e-19. Hence + * the predicted relative error in the result is 2.3e-21 y . + * + * Relative error: + * arithmetic domain # trials peak rms + * + * IEEE +-1000 40000 2.8e-18 3.7e-19 + * .001 < x < 1000, with log(x) uniformly distributed. + * -1000 < y < 1000, y uniformly distributed. + * + * IEEE 0,8700 60000 6.5e-18 1.0e-18 + * 0.99 < x < 1.01, 0 < y < 8700, uniformly distributed. + * + * + * ERROR MESSAGES: + * + * message condition value returned + * pow overflow x**y > MAXNUM INFINITY + * pow underflow x**y < 1/MAXNUM 0.0 + * pow domain x<0 and y noninteger 0.0 + * + */ + +#include +#include + +#include "math_private.h" + +/* Table size */ +#define NXT 32 +/* log2(Table size) */ +#define LNXT 5 + +/* log(1+x) = x - .5x^2 + x^3 * P(z)/Q(z) + * on the domain 2^(-1/32) - 1 <= x <= 2^(1/32) - 1 + */ +static long double P[] = { + 8.3319510773868690346226E-4L, + 4.9000050881978028599627E-1L, + 1.7500123722550302671919E0L, + 1.4000100839971580279335E0L, +}; +static long double Q[] = { +/* 1.0000000000000000000000E0L,*/ + 5.2500282295834889175431E0L, + 8.4000598057587009834666E0L, + 4.2000302519914740834728E0L, +}; +/* A[i] = 2^(-i/32), rounded to IEEE long double precision. + * If i is even, A[i] + B[i/2] gives additional accuracy. + */ +static long double A[33] = { + 1.0000000000000000000000E0L, + 9.7857206208770013448287E-1L, + 9.5760328069857364691013E-1L, + 9.3708381705514995065011E-1L, + 9.1700404320467123175367E-1L, + 8.9735453750155359320742E-1L, + 8.7812608018664974155474E-1L, + 8.5930964906123895780165E-1L, + 8.4089641525371454301892E-1L, + 8.2287773907698242225554E-1L, + 8.0524516597462715409607E-1L, + 7.8799042255394324325455E-1L, + 7.7110541270397041179298E-1L, + 7.5458221379671136985669E-1L, + 7.3841307296974965571198E-1L, + 7.2259040348852331001267E-1L, + 7.0710678118654752438189E-1L, + 6.9195494098191597746178E-1L, + 6.7712777346844636413344E-1L, + 6.6261832157987064729696E-1L, + 6.4841977732550483296079E-1L, + 6.3452547859586661129850E-1L, + 6.2092890603674202431705E-1L, + 6.0762367999023443907803E-1L, + 5.9460355750136053334378E-1L, + 5.8186242938878875689693E-1L, + 5.6939431737834582684856E-1L, + 5.5719337129794626814472E-1L, + 5.4525386633262882960438E-1L, + 5.3357020033841180906486E-1L, + 5.2213689121370692017331E-1L, + 5.1094857432705833910408E-1L, + 5.0000000000000000000000E-1L, +}; +static long double B[17] = { + 0.0000000000000000000000E0L, + 2.6176170809902549338711E-20L, +-1.0126791927256478897086E-20L, + 1.3438228172316276937655E-21L, + 1.2207982955417546912101E-20L, +-6.3084814358060867200133E-21L, + 1.3164426894366316434230E-20L, +-1.8527916071632873716786E-20L, + 1.8950325588932570796551E-20L, + 1.5564775779538780478155E-20L, + 6.0859793637556860974380E-21L, +-2.0208749253662532228949E-20L, + 1.4966292219224761844552E-20L, + 3.3540909728056476875639E-21L, +-8.6987564101742849540743E-22L, +-1.2327176863327626135542E-20L, + 0.0000000000000000000000E0L, +}; + +/* 2^x = 1 + x P(x), + * on the interval -1/32 <= x <= 0 + */ +static long double R[] = { + 1.5089970579127659901157E-5L, + 1.5402715328927013076125E-4L, + 1.3333556028915671091390E-3L, + 9.6181291046036762031786E-3L, + 5.5504108664798463044015E-2L, + 2.4022650695910062854352E-1L, + 6.9314718055994530931447E-1L, +}; + +#define douba(k) A[k] +#define doubb(k) B[k] +#define MEXP (NXT*16384.0L) +/* The following if denormal numbers are supported, else -MEXP: */ +#define MNEXP (-NXT*(16384.0L+64.0L)) +/* log2(e) - 1 */ +#define LOG2EA 0.44269504088896340735992L + +#define F W +#define Fa Wa +#define Fb Wb +#define G W +#define Ga Wa +#define Gb u +#define H W +#define Ha Wb +#define Hb Wb + +static const long double MAXLOGL = 1.1356523406294143949492E4L; +static const long double MINLOGL = -1.13994985314888605586758E4L; +static const long double LOGE2L = 6.9314718055994530941723E-1L; +static volatile long double z; +static long double w, W, Wa, Wb, ya, yb, u; +static const long double huge = 0x1p10000L; +#if 0 /* XXX Prevent gcc from erroneously constant folding this. */ +static const long double twom10000 = 0x1p-10000L; +#else +static volatile long double twom10000 = 0x1p-10000L; +#endif + +static long double reducl( long double ); +static long double powil ( long double, int ); + +long double +powl(long double x, long double y) +{ +/* double F, Fa, Fb, G, Ga, Gb, H, Ha, Hb */ +int i, nflg, iyflg, yoddint; +long e; + +if( y == 0.0L ) + return( 1.0L ); + +if( x == 1.0L ) + return( 1.0L ); + +if( isnan(x) ) + return( x ); +if( isnan(y) ) + return( y ); + +if( y == 1.0L ) + return( x ); + +if( !isfinite(y) && x == -1.0L ) + return( 1.0L ); + +if( y >= LDBL_MAX ) + { + if( x > 1.0L ) + return( INFINITY ); + if( x > 0.0L && x < 1.0L ) + return( 0.0L ); + if( x < -1.0L ) + return( INFINITY ); + if( x > -1.0L && x < 0.0L ) + return( 0.0L ); + } +if( y <= -LDBL_MAX ) + { + if( x > 1.0L ) + return( 0.0L ); + if( x > 0.0L && x < 1.0L ) + return( INFINITY ); + if( x < -1.0L ) + return( 0.0L ); + if( x > -1.0L && x < 0.0L ) + return( INFINITY ); + } +if( x >= LDBL_MAX ) + { + if( y > 0.0L ) + return( INFINITY ); + return( 0.0L ); + } + +w = floorl(y); +/* Set iyflg to 1 if y is an integer. */ +iyflg = 0; +if( w == y ) + iyflg = 1; + +/* Test for odd integer y. */ +yoddint = 0; +if( iyflg ) + { + ya = fabsl(y); + ya = floorl(0.5L * ya); + yb = 0.5L * fabsl(w); + if( ya != yb ) + yoddint = 1; + } + +if( x <= -LDBL_MAX ) + { + if( y > 0.0L ) + { + if( yoddint ) + return( -INFINITY ); + return( INFINITY ); + } + if( y < 0.0L ) + { + if( yoddint ) + return( -0.0L ); + return( 0.0 ); + } + } + + +nflg = 0; /* flag = 1 if x<0 raised to integer power */ +if( x <= 0.0L ) + { + if( x == 0.0L ) + { + if( y < 0.0 ) + { + if( signbit(x) && yoddint ) + return( -INFINITY ); + return( INFINITY ); + } + if( y > 0.0 ) + { + if( signbit(x) && yoddint ) + return( -0.0L ); + return( 0.0 ); + } + if( y == 0.0L ) + return( 1.0L ); /* 0**0 */ + else + return( 0.0L ); /* 0**y */ + } + else + { + if( iyflg == 0 ) + return (x - x) / (x - x); /* (x<0)**(non-int) is NaN */ + nflg = 1; + } + } + +/* Integer power of an integer. */ + +if( iyflg ) + { + i = w; + w = floorl(x); + if( (w == x) && (fabsl(y) < 32768.0) ) + { + w = powil( x, (int) y ); + return( w ); + } + } + + +if( nflg ) + x = fabsl(x); + +/* separate significand from exponent */ +x = frexpl( x, &i ); +e = i; + +/* find significand in antilog table A[] */ +i = 1; +if( x <= douba(17) ) + i = 17; +if( x <= douba(i+8) ) + i += 8; +if( x <= douba(i+4) ) + i += 4; +if( x <= douba(i+2) ) + i += 2; +if( x >= douba(1) ) + i = -1; +i += 1; + + +/* Find (x - A[i])/A[i] + * in order to compute log(x/A[i]): + * + * log(x) = log( a x/a ) = log(a) + log(x/a) + * + * log(x/a) = log(1+v), v = x/a - 1 = (x-a)/a + */ +x -= douba(i); +x -= doubb(i/2); +x /= douba(i); + + +/* rational approximation for log(1+v): + * + * log(1+v) = v - v**2/2 + v**3 P(v) / Q(v) + */ +z = x*x; +w = x * ( z * __polevll( x, P, 3 ) / __p1evll( x, Q, 3 ) ); +w = w - ldexpl( z, -1 ); /* w - 0.5 * z */ + +/* Convert to base 2 logarithm: + * multiply by log2(e) = 1 + LOG2EA + */ +z = LOG2EA * w; +z += w; +z += LOG2EA * x; +z += x; + +/* Compute exponent term of the base 2 logarithm. */ +w = -i; +w = ldexpl( w, -LNXT ); /* divide by NXT */ +w += e; +/* Now base 2 log of x is w + z. */ + +/* Multiply base 2 log by y, in extended precision. */ + +/* separate y into large part ya + * and small part yb less than 1/NXT + */ +ya = reducl(y); +yb = y - ya; + +/* (w+z)(ya+yb) + * = w*ya + w*yb + z*y + */ +F = z * y + w * yb; +Fa = reducl(F); +Fb = F - Fa; + +G = Fa + w * ya; +Ga = reducl(G); +Gb = G - Ga; + +H = Fb + Gb; +Ha = reducl(H); +w = ldexpl( Ga+Ha, LNXT ); + +/* Test the power of 2 for overflow */ +if( w > MEXP ) + return (huge * huge); /* overflow */ + +if( w < MNEXP ) + return (twom10000 * twom10000); /* underflow */ + +e = w; +Hb = H - Ha; + +if( Hb > 0.0L ) + { + e += 1; + Hb -= (1.0L/NXT); /*0.0625L;*/ + } + +/* Now the product y * log2(x) = Hb + e/NXT. + * + * Compute base 2 exponential of Hb, + * where -0.0625 <= Hb <= 0. + */ +z = Hb * __polevll( Hb, R, 6 ); /* z = 2**Hb - 1 */ + +/* Express e/NXT as an integer plus a negative number of (1/NXT)ths. + * Find lookup table entry for the fractional power of 2. + */ +if( e < 0 ) + i = 0; +else + i = 1; +i = e/NXT + i; +e = NXT*i - e; +w = douba( e ); +z = w * z; /* 2**-e * ( 1 + (2**Hb-1) ) */ +z = z + w; +z = ldexpl( z, i ); /* multiply by integer power of 2 */ + +if( nflg ) + { +/* For negative x, + * find out if the integer exponent + * is odd or even. + */ + w = ldexpl( y, -1 ); + w = floorl(w); + w = ldexpl( w, 1 ); + if( w != y ) + z = -z; /* odd exponent */ + } + +return( z ); +} + + +/* Find a multiple of 1/NXT that is within 1/NXT of x. */ +static long double +reducl(long double x) +{ +long double t; + +t = ldexpl( x, LNXT ); +t = floorl( t ); +t = ldexpl( t, -LNXT ); +return(t); +} + +/* powil.c + * + * Real raised to integer power, long double precision + * + * + * + * SYNOPSIS: + * + * long double x, y, powil(); + * int n; + * + * y = powil( x, n ); + * + * + * + * DESCRIPTION: + * + * Returns argument x raised to the nth power. + * The routine efficiently decomposes n as a sum of powers of + * two. The desired power is a product of two-to-the-kth + * powers of x. Thus to compute the 32767 power of x requires + * 28 multiplications instead of 32767 multiplications. + * + * + * + * ACCURACY: + * + * + * Relative error: + * arithmetic x domain n domain # trials peak rms + * IEEE .001,1000 -1022,1023 50000 4.3e-17 7.8e-18 + * IEEE 1,2 -1022,1023 20000 3.9e-17 7.6e-18 + * IEEE .99,1.01 0,8700 10000 3.6e-16 7.2e-17 + * + * Returns MAXNUM on overflow, zero on underflow. + * + */ + +static long double +powil(long double x, int nn) +{ +long double ww, y; +long double s; +int n, e, sign, asign, lx; + +if( x == 0.0L ) + { + if( nn == 0 ) + return( 1.0L ); + else if( nn < 0 ) + return( LDBL_MAX ); + else + return( 0.0L ); + } + +if( nn == 0 ) + return( 1.0L ); + + +if( x < 0.0L ) + { + asign = -1; + x = -x; + } +else + asign = 0; + + +if( nn < 0 ) + { + sign = -1; + n = -nn; + } +else + { + sign = 1; + n = nn; + } + +/* Overflow detection */ + +/* Calculate approximate logarithm of answer */ +s = x; +s = frexpl( s, &lx ); +e = (lx - 1)*n; +if( (e == 0) || (e > 64) || (e < -64) ) + { + s = (s - 7.0710678118654752e-1L) / (s + 7.0710678118654752e-1L); + s = (2.9142135623730950L * s - 0.5L + lx) * nn * LOGE2L; + } +else + { + s = LOGE2L * e; + } + +if( s > MAXLOGL ) + return (huge * huge); /* overflow */ + +if( s < MINLOGL ) + return (twom10000 * twom10000); /* underflow */ +/* Handle tiny denormal answer, but with less accuracy + * since roundoff error in 1.0/x will be amplified. + * The precise demarcation should be the gradual underflow threshold. + */ +if( s < (-MAXLOGL+2.0L) ) + { + x = 1.0L/x; + sign = -sign; + } + +/* First bit of the power */ +if( n & 1 ) + y = x; + +else + { + y = 1.0L; + asign = 0; + } + +ww = x; +n >>= 1; +while( n ) + { + ww = ww * ww; /* arg to the 2-to-the-kth power */ + if( n & 1 ) /* if that bit is set, then include in product */ + y *= ww; + n >>= 1; + } + +if( asign ) + y = -y; /* odd power of negative number */ +if( sign < 0 ) + y = 1.0L/y; +return(y); +} diff --git a/src/openlibm/ld80/e_powl.c.o b/src/openlibm/ld80/e_powl.c.o new file mode 100644 index 0000000000000000000000000000000000000000..7d708d0cc59137bed28c0a3fec5ee3b6dea301b2 GIT binary patch literal 13376 zcmb<-^>JfjWMqH=Mg}_u1P><4z~Eqj#0E1R7z7yj85~1zzS{-jJBEY?do;iCxV=WD zfq{YH{>!^J_-7yBcRkc{pj6~`j!MDJ7Z9;S{4R%D4wQ)9eBsf2#3MS^F~%|Wa2mgS z3&<3P|0OCFAp8QvbBuJ1YCTXQ4APFIm|xz3;r|wu4h9Ao1y&vJ7y-4s^Kk2d(uFr) z+&l@gvWlr>9~R}2ajgeR~Zur!@y18IW<;q8z7?RVHf zcHBG(GCr0a5rE~Jp`iw)z|IGy7MTB`W`q1t#l_#E$HKtyn(6Kh!?zy2H7XXMR0P6c zZ4moix^q-KK#A)9NB-uy>Q+y5c2+K{w5Q!!$A7> zu`@9Ax-t3msxmMzFnAE@}<7!?apJnmy=U|_iM(4!Ze7VbT|_w(j~8z&(#cJsh(8qNo#;x(>oz1rfV<=qA*a5dQ5P6@xpcZl1b#5aM=-D4Yi}0hZpO>C>e% zM@3;jDA;eis3?F_D@uNb=>>ZS6@C2NdH#0RR(ljE=@){Edgm9);S0#b}W0;3mZq<#JfKW4bdU3T70@ zSd>tRjKku{dk10a;~gVlo`z&kP+q%xlfV5a3j+g0j6RP-9o z@T7IRsOa3xQPH_?qjEDxMGxXnk8T+i2C z4Ree~>urzTYI%>&8xT`G_&tAne81pv@P)m{!T+p`$M2o&{LxvX;&Jc+tH%rv%^Q%Q z24x<{+d3>T;~|>S(j`jzgIO361u>!ZEq|*eD=g2ytpEA{KeS+hQsBh)nO^{$dtvr` z<`)c65xD810xETDR1_Qo@11lEgqaOaxwy+&$0)~WSV;@5i`e*EHZnuX*_-dcWo+{$ zRtARGT%f}9HKYiwfrT|jOx%u9u>eH{s9XbKu#-Uv80K71`3))$`MbXT`v0H5^}{c$ zzJx@2yki8|1#PE({r?Y&d1!%(%~}DFwJzN$Dgv+B?%n_uv#zaA_*>S13QbMtFl)AP)sbu?p*RlERe^9|}19CVBgB{-;qT&-5-|O_B zfBn&34~NE|pvFTvN9zIp)^L#7;Oux~oxJ%L5!Saqg3|Y2Hdu6n()TSS-rXBz{5M}Xe!mL}uzNp2Zti^1{D6_aj3tlmoqYXZ0!TkN5SwyA+2_ojytw)9<#mv|!EwI}lpS}D{xz%6RW=vZ)e zdMO8s=+Cy7NcYLgEBr$3MP!D?S?27 zQ-8r)+czIT3hb9b_zEw_2**fpE^9jv@))Shgk%M5VUH-iZoa#D0F*%>fo1d?R7e{9 z{{J6bn%!YyV5sD{3$2-8&VL#589DwVL51bX`!D&s*uX)}f)vz{hJRZdsAqy4g^saN zpm4qa<^O+3o`w{_FMoXkrzKFcxc$*@Xdz5O3IbIyFlT~%1qn|6?rnen|9`pt@Bjb1 zLGkdC_22*htp`e&Za#2qKFY}7sszgNFYbMODG6r06a!feaeI68Z+J{2mpBnoaC;!Z z3<_NRWIDN;@~-@i&1=E@(~xbw(^c!(*iF@UQ>>UwZ%g|3463;eX~A0QD0X zU_SfIFX)5ZJP5mYG7Og72{aDk9V0M(Sn~;z)DUjuZ)yZ*LL@it1_?l-tL+phrX&9# zia?0YdnaFl0t=RuZ=86k_ZOt*=8KoAU`8hksP+U^nJ-WL`2Qc&VZnzR-b-MYp1q7O zSoWRP-*@&9dAH+reF>3G3qL{m+mdgs&H8(I-B&1|<>1V}HPKV&{($o19?VtQ;TG}u z7nCm>t0VU3{ok*Dp!`*p=P!O2FWUGI%7@s3AlZ{Mml#_!tYCD2h#mTOJxOM1S{oCT zZ*;5Z!u6$TZ7_L=Dg?>0WBZCP$FgpHftvramg)R~h=;%aLite+O6Dii86NzH@@JlP z&OX&{ycxzvm;_<9%NyMODq;0~FI2tg8aF#5O|SiX_Cw@dD${mNTp)CMCse-T{}zX5 zdb6JGf%2!G$P8$H9QtAD`cc@{oUoqXW$y1h_&yV|L*(u99+g4x#@ zYw~(xAmd~h|7Jt;4uRjVpYDd5AIs9C@#f&&eK7rR-?qjWxJC8C)Hlst^OUPE_wO#K z`oFmmuSM1uH}8bnXYq4Q)%l6HUcmeV@fAU`0Ty0X%vwdaH#Pr)#i!1hHWkrY)vqxA z>94o$%-;FrJ&dn!sdD%Eu>-GQ{1qO}HP6|0K85iGA5PJFbMMRp7(dkf)2->-f8U1j zzhuq5cIuDIbr?VDiPp!7vMVmZ_)i*Iqe6z!XtBWrmo(SU~2tMoDZMmcm#(#dT z`_=U{hyhYO}iMN<;5CkdBX$cLtM$wz@H9b zt=jd7v;Lp#CY}QjK16-iMi?JGe$mtW`$O>sOW&+`1S?-4rZB+6hk>D?o`InO};i=;qDizsbFZLXQXGSU}RuqYG7z+pr8?ynxf#5SOS&M zHP?ig%)-FHpuoVu02*s?_X}lUVqgUIX5eGIj8Hx|L^*>9lxD07VqmNgV3g)z=a|6A zz>velz#s#aJI>F*z~ICu(97h>C(*;~$fwZ8;>f4b%<95dkk7@Z;mD`p$S2{%C*Z`# z;l=I3SK-3f!066b;lx+qgC_0D?ao)>&ey=`29{2Ma~$~!n6lwKC%%F-2q%zl0%ICq zfg4|i4_^bL7heTP;aZ3s#ELA4eL-LYncDao7)$sjFf#e@buc>eH86&NIOTi=Pv7Z1V(?To_f9sj9ySSNKqb?4N~I=WyeA6E8}ZmWNHID3+kD4 zz79qgz6p#za94Xnltw}v3UPHZ#0x$UsS1b`#Cyytj1WmTu(3>;5S}}j7Y|Vhkz$r) zMCQgoIDTM-Oc4+sB%l-dD!lj_z#eqso4^PP0Z`zCgRL)zSl|ohFfD-SgILGp1LryM z6);6XR6=Zr#*iCd2ctjV1V%r&e<22?L)1dN%M=1~R0CrsUk9TzO5k{bZH1;ZObXPV zWnuUT${!e#%AOMx(fr>-9aB)yp zU}RurPyjiMfq_AQ38DhjO$CWVcnk~zPoU}J!V8<@+$zz_juuz?~U%z_bdUWXH&PTfyRN@O%R1GB7agW?*0tLdw_R zx`%-Q>`z!4hN%V7po$Wk_*GEe1SvqncW{V5!Xf?=hxlh4;-L9KZ0=!ZWWY#MV5gWo8-m3RA%=j>HZlUKF#;O{RsvQ5)@THA z0hly4U;w$BAwE8{I4?0T2h2#z%*!lE&0$E($0Ld5R=cJb9 zfLVrMMotP;rZ_V_FDbJmhk=115*#QD;Pj%yz`y_+X9Tt9+Hr_)LlOs-Nig*fq2i$8 zSqRA-eQ3E1stNRv#I2y>AoUs#is5nSWA4z=4Aw)f{KI0 zknNoV6$hCEl5>IDy9iAjX3h#UahN;TLd8L5AiEPhAjH7H05czE&Q+*-kT|GJgNX}) z1fc3cbreio6GE$uRR*Ld8Lp7*aSN00}_d z1F9Qg>Te;5gUVi*_yZ(yP@M@A|AQnBs;gz7{uhHb6+qG;ahQ5HBykWERBnL$83N)! z-2?K24@i)KfguSh4iYm&a(@O?9ArL74yL{WNgTwS12ty?h{FI$|Dd`Q=AN}sahN%< z@Z63j4m1BCR2*cdF_L@kK*d4kNFj;8LJ|k*ftm9GhxjiX;^2&nC42-xhGG#H!yzt* zLtG0@92O2nP;n52?B6Jm0Fu2h_3=<~5QVHh8zcY?f8_LBjUT;kgh^9Oj;FXyTx<50oVKLB&B7vc0E30$AL68%Z2l{cET=%$=~l-A6QWn7u#I z#9{52|7hYc_p^dJoJjtKg@YiPILv%Ws5r+8z%l1NgQMc%)j5!#9{8_gf{g-_JStoVCIM-iG$36saHi32Ne|{ zyFuw$7b*@?i(F3HLd8MmgXCc5q@anz@=*zzI4m5h(8OWtn{bGC;1HjHLwp(z@p({j zklT^teHm07<}a9gw%`yy0~H6EgIteafr^97L2hq=7E^)36(kPQ1B;hmQ1u`&cK)JanLv#%$$ix;-Ee>Onfnt zxDt{%8T8k2)se)zki<2R#AhRkBfDo84)NXFmiDI{^^aQ=%Vj$96~ zLJKr>^97;eAoG#kqW~30SFZsT2dPIk-vla-uHGL_99I5>;}Fk>ii6BY_HQXv9ArLn z{<@ANj@-|>k0cH<3l{!L;OSII`xZIeETQ5c^Fc$|u=ou@5=Spvsg5L$Ts|8?#nJ7xfr`V-ftABf zXyP#QJS5ugjwTK>M;A>T z=6)lnILHiScRE7FVdlfki9`}d_HQqeIC8l(8He~HByr^O5LDNIQXI%$5C*ZqSg*J; zwBNC~K{hNys$6F`GK z42U^Dh$y7|1F=D24x&S#_Ji6|AU+JQf$9h4C72k92HAy7$3pdk#E|iAsD5NI5F4f+ z#0KG91_lODQx84-9zgY@y9*RoAbl|03bh|yzW`{^2{f*bCV{RWG;R+H3-t6i1L|?m zSQN-EQ2GNk1z`GN;voN^SpibcFaxUK2gq;+1_n^EsLj9tpGSd8Gk}_XXh{UDe*&me e2GR$z04xF_(6|hsWQtAy2B`b{A==<1x_$sxvZWLN literal 0 HcmV?d00001 diff --git a/src/openlibm/ld80/e_rem_pio2l.h b/src/openlibm/ld80/e_rem_pio2l.h new file mode 100644 index 0000000..c44ad48 --- /dev/null +++ b/src/openlibm/ld80/e_rem_pio2l.h @@ -0,0 +1,152 @@ +/* From: @(#)e_rem_pio2.c 1.4 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * Copyright (c) 2008 Steven G. Kargl, David Schultz, Bruce D. Evans. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + * + * Optimized by Bruce D. Evans. + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/ld80/e_rem_pio2l.h,v 1.3 2011/06/18 13:56:33 benl Exp $"); + +/* ld80 version of __ieee754_rem_pio2l(x,y) + * + * return the remainder of x rem pi/2 in y[0]+y[1] + * use __kernel_rem_pio2() + */ + +#include +#include + +#include "math_private.h" + +#define BIAS (LDBL_MAX_EXP - 1) + +/* + * invpio2: 64 bits of 2/pi + * pio2_1: first 39 bits of pi/2 + * pio2_1t: pi/2 - pio2_1 + * pio2_2: second 39 bits of pi/2 + * pio2_2t: pi/2 - (pio2_1+pio2_2) + * pio2_3: third 39 bits of pi/2 + * pio2_3t: pi/2 - (pio2_1+pio2_2+pio2_3) + */ + +static const double +zero = 0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */ +two24 = 1.67772160000000000000e+07, /* 0x41700000, 0x00000000 */ +pio2_1 = 1.57079632679597125389e+00, /* 0x3FF921FB, 0x54444000 */ +pio2_2 = -1.07463465549783099519e-12, /* -0x12e7b967674000.0p-92 */ +pio2_3 = 6.36831716351370313614e-25; /* 0x18a2e037074000.0p-133 */ + +#if defined(__amd64__) || defined(__i386__) +/* Long double constants are slow on these arches, and broken on i386. */ +static const volatile double +invpio2hi = 6.3661977236758138e-01, /* 0x145f306dc9c883.0p-53 */ +invpio2lo = -3.9356538861223811e-17, /* -0x16b00000000000.0p-107 */ +pio2_1thi = -1.0746346554971943e-12, /* -0x12e7b9676733af.0p-92 */ +pio2_1tlo = 8.8451028997905949e-29, /* 0x1c080000000000.0p-146 */ +pio2_2thi = 6.3683171635109499e-25, /* 0x18a2e03707344a.0p-133 */ +pio2_2tlo = 2.3183081793789774e-41, /* 0x10280000000000.0p-187 */ +pio2_3thi = -2.7529965190440717e-37, /* -0x176b7ed8fbbacc.0p-174 */ +pio2_3tlo = -4.2006647512740502e-54; /* -0x19c00000000000.0p-230 */ +#define invpio2 ((long double)invpio2hi + invpio2lo) +#define pio2_1t ((long double)pio2_1thi + pio2_1tlo) +#define pio2_2t ((long double)pio2_2thi + pio2_2tlo) +#define pio2_3t ((long double)pio2_3thi + pio2_3tlo) +#else +static const long double +invpio2 = 6.36619772367581343076e-01L, /* 0xa2f9836e4e44152a.0p-64 */ +pio2_1t = -1.07463465549719416346e-12L, /* -0x973dcb3b399d747f.0p-103 */ +pio2_2t = 6.36831716351095013979e-25L, /* 0xc51701b839a25205.0p-144 */ +pio2_3t = -2.75299651904407171810e-37L; /* -0xbb5bf6c7ddd660ce.0p-185 */ +#endif + +//VBS +//static inline __always_inline int +//__ieee754_rem_pio2l(long double x, long double *y) + +static inline int +__ieee754_rem_pio2l(long double x, long double *y) +{ + union IEEEl2bits u,u1; + long double z,w,t,r,fn; + double tx[3],ty[2]; + int e0,ex,i,j,nx,n; + int16_t expsign; + + u.e = x; + expsign = u.xbits.expsign; + ex = expsign & 0x7fff; + if (ex < BIAS + 25 || (ex == BIAS + 25 && u.bits.manh < 0xc90fdaa2)) { + /* |x| ~< 2^25*(pi/2), medium size */ + /* Use a specialized rint() to get fn. Assume round-to-nearest. */ + fn = x*invpio2+0x1.8p63; + fn = fn-0x1.8p63; +#ifdef HAVE_EFFICIENT_IRINT + n = irint(fn); +#else + n = fn; +#endif + r = x-fn*pio2_1; + w = fn*pio2_1t; /* 1st round good to 102 bit */ + { + union IEEEl2bits u2; + int ex1; + j = ex; + y[0] = r-w; + u2.e = y[0]; + ex1 = u2.xbits.expsign & 0x7fff; + i = j-ex1; + if(i>22) { /* 2nd iteration needed, good to 141 */ + t = r; + w = fn*pio2_2; + r = t-w; + w = fn*pio2_2t-((t-r)-w); + y[0] = r-w; + u2.e = y[0]; + ex1 = u2.xbits.expsign & 0x7fff; + i = j-ex1; + if(i>61) { /* 3rd iteration need, 180 bits acc */ + t = r; /* will cover all possible cases */ + w = fn*pio2_3; + r = t-w; + w = fn*pio2_3t-((t-r)-w); + y[0] = r-w; + } + } + } + y[1] = (r-y[0])-w; + return n; + } + /* + * all other (large) arguments + */ + if(ex==0x7fff) { /* x is inf or NaN */ + y[0]=y[1]=x-x; return 0; + } + /* set z = scalbn(|x|,ilogb(x)-23) */ + u1.e = x; + e0 = ex - BIAS - 23; /* e0 = ilogb(|x|)-23; */ + u1.xbits.expsign = ex - e0; + z = u1.e; + for(i=0;i<2;i++) { + tx[i] = (double)((int32_t)(z)); + z = (z-tx[i])*two24; + } + tx[2] = z; + nx = 3; + while(tx[nx-1]==zero) nx--; /* skip zero term */ + n = __kernel_rem_pio2(tx,ty,e0,nx,2); + r = (long double)ty[0] + ty[1]; + w = ty[1] - (r - ty[0]); + if(expsign<0) {y[0] = -r; y[1] = -w; return -n;} + y[0] = r; y[1] = w; return n; +} diff --git a/src/openlibm/ld80/e_sinhl.c b/src/openlibm/ld80/e_sinhl.c new file mode 100644 index 0000000..cb45204 --- /dev/null +++ b/src/openlibm/ld80/e_sinhl.c @@ -0,0 +1,76 @@ +/* @(#)e_sinh.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* sinhl(x) + * Method : + * mathematically sinh(x) if defined to be (exp(x)-exp(-x))/2 + * 1. Replace x by |x| (sinhl(-x) = -sinhl(x)). + * 2. + * E + E/(E+1) + * 0 <= x <= 25 : sinhl(x) := --------------, E=expm1l(x) + * 2 + * + * 25 <= x <= lnovft : sinhl(x) := expl(x)/2 + * lnovft <= x <= ln2ovft: sinhl(x) := expl(x/2)/2 * expl(x/2) + * ln2ovft < x : sinhl(x) := x*shuge (overflow) + * + * Special cases: + * sinhl(x) is |x| if x is +INF, -INF, or NaN. + * only sinhl(0)=0 is exact for finite x. + */ + +#include + +#include "math_private.h" + +static const long double one = 1.0, shuge = 1.0e4931L; + +long double +sinhl(long double x) +{ + long double t,w,h; + u_int32_t jx,ix,i0,i1; + + /* Words of |x|. */ + GET_LDOUBLE_WORDS(jx,i0,i1,x); + ix = jx&0x7fff; + + /* x is INF or NaN */ + if(ix==0x7fff) return x+x; + + h = 0.5; + if (jx & 0x8000) h = -h; + /* |x| in [0,25], return sign(x)*0.5*(E+E/(E+1))) */ + if (ix < 0x4003 || (ix == 0x4003 && i0 <= 0xc8000000)) { /* |x|<25 */ + if (ix<0x3fdf) /* |x|<2**-32 */ + if(shuge+x>one) return x;/* sinh(tiny) = tiny with inexact */ + t = expm1l(fabsl(x)); + if(ix<0x3fff) return h*(2.0*t-t*t/(t+one)); + return h*(t+t/(t+one)); + } + + /* |x| in [25, log(maxdouble)] return 0.5*exp(|x|) */ + if (ix < 0x400c || (ix == 0x400c && i0 < 0xb17217f7)) + return h*expl(fabsl(x)); + + /* |x| in [log(maxdouble), overflowthreshold] */ + if (ix<0x400c || (ix == 0x400c && (i0 < 0xb174ddc0 + || (i0 == 0xb174ddc0 + && i1 <= 0x31aec0ea)))) { + w = expl(0.5*fabsl(x)); + t = h*w; + return t*w; + } + + /* |x| > overflowthreshold, sinhl(x) overflow */ + return x*shuge; +} diff --git a/src/openlibm/ld80/e_sinhl.c.o b/src/openlibm/ld80/e_sinhl.c.o new file mode 100644 index 0000000000000000000000000000000000000000..cd03efb4de5720a7504ab52a7a3c62272f14c280 GIT binary patch literal 2632 zcmb<-^>JfjWMqH=Mg}_u1P><4z|g^lU^{@B4h;MZdIuEBcKK@^y z*7*B>J%7s{1_p+-)&mvsH(5cd(;9y>In>326e@Tee4&um_?y{*zx5jf1A{FC1H%da z_SXyy47Y7m{+Fm|fba{DE|A%`ZB(G_BMP^5RBpcTXg(qkedExLU-u5(J9!w%`1*yn zZB)`4f8VpOkG!o5(tkTgMd8lDn+I;bxOw{i=exJc4e#DWHS>)Cn)$Ci)A;3G7#KiW zZyb2dboU0>zQg?TEg%yaKyCwJsGCsrr#1fmXMbBqg}*=a|Ns9t4}!GbI23*J(2dhK zU)(!#@AJJ!_f8%Lo1fPBo7;iEZz(948h`URl&0B!6EE7x-!>U85@WmnZpp?nVcP?D zOE#7Ufy2)B)q!<}e&+*GMAOh~*$(M`>edsn~v+Lf;m*@Ze{|~apo`Hd3KZvp9 z$7wOeL&|G@*MoQr3=Hnh&Q=N;Y76t|e1qKENP%3iw3uRzpU_1a4gQZbMD4!W>ya<$LtO{aatPo(7=3(cUz{tRm z!@$5G1Ce1%P%AvL}@ zGcO}YFPTBl$Jqcx7=j2R2Cy(gT4GXh4nt~1L9QW~0>uZ&DrFGCz`y{C5>Ooe`40h+ zP;pRPvokO-z{FFL#5s_}o1o$#b3l4v>SrQ}gF+D|z7r}AQj2W^M4|VBdccx zMJNL#og%AmLJ~(--vJc|xf9vHQ=sA?_i!Tl>k?EPq#oJ*U!dY3^~mOf0}|>UWOHB% z5@ZetL%qYmpjTX(TauW>pjTW{1fervtfJJMM7@&KiV_CBl*E!m2EC->Vg|jUd=N)3 zxwymxnPX_ipqHGVo12h;-33|$h)Kv@&u=EZy89fb4L&FTF9;U7V6u=A&3>hH985kIN z7#P602o%>KH4-3#fq?;(UqDJgaS9azQ^6>K4Hg0uAhloyl+a;dU;vp(u6{$PyM&r; zDAO`9Fu>9YDE)9j;~HcdOdRANs8t|gIF5iOh!0Q^P(=?)<1qVS`ayXesuZdcLU}+V k+6cmhlOX%x90mpkK?YF$gDe7NgDhiUU}%SOVHCQ40IpNhUjP6A literal 0 HcmV?d00001 diff --git a/src/openlibm/ld80/e_tgammal.c b/src/openlibm/ld80/e_tgammal.c new file mode 100644 index 0000000..036061c --- /dev/null +++ b/src/openlibm/ld80/e_tgammal.c @@ -0,0 +1,313 @@ +/* $OpenBSD: e_tgammal.c,v 1.4 2013/11/12 20:35:19 martynas Exp $ */ + +/* + * Copyright (c) 2008 Stephen L. Moshier + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* tgammal.c + * + * Gamma function + * + * + * + * SYNOPSIS: + * + * long double x, y, tgammal(); + * + * y = tgammal( x ); + * + * + * + * DESCRIPTION: + * + * Returns gamma function of the argument. The result is correctly + * signed. This variable is also filled in by the logarithmic gamma + * function lgamma(). + * + * Arguments |x| <= 13 are reduced by recurrence and the function + * approximated by a rational function of degree 7/8 in the + * interval (2,3). Large arguments are handled by Stirling's + * formula. Large negative arguments are made positive using + * a reflection formula. + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE -40,+40 10000 3.6e-19 7.9e-20 + * IEEE -1755,+1755 10000 4.8e-18 6.5e-19 + * + * Accuracy for large arguments is dominated by error in powl(). + * + */ + +#include +#include + +#include "math_private.h" + +/* +tgamma(x+2) = tgamma(x+2) P(x)/Q(x) +0 <= x <= 1 +Relative error +n=7, d=8 +Peak error = 1.83e-20 +Relative error spread = 8.4e-23 +*/ + +static long double P[8] = { + 4.212760487471622013093E-5L, + 4.542931960608009155600E-4L, + 4.092666828394035500949E-3L, + 2.385363243461108252554E-2L, + 1.113062816019361559013E-1L, + 3.629515436640239168939E-1L, + 8.378004301573126728826E-1L, + 1.000000000000000000009E0L, +}; +static long double Q[9] = { +-1.397148517476170440917E-5L, + 2.346584059160635244282E-4L, +-1.237799246653152231188E-3L, +-7.955933682494738320586E-4L, + 2.773706565840072979165E-2L, +-4.633887671244534213831E-2L, +-2.243510905670329164562E-1L, + 4.150160950588455434583E-1L, + 9.999999999999999999908E-1L, +}; + +/* +static long double P[] = { +-3.01525602666895735709e0L, +-3.25157411956062339893e1L, +-2.92929976820724030353e2L, +-1.70730828800510297666e3L, +-7.96667499622741999770e3L, +-2.59780216007146401957e4L, +-5.99650230220855581642e4L, +-7.15743521530849602425e4L +}; +static long double Q[] = { + 1.00000000000000000000e0L, +-1.67955233807178858919e1L, + 8.85946791747759881659e1L, + 5.69440799097468430177e1L, +-1.98526250512761318471e3L, + 3.31667508019495079814e3L, + 1.60577839621734713377e4L, +-2.97045081369399940529e4L, +-7.15743521530849602412e4L +}; +*/ +#define MAXGAML 1755.455L +/*static const long double LOGPI = 1.14472988584940017414L;*/ + +/* Stirling's formula for the gamma function +tgamma(x) = sqrt(2 pi) x^(x-.5) exp(-x) (1 + 1/x P(1/x)) +z(x) = x +13 <= x <= 1024 +Relative error +n=8, d=0 +Peak error = 9.44e-21 +Relative error spread = 8.8e-4 +*/ + +static long double STIR[9] = { + 7.147391378143610789273E-4L, +-2.363848809501759061727E-5L, +-5.950237554056330156018E-4L, + 6.989332260623193171870E-5L, + 7.840334842744753003862E-4L, +-2.294719747873185405699E-4L, +-2.681327161876304418288E-3L, + 3.472222222230075327854E-3L, + 8.333333333333331800504E-2L, +}; + +#define MAXSTIR 1024.0L +static const long double SQTPI = 2.50662827463100050242E0L; + +/* 1/tgamma(x) = z P(z) + * z(x) = 1/x + * 0 < x < 0.03125 + * Peak relative error 4.2e-23 + */ + +static long double S[9] = { +-1.193945051381510095614E-3L, + 7.220599478036909672331E-3L, +-9.622023360406271645744E-3L, +-4.219773360705915470089E-2L, + 1.665386113720805206758E-1L, +-4.200263503403344054473E-2L, +-6.558780715202540684668E-1L, + 5.772156649015328608253E-1L, + 1.000000000000000000000E0L, +}; + +/* 1/tgamma(-x) = z P(z) + * z(x) = 1/x + * 0 < x < 0.03125 + * Peak relative error 5.16e-23 + * Relative error spread = 2.5e-24 + */ + +static long double SN[9] = { + 1.133374167243894382010E-3L, + 7.220837261893170325704E-3L, + 9.621911155035976733706E-3L, +-4.219773343731191721664E-2L, +-1.665386113944413519335E-1L, +-4.200263503402112910504E-2L, + 6.558780715202536547116E-1L, + 5.772156649015328608727E-1L, +-1.000000000000000000000E0L, +}; + +static const long double PIL = 3.1415926535897932384626L; + +static long double stirf ( long double ); + +/* Gamma function computed by Stirling's formula. + */ +static long double stirf(long double x) +{ +long double y, w, v; + +w = 1.0L/x; +/* For large x, use rational coefficients from the analytical expansion. */ +if( x > 1024.0L ) + w = (((((6.97281375836585777429E-5L * w + + 7.84039221720066627474E-4L) * w + - 2.29472093621399176955E-4L) * w + - 2.68132716049382716049E-3L) * w + + 3.47222222222222222222E-3L) * w + + 8.33333333333333333333E-2L) * w + + 1.0L; +else + w = 1.0L + w * __polevll( w, STIR, 8 ); +y = expl(x); +if( x > MAXSTIR ) + { /* Avoid overflow in pow() */ + v = powl( x, 0.5L * x - 0.25L ); + y = v * (v / y); + } +else + { + y = powl( x, x - 0.5L ) / y; + } +y = SQTPI * y * w; +return( y ); +} + +long double +tgammal(long double x) +{ +long double p, q, z; +int i; + +if( isnan(x) ) + return(NAN); +if(x == INFINITY) + return(INFINITY); +if(x == -INFINITY) + return(x - x); +if( x == 0.0L ) + return( 1.0L / x ); +q = fabsl(x); + +if( q > 13.0L ) + { + int sign = 1; + if( q > MAXGAML ) + goto goverf; + if( x < 0.0L ) + { + p = floorl(q); + if( p == q ) + return (x - x) / (x - x); + i = p; + if( (i & 1) == 0 ) + sign = -1; + z = q - p; + if( z > 0.5L ) + { + p += 1.0L; + z = q - p; + } + z = q * sinl( PIL * z ); + z = fabsl(z) * stirf(q); + if( z <= PIL/LDBL_MAX ) + { +goverf: + return( sign * INFINITY); + } + z = PIL/z; + } + else + { + z = stirf(x); + } + return( sign * z ); + } + +z = 1.0L; +while( x >= 3.0L ) + { + x -= 1.0L; + z *= x; + } + +while( x < -0.03125L ) + { + z /= x; + x += 1.0L; + } + +if( x <= 0.03125L ) + goto small; + +while( x < 2.0L ) + { + z /= x; + x += 1.0L; + } + +if( x == 2.0L ) + return(z); + +x -= 2.0L; +p = __polevll( x, P, 7 ); +q = __polevll( x, Q, 8 ); +z = z * p / q; +return z; + +small: +if( x == 0.0L ) + return (x - x) / (x - x); +else + { + if( x < 0.0L ) + { + x = -x; + q = z / (x * __polevll( x, SN, 8 )); + } + else + q = z / (x * __polevll( x, S, 8 )); + } +return q; +} diff --git a/src/openlibm/ld80/e_tgammal.c.o b/src/openlibm/ld80/e_tgammal.c.o new file mode 100644 index 0000000000000000000000000000000000000000..cc128caf5e50a9ce68653f2d248d4343b0a98761 GIT binary patch literal 6048 zcmb<-^>JfjWMqH=Mg}_u1P><4!0-aC2k;O!a}f!j7JFQBF< z+^$h^xSgYtaPzgIvlIVuhw%|{IG{kjLU^W<$E6_4g48uv~fPUDw% zVPLp>^XAFhH7W)mm+j+VU|{g*wFQ}U^T2Hz6_9aY8*k^R2!K@FJ9+a3*ewdTb5sIg zY62i?YE%p$qL^+0g^Wk@5rum{Ul#xW|DRu;A=sn&O#s9L$QDIKwjLvWfd2HO9CUv-LHA>-b~Zumu~?%m*M6+knG)?Rd%H|H(z)(A91+% zG5Rn<{xuiWzc=pQ0Lex}{SPr2BEm240E$Nen7;(T{&I|thA6su^7hBOH*f2x@VCEX z0J#7vd;k>ZH_zPuboUm2(@RDMhMOnTCfs;@=j6>p5G}=@?%uk4>ow2KlL+^~^xpr( z-~I)n2O-HX&v5e~)IVJOEgt{>|G#fCBXH4TuZDA#?BGVMv<2c?#^yb~Yvk zhMVv1f8=jVVPs$cB@>WcFx#Qw7U>uTj>0MdQ1an#*$Ila8#hnBX1;lH!p#~LJO1r1 zDs~NLc+xsuRBU$q2l?{A%^Ve*+cGLQb5!iQWmK9UGxEFKxOwo#Lx^i2;aMhh_Xa2( z-gtTQBs^Y0>DWdE?2OmD`10(Z|Nkf4y?OWMYo@z5Zyvb!@WzLiJO6-O1}Z;pz*5S~ zrGNhaPlM;j*PSvd_deccQMq^WW%nPD<6g6Z(lsa|z)^zY0$6GDvikr3|Dg1TjxWaE zWBR_ccgk0Lh|KI68FxP(o%7~9l)q5tgG9c?(z!pNeEW*Kju+dnulcnfqCUDR_d2U& z=c+$YeoDQGQ0*5kxV&22#c<&T&zJv$>R)wyL+#`ABa>l#h$##W|DpP!d^q)b*X3(Z zRqN(_h04$Rx8)jOzuZ{rV#?k?i{_6e%~?Y>}%iOXyk!NNCBb7Rfl z*!~MJ_lmQ0R_?iO@%SfH{ZykFW(`-*?uEtw`_k=Jm%a8pg~flwljC~fe`~J%g{p@- zq~Sj*A1chi;N`4je@lDQh7VBrRbTaAL>ue9`wZph>d>o$KK70;Id;v@jdv2BVR%wUj#^K2}G4EH@0|Tg;%gDgY-~h6Sfq`KHRHp<30|Q9Bfe9i2uIv~X z7^I-$575+u!XBg^q8ee2JXHMxs07S>MKB)}>tF_)Py@5rz$7xE4d$>h2!Lq>VE|^b zfzuF}2_;OyG#dj%9?Ss~R$!71mYl&n5CO>!YzzS)4iW}sMo{VmB@rZH22U`Dl>yZ3 z0yCk6ADCuiK#$cBusAD*`=g-ZuyhUPGB7~(voi3&1fX;pm}X@F#SfSXC33(tD?AT? zxeN>pMPLRig9eyJ5EWo18$$t@Mi6yiCL04RzQJ4u1_ns$n-wFRyTA%q8C1YDf&j%c zdR&2Ir!p{LgaJr=77pKGt1<-ZG6btL1S>Rx$b!`yK}-i5Z)D7nT2YY0P>^4q!w?@|ke`!UmXpH( zbs$50d}eW8VqOkIT4GXh4ntZ_etuC7Lvdza4kD~U*_exgf#DCR`ThU@eFJEfrFAaju2rNaFXQ;vjRxk;K0tiG#`(n7u|Ih0t^&iKHG@FMy;$;Z_4;fa(t@ z4YC(G+!jE^K@>>+9jJX9KmySCLRNnTDh{HM!{HG~0O}r4T?BI{AIMOsIiRu#CY}Tp z2Wdl&m&s6ZkUK#`Dlqjck;IY1?G#iTWR5gaI6OfTM|S6LBymvP2s2*|WFgf3vPk9_ zAc-S~a|Mz(vicoJ;vlPF=AVFygDB+i{09<%+KcQ?D`*uA@)yXQIiN%aZIgkRAaM`| zu|XJCKZ3+S7*;Mb=oMGymLw)I=oOa~LFfz^t0*-mQLiMmqJ%*&C9x!tK`*Jem_e^7 zAH>m1E-o=a<`|kW=q2ap=BDPAFzDswm!#^s`-SQjmn0@rFsQL`30#(C6x?% zV8c^0;?s%}b5lVsqzr??43sp{TOiQpE`tv=ykNF~$}kukM1#@>D5zoTL1G~M0aQ3L zFfdqvBpDdM^*YENSo;B#=RoQ}?H`ahC@w&J7+wIg7fk}>UYHsX4QdC2%tTYhumB_o zQhDAazC7&7jM>PHp>v0?f^Y!C(|A<$48C~brIFgyXOAKhJ0 zZ^4u?)I#k?*M9)2{{~zogn_Of)Gh;sDSG=S^aJt_y4@g~ zW`Gof%4cZ80M+53`U_n@$eB800ZqTh;UW+Q$UX=QLW0UzZ2BXh?r(=EgOlj` E0eRS`D*ylh literal 0 HcmV?d00001 diff --git a/src/openlibm/ld80/invtrig.c b/src/openlibm/ld80/invtrig.c new file mode 100644 index 0000000..15692ad --- /dev/null +++ b/src/openlibm/ld80/invtrig.c @@ -0,0 +1,82 @@ +/*- + * Copyright (c) 2008 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/ld80/invtrig.c,v 1.1 2008/07/31 22:41:26 das Exp $"); + +#include "ld80/invtrig.h" + +/* + * asinl() and acosl() + */ +const long double +pS0 = 1.66666666666666666631e-01L, +pS1 = -4.16313987993683104320e-01L, +pS2 = 3.69068046323246813704e-01L, +pS3 = -1.36213932016738603108e-01L, +pS4 = 1.78324189708471965733e-02L, +pS5 = -2.19216428382605211588e-04L, +pS6 = -7.10526623669075243183e-06L, +qS1 = -2.94788392796209867269e+00L, +qS2 = 3.27309890266528636716e+00L, +qS3 = -1.68285799854822427013e+00L, +qS4 = 3.90699412641738801874e-01L, +qS5 = -3.14365703596053263322e-02L; + +/* + * atanl() + */ +const long double atanhi[] = { + 4.63647609000806116202e-01L, + 7.85398163397448309628e-01L, + 9.82793723247329067960e-01L, + 1.57079632679489661926e+00L, +}; + +const long double atanlo[] = { + 1.18469937025062860669e-20L, + -1.25413940316708300586e-20L, + 2.55232234165405176172e-20L, + -2.50827880633416601173e-20L, +}; + +const long double aT[] = { + 3.33333333333333333017e-01L, + -1.99999999999999632011e-01L, + 1.42857142857046531280e-01L, + -1.11111111100562372733e-01L, + 9.09090902935647302252e-02L, + -7.69230552476207730353e-02L, + 6.66661718042406260546e-02L, + -5.88158892835030888692e-02L, + 5.25499891539726639379e-02L, + -4.70119845393155721494e-02L, + 4.03539201366454414072e-02L, + -2.91303858419364158725e-02L, + 1.24822046299269234080e-02L, +}; + +const long double pi_lo = -5.01655761266833202345e-20L; diff --git a/src/openlibm/ld80/invtrig.c.o b/src/openlibm/ld80/invtrig.c.o new file mode 100644 index 0000000000000000000000000000000000000000..fa95cf03d5c0aaa8fc6a40c44793e07e389307e3 GIT binary patch literal 2136 zcmb<-^>JfjWMqH=Mg}_u1P><4z%YXq!FB*M9T>P7xEOZ#^#8e7`s~fV{a`^1V*V-! z_-hZ5+LLq!4E{jX+sp0nn55!4=?_%?scpXDV~f7WzoGJ3MGc2~yY+VchRPqQYdN;% zYUf;-eEG4N2C{A)9WZ&#I~u|K?_PZP1=a8MbeD?n3cKsSp!%&8Z{BHK+1H_ z`9;lZDNO#F)%(Z`Hx|A73DqCCVag6I&89Oyp!y-cK#=TGr4={3Pu$-Fm4}7L9;p82 zLzBxT>qIiw-xy{ImVShMo5haGrpfr{i<}q~MeE>;IwlY5IgcyjWaykpU8k3=7Oe4n!)h z+QV=F;-|pO?SD5M&3yM3s=g;6Mbe?{?$b|DzRZ7XD^73GNk5_X^EUq!wOv)+4U5n7 zncrTntogPFX8*75Ei==k)vx}A>R$m#4y$1C&EW3rY^9*#?iZ@5U}&Oeq-UsLWME`! zU}$Kdpb?asqTrEO0+rA;*JNN|VPIfTU|?VXB}aF^PzELj#seTRi0c^`7@>S@X&9yk zM1$m67(V_7v5_%10|SE~*cOPW0EA)?gNlRf1_@mN5ey6ra!_$trhx`4gBDcW0b~&a z11z{1%%I{8P;r>~px^}AI{{7H1FC)jns^{od;^+z6jb~Gns_o)`~sSI4pjUBns_Nx z`~#YJ9aNlw2@(J>_qRjE1<=GNK*bf%#Aiaq4ba3HGV{txiZavnk{RMXOMK!BGUIdd zANTK`>NTK`>NT zK`>mG0Rw|xab<2vViJR1aY+$`&VaE>QY%Ur^imQ_5*hT8ii;Wait-_xJyuiS~hGr5heWD4&k}q6X z5vrdVE&^c?t6!agfq{d8fq`88I#Bze$pd0JQa*A(lYr$*m_ie%egl{Qlx~3P(}(h5 z6f~K`!@(A+A0`i@*F*Kg_%Ir#AIA4(U|?WpV1Q*4m@vZzsD5;Jfx-%|2x>P}DY7ub z1E?S@-*ZCkfa#Zjss@RphdoGY0<^GP1mYlJboUEli93*TBT&K1z`&3I;vivk{Q%YZ BK|}xm literal 0 HcmV?d00001 diff --git a/src/openlibm/ld80/invtrig.h b/src/openlibm/ld80/invtrig.h new file mode 100644 index 0000000..3d543e9 --- /dev/null +++ b/src/openlibm/ld80/invtrig.h @@ -0,0 +1,114 @@ +/*- + * Copyright (c) 2008 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/msun/ld80/invtrig.h,v 1.2 2008/08/02 03:56:22 das Exp $ + */ + +#include + +#include + +#define BIAS (LDBL_MAX_EXP - 1) +#define MANH_SIZE LDBL_MANH_SIZE + +/* Approximation thresholds. */ +#define ASIN_LINEAR (BIAS - 32) /* 2**-32 */ +#define ACOS_CONST (BIAS - 65) /* 2**-65 */ +#define ATAN_CONST (BIAS + 65) /* 2**65 */ +#define ATAN_LINEAR (BIAS - 32) /* 2**-32 */ + +/* 0.95 */ +#define THRESH ((0xe666666666666666ULL>>(64-(MANH_SIZE-1)))|LDBL_NBIT) + +/* Constants shared by the long double inverse trig functions. */ +#define pS0 _ItL_pS0 +#define pS1 _ItL_pS1 +#define pS2 _ItL_pS2 +#define pS3 _ItL_pS3 +#define pS4 _ItL_pS4 +#define pS5 _ItL_pS5 +#define pS6 _ItL_pS6 +#define qS1 _ItL_qS1 +#define qS2 _ItL_qS2 +#define qS3 _ItL_qS3 +#define qS4 _ItL_qS4 +#define qS5 _ItL_qS5 +#define atanhi _ItL_atanhi +#define atanlo _ItL_atanlo +#define aT _ItL_aT +#define pi_lo _ItL_pi_lo + +#define pio2_hi atanhi[3] +#define pio2_lo atanlo[3] +#define pio4_hi atanhi[1] + +#ifdef STRUCT_DECLS +typedef struct longdouble { + uint64_t mant; + uint16_t expsign; +} LONGDOUBLE; +#else +typedef long double LONGDOUBLE; +#endif + +extern const LONGDOUBLE pS0, pS1, pS2, pS3, pS4, pS5, pS6; +extern const LONGDOUBLE qS1, qS2, qS3, qS4, qS5; +extern const LONGDOUBLE atanhi[], atanlo[], aT[]; +extern const LONGDOUBLE pi_lo; + +#ifndef STRUCT_DECLS + +static inline long double +P(long double x) +{ + + return (x * (pS0 + x * (pS1 + x * (pS2 + x * (pS3 + x * \ + (pS4 + x * (pS5 + x * pS6))))))); +} + +static inline long double +Q(long double x) +{ + + return (1.0 + x * (qS1 + x * (qS2 + x * (qS3 + x * (qS4 + x * qS5))))); +} + +static inline long double +T_even(long double x) +{ + + return (aT[0] + x * (aT[2] + x * (aT[4] + x * (aT[6] + x * \ + (aT[8] + x * (aT[10] + x * aT[12])))))); +} + +static inline long double +T_odd(long double x) +{ + + return (aT[1] + x * (aT[3] + x * (aT[5] + x * (aT[7] + x * \ + (aT[9] + x * aT[11]))))); +} + +#endif diff --git a/src/openlibm/ld80/k_cosl.c b/src/openlibm/ld80/k_cosl.c new file mode 100644 index 0000000..403da9d --- /dev/null +++ b/src/openlibm/ld80/k_cosl.c @@ -0,0 +1,78 @@ +/* From: @(#)k_cos.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * Copyright (c) 2008 Steven G. Kargl, David Schultz, Bruce D. Evans. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/ld80/k_cosl.c,v 1.1 2008/02/17 07:32:14 das Exp $"); + +/* + * ld80 version of k_cos.c. See ../src/k_cos.c for most comments. + */ + +#include "math_private.h" + +/* + * Domain [-0.7854, 0.7854], range ~[-2.43e-23, 2.425e-23]: + * |cos(x) - c(x)| < 2**-75.1 + * + * The coefficients of c(x) were generated by a pari-gp script using + * a Remez algorithm that searches for the best higher coefficients + * after rounding leading coefficients to a specified precision. + * + * Simpler methods like Chebyshev or basic Remez barely suffice for + * cos() in 64-bit precision, because we want the coefficient of x^2 + * to be precisely -0.5 so that multiplying by it is exact, and plain + * rounding of the coefficients of a good polynomial approximation only + * gives this up to about 64-bit precision. Plain rounding also gives + * a mediocre approximation for the coefficient of x^4, but a rounding + * error of 0.5 ulps for this coefficient would only contribute ~0.01 + * ulps to the final error, so this is unimportant. Rounding errors in + * higher coefficients are even less important. + * + * In fact, coefficients above the x^4 one only need to have 53-bit + * precision, and this is more efficient. We get this optimization + * almost for free from the complications needed to search for the best + * higher coefficients. + */ +static const double +one = 1.0; + +#if defined(__amd64__) || defined(__i386__) +/* Long double constants are slow on these arches, and broken on i386. */ +static const volatile double +C1hi = 0.041666666666666664, /* 0x15555555555555.0p-57 */ +C1lo = 2.2598839032744733e-18; /* 0x14d80000000000.0p-111 */ +#define C1 ((long double)C1hi + C1lo) +#else +static const long double +C1 = 0.0416666666666666666136L; /* 0xaaaaaaaaaaaaaa9b.0p-68 */ +#endif + +static const double +C2 = -0.0013888888888888874, /* -0x16c16c16c16c10.0p-62 */ +C3 = 0.000024801587301571716, /* 0x1a01a01a018e22.0p-68 */ +C4 = -0.00000027557319215507120, /* -0x127e4fb7602f22.0p-74 */ +C5 = 0.0000000020876754400407278, /* 0x11eed8caaeccf1.0p-81 */ +C6 = -1.1470297442401303e-11, /* -0x19393412bd1529.0p-89 */ +C7 = 4.7383039476436467e-14; /* 0x1aac9d9af5c43e.0p-97 */ + +long double +__kernel_cosl(long double x, long double y) +{ + long double hz,z,r,w; + + z = x*x; + r = z*(C1+z*(C2+z*(C3+z*(C4+z*(C5+z*(C6+z*C7)))))); + hz = 0.5*z; + w = one-hz; + return w + (((one-w)-hz) + (z*r-x*y)); +} diff --git a/src/openlibm/ld80/k_cosl.c.o b/src/openlibm/ld80/k_cosl.c.o new file mode 100644 index 0000000000000000000000000000000000000000..d509ba43abd182b445a2122b8611c11a49aa3db2 GIT binary patch literal 2216 zcmb<-^>JfjWMqH=Mg}_u1P><4z_5Y^!FB*M9T)@{_!(~JsBqjoaO31%R*)csym{yb zFNk;Z#mxgZ9^E{82h6*p3KF|gH2gPy@hS@W?J3Ct`Xt?`@YAP6-=o#r5Di|3U znHm@x8YpN4rKTu&B$hxWbj>vx7(l_Gz`(!&@`SrzC<7A%;{lKu$T=X)2<5}VPy{5% zz`(#*6~w?;A;2ij!_F~*k%0juE(4V-h0^#aka;W&AOB-h!;B@yxIlI?urhE!HNa?o zs5n#@E)U`}gM9^JAu!0D3=C`t0VqonOtXVYWI_(iVMj3+B%}-?7}yyEz%+u;05jPc zB)~L+&;>Ku89-qTWY(Ff*$33CPp1|g(yfQM;zd~$wqj$Sf@vtdRigR@~y zK7*c*vjK=O0uja_!URN^f(SDZVa^aApPgEimzo3C46*l^)PV_ zW(eyBgkk^{bs&2{aR?HEr2|mBgT$fAK~iA66-;6hAhpP%p!5MUlU)6V;Cv5BcgW`M zfO63N3$hC;1*R;a`h~ze1aSh&gyjb)7hFz)*f4Q79QrSS6frO`7(i(l1+yPU2SfFv ztAk~EeV9fl4GTXQ9Rt-5m4;LLFa>ZC2m@U>hk=0slwVQu2*}+~h3M{rxf@~{149ec zesui_MCz}{k^W!-4NGUB^aslKF#BQRAZyU=2DuGX7lG&ikOBq<20jJ`a2iI}4=Q`m k(;i6Q1E`^{APy3S8V45FY+Aq;f=045UqHUIzs literal 0 HcmV?d00001 diff --git a/src/openlibm/ld80/k_sinl.c b/src/openlibm/ld80/k_sinl.c new file mode 100644 index 0000000..792baf6 --- /dev/null +++ b/src/openlibm/ld80/k_sinl.c @@ -0,0 +1,62 @@ +/* From: @(#)k_sin.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * Copyright (c) 2008 Steven G. Kargl, David Schultz, Bruce D. Evans. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/ld80/k_sinl.c,v 1.1 2008/02/17 07:32:14 das Exp $"); + +/* + * ld80 version of k_sin.c. See ../src/k_sin.c for most comments. + */ + +#include "math_private.h" + +static const double +half = 0.5; + +/* + * Domain [-0.7854, 0.7854], range ~[-1.89e-22, 1.915e-22] + * |sin(x)/x - s(x)| < 2**-72.1 + * + * See ../ld80/k_cosl.c for more details about the polynomial. + */ +#if defined(__amd64__) || defined(__i386__) +/* Long double constants are slow on these arches, and broken on i386. */ +static const volatile double +S1hi = -0.16666666666666666, /* -0x15555555555555.0p-55 */ +S1lo = -9.2563760475949941e-18; /* -0x15580000000000.0p-109 */ +#define S1 ((long double)S1hi + S1lo) +#else +static const long double +S1 = -0.166666666666666666671L; /* -0xaaaaaaaaaaaaaaab.0p-66 */ +#endif + +static const double +S2 = 0.0083333333333333332, /* 0x11111111111111.0p-59 */ +S3 = -0.00019841269841269427, /* -0x1a01a01a019f81.0p-65 */ +S4 = 0.0000027557319223597490, /* 0x171de3a55560f7.0p-71 */ +S5 = -0.000000025052108218074604, /* -0x1ae64564f16cad.0p-78 */ +S6 = 1.6059006598854211e-10, /* 0x161242b90243b5.0p-85 */ +S7 = -7.6429779983024564e-13, /* -0x1ae42ebd1b2e00.0p-93 */ +S8 = 2.6174587166648325e-15; /* 0x179372ea0b3f64.0p-101 */ + +long double +__kernel_sinl(long double x, long double y, int iy) +{ + long double z,r,v; + + z = x*x; + v = z*x; + r = S2+z*(S3+z*(S4+z*(S5+z*(S6+z*(S7+z*S8))))); + if(iy==0) return x+v*(S1+z*r); + else return x-((z*(half*y-v*r)-y)-v*S1); +} diff --git a/src/openlibm/ld80/k_sinl.c.o b/src/openlibm/ld80/k_sinl.c.o new file mode 100644 index 0000000000000000000000000000000000000000..9dac288150bf00d203fa3d0d72e7c08099eb81d4 GIT binary patch literal 2368 zcmb<-^>JfjWMqH=Mg}_u1P><4z~I1�E1R7z7yj8E)sOaNN#Ok+^yA#;Kc!Zk)V% z@D49X`i?4yym9IdSl^9P`1!5>OV#e)zIpQIsk>nH5c1x^nWC^bdFBe4W3p=+)Qv6_W}fkAATfw60|O(J4-0b^4py<~=9!;DOZV8fhz20b5V0}x>dB8)(UF^Dh$5vCx*3`CeS z#K&i+7UiYpfK7l}1_>ty1||kbX#M#Q0a8$TkT}S7FmWX$aZudA#I=ybIT;ujVB!#e zL(B)oElk`BNj*1`dM6}t9whM~Bymt0hNayIG;x^uMQGwM^%ZF1F!kU}%>Z#HC^N&v zL3swG1r!b-3}S<^UU6k^Nn#R%UU5kggwBAmic)hD^-5AJN*MG~5=#;p^pc8;8T5+s zAsh&;mt0(80TTpqOc?Z%^K)}k^GX=>^72bk_1yhJb&E?9le3}x^t@8Nf};F_)S{9~ z20gGHsTuKUMTxnoUC}}mIBCd z1_lOD*n*g#v;&fXRy761SM literal 0 HcmV?d00001 diff --git a/src/openlibm/ld80/k_tanl.c b/src/openlibm/ld80/k_tanl.c new file mode 100644 index 0000000..691c952 --- /dev/null +++ b/src/openlibm/ld80/k_tanl.c @@ -0,0 +1,125 @@ +/* From: @(#)k_tan.c 1.5 04/04/22 SMI */ + +/* + * ==================================================== + * Copyright 2004 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2008 Steven G. Kargl, David Schultz, Bruce D. Evans. + * + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/ld80/k_tanl.c,v 1.3 2008/02/18 15:39:52 bde Exp $"); + +/* + * ld80 version of k_tan.c. See ../src/k_tan.c for most comments. + */ + +#include + +#include "math_private.h" + +/* + * Domain [-0.67434, 0.67434], range ~[-2.25e-22, 1.921e-22] + * |tan(x)/x - t(x)| < 2**-71.9 + * + * See k_cosl.c for more details about the polynomial. + */ +#if defined(__amd64__) || defined(__i386__) +/* Long double constants are slow on these arches, and broken on i386. */ +static const volatile double +T3hi = 0.33333333333333331, /* 0x15555555555555.0p-54 */ +T3lo = 1.8350121769317163e-17, /* 0x15280000000000.0p-108 */ +T5hi = 0.13333333333333336, /* 0x11111111111112.0p-55 */ +T5lo = 1.3051083651294260e-17, /* 0x1e180000000000.0p-109 */ +T7hi = 0.053968253968250494, /* 0x1ba1ba1ba1b827.0p-57 */ +T7lo = 3.1509625637859973e-18, /* 0x1d100000000000.0p-111 */ +pio4_hi = 0.78539816339744828, /* 0x1921fb54442d18.0p-53 */ +pio4_lo = 3.0628711372715500e-17, /* 0x11a80000000000.0p-107 */ +pio4lo_hi = -1.2541394031670831e-20, /* -0x1d9cceba3f91f2.0p-119 */ +pio4lo_lo = 6.1493048227390915e-37; /* 0x1a280000000000.0p-173 */ +#define T3 ((long double)T3hi + T3lo) +#define T5 ((long double)T5hi + T5lo) +#define T7 ((long double)T7hi + T7lo) +#define pio4 ((long double)pio4_hi + pio4_lo) +#define pio4lo ((long double)pio4lo_hi + pio4lo_lo) +#else +static const long double +T3 = 0.333333333333333333180L, /* 0xaaaaaaaaaaaaaaa5.0p-65 */ +T5 = 0.133333333333333372290L, /* 0x88888888888893c3.0p-66 */ +T7 = 0.0539682539682504975744L, /* 0xdd0dd0dd0dc13ba2.0p-68 */ +pio4 = 0.785398163397448309628L, /* 0xc90fdaa22168c235.0p-64 */ +pio4lo = -1.25413940316708300586e-20L; /* -0xece675d1fc8f8cbb.0p-130 */ +#endif + +static const double +T9 = 0.021869488536312216, /* 0x1664f4882cc1c2.0p-58 */ +T11 = 0.0088632355256619590, /* 0x1226e355c17612.0p-59 */ +T13 = 0.0035921281113786528, /* 0x1d6d3d185d7ff8.0p-61 */ +T15 = 0.0014558334756312418, /* 0x17da354aa3f96b.0p-62 */ +T17 = 0.00059003538700862256, /* 0x13559358685b83.0p-63 */ +T19 = 0.00023907843576635544, /* 0x1f56242026b5be.0p-65 */ +T21 = 0.000097154625656538905, /* 0x1977efc26806f4.0p-66 */ +T23 = 0.000038440165747303162, /* 0x14275a09b3ceac.0p-67 */ +T25 = 0.000018082171885432524, /* 0x12f5e563e5487e.0p-68 */ +T27 = 0.0000024196006108814377, /* 0x144c0d80cc6896.0p-71 */ +T29 = 0.0000078293456938132840, /* 0x106b59141a6cb3.0p-69 */ +T31 = -0.0000032609076735050182, /* -0x1b5abef3ba4b59.0p-71 */ +T33 = 0.0000023261313142559411; /* 0x13835436c0c87f.0p-71 */ + +long double +__kernel_tanl(long double x, long double y, int iy) { + long double z, r, v, w, s; + long double osign; + int i; + + iy = (iy == 1 ? -1 : 1); /* XXX recover original interface */ + osign = (x >= 0 ? 1.0 : -1.0); /* XXX slow, probably wrong for -0 */ + if (fabsl(x) >= 0.67434) { + if (x < 0) { + x = -x; + y = -y; + } + z = pio4 - x; + w = pio4lo - y; + x = z + w; + y = 0.0; + i = 1; + } else + i = 0; + z = x * x; + w = z * z; + r = T5 + w * (T9 + w * (T13 + w * (T17 + w * (T21 + + w * (T25 + w * (T29 + w * T33)))))); + v = z * (T7 + w * (T11 + w * (T15 + w * (T19 + w * (T23 + + w * (T27 + w * T31)))))); + s = z * x; + r = y + z * (s * (r + v) + y); + r += T3 * s; + w = x + r; + if (i == 1) { + v = (long double) iy; + return osign * + (v - 2.0 * (x - (w * w / (w + v) - r))); + } + if (iy == 1) + return w; + else { + /* + * if allow error up to 2 ulp, simply return + * -1.0 / (x+r) here + */ + /* compute -1.0 / (x+r) accurately */ + long double a, t; + z = w; + z = z + 0x1p32 - 0x1p32; + v = r - (z - x); /* z+v = r+x */ + t = a = -1.0 / w; /* a = -1.0/w */ + t = t + 0x1p32 - 0x1p32; + s = 1.0 + t * z; + return t + a * (s + t * v); + } +} diff --git a/src/openlibm/ld80/k_tanl.c.o b/src/openlibm/ld80/k_tanl.c.o new file mode 100644 index 0000000000000000000000000000000000000000..d8c4bad69522e0c9d7aea67c124d0688401f1e8e GIT binary patch literal 3824 zcmb<-^>JfjWMqH=Mg}_u1P><4!0>?!!FB*M9T)@{_!)u?Z+kSqQE2|pcsobMfPd=Y z-Wcisw{uh+Zoa#D>h`C*xA>b985tPv-tcICBXHYB!5gP;9=LH5qUsaB09f@WegR&Pu21{|q7YipMTO($kx%@BJ}Lq? zPJiMT3{jD|dFT#U)g7>&8>fk-Z=Sm2qQY_S5NZ1Foxba$B5=n=MdIG!o2PD^zIX7( z$s337ow|AQ-XVzVA>_S-_fFnBc=OkaQ_a5_ON?)V-3pSu z@$lx0n-A`NzIo`zp?i<+Jh^%L-jh40@0_~%;@;t#r|%sCnev*QU!LLa&AT@}nvW<% zA5P6qnju1y}Ehw#({e;@0~o%FW&-+GX{|NK=!;8`}hApjPtq^EXSacW$|gE z{jPI!&h7>atZ1~6&~*vaQ=Zz_pEzI^(tOx%bB>fqWcCBQI*+HxPrrV$`@)uS=zY1QeRFh1#N<$C`ychO z61KUy_J+`;-)BC1noN3_oIbyfw+-A-wbr$=5Th$a)!u0L4e=hbi zy%laRRCX}*v09To14Dy9gS)e{m4b%5U#O;np^2W6o}q$~fsv_!p`n3-Mo?;sf=6Nr zR6^HW6YL`f76t|e1qKENPzrGO3uRzpU_1a40|h-u1tXNt4dO5`Fo-~D#;PC&#tH#O zX&!ct35*O3HVh05GEg~pCI$uuM?QgOCO1BVG(HDUJ_|=a17=S~E^P$S&_Ja7#;MfDP5ZDLIWCN4PL?D>MhN2%N6b2#~*cf2$0dpA`7^1-pHU^mc z!CVFgh6FH!4V-qsOem2Grr8)k{suFlL>8E4V*vRZ%!Cs8V44jcUtlf+14Aj8!Nvd! zPcWB(fuS1AU}J!VKbXtFz|aV0urUOHX#~*@X0kCvfN2EL3udxG{Q>5HiOFD+jUfX} zBZ!$`COeo!Cgw9RFbE-~LvY$>U|?9wzhU7+fe(ZoUJ zIY`PKNgNdRFneb~#X)ria(Y+<6$ix^a(cLgBo49{6m}r1jRQEE=2UP)?234>lrVo4%{UQ%%} zgI-ZSgae`Vl8Z|$V1giy34>m8er|4RUI~L!_@P?TSg zT2xZWpa-@iH6uQ)C@~jOHiBJ6HUaV{CVj_==wdN9s-3eOfQIr z@nLi@R6lw>=mXWS57LB$L2dsNu%I0B>i2(jTZ%2-6Qs zf7t8>xs3xFz%QT<1C>3pNbNJ2eoh9=v2, else + * := signl(x)*log1pl(|x| + x^2/(1 + sqrtl(1+x^2))) + */ + +#include + +#include "math_private.h" + +static const long double +one = 1.000000000000000000000e+00L, /* 0x3FFF, 0x00000000, 0x00000000 */ +ln2 = 6.931471805599453094287e-01L, /* 0x3FFE, 0xB17217F7, 0xD1CF79AC */ +huge= 1.000000000000000000e+4900L; + +long double +asinhl(long double x) +{ + long double t,w; + int32_t hx,ix; + GET_LDOUBLE_EXP(hx,x); + ix = hx&0x7fff; + if(ix==0x7fff) return x+x; /* x is inf or NaN */ + if(ix< 0x3fde) { /* |x|<2**-34 */ + if(huge+x>one) return x; /* return x inexact except 0 */ + } + if(ix>0x4020) { /* |x| > 2**34 */ + w = logl(fabsl(x))+ln2; + } else if (ix>0x4000) { /* 2**34 > |x| > 2.0 */ + t = fabsl(x); + w = logl(2.0*t+one/(sqrtl(x*x+one)+t)); + } else { /* 2.0 > |x| > 2**-28 */ + t = x*x; + w =log1pl(fabsl(x)+t/(one+sqrtl(one+t))); + } + if(hx&0x8000) return -w; else return w; +} diff --git a/src/openlibm/ld80/s_asinhl.c.o b/src/openlibm/ld80/s_asinhl.c.o new file mode 100644 index 0000000000000000000000000000000000000000..383d27855ea705e2bdec7b3d71cf52b71fc0ef43 GIT binary patch literal 2144 zcmb<-^>JfjWMqH=Mg}_u1P><4!0>GE z`@f#QWg7znLz?Yf`#Og-TLlOHJ`n$ZiHZdXzX0j>XnrGb+eQV-KB92*?Y)C(t+y+g zZa(m6KB5qPm|wmHq>kaXE{M9FqhfI9;LR5|Pu>4?_h$K>yEi~0AVY2*xN+ikjS7-s zZv<}Fs2JRQaXUvv;od=*B@t0KU)(!*J4Z#}-bYlK$hg<7X?k$`a#Re!F1T^vFu%M5 zLz*pvL)|2hyFnQ0-Zug_58OC-^CZZk+chc*w{uhiZkzyH0QFP6V+6#On=ioj2_RhJ z80i@GQsDpp{~(Vs99&`^sm?NK-IRJTmx00E+1W}#!`&}bQ^C+g&q&Wu!N|bK)WFct zKtUrYHATTAu>>liYp%(_0E!j`1_lOJ1_lOqzfcAy2F3#*F<2ZjLix;4<3*q}V^t6X zV}$^tG!Hw+1V#pi7zPFg8K|5!NV6lKKr@pIpFt*{g$tj9CtrXMpMgIYpMWDDhbMOe zpF;>=Kq#MwBcDSgpM@izK?p?3o!bkhK9SGEiO(U5&%%k%0BSH63S<=v!$(M9pvg01 zNr^mQH6Y)D8E`_7fq_8?Nj=yP3=9ks3=9kca8(F~91d}19O9Zd#2Jd?6N@wRGII2i z8T5Rd4HzIihP1?_;v9yY{PY}#;=-a5Fw?Lghrt-?1W+7-eDUW$1lS{qvoSC*z{HcF z;!F$-44^oKiT6Oo(al+cB+iax&ORh@4kYpSNaD!u5e7vJ10;PRo1=#$j_giQ8Uz^y zawiCb*kG(zT$x*vn8cu0Tv7y~GhnQu)SN`UlGKV42ECNTl0*i*q~c-*y`p>&M=!a! z#L$dEFF8LqH#M(>K`$@ABvsGdFI2a!fR5?fpjH^M80<%yFbYUF^1_qFs~XDpV;<2uvq{EMs6`r~>m41iF3z4=Y5X literal 0 HcmV?d00001 diff --git a/src/openlibm/ld80/s_ceill.c b/src/openlibm/ld80/s_ceill.c new file mode 100644 index 0000000..9a3e805 --- /dev/null +++ b/src/openlibm/ld80/s_ceill.c @@ -0,0 +1,78 @@ +/* @(#)s_ceil.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * ceill(x) + * Return x rounded toward -inf to integral value + * Method: + * Bit twiddling. + * Exception: + * Inexact flag raised if x not equal to ceil(x). + */ + +#include + +#include "math_private.h" + +static const long double huge = 1.0e4930L; + +long double +ceill(long double x) +{ + int32_t i1,jj0; + u_int32_t i,j,se,i0,sx; + GET_LDOUBLE_WORDS(se,i0,i1,x); + sx = (se>>15)&1; + jj0 = (se&0x7fff)-0x3fff; + if(jj0<31) { + if(jj0<0) { /* raise inexact if x != 0 */ + if(huge+x>0.0) {/* return 0*sign(x) if |x|<1 */ + if(sx) {se=0x8000;i0=0;i1=0;} + else if((i0|i1)!=0) { se=0x3fff;i0=0;i1=0;} + } + } else { + i = (0x7fffffff)>>jj0; + if(((i0&i)|i1)==0) return x; /* x is integral */ + if(huge+x>0.0) { /* raise inexact flag */ + if(sx==0) { + if (jj0>0 && (i0+(0x80000000>>jj0))>i0) + i0+=0x80000000>>jj0; + else + { + i = 0x7fffffff; + ++se; + } + } + i0 &= (~i); i1=0; + } + } + } else if (jj0>62) { + if(jj0==0x4000) return x+x; /* inf or NaN */ + else return x; /* x is integral */ + } else { + i = ((u_int32_t)(0xffffffff))>>(jj0-31); + if((i1&i)==0) return x; /* x is integral */ + if(huge+x>0.0) { /* raise inexact flag */ + if(sx==0) { + if(jj0==31) i0+=1; + else { + j = i1 + (1<<(63-jj0)); + if(j + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* double erf(double x) + * double erfc(double x) + * x + * 2 |\ + * erf(x) = --------- | exp(-t*t)dt + * sqrt(pi) \| + * 0 + * + * erfc(x) = 1-erf(x) + * Note that + * erf(-x) = -erf(x) + * erfc(-x) = 2 - erfc(x) + * + * Method: + * 1. For |x| in [0, 0.84375] + * erf(x) = x + x*R(x^2) + * erfc(x) = 1 - erf(x) if x in [-.84375,0.25] + * = 0.5 + ((0.5-x)-x*R) if x in [0.25,0.84375] + * Remark. The formula is derived by noting + * erf(x) = (2/sqrt(pi))*(x - x^3/3 + x^5/10 - x^7/42 + ....) + * and that + * 2/sqrt(pi) = 1.128379167095512573896158903121545171688 + * is close to one. The interval is chosen because the fix + * point of erf(x) is near 0.6174 (i.e., erf(x)=x when x is + * near 0.6174), and by some experiment, 0.84375 is chosen to + * guarantee the error is less than one ulp for erf. + * + * 2. For |x| in [0.84375,1.25], let s = |x| - 1, and + * c = 0.84506291151 rounded to single (24 bits) + * erf(x) = sign(x) * (c + P1(s)/Q1(s)) + * erfc(x) = (1-c) - P1(s)/Q1(s) if x > 0 + * 1+(c+P1(s)/Q1(s)) if x < 0 + * Remark: here we use the taylor series expansion at x=1. + * erf(1+s) = erf(1) + s*Poly(s) + * = 0.845.. + P1(s)/Q1(s) + * Note that |P1/Q1|< 0.078 for x in [0.84375,1.25] + * + * 3. For x in [1.25,1/0.35(~2.857143)], + * erfc(x) = (1/x)*exp(-x*x-0.5625+R1(z)/S1(z)) + * z=1/x^2 + * erf(x) = 1 - erfc(x) + * + * 4. For x in [1/0.35,107] + * erfc(x) = (1/x)*exp(-x*x-0.5625+R2/S2) if x > 0 + * = 2.0 - (1/x)*exp(-x*x-0.5625+R2(z)/S2(z)) + * if -6.666 x >= 107 + * erf(x) = sign(x) *(1 - tiny) (raise inexact) + * erfc(x) = tiny*tiny (raise underflow) if x > 0 + * = 2 - tiny if x<0 + * + * 7. Special case: + * erf(0) = 0, erf(inf) = 1, erf(-inf) = -1, + * erfc(0) = 1, erfc(inf) = 0, erfc(-inf) = 2, + * erfc/erf(NaN) is NaN + */ + + +#include + +#include "math_private.h" + +static const long double +tiny = 1e-4931L, + half = 0.5L, + one = 1.0L, + two = 2.0L, + /* c = (float)0.84506291151 */ + erx = 0.845062911510467529296875L, +/* + * Coefficients for approximation to erf on [0,0.84375] + */ + /* 2/sqrt(pi) - 1 */ + efx = 1.2837916709551257389615890312154517168810E-1L, + /* 8 * (2/sqrt(pi) - 1) */ + efx8 = 1.0270333367641005911692712249723613735048E0L, + + pp[6] = { + 1.122751350964552113068262337278335028553E6L, + -2.808533301997696164408397079650699163276E6L, + -3.314325479115357458197119660818768924100E5L, + -6.848684465326256109712135497895525446398E4L, + -2.657817695110739185591505062971929859314E3L, + -1.655310302737837556654146291646499062882E2L, + }, + + qq[6] = { + 8.745588372054466262548908189000448124232E6L, + 3.746038264792471129367533128637019611485E6L, + 7.066358783162407559861156173539693900031E5L, + 7.448928604824620999413120955705448117056E4L, + 4.511583986730994111992253980546131408924E3L, + 1.368902937933296323345610240009071254014E2L, + /* 1.000000000000000000000000000000000000000E0 */ + }, + +/* + * Coefficients for approximation to erf in [0.84375,1.25] + */ +/* erf(x+1) = 0.845062911510467529296875 + pa(x)/qa(x) + -0.15625 <= x <= +.25 + Peak relative error 8.5e-22 */ + + pa[8] = { + -1.076952146179812072156734957705102256059E0L, + 1.884814957770385593365179835059971587220E2L, + -5.339153975012804282890066622962070115606E1L, + 4.435910679869176625928504532109635632618E1L, + 1.683219516032328828278557309642929135179E1L, + -2.360236618396952560064259585299045804293E0L, + 1.852230047861891953244413872297940938041E0L, + 9.394994446747752308256773044667843200719E-2L, + }, + + qa[7] = { + 4.559263722294508998149925774781887811255E2L, + 3.289248982200800575749795055149780689738E2L, + 2.846070965875643009598627918383314457912E2L, + 1.398715859064535039433275722017479994465E2L, + 6.060190733759793706299079050985358190726E1L, + 2.078695677795422351040502569964299664233E1L, + 4.641271134150895940966798357442234498546E0L, + /* 1.000000000000000000000000000000000000000E0 */ + }, + +/* + * Coefficients for approximation to erfc in [1.25,1/0.35] + */ +/* erfc(1/x) = x exp (-1/x^2 - 0.5625 + ra(x^2)/sa(x^2)) + 1/2.85711669921875 < 1/x < 1/1.25 + Peak relative error 3.1e-21 */ + + ra[] = { + 1.363566591833846324191000679620738857234E-1L, + 1.018203167219873573808450274314658434507E1L, + 1.862359362334248675526472871224778045594E2L, + 1.411622588180721285284945138667933330348E3L, + 5.088538459741511988784440103218342840478E3L, + 8.928251553922176506858267311750789273656E3L, + 7.264436000148052545243018622742770549982E3L, + 2.387492459664548651671894725748959751119E3L, + 2.220916652813908085449221282808458466556E2L, + }, + + sa[] = { + -1.382234625202480685182526402169222331847E1L, + -3.315638835627950255832519203687435946482E2L, + -2.949124863912936259747237164260785326692E3L, + -1.246622099070875940506391433635999693661E4L, + -2.673079795851665428695842853070996219632E4L, + -2.880269786660559337358397106518918220991E4L, + -1.450600228493968044773354186390390823713E4L, + -2.874539731125893533960680525192064277816E3L, + -1.402241261419067750237395034116942296027E2L, + /* 1.000000000000000000000000000000000000000E0 */ + }, +/* + * Coefficients for approximation to erfc in [1/.35,107] + */ +/* erfc(1/x) = x exp (-1/x^2 - 0.5625 + rb(x^2)/sb(x^2)) + 1/6.6666259765625 < 1/x < 1/2.85711669921875 + Peak relative error 4.2e-22 */ + rb[] = { + -4.869587348270494309550558460786501252369E-5L, + -4.030199390527997378549161722412466959403E-3L, + -9.434425866377037610206443566288917589122E-2L, + -9.319032754357658601200655161585539404155E-1L, + -4.273788174307459947350256581445442062291E0L, + -8.842289940696150508373541814064198259278E0L, + -7.069215249419887403187988144752613025255E0L, + -1.401228723639514787920274427443330704764E0L, + }, + + sb[] = { + 4.936254964107175160157544545879293019085E-3L, + 1.583457624037795744377163924895349412015E-1L, + 1.850647991850328356622940552450636420484E0L, + 9.927611557279019463768050710008450625415E0L, + 2.531667257649436709617165336779212114570E1L, + 2.869752886406743386458304052862814690045E1L, + 1.182059497870819562441683560749192539345E1L, + /* 1.000000000000000000000000000000000000000E0 */ + }, +/* erfc(1/x) = x exp (-1/x^2 - 0.5625 + rc(x^2)/sc(x^2)) + 1/107 <= 1/x <= 1/6.6666259765625 + Peak relative error 1.1e-21 */ + rc[] = { + -8.299617545269701963973537248996670806850E-5L, + -6.243845685115818513578933902532056244108E-3L, + -1.141667210620380223113693474478394397230E-1L, + -7.521343797212024245375240432734425789409E-1L, + -1.765321928311155824664963633786967602934E0L, + -1.029403473103215800456761180695263439188E0L, + }, + + sc[] = { + 8.413244363014929493035952542677768808601E-3L, + 2.065114333816877479753334599639158060979E-1L, + 1.639064941530797583766364412782135680148E0L, + 4.936788463787115555582319302981666347450E0L, + 5.005177727208955487404729933261347679090E0L, + /* 1.000000000000000000000000000000000000000E0 */ + }; + +long double +erfl(long double x) +{ + long double R, S, P, Q, s, y, z, r; + int32_t ix, i; + u_int32_t se, i0, i1; + + GET_LDOUBLE_WORDS (se, i0, i1, x); + ix = se & 0x7fff; + + if (ix >= 0x7fff) + { /* erf(nan)=nan */ + i = ((se & 0xffff) >> 15) << 1; + return (long double) (1 - i) + one / x; /* erf(+-inf)=+-1 */ + } + + ix = (ix << 16) | (i0 >> 16); + if (ix < 0x3ffed800) /* |x|<0.84375 */ + { + if (ix < 0x3fde8000) /* |x|<2**-33 */ + { + if (ix < 0x00080000) + return 0.125 * (8.0 * x + efx8 * x); /*avoid underflow */ + return x + efx * x; + } + z = x * x; + r = pp[0] + z * (pp[1] + + z * (pp[2] + z * (pp[3] + z * (pp[4] + z * pp[5])))); + s = qq[0] + z * (qq[1] + + z * (qq[2] + z * (qq[3] + z * (qq[4] + z * (qq[5] + z))))); + y = r / s; + return x + x * y; + } + if (ix < 0x3fffa000) /* 1.25 */ + { /* 0.84375 <= |x| < 1.25 */ + s = fabsl (x) - one; + P = pa[0] + s * (pa[1] + s * (pa[2] + + s * (pa[3] + s * (pa[4] + s * (pa[5] + s * (pa[6] + s * pa[7])))))); + Q = qa[0] + s * (qa[1] + s * (qa[2] + + s * (qa[3] + s * (qa[4] + s * (qa[5] + s * (qa[6] + s)))))); + if ((se & 0x8000) == 0) + return erx + P / Q; + else + return -erx - P / Q; + } + if (ix >= 0x4001d555) /* 6.6666259765625 */ + { /* inf>|x|>=6.666 */ + if ((se & 0x8000) == 0) + return one - tiny; + else + return tiny - one; + } + x = fabsl (x); + s = one / (x * x); + if (ix < 0x4000b6db) /* 2.85711669921875 */ + { + R = ra[0] + s * (ra[1] + s * (ra[2] + s * (ra[3] + s * (ra[4] + + s * (ra[5] + s * (ra[6] + s * (ra[7] + s * ra[8]))))))); + S = sa[0] + s * (sa[1] + s * (sa[2] + s * (sa[3] + s * (sa[4] + + s * (sa[5] + s * (sa[6] + s * (sa[7] + s * (sa[8] + s)))))))); + } + else + { /* |x| >= 1/0.35 */ + R = rb[0] + s * (rb[1] + s * (rb[2] + s * (rb[3] + s * (rb[4] + + s * (rb[5] + s * (rb[6] + s * rb[7])))))); + S = sb[0] + s * (sb[1] + s * (sb[2] + s * (sb[3] + s * (sb[4] + + s * (sb[5] + s * (sb[6] + s)))))); + } + z = x; + GET_LDOUBLE_WORDS (i, i0, i1, z); + i1 = 0; + SET_LDOUBLE_WORDS (z, i, i0, i1); + r = + expl (-z * z - 0.5625) * expl ((z - x) * (z + x) + R / S); + if ((se & 0x8000) == 0) + return one - r / x; + else + return r / x - one; +} + +long double +erfcl(long double x) +{ + int32_t hx, ix; + long double R, S, P, Q, s, y, z, r; + u_int32_t se, i0, i1; + + GET_LDOUBLE_WORDS (se, i0, i1, x); + ix = se & 0x7fff; + if (ix >= 0x7fff) + { /* erfc(nan)=nan */ + /* erfc(+-inf)=0,2 */ + return (long double) (((se & 0xffff) >> 15) << 1) + one / x; + } + + ix = (ix << 16) | (i0 >> 16); + if (ix < 0x3ffed800) /* |x|<0.84375 */ + { + if (ix < 0x3fbe0000) /* |x|<2**-65 */ + return one - x; + z = x * x; + r = pp[0] + z * (pp[1] + + z * (pp[2] + z * (pp[3] + z * (pp[4] + z * pp[5])))); + s = qq[0] + z * (qq[1] + + z * (qq[2] + z * (qq[3] + z * (qq[4] + z * (qq[5] + z))))); + y = r / s; + if (ix < 0x3ffd8000) /* x<1/4 */ + { + return one - (x + x * y); + } + else + { + r = x * y; + r += (x - half); + return half - r; + } + } + if (ix < 0x3fffa000) /* 1.25 */ + { /* 0.84375 <= |x| < 1.25 */ + s = fabsl (x) - one; + P = pa[0] + s * (pa[1] + s * (pa[2] + + s * (pa[3] + s * (pa[4] + s * (pa[5] + s * (pa[6] + s * pa[7])))))); + Q = qa[0] + s * (qa[1] + s * (qa[2] + + s * (qa[3] + s * (qa[4] + s * (qa[5] + s * (qa[6] + s)))))); + if ((se & 0x8000) == 0) + { + z = one - erx; + return z - P / Q; + } + else + { + z = erx + P / Q; + return one + z; + } + } + if (ix < 0x4005d600) /* 107 */ + { /* |x|<107 */ + x = fabsl (x); + s = one / (x * x); + if (ix < 0x4000b6db) /* 2.85711669921875 */ + { /* |x| < 1/.35 ~ 2.857143 */ + R = ra[0] + s * (ra[1] + s * (ra[2] + s * (ra[3] + s * (ra[4] + + s * (ra[5] + s * (ra[6] + s * (ra[7] + s * ra[8]))))))); + S = sa[0] + s * (sa[1] + s * (sa[2] + s * (sa[3] + s * (sa[4] + + s * (sa[5] + s * (sa[6] + s * (sa[7] + s * (sa[8] + s)))))))); + } + else if (ix < 0x4001d555) /* 6.6666259765625 */ + { /* 6.666 > |x| >= 1/.35 ~ 2.857143 */ + R = rb[0] + s * (rb[1] + s * (rb[2] + s * (rb[3] + s * (rb[4] + + s * (rb[5] + s * (rb[6] + s * rb[7])))))); + S = sb[0] + s * (sb[1] + s * (sb[2] + s * (sb[3] + s * (sb[4] + + s * (sb[5] + s * (sb[6] + s)))))); + } + else + { /* |x| >= 6.666 */ + if (se & 0x8000) + return two - tiny; /* x < -6.666 */ + + R = rc[0] + s * (rc[1] + s * (rc[2] + s * (rc[3] + + s * (rc[4] + s * rc[5])))); + S = sc[0] + s * (sc[1] + s * (sc[2] + s * (sc[3] + + s * (sc[4] + s)))); + } + z = x; + GET_LDOUBLE_WORDS (hx, i0, i1, z); + i1 = 0; + i0 &= 0xffffff00; + SET_LDOUBLE_WORDS (z, hx, i0, i1); + r = expl (-z * z - 0.5625) * + expl ((z - x) * (z + x) + R / S); + if ((se & 0x8000) == 0) + return r / x; + else + return two - r / x; + } + else + { + if ((se & 0x8000) == 0) + return tiny * tiny; + else + return two - tiny; + } +} diff --git a/src/openlibm/ld80/s_erfl.c.o b/src/openlibm/ld80/s_erfl.c.o new file mode 100644 index 0000000000000000000000000000000000000000..6bfdf814a6765cdf8041b78448af336e73ef2adc GIT binary patch literal 11504 zcmb<-^>JfjWMqH=Mg}_u1P><4z+j+>U^{@B4h;MZd<>z%9?fquJi6DYbTBY5cyza@ zG%zqQbiVdD_(CDA@$vuqw8r26>q{yQJ{CCmLV)vdJ7xz9k{=T)1!GXVRA`=7D zxEm)S#@>5L3F~%^iUGu&8wcU$5Y4&=bHl;gH7X7s-7YE|9?fqAj=QKNfIN}b>7tSW z5)}Z&T&Igl%IzGLgqsI$KDcr6=1Gv%H&j9DZriAUJq^+e61|VPLoc&O$FmVSJp<#^zX} z#lR^6Y|{;d2PtB~lj}=Ra((FobN{`UFFpVK{}0cv#Fan%El(I27*NX~{`M6N;PT`D zUVHww5>RG^6f^^o_CWD><0Pn1{A*tx4N8gk4o1h`d~xsLVMsb`{QVzX&OKoSyZI`s zLs>{#>s$Vg*-Q)!AoVxjMaLda1C@8pPnkM(a20fSZ{7r_5NJLF>5PuO@$lZEdk+uu z%R4YY6FQUvr*~NScH;zc>E;YCaQWN6g8~l{{iNnrtce6EIT4)%5jhc_bciYG3=Yt` ztOLbTXWhU5|Djp2_}~BkX?n2o4qh2SV&dLQXnaE>07`-50aWhXft3}|G7G6}dxfXVZS%3fkp8&BK5qZ>MAtfNJ2@Gxv(X#MF1u2h~!TbY?-434r|Nolqvw7#Qrh!y@dt!y@)GFbLQ)Fff3cX!ci@%h~0)++HSdrL_4! zNR)wr0mlCW<-hP3n?3Vm`%<<8V6zw`r@k(C7nNPc1u}twfgx{->`d95!>#;KzRHuM zwH<<27Yai8KLa1xnTBSs7J>44PB$Do_lvhv7|Or7ThGn=)#DB}C_gUT+=g+@pB`=~ zKhtft)!ZdD6Jh38&kUK$yRT)95LEux zZ`SU-e)|1{t1$kS_g%~VoU8Z1+`s-z)6C?FH#=eGFUVe$(dJkA8l#Abk>7N`oH%a!P`BYeZEvs{1`nHDoF)VyvZTlQKow2c-2Woyhufp%c zek}80^6TT0cG|Mx%rNBvS+AM!%Y>oYjX(l_Jk1sH!z zY<9BuqZ5Z<>I)4rd<*{v?tqzhys%0uO!vf6Sa>MT`J&bxqH!1IKDChb^3`S0oB!{J zq~}cwCy6{`GJgb%pV?;?1+cJI^}^KiuDX0R>;9n*n7p~I7Du<)#CQLo>B;!lF;kui z<_BTv%eGlm$m=kF%Xg^!#e~Cij-R$W^8w0#rOD!Jtf9CUX1=3UO(b*Il&7%t;I@0! zo`u~Vr(paEU#sHG>#xs)spr~rZ*vdFqc^bh6}pN0gLR7PB3O85tos&u(eJ=QnEgvR z{;e~uJKPNO@2oP8#$|%v9>Vm?sr5>Je$agY=AUg(HP~L+UU&)fkIJ>;%qE?gXJF<@ z&V3|YZ_T&vBh)`^G2axbv$Ph#!iUkQ`}rB|Uvpvn`hPv2+#jB~2($0XpRD>#yUQ=b z+}nLqTQ+jb_0Atq^BCNnovjo!-2Fl|6%0-EjPwi@j0}uS4Gawp6f}ZTQxrTBOP~_E z=9&x)EDQ_`3JeSkphkxl^ z63$@zy}1+NY-jFRxS@{R!Em-W+yb~$_VZ0(tb;lw7p~9~t`P1Ls3UMtpm1bi_z0<4 z(9|$v85!ULs{zFhm;opF!7Mf~iA+G^hZP*J$l{V<4jY32m_`tCU?v;G2PQBBPN;xc zYzz#{U;$~2B12l0PsJH`~xD!-708QKjDxQEQ?gtewKobvv ziZ`H%M?u9WpoxP!=?rWP3(&;Vpz1fEiRVDY51@$`LB%hiiC2KdSuw)D4lK?F&Vyhk zlxPOiYz&Za1#`dzXcUNnfelvOg2g~YFNk1ZV+a7#2x1bL$;JTjAD9CsW`IdHh5|5+ zAm)LYYz&~WA}|w5ECJJO3=_aKf>;G+vN0?G(+FY%n90Tfp}`z5u?=Cr z10opM7%qTm1aSz=WMg;$rV+#mFq4hp1DHk-=fF%hP{9Re!H6qh1{;F_C0Zse|RJ;I9{2x@j0Zp6*%x7Z&m9=0c zP=X68z5q-^1sNEi{$yj=fF>>m=Cd&z0MiKdGGIO{0|!C~%u<4i^MH8>LIW($#&7{l zBgFNYHA0_L+Zd;rr3aVs#Nje!BJ{DFio8-oCvxEoZx0-CrFRNMefJP0c8 zfF>RR6%RlYkAsRQpoynI#S75Hv!LP)XyTA~Wn-9tCSC?rzW`0V1}eS*O}q&zegI9p z11f$2O}q~({s2vU3Rs+#K>`u0m(y28Lx|^=u3e(8{+p zQ1K6F;+vr2=oJ!p(3pXZK>$=&!whF&VAuy$uYe|g1S)QTCVmPk?tmr^NtbL40chga zpz0IQ#P2}G3(&+LLB$);#9uHnFbE;l*Wfk}0|UcbMh1*B9^}2xIK+QI&4HN@Zo7aq z6vw9)rRC@)GwAs^8-WO85Mcr$Ou+=0Zwe8Bh?s%J&B3Gvn6w0uW(Hu=5KMxNG6U;1 z1M4*d>oo)GH3RE41M39~fcao9*d#-+NrqsP48bNDf=x06n`8(!$q=m35UkS>tkn># z*9ffF2&~r#tk(#v*9ffF2&~r#tk(#v*9ffF2&~r_tk)Q<*BGqV7_8SAtk)Q<*BGqV z7_8SAtk)Q<*95HB1gzHttk(pr*95HB1gzHttk(pr*95HB1gzH-tk)E**A%SR9IV$I zEMg8e!5nOYIoJequnFd16U@OTSb$Bi0IRnEn_vMp!2+z;!ju6N$qZ?UNyRw~sTBn| zAbv8aZ4n7d0}PO25tOC={D**eBymuZgo(rIaZt7gwH9IGmypzhT8l98|4?y|8KDde z3@~v;aC(Q>%Z?Tam;Ck<95w5*I=epNS+cj3mAoNgPy`!pvWb zBrb}i{tc427?SuGs5mHI!jQz3KoQFT>8~M+$3n$HlsJ<5RFD8P{ea4Rn0xY(#6f)m zn0O_UxD=8(%}Cge3kRDh>)yGTG8;79Kz$&Xy}U@`pouz|xHyuy8j?AR zNaE^9;@U{!8c5=%NaCQWV3_&#NaCQr7fjq8Nn9JroIoUT9VGE+ByrG80?eFLByl|? z_4!ER`bgrHNaCQr3Cx^kBymF|^^=gqjgZ6_A&DC!iEly@H$f8Lg(Pl@Bz^=*9Mso@ zx#t{`xH*#g8%W|7NaBx>#4VA;-yn%wA&GxO61PSYhqZG+=?c`xg}H|ZlmMaW$`(nz z7?QXhk~pmW12P9Rv;#9o3rRg_hz}-if+P+au!f1-A&Ge-hi6fUk&Pd|O<ly(i6hs))=1*W^{*?EICA~#k0g#<|3)K;BiFyFNaD!#Z$6SZ za{XJ0B#vDFHY156*T20;;>h*ybR==)`u7HsICA~_04ffO7vy@D4-^?#>R(-`I4GaG zBgJnzR2*aua{LxU#X;(k>z!&OapZcZ6-gYq-swjYN3M5fB8el{JByLTk?WncNaD!# z&UPemqB#vC~+(i;cu6Ldzi6hrLACbh7>z&_7;>h(54=9sB z^ATw55LWIfA&Dc$mkE+May{jQB#vAkc_E1-*GC~p;>h(;9FjP4eUyPDj$9uVA&Dc` zM>R;|$n{Yhk~ngGGyzE*xjveMB#vAkEkhDVu8%e#i6hrXyO6|@>!Tw`;>h*UIV5r9 z`sfCdIC6dT2uU2dK6-;Bj$9vcg9<@tyn7<$M`0v!FC=kUByn#fadjkdA0%-@BynFP zacd-T(3mtVy}2Wa`y;6jL=p#$*}~LEBZ&thsZT``4?+^pM-mT45(m{;pe`P$oB?4F z8-!uwv>-7MhK)Ng=oMGymLw)I=oOa~LFfz^t0*-mQLiMmqJ%*&C9x!tK`*Jem_e^7 zAH>m1E-o=a=79SD$@#gtsd*&~dU^RJse0~yp}NH-iOJbeetKT1UO`cQL26M+C4(N= z@YIa>w4%h^RFDfP!ytcyx=_$!9BvpWZGt#;(C`AWK^RmQfoK>8wJ|_tHcUNC+yc}n z0ZsgaDmw-S22dRdvIm+B;p1wcvKS-|Z63n3GwegN7bXEx3uA+5P}vDGlU)6vG7w}Y zsLlkL2g3)T_JhI)CI+HGenqB1c^;eo2T=VJU>ZQ0K;z74G$^lt^n=Q1s1%qgfQB2W zOa}`<36NS46GnsTN*Eg?4#V@I`eA$+jjk4ygg{jSC~d>kfanEK{pjujg*8YXhHF7{ zo6zzDCI+G}K=nh$y+I-njIJLv&jSh~^z>5!s&p9`;PW}4^aE;_!SsXL$RHCz{y}#; zNc;z=F$GG0Pz|8A7-)_Q%7v#tP&A>Z9guzts0IH(7Jvkx7>&ySYJ*|ZzXIz1cBnoW Hg{~g};s?No literal 0 HcmV?d00001 diff --git a/src/openlibm/ld80/s_exp2l.c b/src/openlibm/ld80/s_exp2l.c new file mode 100644 index 0000000..0cf5259 --- /dev/null +++ b/src/openlibm/ld80/s_exp2l.c @@ -0,0 +1,295 @@ +/*- + * Copyright (c) 2005-2008 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/ld80/s_exp2l.c,v 1.3 2008/02/13 10:44:44 bde Exp $"); + +#include +#include + +#include "bsd_cdefs.h" +#include "amd64/bsd_ieeefp.h" + +#include + +#include "math_private.h" + +#define TBLBITS 7 +#define TBLSIZE (1 << TBLBITS) + +#define BIAS (LDBL_MAX_EXP - 1) +#define EXPMASK (BIAS + LDBL_MAX_EXP) + +static const long double huge = 0x1p10000L; +#if 0 /* XXX Prevent gcc from erroneously constant folding this. */ +static const long double twom10000 = 0x1p-10000L; +#else +static volatile long double twom10000 = 0x1p-10000L; +#endif + +static const double + redux = 0x1.8p63 / TBLSIZE, + P1 = 0x1.62e42fefa39efp-1, + P2 = 0x1.ebfbdff82c58fp-3, + P3 = 0x1.c6b08d7049fap-5, + P4 = 0x1.3b2ab6fba4da5p-7, + P5 = 0x1.5d8804780a736p-10, + P6 = 0x1.430918835e33dp-13; + +static const double tbl[TBLSIZE * 2] = { + 0x1.6a09e667f3bcdp-1, -0x1.bdd3413b2648p-55, + 0x1.6c012750bdabfp-1, -0x1.2895667ff0cp-57, + 0x1.6dfb23c651a2fp-1, -0x1.bbe3a683c88p-58, + 0x1.6ff7df9519484p-1, -0x1.83c0f25860fp-56, + 0x1.71f75e8ec5f74p-1, -0x1.16e4786887bp-56, + 0x1.73f9a48a58174p-1, -0x1.0a8d96c65d5p-55, + 0x1.75feb564267c9p-1, -0x1.0245957316ep-55, + 0x1.780694fde5d3fp-1, 0x1.866b80a0216p-55, + 0x1.7a11473eb0187p-1, -0x1.41577ee0499p-56, + 0x1.7c1ed0130c132p-1, 0x1.f124cd1164ep-55, + 0x1.7e2f336cf4e62p-1, 0x1.05d02ba157ap-57, + 0x1.80427543e1a12p-1, -0x1.27c86626d97p-55, + 0x1.82589994cce13p-1, -0x1.d4c1dd41533p-55, + 0x1.8471a4623c7adp-1, -0x1.8d684a341cep-56, + 0x1.868d99b4492edp-1, -0x1.fc6f89bd4f68p-55, + 0x1.88ac7d98a6699p-1, 0x1.994c2f37cb5p-55, + 0x1.8ace5422aa0dbp-1, 0x1.6e9f156864bp-55, + 0x1.8cf3216b5448cp-1, -0x1.0d55e32e9e4p-57, + 0x1.8f1ae99157736p-1, 0x1.5cc13a2e397p-56, + 0x1.9145b0b91ffc6p-1, -0x1.dd6792e5825p-55, + 0x1.93737b0cdc5e5p-1, -0x1.75fc781b58p-58, + 0x1.95a44cbc8520fp-1, -0x1.64b7c96a5fp-57, + 0x1.97d829fde4e5p-1, -0x1.d185b7c1b86p-55, + 0x1.9a0f170ca07bap-1, -0x1.173bd91cee6p-55, + 0x1.9c49182a3f09p-1, 0x1.c7c46b071f2p-57, + 0x1.9e86319e32323p-1, 0x1.824ca78e64cp-57, + 0x1.a0c667b5de565p-1, -0x1.359495d1cd5p-55, + 0x1.a309bec4a2d33p-1, 0x1.6305c7ddc368p-55, + 0x1.a5503b23e255dp-1, -0x1.d2f6edb8d42p-55, + 0x1.a799e1330b358p-1, 0x1.bcb7ecac564p-55, + 0x1.a9e6b5579fdbfp-1, 0x1.0fac90ef7fdp-55, + 0x1.ac36bbfd3f37ap-1, -0x1.f9234cae76dp-56, + 0x1.ae89f995ad3adp-1, 0x1.7a1cd345dcc8p-55, + 0x1.b0e07298db666p-1, -0x1.bdef54c80e4p-55, + 0x1.b33a2b84f15fbp-1, -0x1.2805e3084d8p-58, + 0x1.b59728de5593ap-1, -0x1.c71dfbbba6ep-55, + 0x1.b7f76f2fb5e47p-1, -0x1.5584f7e54acp-57, + 0x1.ba5b030a1064ap-1, -0x1.efcd30e5429p-55, + 0x1.bcc1e904bc1d2p-1, 0x1.23dd07a2d9fp-56, + 0x1.bf2c25bd71e09p-1, -0x1.efdca3f6b9c8p-55, + 0x1.c199bdd85529cp-1, 0x1.11065895049p-56, + 0x1.c40ab5fffd07ap-1, 0x1.b4537e083c6p-55, + 0x1.c67f12e57d14bp-1, 0x1.2884dff483c8p-55, + 0x1.c8f6d9406e7b5p-1, 0x1.1acbc48805cp-57, + 0x1.cb720dcef9069p-1, 0x1.503cbd1e94ap-57, + 0x1.cdf0b555dc3fap-1, -0x1.dd83b53829dp-56, + 0x1.d072d4a07897cp-1, -0x1.cbc3743797a8p-55, + 0x1.d2f87080d89f2p-1, -0x1.d487b719d858p-55, + 0x1.d5818dcfba487p-1, 0x1.2ed02d75b37p-56, + 0x1.d80e316c98398p-1, -0x1.11ec18bedep-55, + 0x1.da9e603db3285p-1, 0x1.c2300696db5p-55, + 0x1.dd321f301b46p-1, 0x1.2da5778f019p-55, + 0x1.dfc97337b9b5fp-1, -0x1.1a5cd4f184b8p-55, + 0x1.e264614f5a129p-1, -0x1.7b627817a148p-55, + 0x1.e502ee78b3ff6p-1, 0x1.39e8980a9cdp-56, + 0x1.e7a51fbc74c83p-1, 0x1.2d522ca0c8ep-55, + 0x1.ea4afa2a490dap-1, -0x1.e9c23179c288p-55, + 0x1.ecf482d8e67f1p-1, -0x1.c93f3b411ad8p-55, + 0x1.efa1bee615a27p-1, 0x1.dc7f486a4b68p-55, + 0x1.f252b376bba97p-1, 0x1.3a1a5bf0d8e8p-55, + 0x1.f50765b6e454p-1, 0x1.9d3e12dd8a18p-55, + 0x1.f7bfdad9cbe14p-1, -0x1.dbb12d00635p-55, + 0x1.fa7c1819e90d8p-1, 0x1.74853f3a593p-56, + 0x1.fd3c22b8f71f1p-1, 0x1.2eb74966578p-58, + 0x1p+0, 0x0p+0, + 0x1.0163da9fb3335p+0, 0x1.b61299ab8cd8p-54, + 0x1.02c9a3e778061p+0, -0x1.19083535b08p-56, + 0x1.04315e86e7f85p+0, -0x1.0a31c1977c98p-54, + 0x1.059b0d3158574p+0, 0x1.d73e2a475b4p-55, + 0x1.0706b29ddf6dep+0, -0x1.c91dfe2b13cp-55, + 0x1.0874518759bc8p+0, 0x1.186be4bb284p-57, + 0x1.09e3ecac6f383p+0, 0x1.14878183161p-54, + 0x1.0b5586cf9890fp+0, 0x1.8a62e4adc61p-54, + 0x1.0cc922b7247f7p+0, 0x1.01edc16e24f8p-54, + 0x1.0e3ec32d3d1a2p+0, 0x1.03a1727c58p-59, + 0x1.0fb66affed31bp+0, -0x1.b9bedc44ebcp-57, + 0x1.11301d0125b51p+0, -0x1.6c51039449bp-54, + 0x1.12abdc06c31ccp+0, -0x1.1b514b36ca8p-58, + 0x1.1429aaea92dep+0, -0x1.32fbf9af1368p-54, + 0x1.15a98c8a58e51p+0, 0x1.2406ab9eeabp-55, + 0x1.172b83c7d517bp+0, -0x1.19041b9d78ap-55, + 0x1.18af9388c8deap+0, -0x1.11023d1970f8p-54, + 0x1.1a35beb6fcb75p+0, 0x1.e5b4c7b4969p-55, + 0x1.1bbe084045cd4p+0, -0x1.95386352ef6p-54, + 0x1.1d4873168b9aap+0, 0x1.e016e00a264p-54, + 0x1.1ed5022fcd91dp+0, -0x1.1df98027bb78p-54, + 0x1.2063b88628cd6p+0, 0x1.dc775814a85p-55, + 0x1.21f49917ddc96p+0, 0x1.2a97e9494a6p-55, + 0x1.2387a6e756238p+0, 0x1.9b07eb6c7058p-54, + 0x1.251ce4fb2a63fp+0, 0x1.ac155bef4f5p-55, + 0x1.26b4565e27cddp+0, 0x1.2bd339940eap-55, + 0x1.284dfe1f56381p+0, -0x1.a4c3a8c3f0d8p-54, + 0x1.29e9df51fdee1p+0, 0x1.612e8afad12p-55, + 0x1.2b87fd0dad99p+0, -0x1.10adcd6382p-59, + 0x1.2d285a6e4030bp+0, 0x1.0024754db42p-54, + 0x1.2ecafa93e2f56p+0, 0x1.1ca0f45d524p-56, + 0x1.306fe0a31b715p+0, 0x1.6f46ad23183p-55, + 0x1.32170fc4cd831p+0, 0x1.a9ce78e1804p-55, + 0x1.33c08b26416ffp+0, 0x1.327218436598p-54, + 0x1.356c55f929ff1p+0, -0x1.b5cee5c4e46p-55, + 0x1.371a7373aa9cbp+0, -0x1.63aeabf42ebp-54, + 0x1.38cae6d05d866p+0, -0x1.e958d3c99048p-54, + 0x1.3a7db34e59ff7p+0, -0x1.5e436d661f6p-56, + 0x1.3c32dc313a8e5p+0, -0x1.efff8375d2ap-54, + 0x1.3dea64c123422p+0, 0x1.ada0911f09fp-55, + 0x1.3fa4504ac801cp+0, -0x1.7d023f956fap-54, + 0x1.4160a21f72e2ap+0, -0x1.ef3691c309p-58, + 0x1.431f5d950a897p+0, -0x1.1c7dde35f7ap-55, + 0x1.44e086061892dp+0, 0x1.89b7a04ef8p-59, + 0x1.46a41ed1d0057p+0, 0x1.c944bd1648a8p-54, + 0x1.486a2b5c13cdp+0, 0x1.3c1a3b69062p-56, + 0x1.4a32af0d7d3dep+0, 0x1.9cb62f3d1be8p-54, + 0x1.4bfdad5362a27p+0, 0x1.d4397afec42p-56, + 0x1.4dcb299fddd0dp+0, 0x1.8ecdbbc6a78p-54, + 0x1.4f9b2769d2ca7p+0, -0x1.4b309d25958p-54, + 0x1.516daa2cf6642p+0, -0x1.f768569bd94p-55, + 0x1.5342b569d4f82p+0, -0x1.07abe1db13dp-55, + 0x1.551a4ca5d920fp+0, -0x1.d689cefede6p-55, + 0x1.56f4736b527dap+0, 0x1.9bb2c011d938p-54, + 0x1.58d12d497c7fdp+0, 0x1.295e15b9a1ep-55, + 0x1.5ab07dd485429p+0, 0x1.6324c0546478p-54, + 0x1.5c9268a5946b7p+0, 0x1.c4b1b81698p-60, + 0x1.5e76f15ad2148p+0, 0x1.ba6f93080e68p-54, + 0x1.605e1b976dc09p+0, -0x1.3e2429b56de8p-54, + 0x1.6247eb03a5585p+0, -0x1.383c17e40b48p-54, + 0x1.6434634ccc32p+0, -0x1.c483c759d89p-55, + 0x1.6623882552225p+0, -0x1.bb60987591cp-54, + 0x1.68155d44ca973p+0, 0x1.038ae44f74p-57, +}; + +/* + * exp2l(x): compute the base 2 exponential of x + * + * Accuracy: Peak error < 0.511 ulp. + * + * Method: (equally-spaced tables) + * + * Reduce x: + * x = 2**k + y, for integer k and |y| <= 1/2. + * Thus we have exp2l(x) = 2**k * exp2(y). + * + * Reduce y: + * y = i/TBLSIZE + z for integer i near y * TBLSIZE. + * Thus we have exp2(y) = exp2(i/TBLSIZE) * exp2(z), + * with |z| <= 2**-(TBLBITS+1). + * + * We compute exp2(i/TBLSIZE) via table lookup and exp2(z) via a + * degree-6 minimax polynomial with maximum error under 2**-69. + * The table entries each have 104 bits of accuracy, encoded as + * a pair of double precision values. + */ +OLM_DLLEXPORT long double +exp2l(long double x) +{ + union IEEEl2bits u, v; + long double r, twopk, twopkp10000, z; + uint32_t hx, ix, i0; + int k; + + /* Filter out exceptional cases. */ + u.e = x; + hx = u.xbits.expsign; + ix = hx & EXPMASK; + if (ix >= BIAS + 14) { /* |x| >= 16384 or x is NaN */ + if (ix == BIAS + LDBL_MAX_EXP) { + if (u.xbits.man != 1ULL << 63 || (hx & 0x8000) == 0) + return (x + x); /* x is +Inf or NaN */ + else + return (0.0); /* x is -Inf */ + } + if (x >= 16384) + return (huge * huge); /* overflow */ + if (x <= -16446) + return (twom10000 * twom10000); /* underflow */ + } else if (ix <= BIAS - 66) { /* |x| < 0x1p-66 */ + return (1.0 + x); + } + +#ifdef __i386__ + /* + * The default precision on i386 is 53 bits, so long doubles are + * broken. Call exp2() to get an accurate (double precision) result. + */ + if (__fpgetprec() != FP_PE) + return (exp2(x)); +#endif + + + /* + * Reduce x, computing z, i0, and k. The low bits of x + redux + * contain the 16-bit integer part of the exponent (k) followed by + * TBLBITS fractional bits (i0). We use bit tricks to extract these + * as integers, then set z to the remainder. + * + * Example: Suppose x is 0xabc.123456p0 and TBLBITS is 8. + * Then the low-order word of x + redux is 0x000abc12, + * We split this into k = 0xabc and i0 = 0x12 (adjusted to + * index into the table), then we compute z = 0x0.003456p0. + * + * XXX If the exponent is negative, the computation of k depends on + * '>>' doing sign extension. + */ + u.e = x + redux; + i0 = u.bits.manl + TBLSIZE / 2; + k = (int)i0 >> TBLBITS; + i0 = (i0 & (TBLSIZE - 1)) << 1; + u.e -= redux; + z = x - u.e; + v.xbits.man = 1ULL << 63; + if (k >= LDBL_MIN_EXP) { + v.xbits.expsign = LDBL_MAX_EXP - 1 + k; + twopk = v.e; + } else { + v.xbits.expsign = LDBL_MAX_EXP - 1 + k + 10000; + twopkp10000 = v.e; + } + + /* Compute r = exp2l(y) = exp2lt[i0] * p(z). */ + long double t_hi = tbl[i0]; + long double t_lo = tbl[i0 + 1]; + /* XXX This gives > 1 ulp errors outside of FE_TONEAREST mode */ + r = t_lo + (t_hi + t_lo) * z * (P1 + z * (P2 + z * (P3 + z * (P4 + + z * (P5 + z * P6))))) + t_hi; + + /* Scale by 2**k. */ + if (k >= LDBL_MIN_EXP) { + if (k == LDBL_MAX_EXP) + return (r * 2.0 * 0x1p16383L); + return (r * twopk); + } else { + return (r * twopkp10000 * twom10000); + } +} diff --git a/src/openlibm/ld80/s_exp2l.c.o b/src/openlibm/ld80/s_exp2l.c.o new file mode 100644 index 0000000000000000000000000000000000000000..11b98d35e23af81e64f5d8f0216e1dea2a453395 GIT binary patch literal 5120 zcmb<-^>JfjWMqH=Mg}_u1P><4z;J*c!FB*M9T)@|1Q>3zf;bS;qdP=Jpz}hS>i_yQ zTOJ4gw*L$a3~9Fi>-k$u85y8TZ|A6R-2Zs@27hxQBLf472hj`>1F7@a4>FR0fuR8+ z15)GBS)=me#=)BhZr7;X0NHb+`H(~B#atoZ=rU6xOGSq|Mie1{h#bO-E@8)xv- zHxJ!7bnooFGxrYPJJk4-`N04G{5`XvRyF=)aA08IZ&}5_z;N&6VSf1rkhy8Ld+qt# zHUIzrfA_}S8#iBo9DDEJ;WU2v7LYW<-J87=`O}e{c=OcDu>b%6!{u+>z2UI~tdxPF z!K2$pg~P-0U@2=_>!pfdkYP6t9OjpIU;vqZTNk7bLV{i3!oYC%284g})V-7UP9C0s zP>-gvP40(p(ktz*)>|^iwXEr>y zXAooJ+L6{_)6V$1SY+XIdxn`T@5)6>_81*BV0?Siz!_37QS_PDZ}l=};NhI5XK zTdq~?c{|Bv_RWkJ_6^^z%>Hq#f6vUcuA9fZUf45it@(UtN~g{31zJu|*SxT2@NNtH z__EEW$7QRS(fJql3{PGf#a&I9iW}v^@cS_vSa%zO-j(ldg%D=-so6 z{Zzrn1uyLxo}HVxx43c7gb$0GCLVcd&+w^mgIi6Gjk5A%$>bL=?HPQYRh&}Eut|Ly zTb;)9%AVn>Osr>Q^B!YeuQ#&|UfDO8-KmW+XtRk`wcErT`pTZcsrPoCe(#=$%?85r zDqq<%q#Qj}ce>kV|KG~c?0K*38UB9fJNc`@rt0(M{n>|K*)!xmKV>qhe$U#=Q8VYi zcxB&kCf4Na!giaqZM~Z8e6Q^po;3J;z1O|xx2XS)MaHk~8E&)~#5Dx%v5I`!TNL@) zo*{47?)!y3d)(uGe=4hgZO^bKq|QGgb&nU@LW2!UU)wWihVWhf)3@i+LGKB2XI|Sg z%-5~DU|VFvDR({k(5Kh-4Rf;XPyOxNGbgC^?rh07_6(i@ov8waHdPn?$FFvHW6yA` z`GL7>w~hD3aJ`S|Z|oavJpTK3G}&x@&Nd~t|BXFEOoPXsHHkKv6W-rZ*#5?z!RzJ4 z)6A(hzYfQSa^HVr&oH+s*!o88o|;Z}FJ1Px_6=2)&gOf1_I&E(agXN0uOe=0@9Y~ysv6a|weR_6 z-~C)K;GI3g*_92Q^NMYneUASQta@k9(8qI1>1vbBtqDsOtzYuazCmM-xbmF7Js;Ei zbUn_$vu{`{xaITYo;~VOiSML;y|ZuFwxsRL@m`zhyRyx-Ro~k;^zrUry0F>C!8I?s zEa1I;!@?W74=;Dxi0qrQ_HXrjdj?as3qrel_uQB;ukqmW_x22vmwpcRD7X1o*sp!) z@_T!RiqvT(uY+tLrN9S!2+hD?YW#bpt=I?qhO;|nX(rCLNo**$o2B!?o`EAexOqb1 zp4R%j7oyG|>>Ey&OUf*su&1O|^zw$t5B3aON|!t;?zOr1?XG5a!3TQ=n~jg|Pwd%q zVs@#7Yx@U#hL%m<``Qw1nm->qWjF7GJwu|QM1{vh8~)CpIT2ey{5xKH%VyYocQ4YO zbmoJ7ga0G3J8~0j7G1n-^ycvgdxnOi>f%-oHqw{>txx;?!Jc7{-;uYov-bo>3teCo z{%FrI+r?7g=(Ig&408_b)%s}9up(!($kxC;4|G?qo8|P;zQOF{to{0v_XPGWJuxHd zqdmjwcRRBjnrx~AYi)KEeY9ujy1vtKLgSuSy*(B`yFS`C@K3*}EHH6T>FNB}(ThLY zGh}*J`$YHIT!~?6d9eGVJ;OIW)3)H5dsgktFl@i_(Vih?5kns1JR8}Yf0P2=ezb4c zUd=S){=_}kdXhS<**@7bw0bp`9`Ci8cBgitr~D^-hGkQx)U9l?u}CV-tFriH-@tl& zTiu44HulRl`JW5?WY6&R%f8TqT{d@X9;Lcwf3jzIvS(1RxORujaSu21lVz=!KG`!k-41bQ znqU*AZ?|&&n@{!(Dpy_kPZipTZa3um$M)Htq1o_K)|WOL!y7(-3KT!vGq6bXJ)hHM z^It4w6Nk-b`-Vuf7De^RHXr9tia#3m*`C48FXmlL_ny-$t<0Afezs?L?X>@u)wDfn zH&}Dm^?bH(V3}#tJ9XZk@AIFU++P0Kp5a^KHM1wBd!DWkKCFBAvps`Wtoe`s^Y$p2 z2>C3#_t~Cd{s%$MTU|CX4Qp6je|@%R_!ah3`NH%)T6*6Vxx~KMGfXg$$^0C*XZnhO zn_msT*fUhcKfZgsagT0iVgiTX7kh?=_bgSjJ#4}mWZybweX(!oO1bDgWsc1Sn}b^y zwSBQ?NSd&1@xfx7dzY_&&|3V(zG2_R&q=3e+Nf)pUA?vci#>zWoAuM3Yi)S%{++q$ z&KG-zimW}i-^{RCt~0l6)6XyV3=xr+I5$t(VgY z)tpK+BdknvHBQIv)S$z*`;>!t35+QW}~#Xjg5!mTG9OHU+o*7 zH5mL{Hrs~tPT9_ftl#V#?uE^EdNg@YYpB(RI+bts4O<-Q4mMBTqj30)iJS8`dxp-r zr8XWtdsLM|n=F#P*)zyQwsUTqy{CAk&y~=|Z}toh-(A*OB-k)8G`KO;G#q1KI1tUi zaG)Mq4m5z;G*C8(YWN40v3+dXG0{N9-fVe;d&7-T`=!3S@>g$awqG!x42%^5jM6;p z91|EJ;xbUV%P`GQJ~j%ZgoWWFsKtvR&5X50&A`CS0CNRG3pWD;10&e=P%#b&4QhTf zBB>XE2!lyxWc6SX1_ntm&Bnk3rV)fZn8^kvkqH$rhYcKlU?!B%1k-E`P-lR7AVLpB zV2Cm>7(>O;)muQtk=+dvvIP+g91Q5qODCu}C@#TFDB%I7IT$p+G=lI0Gugo;G7${s zurr|B8_B@HAcPbz@Hj4xPpv30%F#<^C`rm;C@Ig+H8e0VFksO0aW*solOVzvM3{mI zGZ0}8A}m0JC5SMDC^rPLjX;E<5d+v%1_maudmuE(wSWFY04%&f^2p-4Na{gqVCr3w z#5oxl7+~V@Na9>b;v12~L9q{0e*{S!l=fiar;x-!X$U5M2}vB(ae|58LK5dgviA{^ zI4BLn)W1R!2gMCcybqL-7$D&T${jHADLBNJ;1J)2Brb^Lo?}SjLP+AUbOs845QaLB zfkCghGPfi#i9xTpqzFQ1z*t48If;5DsTCy*dMSw|i41y4#l;MIMfng8gw{(gE-`@# zf;fg|$UF-Mz2yAd+|;}h2EDxel2ko+zfj%clEma}C_g=~RIi{YzaX`!q>@1oY-4Ih zd|FXrZYtb~lrTX41_cQyO(2^C>Ekmn!1D!E5)@ZZCYX|DfRwo~^<##o3c?T*BL81t(0F4B6`_TD13=H5>2$WV3x)~S@p!$); zKx~j3Kr{>+LhVOa?f?^jIT)$|6kbp!n6iZG2c;#j0F-b5Wj+Q5jB*E57lD+(Xg3`C z1EBiR?SuIrMu*_gUjWr_0J01T!@L8d6QTOi)h&SP*GJL|V#2}?MrT3wgXEC$d8mG5 zF%TQ355xxHDh37yP + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* expm1l.c + * + * Exponential function, minus 1 + * Long double precision + * + * + * SYNOPSIS: + * + * long double x, y, expm1l(); + * + * y = expm1l( x ); + * + * + * + * DESCRIPTION: + * + * Returns e (2.71828...) raised to the x power, minus 1. + * + * Range reduction is accomplished by separating the argument + * into an integer k and fraction f such that + * + * x k f + * e = 2 e. + * + * An expansion x + .5 x^2 + x^3 R(x) approximates exp(f) - 1 + * in the basic range [-0.5 ln 2, 0.5 ln 2]. + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE -45,+MAXLOG 200,000 1.2e-19 2.5e-20 + * + * ERROR MESSAGES: + * + * message condition value returned + * expm1l overflow x > MAXLOG MAXNUM + * + */ + +#include + +static const long double MAXLOGL = 1.1356523406294143949492E4L; + +/* exp(x) - 1 = x + 0.5 x^2 + x^3 P(x)/Q(x) + -.5 ln 2 < x < .5 ln 2 + Theoretical peak relative error = 3.4e-22 */ + +static const long double + P0 = -1.586135578666346600772998894928250240826E4L, + P1 = 2.642771505685952966904660652518429479531E3L, + P2 = -3.423199068835684263987132888286791620673E2L, + P3 = 1.800826371455042224581246202420972737840E1L, + P4 = -5.238523121205561042771939008061958820811E-1L, + + Q0 = -9.516813471998079611319047060563358064497E4L, + Q1 = 3.964866271411091674556850458227710004570E4L, + Q2 = -7.207678383830091850230366618190187434796E3L, + Q3 = 7.206038318724600171970199625081491823079E2L, + Q4 = -4.002027679107076077238836622982900945173E1L, + /* Q5 = 1.000000000000000000000000000000000000000E0 */ + +/* C1 + C2 = ln 2 */ +C1 = 6.93145751953125E-1L, +C2 = 1.428606820309417232121458176568075500134E-6L, +/* ln 2^-65 */ +minarg = -4.5054566736396445112120088E1L; +static const long double huge = 0x1p10000L; + +long double +expm1l(long double x) +{ +long double px, qx, xx; +int k; + +/* Overflow. */ +if (x > MAXLOGL) + return (huge*huge); /* overflow */ + +if (x == 0.0) + return x; + +/* Minimum value. */ +if (x < minarg) + return -1.0L; + +xx = C1 + C2; + +/* Express x = ln 2 (k + remainder), remainder not exceeding 1/2. */ +px = floorl (0.5 + x / xx); +k = px; +/* remainder times ln 2 */ +x -= px * C1; +x -= px * C2; + +/* Approximate exp(remainder ln 2). */ +px = (((( P4 * x + + P3) * x + + P2) * x + + P1) * x + + P0) * x; + +qx = (((( x + + Q4) * x + + Q3) * x + + Q2) * x + + Q1) * x + + Q0; + +xx = x * x; +qx = x + (0.5 * xx + xx * px / qx); + +/* exp(x) = exp(k ln 2) exp(remainder ln 2) = 2^k exp(remainder ln 2). + We have qx = exp(remainder ln 2) - 1, so + exp(x) - 1 = 2^k (qx + 1) - 1 = 2^k qx + 2^k - 1. */ +px = ldexpl(1.0L, k); +x = px * qx + (px - 1.0); +return x; +} diff --git a/src/openlibm/ld80/s_expm1l.c.o b/src/openlibm/ld80/s_expm1l.c.o new file mode 100644 index 0000000000000000000000000000000000000000..91cc17302caa9a359ac72951f298bf0830a28b95 GIT binary patch literal 3088 zcmb<-^>JfjWMqH=Mg}_u1P><4z!1QJU^{@B4h;MZd<-7VZ!~V}f&^~os2JS-c=slM zy9Ofz!_9X$Pu_lc_huE>%>(=`Y>W&HcW*${-T%nnE(TKZ)}#52z>S|bPu{Lkak$9} zGUMLC+cqjMK&+cJDti3eT~zcM&hVslx~S;fJa98dMdx;mioner6+MvF?iv+^n+I<2 zf|TFRQ3<&B5Msf-Q}-U;JaFSAgm>cfuVsv9m1TnU2J3c1M@8`2OxYo z|G2Z&ef##mwukUfUVc)WqA%U{Z$E_pxaQg432y`@Fhk8-*AY>;^^?YGb|^owb8duK zgw9efD4*%j`LN)etKVVvKUWdVDmW~%fCVal@{xRj-cq$K98msB&g6!WT-%4-P`=Th z6APEGd@zd-%J04?-DoHHU?)G64{;Sk!#}8d85kJs8Hx<;8Qh(ntrRre{X#Vr3{CWm z^b8e@42(<-3=ItwG=fr76g(13pc1;~nhXpq3=9kk3=9mQWaRD_%D}|HcmN~@OUsN< zJ~Pxp5h%@A6~w?;A;2ij!_F~*k%2*nfq_8=Di;mX?80YI!{<=V7r?ZF&mfqKkHd@G zhl`KHh1-J0Bh7DjEL4<&rtPIfP59Wc0C=kKG z%5VWpBM6AQSs5N6gutvcFv-dw0HzT{HUk5L5K?@B(*y$pLlFZ5hFXxWN*v-0#qp^X z1-XVfddUoWKF)?9!URN^fe3RDVF4m6L4=_Jm;@^_Gy=1Y!6aCRp(&UR)@TUUX$aP8 z1Xgdv0I`Q5Ehj&}D2E{@CAFd;hXIySm>3usKzZQLe+bY6Ihuii0VEE}FEDX0Bymux zgo#7K8}3vL3Y8!`;o-ik<`yc5(niYnEIti;+#n8*CUB@A&Kuq66Zz| zhm@WWe}VEA%>466>OnOJO#CL2I3JQZkCDXrk;LC3iG$J%%$)B?;-I_>6Ngo?pl}vK zGDj3tP%uEk6O^Z6>Rq7XAoapX>LK|U;xCXK)H((Rz2eH;lEfqiz2cH02%Q0A6{Y4R z>XoEclrZR}B$gyH=p_{wGw2oNgE)H0#U+Mj$UGAUz2yAd+|;}h2EDxel2ko+zfj%c zlEma}C_g=~RIi{YzaX`!q>@1oY}+s27+fm_3J~pa1vw}hy$ZTq545$$oM!^Ke8Bz4bul=gD@xwfyxPV z9YDE)xSA((!c zILJRxtH9>N2nT3_(11#U${tV~1YJL<%!4Y0X$8|6(DaL5kAmz2D}WN9G6$Rf6HxcJ KL)F13bo~HBBLCe0 literal 0 HcmV?d00001 diff --git a/src/openlibm/ld80/s_floorl.c b/src/openlibm/ld80/s_floorl.c new file mode 100644 index 0000000..7d42bd6 --- /dev/null +++ b/src/openlibm/ld80/s_floorl.c @@ -0,0 +1,80 @@ +/* @(#)s_floor.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * floorl(x) + * Return x rounded toward -inf to integral value + * Method: + * Bit twiddling. + * Exception: + * Inexact flag raised if x not equal to floor(x). + */ + +#include + +#include "math_private.h" + +static const long double huge = 1.0e4930L; + +long double +floorl(long double x) +{ + int32_t i1,jj0; + u_int32_t i,j,se,i0,sx; + GET_LDOUBLE_WORDS(se,i0,i1,x); + sx = (se>>15)&1; + jj0 = (se&0x7fff)-0x3fff; + if(jj0<31) { + if(jj0<0) { /* raise inexact if x != 0 */ + if(huge+x>0.0) { + if(sx==0) + return 0.0L; + else if(((se&0x7fff)|i0|i1)!=0) + return -1.0L; + } + } else { + i = (0x7fffffff)>>jj0; + if(((i0&i)|i1)==0) return x; /* x is integral */ + if(huge+x>0.0) { /* raise inexact flag */ + if(sx) { + if (jj0>0 && (i0+(0x80000000>>jj0))>i0) + i0 += (0x80000000)>>jj0; + else + { + i = 0x7fffffff; + ++se; + } + } + i0 &= (~i); i1=0; + } + } + } else if (jj0>62) { + if(jj0==0x4000) return x+x; /* inf or NaN */ + else return x; /* x is integral */ + } else { + i = ((u_int32_t)(0xffffffff))>>(jj0-31); + if((i1&i)==0) return x; /* x is integral */ + if(huge+x>0.0) { /* raise inexact flag */ + if(sx) { + if(jj0==31) i0+=1; + else { + j = i1+(1<<(63-jj0)); + if(j + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* log1pl.c + * + * Relative error logarithm + * Natural logarithm of 1+x, long double precision + * + * + * + * SYNOPSIS: + * + * long double x, y, log1pl(); + * + * y = log1pl( x ); + * + * + * + * DESCRIPTION: + * + * Returns the base e (2.718...) logarithm of 1+x. + * + * The argument 1+x is separated into its exponent and fractional + * parts. If the exponent is between -1 and +1, the logarithm + * of the fraction is approximated by + * + * log(1+x) = x - 0.5 x^2 + x^3 P(x)/Q(x). + * + * Otherwise, setting z = 2(x-1)/x+1), + * + * log(x) = z + z^3 P(z)/Q(z). + * + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE -1.0, 9.0 100000 8.2e-20 2.5e-20 + * + * ERROR MESSAGES: + * + * log singularity: x-1 = 0; returns -INFINITY + * log domain: x-1 < 0; returns NAN + */ + +#include + +#include "math_private.h" + +/* Coefficients for log(1+x) = x - x^2 / 2 + x^3 P(x)/Q(x) + * 1/sqrt(2) <= x < sqrt(2) + * Theoretical peak relative error = 2.32e-20 + */ + +static long double P[] = { + 4.5270000862445199635215E-5L, + 4.9854102823193375972212E-1L, + 6.5787325942061044846969E0L, + 2.9911919328553073277375E1L, + 6.0949667980987787057556E1L, + 5.7112963590585538103336E1L, + 2.0039553499201281259648E1L, +}; +static long double Q[] = { +/* 1.0000000000000000000000E0,*/ + 1.5062909083469192043167E1L, + 8.3047565967967209469434E1L, + 2.2176239823732856465394E2L, + 3.0909872225312059774938E2L, + 2.1642788614495947685003E2L, + 6.0118660497603843919306E1L, +}; + +/* Coefficients for log(x) = z + z^3 P(z^2)/Q(z^2), + * where z = 2(x-1)/(x+1) + * 1/sqrt(2) <= x < sqrt(2) + * Theoretical peak relative error = 6.16e-22 + */ + +static long double R[4] = { + 1.9757429581415468984296E-3L, +-7.1990767473014147232598E-1L, + 1.0777257190312272158094E1L, +-3.5717684488096787370998E1L, +}; +static long double S[4] = { +/* 1.00000000000000000000E0L,*/ +-2.6201045551331104417768E1L, + 1.9361891836232102174846E2L, +-4.2861221385716144629696E2L, +}; +static const long double C1 = 6.9314575195312500000000E-1L; +static const long double C2 = 1.4286068203094172321215E-6L; + +#define SQRTH 0.70710678118654752440L + +long double +log1pl(long double xm1) +{ +long double x, y, z; +int e; + +if( isnan(xm1) ) + return(xm1); +if( xm1 == INFINITY ) + return(xm1); +if(xm1 == 0.0) + return(xm1); + +x = xm1 + 1.0L; + +/* Test for domain errors. */ +if( x <= 0.0L ) + { + if( x == 0.0L ) + return( -INFINITY ); + else + return( NAN ); + } + +/* Separate mantissa from exponent. + Use frexp so that denormal numbers will be handled properly. */ +x = frexpl( x, &e ); + +/* logarithm using log(x) = z + z^3 P(z)/Q(z), + where z = 2(x-1)/x+1) */ +if( (e > 2) || (e < -2) ) +{ +if( x < SQRTH ) + { /* 2( 2x-1 )/( 2x+1 ) */ + e -= 1; + z = x - 0.5L; + y = 0.5L * z + 0.5L; + } +else + { /* 2 (x-1)/(x+1) */ + z = x - 0.5L; + z -= 0.5L; + y = 0.5L * x + 0.5L; + } +x = z / y; +z = x*x; +z = x * ( z * __polevll( z, R, 3 ) / __p1evll( z, S, 3 ) ); +z = z + e * C2; +z = z + x; +z = z + e * C1; +return( z ); +} + + +/* logarithm using log(1+x) = x - .5x**2 + x**3 P(x)/Q(x) */ + +if( x < SQRTH ) + { + e -= 1; + if (e != 0) + x = 2.0 * x - 1.0L; + else + x = xm1; + } +else + { + if (e != 0) + x = x - 1.0L; + else + x = xm1; + } +z = x*x; +y = x * ( z * __polevll( x, P, 6 ) / __p1evll( x, Q, 6 ) ); +y = y + e * C2; +z = y - 0.5 * z; +z = z + x; +z = z + e * C1; +return( z ); +} diff --git a/src/openlibm/ld80/s_log1pl.c.o b/src/openlibm/ld80/s_log1pl.c.o new file mode 100644 index 0000000000000000000000000000000000000000..e7dd1e194778de0ac5c033e07bed2b0bf9ac2435 GIT binary patch literal 3432 zcmb<-^>JfjWMqH=Mg}_u1P><4z_5Z7!FB*M9T@l-_!vBz-+0{4Q3<$hqw)eI9Pb!$ zJ4eN#^+2iJO;(V=&6BrZ-o07HRHAqD9h|Ln^TmyWH{ad{w~vj1 zf#JqUk6v4l?ClyAftv?z+o;^GQ3(M1=XQ>Y09+kZ)jg1l3~uMBB*4@rz|OP3)U;g_C z5^-T*Xnw)i>7t^;-{SrM|Npx;ZX5vl=B2~`|NqnYIcKl8Uu zV_;yod+X-On+KX-Fy1%?GU48#dmq6bVP;@pfO_QSfg2~m!K(oChyd6l=;}ZoxdT-R z3xALp*s}%@&mwv8l@0?7VCG79V!n|g&@D=Dg8_?uWtNi4-xw-`cta^ zp7)M_`yu>k-M#)cOY_$-LCrJje7t4di+g=6Q1iC$_}KVm4dX|cyy2cDoD-uYma#(B zzgc(ddArWxyD<0M({}ZEx2R_pJ5*l5klFoHXYLJ{ynC^Vk#bYz2NtOO&cJnZM77#J8BtAZF9D+Cy&dDuB7 zFfuUMFfcI4K;`V27#J8__yTF(n7p|7IGniy!F)$P2PQ|pfDFC_CXiG+m|4OH z4J@dBWD4XC7KV@ik;PzaW~?P00|PSy%(XC;3=BLVH#0CZJb(%nKxsaxIJj_OU|>jq ziVHx+VJ?HwLQrw2G6tA9BwSb-IA9V`S`tiyLKn<{6LMe{sPF!0}-Ym!W=|cfCxhdh#rRc_{`$G z#Jn7aw4&6Cf*gkU_=5bL)Uq5f%Mi=}IhFwu&mbl!4THk!&wmJz1qm`RFo2RKD2`y_ zp-AGODiS7M3Ka*LBgnwO027}G6$hEag(Q9oNgR~=?m+o48e|SA?ZC|W0F?)s15#fD z<#T`%JOd3??3gBo0dZF!2^7ab)xRki?Pw zyAw$q@QFm2C^R{ z4ZV z5_40*E}@73`41FS=p_cM{DI|Tm?faJ4`YL9X=s{)sRxOHumC%VWMKFKG8~$JKuk~` z0m(>!2nGfQHE_8HDqEofP^tkM*a09-P%#h%axaL6VI2kraM=iodzcuAzJM+O5`@|X zWr8U~s2C^@fd!xhOh2Ujg$hFb3gUs%6^I6vZy+b4>;C|?AKksM@PpAlQ2Px)h9O}A zs0I2+Vjw2SE@T>1&cMV#;xKFv)eqytXmqupBm{~oXmG=nF*rc=qq_?he=vo$Q1_$j zFM#R?mD@12AR1kN1vE_2(+>xz&}3j>fTa^qUImpCF#Rxbkblta2HA50YX1X}0tN;K zP@d+8rWKGpOh3pPXjFlO;dli!LnOjQAPlH+5Do(a1E>tgre6VMFarZaJ6t7%fvz6_ DvMhxE literal 0 HcmV?d00001 diff --git a/src/openlibm/ld80/s_modfl.c b/src/openlibm/ld80/s_modfl.c new file mode 100644 index 0000000..f9884af --- /dev/null +++ b/src/openlibm/ld80/s_modfl.c @@ -0,0 +1,69 @@ +/* @(#)s_modf.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * modfl(long double x, long double *iptr) + * return fraction part of x, and return x's integral part in *iptr. + * Method: + * Bit twiddling. + * + * Exception: + * No exception. + */ + +#include + +#include "math_private.h" + +static const long double one = 1.0; + +long double +modfl(long double x, long double *iptr) +{ + int32_t i0,i1,jj0; + u_int32_t i,se; + GET_LDOUBLE_WORDS(se,i0,i1,x); + jj0 = (se&0x7fff)-0x3fff; /* exponent of x */ + if(jj0<32) { /* integer part in high x */ + if(jj0<0) { /* |x|<1 */ + SET_LDOUBLE_WORDS(*iptr,se&0x8000,0,0); /* *iptr = +-0 */ + return x; + } else { + i = (0x7fffffff)>>jj0; + if(((i0&i)|i1)==0) { /* x is integral */ + *iptr = x; + SET_LDOUBLE_WORDS(x,se&0x8000,0,0); /* return +-0 */ + return x; + } else { + SET_LDOUBLE_WORDS(*iptr,se,i0&(~i),0); + return x - *iptr; + } + } + } else if (jj0>63) { /* no fraction part */ + *iptr = x*one; + /* We must handle NaNs separately. */ + if (jj0 == 0x4000 && ((i0 & 0x7fffffff) | i1)) + return x*one; + SET_LDOUBLE_WORDS(x,se&0x8000,0,0); /* return +-0 */ + return x; + } else { /* fraction part in low x */ + i = ((u_int32_t)(0x7fffffff))>>(jj0-32); + if((i1&i)==0) { /* x is integral */ + *iptr = x; + SET_LDOUBLE_WORDS(x,se&0x8000,0,0); /* return +-0 */ + return x; + } else { + SET_LDOUBLE_WORDS(*iptr,se,i0,i1&(~i)); + return x - *iptr; + } + } +} diff --git a/src/openlibm/ld80/s_nanl.c b/src/openlibm/ld80/s_nanl.c new file mode 100644 index 0000000..ca77048 --- /dev/null +++ b/src/openlibm/ld80/s_nanl.c @@ -0,0 +1,45 @@ +/*- + * Copyright (c) 2007 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/msun/ld80/s_nanl.c,v 1.2 2007/12/18 23:46:31 das Exp $ + */ + +#include + +#include "math_private.h" + +OLM_DLLEXPORT long double +nanl(const char *s) +{ + union { + union IEEEl2bits ieee; + uint32_t bits[3]; + } u; + + __scan_nan(u.bits, 3, s); + u.ieee.bits.exp = 0x7fff; + u.ieee.bits.manh |= 0xc0000000; /* make it a quiet NaN */ + return (u.ieee.e); +} diff --git a/src/openlibm/ld80/s_nanl.c.o b/src/openlibm/ld80/s_nanl.c.o new file mode 100644 index 0000000000000000000000000000000000000000..ccb2ea95420771aa6cfff090905a0cca15b9f940 GIT binary patch literal 1400 zcmb<-^>JfjWMqH=Mg}_u1P><4z+l0IU^{@B4h*~uJPaPqZzMcAf9+#tU|{g*eEtF? zmDcE^!tuYp(MN@afq~(`Z5W9-VZ|WxSQtM3$0o^)C4{&b7#M_*#KCqj zFfi~lFfa&UGo&~^FEKAiFPQ;EF~r9gCnx5CgrI6+dO&^!;XnT&02CG=C7|d4VGtXP z^@=NVOA?b9^omQ0Aan+dRg{{Os8^C&QNo~?l30?+pqEr!%%GQ?pPQSSSHhr|mtT^q z=k6D(TU?TuoDJot=auRe6y+DB7L`;o=z&d0&4^DcO3Y0KTSqAY@&_o4+0YDvq%8&p zSop!DVc`MeOGDEJOg&6|2FOqb1_lYJ04QESLa>;IiK{U%fMW}kZlOxSR5qBzBtT{$ zi|Q~iFo4V?SHB_DegkAf85kH~_UogG!|aFAR#5$D${1#$3qbiWeNZlg7Xt$WI|Bm) zN*ZEdU|0ZEfbK4kU!hW9DhX;oy8a7bSq26|`eSj#-v+2dVetftKakxZ3^E!f4pN40 zH%J~FsSFGZ6<`hn12+Q$11OHr^>aeSp~~P?1;}6q1_mj(2!sI@hHw}d7zA + +#include "math_private.h" + +long double +nextafterl(long double x, long double y) +{ + int32_t hx,hy,ix,iy; + u_int32_t lx,ly,esx,esy; + + GET_LDOUBLE_WORDS(esx,hx,lx,x); + GET_LDOUBLE_WORDS(esy,hy,ly,y); + ix = esx&0x7fff; /* |x| */ + iy = esy&0x7fff; /* |y| */ + + if (((ix==0x7fff)&&((hx&0x7fffffff|lx)!=0)) || /* x is nan */ + ((iy==0x7fff)&&((hy&0x7fffffff|ly)!=0))) /* y is nan */ + return x+y; + if(x==y) return y; /* x=y, return y */ + if((ix|hx|lx)==0) { /* x == 0 */ + volatile long double u; + SET_LDOUBLE_WORDS(x,esy&0x8000,0,1);/* return +-minsubnormal */ + u = x; + u = u * u; /* raise underflow flag */ + return x; + } + if(esx<0x8000) { /* x > 0 */ + if(ix>iy||((ix==iy) && (hx>hy||((hx==hy)&&(lx>ly))))) { + /* x > y, x -= ulp */ + if(lx==0) { + if ((hx&0x7fffffff)==0) esx -= 1; + hx = (hx - 1) | (hx & 0x80000000); + } + lx -= 1; + } else { /* x < y, x += ulp */ + lx += 1; + if(lx==0) { + hx = (hx + 1) | (hx & 0x80000000); + if ((hx&0x7fffffff)==0) esx += 1; + } + } + } else { /* x < 0 */ + if(esy>=0||(ix>iy||((ix==iy)&&(hx>hy||((hx==hy)&&(lx>ly)))))){ + /* x < y, x -= ulp */ + if(lx==0) { + if ((hx&0x7fffffff)==0) esx -= 1; + hx = (hx - 1) | (hx & 0x80000000); + } + lx -= 1; + } else { /* x > y, x += ulp */ + lx += 1; + if(lx==0) { + hx = (hx + 1) | (hx & 0x80000000); + if ((hx&0x7fffffff)==0) esx += 1; + } + } + } + esy = esx&0x7fff; + if(esy==0x7fff) return x+x; /* overflow */ + if(esy==0) { + volatile long double u = x*x; /* underflow */ + if(u==x) { + SET_LDOUBLE_WORDS(x,esx,hx,lx); + return x; + } + } + SET_LDOUBLE_WORDS(x,esx,hx,lx); + return x; +} + +//__strong_alias(nexttowardl, nextafterl); diff --git a/src/openlibm/ld80/s_nexttoward.c b/src/openlibm/ld80/s_nexttoward.c new file mode 100644 index 0000000..b017668 --- /dev/null +++ b/src/openlibm/ld80/s_nexttoward.c @@ -0,0 +1,86 @@ +/* @(#)s_nextafter.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* IEEE functions + * nexttoward(x,y) + * return the next machine floating-point number of x in the + * direction toward y. + * Special cases: + */ + +#include +#include + +#include "math_private.h" + +double +nexttoward(double x, long double y) +{ + int32_t hx,ix,iy; + u_int32_t lx,hy,ly,esy; + + EXTRACT_WORDS(hx,lx,x); + GET_LDOUBLE_WORDS(esy,hy,ly,y); + ix = hx&0x7fffffff; /* |x| */ + iy = esy&0x7fff; /* |y| */ + + if(((ix>=0x7ff00000)&&((ix-0x7ff00000)|lx)!=0) || /* x is nan */ + ((iy>=0x7fff)&&(hy|ly)!=0)) /* y is nan */ + return x+y; + if((long double) x==y) return y; /* x=y, return y */ + if((ix|lx)==0) { /* x == 0 */ + volatile double u; + INSERT_WORDS(x,(esy&0x8000)<<16,1); /* return +-minsub */ + u = x; + u = u * u; /* raise underflow flag */ + return x; + } + if(hx>=0) { /* x > 0 */ + if (esy>=0x8000||((ix>>20)&0x7ff)>iy-0x3c00 + || (((ix>>20)&0x7ff)==iy-0x3c00 + && (((hx<<11)|(lx>>21))>(hy&0x7fffffff) + || (((hx<<11)|(lx>>21))==(hy&0x7fffffff) + && (lx<<11)>ly)))) { /* x > y, x -= ulp */ + if(lx==0) hx -= 1; + lx -= 1; + } else { /* x < y, x += ulp */ + lx += 1; + if(lx==0) hx += 1; + } + } else { /* x < 0 */ + if (esy<0x8000||((ix>>20)&0x7ff)>iy-0x3c00 + || (((ix>>20)&0x7ff)==iy-0x3c00 + && (((hx<<11)|(lx>>21))>(hy&0x7fffffff) + || (((hx<<11)|(lx>>21))==(hy&0x7fffffff) + && (lx<<11)>ly)))) {/* x < y, x -= ulp */ + if(lx==0) hx -= 1; + lx -= 1; + } else { /* x > y, x += ulp */ + lx += 1; + if(lx==0) hx += 1; + } + } + hy = hx&0x7ff00000; + if(hy>=0x7ff00000) { + x = x+x; /* overflow */ + return x; + } + if(hy<0x00100000) { + volatile double u = x*x; /* underflow */ + if(u==x) { + INSERT_WORDS(x,hx,lx); + return x; + } + } + INSERT_WORDS(x,hx,lx); + return x; +} diff --git a/src/openlibm/ld80/s_nexttowardf.c b/src/openlibm/ld80/s_nexttowardf.c new file mode 100644 index 0000000..f2ac10d --- /dev/null +++ b/src/openlibm/ld80/s_nexttowardf.c @@ -0,0 +1,67 @@ +/* @(#)s_nextafter.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include +#include + +#include "math_private.h" + +float +nexttowardf(float x, long double y) +{ + int32_t hx,ix,iy; + u_int32_t hy,ly,esy; + + GET_FLOAT_WORD(hx,x); + GET_LDOUBLE_WORDS(esy,hy,ly,y); + ix = hx&0x7fffffff; /* |x| */ + iy = esy&0x7fff; /* |y| */ + + if((ix>0x7f800000) || /* x is nan */ + (iy>=0x7fff&&((hy|ly)!=0))) /* y is nan */ + return x+y; + if((long double) x==y) return y; /* x=y, return y */ + if(ix==0) { /* x == 0 */ + volatile float u; + SET_FLOAT_WORD(x,((esy&0x8000)<<16)|1);/* return +-minsub*/ + u = x; + u = u * u; /* raise underflow flag */ + return x; + } + if(hx>=0) { /* x > 0 */ + if(esy>=0x8000||((ix>>23)&0xff)>iy-0x3f80 + || (((ix>>23)&0xff)==iy-0x3f80 + && ((ix&0x7fffff)<<8)>(hy&0x7fffffff))) {/* x > y, x -= ulp */ + hx -= 1; + } else { /* x < y, x += ulp */ + hx += 1; + } + } else { /* x < 0 */ + if(esy<0x8000||((ix>>23)&0xff)>iy-0x3f80 + || (((ix>>23)&0xff)==iy-0x3f80 + && ((ix&0x7fffff)<<8)>(hy&0x7fffffff))) {/* x < y, x -= ulp */ + hx -= 1; + } else { /* x > y, x += ulp */ + hx += 1; + } + } + hy = hx&0x7f800000; + if(hy>=0x7f800000) { + x = x+x; /* overflow */ + return x; + } + if(hy<0x00800000) { + volatile float u = x*x; /* underflow */ + } + SET_FLOAT_WORD(x,hx); + return x; +} diff --git a/src/openlibm/ld80/s_remquol.c b/src/openlibm/ld80/s_remquol.c new file mode 100644 index 0000000..f649dca --- /dev/null +++ b/src/openlibm/ld80/s_remquol.c @@ -0,0 +1,166 @@ +/* @(#)e_fmod.c 1.3 95/01/18 */ +/*- + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include +#include + +#include +#include +#include + +#include "math_private.h" + +#define BIAS (LDBL_MAX_EXP - 1) + +/* + * These macros add and remove an explicit integer bit in front of the + * fractional mantissa, if the architecture doesn't have such a bit by + * default already. + */ +#ifdef LDBL_IMPLICIT_NBIT +#define LDBL_NBIT 0 +#define SET_NBIT(hx) ((hx) | (1ULL << LDBL_MANH_SIZE)) +#define HFRAC_BITS EXT_FRACHBITS +#else +#define LDBL_NBIT 0x80000000 +#define SET_NBIT(hx) (hx) +#define HFRAC_BITS (EXT_FRACHBITS - 1) +#endif + +#define MANL_SHIFT (EXT_FRACLBITS - 1) + +static const long double Zero[] = {0.0L, -0.0L}; + +/* + * Return the IEEE remainder and set *quo to the last n bits of the + * quotient, rounded to the nearest integer. We choose n=31 because + * we wind up computing all the integer bits of the quotient anyway as + * a side-effect of computing the remainder by the shift and subtract + * method. In practice, this is far more bits than are needed to use + * remquo in reduction algorithms. + * + * Assumptions: + * - The low part of the mantissa fits in a manl_t exactly. + * - The high part of the mantissa fits in an int64_t with enough room + * for an explicit integer bit in front of the fractional bits. + */ +long double +remquol(long double x, long double y, int *quo) +{ + int64_t hx,hz; /* We need a carry bit even if LDBL_MANH_SIZE is 32. */ + uint32_t hy; + uint32_t lx,ly,lz; + uint32_t esx, esy; + int ix,iy,n,q,sx,sxy; + + GET_LDOUBLE_WORDS(esx,hx,lx,x); + GET_LDOUBLE_WORDS(esy,hy,ly,y); + sx = esx & 0x8000; + sxy = sx ^ (esy & 0x8000); + esx &= 0x7fff; /* |x| */ + esy &= 0x7fff; /* |y| */ + SET_LDOUBLE_EXP(x,esx); + SET_LDOUBLE_EXP(y,esy); + + /* purge off exception values */ + if((esy|hy|ly)==0 || /* y=0 */ + (esx == BIAS + LDBL_MAX_EXP) || /* or x not finite */ + (esy == BIAS + LDBL_MAX_EXP && + ((hy&~LDBL_NBIT)|ly)!=0)) /* or y is NaN */ + return (x*y)/(x*y); + if(esx<=esy) { + if((esx>MANL_SHIFT); lx = lx+lx;} + else {hx = hz+hz+(lz>>MANL_SHIFT); lx = lz+lz; q++;} + q <<= 1; + } + hz=hx-hy;lz=lx-ly; if(lx=0) {hx=hz;lx=lz;q++;} + + /* convert back to floating value and restore the sign */ + if((hx|lx)==0) { /* return sign(x)*0 */ + *quo = (sxy ? -q : q); + return Zero[sx!=0]; + } + while(hx<(1ULL<>MANL_SHIFT); lx = lx+lx; + iy -= 1; + } + if (iy < LDBL_MIN_EXP) { + esx = (iy + BIAS + 512) & 0x7fff; + SET_LDOUBLE_WORDS(x,esx,hx,lx); + x *= 0x1p-512; + GET_LDOUBLE_WORDS(esx,hx,lx,x); + } else { + esx = (iy + BIAS) & 0x7fff; + } + SET_LDOUBLE_WORDS(x,esx,hx,lx); +fixup: + y = fabsl(y); + if (y < LDBL_MIN * 2) { + if (x+x>y || (x+x==y && (q & 1))) { + q++; + x-=y; + } + } else if (x>0.5*y || (x==0.5*y && (q & 1))) { + q++; + x-=y; + } + + GET_LDOUBLE_EXP(esx,x); + esx ^= sx; + SET_LDOUBLE_EXP(x,esx); + + q &= 0x7fffffff; + *quo = (sxy ? -q : q); + return x; +} diff --git a/src/openlibm/ld80/s_tanhl.c b/src/openlibm/ld80/s_tanhl.c new file mode 100644 index 0000000..1a46583 --- /dev/null +++ b/src/openlibm/ld80/s_tanhl.c @@ -0,0 +1,79 @@ +/* @(#)s_tanh.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* tanhl(x) + * Return the Hyperbolic Tangent of x + * + * Method : + * x -x + * e - e + * 0. tanhl(x) is defined to be ----------- + * x -x + * e + e + * 1. reduce x to non-negative by tanhl(-x) = -tanhl(x). + * 2. 0 <= x <= 2**-55 : tanhl(x) := x*(one+x) + * -t + * 2**-55 < x <= 1 : tanhl(x) := -----; t = expm1l(-2x) + * t + 2 + * 2 + * 1 <= x <= 23.0 : tanhl(x) := 1- ----- ; t=expm1l(2x) + * t + 2 + * 23.0 < x <= INF : tanhl(x) := 1. + * + * Special cases: + * tanhl(NaN) is NaN; + * only tanhl(0)=0 is exact for finite argument. + */ + +#include + +#include "math_private.h" + +static const long double one=1.0, two=2.0, tiny = 1.0e-4900L; + +long double +tanhl(long double x) +{ + long double t,z; + int32_t se; + u_int32_t jj0,jj1,ix; + + /* High word of |x|. */ + GET_LDOUBLE_WORDS(se,jj0,jj1,x); + ix = se&0x7fff; + + /* x is INF or NaN */ + if(ix==0x7fff) { + /* for NaN it's not important which branch: tanhl(NaN) = NaN */ + if (se&0x8000) return one/x-one; /* tanhl(-inf)= -1; */ + else return one/x+one; /* tanhl(+inf)=+1 */ + } + + /* |x| < 23 */ + if (ix < 0x4003 || (ix == 0x4003 && jj0 < 0xb8000000u)) {/* |x|<23 */ + if ((ix|jj0|jj1) == 0) + return x; /* x == +- 0 */ + if (ix<0x3fc8) /* |x|<2**-55 */ + return x*(one+tiny); /* tanh(small) = small */ + if (ix>=0x3fff) { /* |x|>=1 */ + t = expm1l(two*fabsl(x)); + z = one - two/(t+two); + } else { + t = expm1l(-two*fabsl(x)); + z= -t/(t+two); + } + /* |x| > 23, return +-1 */ + } else { + z = one - tiny; /* raised inexact flag */ + } + return (se&0x8000)? -z: z; +} diff --git a/src/openlibm/ld80/s_tanhl.c.o b/src/openlibm/ld80/s_tanhl.c.o new file mode 100644 index 0000000000000000000000000000000000000000..214e691197852007e02730cf2d05388104415874 GIT binary patch literal 1968 zcmb<-^>JfjWMqH=Mg}_u1P><4z+k|FU^{@B4h(z@ybQq}-7zW>oj1}{|JSG4{;%h6 zImN)h;L+`)BH+<^%H!ZGg*00xhq{b3TV@CT)?*9|42{43|Np<8zkL@21H)^9yEoF( z^!Vjlz((@RGyE@6kpSTrAOVl&Hv%^f+_q5x^KP<2#EvN3Ie72m%@_9`rnTO#WV-nv z`Y^(X+c_!%oTvErpWr-I@;uG-PzenLBriIR8zswM9)aiP{GK+$kf2l&_F>WC^bdFBe4W3p=+)QGKGNw6s!si z3=AM!-Tgutm>3ujfW#oO3=E7=J}gc|pc0H#K@5x)0*ul;>>Lvq85nFB7#L)rax5Ul zj(h^mOiaOi5-xlSo_q!&d;$Snd>r1~v3v?add>l|+*eQ@vEDRt2 zW0PgZl2W+A3PHXBGvI^(n8gbAFPI4>L>U+ugpkYuyPbi7L7IVq0ip-05K1ZH5N9Zk zFGSMG!gz#wtq9Nz^Mzttes8OGzwAWY9}0E@sdx$_H`ul8Z}B81$0! zb8}PkN*MI=@=H?n-2Fmzi%Sxdv!VR-yi&b_qWpr?qLNAmJ+N`98S!aFiMgp@yQx5c z`~^x=ps+_a4wQjFd|3R0*dUCa20-Zo6oxSMAT=QT0UAgvKpX}J22eT#*#k@65>Rn9 z22h@Y#3fV+Ou2v*gITBqy08ud0|UrRP+TFaBv!v6)P5mk%?u0-F#RC2k)=R>1@U3D z9aO&oNDvA8Kpm=&BnDzah2c5O9jYHBhm5OX3Xuh|s10XeU;w3GXmG<-H$e5Hy9?bv z`A{>_^>2XckARy9VW8{JVt|yH=TF2E{)oG_F7K +//#include + +#include +#include +#include + +#include "math_private.h" + +#ifdef LDBL_IMPLICIT_NBIT +#define MANH_SIZE (EXT_FRACHBITS + 1) +#else +#define MANH_SIZE EXT_FRACHBITS +#endif + +static const long double huge = 1.0e300; +static const float zero[] = { 0.0, -0.0 }; + +long double +truncl(long double x) +{ + int e, es; + uint32_t ix0, ix1; + + GET_LDOUBLE_WORDS(es,ix0,ix1,x); + e = (es&0x7fff) - LDBL_MAX_EXP + 1; + + if (e < MANH_SIZE - 1) { + if (e < 0) { /* raise inexact if x != 0 */ + if (huge + x > 0.0) + return (zero[(es&0x8000)!=0]); + } else { + uint64_t m = ((1llu << MANH_SIZE) - 1) >> (e + 1); + if (((ix0 & m) | ix1) == 0) + return (x); /* x is integral */ + if (huge + x > 0.0) { /* raise inexact flag */ + ix0 &= ~m; + ix1 = 0; + } + } + } else if (e < LDBL_MANT_DIG - 1) { + uint64_t m = (uint64_t)-1 >> (64 - LDBL_MANT_DIG + e + 1); + if ((ix1 & m) == 0) + return (x); /* x is integral */ + if (huge + x > 0.0) /* raise inexact flag */ + ix1 &= ~m; + } + SET_LDOUBLE_WORDS(x,es,ix0,ix1); + return (x); +} diff --git a/src/openlibm/loongarch64/Make.files b/src/openlibm/loongarch64/Make.files new file mode 100644 index 0000000..483a7cc --- /dev/null +++ b/src/openlibm/loongarch64/Make.files @@ -0,0 +1 @@ +$(CUR_SRCS) = fenv.c diff --git a/src/openlibm/loongarch64/fenv.c b/src/openlibm/loongarch64/fenv.c new file mode 100644 index 0000000..9c95f2a --- /dev/null +++ b/src/openlibm/loongarch64/fenv.c @@ -0,0 +1,27 @@ +#define __fenv_static +#include + +#ifdef __GNUC_GNU_INLINE__ +#error "This file must be compiled with C99 'inline' semantics" +#endif + +/* + * Hopefully the system ID byte is immutable, so it's valid to use + * this as a default environment. + */ +const fenv_t __fe_dfl_env = 0; + +extern inline int feclearexcept(int __excepts); +extern inline int fegetexceptflag(fexcept_t *__flagp, int __excepts); +extern inline int fesetexceptflag(const fexcept_t *__flagp, int __excepts); +extern inline int feraiseexcept(int __excepts); +extern inline int fetestexcept(int __excepts); +extern inline int fegetround(void); +extern inline int fesetround(int __round); +extern inline int fegetenv(fenv_t *__envp); +extern inline int feholdexcept(fenv_t *__envp); +extern inline int fesetenv(const fenv_t *__envp); +extern inline int feupdateenv(const fenv_t *__envp); +extern inline int feenableexcept(int __mask); +extern inline int fedisableexcept(int __mask); +extern inline int fegetexcept(void); \ No newline at end of file diff --git a/src/openlibm/mips/Make.files b/src/openlibm/mips/Make.files new file mode 100644 index 0000000..483a7cc --- /dev/null +++ b/src/openlibm/mips/Make.files @@ -0,0 +1 @@ +$(CUR_SRCS) = fenv.c diff --git a/src/openlibm/mips/fenv-softfloat.h b/src/openlibm/mips/fenv-softfloat.h new file mode 100644 index 0000000..0511335 --- /dev/null +++ b/src/openlibm/mips/fenv-softfloat.h @@ -0,0 +1,184 @@ +/*- + * Copyright (c) 2004-2011 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _FENV_H_ +#error "This file is meant to be included only by ." +#endif + +/* + * This file implements the functionality of on platforms that + * lack an FPU and use softfloat in libc for floating point. To use it, + * you must write an that provides the following: + * + * - a typedef for fenv_t, which may be an integer or struct type + * - a typedef for fexcept_t (XXX This file assumes fexcept_t is a + * simple integer type containing the exception mask.) + * - definitions of FE_* constants for the five exceptions and four + * rounding modes in IEEE 754, as described in fenv(3) + * - a definition, and the corresponding external symbol, for FE_DFL_ENV + * - a macro __set_env(env, flags, mask, rnd), which sets the given fenv_t + * from the exception flags, mask, and rounding mode + * - macros __env_flags(env), __env_mask(env), and __env_round(env), which + * extract fields from an fenv_t + * - a definition of __fenv_static + * + * If the architecture supports an optional FPU, it's recommended that you + * define fenv_t and fexcept_t to match the hardware ABI. Otherwise, it + * doesn't matter how you define them. + */ + +extern int __softfloat_float_exception_flags; +extern int __softfloat_float_exception_mask; +extern int __softfloat_float_rounding_mode; +void __softfloat_float_raise(int); + +__fenv_static inline int +feclearexcept(int __excepts) +{ + + __softfloat_float_exception_flags &= ~__excepts; + return (0); +} + +__fenv_static inline int +fegetexceptflag(fexcept_t *__flagp, int __excepts) +{ + + *__flagp = __softfloat_float_exception_flags & __excepts; + return (0); +} + +__fenv_static inline int +fesetexceptflag(const fexcept_t *__flagp, int __excepts) +{ + + __softfloat_float_exception_flags &= ~__excepts; + __softfloat_float_exception_flags |= *__flagp & __excepts; + return (0); +} + +__fenv_static inline int +feraiseexcept(int __excepts) +{ + + __softfloat_float_raise(__excepts); + return (0); +} + +__fenv_static inline int +fetestexcept(int __excepts) +{ + + return (__softfloat_float_exception_flags & __excepts); +} + +__fenv_static inline int +fegetround(void) +{ + + return (__softfloat_float_rounding_mode); +} + +__fenv_static inline int +fesetround(int __round) +{ + + __softfloat_float_rounding_mode = __round; + return (0); +} + +__fenv_static inline int +fegetenv(fenv_t *__envp) +{ + + __set_env(*__envp, __softfloat_float_exception_flags, + __softfloat_float_exception_mask, __softfloat_float_rounding_mode); + return (0); +} + +__fenv_static inline int +feholdexcept(fenv_t *__envp) +{ + fenv_t __env; + + fegetenv(__envp); + __softfloat_float_exception_flags = 0; + __softfloat_float_exception_mask = 0; + return (0); +} + +__fenv_static inline int +fesetenv(const fenv_t *__envp) +{ + + __softfloat_float_exception_flags = __env_flags(*__envp); + __softfloat_float_exception_mask = __env_mask(*__envp); + __softfloat_float_rounding_mode = __env_round(*__envp); + return (0); +} + +__fenv_static inline int +feupdateenv(const fenv_t *__envp) +{ + int __oflags = __softfloat_float_exception_flags; + + fesetenv(__envp); + feraiseexcept(__oflags); + return (0); +} + +#if __BSD_VISIBLE + +/* We currently provide no external definitions of the functions below. */ + +__fenv_static inline int +feenableexcept(int __mask) +{ + int __omask = __softfloat_float_exception_mask; + + __softfloat_float_exception_mask |= __mask; + return (__omask); +} + +__fenv_static inline int +fedisableexcept(int __mask) +{ + int __omask = __softfloat_float_exception_mask; + + __softfloat_float_exception_mask &= ~__mask; + return (__omask); +} + +__fenv_static inline int +fegetexcept(void) +{ + + return (__softfloat_float_exception_mask); +} + +#endif /* __BSD_VISIBLE */ \ No newline at end of file diff --git a/src/openlibm/mips/fenv.c b/src/openlibm/mips/fenv.c new file mode 100644 index 0000000..4a7ed80 --- /dev/null +++ b/src/openlibm/mips/fenv.c @@ -0,0 +1,67 @@ +/*- + * Copyright (c) 2004 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#define __fenv_static +#include "openlibm_fenv.h" + +#ifdef __GNUC_GNU_INLINE__ +#error "This file must be compiled with C99 'inline' semantics" +#endif + +/* + * Hopefully the system ID byte is immutable, so it's valid to use + * this as a default environment. + */ +const fenv_t __fe_dfl_env = 0; + +#ifdef __mips_soft_float +#define __set_env(env, flags, mask, rnd) env = ((flags) \ + | (mask)<<_FPUSW_SHIFT \ + | (rnd) << 24) +#define __env_flags(env) ((env) & FE_ALL_EXCEPT) +#define __env_mask(env) (((env) >> _FPUSW_SHIFT) \ + & FE_ALL_EXCEPT) +#define __env_round(env) (((env) >> 24) & _ROUND_MASK) +#include "fenv-softfloat.h" +#endif + +extern inline int feclearexcept(int __excepts); +extern inline int fegetexceptflag(fexcept_t *__flagp, int __excepts); +extern inline int fesetexceptflag(const fexcept_t *__flagp, int __excepts); +extern inline int feraiseexcept(int __excepts); +extern inline int fetestexcept(int __excepts); +extern inline int fegetround(void); +extern inline int fesetround(int __round); +extern inline int fegetenv(fenv_t *__envp); +extern inline int feholdexcept(fenv_t *__envp); +extern inline int fesetenv(const fenv_t *__envp); +extern inline int feupdateenv(const fenv_t *__envp); +extern inline int feenableexcept(int __mask); +extern inline int fedisableexcept(int __mask); +extern inline int fegetexcept(void); + diff --git a/src/openlibm/openlibm.pc.in b/src/openlibm/openlibm.pc.in new file mode 100644 index 0000000..bfad876 --- /dev/null +++ b/src/openlibm/openlibm.pc.in @@ -0,0 +1,6 @@ +Name: openlibm +Version: ${version} +URL: https://github.com/JuliaMath/openlibm +Description: High quality system independent, open source libm. +Cflags: -I${includedir} +Libs: -L${libdir} -lopenlibm diff --git a/src/openlibm/powerpc/Make.files b/src/openlibm/powerpc/Make.files new file mode 100644 index 0000000..483a7cc --- /dev/null +++ b/src/openlibm/powerpc/Make.files @@ -0,0 +1 @@ +$(CUR_SRCS) = fenv.c diff --git a/src/openlibm/powerpc/fenv.c b/src/openlibm/powerpc/fenv.c new file mode 100644 index 0000000..bf7d0cb --- /dev/null +++ b/src/openlibm/powerpc/fenv.c @@ -0,0 +1,47 @@ +/*- + * Copyright (c) 2004 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include + +#ifdef __GNUC_GNU_INLINE__ +#error "This file must be compiled with C99 'inline' semantics" +#endif + +const fenv_t __fe_dfl_env = 0x00000000; + +extern inline int feclearexcept(int __excepts); +extern inline int fegetexceptflag(fexcept_t *__flagp, int __excepts); +extern inline int fesetexceptflag(const fexcept_t *__flagp, int __excepts); +extern inline int feraiseexcept(int __excepts); +extern inline int fetestexcept(int __excepts); +extern inline int fegetround(void); +extern inline int fesetround(int __round); +extern inline int fegetenv(fenv_t *__envp); +extern inline int feholdexcept(fenv_t *__envp); +extern inline int fesetenv(const fenv_t *__envp); +extern inline int feupdateenv(const fenv_t *__envp); diff --git a/src/openlibm/riscv64/Make.files b/src/openlibm/riscv64/Make.files new file mode 100644 index 0000000..483a7cc --- /dev/null +++ b/src/openlibm/riscv64/Make.files @@ -0,0 +1 @@ +$(CUR_SRCS) = fenv.c diff --git a/src/openlibm/riscv64/fenv.c b/src/openlibm/riscv64/fenv.c new file mode 100644 index 0000000..467bffe --- /dev/null +++ b/src/openlibm/riscv64/fenv.c @@ -0,0 +1,63 @@ +/*- + * Copyright (c) 2004 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: head/lib/msun/riscv/fenv.c 332792 2018-04-19 20:36:15Z brooks $ + */ + +#define __fenv_static +#include + +#ifdef __GNUC_GNU_INLINE__ +#error "This file must be compiled with C99 'inline' semantics" +#endif + +/* + * Hopefully the system ID byte is immutable, so it's valid to use + * this as a default environment. + */ +const fenv_t __fe_dfl_env = 0; + +#ifdef __riscv_float_abi_soft +#define __set_env(env, flags, mask, rnd) env = ((flags) | (rnd) << 5) +#define __env_flags(env) ((env) & FE_ALL_EXCEPT) +#define __env_mask(env) (0) /* No exception traps. */ +#define __env_round(env) (((env) >> 5) & _ROUND_MASK) +#include "fenv-softfloat.h" +#endif + +extern inline int feclearexcept(int __excepts); +extern inline int fegetexceptflag(fexcept_t *__flagp, int __excepts); +extern inline int fesetexceptflag(const fexcept_t *__flagp, int __excepts); +extern inline int feraiseexcept(int __excepts); +extern inline int fetestexcept(int __excepts); +extern inline int fegetround(void); +extern inline int fesetround(int __round); +extern inline int fegetenv(fenv_t *__envp); +extern inline int feholdexcept(fenv_t *__envp); +extern inline int fesetenv(const fenv_t *__envp); +extern inline int feupdateenv(const fenv_t *__envp); +extern inline int feenableexcept(int __mask); +extern inline int fedisableexcept(int __mask); +extern inline int fegetexcept(void); diff --git a/src/openlibm/s390/Make.files b/src/openlibm/s390/Make.files new file mode 100644 index 0000000..483a7cc --- /dev/null +++ b/src/openlibm/s390/Make.files @@ -0,0 +1 @@ +$(CUR_SRCS) = fenv.c diff --git a/src/openlibm/s390/fenv.c b/src/openlibm/s390/fenv.c new file mode 100644 index 0000000..2bcce76 --- /dev/null +++ b/src/openlibm/s390/fenv.c @@ -0,0 +1,50 @@ +/*- + * Copyright (c) 2016 Dan Horák + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + * + * cloned from ppc/fenv.c + */ + +#define __fenv_static +#include + +#ifdef __GNUC_GNU_INLINE__ +#error "This file must be compiled with C99 'inline' semantics" +#endif + +const fenv_t __fe_dfl_env = 0x00000000; + +extern inline int feclearexcept(int __excepts); +extern inline int fegetexceptflag(fexcept_t *__flagp, int __excepts); +extern inline int fesetexceptflag(const fexcept_t *__flagp, int __excepts); +extern inline int feraiseexcept(int __excepts); +extern inline int fetestexcept(int __excepts); +extern inline int fegetround(void); +extern inline int fesetround(int __round); +extern inline int fegetenv(fenv_t *__envp); +extern inline int feholdexcept(fenv_t *__envp); +extern inline int fesetenv(const fenv_t *__envp); +extern inline int feupdateenv(const fenv_t *__envp); diff --git a/src/openlibm/src/Make.files b/src/openlibm/src/Make.files new file mode 100644 index 0000000..5170403 --- /dev/null +++ b/src/openlibm/src/Make.files @@ -0,0 +1,78 @@ +$(CUR_SRCS) = common.c \ + e_acos.c e_acosf.c e_acosh.c e_acoshf.c e_asin.c e_asinf.c \ + e_atan2.c e_atan2f.c e_atanh.c e_atanhf.c e_cosh.c e_coshf.c e_exp.c \ + e_expf.c e_fmod.c e_fmodf.c \ + e_hypot.c e_hypotf.c e_j0.c e_j0f.c e_j1.c e_j1f.c \ + e_jn.c e_jnf.c e_lgamma.c e_lgamma_r.c e_lgammaf.c e_lgammaf_r.c \ + e_log.c e_log10.c e_log10f.c e_log2.c e_log2f.c e_logf.c \ + e_pow.c e_powf.c e_remainder.c e_remainderf.c \ + e_rem_pio2.c e_rem_pio2f.c \ + e_sinh.c e_sinhf.c e_sqrt.c e_sqrtf.c \ + k_cos.c k_exp.c k_expf.c k_rem_pio2.c k_sin.c k_tan.c \ + k_cosf.c k_sinf.c k_tanf.c \ + s_asinh.c s_asinhf.c s_atan.c s_atanf.c s_carg.c s_cargf.c \ + s_cbrt.c s_cbrtf.c s_ceil.c s_ceilf.c \ + s_copysign.c s_copysignf.c s_cos.c s_cosf.c \ + s_csqrt.c s_csqrtf.c s_erf.c s_erff.c \ + s_exp2.c s_exp2f.c s_expm1.c s_expm1f.c s_fabs.c s_fabsf.c s_fdim.c \ + s_floor.c s_floorf.c \ + s_fmax.c s_fmaxf.c s_fmin.c \ + s_fminf.c s_fpclassify.c \ + s_frexp.c s_frexpf.c s_ilogb.c s_ilogbf.c \ + s_isinf.c s_isfinite.c s_isnormal.c s_isnan.c \ + s_log1p.c s_log1pf.c s_logb.c s_logbf.c \ + s_modf.c s_modff.c \ + s_nextafter.c s_nextafterf.c \ + s_nexttowardf.c s_remquo.c s_remquof.c \ + s_rint.c s_rintf.c s_round.c s_roundf.c \ + s_scalbln.c s_scalbn.c s_scalbnf.c s_signbit.c \ + s_signgam.c s_sin.c s_sincos.c \ + s_sinf.c s_sincosf.c s_tan.c s_tanf.c s_tanh.c s_tanhf.c s_tgammaf.c \ + s_trunc.c s_truncf.c s_cpow.c s_cpowf.c \ + w_cabs.c w_cabsf.c + +ifneq ($(ARCH), wasm32) + +$(CUR_SRCS) += \ + s_fma.c s_fmaf.c s_lrint.c s_lrintf.c s_lround.c s_lroundf.c \ + s_llrint.c s_llrintf.c s_llround.c s_llroundf.c s_nearbyint.c + +ifneq ($(OS), WINNT) +$(CUR_SRCS) += s_nan.c +endif + +endif + +# Add in long double functions for x86, x64 and aarch64 +ifeq ($(LONG_DOUBLE_NOT_DOUBLE),1) +# C99 long double functions +$(CUR_SRCS) += s_copysignl.c s_fabsl.c s_llrintl.c s_lrintl.c s_modfl.c + +# If long double != double use these; otherwise, we alias the double versions. +$(CUR_SRCS) += e_acosl.c e_asinl.c e_atan2l.c e_fmodl.c \ + s_fmaxl.c s_fminl.c s_ilogbl.c \ + e_hypotl.c e_lgammal.c e_remainderl.c e_sqrtl.c \ + s_atanl.c s_ceill.c s_cosl.c s_cprojl.c \ + s_csqrtl.c s_floorl.c s_fmal.c \ + s_frexpl.c s_logbl.c s_nexttoward.c \ + s_remquol.c s_roundl.c s_lroundl.c s_llroundl.c \ + s_cpowl.c s_cargl.c \ + s_sinl.c s_sincosl.c s_tanl.c s_truncl.c w_cabsl.c \ + s_nextafterl.c s_rintl.c s_scalbnl.c polevll.c \ + s_casinl.c s_ctanl.c \ + s_cimagl.c s_conjl.c s_creall.c s_cacoshl.c s_catanhl.c s_casinhl.c \ + s_catanl.c s_csinl.c s_cacosl.c s_cexpl.c s_csinhl.c s_ccoshl.c \ + s_clogl.c s_ctanhl.c s_ccosl.c s_cbrtl.c +endif + +# C99 complex functions +$(CUR_SRCS) += s_ccosh.c s_ccoshf.c s_cexp.c s_cexpf.c \ + s_cimag.c s_cimagf.c \ + s_conj.c s_conjf.c \ + s_cproj.c s_cprojf.c s_creal.c s_crealf.c \ + s_csinh.c s_csinhf.c s_ctanh.c s_ctanhf.c \ + s_cacos.c s_cacosf.c \ + s_cacosh.c s_cacoshf.c \ + s_casin.c s_casinf.c s_casinh.c s_casinhf.c \ + s_catan.c s_catanf.c s_catanh.c s_catanhf.c \ + s_clog.c s_clogf.c diff --git a/src/openlibm/src/aarch64_fpmath.h b/src/openlibm/src/aarch64_fpmath.h new file mode 100644 index 0000000..e1fdc63 --- /dev/null +++ b/src/openlibm/src/aarch64_fpmath.h @@ -0,0 +1,60 @@ +/*- + * Copyright (c) 2002, 2003 David Schultz + * Copyright (2) 2014 The FreeBSD Foundation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: head/lib/libc/aarch64/_fpmath.h 281197 2015-04-07 09:52:14Z andrew $ + */ + +#include + +union IEEEl2bits { + long double e; + struct { + uint64_t manl :64; + uint64_t manh :48; + unsigned int exp :15; + unsigned int sign :1; + } bits; + /* TODO andrew: Check the packing here */ + struct { + uint64_t manl :64; + uint64_t manh :48; + unsigned int expsign :16; + } xbits; +}; + +#define LDBL_NBIT 0 +#define LDBL_IMPLICIT_NBIT +#define mask_nbit_l(u) ((void)0) + +#define LDBL_MANH_SIZE 48 +#define LDBL_MANL_SIZE 64 + +#define LDBL_TO_ARRAY32(u, a) do { \ + (a)[0] = (uint32_t)(u).bits.manl; \ + (a)[1] = (uint32_t)((u).bits.manl >> 32); \ + (a)[2] = (uint32_t)(u).bits.manh; \ + (a)[3] = (uint32_t)((u).bits.manh >> 32); \ +} while(0) diff --git a/src/openlibm/src/amd64_fpmath.h b/src/openlibm/src/amd64_fpmath.h new file mode 100644 index 0000000..41b01c3 --- /dev/null +++ b/src/openlibm/src/amd64_fpmath.h @@ -0,0 +1,55 @@ +/*- + * Copyright (c) 2002, 2003 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libc/amd64/_fpmath.h,v 1.7 2008/01/17 16:39:06 bde Exp $ + */ + +union IEEEl2bits { + long double e; + struct { + unsigned int manl :32; + unsigned int manh :32; + unsigned int exp :15; + unsigned int sign :1; + unsigned int junkl :16; + unsigned int junkh :32; + } bits; + struct { + unsigned long man :64; + unsigned int expsign :16; + unsigned long junk :48; + } xbits; +}; + +#define LDBL_NBIT 0x80000000 +#define mask_nbit_l(u) ((u).bits.manh &= ~LDBL_NBIT) + +#define LDBL_MANH_SIZE 32 +#define LDBL_MANL_SIZE 32 + +#define LDBL_TO_ARRAY32(u, a) do { \ + (a)[0] = (uint32_t)(u).bits.manl; \ + (a)[1] = (uint32_t)(u).bits.manh; \ +} while (0) diff --git a/src/openlibm/src/bsd_cdefs.h b/src/openlibm/src/bsd_cdefs.h new file mode 100644 index 0000000..5799193 --- /dev/null +++ b/src/openlibm/src/bsd_cdefs.h @@ -0,0 +1,102 @@ +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Berkeley Software Design, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)cdefs.h 8.8 (Berkeley) 1/9/95 + * $FreeBSD: src/sys/sys/cdefs.h,v 1.114 2011/02/18 21:44:53 nwhitehorn Exp $ + */ + +/* Do not redefine macros if the system provides them in sys/cdefs.h. + * The two macros correspond to different platforms. */ +#ifndef _BSD_CDEFS_H_ +#define _BSD_CDEFS_H_ + +/* + * This code has been put in place to help reduce the addition of + * compiler specific defines in FreeBSD code. It helps to aid in + * having a compiler-agnostic source tree. + */ + +#if defined(__GNUC__) || defined(__INTEL_COMPILER) + +#if __GNUC__ >= 3 || defined(__INTEL_COMPILER) +#define __GNUCLIKE_ASM 3 +#else +#define __GNUCLIKE_ASM 2 +#endif + +#define __CC_SUPPORTS___INLINE__ 1 + +#endif /* __GNUC__ || __INTEL_COMPILER */ + +#if defined(__STDC__) || defined(__cplusplus) + +#define __volatile volatile +#if defined(__cplusplus) +#define __inline inline /* convert to C++ keyword */ +#else +#if !defined(__CC_SUPPORTS___INLINE) +#define __inline /* delete GCC keyword */ +#endif /* ! __CC_SUPPORTS___INLINE */ +#endif /* !__cplusplus */ + +#else /* !(__STDC__ || __cplusplus) */ + +#if !defined(__CC_SUPPORTS___INLINE) +#define __inline +#define __volatile +#endif /* !__CC_SUPPORTS___INLINE */ +#endif /* !(__STDC__ || __cplusplus) */ + +/* + * Macro to test if we're using a specific version of gcc or later. + */ +#ifndef __GNUC_PREREQ__ +#if defined(__GNUC__) && !defined(__INTEL_COMPILER) +#define __GNUC_PREREQ__(ma, mi) \ + (__GNUC__ > (ma) || __GNUC__ == (ma) && __GNUC_MINOR__ >= (mi)) +#else +#define __GNUC_PREREQ__(ma, mi) 0 +#endif +#endif /* __GNUC_PREREQ__ */ + +/* + * Compiler-dependent macro to help declare pure (no side effects) functions. + * It is null except for versions of gcc that are known to support the features + * properly (old versions of gcc-2 supported the dead and pure features + * in a different (wrong) way), and for icc. If we do not provide an implementation + * for a given compiler, let the compile fail if it is told to use + * a feature that we cannot live without. + */ +#if !defined(__pure2) && (__GNUC_PREREQ__(2, 7) || defined(__INTEL_COMPILER)) +#define __pure2 __attribute__((__const__)) +#endif + +#endif /* !_BSD_CDEFS_H_ */ diff --git a/src/openlibm/src/cdefs-compat.h b/src/openlibm/src/cdefs-compat.h new file mode 100644 index 0000000..834c547 --- /dev/null +++ b/src/openlibm/src/cdefs-compat.h @@ -0,0 +1,105 @@ +#ifndef _CDEFS_COMPAT_H_ +#define _CDEFS_COMPAT_H_ + +#if !defined(__BEGIN_DECLS) +#if defined(__cplusplus) +#define __BEGIN_DECLS extern "C" { +#define __END_DECLS } +#else +#define __BEGIN_DECLS +#define __END_DECLS +#endif +#endif /* !defined(__BEGIN_DECLS) */ + +#ifdef __GNUC__ +#if defined(__strong_alias) && defined(__NetBSD__) +#define openlibm_strong_reference(sym,alias) __strong_alias(alias,sym) +#elif defined(__strong_reference) +#define openlibm_strong_reference(sym,alias) __strong_reference(sym,alias) +#else +#ifdef __APPLE__ +#define openlibm_strong_reference(sym,aliassym) openlibm_weak_reference(sym,aliassym) +#else +#define openlibm_strong_reference(sym,aliassym) \ + OLM_DLLEXPORT extern __typeof (aliassym) aliassym __attribute__ ((__alias__ (#sym))); +#endif /* __APPLE__ */ +#endif /* __strong_reference */ + +#ifdef __wasm__ +#define openlibm_weak_reference(sym,alias) openlibm_strong_reference(sym,alias) +#elif defined(__weak_alias) && defined(__NetBSD__) +#define openlibm_weak_reference(sym,alias) __weak_alias(alias,sym) +#elif defined(__weak_reference) +#define openlibm_weak_reference(sym,alias) __weak_reference(sym,alias) +#else +#ifdef __ELF__ +#ifdef __STDC__ +#define openlibm_weak_reference(sym,alias) \ + __asm__(".weak " #alias); \ + __asm__(".equ " #alias ", " #sym) +#ifdef __warn_references +#define openlibm_warn_references(sym,msg) __warn_references(sym,msg) +#else +#define openlibm_warn_references(sym,msg) \ + __asm__(".section .gnu.warning." #sym); \ + __asm__(".asciz \"" msg "\""); \ + __asm__(".previous") +#endif /* __warn_references */ +#else +#define openlibm_weak_reference(sym,alias) \ + __asm__(".weak alias"); \ + __asm__(".equ alias, sym") +#ifdef __warn_references +#define openlibm_warn_references(sym,msg) __warn_references(sym,msg) +#else +#define openlibm_warn_references(sym,msg) \ + __asm__(".section .gnu.warning.sym"); \ + __asm__(".asciz \"msg\""); \ + __asm__(".previous") +#endif /* __warn_references */ +#endif /* __STDC__ */ +#elif defined(__clang__) /* CLANG */ +#if defined(_WIN32) && defined(_X86_) +#define openlibm_asm_symbol_prefix "_" +#else +#define openlibm_asm_symbol_prefix "" +#endif +#ifdef __STDC__ +#define openlibm_weak_reference(sym,alias) \ + __asm__(".weak_reference " openlibm_asm_symbol_prefix #alias); \ + __asm__(".set " openlibm_asm_symbol_prefix #alias ", " openlibm_asm_symbol_prefix #sym) +#else +#define openlibm_weak_reference(sym,alias) \ + __asm__(".weak_reference openlibm_asm_symbol_prefix/**/alias");\ + __asm__(".set openlibm_asm_symbol_prefix/**/alias, openlibm_asm_symbol_prefix/**/sym") +#endif +#else /* !__ELF__ */ +#ifdef __STDC__ +#define openlibm_weak_reference(sym,alias) \ + __asm__(".stabs \"_" #alias "\",11,0,0,0"); \ + __asm__(".stabs \"_" #sym "\",1,0,0,0") +#ifdef __warn_references +#define openlibm_warn_references(sym,msg) __warn_references(sym,msg) +#else +#define openlibm_warn_references(sym,msg) \ + __asm__(".stabs \"" msg "\",30,0,0,0"); \ + __asm__(".stabs \"_" #sym "\",1,0,0,0") +#endif /* __warn_references */ +#else +#define openlibm_weak_reference(sym,alias) \ + __asm__(".stabs \"_/**/alias\",11,0,0,0"); \ + __asm__(".stabs \"_/**/sym\",1,0,0,0") +#ifdef __warn_references +#define openlibm_warn_references(sym,msg) __warn_references(sym,msg) +#else +#define openlibm_warn_references(sym,msg) \ + __asm__(".stabs msg,30,0,0,0"); \ + __asm__(".stabs \"_/**/sym\",1,0,0,0") +#endif /* __warn_references */ +#endif /* __STDC__ */ +#endif /* __ELF__ */ +#endif /* __weak_reference */ +#endif /* __GNUC__ */ + + +#endif /* _CDEFS_COMPAT_H_ */ diff --git a/src/openlibm/src/common.c b/src/openlibm/src/common.c new file mode 100644 index 0000000..b02d697 --- /dev/null +++ b/src/openlibm/src/common.c @@ -0,0 +1,7 @@ +#include + +#include "math_private.h" + +OLM_DLLEXPORT int isopenlibm(void) { + return 1; +} diff --git a/src/openlibm/src/common.c.o b/src/openlibm/src/common.c.o new file mode 100644 index 0000000000000000000000000000000000000000..b32a95a0f8a56f8642d48d33ebecd324242095c4 GIT binary patch literal 1232 zcmb<-^>JfjWMqH=Mg}_u1P><4z;FRc&;cy$z`(=6&9DO`ewe}C+1W}#!`&}bQ^C+g z&q&Wu!N|bK)WFctKtUrYHATTAu>>liYpw~>&ceXJpuoVuz{wn6dbr zi-Cbb2uU1nM{<5{ZhoF#GDBu@enDzpPG(Xr$V`x*Kr|Br0|N+y*kG(zT$x*vn8cu0 zTv7y~GhnQe)QS=Yy_Cd~L1odU%NvY0vp0|N&G0|UAGb)fbeAREfSzyPyfA59!)Ka4ho>PJ(?P>L=9<-_zr zxeTrh3=Hh(anHcOPytnd?k0.5 + * acos(x) = pi/2 - (pi/2 - 2asin(sqrt((1-x)/2))) + * = 2asin(sqrt((1-x)/2)) + * = 2s + 2s*z*R(z) ...z=(1-x)/2, s=sqrt(z) + * = 2f + (2c + 2s*z*R(z)) + * where f=hi part of s, and c = (z-f*f)/(s+f) is the correction term + * for f so that f+c ~ sqrt(z). + * For x<-0.5 + * acos(x) = pi - 2asin(sqrt((1-|x|)/2)) + * = pi - 0.5*(s+s*z*R(z)), where z=(1-|x|)/2,s=sqrt(z) + * + * Special cases: + * if x is NaN, return x itself; + * if |x|>1, return NaN with invalid signal. + * + * Function needed: sqrt + */ + +#include +#include + +#include "math_private.h" + +static const double +one= 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */ +pi = 3.14159265358979311600e+00, /* 0x400921FB, 0x54442D18 */ +pio2_hi = 1.57079632679489655800e+00; /* 0x3FF921FB, 0x54442D18 */ +static volatile double +pio2_lo = 6.12323399573676603587e-17; /* 0x3C91A626, 0x33145C07 */ +static const double +pS0 = 1.66666666666666657415e-01, /* 0x3FC55555, 0x55555555 */ +pS1 = -3.25565818622400915405e-01, /* 0xBFD4D612, 0x03EB6F7D */ +pS2 = 2.01212532134862925881e-01, /* 0x3FC9C155, 0x0E884455 */ +pS3 = -4.00555345006794114027e-02, /* 0xBFA48228, 0xB5688F3B */ +pS4 = 7.91534994289814532176e-04, /* 0x3F49EFE0, 0x7501B288 */ +pS5 = 3.47933107596021167570e-05, /* 0x3F023DE1, 0x0DFDF709 */ +qS1 = -2.40339491173441421878e+00, /* 0xC0033A27, 0x1C8A2D4B */ +qS2 = 2.02094576023350569471e+00, /* 0x40002AE5, 0x9C598AC8 */ +qS3 = -6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */ +qS4 = 7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */ + +OLM_DLLEXPORT double +__ieee754_acos(double x) +{ + double z,p,q,r,w,s,c,df; + int32_t hx,ix; + GET_HIGH_WORD(hx,x); + ix = hx&0x7fffffff; + if(ix>=0x3ff00000) { /* |x| >= 1 */ + u_int32_t lx; + GET_LOW_WORD(lx,x); + if(((ix-0x3ff00000)|lx)==0) { /* |x|==1 */ + if(hx>0) return 0.0; /* acos(1) = 0 */ + else return pi+2.0*pio2_lo; /* acos(-1)= pi */ + } + return (x-x)/(x-x); /* acos(|x|>1) is NaN */ + } + if(ix<0x3fe00000) { /* |x| < 0.5 */ + if(ix<=0x3c600000) return pio2_hi+pio2_lo;/*if|x|<2**-57*/ + z = x*x; + p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5))))); + q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4))); + r = p/q; + return pio2_hi - (x - (pio2_lo-x*r)); + } else if (hx<0) { /* x < -0.5 */ + z = (one+x)*0.5; + p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5))))); + q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4))); + s = sqrt(z); + r = p/q; + w = r*s-pio2_lo; + return pi - 2.0*(s+w); + } else { /* x > 0.5 */ + z = (one-x)*0.5; + s = sqrt(z); + df = s; + SET_LOW_WORD(df,0); + c = (z-df*df)/(s+df); + p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5))))); + q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4))); + r = p/q; + w = r*s+c; + return 2.0*(df+w); + } +} + +#if LDBL_MANT_DIG == 53 +openlibm_weak_reference(acos, acosl); +#endif diff --git a/src/openlibm/src/e_acos.c.o b/src/openlibm/src/e_acos.c.o new file mode 100644 index 0000000000000000000000000000000000000000..dab6f223a0ccd25eebaf4368d0eb516e658f7566 GIT binary patch literal 3904 zcmb<-^>JfjWMqH=Mg}_u1P><4z;J*Y!FB*M9T@l+cp1_>`0EaObe{4!_)4Mkg6jYO z|Lbl4|9@{^Ca255@WGz*1b?d~BLhPk|N8^2m-zc^85tN3^UFIh*#7^2-@aVYmVqI` zhQHm8k%8e8zW^)9;7|M!VEQn>ybA+^NAnwr)=T^yS0E~QAu3`{eBzG;v(xxB4u0Yn za0h z_#^Io;*UH1i9Z6Q{>Uf(hyxJ+f8vih@QFVT#A^U~2jPQ=12B^h^UE`Uy!eS<030T; z0QkfodE*nmfGR{^B*=8AeB@=Aw?FZN#AA@eVLk?lM<9vAd<+sNsQ&aP{y31&PJH5z zd6>qpaRTA)m@}XFV-6nXmxuXB7UDj1w?`cQ#2*O@^%I}?;cmHr8*ao}_Xc4`{G#sx^Si#+s+KL!+epa=yS z1@|T-vSSV&W{(juR$DgFMncymbeoR@Dv5&v*~h~0@jo_cW~?O>0|PSy z$Rbo7Tnr2hj7Z`zYlXndSQ%h^FqeUWK^)9rWk>+i2m&1A46F_8BDS=Km#7k z0}&b^f`OGm08AqYT`-fC!2?Vq2xBmll|cebBM1vHla(O=Od|+8Fq0J=S70WTa0b(? z3=v=&L3o0htPBu$fjMBp4@|N$7=UR65e#OsGC=GHbHD_|Tu|x&bKyiR0|SE)QoMlU zoPmKMiGcwl48WRF;}etfi}jKj3NrJJ;&bvD^n9F+K!l+&m^1;AmLLMcHvlogf`*15 zrYVRp1nV#ZG0j1Q1&Af!Z4|_aKM!10?mx;r0ee966kSAc-S~8w<#z(C|kNX8|N}napdro72Y>vE`am@lHB<&d6+qKpI)n=+LH5Bp3=9mQvI3ia2atmq7#J#%6+^=c GSqK2W&K+j} literal 0 HcmV?d00001 diff --git a/src/openlibm/src/e_acosf.c b/src/openlibm/src/e_acosf.c new file mode 100644 index 0000000..2beab5c --- /dev/null +++ b/src/openlibm/src/e_acosf.c @@ -0,0 +1,78 @@ +/* e_acosf.c -- float version of e_acos.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/e_acosf.c,v 1.11 2008/08/03 17:39:54 das Exp $"); + +#include + +#include "math_private.h" + +static const float +one = 1.0000000000e+00, /* 0x3F800000 */ +pi = 3.1415925026e+00, /* 0x40490fda */ +pio2_hi = 1.5707962513e+00; /* 0x3fc90fda */ +static volatile float +pio2_lo = 7.5497894159e-08; /* 0x33a22168 */ +static const float +pS0 = 1.6666586697e-01, +pS1 = -4.2743422091e-02, +pS2 = -8.6563630030e-03, +qS1 = -7.0662963390e-01; + +OLM_DLLEXPORT float +__ieee754_acosf(float x) +{ + float z,p,q,r,w,s,c,df; + int32_t hx,ix; + GET_FLOAT_WORD(hx,x); + ix = hx&0x7fffffff; + if(ix>=0x3f800000) { /* |x| >= 1 */ + if(ix==0x3f800000) { /* |x| == 1 */ + if(hx>0) return 0.0; /* acos(1) = 0 */ + else return pi+(float)2.0*pio2_lo; /* acos(-1)= pi */ + } + return (x-x)/(x-x); /* acos(|x|>1) is NaN */ + } + if(ix<0x3f000000) { /* |x| < 0.5 */ + if(ix<=0x32800000) return pio2_hi+pio2_lo;/*if|x|<2**-26*/ + z = x*x; + p = z*(pS0+z*(pS1+z*pS2)); + q = one+z*qS1; + r = p/q; + return pio2_hi - (x - (pio2_lo-x*r)); + } else if (hx<0) { /* x < -0.5 */ + z = (one+x)*(float)0.5; + p = z*(pS0+z*(pS1+z*pS2)); + q = one+z*qS1; + s = sqrtf(z); + r = p/q; + w = r*s-pio2_lo; + return pi - (float)2.0*(s+w); + } else { /* x > 0.5 */ + int32_t idf; + z = (one-x)*(float)0.5; + s = sqrtf(z); + df = s; + GET_FLOAT_WORD(idf,df); + SET_FLOAT_WORD(df,idf&0xfffff000); + c = (z-df*df)/(s+df); + p = z*(pS0+z*(pS1+z*pS2)); + q = one+z*qS1; + r = p/q; + w = r*s+c; + return (float)2.0*(df+w); + } +} diff --git a/src/openlibm/src/e_acosf.c.o b/src/openlibm/src/e_acosf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..7833c2c129d4c989a1c688756510edf3c3521eb9 GIT binary patch literal 2968 zcmb<-^>JfjWMqH=Mg}_u1P><4z#zeaU^{@B4h(z@ybNjlb%#1HsQ&-|zuxx$|9bl} zIa>yX27CV2#|#V%Y5eaGv|i%xd(Ozfa5#-$-i3j|_W%F?cIAp7MMnJX=NK3mKJyE( zf(-o39|5KhgVlL7zmaIY#NQ#p2v)%hQ4w?EGk+wQ&98CrGrypZ3dakGjDU{{$7g;4 zRS=I~<3bvL-2sHbkq=cFKK%dxnLqO2XZ{GVnl%2r8=v`Oz&1j~!EBG_BN7mP+!20_ z$DjElAAjbLIrEu6^3Z4gh|8b(<4%3%j{q5S_%naRfy1BqV-9@gk2`RfU%mlq_h)_q zuoFM?3&?_mKJ!Oj_{<-9>N9@~R2;;PKw?LVLexb-X^CgNz z2O;6}nO^{^7~QgnL!bF0!G8J74>km5(G3V6W^u$V2wyM;6mo(-Dm;jw zQJROHV*(=sg9-x!gA7zom5G6YfhmShfvJLzgJ}t$0@EZuq~s4(g-U_!V`2FCA5|2> zW5$}J7#Nrtm>~*~NNxrO21X=tkY7O3!XScy73^Oy6G}*cX;uaZ4d#FeaJ(_F!uz?xFy6O;3c)AW)V3NrJJ;&bvD^n9F+K!iDnumBNeAi@|#n1BdV z5Mjsw*2hp>SX7e6z~BZpjDZ0ZrJ&IM^B)5IkiQarAh62o(p#BXYPgfdru849Xj@@E1W6M^>+ZB#x{eRCa-) z5+n`6AT}856<6k#BqlNF6_*r2=nNREC^aWhuOzjigh4MQu_Tc}FR8egL9Zwu#L-JG zE-_)yOU}>DP0cG|(96p&N!4@r3)L+yNlea$^3(H5^$Lpe3sQ?pDjD>^#-(P&rxhjU zrh@IJ0s-WZm51_F%TQ3 z55xxHa0UhjP<}#JegG2; else + * acosh(x) := log1p(t+sqrt(2.0*t+t*t)); where t=x-1. + * + * Special cases: + * acosh(x) is NaN with signal if x<1. + * acosh(NaN) is NaN without signal. + */ + +#include +#include + +#include "math_private.h" + +static const double +one = 1.0, +ln2 = 6.93147180559945286227e-01; /* 0x3FE62E42, 0xFEFA39EF */ + +OLM_DLLEXPORT double +__ieee754_acosh(double x) +{ + double t; + int32_t hx; + u_int32_t lx; + EXTRACT_WORDS(hx,lx,x); + if(hx<0x3ff00000) { /* x < 1 */ + return (x-x)/(x-x); + } else if(hx >=0x41b00000) { /* x > 2**28 */ + if(hx >=0x7ff00000) { /* x is inf of NaN */ + return x+x; + } else + return __ieee754_log(x)+ln2; /* acosh(huge)=log(2x) */ + } else if(((hx-0x3ff00000)|lx)==0) { + return 0.0; /* acosh(1) = 0 */ + } else if (hx > 0x40000000) { /* 2**28 > x > 2 */ + t=x*x; + return __ieee754_log(2.0*x-one/(x+sqrt(t-one))); + } else { /* 1JfjWMqH=Mg}_u1P><4z|g^hU^{@B4h(z@ybNg`{B?)Y_%%*=bYAc{_(H+< z|Nr;){C&L)3=AI4ZzOF0|6lJ|Cj}C%=kGhuz`*c{KjMT(^AU+OevN~N(85kTA&TPyBHwKJmv~Oyk!$^b#bmn~g42w8~umoac#6hr8Y5eaGfCLWn%Qt|GhAN8yI}a=Y5@ld`Z~5z=lio9X z2=9YEgS)e{m4b%5U#O;np^2W6o}q$~fsv_!p`n3-Mo?;sf=6NrR6^HWlYs#g+zJc~ z3?Ose{X!X-7#I(L#9(p52<3A^EMO3U(u`F>42%^5jM6;p91|EB7<3pI7-XPwLLklY zdroFOd)(6DSQg~Tznj!+#Xzf93I?(d>l}v7!*h=3&Y3%7!nK&49r+k3^!OI zD+9WL0#I=~vD20lH;)0CIQOM_0cG zhxje1IJ!BotOyckM>3xi6afqj3?TDCaxnKSL^20i{Tn24P#nP2gTf6Y1u_SOL2NMA zE3V8fNlaqUD=sO5&>1jRQEE=2UP)?234>lrVo4%{UQ%%}gI-ZSh@+QWTw=kXmzJ=2_7o--IR5Iv+jZ4jlPb*5yO$FOc1p?$R zP!NIQ1lc%9S;fErOHVL4^t1y?XP|I}sfVePV1}@6Kqv-Kx(3+;3R94f1c+c@U{GUV z0Hd-yNzS#74%`VG5B2v8WAaU|;~HUz9Y-z`!sAsvq55Fn7a@&4-$a zuKxs7zXwbqlt$MN%J10X{{u8aVDSu!e^8kV(+?8|S%Ypj$SMJ-AT0gxK+AM={U9@; qR)Ms^@e8PaEw~7T0kRLmf{=pHatgvjkQ^XSF)%PxB80#!bo~IKz6~k> literal 0 HcmV?d00001 diff --git a/src/openlibm/src/e_acoshf.c b/src/openlibm/src/e_acoshf.c new file mode 100644 index 0000000..729e593 --- /dev/null +++ b/src/openlibm/src/e_acoshf.c @@ -0,0 +1,49 @@ +/* e_acoshf.c -- float version of e_acosh.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/e_acoshf.c,v 1.8 2008/02/22 02:30:34 das Exp $"); + +#include + +#include "math_private.h" + +static const float +one = 1.0, +ln2 = 6.9314718246e-01; /* 0x3f317218 */ + +OLM_DLLEXPORT float +__ieee754_acoshf(float x) +{ + float t; + int32_t hx; + GET_FLOAT_WORD(hx,x); + if(hx<0x3f800000) { /* x < 1 */ + return (x-x)/(x-x); + } else if(hx >=0x4d800000) { /* x > 2**28 */ + if(hx >=0x7f800000) { /* x is inf of NaN */ + return x+x; + } else + return __ieee754_logf(x)+ln2; /* acosh(huge)=log(2x) */ + } else if (hx==0x3f800000) { + return 0.0; /* acosh(1) = 0 */ + } else if (hx > 0x40000000) { /* 2**28 > x > 2 */ + t=x*x; + return __ieee754_logf((float)2.0*x-one/(x+__ieee754_sqrtf(t-one))); + } else { /* 1JfjWMqH=Mg}_u1P><4z|g>gU^{@B4h(z@ybNjlbqDx0PT2ncUvJOf*T=xX z;L-d>0>t&LlLk@s{Cy`F7#KeDN1Wi-IOx%QMB*^NyaR(R14Dy7f6Gw@1`w0Mp)QSI zGe)$%Vp$t&@2(ZgQDh@;JN#lQi;HBLE|Nj{n7$k}e?LppSaCdgLQqXYs z3)NIGG|@BCGgL4#FfuhTG&E4q2ue*+@JK9yO6Zzvf{kYY1+xMJ0|Ur>cfU{uCI-d> zATd~+Fhcp95akRaP@1tSh=H*}fKi%c%6G{kzX^^kL3^*ai zz`!7cWDeM^3=9mi3=9kca8(F~G7fPK9O4YA@rlX##TjXO$qafv&PE`@kO3mZP+VA4 zlE#pepAIGr3(^=E;-OYCF)%PNGcYjx`40hEP;pRPupx;zLB-M4Z^0pc5h{*u&POD1 zb|mwELd8MmgY>}MGYu*Z5<^!11WB9&$sACc0!e|)0bvjujP;5ub4wDF81#xuiXe0b zj8&AHlc-mcT2aEFmy%eL$e@>0T+E(QB^Q^NFz6-c=jNv7l`!b#<(H)Dx%-9c z7MCO@XG8hvd8K*V5_40*c2j`>`3sarL2-g?9Hfk5V1T73 zm>hbVl4f84r&XAGxH?eeGcYjRfC_-}2*@5#n1X~PKm-E=gBk+^IQ2r6Lq!=F0zr!5 zJOl$>7?e*zW|FJl5Nf{=!U`}e1Zok;Y_I^70HqfY6Gq!X^&5Z$k#G!Dzdn)}hzS)2 z`x(S{hw2Bhk#RRnA+jJAwc!j5450Ljk|r4#7(ithNGrO#(EXDSH4|O`0jT{RAVZKa zx_(f;289KB{J(%k2rQmK@ee9AZyU=23f}e6@;Z9P`L;y{m}J;%!FD6(gw#5 gp!#uzKTIL0T*amzoTwQX7%E{3p)|<7P$rlH0Cb54dH?_b literal 0 HcmV?d00001 diff --git a/src/openlibm/src/e_acosl.c b/src/openlibm/src/e_acosl.c new file mode 100644 index 0000000..ebe5a22 --- /dev/null +++ b/src/openlibm/src/e_acosl.c @@ -0,0 +1,87 @@ + +/* @(#)e_acos.c 1.3 95/01/18 */ +/* FreeBSD: head/lib/msun/src/e_acos.c 176451 2008-02-22 02:30:36Z das */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/e_acosl.c,v 1.2 2008/08/02 03:56:22 das Exp $"); + +/* + * See comments in e_acos.c. + * Converted to long double by David Schultz . + */ + +#include +#include + +#include "invtrig.h" +#include "math_private.h" + +static const long double +one= 1.00000000000000000000e+00; + +#ifdef __i386__ +/* XXX Work around the fact that gcc truncates long double constants on i386 */ +static volatile double +pi1 = 3.14159265358979311600e+00, /* 0x1.921fb54442d18p+1 */ +pi2 = 1.22514845490862001043e-16; /* 0x1.1a80000000000p-53 */ +#define pi ((long double)pi1 + pi2) +#else +static const long double +pi = 3.14159265358979323846264338327950280e+00L; +#endif + +OLM_DLLEXPORT long double +acosl(long double x) +{ + union IEEEl2bits u; + long double z,p,q,r,w,s,c,df; + int16_t expsign, expt; + u.e = x; + expsign = u.xbits.expsign; + expt = expsign & 0x7fff; + if(expt >= BIAS) { /* |x| >= 1 */ + if(expt==BIAS && ((u.bits.manh&~LDBL_NBIT)|u.bits.manl)==0) { + if (expsign>0) return 0.0; /* acos(1) = 0 */ + else return pi+2.0*pio2_lo; /* acos(-1)= pi */ + } + return (x-x)/(x-x); /* acos(|x|>1) is NaN */ + } + if(expt 0.5 */ + z = (one-x)*0.5; + s = sqrtl(z); + u.e = s; + u.bits.manl = 0; + df = u.e; + c = (z-df*df)/(s+df); + p = P(z); + q = Q(z); + r = p/q; + w = r*s+c; + return 2.0*(df+w); + } +} diff --git a/src/openlibm/src/e_acosl.c.o b/src/openlibm/src/e_acosl.c.o new file mode 100644 index 0000000000000000000000000000000000000000..769a773f40bd48aa1c6f77ce2b8aadbcd3366cb3 GIT binary patch literal 3696 zcmb<-^>JfjWMqH=Mg}_u1P><4!0>?!!FB*M9T@l+co{qz-@IU8VDRXkqVj`*fuZw4 zn(F`hG~0jnWwL3u|LsfMZ?94Lz`($8t(W-wzB4f}+i|jR1FM9jf%o;xM+=v0D@zqf?(IE7$7)s<+vF)58SR%NkC|+QE|Afal1w( z0OYWaeT)nYcW-z!zY(~-N96(o1H_8JvX;NN?BgBRq9 zn+I;&sNCM8(!jvL017yUn+I<1QF*|?z;L_;Oo0^LUIS*{UISKkdyNXn#2Y7XuTcTn zaPJ_P39=K)1i1pt%uy+T(g9F90Zgw^0XgQzsoOa!2KNqvX$2@P0HqxwqM)$@61e%| z-obl6Z=Ak)=*H=LuWp{cap>O9dx!2Fym8=g+5~9yLu2FSfg2~_VRhpqoC&rV7RVHH zZk$3k7(WM+B<~%(ck1Sgdx!3Qym9j0t9uXcy*$h>4+?gMn=inz2Z@*)2O$x2=iJS6 z_m18?bK~s2!#7XeICJmdjnklzxSgW{3QJJXfx_|>C>`89b>k#7C_ywRC_ywRC_%IX z$hY?n-8^|4lq79b!0`+XEs$}yb5sN(>uaq@PC!M&HDP`&y3-ouw0{`~(B%11Dz z83s2F+ahl`KHl{=G*kHejt=>T5?6VrLVAB>KC9~j-a z_&5@|nU-r(VAm4!*a6*8Afk6mK zJ=o0*3=Con3=AMSxI!pH2Zy)?4sjP8;=VYyb6bSGY;_{9O6@P zh|j|zz8r@*sIbBo&J3yXiOKoJIeN(qdOps^3}6mJyt|LTlcP_(znfdIYe;;Eqmz$o zJVU%^iBEiDNn&0`CW4)l4`CMuo5C0-ForRVVFY6sLKp?XW-ta+S3xjTS3xjTS3xjT zS3xjbmjOd@VNppA0|SFCG@WQMFfgz&Ffjc24*~8-;_OJ`laa(Zki_R8iE|=}FGUgu zRn0K-HzA3G(mG6hKaw~Pk~yc5#6gt~O#KZcaXuvV50S+Ak;GpiiG$)1X3l3MaX}>Y ze~`q5ki@w`8JdBC0Tgb+Na7JtaV7=^22gPVGd~k54l1KSWf4qV3#1Tg4zj<@k;IYx z<%A@T>@R;Lab$nRAc-UUD-%f^*iALMiNJk_X$Yi$nicKNgO%eS0ITa$NN?! zapZXa2o(oW$l)0X;xI5UpoeD!R2&p9$mzBjhd8JX0Yx#$d=Lh)!C0@jGPfi#i9xTp zqzFQ1z*t48If;5DsTCy*dMSw|i41y4#l;MIMfo6(UUG4X34>m8er|4RUI~L!_@P?TSgT2xZWpa(WCH6uQ)C^0t`Y&R7MkiS4l4wR>njf1p_ z85m&o222i=W?*a(Ee#D@n0k;H2uFYd6~ussCnyd<_JGm^NLT_yFfcHvF@Wk|NFIO+ zfvKxdeP9j}0Wt%L%K)mkKxU#VCsw~9)P7LfMmF~b)IdIc=s$m-GcXW@!}P-bReV1UIlDE>kD9;P2A4)Qy?-5~o`K<)nlQoz8#0LtqiA$0v9 qGoe8Z(gw#1pb2^#Tm-^^8VBJpFff41I&At2pzg1PtAsGn^#cGurbDFw literal 0 HcmV?d00001 diff --git a/src/openlibm/src/e_asin.c b/src/openlibm/src/e_asin.c new file mode 100644 index 0000000..e287bf1 --- /dev/null +++ b/src/openlibm/src/e_asin.c @@ -0,0 +1,117 @@ + +/* @(#)e_asin.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/e_asin.c,v 1.15 2011/02/10 07:37:50 das Exp $"); + +/* __ieee754_asin(x) + * Method : + * Since asin(x) = x + x^3/6 + x^5*3/40 + x^7*15/336 + ... + * we approximate asin(x) on [0,0.5] by + * asin(x) = x + x*x^2*R(x^2) + * where + * R(x^2) is a rational approximation of (asin(x)-x)/x^3 + * and its remez error is bounded by + * |(asin(x)-x)/x^3 - R(x^2)| < 2^(-58.75) + * + * For x in [0.5,1] + * asin(x) = pi/2-2*asin(sqrt((1-x)/2)) + * Let y = (1-x), z = y/2, s := sqrt(z), and pio2_hi+pio2_lo=pi/2; + * then for x>0.98 + * asin(x) = pi/2 - 2*(s+s*z*R(z)) + * = pio2_hi - (2*(s+s*z*R(z)) - pio2_lo) + * For x<=0.98, let pio4_hi = pio2_hi/2, then + * f = hi part of s; + * c = sqrt(z) - f = (z-f*f)/(s+f) ...f+c=sqrt(z) + * and + * asin(x) = pi/2 - 2*(s+s*z*R(z)) + * = pio4_hi+(pio4-2s)-(2s*z*R(z)-pio2_lo) + * = pio4_hi+(pio4-2f)-(2s*z*R(z)-(pio2_lo+2c)) + * + * Special cases: + * if x is NaN, return x itself; + * if |x|>1, return NaN with invalid signal. + * + */ + +#include +#include + +#include "math_private.h" + +static const double +one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */ +huge = 1.000e+300, +pio2_hi = 1.57079632679489655800e+00, /* 0x3FF921FB, 0x54442D18 */ +pio2_lo = 6.12323399573676603587e-17, /* 0x3C91A626, 0x33145C07 */ +pio4_hi = 7.85398163397448278999e-01, /* 0x3FE921FB, 0x54442D18 */ + /* coefficient for R(x^2) */ +pS0 = 1.66666666666666657415e-01, /* 0x3FC55555, 0x55555555 */ +pS1 = -3.25565818622400915405e-01, /* 0xBFD4D612, 0x03EB6F7D */ +pS2 = 2.01212532134862925881e-01, /* 0x3FC9C155, 0x0E884455 */ +pS3 = -4.00555345006794114027e-02, /* 0xBFA48228, 0xB5688F3B */ +pS4 = 7.91534994289814532176e-04, /* 0x3F49EFE0, 0x7501B288 */ +pS5 = 3.47933107596021167570e-05, /* 0x3F023DE1, 0x0DFDF709 */ +qS1 = -2.40339491173441421878e+00, /* 0xC0033A27, 0x1C8A2D4B */ +qS2 = 2.02094576023350569471e+00, /* 0x40002AE5, 0x9C598AC8 */ +qS3 = -6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */ +qS4 = 7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */ + +OLM_DLLEXPORT double +__ieee754_asin(double x) +{ + double t=0.0,w,p,q,c,r,s; + int32_t hx,ix; + GET_HIGH_WORD(hx,x); + ix = hx&0x7fffffff; + if(ix>= 0x3ff00000) { /* |x|>= 1 */ + u_int32_t lx; + GET_LOW_WORD(lx,x); + if(((ix-0x3ff00000)|lx)==0) + /* asin(1)=+-pi/2 with inexact */ + return x*pio2_hi+x*pio2_lo; + return (x-x)/(x-x); /* asin(|x|>1) is NaN */ + } else if (ix<0x3fe00000) { /* |x|<0.5 */ + if(ix<0x3e500000) { /* if |x| < 2**-26 */ + if(huge+x>one) return x;/* return x with inexact if x!=0*/ + } + t = x*x; + p = t*(pS0+t*(pS1+t*(pS2+t*(pS3+t*(pS4+t*pS5))))); + q = one+t*(qS1+t*(qS2+t*(qS3+t*qS4))); + w = p/q; + return x+x*w; + } + /* 1> |x|>= 0.5 */ + w = one-fabs(x); + t = w*0.5; + p = t*(pS0+t*(pS1+t*(pS2+t*(pS3+t*(pS4+t*pS5))))); + q = one+t*(qS1+t*(qS2+t*(qS3+t*qS4))); + s = sqrt(t); + if(ix>=0x3FEF3333) { /* if |x| > 0.975 */ + w = p/q; + t = pio2_hi-(2.0*(s+s*w)-pio2_lo); + } else { + w = s; + SET_LOW_WORD(w,0); + c = (t-w*w)/(s+w); + r = p/q; + p = 2.0*s*r-(pio2_lo-2.0*c); + q = pio4_hi-2.0*w; + t = pio4_hi-(p-q); + } + if(hx>0) return t; else return -t; +} + +#if LDBL_MANT_DIG == 53 +openlibm_weak_reference(asin, asinl); +#endif diff --git a/src/openlibm/src/e_asin.c.o b/src/openlibm/src/e_asin.c.o new file mode 100644 index 0000000000000000000000000000000000000000..f9a0e64817e6d92e8dd6fe483c7fcdd293e662ae GIT binary patch literal 3688 zcmb<-^>JfjWMqH=Mg}_u1P><4z_5Y~!FB*M9T@l-_!!bW`0EaYrtxc>@aQ}m>~Zj| zLg(wo$N&HTulHzvqtW>L|Nr;)Wm=7|85lm;a~|ezdBVWJ@QFX>L>j-w!B6~g2R)jP zXhg>zPUDwv0hhokAdn0iN_#`M<9t4qaLImq7LNpPy7*=qhleq#U1*@ zA9?T-f5gGV{PGM4SAoPLc|k4&=>VyYIEe7?3y{Poeuzgu@e6!8|DVPm4vvGDfB*jf&oA%7z>vnT@c^8bJa&OX`_%$AX;*Wg%i9h1@C;pf#pZMc0AX#?l6MqaSJm3yUb z__FH%|NkHhBy?Ruek=a8XO9svR$DgFW=<(Xhs_i7I*=SVt$zQ@`_PujzGD+(>4W#4 z_SXFwTQ!=N*oV4w@P!^cXbV8GEI3*q+&+=!%^4 zRExpETenL_-HI8KWf&gVL+pKN53vVMHo#f#&dyc}8t#6fnhJ&{dPaJN3PuJ-rUr(F z1_~NMsVNE`i6u}8U2{za1{MYe1_cHN22gOi`-L(vF)$tgiNW$PBb3hxwLk<)GgbvL zFjfdKO7pODOkiYSaA9Czkb%l=VParlaN`qbWAfmWXl4%Jb4cUjlW^n{aOC6g;$~XM z#V6qk=7exZz$N^+p}MhCAos8^d<2I*x(a42B@U#xVP%j&Q_K(MvoZ*PX#@fB7b`d{ z5TXnWl3)%iLjagY5b|IqD}x4@Mi44sCM!b(m_`sUSK9D*1-%o;SXl9GH`%t1Q7ye zvN9BaX#^1kX0m}vWCG$JR)z{>K?VkfGzJC+A*A>MrxgYUhHM4~j5q;l1=)ulS0HhQ z)cC~W%sjnh20b5VV-R5kB1}Mpp#g|A1rdgZAkqv(7=jg;gPC9r79gf2hybext2Bfd z0MTH|0J4H1EitK>p}4T91Y|G7UknVOB+ksh!0-oD()|DbALLGuJV+dre_-NmAVCI* zdQfP?#QTuML7@i|pNAyQj%5BSBymvOz|?O;5(ni`nD`+iaZp}>iJwCf2jw`J_$?%H z9wd98A&G-(2AKM9NaB1*>SaI~73yD5UW2LEKoSSVCrsQCDh>)WP+bKR_k@ar!V@{1 z1Chj$!!r>{ToB1UnMmTu;arU*jvUVINaD!hJQ+zGIh^Msi6e*eY9w*waNdq2jvUU1 zk;IY1`7)9?ayWm0ii5&U49UMzpa8=X{%T0#$l-5=Brb$xPCJq~vijLb;=)MkL3Icy zNr0q57{mr+z2eH;lEfqiz2cH02%Q0A6{Y4R>XoEclrZR}B$gyH=p_{wGw2oNgE)H0 z#U&QV978h(z2yAd+|;}h2EDxel2ko+zfj%clEma}C_g=~RIi{YzaX`!q>@1oYAhL8<{mA9~R3?>H(GZ-60OEW;~T9|r}7zlrW8Ylru$KN??P9zy!z)Fat{HFff42baM3@LhT2o5vY-1 z>Ic+*L<0mY47Llzg89P^hyDhrgV4hZ#)r{9Q2prj=LD#JNIeR&5rSd{Sa9M zxgV+@Ap&8+^g(zG44@W9@UF!kvALG>so zucN0Q4p5=PzyNROfYJ|02&NyFen9>~w;N + +#include "math_private.h" + +static const float +one = 1.0000000000e+00, /* 0x3F800000 */ +huge = 1.000e+30, + /* coefficient for R(x^2) */ +pS0 = 1.6666586697e-01, +pS1 = -4.2743422091e-02, +pS2 = -8.6563630030e-03, +qS1 = -7.0662963390e-01; + +static const double +pio2 = 1.570796326794896558e+00; + +OLM_DLLEXPORT float +__ieee754_asinf(float x) +{ + double s; + float t,w,p,q; + int32_t hx,ix; + GET_FLOAT_WORD(hx,x); + ix = hx&0x7fffffff; + if(ix>=0x3f800000) { /* |x| >= 1 */ + if(ix==0x3f800000) /* |x| == 1 */ + return x*pio2; /* asin(+-1) = +-pi/2 with inexact */ + return (x-x)/(x-x); /* asin(|x|>1) is NaN */ + } else if (ix<0x3f000000) { /* |x|<0.5 */ + if(ix<0x39800000) { /* |x| < 2**-12 */ + if(huge+x>one) return x;/* return x with inexact if x!=0*/ + } + t = x*x; + p = t*(pS0+t*(pS1+t*pS2)); + q = one+t*qS1; + w = p/q; + return x+x*w; + } + /* 1> |x|>= 0.5 */ + w = one-fabsf(x); + t = w*(float)0.5; + p = t*(pS0+t*(pS1+t*pS2)); + q = one+t*qS1; + s = sqrt(t); + w = p/q; + t = pio2-2.0*(s+s*w); + if(hx>0) return t; else return -t; +} diff --git a/src/openlibm/src/e_asinf.c.o b/src/openlibm/src/e_asinf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..7bd5b0a1053b28f11632014bd3477769f7a5ba89 GIT binary patch literal 2752 zcmb<-^>JfjWMqH=Mg}_u1P><4z;J*K!FB*M9T)@{_!)xJ`0EaL-cbGj|9`zl^BV!% z|Nral%QS5n7#i&PTjnt^Fns2ZIl!-R;xm8T36JI@0{j{WqYtO)@yoY>O|kv||Gyo7 z`&6((0a=h3$Oy}Fk`v34i8~yzrSn^3-Sk7#RQ5 zXZ{Ezb|hFk$j<1`{1KNw^T(a~%pZB;Gk?ShevN~N)A;3GK(32A@QFW?6=Y-@|NE0* z<)8SYz)JY#8D4-SU{3kW4{;&C#tD9nL!bF$4t|DeMRL^%Bp2O)S_pMj#4QLv>cD4y z!59^e&-{WuDm*YNd{lTo^T+w9aHR2TTu9@8f8aBJ)WJ{uk%vA(z5Izk;?O7lhy$Pa zV@`bHk2=|Uo48+mWCLid`_q(B2b#KDu{uxLV!`4hn-^r zBLjm80|SE$R1U;vaO4wcX7cA#NaW%ZaN*ZRfgPH7L5}B}IU|j66#+rB>!?F zi6i?<97!D6U+PHW$o_JHii6zAhh%;RR2<|^WPi0IiG$KU%wM3q4Dtdf`?faMpM9D4qhW`LA|F!eBX6`+Vz)8APsrL#X{iNOpjjF#BQd1&M($j1Qwh zf41c9y}RQ`d&6g~Y3Koc}9oq^IHD4)ah!^A=Ufm(&Ign@zK08|iGet^mpP@RUZ tA5^BGr#+BC8X!k8Ffe$6I7k>|9}<^A5L*5ti-Fi0Q1?#(agZ>&egKq+o5=tG literal 0 HcmV?d00001 diff --git a/src/openlibm/src/e_asinl.c b/src/openlibm/src/e_asinl.c new file mode 100644 index 0000000..521913a --- /dev/null +++ b/src/openlibm/src/e_asinl.c @@ -0,0 +1,77 @@ + +/* @(#)e_asin.c 1.3 95/01/18 */ +/* FreeBSD: head/lib/msun/src/e_asin.c 176451 2008-02-22 02:30:36Z das */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/e_asinl.c,v 1.2 2008/08/03 17:49:05 das Exp $"); + +/* + * See comments in e_asin.c. + * Converted to long double by David Schultz . + */ + +#include +#include + +#include "invtrig.h" +#include "math_private.h" + +static const long double +one = 1.00000000000000000000e+00, +huge = 1.000e+300; + +OLM_DLLEXPORT long double +asinl(long double x) +{ + union IEEEl2bits u; + long double t=0.0,w,p,q,c,r,s; + int16_t expsign, expt; + u.e = x; + expsign = u.xbits.expsign; + expt = expsign & 0x7fff; + if(expt >= BIAS) { /* |x|>= 1 */ + if(expt==BIAS && ((u.bits.manh&~LDBL_NBIT)|u.bits.manl)==0) + /* asin(1)=+-pi/2 with inexact */ + return x*pio2_hi+x*pio2_lo; + return (x-x)/(x-x); /* asin(|x|>1) is NaN */ + } else if (exptone) return x;/* return x with inexact if x!=0*/ + } + t = x*x; + p = P(t); + q = Q(t); + w = p/q; + return x+x*w; + } + /* 1> |x|>= 0.5 */ + w = one-fabsl(x); + t = w*0.5; + p = P(t); + q = Q(t); + s = sqrtl(t); + if(u.bits.manh>=THRESH) { /* if |x| is close to 1 */ + w = p/q; + t = pio2_hi-(2.0*(s+s*w)-pio2_lo); + } else { + u.e = s; + u.bits.manl = 0; + w = u.e; + c = (t-w*w)/(s+w); + r = p/q; + p = 2.0*s*r-(pio2_lo-2.0*c); + q = pio4_hi-2.0*w; + t = pio4_hi-(p-q); + } + if(expsign>0) return t; else return -t; +} diff --git a/src/openlibm/src/e_asinl.c.o b/src/openlibm/src/e_asinl.c.o new file mode 100644 index 0000000000000000000000000000000000000000..f9a3eca78cfb6b293187fab3137472f59ae4c26e GIT binary patch literal 3648 zcmb<-^>JfjWMqH=Mg}_u1P><4z|g>jU^{@B4h;MZd3@4{m($Xg=Z)eK>6be~T0&14EkaJ^OMgklYsmJ52xwz%eR0$!r;*zq7vZIdBNl03kB8x|Nqx>Uf^&2{_p>Ps1I&u7{FLL zDgk#+g7{zqLB{aQGyE@6i2&gjAk&~KJ(}ML+@VZ~*0~7~IYfxOwEp(R-(F9=vht-n*M;ZXCS#_vV=!2kyPP_weSa8wYN@ z1hHN(18HDjm{ZEoVe`bij)8%}p26MO*-Amf-7i#A!O%p{NY7Bg$iT?dz|hb@K_e(N zMZqJn1S+9xt_ji4!oa|wz`(!&O0({Mp$tq6j0Zqsu)M?w0EpQj(i->+)T$HtVr&12*ZQhg)hQ| zFCl=hfawNb08}#$3gjLZhL8WTNi$=~`P^WIAYXwQa6$mgVgr-NgeU_8gAkHAU_UT0 zFi0~nFhKMmt7c#@#362lL);mMxDO8TP#ofMIKlDUK2sus0<9S`UhqUD6U{^5DluAKw%G4 z4-y066Ho&sK!phd0|O`xf$RaLRgk;{h+tq~P-9>K*LF~4P*Da3CUgO)49E;96HMta zFff43L|0C%eo*}hG82@hzy?AI4yb`3v!Oy@3dV=gc2M`D>lc9P2Zaq-Bb0#gVYD|? zKe*imRRf|#p!)Se93%{KD~JoDL!kOWV#wGTsvlVl#D?huu|YTmTCSs{Z3YGg52${0 zcftG((hI^hQ2WvKS3vbAfD|ENbp7Sfyo;WG9)Joj1_lOLIsv60P`L%u4-*IZ2iR=SQ FegLhj`}qI> literal 0 HcmV?d00001 diff --git a/src/openlibm/src/e_atan2.c b/src/openlibm/src/e_atan2.c new file mode 100644 index 0000000..9b021b9 --- /dev/null +++ b/src/openlibm/src/e_atan2.c @@ -0,0 +1,129 @@ + +/* @(#)e_atan2.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + * + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/e_atan2.c,v 1.14 2008/08/02 19:17:00 das Exp $"); + +/* __ieee754_atan2(y,x) + * Method : + * 1. Reduce y to positive by atan2(y,x)=-atan2(-y,x). + * 2. Reduce x to positive by (if x and y are unexceptional): + * ARG (x+iy) = arctan(y/x) ... if x > 0, + * ARG (x+iy) = pi - arctan[y/(-x)] ... if x < 0, + * + * Special cases: + * + * ATAN2((anything), NaN ) is NaN; + * ATAN2(NAN , (anything) ) is NaN; + * ATAN2(+-0, +(anything but NaN)) is +-0 ; + * ATAN2(+-0, -(anything but NaN)) is +-pi ; + * ATAN2(+-(anything but 0 and NaN), 0) is +-pi/2; + * ATAN2(+-(anything but INF and NaN), +INF) is +-0 ; + * ATAN2(+-(anything but INF and NaN), -INF) is +-pi; + * ATAN2(+-INF,+INF ) is +-pi/4 ; + * ATAN2(+-INF,-INF ) is +-3pi/4; + * ATAN2(+-INF, (anything but,0,NaN, and INF)) is +-pi/2; + * + * Constants: + * The hexadecimal values are the intended ones for the following + * constants. The decimal values may be used, provided that the + * compiler will convert from decimal to binary accurately enough + * to produce the hexadecimal values shown. + */ + +#include +#include + +#include "math_private.h" + +static volatile double +tiny = 1.0e-300; +static const double +zero = 0.0, +pi_o_4 = 7.8539816339744827900E-01, /* 0x3FE921FB, 0x54442D18 */ +pi_o_2 = 1.5707963267948965580E+00, /* 0x3FF921FB, 0x54442D18 */ +pi = 3.1415926535897931160E+00; /* 0x400921FB, 0x54442D18 */ +static volatile double +pi_lo = 1.2246467991473531772E-16; /* 0x3CA1A626, 0x33145C07 */ + +OLM_DLLEXPORT double +__ieee754_atan2(double y, double x) +{ + double z; + int32_t k,m,hx,hy,ix,iy; + u_int32_t lx,ly; + + EXTRACT_WORDS(hx,lx,x); + ix = hx&0x7fffffff; + EXTRACT_WORDS(hy,ly,y); + iy = hy&0x7fffffff; + if(((ix|((lx|-lx)>>31))>0x7ff00000)|| + ((iy|((ly|-ly)>>31))>0x7ff00000)) /* x or y is NaN */ + return x+y; + if(hx==0x3ff00000&&lx==0) return atan(y); /* x=1.0 */ + m = ((hy>>31)&1)|((hx>>30)&2); /* 2*sign(x)+sign(y) */ + + /* when y = 0 */ + if((iy|ly)==0) { + switch(m) { + case 0: + case 1: return y; /* atan(+-0,+anything)=+-0 */ + case 2: return pi+tiny;/* atan(+0,-anything) = pi */ + case 3: return -pi-tiny;/* atan(-0,-anything) =-pi */ + } + } + /* when x = 0 */ + if((ix|lx)==0) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny; + + /* when x is INF */ + if(ix==0x7ff00000) { + if(iy==0x7ff00000) { + switch(m) { + case 0: return pi_o_4+tiny;/* atan(+INF,+INF) */ + case 1: return -pi_o_4-tiny;/* atan(-INF,+INF) */ + case 2: return 3.0*pi_o_4+tiny;/*atan(+INF,-INF)*/ + case 3: return -3.0*pi_o_4-tiny;/*atan(-INF,-INF)*/ + } + } else { + switch(m) { + case 0: return zero ; /* atan(+...,+INF) */ + case 1: return -zero ; /* atan(-...,+INF) */ + case 2: return pi+tiny ; /* atan(+...,-INF) */ + case 3: return -pi-tiny ; /* atan(-...,-INF) */ + } + } + } + /* when y is INF */ + if(iy==0x7ff00000) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny; + + /* compute y/x */ + k = (iy-ix)>>20; + if(k > 60) { /* |y/x| > 2**60 */ + z=pi_o_2+0.5*pi_lo; + m&=1; + } + else if(hx<0&&k<-60) z=0.0; /* 0 > |y|/x > -2**-60 */ + else z=atan(fabs(y/x)); /* safe to do y/x */ + switch (m) { + case 0: return z ; /* atan(+,+) */ + case 1: return -z ; /* atan(-,+) */ + case 2: return pi-(z-pi_lo);/* atan(+,-) */ + default: /* case 3 */ + return (z-pi_lo)-pi;/* atan(-,-) */ + } +} + +#if LDBL_MANT_DIG == 53 +openlibm_weak_reference(atan2, atan2l); +#endif diff --git a/src/openlibm/src/e_atan2.c.o b/src/openlibm/src/e_atan2.c.o new file mode 100644 index 0000000000000000000000000000000000000000..d81aae81d900f9eeecc51c71c62b2745106c153e GIT binary patch literal 3400 zcmb<-^>JfjWMqH=Mg}_u1P><4z|g^oU^{@B4h;MZd<3=9mxou6GgPaOO$ckqRL^J6B?!!Dc$OWm4(Gx4`P z1sTk*aiRG)bE(KDegRgH(?0PFh(hR?3u*ishoTRs>G8|AfP@&*_%$wm;*S7}ALf^5 z;QYnk(!jvL(D)zh(w09A3=EEqKR}$4Y?sahnm;-Z9sDI?`~UxWX8!(l3=9k&2j9u_ zw*)XUFr@LnztsHe2!F3LBLhS8Z$|!>^$Z{e6MyS71_p*t`~tinJ3sNqTm(4-*;y}B z{{R2aFYmzc5~PA(p24;CWQ8$8MFiLbFYW&S|DVP$?*cXqEcA&VDy0lI0AvYl{jNos%{|{t*I9T-MB@kx<%E--?|Npn%=5Lt}Q2}*G%!N<q{F}MNtNAx$i4M#> zm|I?kfQ^Vd_yQCjU?PoQ>liYp%(_z{0@5puoVu z018WYzfcAy2F3#*F<72tgz{n8Q3PxW0|R4K5Cda{0HZVyJI4e@1_m7l1_l|Z+$tsp z1_q{7K7nQ?CI>za@52FLW&PwKskpjTW{1fervtfJJMM7@&KiV_CBl*E!m2EC->Vg|jUd=N)3xwymv znPX_ipqHGVo12P~- zsvlVl#70*ONa_|S!hjkF;V>{TfXu|Ep8;er0|P@lTqT5ot{(ttGe-ab literal 0 HcmV?d00001 diff --git a/src/openlibm/src/e_atan2f.c b/src/openlibm/src/e_atan2f.c new file mode 100644 index 0000000..a52a581 --- /dev/null +++ b/src/openlibm/src/e_atan2f.c @@ -0,0 +1,97 @@ +/* e_atan2f.c -- float version of e_atan2.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/e_atan2f.c,v 1.12 2008/08/03 17:39:54 das Exp $"); + +#include + +#include "math_private.h" + +static volatile float +tiny = 1.0e-30; +static const float +zero = 0.0, +pi_o_4 = 7.8539818525e-01, /* 0x3f490fdb */ +pi_o_2 = 1.5707963705e+00, /* 0x3fc90fdb */ +pi = 3.1415927410e+00; /* 0x40490fdb */ +static volatile float +pi_lo = -8.7422776573e-08; /* 0xb3bbbd2e */ + +OLM_DLLEXPORT float +__ieee754_atan2f(float y, float x) +{ + float z; + int32_t k,m,hx,hy,ix,iy; + + GET_FLOAT_WORD(hx,x); + ix = hx&0x7fffffff; + GET_FLOAT_WORD(hy,y); + iy = hy&0x7fffffff; + if((ix>0x7f800000)|| + (iy>0x7f800000)) /* x or y is NaN */ + return x+y; + if(hx==0x3f800000) return atanf(y); /* x=1.0 */ + m = ((hy>>31)&1)|((hx>>30)&2); /* 2*sign(x)+sign(y) */ + + /* when y = 0 */ + if(iy==0) { + switch(m) { + case 0: + case 1: return y; /* atan(+-0,+anything)=+-0 */ + case 2: return pi+tiny;/* atan(+0,-anything) = pi */ + case 3: return -pi-tiny;/* atan(-0,-anything) =-pi */ + } + } + /* when x = 0 */ + if(ix==0) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny; + + /* when x is INF */ + if(ix==0x7f800000) { + if(iy==0x7f800000) { + switch(m) { + case 0: return pi_o_4+tiny;/* atan(+INF,+INF) */ + case 1: return -pi_o_4-tiny;/* atan(-INF,+INF) */ + case 2: return (float)3.0*pi_o_4+tiny;/*atan(+INF,-INF)*/ + case 3: return (float)-3.0*pi_o_4-tiny;/*atan(-INF,-INF)*/ + } + } else { + switch(m) { + case 0: return zero ; /* atan(+...,+INF) */ + case 1: return -zero ; /* atan(-...,+INF) */ + case 2: return pi+tiny ; /* atan(+...,-INF) */ + case 3: return -pi-tiny ; /* atan(-...,-INF) */ + } + } + } + /* when y is INF */ + if(iy==0x7f800000) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny; + + /* compute y/x */ + k = (iy-ix)>>23; + if(k > 26) { /* |y/x| > 2**26 */ + z=pi_o_2+(float)0.5*pi_lo; + m&=1; + } + else if(k<-26&&hx<0) z=0.0; /* 0 > |y|/x > -2**-26 */ + else z=atanf(fabsf(y/x)); /* safe to do y/x */ + switch (m) { + case 0: return z ; /* atan(+,+) */ + case 1: return -z ; /* atan(-,+) */ + case 2: return pi-(z-pi_lo);/* atan(+,-) */ + default: /* case 3 */ + return (z-pi_lo)-pi;/* atan(-,-) */ + } +} diff --git a/src/openlibm/src/e_atan2f.c.o b/src/openlibm/src/e_atan2f.c.o new file mode 100644 index 0000000000000000000000000000000000000000..a31aed03238fd5b885992b02d16b1c1ca5f375bc GIT binary patch literal 3296 zcmb<-^>JfjWMqH=Mg}_u1P><4z@Wg1U^{@B4h;MZd<<#)btlsJ>kf7v>pa!??EnA& z^^K3fXHkB`J*% zyIN+z?J5b-{M32z;7{?!U;qEt^YZsyWnf@{8PWWh@iTuU)U*gNU9yHh9L#vV7-}xR z#>LP45g@A$^UJ$1FtnbmD1jO9nIEF-W%2+2|Do#9<)ZmD4jtx~XLt#6B)>c?3|e{^ z7#Ny=GnJfg{>{waBKQCQf0)kZ-;De%ivR!rPvd`o>7@kNXa|s^G5r7X_dmG3%|D;j zW`lIJ9;i$P8)5YS|NrLSOr^P>`2~1Ewtwc2xyY|^2xiY`{+J6dcY;lD0lS62WfIs? z%q1nwzZpxy5DKB*>;Wro0hz_{nLqB}3lIxT@M~On-31As+x#sl|G>V1x;N&+XZ{#) zpuY4*kw8S`OCwwok`M{7c6e~J{QLi3Z}0BS2~LZ6Z}WRP+~)T@aGU?+{@eT~?QipY zg7E$)r^OteoEAI4z`$S+awY=<12~;P*$fQs&dyc}8t#6fnhJ&{dPaJN3PuJ-rUr(F z1_~NMsVNE`i6u}8U2{za1{MYe1_cHN29T%R{X!X-7#I(L#9(=Z5z2>U4-u$Ej8#Dl zj1>Zm(md=O6Brp7bQl;IWT0{dObiSRHGBfiOf_7593I?E5qunn13>&jJ`VT89v~J} zDFy|ymxbZue+&r*1_oxVITs|(jG>%|fq{XMff?*SkR-@YAX*SA4q}5aOk5nqVPFH3 z$OObsnBq!cMXYf1!CVFg26Zrl6&$8uCX~3rV&H{0|SE)QaFR- zl7WFCoPhzuPLQrx9O4YA@rfmgc}8h^$qXf#d6f(WnejRK40=A!hF}6r8iSbzAkq{> z7=Z{A5Mc%)%t3@Dh_GOQ7zU=&7}64xiqk;0Gccq;C z+(_oTA&G-hCCoi3NaD!$<{*iK(jH9xd?ay@dYJe+BynVWuOo?r)I+_)a34t=R2sv~ z`3e;WL43}S<^UU6k^Nn#R%UU5kggwBAmic)hD^-5AJ zN*MG~5=#;p^pc8;8T5+sK^(p0;t~^Nj-eTYUUGhJZfaf$gI->KNvfW^U#MiU^SZKwbx>MP!2@Z72o?Sor~y1BDrk z4WgwPAaxK-JxC0MA3%%51<*hPrCpFcpu7x{hm~7u;PM<)2Y^Hocmq@)Og&5nlpbMh z5DlugKx&ZV7$m*}svpEg#vnH!^9`Z)gVHjxI846^vLMv2AR(AL>~QFR0JR@IykLA7 z?E}?s05TK_e}L-OM-l@uVeW^~p-}xGIb8Al|5iFg6(hsQIg$l##J&=FU?FLyn z18V;RkOBq<22j}sYCE9o2h|l&r66r^TmenL$#4+}18N+E!@$4*G83Er8BmMb;VK~v Gbo~Hgz7`7r literal 0 HcmV?d00001 diff --git a/src/openlibm/src/e_atan2l.c b/src/openlibm/src/e_atan2l.c new file mode 100644 index 0000000..1c0a796 --- /dev/null +++ b/src/openlibm/src/e_atan2l.c @@ -0,0 +1,120 @@ + +/* @(#)e_atan2.c 1.3 95/01/18 */ +/* FreeBSD: head/lib/msun/src/e_atan2.c 176451 2008-02-22 02:30:36Z das */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + * + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/e_atan2l.c,v 1.3 2008/08/02 19:17:00 das Exp $"); + +/* + * See comments in e_atan2.c. + * Converted to long double by David Schultz . + */ + +#include +#include + +#include "invtrig.h" +#include "math_private.h" + +static volatile long double +tiny = 1.0e-300; +static const long double +zero = 0.0; + +#ifdef __i386__ +/* XXX Work around the fact that gcc truncates long double constants on i386 */ +static volatile double +pi1 = 3.14159265358979311600e+00, /* 0x1.921fb54442d18p+1 */ +pi2 = 1.22514845490862001043e-16; /* 0x1.1a80000000000p-53 */ +#define pi ((long double)pi1 + pi2) +#else +static const long double +pi = 3.14159265358979323846264338327950280e+00L; +#endif + +OLM_DLLEXPORT long double +atan2l(long double y, long double x) +{ + union IEEEl2bits ux, uy; + long double z; + int32_t k,m; + int16_t exptx, expsignx, expty, expsigny; + + uy.e = y; + expsigny = uy.xbits.expsign; + expty = expsigny & 0x7fff; + ux.e = x; + expsignx = ux.xbits.expsign; + exptx = expsignx & 0x7fff; + + if ((exptx==BIAS+LDBL_MAX_EXP && + ((ux.bits.manh&~LDBL_NBIT)|ux.bits.manl)!=0) || /* x is NaN */ + (expty==BIAS+LDBL_MAX_EXP && + ((uy.bits.manh&~LDBL_NBIT)|uy.bits.manl)!=0)) /* y is NaN */ + return x+y; + if (expsignx==BIAS && ((ux.bits.manh&~LDBL_NBIT)|ux.bits.manl)==0) + return atanl(y); /* x=1.0 */ + m = ((expsigny>>15)&1)|((expsignx>>14)&2); /* 2*sign(x)+sign(y) */ + + /* when y = 0 */ + if(expty==0 && ((uy.bits.manh&~LDBL_NBIT)|uy.bits.manl)==0) { + switch(m) { + case 0: + case 1: return y; /* atan(+-0,+anything)=+-0 */ + case 2: return pi+tiny;/* atan(+0,-anything) = pi */ + case 3: return -pi-tiny;/* atan(-0,-anything) =-pi */ + } + } + /* when x = 0 */ + if(exptx==0 && ((ux.bits.manh&~LDBL_NBIT)|ux.bits.manl)==0) + return (expsigny<0)? -pio2_hi-tiny: pio2_hi+tiny; + + /* when x is INF */ + if(exptx==BIAS+LDBL_MAX_EXP) { + if(expty==BIAS+LDBL_MAX_EXP) { + switch(m) { + case 0: return pio2_hi*0.5+tiny;/* atan(+INF,+INF) */ + case 1: return -pio2_hi*0.5-tiny;/* atan(-INF,+INF) */ + case 2: return 1.5*pio2_hi+tiny;/*atan(+INF,-INF)*/ + case 3: return -1.5*pio2_hi-tiny;/*atan(-INF,-INF)*/ + } + } else { + switch(m) { + case 0: return zero ; /* atan(+...,+INF) */ + case 1: return -zero ; /* atan(-...,+INF) */ + case 2: return pi+tiny ; /* atan(+...,-INF) */ + case 3: return -pi-tiny ; /* atan(-...,-INF) */ + } + } + } + /* when y is INF */ + if(expty==BIAS+LDBL_MAX_EXP) + return (expsigny<0)? -pio2_hi-tiny: pio2_hi+tiny; + + /* compute y/x */ + k = expty-exptx; + if(k > LDBL_MANT_DIG+2) { /* |y/x| huge */ + z=pio2_hi+pio2_lo; + m&=1; + } + else if(expsignx<0&&k<-LDBL_MANT_DIG-2) z=0.0; /* |y/x| tiny, x<0 */ + else z=atanl(fabsl(y/x)); /* safe to do y/x */ + switch (m) { + case 0: return z ; /* atan(+,+) */ + case 1: return -z ; /* atan(-,+) */ + case 2: return pi-(z-pi_lo);/* atan(+,-) */ + default: /* case 3 */ + return (z-pi_lo)-pi;/* atan(-,-) */ + } +} diff --git a/src/openlibm/src/e_atan2l.c.o b/src/openlibm/src/e_atan2l.c.o new file mode 100644 index 0000000000000000000000000000000000000000..483e2c7afa3af249a3d0449f7d9f2a3177b501ce GIT binary patch literal 3504 zcmb<-^>JfjWMqH=Mg}_u1P><4!0>?+!FB*M9T@l-_!t~RLW4b;-w1SvsCc+^`>0s> zbi1e+cyzm{I5>7*a_v0r(|OLL^J1D~ueX^xGL!Q`+1_53Y?j0_BEj*Y)T?4t|} z3~7zO{@e4nR539ybY6GqJe_v%KVRCx*Zj@TnK)`CEDz z7#MsySyVtScIos{k+_|sBH+>Kq9V{40^!{IdD}+i1;~RSH3;?*h34Ok{4Ftz3=GY` znfO~%m>3v5x>-RAZ)@CpdGqzXhp$Wcz( z|NsAY<==kWm4EvsSIx_g&A*-a`(`l0!>su^2`(z=f||>pG^EMl8i8SrZxX$=5L7v z``{-de~URI1H;XeH+VrN-#hqn=D+{{Z=SsQ;NHWR+y4Fk4-RLv@Z)cp&A`Cm(s@4Z z;Cp`l?a(x+^#A{VpU#8elyvZ=0xVu2>C6R`(9-_>|9|(!%L#w~|A)k1TJwLV5~;N2 z|IGX?+d)2P{?AyFbo1Ry8?epLfW7(p-ockzAZeKYTW|BXNdEi(AL?6ZT6_7D6|BvH z!Kc$j#Q@|03s{1A3G!VUO#jVyHy^yb@fYN~29N|K>W~6q4_J;Nt@R{-=fgk$|2sDS z-pAj2{m=jZH{ZSFfV&@}@7}3+1R?PQH|gQaqQ9U}VNn6O29!2mCjR~ZpW(!; zAzFj7$v-4Gk1Df>KiyJQ7Qw61wJ^5dAC+3=9ek3=E*0>FyWGz{J3K03-&H zWnf^0@?mA12vmZxDu{uxLV!`4hn-^rBLhPW0|SE$R89e8fD@lU50fLGL>sdspF%T> z3!eegCO(H0z5pLS1EyjwJ_ScU2}eEwCq52$?pRbV^FKyp0Y7f2x!5R>yI2@L{>LWA zjJ0HDU|?oo#!$|~0P-tBTmY&<5KMzY2h4yIVqg{9Tq4)H7;;tZ+r zi6x17Mmc)P3?-R)l?-}5&c-0Z1VosE2y+l&#sE>qkd~NKoCD_MFvPq2_&YiJ#QVFs z1-pjChd4UFmXpv0%Blb0EzP>iF-lCnHWIn1)=^U4)O0u;-J(5Gv63w02cEd zkiM1xlqb^;57GmTJ_ZK8 z;>z5T#3Tm2;*uf=odIJNrRF5+m84dbFzBTumLxLhB^4Jl=oRIIIC{y&C5C3mJQD`J z?> zGeG_WB@IyAAR7W{6EZNs@-<8jlonuY5Dh9%Kw$<`4-y064p3w;Ffg0|8P34K018tO z6BHL9c?l4~z`&peF4rJw7%Bv&5o72Y%O+^_f%Srj0;qlv8ySP#fXoM# zS0FJVWI+Z72AFNfy!knkL+LVYAL z5EJB9WI7b8A0&p1Peb)1i-FiM{UA07gOU&^s!-B40|UbasD5;J!Qv037ldn}_M__u zSJ(^;3>6?nNElr|NFHPrdin_fWljbL23R@)g(DX=0.5 + * 1 2x x + * atanh(x) = --- * log(1 + -------) = 0.5 * log1p(2 * --------) + * 2 1 - x 1 - x + * + * For x<0.5 + * atanh(x) = 0.5*log1p(2x+2x*x/(1-x)) + * + * Special cases: + * atanh(x) is NaN if |x| > 1 with signal; + * atanh(NaN) is that NaN with no signal; + * atanh(+-1) is +-INF with signal. + * + */ + +#include +#include + +#include "math_private.h" + +static const double one = 1.0, huge = 1e300; +static const double zero = 0.0; + +OLM_DLLEXPORT double +__ieee754_atanh(double x) +{ + double t; + int32_t hx,ix; + u_int32_t lx; + EXTRACT_WORDS(hx,lx,x); + ix = hx&0x7fffffff; + if ((ix|((lx|(-lx))>>31))>0x3ff00000) /* |x|>1 */ + return (x-x)/(x-x); + if(ix==0x3ff00000) + return x/zero; + if(ix<0x3e300000&&(huge+x)>zero) return x; /* x<2**-28 */ + SET_HIGH_WORD(x,ix); + if(ix<0x3fe00000) { /* x < 0.5 */ + t = x+x; + t = 0.5*log1p(t+t*x/(one-x)); + } else + t = 0.5*log1p((x+x)/(one-x)); + if(hx>=0) return t; else return -t; +} + +#if (LDBL_MANT_DIG == 53) +openlibm_weak_reference(atanh, atanhl); +#endif diff --git a/src/openlibm/src/e_atanh.c.o b/src/openlibm/src/e_atanh.c.o new file mode 100644 index 0000000000000000000000000000000000000000..23f3fff706385149c1cd27f34b5463f1b3bea56c GIT binary patch literal 2128 zcmb<-^>JfjWMqH=Mg}_u1P><4z%YRY!FB*M9T@l-_!!bW`0EY@cV6)5yzFuCwZius zoi{lzG(PoaWnf@v{0U~aTm-ZK|JS!G3-stb(Rt|;zkn>r zNRNXL6g)T&rSWSVPV?Z;JC(+-aq$y>%)w9m5f>YO{{Mg9zAWSuf82#MevLyfKpH;r zN3w$G*4q^c(TDlvT^JZX@e7E8gwpumpZvrhaUqRg|6=)LkAn{tknG_+g=BujMUZ)) z_+xH<;*UJ|i9hb}C;kX@^D7sm@rQ%$g4+{wAo>%3+=0VsV0%IKf%pdxgKTGDm{ZEo zVe`bi4#N9j51}7GX@&*}pMinF-PzenLBriIR8zswM9)aiP{GK+$kf2l&_F>WC^bdF zBe4W3p=++mzyOK{1qKENkXzjSLK&DC7!QENU~$F><#R$U5P{N+RY44l6#|UXJnS43 z7#SFJ7#J92pmIVW&2D@G%}h)!TznjE+)PPe%9V?c!<*Zcj{~X>8wJwJ!tn7wHaTW2 zDTy1bkd*=5OaZ7kga&iK1UNFmz6EpPgcO*?1}2dSc?JdsAtZajeq&%@P-S3XKsOt# zFEu`~Brz{TFPTBl$Jq!(7=s8y5MjaqmSf1tPd6+8t7hrJ}B*g zq(JIH7{mr+z2eH;lEfqiz2cH02%Q0A6{Y4R>XoEclrZR}B$gyH=p_{wGw2oNgE)H0 z#U&QV978h(z2yAd+|;}h2EDxel2ko+zfj%clEma}C_g=~RIi{YzaX`!q>@1oYA{ZDL)S%)} + +#include "math_private.h" + +static const float one = 1.0, huge = 1e30; + +static const float zero = 0.0; + +OLM_DLLEXPORT float +__ieee754_atanhf(float x) +{ + float t; + int32_t hx,ix; + GET_FLOAT_WORD(hx,x); + ix = hx&0x7fffffff; + if (ix>0x3f800000) /* |x|>1 */ + return (x-x)/(x-x); + if(ix==0x3f800000) + return x/zero; + if(ix<0x31800000&&(huge+x)>zero) return x; /* x<2**-28 */ + SET_FLOAT_WORD(x,ix); + if(ix<0x3f000000) { /* x < 0.5 */ + t = x+x; + t = (float)0.5*log1pf(t+t*x/(one-x)); + } else + t = (float)0.5*log1pf((x+x)/(one-x)); + if(hx>=0) return t; else return -t; +} diff --git a/src/openlibm/src/e_atanhf.c.o b/src/openlibm/src/e_atanhf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..99124385d149d5b5d1726fc3b18d7197c77d691a GIT binary patch literal 2048 zcmb<-^>JfjWMqH=Mg}_u1P><4z~I1w#0E1R82B0Z7=qLI>kfC`Q2qb^f4waOLxVkk z`$7f=2L6`S3=9mm|Nqw;mf3vf7mx*MN#oBu!LMX!$`Qtzqpc_}Ykv|-4a`a(-d4|vYF$bbQ^T!=HoW?Kj!oUDBAH+X+ zn1SKcC(lBVR~Q%=>=_ss8bJ2LvAeUgm4b%5U#O;np^2W6o}q$~fsv_!p`n3-Mo?;s zf=6NrR6^HWlYs#gYzhnv3?Q4`{X!X-7#I(L#9(2}2<3A^Ef9gyj8#Dlj1>Zm(md=O z6Brp7bQl;IWT0}FK(r&DKr<6lEEgY#6E{-`7axZUw<{MPhc~w?9|uSt2L{>8!tn7w zHfd%oG0y{5$O`rcm1jRQEE=2UP)?234>lrVo4%{UQ%%}gI-ZS zh@+QWTw;REF*IY)OU}>DP0cG|(96p&N!4@r3)L+yNlea$^3(H5^$Lpe3sQ?pDjD>^ zhNou4rxhjUrh;8U5drcaC{2R=jBJntlmkl-P%cKA0HrHX7{k=V)IER()&ZyhC>?|B z0mTJKNCHGKFfgbwFo07ZDDI#_U`hz27|cQ?(1k(y5@aU1`VFD>3!z%WAOf`r?gmJLfq~%$h{M3Zz{|kE0P-iyewcnxxev7psuDtN efO<#|!iAGiW8r*IIgCyJ4ya%|TqT5ot{(syF8Ce* literal 0 HcmV?d00001 diff --git a/src/openlibm/src/e_cosh.c b/src/openlibm/src/e_cosh.c new file mode 100644 index 0000000..2e76570 --- /dev/null +++ b/src/openlibm/src/e_cosh.c @@ -0,0 +1,85 @@ + +/* @(#)e_cosh.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/e_cosh.c,v 1.10 2011/10/21 06:28:47 das Exp $"); + +/* __ieee754_cosh(x) + * Method : + * mathematically cosh(x) if defined to be (exp(x)+exp(-x))/2 + * 1. Replace x by |x| (cosh(x) = cosh(-x)). + * 2. + * [ exp(x) - 1 ]^2 + * 0 <= x <= ln2/2 : cosh(x) := 1 + ------------------- + * 2*exp(x) + * + * exp(x) + 1/exp(x) + * ln2/2 <= x <= 22 : cosh(x) := ------------------- + * 2 + * 22 <= x <= lnovft : cosh(x) := exp(x)/2 + * lnovft <= x <= ln2ovft: cosh(x) := exp(x/2)/2 * exp(x/2) + * ln2ovft < x : cosh(x) := huge*huge (overflow) + * + * Special cases: + * cosh(x) is |x| if x is +INF, -INF, or NaN. + * only cosh(0)=1 is exact for finite x. + */ + +#include +#include + +#include "math_private.h" + +static const double one = 1.0, half=0.5, huge = 1.0e300; + +OLM_DLLEXPORT double +__ieee754_cosh(double x) +{ + double t,w; + int32_t ix; + + /* High word of |x|. */ + GET_HIGH_WORD(ix,x); + ix &= 0x7fffffff; + + /* x is INF or NaN */ + if(ix>=0x7ff00000) return x*x; + + /* |x| in [0,0.5*ln2], return 1+expm1(|x|)^2/(2*exp(|x|)) */ + if(ix<0x3fd62e43) { + t = expm1(fabs(x)); + w = one+t; + if (ix<0x3c800000) return w; /* cosh(tiny) = 1 */ + return one+(t*t)/(w+w); + } + + /* |x| in [0.5*ln2,22], return (exp(|x|)+1/exp(|x|)/2; */ + if (ix < 0x40360000) { + t = __ieee754_exp(fabs(x)); + return half*t+half/t; + } + + /* |x| in [22, log(maxdouble)] return half*exp(|x|) */ + if (ix < 0x40862E42) return half*__ieee754_exp(fabs(x)); + + /* |x| in [log(maxdouble), overflowthresold] */ + if (ix<=0x408633CE) + return __ldexp_exp(fabs(x), -1); + + /* |x| > overflowthresold, cosh(x) overflow */ + return huge*huge; +} + +#if (LDBL_MANT_DIG == 53) +openlibm_weak_reference(cosh, coshl); +#endif diff --git a/src/openlibm/src/e_cosh.c.o b/src/openlibm/src/e_cosh.c.o new file mode 100644 index 0000000000000000000000000000000000000000..f7cc2f0b4add7d4c85f8c27283a342e153c85e74 GIT binary patch literal 2144 zcmb<-^>JfjWMqH=Mg}_u1P><4!0>7|ka3^* zBM(F$PMh!o!~qkZ_yt5koHTxo6QB4a4uMRnw<){zi9hn>C;o^7(VzI^KoY0Y_%#k5 z=9dSV%)kKF3MM}B3-E&UN2l>?T=>KvdGHf|+^J9e5g@e=DC#1?E{HzNFAo*p|NsC0 z|Isf&x*_<3J%oN>Kc|$T!{&*39fP~Gvz3B|yI-iLf}x3?k)EM~k%5t^fuW&+f<{nk zih@UC2~3ujfW%;7%?RalLM&nsfzpgsK@5x)0*ul; z>>Lvq85m3$7#L)rat}bXBcDJs6O#`YABQt{HWwd9D0eWNbmjKu;{YkbjY0OaFns)v zO$9TSl)wd6$jTr9rV#``mMxFL>bZ&lZqKqD++QA8RFw}Qc^1l;!`UM zK=!+U2nGfQCI$uuW(Ed^KcFP?|Ns9$s5mGt*^$J4Aw)go=a2 zkjk^a|cNrlonw2g3>lf z3SK`$@ABvsGdFI2a + +#include "math_private.h" + +static const float one = 1.0, half=0.5, huge = 1.0e30; + +OLM_DLLEXPORT float +__ieee754_coshf(float x) +{ + float t,w; + int32_t ix; + + GET_FLOAT_WORD(ix,x); + ix &= 0x7fffffff; + + /* x is INF or NaN */ + if(ix>=0x7f800000) return x*x; + + /* |x| in [0,0.5*ln2], return 1+expm1(|x|)^2/(2*exp(|x|)) */ + if(ix<0x3eb17218) { + t = expm1f(fabsf(x)); + w = one+t; + if (ix<0x39800000) return one; /* cosh(tiny) = 1 */ + return one+(t*t)/(w+w); + } + + /* |x| in [0.5*ln2,9], return (exp(|x|)+1/exp(|x|))/2; */ + if (ix < 0x41100000) { + t = __ieee754_expf(fabsf(x)); + return half*t+half/t; + } + + /* |x| in [9, log(maxfloat)] return half*exp(|x|) */ + if (ix < 0x42b17217) return half*__ieee754_expf(fabsf(x)); + + /* |x| in [log(maxfloat), overflowthresold] */ + if (ix<=0x42b2d4fc) + return __ldexp_expf(fabsf(x), -1); + + /* |x| > overflowthresold, cosh(x) overflow */ + return huge*huge; +} diff --git a/src/openlibm/src/e_coshf.c.o b/src/openlibm/src/e_coshf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..b1f3bb92dc6aa9b9ba47cc2b8455566c4837de5f GIT binary patch literal 2128 zcmb<-^>JfjWMqH=Mg}_u1P><4z;J;D!FB*M9T@l+co~Az`0EZgKK}pze|_Wc|Nraj z%XJ!mix+LQE7Jw>`5nt*8-I%xZFDNDZT$V`$|fiNwoV2HhR^&0tRPc9^G6MhIe@oQX+{>&eF@iTwKiO>8ICqMJYf!K!*r%eEB0TZA31$aS* zMDuH0_{<-9@H2nhsn7fo2M_bhyD%V`|Cv7$Y&FPQ2Z;Fo|NsC0kA4Z#&A`xL&%nT7 zf9jKGA%nZKvz3B|yI-iLf}x3?k)EM~k%5t^fuW&+f<{nkih@UC2~3ujfW%;7$_V9iLX*3=Ad=3=A?*xeFlL zkx!tRiOHFZkHdvKk&BNboI99{k0TUJx^jE-aex%z#vuDy7(V{Trh*wujB|q(vNE6> zD*zP-Q%Hm;n9a%n@++7LC8QV_7=)0_2m6JAfdLdo5VN2Pp_Cc}0|Pd3Qyk*DIK&xJ zC!t{(zFm|Ns9zq2eHavLlK6A&G;+45mI3Dh@ISqz5M62o(p3A)C{NBo0a= zF!g;k^a|TJA3(3Er_yb9S%mHB#8;tde zD|1T{lNj`hONtmdnvi;8>bd)c>K2zICTBzW>3OAk1x5JSWQZwSyiV|~E!FE%D0Qn1) zSJ=?Zf|Pj-46yVIlSWUg(hLmXJOEPK0i0*a)o;ka0M4yK2rIxWnEgCp9)bX+7Z49d+d=gk zfCQ1S4Ai0eNMax+R2Xb0i0=;74`L%@ZJNY^gwp8xvv9<}1vG$Q@eGQ8P`-rehlzu%LAM)Z)di3QC~l!NC>}s* q6kR{aO!T-1>AwLr)C$Bw!cgPjB7)HJ4lV#?1VG(i3FX5mbo~IUOdE*+ literal 0 HcmV?d00001 diff --git a/src/openlibm/src/e_exp.c b/src/openlibm/src/e_exp.c new file mode 100644 index 0000000..639b9fe --- /dev/null +++ b/src/openlibm/src/e_exp.c @@ -0,0 +1,171 @@ + +/* @(#)e_exp.c 1.6 04/04/22 */ +/* + * ==================================================== + * Copyright (C) 2004 by Sun Microsystems, Inc. All rights reserved. + * + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/e_exp.c,v 1.14 2011/10/21 06:26:38 das Exp $"); + +/* __ieee754_exp(x) + * Returns the exponential of x. + * + * Method + * 1. Argument reduction: + * Reduce x to an r so that |r| <= 0.5*ln2 ~ 0.34658. + * Given x, find r and integer k such that + * + * x = k*ln2 + r, |r| <= 0.5*ln2. + * + * Here r will be represented as r = hi-lo for better + * accuracy. + * + * 2. Approximation of exp(r) by a special rational function on + * the interval [0,0.34658]: + * Write + * R(r**2) = r*(exp(r)+1)/(exp(r)-1) = 2 + r*r/6 - r**4/360 + ... + * We use a special Remes algorithm on [0,0.34658] to generate + * a polynomial of degree 5 to approximate R. The maximum error + * of this polynomial approximation is bounded by 2**-59. In + * other words, + * R(z) ~ 2.0 + P1*z + P2*z**2 + P3*z**3 + P4*z**4 + P5*z**5 + * (where z=r*r, and the values of P1 to P5 are listed below) + * and + * | 5 | -59 + * | 2.0+P1*z+...+P5*z - R(z) | <= 2 + * | | + * The computation of exp(r) thus becomes + * 2*r + * exp(r) = 1 + ------- + * R - r + * r*R1(r) + * = 1 + r + ----------- (for better accuracy) + * 2 - R1(r) + * where + * 2 4 10 + * R1(r) = r - (P1*r + P2*r + ... + P5*r ). + * + * 3. Scale back to obtain exp(x): + * From step 1, we have + * exp(x) = 2^k * exp(r) + * + * Special cases: + * exp(INF) is INF, exp(NaN) is NaN; + * exp(-INF) is 0, and + * for finite argument, only exp(0)=1 is exact. + * + * Accuracy: + * according to an error analysis, the error is always less than + * 1 ulp (unit in the last place). + * + * Misc. info. + * For IEEE double + * if x > 7.09782712893383973096e+02 then exp(x) overflow + * if x < -7.45133219101941108420e+02 then exp(x) underflow + * + * Constants: + * The hexadecimal values are the intended ones for the following + * constants. The decimal values may be used, provided that the + * compiler will convert from decimal to binary accurately enough + * to produce the hexadecimal values shown. + */ + +#include +#include + +#include "math_private.h" + +static const double +one = 1.0, +halF[2] = {0.5,-0.5,}, +huge = 1.0e+300, +o_threshold= 7.09782712893383973096e+02, /* 0x40862E42, 0xFEFA39EF */ +u_threshold= -7.45133219101941108420e+02, /* 0xc0874910, 0xD52D3051 */ +ln2HI[2] ={ 6.93147180369123816490e-01, /* 0x3fe62e42, 0xfee00000 */ + -6.93147180369123816490e-01,},/* 0xbfe62e42, 0xfee00000 */ +ln2LO[2] ={ 1.90821492927058770002e-10, /* 0x3dea39ef, 0x35793c76 */ + -1.90821492927058770002e-10,},/* 0xbdea39ef, 0x35793c76 */ +invln2 = 1.44269504088896338700e+00, /* 0x3ff71547, 0x652b82fe */ +P1 = 1.66666666666666019037e-01, /* 0x3FC55555, 0x5555553E */ +P2 = -2.77777777770155933842e-03, /* 0xBF66C16C, 0x16BEBD93 */ +P3 = 6.61375632143793436117e-05, /* 0x3F11566A, 0xAF25DE2C */ +P4 = -1.65339022054652515390e-06, /* 0xBEBBBD41, 0xC5D26BF1 */ +P5 = 4.13813679705723846039e-08; /* 0x3E663769, 0x72BEA4D0 */ + +static volatile double +twom1000= 9.33263618503218878990e-302; /* 2**-1000=0x01700000,0*/ + +OLM_DLLEXPORT double +__ieee754_exp(double x) /* default IEEE double exp */ +{ + double y,hi=0.0,lo=0.0,c,t,twopk; + int32_t k=0,xsb; + u_int32_t hx; + + GET_HIGH_WORD(hx,x); + xsb = (hx>>31)&1; /* sign bit of x */ + hx &= 0x7fffffff; /* high word of |x| */ + + /* filter out non-finite argument */ + if(hx >= 0x40862E42) { /* if |x|>=709.78... */ + if(hx>=0x7ff00000) { + u_int32_t lx; + GET_LOW_WORD(lx,x); + if(((hx&0xfffff)|lx)!=0) + return x+x; /* NaN */ + else return (xsb==0)? x:0.0; /* exp(+-inf)={inf,0} */ + } + if(x > o_threshold) return huge*huge; /* overflow */ + if(x < u_threshold) return twom1000*twom1000; /* underflow */ + } + + /* this implementation gives 2.7182818284590455 for exp(1.0), + which is well within the allowable error. however, + 2.718281828459045 is closer to the true value so we prefer that + answer, given that 1.0 is such an important argument value. */ + if (x == 1.0) + return 2.718281828459045235360; + + /* argument reduction */ + if(hx > 0x3fd62e42) { /* if |x| > 0.5 ln2 */ + if(hx < 0x3FF0A2B2) { /* and |x| < 1.5 ln2 */ + hi = x-ln2HI[xsb]; lo=ln2LO[xsb]; k = 1-xsb-xsb; + } else { + k = (int)(invln2*x+halF[xsb]); + t = k; + hi = x - t*ln2HI[0]; /* t*ln2HI is exact here */ + lo = t*ln2LO[0]; + } + STRICT_ASSIGN(double, x, hi - lo); + } + else if(hx < 0x3e300000) { /* when |x|<2**-28 */ + if(huge+x>one) return one+x;/* trigger inexact */ + } + else k = 0; + + /* x is now in primary range */ + t = x*x; + if(k >= -1021) + INSERT_WORDS(twopk,0x3ff00000+(k<<20), 0); + else + INSERT_WORDS(twopk,0x3ff00000+((k+1000)<<20), 0); + c = x - t*(P1+t*(P2+t*(P3+t*(P4+t*P5)))); + if(k==0) return one-((x*c)/(c-2.0)-x); + else y = one-((lo-(x*c)/(2.0-c))-hi); + if(k >= -1021) { + if (k==1024) return y*2.0*0x1p1023; + return y*twopk; + } else { + return y*twopk*twom1000; + } +} + +#if (LDBL_MANT_DIG == 53) +openlibm_weak_reference(exp, expl); +#endif diff --git a/src/openlibm/src/e_exp.c.o b/src/openlibm/src/e_exp.c.o new file mode 100644 index 0000000000000000000000000000000000000000..aa5c657ae3ef7c46d4f418533eca45011fd9cbc8 GIT binary patch literal 3848 zcmb<-^>JfjWMqH=Mg}_u1P><4z~I4+U^{@B4h;MZd<E&;8V3*a%QJl97hnZhlg6)iqKb{bMTCigq4AfK-Zgvv_5?8d|9^cu z{x%tio|kF-?{Dv7VEABfc;FL%v2$RBYL%80oDX7EQ`2hnN#8ZSTb$GmDiz~7?J#K7>0Kk_WxCjOYK zpZMcWed3R~`H4T~&L{qu!?p}83=I4&HXwI;@aO&d#2@)1jbG#V;WU1E7m(le!T#iL zFJc542J^N4LH_m+C?b$>;DLyNJ?4@84dm@KevOA7y;weBR_!x?9(Uy$giLP z`v_&kd;l}}Bff)a7yg)gw#Y<;)Aab|TR@uN>EtlKd;>_}6Mw{sG=6Xzg7Tq>fIs45 z8o&Mp{}|NsBQ9|1~bE{G8S#2Z`~uLV8VPbK!zca-P{Ibs@?j(^UON8${~zRWFfL#$ zv#B(FZ~4j=O7CT0c<|3j@0mT6-VavB@W38Q@6QYu>E_zc>hRw3*FPt{HitQ-3>`L4 z%$r@DUNjNNSnkwj&8LFfcGPU>Xc^7b62J*bgAp z0w98cfq@U~2ZVYKsJJ*-oRtBl4n~8rC&(PAGPpd5&kPP75DS5o!Av%|y93UNS>QVvZX_NqK&*p@D$` zLr$KNhbM^i@n_KUaW(}JmLS5=08AQ!Nnk_Atd!(NaCQh1pw4%h^RInSUK!E%QN&@I55wyZ&fR`swyFhsb$^=u=43Ih!rXDQF zz`$^W9m2W*4Kz?Zg6sjsDM$uZuBw6S8&KT^5=Gz>(D;Crt0*#+XjXn&}FkQg#v4%Lq=24chXf!H7ns-Hknh3@|qQ2prcg1H-{ z7lg~9_M_{+L8Sg79O-8Ts4!w+fY-mE^aB!t*$+!UApfA-4RRL;sKLg-zz_kI1eKj2 rJ?Q#DWjVH_k^l-6Eb#}j4`e +#include + +#include "math_private.h" + +static const float +one = 1.0, +halF[2] = {0.5,-0.5,}, +huge = 1.0e+30, +o_threshold= 8.8721679688e+01, /* 0x42b17180 */ +u_threshold= -1.0397208405e+02, /* 0xc2cff1b5 */ +ln2HI[2] ={ 6.9314575195e-01, /* 0x3f317200 */ + -6.9314575195e-01,}, /* 0xbf317200 */ +ln2LO[2] ={ 1.4286067653e-06, /* 0x35bfbe8e */ + -1.4286067653e-06,}, /* 0xb5bfbe8e */ +invln2 = 1.4426950216e+00, /* 0x3fb8aa3b */ +/* + * Domain [-0.34568, 0.34568], range ~[-4.278e-9, 4.447e-9]: + * |x*(exp(x)+1)/(exp(x)-1) - p(x)| < 2**-27.74 + */ +P1 = 1.6666625440e-1, /* 0xaaaa8f.0p-26 */ +P2 = -2.7667332906e-3; /* -0xb55215.0p-32 */ + +static volatile float twom100 = 7.8886090522e-31; /* 2**-100=0x0d800000 */ + +OLM_DLLEXPORT float +__ieee754_expf(float x) +{ + float y,hi=0.0,lo=0.0,c,t,twopk; + int32_t k=0,xsb; + u_int32_t hx; + + GET_FLOAT_WORD(hx,x); + xsb = (hx>>31)&1; /* sign bit of x */ + hx &= 0x7fffffff; /* high word of |x| */ + + /* filter out non-finite argument */ + if(hx >= 0x42b17218) { /* if |x|>=88.721... */ + if(hx>0x7f800000) + return x+x; /* NaN */ + if(hx==0x7f800000) + return (xsb==0)? x:0.0; /* exp(+-inf)={inf,0} */ + if(x > o_threshold) return huge*huge; /* overflow */ + if(x < u_threshold) return twom100*twom100; /* underflow */ + } + + /* argument reduction */ + if(hx > 0x3eb17218) { /* if |x| > 0.5 ln2 */ + if(hx < 0x3F851592) { /* and |x| < 1.5 ln2 */ + hi = x-ln2HI[xsb]; lo=ln2LO[xsb]; k = 1-xsb-xsb; + } else { + k = invln2*x+halF[xsb]; + t = k; + hi = x - t*ln2HI[0]; /* t*ln2HI is exact here */ + lo = t*ln2LO[0]; + } + STRICT_ASSIGN(float, x, hi - lo); + } + else if(hx < 0x39000000) { /* when |x|<2**-14 */ + if(huge+x>one) return one+x;/* trigger inexact */ + } + else k = 0; + + /* x is now in primary range */ + t = x*x; + if(k >= -125) + SET_FLOAT_WORD(twopk,0x3f800000+(k<<23)); + else + SET_FLOAT_WORD(twopk,0x3f800000+((k+100)<<23)); + c = x - t*(P1+t*P2); + if(k==0) return one-((x*c)/(c-(float)2.0)-x); + else y = one-((lo-(x*c)/((float)2.0-c))-hi); + if(k >= -125) { + if(k==128) return y*2.0F*0x1p127F; + return y*twopk; + } else { + return y*twopk*twom100; + } +} diff --git a/src/openlibm/src/e_expf.c.o b/src/openlibm/src/e_expf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..046c1979ef2c44c2bafff02282c2933e1463add3 GIT binary patch literal 3336 zcmb<-^>JfjWMqH=Mg}_u1P><4z~I4&U^{@B4h;MZd<<#)bqDx0PIMkp{r~@e{lQoA zw&Fz_o%q|nFfcIKGB7mM^S4VfF);AAID<%iR*+Wyb}=RfhR^&05T5=){&rI&0gqm= zcpCrv+x!|YKl2NSf;4^R7chm;kq1BXN3cxz%&&6*X2xfJts9^DBM*P(kCcTdih04W zarQHR%xQj&hx{5pKl4XEAABGVvzL{Dp`q|If6Vzb{=5&L`Qr|L=8w67us7!JXZ{$Fy&y9W9iCt-QMA#n zybz|q_W%F?7Ufbf!#?vzT;$ikP{#S0KjPqFet8E5evO+jNq&uopZOzie&&z7{Fy%j z>S+)=<`KWfmCyW<7eDjIsDhmLnLqBzXZ{!v|Ipzyet8!L2HT0Et@ixwJO2Iu?~#1S zqZjNAevKC}!$0%K=rlrw5kV;+)7W{T`2!=r##zk^(9i+})o1?5E1ic9J`(TU#K6#C zpT?he>@$DFHIOjam2ele9^h~3V?YGlXa1NopZVi1e&!bdyWlf_%&pJ-;6OTU+rYrU zP@?ylKk^{R(JdgKFns2ZIKi(03JVw?k}5v)M;vvATd}T zV}$Zy*-HeXje)T$h=H*}fKi%BiG#&i8DQ#QG$>nw%mJwZVVF3G%?u75 z5DS5o!Av$ViA-pKIc#wA!CVFg23;_Nje!SDBM2iflZ`0|SE% zn8613FPO`~z~BgGuz}+N%!CqdV496V1xzCdA25>*9QR-*ln4aVY~XYOWF8HqV=3?=3HxrPP?3^{p59-bi5$DcvZ$Jr1> z7=s8C5Md4?EI@=Qh%f^Yh6W(g5=0n*2tz{#kilTf85kH0pbSuw1EtYF{~^E*NgR|$ zVB-Er;@k`j3@~ws{}>oR=78cJ7Eh^2>Oo>K^|?smpv(^wZ$c91Lo$C7k~k=B!qi_v z5(lMWnD|{JaZoCTiT^?p7eq2&8kC_JAnr#N*Fq8(LQ?OJB#!K_C?s)Ye-$E$BfE1Z zk~k>bVEJqbk~p&Y8<507>S6xcfh3M>FE=Pcp#DO(R~kti*}ox3;>iBZKoS>53WpXX zapZ9B!67~qNgUZ;P#Fq}8jv&ygVV5_4h67wi;D2$26kQG{ONfhr!5x$t}s;xI5^luyzOkh%t@ z9;%E%0cv0eG|)h41!NB>ZGhCk%0)GBxeclVK%xlz1gZ~~?qD+Ld>sY`aG4B>W0)Ec z{Q{~V#74#-Hz4y3q4uLIhv|p86Q&2|ei+{psvndlVPaq!>L8H&zW#U4@y6v@*XM-uUA3-LAM*^{sU0^e}EJ)Fff419#C5b wT|cO9fhq-QgX0~bh7$t=Ln2%R!hjkF;V>{TfXWJN`VT-YYJ{tVFwpe_0Q2EN8vp + +#include "math_private.h" + +static const double one = 1.0, Zero[] = {0.0, -0.0,}; + +OLM_DLLEXPORT double +__ieee754_fmod(double x, double y) +{ + int32_t n,hx,hy,hz,ix,iy,sx,i; + u_int32_t lx,ly,lz; + + EXTRACT_WORDS(hx,lx,x); + EXTRACT_WORDS(hy,ly,y); + sx = hx&0x80000000; /* sign of x */ + hx ^=sx; /* |x| */ + hy &= 0x7fffffff; /* |y| */ + + /* purge off exception values */ + if((hy|ly)==0||(hx>=0x7ff00000)|| /* y=0,or x not finite */ + ((hy|((ly|-ly)>>31))>0x7ff00000)) /* or y is NaN */ + return (x*y)/(x*y); + if(hx<=hy) { + if((hx>31]; /* |x|=|y| return x*0*/ + } + + /* determine ix = ilogb(x) */ + if(hx<0x00100000) { /* subnormal x */ + if(hx==0) { + for (ix = -1043, i=lx; i>0; i<<=1) ix -=1; + } else { + for (ix = -1022,i=(hx<<11); i>0; i<<=1) ix -=1; + } + } else ix = (hx>>20)-1023; + + /* determine iy = ilogb(y) */ + if(hy<0x00100000) { /* subnormal y */ + if(hy==0) { + for (iy = -1043, i=ly; i>0; i<<=1) iy -=1; + } else { + for (iy = -1022,i=(hy<<11); i>0; i<<=1) iy -=1; + } + } else iy = (hy>>20)-1023; + + /* set up {hx,lx}, {hy,ly} and align y to x */ + if(ix >= -1022) + hx = 0x00100000|(0x000fffff&hx); + else { /* subnormal x, shift x to normal */ + n = -1022-ix; + if(n<=31) { + hx = (hx<>(32-n)); + lx <<= n; + } else { + hx = lx<<(n-32); + lx = 0; + } + } + if(iy >= -1022) + hy = 0x00100000|(0x000fffff&hy); + else { /* subnormal y, shift y to normal */ + n = -1022-iy; + if(n<=31) { + hy = (hy<>(32-n)); + ly <<= n; + } else { + hy = ly<<(n-32); + ly = 0; + } + } + + /* fix point fmod */ + n = ix - iy; + while(n--) { + hz=hx-hy;lz=lx-ly; if(lx>31); lx = lx+lx;} + else { + if((hz|lz)==0) /* return sign(x)*0 */ + return Zero[(u_int32_t)sx>>31]; + hx = hz+hz+(lz>>31); lx = lz+lz; + } + } + hz=hx-hy;lz=lx-ly; if(lx=0) {hx=hz;lx=lz;} + + /* convert back to floating value and restore the sign */ + if((hx|lx)==0) /* return sign(x)*0 */ + return Zero[(u_int32_t)sx>>31]; + while(hx<0x00100000) { /* normalize x */ + hx = hx+hx+(lx>>31); lx = lx+lx; + iy -= 1; + } + if(iy>= -1022) { /* normalize output */ + hx = ((hx-0x00100000)|((iy+1023)<<20)); + INSERT_WORDS(x,hx|sx,lx); + } else { /* subnormal output */ + n = -1022 - iy; + if(n<=20) { + lx = (lx>>n)|((u_int32_t)hx<<(32-n)); + hx >>= n; + } else if (n<=31) { + lx = (hx<<(32-n))|(lx>>n); hx = sx; + } else { + lx = hx>>(n-32); hx = sx; + } + INSERT_WORDS(x,hx|sx,lx); + x *= one; /* create necessary signal */ + } + return x; /* exact output */ +} diff --git a/src/openlibm/src/e_fmodf.c b/src/openlibm/src/e_fmodf.c new file mode 100644 index 0000000..88fd8ae --- /dev/null +++ b/src/openlibm/src/e_fmodf.c @@ -0,0 +1,105 @@ +/* e_fmodf.c -- float version of e_fmod.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/e_fmodf.c,v 1.7 2008/02/22 02:30:34 das Exp $"); + +/* + * __ieee754_fmodf(x,y) + * Return x mod y in exact arithmetic + * Method: shift and subtract + */ + +#include + +#include "math_private.h" + +static const float one = 1.0, Zero[] = {0.0, -0.0,}; + +OLM_DLLEXPORT float +__ieee754_fmodf(float x, float y) +{ + int32_t n,hx,hy,hz,ix,iy,sx,i; + + GET_FLOAT_WORD(hx,x); + GET_FLOAT_WORD(hy,y); + sx = hx&0x80000000; /* sign of x */ + hx ^=sx; /* |x| */ + hy &= 0x7fffffff; /* |y| */ + + /* purge off exception values */ + if(hy==0||(hx>=0x7f800000)|| /* y=0,or x not finite */ + (hy>0x7f800000)) /* or y is NaN */ + return (x*y)/(x*y); + if(hx>31]; /* |x|=|y| return x*0*/ + + /* determine ix = ilogb(x) */ + if(hx<0x00800000) { /* subnormal x */ + for (ix = -126,i=(hx<<8); i>0; i<<=1) ix -=1; + } else ix = (hx>>23)-127; + + /* determine iy = ilogb(y) */ + if(hy<0x00800000) { /* subnormal y */ + for (iy = -126,i=(hy<<8); i>=0; i<<=1) iy -=1; + } else iy = (hy>>23)-127; + + /* set up {hx,lx}, {hy,ly} and align y to x */ + if(ix >= -126) + hx = 0x00800000|(0x007fffff&hx); + else { /* subnormal x, shift x to normal */ + n = -126-ix; + hx = hx<= -126) + hy = 0x00800000|(0x007fffff&hy); + else { /* subnormal y, shift y to normal */ + n = -126-iy; + hy = hy<>31]; + hx = hz+hz; + } + } + hz=hx-hy; + if(hz>=0) {hx=hz;} + + /* convert back to floating value and restore the sign */ + if(hx==0) /* return sign(x)*0 */ + return Zero[(u_int32_t)sx>>31]; + while(hx<0x00800000) { /* normalize x */ + hx = hx+hx; + iy -= 1; + } + if(iy>= -126) { /* normalize output */ + hx = ((hx-0x00800000)|((iy+127)<<23)); + SET_FLOAT_WORD(x,hx|sx); + } else { /* subnormal output */ + n = -126 - iy; + hx >>= n; + SET_FLOAT_WORD(x,hx|sx); + x *= one; /* create necessary signal */ + } + return x; /* exact output */ +} diff --git a/src/openlibm/src/e_fmodl.c b/src/openlibm/src/e_fmodl.c new file mode 100644 index 0000000..47d961b --- /dev/null +++ b/src/openlibm/src/e_fmodl.c @@ -0,0 +1,150 @@ +/* @(#)e_fmod.c 1.3 95/01/18 */ +/*- + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/e_fmodl.c,v 1.2 2008/07/31 20:09:47 das Exp $"); + +#include +#include +#include + +#include "fpmath.h" + +#include "math_private.h" + +#define BIAS (LDBL_MAX_EXP - 1) + +#if LDBL_MANL_SIZE > 32 +typedef u_int64_t manl_t; +#else +typedef u_int32_t manl_t; +#endif + +#if LDBL_MANH_SIZE > 32 +typedef u_int64_t manh_t; +#else +typedef u_int32_t manh_t; +#endif + +/* + * These macros add and remove an explicit integer bit in front of the + * fractional mantissa, if the architecture doesn't have such a bit by + * default already. + */ +#ifdef LDBL_IMPLICIT_NBIT +#define SET_NBIT(hx) ((hx) | (1ULL << LDBL_MANH_SIZE)) +#define HFRAC_BITS LDBL_MANH_SIZE +#else +#define SET_NBIT(hx) (hx) +#define HFRAC_BITS (LDBL_MANH_SIZE - 1) +#endif + +#define MANL_SHIFT (LDBL_MANL_SIZE - 1) + +static const long double one = 1.0, Zero[] = {0.0, -0.0,}; + +/* + * fmodl(x,y) + * Return x mod y in exact arithmetic + * Method: shift and subtract + * + * Assumptions: + * - The low part of the mantissa fits in a manl_t exactly. + * - The high part of the mantissa fits in an int64_t with enough room + * for an explicit integer bit in front of the fractional bits. + */ +OLM_DLLEXPORT long double +fmodl(long double x, long double y) +{ + union IEEEl2bits ux, uy; + int64_t hx,hz; /* We need a carry bit even if LDBL_MANH_SIZE is 32. */ + manh_t hy; + manl_t lx,ly,lz; + int ix,iy,n,sx; + + ux.e = x; + uy.e = y; + sx = ux.bits.sign; + + /* purge off exception values */ + if((uy.bits.exp|uy.bits.manh|uy.bits.manl)==0 || /* y=0 */ + (ux.bits.exp == BIAS + LDBL_MAX_EXP) || /* or x not finite */ + (uy.bits.exp == BIAS + LDBL_MAX_EXP && + ((uy.bits.manh&~LDBL_NBIT)|uy.bits.manl)!=0)) /* or y is NaN */ + return (x*y)/(x*y); + if(ux.bits.exp<=uy.bits.exp) { + if((ux.bits.exp>MANL_SHIFT); lx = lx+lx;} + else { + if ((hz|lz)==0) /* return sign(x)*0 */ + return Zero[sx]; + hx = hz+hz+(lz>>MANL_SHIFT); lx = lz+lz; + } + } + hz=hx-hy;lz=lx-ly; if(lx=0) {hx=hz;lx=lz;} + + /* convert back to floating value and restore the sign */ + if((hx|lx)==0) /* return sign(x)*0 */ + return Zero[sx]; + while(hx<(1ULL<>MANL_SHIFT); lx = lx+lx; + iy -= 1; + } + ux.bits.manh = hx; /* The mantissa is truncated here if needed. */ + ux.bits.manl = lx; + if (iy < LDBL_MIN_EXP) { + ux.bits.exp = iy + (BIAS + 512); + ux.e *= 0x1p-512; + } else { + ux.bits.exp = iy + BIAS; + } + x = ux.e * one; /* create necessary signal */ + return x; /* exact output */ +} diff --git a/src/openlibm/src/e_hypot.c b/src/openlibm/src/e_hypot.c new file mode 100644 index 0000000..3f4c1d1 --- /dev/null +++ b/src/openlibm/src/e_hypot.c @@ -0,0 +1,131 @@ + +/* @(#)e_hypot.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/e_hypot.c,v 1.14 2011/10/15 07:00:28 das Exp $"); + +/* __ieee754_hypot(x,y) + * + * Method : + * If (assume round-to-nearest) z=x*x+y*y + * has error less than sqrt(2)/2 ulp, than + * sqrt(z) has error less than 1 ulp (exercise). + * + * So, compute sqrt(x*x+y*y) with some care as + * follows to get the error below 1 ulp: + * + * Assume x>y>0; + * (if possible, set rounding to round-to-nearest) + * 1. if x > 2y use + * x1*x1+(y*y+(x2*(x+x1))) for x*x+y*y + * where x1 = x with lower 32 bits cleared, x2 = x-x1; else + * 2. if x <= 2y use + * t1*y1+((x-y)*(x-y)+(t1*y2+t2*y)) + * where t1 = 2x with lower 32 bits cleared, t2 = 2x-t1, + * y1= y with lower 32 bits chopped, y2 = y-y1. + * + * NOTE: scaling may be necessary if some argument is too + * large or too tiny + * + * Special cases: + * hypot(x,y) is INF if x or y is +INF or -INF; else + * hypot(x,y) is NAN if x or y is NAN. + * + * Accuracy: + * hypot(x,y) returns sqrt(x^2+y^2) with error less + * than 1 ulps (units in the last place) + */ + +#include +#include + +#include "math_private.h" + +OLM_DLLEXPORT double +__ieee754_hypot(double x, double y) +{ + double a,b,t1,t2,y1,y2,w; + int32_t j,k,ha,hb; + + GET_HIGH_WORD(ha,x); + ha &= 0x7fffffff; + GET_HIGH_WORD(hb,y); + hb &= 0x7fffffff; + if(hb > ha) {a=y;b=x;j=ha; ha=hb;hb=j;} else {a=x;b=y;} + a = fabs(a); + b = fabs(b); + if((ha-hb)>0x3c00000) {return a+b;} /* x/y > 2**60 */ + k=0; + if(ha > 0x5f300000) { /* a>2**500 */ + if(ha >= 0x7ff00000) { /* Inf or NaN */ + u_int32_t low; + /* Use original arg order iff result is NaN; quieten sNaNs. */ + w = fabs(x+0.0)-fabs(y+0.0); + GET_LOW_WORD(low,a); + if(((ha&0xfffff)|low)==0) w = a; + GET_LOW_WORD(low,b); + if(((hb^0x7ff00000)|low)==0) w = b; + return w; + } + /* scale a and b by 2**-600 */ + ha -= 0x25800000; hb -= 0x25800000; k += 600; + SET_HIGH_WORD(a,ha); + SET_HIGH_WORD(b,hb); + } + if(hb < 0x20b00000) { /* b < 2**-500 */ + if(hb <= 0x000fffff) { /* subnormal b or 0 */ + u_int32_t low; + GET_LOW_WORD(low,b); + if((hb|low)==0) return a; + t1=0; + SET_HIGH_WORD(t1,0x7fd00000); /* t1=2^1022 */ + b *= t1; + a *= t1; + k -= 1022; + } else { /* scale a and b by 2^600 */ + ha += 0x25800000; /* a *= 2^600 */ + hb += 0x25800000; /* b *= 2^600 */ + k -= 600; + SET_HIGH_WORD(a,ha); + SET_HIGH_WORD(b,hb); + } + } + /* medium size a and b */ + w = a-b; + if (w>b) { + t1 = 0; + SET_HIGH_WORD(t1,ha); + t2 = a-t1; + w = sqrt(t1*t1-(b*(-b)-t2*(a+t1))); + } else { + a = a+a; + y1 = 0; + SET_HIGH_WORD(y1,hb); + y2 = b - y1; + t1 = 0; + SET_HIGH_WORD(t1,ha+0x00100000); + t2 = a - t1; + w = sqrt(t1*y1-(w*(-w)-(t1*y2+t2*b))); + } + if(k!=0) { + u_int32_t high; + t1 = 1.0; + GET_HIGH_WORD(high,t1); + SET_HIGH_WORD(t1,high+(k<<20)); + return t1*w; + } else return w; +} + +#if LDBL_MANT_DIG == 53 +openlibm_weak_reference(hypot, hypotl); +#endif diff --git a/src/openlibm/src/e_hypot.c.o b/src/openlibm/src/e_hypot.c.o new file mode 100644 index 0000000000000000000000000000000000000000..99ee3647ce6a7130b22988f69d831c5040478f48 GIT binary patch literal 2672 zcmb<-^>JfjWMqH=Mg}_u1P><4z_5W0!FB*M9T@l-_!!bW`0EZhhNSUpJP7qT_(CBV zByhU(sK>$A3XMyvyHX!pOkTc_Yn}zwS)u>&~N}_yv7bBtG#A zrl<(K02%vmxpZEoQR3y^)HEuNiVqiGH z%-Y zx3Ph=^J|>;=)94}AI=L><8knT!YBU7(`g?3c@NU~HEw<4kGS)RKjumrzs8YI{E;Ah z`4fN4sZabd2fNk&Q~C7E`St)#X1joa9-FI1v1lvKktU&0W|YJ@kd+$xd-GH zkeguc`NSV_sdq91g8)Mszs56<&KF<{4n9yw;}2H_JJ^Fi4{X`1N1rqDL0N7 zFhoTFlJr2a1dbJ0!g~J}9MqrqBhG>x43h(E5QtIX09kZ_^KhwJ=L-aZ1_qe8D98W?1_ls?tlkGCfJOaLBynVSKExpo3Kx)*K++%#VuP_>ab<2v zViJR1aY+$`&VaFsQgagZN>VFI81zySOA;CMl8TEN^osI99KGb?5({LGp&5f-a(-@Z zYF-J0US57ls-C-FsBUpdVsbW=pPpB$S5TB+kXlqy$)E=|JT)Uettc@!73>m<2$26k zK?@2CWP>1e8Uq6?-N59~(+DU%fx;c89;VI$npAH<1$Y=3z^Rb~%9nuBYEW@d8h{Fc zscdusuqea~C=*QSFfcHH%tTjCtbRkN{X$^V5JUmgK#u!h;m;~7eW + +#include "math_private.h" + +OLM_DLLEXPORT float +__ieee754_hypotf(float x, float y) +{ + float a,b,t1,t2,y1,y2,w; + int32_t j,k,ha,hb; + + GET_FLOAT_WORD(ha,x); + ha &= 0x7fffffff; + GET_FLOAT_WORD(hb,y); + hb &= 0x7fffffff; + if(hb > ha) {a=y;b=x;j=ha; ha=hb;hb=j;} else {a=x;b=y;} + a = fabsf(a); + b = fabsf(b); + if((ha-hb)>0xf000000) {return a+b;} /* x/y > 2**30 */ + k=0; + if(ha > 0x58800000) { /* a>2**50 */ + if(ha >= 0x7f800000) { /* Inf or NaN */ + /* Use original arg order iff result is NaN; quieten sNaNs. */ + w = fabsf(x+0.0F)-fabsf(y+0.0F); + if(ha == 0x7f800000) w = a; + if(hb == 0x7f800000) w = b; + return w; + } + /* scale a and b by 2**-68 */ + ha -= 0x22000000; hb -= 0x22000000; k += 68; + SET_FLOAT_WORD(a,ha); + SET_FLOAT_WORD(b,hb); + } + if(hb < 0x26800000) { /* b < 2**-50 */ + if(hb <= 0x007fffff) { /* subnormal b or 0 */ + if(hb==0) return a; + SET_FLOAT_WORD(t1,0x7e800000); /* t1=2^126 */ + b *= t1; + a *= t1; + k -= 126; + } else { /* scale a and b by 2^68 */ + ha += 0x22000000; /* a *= 2^68 */ + hb += 0x22000000; /* b *= 2^68 */ + k -= 68; + SET_FLOAT_WORD(a,ha); + SET_FLOAT_WORD(b,hb); + } + } + /* medium size a and b */ + w = a-b; + if (w>b) { + SET_FLOAT_WORD(t1,ha&0xfffff000); + t2 = a-t1; + w = __ieee754_sqrtf(t1*t1-(b*(-b)-t2*(a+t1))); + } else { + a = a+a; + SET_FLOAT_WORD(y1,hb&0xfffff000); + y2 = b - y1; + SET_FLOAT_WORD(t1,(ha+0x00800000)&0xfffff000); + t2 = a - t1; + w = __ieee754_sqrtf(t1*y1-(w*(-w)-(t1*y2+t2*b))); + } + if(k!=0) { + SET_FLOAT_WORD(t1,0x3f800000+(k<<23)); + return t1*w; + } else return w; +} diff --git a/src/openlibm/src/e_hypotf.c.o b/src/openlibm/src/e_hypotf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..303be41b14559722c306fee7b8711629b60f51f1 GIT binary patch literal 2512 zcmb<-^>JfjWMqH=Mg}_u1P><4z#zbeU^{@B4h;MZd<>3Zj-hFe{B=hiLqOD-P?yfP z!7iPT8=wCF|G&QRF^KeNej{Lcm%j&OaOVxz&S#ykJCD8q8S{oPpZOzSeCCflk;X6Y!oa|<@$fT$%u{~- zr~GXf7#J8DA2WRT|DRvuA-~4eH2%EX{NbV?eV_Rw9)ISKInA$e_%nax)zAEqAo|Q_ z{+NrO`C|@&9m}tA!nO5DiLguOgM$ymSs54_?9=%3ethPSJnzwbM1Wu8V05fwjAN{0 z+~G7me)$%VxeTtI@Ax$izWn#^|9`N18h`))UtiDPe+1-~*9;5{N{w$pYdS1_p+gy#N3Ihxp?&f5ZupEf6dCH4Zw)9p;yJVED`*akB9+149D? zzs8-$ry$QkyqLzH_mw|f7UYOD{=Ccl8pl5K$DI1iA9?39f8?Rh{E=rr^T)jV%pdvc zGk*k#ee*Ma%wd>EUkd#PIoN>#WHy6R<57?s9XpS}-1l+`*h3BsY5eamA!7CDXa0yo zpZNuSRCvH9fn-6+!rvx7+4q>7!(*77(l7T-7l1ZiGlF|NDP(-7@>Slu;C00B2b#KDu{uxLV!`4 zhn-^rBLhPW0|SE$RIZGPfq}t^PoR& z3!jD~pMn#ggcF~D6CZ~+H&Xx?pMfKis4E|bD>u|kTolNiEDRsPA%d=k8I0duedU|Br%CWuehWLLTA8OMX5Q7dL^k9B@B8gi6w~)dP&8_40=WRAdX&gaft~s z$Iy&HFF8LqH#M(>K`$@ABvsGdFI2aQ`=Ai8!QASKxTj$P(p`+fdOPDx%v&E_6tGHgHb!6_Cvh^69$(* zAP!924u}2&Q2prP1>?hLAE;p0{m5b8Ai%ot0C5-?7@Vqjp`$UZoS Xfq?;34r9~b0d;>nvSMghAqxQjK@-BC literal 0 HcmV?d00001 diff --git a/src/openlibm/src/e_hypotl.c b/src/openlibm/src/e_hypotl.c new file mode 100644 index 0000000..2632774 --- /dev/null +++ b/src/openlibm/src/e_hypotl.c @@ -0,0 +1,124 @@ +/* From: @(#)e_hypot.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/e_hypotl.c,v 1.3 2011/10/16 05:36:39 das Exp $"); + +/* long double version of hypot(). See e_hypot.c for most comments. */ + +#include +#include + +#include "fpmath.h" +#include "math_private.h" + +#define GET_LDBL_MAN(h, l, v) do { \ + union IEEEl2bits uv; \ + \ + uv.e = v; \ + h = uv.bits.manh; \ + l = uv.bits.manl; \ +} while (0) + +#undef GET_HIGH_WORD +#define GET_HIGH_WORD(i, v) GET_LDBL_EXPSIGN(i, v) +#undef SET_HIGH_WORD +#define SET_HIGH_WORD(v, i) SET_LDBL_EXPSIGN(v, i) + +#define DESW(exp) (exp) /* delta expsign word */ +#define ESW(exp) (MAX_EXP - 1 + (exp)) /* expsign word */ +#define MANT_DIG LDBL_MANT_DIG +#define MAX_EXP LDBL_MAX_EXP + +#if LDBL_MANL_SIZE > 32 +typedef u_int64_t man_t; +#else +typedef u_int32_t man_t; +#endif + +OLM_DLLEXPORT long double +hypotl(long double x, long double y) +{ + long double a=x,b=y,t1,t2,y1,y2,w; + int32_t j,k,ha,hb; + + GET_HIGH_WORD(ha,x); + ha &= 0x7fff; + GET_HIGH_WORD(hb,y); + hb &= 0x7fff; + if(hb > ha) {a=y;b=x;j=ha; ha=hb;hb=j;} else {a=x;b=y;} + a = fabsl(a); + b = fabsl(b); + if((ha-hb)>DESW(MANT_DIG+7)) {return a+b;} /* x/y > 2**(MANT_DIG+7) */ + k=0; + if(ha > ESW(MAX_EXP/2-12)) { /* a>2**(MAX_EXP/2-12) */ + if(ha >= ESW(MAX_EXP)) { /* Inf or NaN */ + man_t manh, manl; + /* Use original arg order iff result is NaN; quieten sNaNs. */ + w = fabsl(x+0.0)-fabsl(y+0.0); + GET_LDBL_MAN(manh,manl,a); + if (manh == LDBL_NBIT && manl == 0) w = a; + GET_LDBL_MAN(manh,manl,b); + if (hb >= ESW(MAX_EXP) && manh == LDBL_NBIT && manl == 0) w = b; + return w; + } + /* scale a and b by 2**-(MAX_EXP/2+88) */ + ha -= DESW(MAX_EXP/2+88); hb -= DESW(MAX_EXP/2+88); + k += MAX_EXP/2+88; + SET_HIGH_WORD(a,ha); + SET_HIGH_WORD(b,hb); + } + if(hb < ESW(-(MAX_EXP/2-12))) { /* b < 2**-(MAX_EXP/2-12) */ + if(hb <= 0) { /* subnormal b or 0 */ + man_t manh, manl; + GET_LDBL_MAN(manh,manl,b); + if((manh|manl)==0) return a; + t1=1; + SET_HIGH_WORD(t1,ESW(MAX_EXP-2)); /* t1=2^(MAX_EXP-2) */ + b *= t1; + a *= t1; + k -= MAX_EXP-2; + } else { /* scale a and b by 2^(MAX_EXP/2+88) */ + ha += DESW(MAX_EXP/2+88); + hb += DESW(MAX_EXP/2+88); + k -= MAX_EXP/2+88; + SET_HIGH_WORD(a,ha); + SET_HIGH_WORD(b,hb); + } + } + /* medium size a and b */ + w = a-b; + if (w>b) { + t1 = a; + union IEEEl2bits uv; + uv.e = t1; uv.bits.manl = 0; t1 = uv.e; + t2 = a-t1; + w = sqrtl(t1*t1-(b*(-b)-t2*(a+t1))); + } else { + a = a+a; + y1 = b; + union IEEEl2bits uv; + uv.e = y1; uv.bits.manl = 0; y1 = uv.e; + y2 = b - y1; + t1 = a; + uv.e = t1; uv.bits.manl = 0; t1 = uv.e; + t2 = a - t1; + w = sqrtl(t1*y1-(w*(-w)-(t1*y2+t2*b))); + } + if(k!=0) { + u_int32_t high; + t1 = 1.0; + GET_HIGH_WORD(high,t1); + SET_HIGH_WORD(t1,high+DESW(k)); + return t1*w; + } else return w; +} diff --git a/src/openlibm/src/e_hypotl.c.o b/src/openlibm/src/e_hypotl.c.o new file mode 100644 index 0000000000000000000000000000000000000000..4f9d76f1ad1eb9d40afd52b3c3b9f05019e37162 GIT binary patch literal 2552 zcmb<-^>JfjWMqH=Mg}_u1P><4z)-=4U^{@B4h(z@ybO*Zp}`)_Zvs5Jb5trky632L zFfcGQKK){h$qXLe* zs04tVemh4c;O2oFCvP6U`QYA}n}=>3x_Ro}>zk+UoxJzz-b0vYKpu{ab8UT6B6sse znq%XU|Mp;eT{=^s7VD_oI|*_T$c`fc(Xoy(hoM0R3cZ)7{{8>o_!|_c{4G3Czr6)Ve|0bOXN_A zhMwU6=ZSo zDLC>;IPwWN@o_kEGnFIrUAaB^8W@>k!77>D`5G9b`6e(X@fARA!lXd%W?}gFA5(^b zff-9l!~<3c@;#UVCj=Q77=)12gZ;$7z#zfEz#srug<#0x5NAk@&!{ZOFUiqMX3+C- zHe`VC7}64xigOr>3yVrXA;-Yr1~m#4_8`~%`40h6IKUAE+pWskdcIw!XP#n>lIh#mLw)I=oOa~LFfz^t0*-m zQLiMmqJ%*&C9x!tK`*Jem_e^7AH>m1E-o=NW6(>^&&^HED`C*f%P&dQbN36?EiOq+ z&W7^S^Gfv!it-Cmi%KdP^uXq&X2hozCFZ7rEvK9S`3n@JpfE!=4N^BTFu>v;CWoE| zq@iI5Qx8*T0SZ(G28I<-0d58caH`^f@3 zAHqYBFnutQ2nGfQb_NCplr+h}z_0W(Y_f45RDM z#u5Jypz#ljXHfieLgNZ#7EBzQ-5~i4P)0^dKcMmoBm}b`rXOS`)TtnCa4Z0|Uj;4# aVSwy|uplI;yu+sd2ULF*L>Zh!*AD=iXdJfy literal 0 HcmV?d00001 diff --git a/src/openlibm/src/e_j0.c b/src/openlibm/src/e_j0.c new file mode 100644 index 0000000..a2419d3 --- /dev/null +++ b/src/openlibm/src/e_j0.c @@ -0,0 +1,388 @@ + +/* @(#)e_j0.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/e_j0.c,v 1.9 2008/02/22 02:30:35 das Exp $"); + +/* __ieee754_j0(x), __ieee754_y0(x) + * Bessel function of the first and second kinds of order zero. + * Method -- j0(x): + * 1. For tiny x, we use j0(x) = 1 - x^2/4 + x^4/64 - ... + * 2. Reduce x to |x| since j0(x)=j0(-x), and + * for x in (0,2) + * j0(x) = 1-z/4+ z^2*R0/S0, where z = x*x; + * (precision: |j0-1+z/4-z^2R0/S0 |<2**-63.67 ) + * for x in (2,inf) + * j0(x) = sqrt(2/(pi*x))*(p0(x)*cos(x0)-q0(x)*sin(x0)) + * where x0 = x-pi/4. It is better to compute sin(x0),cos(x0) + * as follow: + * cos(x0) = cos(x)cos(pi/4)+sin(x)sin(pi/4) + * = 1/sqrt(2) * (cos(x) + sin(x)) + * sin(x0) = sin(x)cos(pi/4)-cos(x)sin(pi/4) + * = 1/sqrt(2) * (sin(x) - cos(x)) + * (To avoid cancellation, use + * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x)) + * to compute the worse one.) + * + * 3 Special cases + * j0(nan)= nan + * j0(0) = 1 + * j0(inf) = 0 + * + * Method -- y0(x): + * 1. For x<2. + * Since + * y0(x) = 2/pi*(j0(x)*(ln(x/2)+Euler) + x^2/4 - ...) + * therefore y0(x)-2/pi*j0(x)*ln(x) is an even function. + * We use the following function to approximate y0, + * y0(x) = U(z)/V(z) + (2/pi)*(j0(x)*ln(x)), z= x^2 + * where + * U(z) = u00 + u01*z + ... + u06*z^6 + * V(z) = 1 + v01*z + ... + v04*z^4 + * with absolute approximation error bounded by 2**-72. + * Note: For tiny x, U/V = u0 and j0(x)~1, hence + * y0(tiny) = u0 + (2/pi)*ln(tiny), (choose tiny<2**-27) + * 2. For x>=2. + * y0(x) = sqrt(2/(pi*x))*(p0(x)*cos(x0)+q0(x)*sin(x0)) + * where x0 = x-pi/4. It is better to compute sin(x0),cos(x0) + * by the method mentioned above. + * 3. Special cases: y0(0)=-inf, y0(x<0)=NaN, y0(inf)=0. + */ + +#include + +#include "math_private.h" + +static double pzero(double), qzero(double); + +static const double +huge = 1e300, +one = 1.0, +invsqrtpi= 5.64189583547756279280e-01, /* 0x3FE20DD7, 0x50429B6D */ +tpi = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */ + /* R0/S0 on [0, 2.00] */ +R02 = 1.56249999999999947958e-02, /* 0x3F8FFFFF, 0xFFFFFFFD */ +R03 = -1.89979294238854721751e-04, /* 0xBF28E6A5, 0xB61AC6E9 */ +R04 = 1.82954049532700665670e-06, /* 0x3EBEB1D1, 0x0C503919 */ +R05 = -4.61832688532103189199e-09, /* 0xBE33D5E7, 0x73D63FCE */ +S01 = 1.56191029464890010492e-02, /* 0x3F8FFCE8, 0x82C8C2A4 */ +S02 = 1.16926784663337450260e-04, /* 0x3F1EA6D2, 0xDD57DBF4 */ +S03 = 5.13546550207318111446e-07, /* 0x3EA13B54, 0xCE84D5A9 */ +S04 = 1.16614003333790000205e-09; /* 0x3E1408BC, 0xF4745D8F */ + +static const double zero = 0.0; + +OLM_DLLEXPORT double +__ieee754_j0(double x) +{ + double z, s,c,ss,cc,r,u,v; + int32_t hx,ix; + + GET_HIGH_WORD(hx,x); + ix = hx&0x7fffffff; + if(ix>=0x7ff00000) return one/(x*x); + x = fabs(x); + if(ix >= 0x40000000) { /* |x| >= 2.0 */ + s = sin(x); + c = cos(x); + ss = s-c; + cc = s+c; + if(ix<0x7fe00000) { /* make sure x+x not overflow */ + z = -cos(x+x); + if ((s*c)0x48000000) z = (invsqrtpi*cc)/sqrt(x); + else { + u = pzero(x); v = qzero(x); + z = invsqrtpi*(u*cc-v*ss)/sqrt(x); + } + return z; + } + if(ix<0x3f200000) { /* |x| < 2**-13 */ + if(huge+x>one) { /* raise inexact if x != 0 */ + if(ix<0x3e400000) return one; /* |x|<2**-27 */ + else return one - 0.25*x*x; + } + } + z = x*x; + r = z*(R02+z*(R03+z*(R04+z*R05))); + s = one+z*(S01+z*(S02+z*(S03+z*S04))); + if(ix < 0x3FF00000) { /* |x| < 1.00 */ + return one + z*(-0.25+(r/s)); + } else { + u = 0.5*x; + return((one+u)*(one-u)+z*(r/s)); + } +} + +static const double +u00 = -7.38042951086872317523e-02, /* 0xBFB2E4D6, 0x99CBD01F */ +u01 = 1.76666452509181115538e-01, /* 0x3FC69D01, 0x9DE9E3FC */ +u02 = -1.38185671945596898896e-02, /* 0xBF8C4CE8, 0xB16CFA97 */ +u03 = 3.47453432093683650238e-04, /* 0x3F36C54D, 0x20B29B6B */ +u04 = -3.81407053724364161125e-06, /* 0xBECFFEA7, 0x73D25CAD */ +u05 = 1.95590137035022920206e-08, /* 0x3E550057, 0x3B4EABD4 */ +u06 = -3.98205194132103398453e-11, /* 0xBDC5E43D, 0x693FB3C8 */ +v01 = 1.27304834834123699328e-02, /* 0x3F8A1270, 0x91C9C71A */ +v02 = 7.60068627350353253702e-05, /* 0x3F13ECBB, 0xF578C6C1 */ +v03 = 2.59150851840457805467e-07, /* 0x3E91642D, 0x7FF202FD */ +v04 = 4.41110311332675467403e-10; /* 0x3DFE5018, 0x3BD6D9EF */ + +OLM_DLLEXPORT double +__ieee754_y0(double x) +{ + double z, s,c,ss,cc,u,v; + int32_t hx,ix,lx; + + EXTRACT_WORDS(hx,lx,x); + ix = 0x7fffffff&hx; + /* Y0(NaN) is NaN, y0(-inf) is Nan, y0(inf) is 0 */ + if(ix>=0x7ff00000) return one/(x+x*x); + if((ix|lx)==0) return -one/zero; + if(hx<0) return zero/zero; + if(ix >= 0x40000000) { /* |x| >= 2.0 */ + /* y0(x) = sqrt(2/(pi*x))*(p0(x)*sin(x0)+q0(x)*cos(x0)) + * where x0 = x-pi/4 + * Better formula: + * cos(x0) = cos(x)cos(pi/4)+sin(x)sin(pi/4) + * = 1/sqrt(2) * (sin(x) + cos(x)) + * sin(x0) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4) + * = 1/sqrt(2) * (sin(x) - cos(x)) + * To avoid cancellation, use + * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x)) + * to compute the worse one. + */ + s = sin(x); + c = cos(x); + ss = s-c; + cc = s+c; + /* + * 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<0x7fe00000) { /* make sure x+x not overflow */ + z = -cos(x+x); + if ((s*c)0x48000000) z = (invsqrtpi*ss)/sqrt(x); + else { + u = pzero(x); v = qzero(x); + z = invsqrtpi*(u*ss+v*cc)/sqrt(x); + } + return z; + } + if(ix<=0x3e400000) { /* x < 2**-27 */ + return(u00 + tpi*__ieee754_log(x)); + } + z = x*x; + u = u00+z*(u01+z*(u02+z*(u03+z*(u04+z*(u05+z*u06))))); + v = one+z*(v01+z*(v02+z*(v03+z*v04))); + return(u/v + tpi*(__ieee754_j0(x)*__ieee754_log(x))); +} + +/* The asymptotic expansions 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) + * where R = pR0 + pR1*s^2 + pR2*s^4 + ... + pR5*s^10 + * S = 1 + pS0*s^2 + ... + pS4*s^10 + * and + * | pzero(x)-1-R/S | <= 2 ** ( -60.26) + */ +static const double pR8[6] = { /* for x in [inf, 8]=1/[0,0.125] */ + 0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */ + -7.03124999999900357484e-02, /* 0xBFB1FFFF, 0xFFFFFD32 */ + -8.08167041275349795626e+00, /* 0xC02029D0, 0xB44FA779 */ + -2.57063105679704847262e+02, /* 0xC0701102, 0x7B19E863 */ + -2.48521641009428822144e+03, /* 0xC0A36A6E, 0xCD4DCAFC */ + -5.25304380490729545272e+03, /* 0xC0B4850B, 0x36CC643D */ +}; +static const double pS8[5] = { + 1.16534364619668181717e+02, /* 0x405D2233, 0x07A96751 */ + 3.83374475364121826715e+03, /* 0x40ADF37D, 0x50596938 */ + 4.05978572648472545552e+04, /* 0x40E3D2BB, 0x6EB6B05F */ + 1.16752972564375915681e+05, /* 0x40FC810F, 0x8F9FA9BD */ + 4.76277284146730962675e+04, /* 0x40E74177, 0x4F2C49DC */ +}; + +static const double pR5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */ + -1.14125464691894502584e-11, /* 0xBDA918B1, 0x47E495CC */ + -7.03124940873599280078e-02, /* 0xBFB1FFFF, 0xE69AFBC6 */ + -4.15961064470587782438e+00, /* 0xC010A370, 0xF90C6BBF */ + -6.76747652265167261021e+01, /* 0xC050EB2F, 0x5A7D1783 */ + -3.31231299649172967747e+02, /* 0xC074B3B3, 0x6742CC63 */ + -3.46433388365604912451e+02, /* 0xC075A6EF, 0x28A38BD7 */ +}; +static const double pS5[5] = { + 6.07539382692300335975e+01, /* 0x404E6081, 0x0C98C5DE */ + 1.05125230595704579173e+03, /* 0x40906D02, 0x5C7E2864 */ + 5.97897094333855784498e+03, /* 0x40B75AF8, 0x8FBE1D60 */ + 9.62544514357774460223e+03, /* 0x40C2CCB8, 0xFA76FA38 */ + 2.40605815922939109441e+03, /* 0x40A2CC1D, 0xC70BE864 */ +}; + +static const double pR3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */ + -2.54704601771951915620e-09, /* 0xBE25E103, 0x6FE1AA86 */ + -7.03119616381481654654e-02, /* 0xBFB1FFF6, 0xF7C0E24B */ + -2.40903221549529611423e+00, /* 0xC00345B2, 0xAEA48074 */ + -2.19659774734883086467e+01, /* 0xC035F74A, 0x4CB94E14 */ + -5.80791704701737572236e+01, /* 0xC04D0A22, 0x420A1A45 */ + -3.14479470594888503854e+01, /* 0xC03F72AC, 0xA892D80F */ +}; +static const double pS3[5] = { + 3.58560338055209726349e+01, /* 0x4041ED92, 0x84077DD3 */ + 3.61513983050303863820e+02, /* 0x40769839, 0x464A7C0E */ + 1.19360783792111533330e+03, /* 0x4092A66E, 0x6D1061D6 */ + 1.12799679856907414432e+03, /* 0x40919FFC, 0xB8C39B7E */ + 1.73580930813335754692e+02, /* 0x4065B296, 0xFC379081 */ +}; + +static const double pR2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */ + -8.87534333032526411254e-08, /* 0xBE77D316, 0xE927026D */ + -7.03030995483624743247e-02, /* 0xBFB1FF62, 0x495E1E42 */ + -1.45073846780952986357e+00, /* 0xBFF73639, 0x8A24A843 */ + -7.63569613823527770791e+00, /* 0xC01E8AF3, 0xEDAFA7F3 */ + -1.11931668860356747786e+01, /* 0xC02662E6, 0xC5246303 */ + -3.23364579351335335033e+00, /* 0xC009DE81, 0xAF8FE70F */ +}; +static const double pS2[5] = { + 2.22202997532088808441e+01, /* 0x40363865, 0x908B5959 */ + 1.36206794218215208048e+02, /* 0x4061069E, 0x0EE8878F */ + 2.70470278658083486789e+02, /* 0x4070E786, 0x42EA079B */ + 1.53875394208320329881e+02, /* 0x40633C03, 0x3AB6FAFF */ + 1.46576176948256193810e+01, /* 0x402D50B3, 0x44391809 */ +}; + + /* Note: This function is only called for ix>=0x40000000 (see above) */ + static double pzero(double x) +{ + const double *p,*q; + double z,r,s; + int32_t ix; + GET_HIGH_WORD(ix,x); + ix &= 0x7fffffff; + assert(ix>=0x40000000 && ix<=0x48000000); + if(ix>=0x40200000) {p = pR8; q= pS8;} + else if(ix>=0x40122E8B){p = pR5; q= pS5;} + else if(ix>=0x4006DB6D){p = pR3; q= pS3;} + else {p = pR2; q= pS2;} + z = one/(x*x); + r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5])))); + s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*q[4])))); + return one+ r/s; +} + + +/* For x >= 8, the asymptotic expansions 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)) + * where R = qR0 + qR1*s^2 + qR2*s^4 + ... + qR5*s^10 + * S = 1 + qS0*s^2 + ... + qS5*s^12 + * and + * | qzero(x)/s +1.25-R/S | <= 2 ** ( -61.22) + */ +static const double qR8[6] = { /* for x in [inf, 8]=1/[0,0.125] */ + 0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */ + 7.32421874999935051953e-02, /* 0x3FB2BFFF, 0xFFFFFE2C */ + 1.17682064682252693899e+01, /* 0x40278952, 0x5BB334D6 */ + 5.57673380256401856059e+02, /* 0x40816D63, 0x15301825 */ + 8.85919720756468632317e+03, /* 0x40C14D99, 0x3E18F46D */ + 3.70146267776887834771e+04, /* 0x40E212D4, 0x0E901566 */ +}; +static const double qS8[6] = { + 1.63776026895689824414e+02, /* 0x406478D5, 0x365B39BC */ + 8.09834494656449805916e+03, /* 0x40BFA258, 0x4E6B0563 */ + 1.42538291419120476348e+05, /* 0x41016652, 0x54D38C3F */ + 8.03309257119514397345e+05, /* 0x412883DA, 0x83A52B43 */ + 8.40501579819060512818e+05, /* 0x4129A66B, 0x28DE0B3D */ + -3.43899293537866615225e+05, /* 0xC114FD6D, 0x2C9530C5 */ +}; + +static const double qR5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */ + 1.84085963594515531381e-11, /* 0x3DB43D8F, 0x29CC8CD9 */ + 7.32421766612684765896e-02, /* 0x3FB2BFFF, 0xD172B04C */ + 5.83563508962056953777e+00, /* 0x401757B0, 0xB9953DD3 */ + 1.35111577286449829671e+02, /* 0x4060E392, 0x0A8788E9 */ + 1.02724376596164097464e+03, /* 0x40900CF9, 0x9DC8C481 */ + 1.98997785864605384631e+03, /* 0x409F17E9, 0x53C6E3A6 */ +}; +static const double qS5[6] = { + 8.27766102236537761883e+01, /* 0x4054B1B3, 0xFB5E1543 */ + 2.07781416421392987104e+03, /* 0x40A03BA0, 0xDA21C0CE */ + 1.88472887785718085070e+04, /* 0x40D267D2, 0x7B591E6D */ + 5.67511122894947329769e+04, /* 0x40EBB5E3, 0x97E02372 */ + 3.59767538425114471465e+04, /* 0x40E19118, 0x1F7A54A0 */ + -5.35434275601944773371e+03, /* 0xC0B4EA57, 0xBEDBC609 */ +}; + +static const double qR3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */ + 4.37741014089738620906e-09, /* 0x3E32CD03, 0x6ADECB82 */ + 7.32411180042911447163e-02, /* 0x3FB2BFEE, 0x0E8D0842 */ + 3.34423137516170720929e+00, /* 0x400AC0FC, 0x61149CF5 */ + 4.26218440745412650017e+01, /* 0x40454F98, 0x962DAEDD */ + 1.70808091340565596283e+02, /* 0x406559DB, 0xE25EFD1F */ + 1.66733948696651168575e+02, /* 0x4064D77C, 0x81FA21E0 */ +}; +static const double qS3[6] = { + 4.87588729724587182091e+01, /* 0x40486122, 0xBFE343A6 */ + 7.09689221056606015736e+02, /* 0x40862D83, 0x86544EB3 */ + 3.70414822620111362994e+03, /* 0x40ACF04B, 0xE44DFC63 */ + 6.46042516752568917582e+03, /* 0x40B93C6C, 0xD7C76A28 */ + 2.51633368920368957333e+03, /* 0x40A3A8AA, 0xD94FB1C0 */ + -1.49247451836156386662e+02, /* 0xC062A7EB, 0x201CF40F */ +}; + +static const double qR2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */ + 1.50444444886983272379e-07, /* 0x3E84313B, 0x54F76BDB */ + 7.32234265963079278272e-02, /* 0x3FB2BEC5, 0x3E883E34 */ + 1.99819174093815998816e+00, /* 0x3FFFF897, 0xE727779C */ + 1.44956029347885735348e+01, /* 0x402CFDBF, 0xAAF96FE5 */ + 3.16662317504781540833e+01, /* 0x403FAA8E, 0x29FBDC4A */ + 1.62527075710929267416e+01, /* 0x403040B1, 0x71814BB4 */ +}; +static const double qS2[6] = { + 3.03655848355219184498e+01, /* 0x403E5D96, 0xF7C07AED */ + 2.69348118608049844624e+02, /* 0x4070D591, 0xE4D14B40 */ + 8.44783757595320139444e+02, /* 0x408A6645, 0x22B3BF22 */ + 8.82935845112488550512e+02, /* 0x408B977C, 0x9C5CC214 */ + 2.12666388511798828631e+02, /* 0x406A9553, 0x0E001365 */ + -5.31095493882666946917e+00, /* 0xC0153E6A, 0xF8B32931 */ +}; + + /* Note: This function is only called for ix>=0x40000000 (see above) */ + static double qzero(double x) +{ + const double *p,*q; + double s,r,z; + int32_t ix; + GET_HIGH_WORD(ix,x); + ix &= 0x7fffffff; + assert(ix>=0x40000000 && ix<=0x48000000); + if(ix>=0x40200000) {p = qR8; q= qS8;} + else if(ix>=0x40122E8B){p = qR5; q= qS5;} + else if(ix>=0x4006DB6D){p = qR3; q= qS3;} + else {p = qR2; q= qS2;} + z = one/(x*x); + r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5])))); + s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5]))))); + return (-.125 + r/s)/x; +} diff --git a/src/openlibm/src/e_j0.c.o b/src/openlibm/src/e_j0.c.o new file mode 100644 index 0000000000000000000000000000000000000000..9c73d5c3e15ec99948f9ee94732c9c66be4dee1d GIT binary patch literal 13280 zcmb<-^>JfjWMqH=Mg}_u1P><4z>uJiU^{@B4h%vJf(&UM{B;LB4!%%O{r~@eeeVPY z28IKTzZe)8IQZLbm>3vr|NobF;BR}&z`*dygfB*mU z%R3+3w+T=+G9KocP- zVS}6tHV7jTf4wnrJwtsplSV+BY))mG=7bDpZMcm zf8vjPij)lRA|=DCpi~7*hG#$VN5GTe*-!kDM?tcuLBx?y{E=rt3{X-8GeAiZ%m5`t zkk0d9CHxWRAW1R?;z~#UxZ{V@CP30=)HZp!Y6)+K9EPFW1%VcA;`;z!R6>D{z!1C1(FBJ zM#rY{YaIT>A93Upf6U`g{E-hn@kgMj7j#kK0Ef~iet{Sjj!*o8EGi&9FfkPsklpv| z;nFTD0-yLJ9`LtcU|;}+!{JZ-f+;EzpZFsV!}OS_r18Ih`-xw`M@1lwKOB;yz{aQX zYh3%pF922_c`=P&{}q4x28cNqKJmw0Y5dE;z~E6{0dfJ%T)_~Kje;>M9543%`2Qd7 z5U4vfe}l!qil7FosK69OUVxYs^XL9?fqQ8XtpFZsTuI zs^xE2XJlaDyush{pMim)^%8$aI3okY_d}5M8O_MR(D<8y!NHEdO`Z`Pz&8*HP0$Av z6p%=i6&0AdL%RB4#85&L0Djd-3CfdpjH7?FwzB- zq#~gXj9^jmXg;D44a%G?pehNJ6~S_8{O?bK%3r9o9=|+H9@J8aI04IuV0n;2kP$8n z3@~fJhQNIMdS@C;e;WV$10X%0_~Q;lA5NR_i67)Zs4f8?kmDff9qtPe6;L#R(>p{O zoZe$Dz|-l$PyB)*;PejHqXJ9sF(~OBtUvN`8o&M<{`N(nx`RJL29&u#N&PY?mKi+C zK^YWoq+kpveg%D0I9^=(3QpEwGhj}%gC&1~Py7O4H$;knk~&xsC{;vU{=^>%O#y-; zDzAA_xJdCL0MZu+${dGYc7V%%Sa^fX1r?Z|_~UN9jQIcme{oT=erkM{fnG8L14Cwo zovlHIi2(#CsHrJrR@i_%br=}VDYQ$*N!uX91>*r_5X<4?vSEU7sHf0!Qp!MVvYC9 zN)IHTaZ2C3x#U2zcx{ya>wp9Mvw40NEEYI$?Dwo^AoK1Wox#(X;OB5=>J#^k5-ayM zPB8y7ZBwd4-R#3V{>-1~a4k_FH*eV_2fi9FH_I7i4*WMJtyoiJf526W%SnmL_kf7s zP9LxDrUyzImaN<4%6!24(Sh&Z{%_oWxt6_U(pyJ|wp9=FnIEd|_!Md*=3?iUHWnZ5@dR3!{VlXDv#u9<9( z4(e2Q(E0cO|Ns4)?Dtqkn_aC)ao{|5dtdmgEe95aRLM(BeCSZ5{9yXyt*;$&ns}gd-KK+hnqcTH2ZD0*z$joQFy&P>A-=F{x?^xSnQyYb^Lmc%}$5pKfX`AKdf=s z>=)A3tlQ@BK=D^&&Gi%q`M+_GZbzm%++C+TZHB+A!`C??iGL1oIXH3j^1a)?$$pvh zpQL2~&&7@V z>|P#|+P3tWhCMhr|L?c&k1hGKheO0}<<*vRA=V4+zT6JKduf@R{gOi`nqK_rw}+VX z07`$@-+ba^u0i}0d-)5eXI^`<$^OJ<`%K#>NB3S??Pnd%5NfwJ=2G$Uf9LJ8XKzyQ zJ!)n@{a4P$7d}1qe;&V_%Q*L#{rj8OtR({e+5TnvRIi&d(eB`}im$uh2-`~?KRK~L zs0(Tj#8w6dh6Xsx-PzenLBriIR8zswM9)aiP{GK+$kf2l&_F>WC^bdFBe4W3p=++m zz`(-5z@WguzyK3ujfW%;ZWJV~T6Ka77lxD07VqmNgV3g)z=a|6AzyK1L zfy&h|F)%PN$1?E=K*UX;;%mU-y@tGOeK@0MiHp)T#i5!vTa4 zm<4e+2c&%j7J(4!z!V3=2QZBwwt$%&3_rj$g4hLSaxesdX#@eWkAoosAp~X}1CtyK z1z;LMoB=aA7$D&a=75PyV3Gr=zyS+D!-a#P1Hy%qpdL8LzX@;=2;&Ku;$VQpKbQk1 zUV%vt21s~=IbZ_fe-4HjU><__24-?FECAC8;t!a~0m^(}7K~s5ryC9i4loT9Wq|TI z7!=UN`M`V*1`RNcP%i@Jb1)cyX@odvCYI@BCEiB4u%FW4HAK12%m#t1Dbdnn9sqm08B&Fg2)~)pM&8Bw0s7M zf$$`#xCELw#6KJi3TWcU!i z2yrf`_zg610jM~{9)x-^s5l3hMu^LR`5X)oeF$+SsCWgKMuo;3>&~SLL8F*I2aC~iMxUM91I;`8lm0?%;#X30HzV* zL0~=y!wfKu5Qn524u&0Q;&EU;2g3<4jZmKg=5sJy0MiKZEHIyg;RTpRh(ppD2g3(6 z@iH)HDFj%08Zvm@^wYnj02a&tL;v5VQz%)n%f+6wB!O($b&T+6h4u%Lc z@pDk|1T^uhQ1J<9;&-6p8EE2p#9u+h3(&+rLd6%Li9_OvgP{UV{6AEE1DZG+ zn9sow0Hz^f03vz8d=3T=FbxucU=c8%gTVnzL&QL&G&2K6TNNa($;`kY#K6d40IfP9 z@x;KOgG0R`4slZ);+8nX?V$EPfHw8P{Tc=a21gv~8K5IQkO7?d_<$hSkdVlDw@^Rl z5Kn)<_;@`-=nxM!IRgegA7?OO2x6Il2vZPY1|rNsgb|1^1`!q@!V*N7fTfMVQbu4o zBZvq@2UwvISfvrzNF%VB#$bz#!8RF#^%{cNh7dMbjUm_^L$Eo9U~>$?<{N^|F@%^2 zHpd98*BC5o43;$p>oNxGG6t(O0jo3yn`{g=*#xZ11Z<-TSg#3KuL)R<3D^V^unDGM zHKt%SreHOu5EH;An}SU?1)F9H)@2Gd!4j;}94u=NmNf^9n}hY5gH@V?O)v+WZw@x! z9HI+suLW4I1z4{sSi}^p-VChL46M=&Y^E95G&8VzGq8Fyu$g9HyUf6P&A@ssz~UBQ z6D+{GEWolBU|CDBUJJ0v7GRStz$RFNO|}Hoqih2!V|-Gyv;1GyrQc zGyt1oXaF|Y&;V?jp#j(+Lj#BzU=@}S8EAAvQv)o{g9Y9geC(ch&6^_Lkyv5 z#t z!}_ngT@eG;;?=i$UXc>=2Rk?59)iv)HflC3nHoSLlPH464!^e zdqCz3BZ))$7Z7)X#(H4p!}=#6^`LQVm^iF|0umQPG6&L+fS4nWBo6D(gVakPi69A`T`#6-itU$s9;~9^!s^B=KcP>Oo^G zFmu)+i7O(hhqT)v<|rYF??Y0rj3j;>NgOnG1T!Djeg%b_Dw6t}Nb1#)#2+Dvt0RfO zMiSRR690=Nu8Abh2C@*EK0#wvF!%5wiEAUNhqRL+{?$PemqStyT3rA$M-53_4@tc~ zk~nC|4op3)KLe5m(L#Ep@}Vf`+UG^lC@(V#2@T7vG}2L2H;e zKeQbN(gqsCgo(=_i6fUwOOV7Jk=%0}N!$rZ`~s4=Gm`iXBykrc@drraps`b!dtM-k zgUWoE_y;6$cO-LuB8h{>E@A4KKoJfNe@`U!+(_b}v00dU5hQVMB=s^#;-K+!n0i$t zabG0$rbyzTx(TM<4oMs|_6rktLlOs#A;QG{ki-L#%nw5n4?+@;LlO^05>H1G2aPSm z%r8I^4@FX6i6joHLt*Nhki^50)OR6?gT^{x>L(+KgT}65;!Balqmay5ha?`2B)$zv zJO)X8ACh=1lK3$saZp_kv-cd5cs!E&>qz3DF;kfO2T0vq9ArImxd&Nm0x=&s zzZW8@2en~f_I5(WLGDCWKNCqj4axnRk;Fl5DwsJJki&q5Oa zf+U`eBo3Rn0l6~=Nt_2dCLH4#Hsb2yW2bqJc zeiKw2UA-l!Q4Te~7|9%OB=Hg?@o*&ZQY7(YB=IsN@q8rlawPF;ByrGO2+UvYNaCQj zH%xpol6V!8IrEXktC7T4BZ(uY=j}-1HAw0YBZ=1{iC=|^gTk#5N&FR(csr8#52!dO z{6TYMF!zgqIyumAu18XDgCvgZ&OoR*$X;agBcbBx<|iVFBfGyHDh@ISIepGX5=Ty- z=W&QXgNlRfMNXfopiUapU&!gL1c!JNR2<|UAUi;85C*luKr~1Ugkj^j zpgI&;95$Xb1tbV{4@f<1yoW)rxH7jSF^NI1xTFX|XTVrRsX2*yC8-r940*{WddbBla6u5q(2PMZIX^cyHLrw0FE76&RnOfoRJXV! zF*zH`PtPmWD=5k@NG&RYRv3CMm>9|U3|goN1-8bg4HKuC~U5DP|w{0(BG z>t}#!1ob&V>R}k9SN%OL%rJ|Dz@aj z%L1)Lh04RI08poyfq? +#include "cdefs-compat.h" + +#include +#include "math_private.h" + +static float pzerof(float), qzerof(float); + +static const float +huge = 1e30, +one = 1.0, +invsqrtpi= 5.6418961287e-01, /* 0x3f106ebb */ +tpi = 6.3661974669e-01, /* 0x3f22f983 */ + /* R0/S0 on [0, 2.00] */ +R02 = 1.5625000000e-02, /* 0x3c800000 */ +R03 = -1.8997929874e-04, /* 0xb947352e */ +R04 = 1.8295404516e-06, /* 0x35f58e88 */ +R05 = -4.6183270541e-09, /* 0xb19eaf3c */ +S01 = 1.5619102865e-02, /* 0x3c7fe744 */ +S02 = 1.1692678527e-04, /* 0x38f53697 */ +S03 = 5.1354652442e-07, /* 0x3509daa6 */ +S04 = 1.1661400734e-09; /* 0x30a045e8 */ + +static const float zero = 0.0; + +OLM_DLLEXPORT float +__ieee754_j0f(float x) +{ + float z, s,c,ss,cc,r,u,v; + int32_t hx,ix; + + GET_FLOAT_WORD(hx,x); + ix = hx&0x7fffffff; + if(ix>=0x7f800000) return one/(x*x); + x = fabsf(x); + if(ix >= 0x40000000) { /* |x| >= 2.0 */ + s = sinf(x); + c = cosf(x); + ss = s-c; + cc = s+c; + if(ix<0x7f000000) { /* make sure x+x not overflow */ + z = -cosf(x+x); + if ((s*c)0x58000000) z = (invsqrtpi*cc)/sqrtf(x); /* |x|>2**49 */ + else { + u = pzerof(x); v = qzerof(x); + z = invsqrtpi*(u*cc-v*ss)/sqrtf(x); + } + return z; + } + if(ix<0x3b000000) { /* |x| < 2**-9 */ + if(huge+x>one) { /* raise inexact if x != 0 */ + if(ix<0x39800000) return one; /* |x|<2**-12 */ + else return one - x*x/4; + } + } + z = x*x; + r = z*(R02+z*(R03+z*(R04+z*R05))); + s = one+z*(S01+z*(S02+z*(S03+z*S04))); + if(ix < 0x3F800000) { /* |x| < 1.00 */ + return one + z*((float)-0.25+(r/s)); + } else { + u = (float)0.5*x; + return((one+u)*(one-u)+z*(r/s)); + } +} + +static const float +u00 = -7.3804296553e-02, /* 0xbd9726b5 */ +u01 = 1.7666645348e-01, /* 0x3e34e80d */ +u02 = -1.3818567619e-02, /* 0xbc626746 */ +u03 = 3.4745343146e-04, /* 0x39b62a69 */ +u04 = -3.8140706238e-06, /* 0xb67ff53c */ +u05 = 1.9559013964e-08, /* 0x32a802ba */ +u06 = -3.9820518410e-11, /* 0xae2f21eb */ +v01 = 1.2730483897e-02, /* 0x3c509385 */ +v02 = 7.6006865129e-05, /* 0x389f65e0 */ +v03 = 2.5915085189e-07, /* 0x348b216c */ +v04 = 4.4111031494e-10; /* 0x2ff280c2 */ + +OLM_DLLEXPORT float +__ieee754_y0f(float x) +{ + float z, s,c,ss,cc,u,v; + int32_t hx,ix; + + GET_FLOAT_WORD(hx,x); + ix = 0x7fffffff&hx; + /* Y0(NaN) is NaN, y0(-inf) is Nan, y0(inf) is 0 */ + if(ix>=0x7f800000) return one/(x+x*x); + if(ix==0) return -one/zero; + if(hx<0) return zero/zero; + if(ix >= 0x40000000) { /* |x| >= 2.0 */ + /* y0(x) = sqrt(2/(pi*x))*(p0(x)*sin(x0)+q0(x)*cos(x0)) + * where x0 = x-pi/4 + * Better formula: + * cos(x0) = cos(x)cos(pi/4)+sin(x)sin(pi/4) + * = 1/sqrt(2) * (sin(x) + cos(x)) + * sin(x0) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4) + * = 1/sqrt(2) * (sin(x) - cos(x)) + * To avoid cancellation, use + * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x)) + * to compute the worse one. + */ + s = sinf(x); + c = cosf(x); + ss = s-c; + cc = s+c; + /* + * 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)0x58000000) z = (invsqrtpi*ss)/sqrtf(x); /* |x|>2**49 */ + else { + u = pzerof(x); v = qzerof(x); + z = invsqrtpi*(u*ss+v*cc)/sqrtf(x); + } + return z; + } + if(ix<=0x39000000) { /* x < 2**-13 */ + return(u00 + tpi*__ieee754_logf(x)); + } + z = x*x; + u = u00+z*(u01+z*(u02+z*(u03+z*(u04+z*(u05+z*u06))))); + v = one+z*(v01+z*(v02+z*(v03+z*v04))); + return(u/v + tpi*(__ieee754_j0f(x)*__ieee754_logf(x))); +} + +/* The asymptotic expansions 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) + * where R = pR0 + pR1*s^2 + pR2*s^4 + ... + pR5*s^10 + * S = 1 + pS0*s^2 + ... + pS4*s^10 + * and + * | pzero(x)-1-R/S | <= 2 ** ( -60.26) + */ +static const float pR8[6] = { /* for x in [inf, 8]=1/[0,0.125] */ + 0.0000000000e+00, /* 0x00000000 */ + -7.0312500000e-02, /* 0xbd900000 */ + -8.0816707611e+00, /* 0xc1014e86 */ + -2.5706311035e+02, /* 0xc3808814 */ + -2.4852163086e+03, /* 0xc51b5376 */ + -5.2530439453e+03, /* 0xc5a4285a */ +}; +static const float pS8[5] = { + 1.1653436279e+02, /* 0x42e91198 */ + 3.8337448730e+03, /* 0x456f9beb */ + 4.0597855469e+04, /* 0x471e95db */ + 1.1675296875e+05, /* 0x47e4087c */ + 4.7627726562e+04, /* 0x473a0bba */ +}; +static const float pR5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */ + -1.1412546255e-11, /* 0xad48c58a */ + -7.0312492549e-02, /* 0xbd8fffff */ + -4.1596107483e+00, /* 0xc0851b88 */ + -6.7674766541e+01, /* 0xc287597b */ + -3.3123129272e+02, /* 0xc3a59d9b */ + -3.4643338013e+02, /* 0xc3ad3779 */ +}; +static const float pS5[5] = { + 6.0753936768e+01, /* 0x42730408 */ + 1.0512523193e+03, /* 0x44836813 */ + 5.9789707031e+03, /* 0x45bad7c4 */ + 9.6254453125e+03, /* 0x461665c8 */ + 2.4060581055e+03, /* 0x451660ee */ +}; + +static const float pR3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */ + -2.5470459075e-09, /* 0xb12f081b */ + -7.0311963558e-02, /* 0xbd8fffb8 */ + -2.4090321064e+00, /* 0xc01a2d95 */ + -2.1965976715e+01, /* 0xc1afba52 */ + -5.8079170227e+01, /* 0xc2685112 */ + -3.1447946548e+01, /* 0xc1fb9565 */ +}; +static const float pS3[5] = { + 3.5856033325e+01, /* 0x420f6c94 */ + 3.6151397705e+02, /* 0x43b4c1ca */ + 1.1936077881e+03, /* 0x44953373 */ + 1.1279968262e+03, /* 0x448cffe6 */ + 1.7358093262e+02, /* 0x432d94b8 */ +}; + +static const float pR2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */ + -8.8753431271e-08, /* 0xb3be98b7 */ + -7.0303097367e-02, /* 0xbd8ffb12 */ + -1.4507384300e+00, /* 0xbfb9b1cc */ + -7.6356959343e+00, /* 0xc0f4579f */ + -1.1193166733e+01, /* 0xc1331736 */ + -3.2336456776e+00, /* 0xc04ef40d */ +}; +static const float pS2[5] = { + 2.2220300674e+01, /* 0x41b1c32d */ + 1.3620678711e+02, /* 0x430834f0 */ + 2.7047027588e+02, /* 0x43873c32 */ + 1.5387539673e+02, /* 0x4319e01a */ + 1.4657617569e+01, /* 0x416a859a */ +}; + + static float pzerof(float x) +{ + const float *p,*q; + float z,r,s; + int32_t ix; + GET_FLOAT_WORD(ix,x); + ix &= 0x7fffffff; + if(ix>=0x41000000) {p = pR8; q= pS8;} + else if(ix>=0x409173eb){p = pR5; q= pS5;} + else if(ix>=0x4036d917){p = pR3; q= pS3;} + else {p = pR2; q= pS2;} /* ix>=0x40000000 */ + z = one/(x*x); + r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5])))); + s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*q[4])))); + return one+ r/s; +} + + +/* For x >= 8, the asymptotic expansions 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)) + * where R = qR0 + qR1*s^2 + qR2*s^4 + ... + qR5*s^10 + * S = 1 + qS0*s^2 + ... + qS5*s^12 + * and + * | qzero(x)/s +1.25-R/S | <= 2 ** ( -61.22) + */ +static const float qR8[6] = { /* for x in [inf, 8]=1/[0,0.125] */ + 0.0000000000e+00, /* 0x00000000 */ + 7.3242187500e-02, /* 0x3d960000 */ + 1.1768206596e+01, /* 0x413c4a93 */ + 5.5767340088e+02, /* 0x440b6b19 */ + 8.8591972656e+03, /* 0x460a6cca */ + 3.7014625000e+04, /* 0x471096a0 */ +}; +static const float qS8[6] = { + 1.6377603149e+02, /* 0x4323c6aa */ + 8.0983447266e+03, /* 0x45fd12c2 */ + 1.4253829688e+05, /* 0x480b3293 */ + 8.0330925000e+05, /* 0x49441ed4 */ + 8.4050156250e+05, /* 0x494d3359 */ + -3.4389928125e+05, /* 0xc8a7eb69 */ +}; + +static const float qR5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */ + 1.8408595828e-11, /* 0x2da1ec79 */ + 7.3242180049e-02, /* 0x3d95ffff */ + 5.8356351852e+00, /* 0x40babd86 */ + 1.3511157227e+02, /* 0x43071c90 */ + 1.0272437744e+03, /* 0x448067cd */ + 1.9899779053e+03, /* 0x44f8bf4b */ +}; +static const float qS5[6] = { + 8.2776611328e+01, /* 0x42a58da0 */ + 2.0778142090e+03, /* 0x4501dd07 */ + 1.8847289062e+04, /* 0x46933e94 */ + 5.6751113281e+04, /* 0x475daf1d */ + 3.5976753906e+04, /* 0x470c88c1 */ + -5.3543427734e+03, /* 0xc5a752be */ +}; + +static const float qR3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */ + 4.3774099900e-09, /* 0x3196681b */ + 7.3241114616e-02, /* 0x3d95ff70 */ + 3.3442313671e+00, /* 0x405607e3 */ + 4.2621845245e+01, /* 0x422a7cc5 */ + 1.7080809021e+02, /* 0x432acedf */ + 1.6673394775e+02, /* 0x4326bbe4 */ +}; +static const float qS3[6] = { + 4.8758872986e+01, /* 0x42430916 */ + 7.0968920898e+02, /* 0x44316c1c */ + 3.7041481934e+03, /* 0x4567825f */ + 6.4604252930e+03, /* 0x45c9e367 */ + 2.5163337402e+03, /* 0x451d4557 */ + -1.4924745178e+02, /* 0xc3153f59 */ +}; + +static const float qR2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */ + 1.5044444979e-07, /* 0x342189db */ + 7.3223426938e-02, /* 0x3d95f62a */ + 1.9981917143e+00, /* 0x3fffc4bf */ + 1.4495602608e+01, /* 0x4167edfd */ + 3.1666231155e+01, /* 0x41fd5471 */ + 1.6252708435e+01, /* 0x4182058c */ +}; +static const float qS2[6] = { + 3.0365585327e+01, /* 0x41f2ecb8 */ + 2.6934811401e+02, /* 0x4386ac8f */ + 8.4478375244e+02, /* 0x44533229 */ + 8.8293585205e+02, /* 0x445cbbe5 */ + 2.1266638184e+02, /* 0x4354aa98 */ + -5.3109550476e+00, /* 0xc0a9f358 */ +}; + + static float qzerof(float x) +{ + const float *p,*q; + float s,r,z; + int32_t ix; + GET_FLOAT_WORD(ix,x); + ix &= 0x7fffffff; + if(ix>=0x41000000) {p = qR8; q= qS8;} + else if(ix>=0x409173eb){p = qR5; q= qS5;} + else if(ix>=0x4036d917){p = qR3; q= qS3;} + else {p = qR2; q= qS2;} /* ix>=0x40000000 */ + z = one/(x*x); + r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5])))); + s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5]))))); + return (-(float).125 + r/s)/x; +} diff --git a/src/openlibm/src/e_j0f.c.o b/src/openlibm/src/e_j0f.c.o new file mode 100644 index 0000000000000000000000000000000000000000..36db65a17bb399958e7e2ce9ff61b194731238fe GIT binary patch literal 11968 zcmb<-^>JfjWMqH=Mg}_u1P><4z`&r5U^{@B4h;MZd<<#)bq7@c|Nmca`~Uxchw=j3 zSH%+@_}g3=85lmh@C%rNl!6$tUI|^@)^Iz zozMIcw?6Yn-s9J}{Fy)E;%ENIYo8tYBd+pmochckd5&M>pd-J=IS>;hd;~g;F!$fF>+(;(u=Xa2~uAO(>j?!1<3~<29y-BSC57>Sz84NWuoiGk*l6eB_Tr6OX|mj;uZslo+mj=8roC zc8-0y;%9z{K9DD)W1-3948O)pevPAG|H9k~Qt+8S@?~@^zsBLu{1Hb!^T&Y7!Xuyg zBVIrhH-LiXGrypV3JW-tKJyF2sIYwI7i3Z4*EkFl(oq4~{l5+_>!QK|HlzI{0|Nut zaKRiEp3nRda4jY(X`nKmU%*F&gFhUSc)@1#Yh3%xF922@d68fL5r6wyuo)LV^T%Cn z{LR3?5K&%+WTapS$S%Pc6_yt^KmY%SI|1Ur%->)kuo|eLIw~+Vkr%+`#Ju{<9|=tw zf;uV)Pk~a(%ZqQh0-m=hwLLnLqB<%aH&7|1&V`;)H9PQ5s8*mIX^673pX=+~&u4kbz;s-Wh@~o!%vgxt>TBb31ZS|NVP8Sc;vxj(V)!F-6z;+5aAwV&kbUrw(p$PM!Mupip4Op`cys z4^GvUIAR z(C_}ex`#J9ZlAGlGXq0|edg=sCnAk~J+H{QcuqFr_BbT;*LA@(0ryimTyB!t+%A*7 zY#bRFrrEAKrtG{gX!+5D9X#%`>to%g*iCk0zsuH+4KgN2{P=?ZF_e){Qp1I zc0un_r^+`AbtCOX4~M(Tx~4xq=^EdZ?kbaG=<;N@n)Cg0TFysnw45HZhdC7dpK2?{ z>Fgw(G0iaI^U4D=R)sh}-5ukiX%y_zzoyN(hqcMEFyyb}-?!~`k~*q{33S;)Z9U}v*_-o}o;ucmsY?v@M;4K^=a7Z@zN#c4X-?5l;# z^LiTw1_pZuhKBvkKb7pas!g|jt*F0l7t;zOo3Hg|nOfT{-O`h6cwd;<9cuWbpQG4q z@*s7-MeF1MkUmf`55nMd0%Cx%yR);Ef`+?asHTFUiJp<3p@NZtk*R^9p@D)%P-=>T zM`8(7Lf2fAfq{jAfkA3ujfW%;Z5Jo7U6KpsGg9wyntO{aatPo(7 z=3(cUz{tQLz`(#D1C=vjf-pd01`sAg2~-T!cX5G=%?61%@(Hvtx$;RgGyCuv#BlLR zxbO)$@^QFwGu`ImlW+ucg1LRT_#|Ax>^N=)kQp6NGY&z`Xl4rLQ($Ic1&A`e43wx+A zgEg4J$^eTeFqeUW!4b@0WdJ2;FcV6+gK1U<4={}&e8Egs1|KkuAcDb6R)zpDjUXby zOi-!=GvGuVn8gZCmtZE8NCwla;B*FNLWvA8%?eMKU@ij#LoS%X${+!z5kwJ~$qG-a zU@ij#Lphki%D@4p5kw7`$;!Y3rV&IVn8^yxJ76Z1Xam!%3@Tt6L3D$etPE?wG=i82 zX0kGbfN2CV9n559hyc?FVlJ4;%8&x45yWCJla&Dy9$*fb0JTRzxjP5ULlEo1Ojd>h zFpVI#f|;xgF<=@&>;^Mg84|!Wf;b3fvNDu_X#{Z`%w%P#0MiKKESSm400~zx2TWWB zldKG=g&70GO{h4ey9(xjiThxZm0<#yMi8JL0m#2o5JF(qYcR>mFat~@h>u_MZ&RsRRXLBfGhaTYL*kO&9!Ss6IMG(tQU%x7iTfDi(+ zlA+>Tz&r$z2^Bwr5CXIEq2edNJOoh+6+eRz0<)^2;#a^t1knf;-+>SUv)ZBJd%!#d z(F+wnfDi(+CPT$}IeyD?k(LB&s?i7$nUZ$T4Z0~J4mCcYUez5`8s z7gYQLn)pGe_#QOz6HxI3XyWIg;w#X^uR+C^po!mwiZ4JDf5ODTAjH7P0Pb`!Fff4o z1PlxeFPI>G3UHt!5$|w_f5svH1BduOsJ#j75W~U!2nGfQCT8sRGNi_58KmhYGZa*% z7Uicg6hbIHA7?{D1`ufkCQZSl8JIK&lNMmo7)+XgNlOrEWB?|?dcjOE3#a!H3Q3DK$3?Ok(sRF5(o9{VdBw9;-J18OdQs4 z0=bhH$s9<35n?YNl6V=CIs8cCtw`daaSoXIlaa&)k<`yd5*I=ehxFSZ_6j43uSQZ2 z8gqe}zZpp!G%yGghqW_7{t`nn=O~hT(AWb^{W&CYP#+m4ejQ0%63Lv$Na9jR;;{B7 z$X;nAaY#EF;xEv+5X}5qX!#FP4;u4;iMJw&%ORNqX)i;}kw+4riliPieg!jU9+J2s zlKSOH;z~&3u=*F|9?)0|%$%J_>Op;ZnD`+ianNKFOdQf~g}74<$^3gr>eZ3NpCO5Z z#)4qxyh9QPHzaW_By;{DiG!91z|^yYJOs^mpfM$wxB!wkX#NByE{PQ^I)gT^Xh>K`GABd52YP;n3i8k2;nhb(r29JgD)<0GU^+MG`kc60buNPsJf#4HX9!XP~ibnEU@CiG$i~ zFmZNJ;}U9bJ(BqVwZXk&l zBB_6ZBo3O3fT{n0Bwmc9{tuEkXp9}Eo&(fqhNi<(B=sUl;-I!GOuYhi%8d2@H78N8B(b~ZGDh9wD|zj&X9y=FH8cY7RCnAptd>4Omg*u+Snj7L48V)c`%#;wf_o8 z5+(>u-ykl?&mbDq)&wa**Y5!8G&5k1g~7rPMuXZ=ApM{|0LVNT4uI+h^%-DdAR43= znFh60U}7L~7_Nuvhw))Fx>`^Y0u_;<@%*AD>h=|GbJ literal 0 HcmV?d00001 diff --git a/src/openlibm/src/e_j1.c b/src/openlibm/src/e_j1.c new file mode 100644 index 0000000..4be57cd --- /dev/null +++ b/src/openlibm/src/e_j1.c @@ -0,0 +1,383 @@ + +/* @(#)e_j1.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/e_j1.c,v 1.9 2008/02/22 02:30:35 das Exp $"); + +/* __ieee754_j1(x), __ieee754_y1(x) + * Bessel function of the first and second kinds of order zero. + * Method -- j1(x): + * 1. For tiny x, we use j1(x) = x/2 - x^3/16 + x^5/384 - ... + * 2. Reduce x to |x| since j1(x)=-j1(-x), and + * for x in (0,2) + * j1(x) = x/2 + x*z*R0/S0, where z = x*x; + * (precision: |j1/x - 1/2 - R0/S0 |<2**-61.51 ) + * for x in (2,inf) + * j1(x) = sqrt(2/(pi*x))*(p1(x)*cos(x1)-q1(x)*sin(x1)) + * y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x1)+q1(x)*cos(x1)) + * where x1 = x-3*pi/4. It is better to compute sin(x1),cos(x1) + * as follow: + * cos(x1) = cos(x)cos(3pi/4)+sin(x)sin(3pi/4) + * = 1/sqrt(2) * (sin(x) - cos(x)) + * sin(x1) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4) + * = -1/sqrt(2) * (sin(x) + cos(x)) + * (To avoid cancellation, use + * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x)) + * to compute the worse one.) + * + * 3 Special cases + * j1(nan)= nan + * j1(0) = 0 + * j1(inf) = 0 + * + * Method -- y1(x): + * 1. screen out x<=0 cases: y1(0)=-inf, y1(x<0)=NaN + * 2. For x<2. + * Since + * y1(x) = 2/pi*(j1(x)*(ln(x/2)+Euler)-1/x-x/2+5/64*x^3-...) + * therefore y1(x)-2/pi*j1(x)*ln(x)-1/x is an odd function. + * We use the following function to approximate y1, + * y1(x) = x*U(z)/V(z) + (2/pi)*(j1(x)*ln(x)-1/x), z= x^2 + * where for x in [0,2] (abs err less than 2**-65.89) + * U(z) = U0[0] + U0[1]*z + ... + U0[4]*z^4 + * V(z) = 1 + v0[0]*z + ... + v0[4]*z^5 + * Note: For tiny x, 1/x dominate y1 and hence + * y1(tiny) = -2/pi/tiny, (choose tiny<2**-54) + * 3. For x>=2. + * y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x1)+q1(x)*cos(x1)) + * where x1 = x-3*pi/4. It is better to compute sin(x1),cos(x1) + * by method mentioned above. + */ + +#include + +#include "math_private.h" + +static double pone(double), qone(double); + +static const double +huge = 1e300, +one = 1.0, +invsqrtpi= 5.64189583547756279280e-01, /* 0x3FE20DD7, 0x50429B6D */ +tpi = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */ + /* R0/S0 on [0,2] */ +r00 = -6.25000000000000000000e-02, /* 0xBFB00000, 0x00000000 */ +r01 = 1.40705666955189706048e-03, /* 0x3F570D9F, 0x98472C61 */ +r02 = -1.59955631084035597520e-05, /* 0xBEF0C5C6, 0xBA169668 */ +r03 = 4.96727999609584448412e-08, /* 0x3E6AAAFA, 0x46CA0BD9 */ +s01 = 1.91537599538363460805e-02, /* 0x3F939D0B, 0x12637E53 */ +s02 = 1.85946785588630915560e-04, /* 0x3F285F56, 0xB9CDF664 */ +s03 = 1.17718464042623683263e-06, /* 0x3EB3BFF8, 0x333F8498 */ +s04 = 5.04636257076217042715e-09, /* 0x3E35AC88, 0xC97DFF2C */ +s05 = 1.23542274426137913908e-11; /* 0x3DAB2ACF, 0xCFB97ED8 */ + +static const double zero = 0.0; + +OLM_DLLEXPORT double +__ieee754_j1(double x) +{ + double z, s,c,ss,cc,r,u,v,y; + int32_t hx,ix; + + GET_HIGH_WORD(hx,x); + ix = hx&0x7fffffff; + if(ix>=0x7ff00000) return one/x; + y = fabs(x); + if(ix >= 0x40000000) { /* |x| >= 2.0 */ + s = sin(y); + c = cos(y); + ss = -s-c; + cc = s-c; + if(ix<0x7fe00000) { /* make sure y+y not overflow */ + z = cos(y+y); + if ((s*c)>zero) cc = z/ss; + else ss = z/cc; + } + /* + * j1(x) = 1/sqrt(pi) * (P(1,x)*cc - Q(1,x)*ss) / sqrt(x) + * y1(x) = 1/sqrt(pi) * (P(1,x)*ss + Q(1,x)*cc) / sqrt(x) + */ + if(ix>0x48000000) z = (invsqrtpi*cc)/sqrt(y); + else { + u = pone(y); v = qone(y); + z = invsqrtpi*(u*cc-v*ss)/sqrt(y); + } + if(hx<0) return -z; + else return z; + } + if(ix<0x3e400000) { /* |x|<2**-27 */ + if(huge+x>one) return 0.5*x;/* inexact if x!=0 necessary */ + } + z = x*x; + r = z*(r00+z*(r01+z*(r02+z*r03))); + s = one+z*(s01+z*(s02+z*(s03+z*(s04+z*s05)))); + r *= x; + return(x*0.5+r/s); +} + +static const double U0[5] = { + -1.96057090646238940668e-01, /* 0xBFC91866, 0x143CBC8A */ + 5.04438716639811282616e-02, /* 0x3FA9D3C7, 0x76292CD1 */ + -1.91256895875763547298e-03, /* 0xBF5F55E5, 0x4844F50F */ + 2.35252600561610495928e-05, /* 0x3EF8AB03, 0x8FA6B88E */ + -9.19099158039878874504e-08, /* 0xBE78AC00, 0x569105B8 */ +}; +static const double V0[5] = { + 1.99167318236649903973e-02, /* 0x3F94650D, 0x3F4DA9F0 */ + 2.02552581025135171496e-04, /* 0x3F2A8C89, 0x6C257764 */ + 1.35608801097516229404e-06, /* 0x3EB6C05A, 0x894E8CA6 */ + 6.22741452364621501295e-09, /* 0x3E3ABF1D, 0x5BA69A86 */ + 1.66559246207992079114e-11, /* 0x3DB25039, 0xDACA772A */ +}; + +OLM_DLLEXPORT double +__ieee754_y1(double x) +{ + double z, s,c,ss,cc,u,v; + int32_t hx,ix,lx; + + EXTRACT_WORDS(hx,lx,x); + ix = 0x7fffffff&hx; + /* if Y1(NaN) is NaN, Y1(-inf) is NaN, Y1(inf) is 0 */ + if(ix>=0x7ff00000) return one/(x+x*x); + if((ix|lx)==0) return -one/zero; + if(hx<0) return zero/zero; + if(ix >= 0x40000000) { /* |x| >= 2.0 */ + s = sin(x); + c = cos(x); + ss = -s-c; + cc = s-c; + if(ix<0x7fe00000) { /* make sure x+x not overflow */ + z = cos(x+x); + if ((s*c)>zero) cc = z/ss; + else ss = z/cc; + } + /* y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x0)+q1(x)*cos(x0)) + * where x0 = x-3pi/4 + * Better formula: + * cos(x0) = cos(x)cos(3pi/4)+sin(x)sin(3pi/4) + * = 1/sqrt(2) * (sin(x) - cos(x)) + * sin(x0) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4) + * = -1/sqrt(2) * (cos(x) + sin(x)) + * To avoid cancellation, use + * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x)) + * to compute the worse one. + */ + if(ix>0x48000000) z = (invsqrtpi*ss)/sqrt(x); + else { + u = pone(x); v = qone(x); + z = invsqrtpi*(u*ss+v*cc)/sqrt(x); + } + return z; + } + if(ix<=0x3c900000) { /* x < 2**-54 */ + return(-tpi/x); + } + z = x*x; + u = U0[0]+z*(U0[1]+z*(U0[2]+z*(U0[3]+z*U0[4]))); + v = one+z*(V0[0]+z*(V0[1]+z*(V0[2]+z*(V0[3]+z*V0[4])))); + return(x*(u/v) + tpi*(__ieee754_j1(x)*__ieee754_log(x)-one/x)); +} + +/* For x >= 8, the asymptotic expansions of pone is + * 1 + 15/128 s^2 - 4725/2^15 s^4 - ..., where s = 1/x. + * We approximate pone by + * pone(x) = 1 + (R/S) + * where R = pr0 + pr1*s^2 + pr2*s^4 + ... + pr5*s^10 + * S = 1 + ps0*s^2 + ... + ps4*s^10 + * and + * | pone(x)-1-R/S | <= 2 ** ( -60.06) + */ + +static const double pr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */ + 0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */ + 1.17187499999988647970e-01, /* 0x3FBDFFFF, 0xFFFFFCCE */ + 1.32394806593073575129e+01, /* 0x402A7A9D, 0x357F7FCE */ + 4.12051854307378562225e+02, /* 0x4079C0D4, 0x652EA590 */ + 3.87474538913960532227e+03, /* 0x40AE457D, 0xA3A532CC */ + 7.91447954031891731574e+03, /* 0x40BEEA7A, 0xC32782DD */ +}; +static const double ps8[5] = { + 1.14207370375678408436e+02, /* 0x405C8D45, 0x8E656CAC */ + 3.65093083420853463394e+03, /* 0x40AC85DC, 0x964D274F */ + 3.69562060269033463555e+04, /* 0x40E20B86, 0x97C5BB7F */ + 9.76027935934950801311e+04, /* 0x40F7D42C, 0xB28F17BB */ + 3.08042720627888811578e+04, /* 0x40DE1511, 0x697A0B2D */ +}; + +static const double pr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */ + 1.31990519556243522749e-11, /* 0x3DAD0667, 0xDAE1CA7D */ + 1.17187493190614097638e-01, /* 0x3FBDFFFF, 0xE2C10043 */ + 6.80275127868432871736e+00, /* 0x401B3604, 0x6E6315E3 */ + 1.08308182990189109773e+02, /* 0x405B13B9, 0x452602ED */ + 5.17636139533199752805e+02, /* 0x40802D16, 0xD052D649 */ + 5.28715201363337541807e+02, /* 0x408085B8, 0xBB7E0CB7 */ +}; +static const double ps5[5] = { + 5.92805987221131331921e+01, /* 0x404DA3EA, 0xA8AF633D */ + 9.91401418733614377743e+02, /* 0x408EFB36, 0x1B066701 */ + 5.35326695291487976647e+03, /* 0x40B4E944, 0x5706B6FB */ + 7.84469031749551231769e+03, /* 0x40BEA4B0, 0xB8A5BB15 */ + 1.50404688810361062679e+03, /* 0x40978030, 0x036F5E51 */ +}; + +static const double pr3[6] = { + 3.02503916137373618024e-09, /* 0x3E29FC21, 0xA7AD9EDD */ + 1.17186865567253592491e-01, /* 0x3FBDFFF5, 0x5B21D17B */ + 3.93297750033315640650e+00, /* 0x400F76BC, 0xE85EAD8A */ + 3.51194035591636932736e+01, /* 0x40418F48, 0x9DA6D129 */ + 9.10550110750781271918e+01, /* 0x4056C385, 0x4D2C1837 */ + 4.85590685197364919645e+01, /* 0x4048478F, 0x8EA83EE5 */ +}; +static const double ps3[5] = { + 3.47913095001251519989e+01, /* 0x40416549, 0xA134069C */ + 3.36762458747825746741e+02, /* 0x40750C33, 0x07F1A75F */ + 1.04687139975775130551e+03, /* 0x40905B7C, 0x5037D523 */ + 8.90811346398256432622e+02, /* 0x408BD67D, 0xA32E31E9 */ + 1.03787932439639277504e+02, /* 0x4059F26D, 0x7C2EED53 */ +}; + +static const double pr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */ + 1.07710830106873743082e-07, /* 0x3E7CE9D4, 0xF65544F4 */ + 1.17176219462683348094e-01, /* 0x3FBDFF42, 0xBE760D83 */ + 2.36851496667608785174e+00, /* 0x4002F2B7, 0xF98FAEC0 */ + 1.22426109148261232917e+01, /* 0x40287C37, 0x7F71A964 */ + 1.76939711271687727390e+01, /* 0x4031B1A8, 0x177F8EE2 */ + 5.07352312588818499250e+00, /* 0x40144B49, 0xA574C1FE */ +}; +static const double ps2[5] = { + 2.14364859363821409488e+01, /* 0x40356FBD, 0x8AD5ECDC */ + 1.25290227168402751090e+02, /* 0x405F5293, 0x14F92CD5 */ + 2.32276469057162813669e+02, /* 0x406D08D8, 0xD5A2DBD9 */ + 1.17679373287147100768e+02, /* 0x405D6B7A, 0xDA1884A9 */ + 8.36463893371618283368e+00, /* 0x4020BAB1, 0xF44E5192 */ +}; + + /* Note: This function is only called for ix>=0x40000000 (see above) */ + static double pone(double x) +{ + const double *p,*q; + double z,r,s; + int32_t ix; + GET_HIGH_WORD(ix,x); + ix &= 0x7fffffff; + assert(ix>=0x40000000 && ix<=0x48000000); + if(ix>=0x40200000) {p = pr8; q= ps8;} + else if(ix>=0x40122E8B){p = pr5; q= ps5;} + else if(ix>=0x4006DB6D){p = pr3; q= ps3;} + else {p = pr2; q= ps2;} + z = one/(x*x); + r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5])))); + s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*q[4])))); + return one+ r/s; +} + + +/* For x >= 8, the asymptotic expansions of qone is + * 3/8 s - 105/1024 s^3 - ..., where s = 1/x. + * We approximate pone by + * qone(x) = s*(0.375 + (R/S)) + * where R = qr1*s^2 + qr2*s^4 + ... + qr5*s^10 + * S = 1 + qs1*s^2 + ... + qs6*s^12 + * and + * | qone(x)/s -0.375-R/S | <= 2 ** ( -61.13) + */ + +static const double qr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */ + 0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */ + -1.02539062499992714161e-01, /* 0xBFBA3FFF, 0xFFFFFDF3 */ + -1.62717534544589987888e+01, /* 0xC0304591, 0xA26779F7 */ + -7.59601722513950107896e+02, /* 0xC087BCD0, 0x53E4B576 */ + -1.18498066702429587167e+04, /* 0xC0C724E7, 0x40F87415 */ + -4.84385124285750353010e+04, /* 0xC0E7A6D0, 0x65D09C6A */ +}; +static const double qs8[6] = { + 1.61395369700722909556e+02, /* 0x40642CA6, 0xDE5BCDE5 */ + 7.82538599923348465381e+03, /* 0x40BE9162, 0xD0D88419 */ + 1.33875336287249578163e+05, /* 0x4100579A, 0xB0B75E98 */ + 7.19657723683240939863e+05, /* 0x4125F653, 0x72869C19 */ + 6.66601232617776375264e+05, /* 0x412457D2, 0x7719AD5C */ + -2.94490264303834643215e+05, /* 0xC111F969, 0x0EA5AA18 */ +}; + +static const double qr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */ + -2.08979931141764104297e-11, /* 0xBDB6FA43, 0x1AA1A098 */ + -1.02539050241375426231e-01, /* 0xBFBA3FFF, 0xCB597FEF */ + -8.05644828123936029840e+00, /* 0xC0201CE6, 0xCA03AD4B */ + -1.83669607474888380239e+02, /* 0xC066F56D, 0x6CA7B9B0 */ + -1.37319376065508163265e+03, /* 0xC09574C6, 0x6931734F */ + -2.61244440453215656817e+03, /* 0xC0A468E3, 0x88FDA79D */ +}; +static const double qs5[6] = { + 8.12765501384335777857e+01, /* 0x405451B2, 0xFF5A11B2 */ + 1.99179873460485964642e+03, /* 0x409F1F31, 0xE77BF839 */ + 1.74684851924908907677e+04, /* 0x40D10F1F, 0x0D64CE29 */ + 4.98514270910352279316e+04, /* 0x40E8576D, 0xAABAD197 */ + 2.79480751638918118260e+04, /* 0x40DB4B04, 0xCF7C364B */ + -4.71918354795128470869e+03, /* 0xC0B26F2E, 0xFCFFA004 */ +}; + +static const double qr3[6] = { + -5.07831226461766561369e-09, /* 0xBE35CFA9, 0xD38FC84F */ + -1.02537829820837089745e-01, /* 0xBFBA3FEB, 0x51AEED54 */ + -4.61011581139473403113e+00, /* 0xC01270C2, 0x3302D9FF */ + -5.78472216562783643212e+01, /* 0xC04CEC71, 0xC25D16DA */ + -2.28244540737631695038e+02, /* 0xC06C87D3, 0x4718D55F */ + -2.19210128478909325622e+02, /* 0xC06B66B9, 0x5F5C1BF6 */ +}; +static const double qs3[6] = { + 4.76651550323729509273e+01, /* 0x4047D523, 0xCCD367E4 */ + 6.73865112676699709482e+02, /* 0x40850EEB, 0xC031EE3E */ + 3.38015286679526343505e+03, /* 0x40AA684E, 0x448E7C9A */ + 5.54772909720722782367e+03, /* 0x40B5ABBA, 0xA61D54A6 */ + 1.90311919338810798763e+03, /* 0x409DBC7A, 0x0DD4DF4B */ + -1.35201191444307340817e+02, /* 0xC060E670, 0x290A311F */ +}; + +static const double qr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */ + -1.78381727510958865572e-07, /* 0xBE87F126, 0x44C626D2 */ + -1.02517042607985553460e-01, /* 0xBFBA3E8E, 0x9148B010 */ + -2.75220568278187460720e+00, /* 0xC0060484, 0x69BB4EDA */ + -1.96636162643703720221e+01, /* 0xC033A9E2, 0xC168907F */ + -4.23253133372830490089e+01, /* 0xC04529A3, 0xDE104AAA */ + -2.13719211703704061733e+01, /* 0xC0355F36, 0x39CF6E52 */ +}; +static const double qs2[6] = { + 2.95333629060523854548e+01, /* 0x403D888A, 0x78AE64FF */ + 2.52981549982190529136e+02, /* 0x406F9F68, 0xDB821CBA */ + 7.57502834868645436472e+02, /* 0x4087AC05, 0xCE49A0F7 */ + 7.39393205320467245656e+02, /* 0x40871B25, 0x48D4C029 */ + 1.55949003336666123687e+02, /* 0x40637E5E, 0x3C3ED8D4 */ + -4.95949898822628210127e+00, /* 0xC013D686, 0xE71BE86B */ +}; + + /* Note: This function is only called for ix>=0x40000000 (see above) */ + static double qone(double x) +{ + const double *p,*q; + double s,r,z; + int32_t ix; + GET_HIGH_WORD(ix,x); + ix &= 0x7fffffff; + assert(ix>=0x40000000 && ix<=0x48000000); + if(ix>=0x40200000) {p = qr8; q= qs8;} + else if(ix>=0x40122E8B){p = qr5; q= qs5;} + else if(ix>=0x4006DB6D){p = qr3; q= qs3;} + else {p = qr2; q= qs2;} + z = one/(x*x); + r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5])))); + s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5]))))); + return (.375 + r/s)/x; +} diff --git a/src/openlibm/src/e_j1.c.o b/src/openlibm/src/e_j1.c.o new file mode 100644 index 0000000000000000000000000000000000000000..fb1e1078756433a7eda7c9e15663584afe4d1c51 GIT binary patch literal 13176 zcmb<-^>JfjWMqH=Mg}_u1P><4!0iC;h$O2hb~ zP(Cl1cHtL*2)OVIz(pWhT=)f8!D{#;4}9Vmum!Qx_%*(N;*b0Ai9hn)C;o`nY5W>b zKk-LC`@|pdD2-p^&L{rJdujX{mp}1GT>QizdF_)Uf5g=^evMO~_#@Ay@oOARbL7`J z2jYNaj(~{MFdkS9NaQ3;?g zJBRFj>iXP;UqBV)?Uz6P{r{gf0c1EhkU{5^jd~Hy@m#ZQtV-mgRd1j?>0UK6`CH+Z!{YJ{{R2JzDyAj2yquY znvZCt@oOB4jy;^F$1mRkO7aY!_yt*1z^VWHVFm^Uhfn+hJSzOHM?n#ZNW0LC9(fUD zuDxBk&?i_r1|=+h{ln#p()cwVB19t}e&UZj@`*nNl32j(2qZSLc;pEreMdg=Bdf#D z2KgvD7GhJx;ZOW=CqRWT$d8AS{O6*=0ruc0et{Sj4zP#Q_%#m0#6(m;p1NNTmv&JR z_{1M`fxrC%0|Ns{U7Svq_u% z?sM4AQ@49ZYlDO5wV(@Px(yC*nbcf&3P(FU7ER7$F_U(1W;pl=WS(vE`W3Gh`#RK~ zdUz|HZLMwaTfLgxPmvBU4fPh+Uh8&HzG@y&6FtEpe)&gsW1donr*gg@w@Tjj|e8omXhm@6t_2xAi z4hPot|J?qG$)TCIY@gHrz4mwBTOm>Nq2A`-WNJ433g5H!dVi+~<%r=R)d*WzP?Ymi%ydu5$c9+14k) z7xuIt_+FX5XrimZfzN;c|Nn2lYyZ=;(f5|=q&ToF`2R;Qf71bPvzqfP-nSj5U);4S zH~fWz=D8GJdH#zImOrYW8_Lgjn7jOM$K#A82mFf-Gmn)_J+NWt@|@hSX$QR5GM{=T zqj2DTedKA7xtj!|{%;BlahS1Sp_KElZF}Vnxikx&B^>a+e}%Vd&s>LPA+pPMt={S| ztESJzFJqO1-8;hrulZUXzDdW#?@Y@+5Pwy|{c?NGfm>p+hYH{L9Qc2e$@ox#(1DP* z>jGcf@7n(){qh;*tL_f|C;Bh1Ja4)$`-SxLwrj!%uH3M*iK|O?&^&O(Lsh!n;rjy5 zbF6FH9d^ky-OiYw?+}!C-qI}I^uQ`FfqRQJT@Tbx$T;|DrSXAVe!DYUSlA8-Z19-a zXSZwr|CDtVT^+U#m(-5AsC{hT2MPZh_PMj20ObsnK5;VFApXhz9jp_>7}iwm>)WxcpLz8UJN~aO9#2E#?Jw$R zmL0#m(!OhtjYyirNqepGQ@1PwHrck#S{5z4-^y-Tk6&lhfo*mv<*GTIJzDl3R{GlW zrcSYknhUju0bFK){o?NIY^9*#?iZ@5U}&Oeq-UsLWME`!U}$Kdpb?asqTrEO0+rA; z*JNN|VPIfTU|?VXmC5dYp$tq6j0Zqsus$y%l+Ot^oPj|EN;6gkF)&sLFiP{Vb4*}_ zh|56bYM2-p7?@+3_yi#0CQ$J;VDVnCI7rL~Dqac_cjOajV{+t^Xl4%ObBN&LlW^q| zaOC6g=4Lv`#V6qi=EQO{xG*pnC2!Lq>kqBmTFi3!D z1d#@2axg%~PQV;6kqss}7$EKibHGFanB-uH07Vd(4I#?F6bHi!FpVH;z)TJXP~8t^ zLWw3Y&A|X_+k%-;q618GFo4?3U?!C41JfJ~H^4N4m;z>UFgyU$2x1nP$-%G#Oe2T| zU?vB{0WggqmVucZ4B+Y=%!Uwaz!V3=2QZBwHi4NO3_rj$f`Hh^!4QBD0<$0m9tT4N zn1>*afSDW&kZ=Waz{Dvq$-z(orV#`rTsV*l8i?FAFvY4hWng#*=5R2~0MiKK3z*5l00~zx2TXv5+898oA1$3gvMvV$ z2bwq=n9sqW0H(o4fC(NjpMyaIOoN5MgbH zz~XEW4iX75mxCbzERT@z1M@i;GQc!KJOs?=VCVqT2=OQ|pMwEZCm=)_pyqNg%mB+H zWYWNV4u%zA8X=wo=5sI6?Z@rUj!BRKof`fpMxO)O?(|xeFB>J z7O1!en)oiLxB;5@0jRhIn)orOcm$gG8K`&$n)oHCcmbOD4XF4IFbxYe28MfJJ_iHD zeuVfFsQ3dgjSznY=5sK-0MiKZ4`4nA1B6D1e}jrMpt(MyO{3tK(p}fF{lX z6^Hl(p`H&a{sT?D2vi)R520QPDlPz~5#o^a!NE|0CawnNb1=Z#127#rQ1Jy|8YarX zU@$4!Qg>r&QYki1Dg05sCWRH_+_Yg1)BIR zsCWaK_(Q081e!P`{x}#q(8S+E)hD2de}jroKokE970*BuX94p$7-oQJL^yDR`5X)d zU>YGV1m<%vECAC8aY<$djJ7IBR-KuFL5P8o!2nuyg8L>63=CR0)a&CAH^w1ujzioA zYVQVUQy<*7VPIge$Dy79I=llOv5Ail2yzVxiHvs(^>YsK^!JO8*E58S=wOpFV9@h% z1`~!LmI;V31rcT-!W={xfe2#|VF4m6L4*ld+6XLV1eP;`h(L6J6&it68i9>80-I?J zw#XQ4lQCGYA((9lVT08eg3U1mn_~zz#}I73A=n&4h?!t>jKF%0!Lr6+S!1v+W3Vn` zuu2oKN@K9e#$c08z`9JpHkyF-nt=71fYq3QO)vqQUZDaFWuAwE8_xHz?_ zBt9)MGlwC|kRdHGshFWSGmjxTznG!8u&9Kg(vTr1KOL0Y8Q}d}P;mq5GlPdM|Ns9F z>0g8T_6!W5(ikT02GIs?Zg4R$Fu=t9ki@x>#KVxpd62~8ki*7e*3?^=Clhps^pA`LO;8 zNE|eU027DwBOvCBA(;c~pMcbhBZN8BXlw;$4y4@<2?s?a_1lotD?j;q&*BV2eiZnCa#a9ULVOENV^xJ9yC@3Q}2kR z-VjMWqaCE(A0vrdBZVG1MgT^jl>X|?h z4owf9Nb0$f#J!NjMUce3k;G+?#6jccF!NQB#6e@ZFmY2PaZud^6SqSW_eV0{4M`j{ zh6q#dha?_|q&^Hu95hx8Qy+&U9*m?u9Z5U{NxT3_JQPX15=k6Xhr-NnLJ|j!MZ?6q zkiXFMmWh8Ora!&&)4zeD(+zW<^gX~4l?`2SNka|!X24-(RR2-xpG zGRF;+2%zOy5t4WSR2*b)E0TB$R2*auvic&ZIJ)|7s5nSHvb{f%#EX&47XdZaq3$U` z61PDTM@|nBNaCeP>a&osILPOhc?4t+8K_a*$a~ZsfDpYG^lR^GLu~Wpgso3Oi-T! zWF8E|><5hrz{Ef_NG&oA@;68fUH=WJ`$2t3ka`#fxfR3)=>gH8wj78JN`oLi4F81c zhf*+M$aE;2$G`w;OM&!*@;H((0|(UME6@T4WclfJFsudh5Cpn@07|B^?f?J) literal 0 HcmV?d00001 diff --git a/src/openlibm/src/e_j1f.c b/src/openlibm/src/e_j1f.c new file mode 100644 index 0000000..ac32c6f --- /dev/null +++ b/src/openlibm/src/e_j1f.c @@ -0,0 +1,332 @@ +/* e_j1f.c -- float version of e_j1.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include +#include "cdefs-compat.h" +#include +#include "math_private.h" + +static float ponef(float), qonef(float); + +static const float +huge = 1e30, +one = 1.0, +invsqrtpi= 5.6418961287e-01, /* 0x3f106ebb */ +tpi = 6.3661974669e-01, /* 0x3f22f983 */ + /* R0/S0 on [0,2] */ +r00 = -6.2500000000e-02, /* 0xbd800000 */ +r01 = 1.4070566976e-03, /* 0x3ab86cfd */ +r02 = -1.5995563444e-05, /* 0xb7862e36 */ +r03 = 4.9672799207e-08, /* 0x335557d2 */ +s01 = 1.9153760746e-02, /* 0x3c9ce859 */ +s02 = 1.8594678841e-04, /* 0x3942fab6 */ +s03 = 1.1771846857e-06, /* 0x359dffc2 */ +s04 = 5.0463624390e-09, /* 0x31ad6446 */ +s05 = 1.2354227016e-11; /* 0x2d59567e */ + +static const float zero = 0.0; + +OLM_DLLEXPORT float +__ieee754_j1f(float x) +{ + float z, s,c,ss,cc,r,u,v,y; + int32_t hx,ix; + + GET_FLOAT_WORD(hx,x); + ix = hx&0x7fffffff; + if(ix>=0x7f800000) return one/x; + y = fabsf(x); + if(ix >= 0x40000000) { /* |x| >= 2.0 */ + s = sinf(y); + c = cosf(y); + ss = -s-c; + cc = s-c; + if(ix<0x7f000000) { /* make sure y+y not overflow */ + z = cosf(y+y); + if ((s*c)>zero) cc = z/ss; + else ss = z/cc; + } + /* + * j1(x) = 1/sqrt(pi) * (P(1,x)*cc - Q(1,x)*ss) / sqrt(x) + * y1(x) = 1/sqrt(pi) * (P(1,x)*ss + Q(1,x)*cc) / sqrt(x) + */ + if(ix>0x58000000) z = (invsqrtpi*cc)/sqrtf(y); /* |x|>2**49 */ + else { + u = ponef(y); v = qonef(y); + z = invsqrtpi*(u*cc-v*ss)/sqrtf(y); + } + if(hx<0) return -z; + else return z; + } + if(ix<0x39000000) { /* |x|<2**-13 */ + if(huge+x>one) return (float)0.5*x;/* inexact if x!=0 necessary */ + } + z = x*x; + r = z*(r00+z*(r01+z*(r02+z*r03))); + s = one+z*(s01+z*(s02+z*(s03+z*(s04+z*s05)))); + r *= x; + return(x*(float)0.5+r/s); +} + +static const float U0[5] = { + -1.9605709612e-01, /* 0xbe48c331 */ + 5.0443872809e-02, /* 0x3d4e9e3c */ + -1.9125689287e-03, /* 0xbafaaf2a */ + 2.3525259166e-05, /* 0x37c5581c */ + -9.1909917899e-08, /* 0xb3c56003 */ +}; +static const float V0[5] = { + 1.9916731864e-02, /* 0x3ca3286a */ + 2.0255257550e-04, /* 0x3954644b */ + 1.3560879779e-06, /* 0x35b602d4 */ + 6.2274145840e-09, /* 0x31d5f8eb */ + 1.6655924903e-11, /* 0x2d9281cf */ +}; + +OLM_DLLEXPORT float +__ieee754_y1f(float x) +{ + float z, s,c,ss,cc,u,v; + int32_t hx,ix; + + GET_FLOAT_WORD(hx,x); + ix = 0x7fffffff&hx; + /* if Y1(NaN) is NaN, Y1(-inf) is NaN, Y1(inf) is 0 */ + if(ix>=0x7f800000) return one/(x+x*x); + if(ix==0) return -one/zero; + if(hx<0) return zero/zero; + if(ix >= 0x40000000) { /* |x| >= 2.0 */ + s = sinf(x); + c = cosf(x); + 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; + } + /* y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x0)+q1(x)*cos(x0)) + * where x0 = x-3pi/4 + * Better formula: + * cos(x0) = cos(x)cos(3pi/4)+sin(x)sin(3pi/4) + * = 1/sqrt(2) * (sin(x) - cos(x)) + * sin(x0) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4) + * = -1/sqrt(2) * (cos(x) + sin(x)) + * To avoid cancellation, use + * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x)) + * to compute the worse one. + */ + if(ix>0x58000000) z = (invsqrtpi*ss)/sqrtf(x); /* |x|>2**49 */ + else { + u = ponef(x); v = qonef(x); + z = invsqrtpi*(u*ss+v*cc)/sqrtf(x); + } + return z; + } + if(ix<=0x33000000) { /* x < 2**-25 */ + return(-tpi/x); + } + z = x*x; + u = U0[0]+z*(U0[1]+z*(U0[2]+z*(U0[3]+z*U0[4]))); + v = one+z*(V0[0]+z*(V0[1]+z*(V0[2]+z*(V0[3]+z*V0[4])))); + return(x*(u/v) + tpi*(__ieee754_j1f(x)*__ieee754_logf(x)-one/x)); +} + +/* For x >= 8, the asymptotic expansions of pone is + * 1 + 15/128 s^2 - 4725/2^15 s^4 - ..., where s = 1/x. + * We approximate pone by + * pone(x) = 1 + (R/S) + * where R = pr0 + pr1*s^2 + pr2*s^4 + ... + pr5*s^10 + * S = 1 + ps0*s^2 + ... + ps4*s^10 + * and + * | pone(x)-1-R/S | <= 2 ** ( -60.06) + */ + +static const float pr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */ + 0.0000000000e+00, /* 0x00000000 */ + 1.1718750000e-01, /* 0x3df00000 */ + 1.3239480972e+01, /* 0x4153d4ea */ + 4.1205184937e+02, /* 0x43ce06a3 */ + 3.8747453613e+03, /* 0x45722bed */ + 7.9144794922e+03, /* 0x45f753d6 */ +}; +static const float ps8[5] = { + 1.1420736694e+02, /* 0x42e46a2c */ + 3.6509309082e+03, /* 0x45642ee5 */ + 3.6956207031e+04, /* 0x47105c35 */ + 9.7602796875e+04, /* 0x47bea166 */ + 3.0804271484e+04, /* 0x46f0a88b */ +}; + +static const float pr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */ + 1.3199052094e-11, /* 0x2d68333f */ + 1.1718749255e-01, /* 0x3defffff */ + 6.8027510643e+00, /* 0x40d9b023 */ + 1.0830818176e+02, /* 0x42d89dca */ + 5.1763616943e+02, /* 0x440168b7 */ + 5.2871520996e+02, /* 0x44042dc6 */ +}; +static const float ps5[5] = { + 5.9280597687e+01, /* 0x426d1f55 */ + 9.9140142822e+02, /* 0x4477d9b1 */ + 5.3532670898e+03, /* 0x45a74a23 */ + 7.8446904297e+03, /* 0x45f52586 */ + 1.5040468750e+03, /* 0x44bc0180 */ +}; + +static const float pr3[6] = { + 3.0250391081e-09, /* 0x314fe10d */ + 1.1718686670e-01, /* 0x3defffab */ + 3.9329774380e+00, /* 0x407bb5e7 */ + 3.5119403839e+01, /* 0x420c7a45 */ + 9.1055007935e+01, /* 0x42b61c2a */ + 4.8559066772e+01, /* 0x42423c7c */ +}; +static const float ps3[5] = { + 3.4791309357e+01, /* 0x420b2a4d */ + 3.3676245117e+02, /* 0x43a86198 */ + 1.0468714600e+03, /* 0x4482dbe3 */ + 8.9081134033e+02, /* 0x445eb3ed */ + 1.0378793335e+02, /* 0x42cf936c */ +}; + +static const float pr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */ + 1.0771083225e-07, /* 0x33e74ea8 */ + 1.1717621982e-01, /* 0x3deffa16 */ + 2.3685150146e+00, /* 0x401795c0 */ + 1.2242610931e+01, /* 0x4143e1bc */ + 1.7693971634e+01, /* 0x418d8d41 */ + 5.0735230446e+00, /* 0x40a25a4d */ +}; +static const float ps2[5] = { + 2.1436485291e+01, /* 0x41ab7dec */ + 1.2529022980e+02, /* 0x42fa9499 */ + 2.3227647400e+02, /* 0x436846c7 */ + 1.1767937469e+02, /* 0x42eb5bd7 */ + 8.3646392822e+00, /* 0x4105d590 */ +}; + + static float ponef(float x) +{ + const float *p,*q; + float z,r,s; + int32_t ix; + GET_FLOAT_WORD(ix,x); + ix &= 0x7fffffff; + if(ix>=0x41000000) {p = pr8; q= ps8;} + else if(ix>=0x409173eb){p = pr5; q= ps5;} + else if(ix>=0x4036d917){p = pr3; q= ps3;} + else {p = pr2; q= ps2;} /* ix>=0x40000000 */ + z = one/(x*x); + r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5])))); + s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*q[4])))); + return one+ r/s; +} + + +/* For x >= 8, the asymptotic expansions of qone is + * 3/8 s - 105/1024 s^3 - ..., where s = 1/x. + * We approximate pone by + * qone(x) = s*(0.375 + (R/S)) + * where R = qr1*s^2 + qr2*s^4 + ... + qr5*s^10 + * S = 1 + qs1*s^2 + ... + qs6*s^12 + * and + * | qone(x)/s -0.375-R/S | <= 2 ** ( -61.13) + */ + +static const float qr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */ + 0.0000000000e+00, /* 0x00000000 */ + -1.0253906250e-01, /* 0xbdd20000 */ + -1.6271753311e+01, /* 0xc1822c8d */ + -7.5960174561e+02, /* 0xc43de683 */ + -1.1849806641e+04, /* 0xc639273a */ + -4.8438511719e+04, /* 0xc73d3683 */ +}; +static const float qs8[6] = { + 1.6139537048e+02, /* 0x43216537 */ + 7.8253862305e+03, /* 0x45f48b17 */ + 1.3387534375e+05, /* 0x4802bcd6 */ + 7.1965775000e+05, /* 0x492fb29c */ + 6.6660125000e+05, /* 0x4922be94 */ + -2.9449025000e+05, /* 0xc88fcb48 */ +}; + +static const float qr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */ + -2.0897993405e-11, /* 0xadb7d219 */ + -1.0253904760e-01, /* 0xbdd1fffe */ + -8.0564479828e+00, /* 0xc100e736 */ + -1.8366960144e+02, /* 0xc337ab6b */ + -1.3731937256e+03, /* 0xc4aba633 */ + -2.6124443359e+03, /* 0xc523471c */ +}; +static const float qs5[6] = { + 8.1276550293e+01, /* 0x42a28d98 */ + 1.9917987061e+03, /* 0x44f8f98f */ + 1.7468484375e+04, /* 0x468878f8 */ + 4.9851425781e+04, /* 0x4742bb6d */ + 2.7948074219e+04, /* 0x46da5826 */ + -4.7191835938e+03, /* 0xc5937978 */ +}; + +static const float qr3[6] = { + -5.0783124372e-09, /* 0xb1ae7d4f */ + -1.0253783315e-01, /* 0xbdd1ff5b */ + -4.6101160049e+00, /* 0xc0938612 */ + -5.7847221375e+01, /* 0xc267638e */ + -2.2824453735e+02, /* 0xc3643e9a */ + -2.1921012878e+02, /* 0xc35b35cb */ +}; +static const float qs3[6] = { + 4.7665153503e+01, /* 0x423ea91e */ + 6.7386511230e+02, /* 0x4428775e */ + 3.3801528320e+03, /* 0x45534272 */ + 5.5477290039e+03, /* 0x45ad5dd5 */ + 1.9031191406e+03, /* 0x44ede3d0 */ + -1.3520118713e+02, /* 0xc3073381 */ +}; + +static const float qr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */ + -1.7838172539e-07, /* 0xb43f8932 */ + -1.0251704603e-01, /* 0xbdd1f475 */ + -2.7522056103e+00, /* 0xc0302423 */ + -1.9663616180e+01, /* 0xc19d4f16 */ + -4.2325313568e+01, /* 0xc2294d1f */ + -2.1371921539e+01, /* 0xc1aaf9b2 */ +}; +static const float qs2[6] = { + 2.9533363342e+01, /* 0x41ec4454 */ + 2.5298155212e+02, /* 0x437cfb47 */ + 7.5750280762e+02, /* 0x443d602e */ + 7.3939318848e+02, /* 0x4438d92a */ + 1.5594900513e+02, /* 0x431bf2f2 */ + -4.9594988823e+00, /* 0xc09eb437 */ +}; + + static float qonef(float x) +{ + const float *p,*q; + float s,r,z; + int32_t ix; + GET_FLOAT_WORD(ix,x); + ix &= 0x7fffffff; + if(ix>=0x41000000) {p = qr8; q= qs8;} + else if(ix>=0x409173eb){p = qr5; q= qs5;} + else if(ix>=0x4036d917){p = qr3; q= qs3;} + else {p = qr2; q= qs2;} /* ix>=0x40000000 */ + z = one/(x*x); + r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5])))); + s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5]))))); + return ((float).375 + r/s)/x; +} diff --git a/src/openlibm/src/e_j1f.c.o b/src/openlibm/src/e_j1f.c.o new file mode 100644 index 0000000000000000000000000000000000000000..6dc443895862e5b0669b1c18b36c8bcd6f1c5efc GIT binary patch literal 11848 zcmb<-^>JfjWMqH=Mg}_u1P><4z|f(EU^{@B4h;MZd<<#)bq7@c|Nmca`~Uxchw=j3 zSH%+@_}g3=85lmh@C%rNl!6$tUI|^@)^Iz zozMIcw?6Yn-s9J}{Fy)E;%ENIYo8tYBd+pmochckd5&M>pd-J=IS>;hd;~g;F!$fF>+(;(u=Xa2~uAOS;jnvY2EYaEJ>J^YzpkVWMMDD8ef%)r3l z@R?tLM}@z2F9QPuLW2M_#3C<(4Et|UF8CRiI{70G^6MWiU&pWU5Fr-%@H2npk@Baqn0;*lqi^d0%kkE{+q8{~=TScpv#hd=YjodA_s{2GT2^UE`Q<`;BPVF7#W zGrvHL3Jchy{2GU0LLw?)ztq8HT~s(e^T%A^Z$HVvz`(Bo3YicUp3nRda4jY(X`nKh zU%&^X6k@1Ahzbuly+^*}*MGy`b_Aq39Gv6$H7@XLJp0Ta^YAl&+?B?^3=9kr<@rb^ z3#Nd~5sXn`dC~gw|9`kkSX4mn-1HkP1XcsGF0rZ;fSSU}*f!z`$T! z9tw+RkLDu+(V!d)i6=-kn8yG9BuES_c^FZkeg;=s5%5F;mIo<340GoVL^>4&M@%G0 z1eV$kBc&)%jRyATXZ}bu@faN95je!LsgJwBuW|4*f8@o_$Z-L75-2V5YaE27J#g~) z3{6LoE}+C2_wh4-%(2h>kx++6u&98&dYE6n0hBw__}?D@34G>{I}nW$J|MGU2K#`F z5(K3mxLqPD(8vYF(tl8LhbV$4_f?=23v#$1B)P+N>cEnF3@DijfVD-w2B-36km3QH z_QB}{9LEvmiQo_rOabK^!4Qx(K_3;C7t6nalQP%@sOzr$01JUt3V>BYQa4ylUQPMk7kV29?zs8}LyFh6eULk+x7f?~**SPSRKjtwg8@>$s|NlP&14H+U z4{m7-_qm(K2)IAhOL4sx{N44fc9H91wsX#}t^_+WFnqAp$$H|{z_`byP4%m*ve$Cg zjW^3(j_I{raO~}M z-1E@c@xWAZ2eDu8ZQsNFi>V7Ro`JXO)TqH^+4wTN48xx1a*e^hk1_5b|gBIB-n)OgwIBiXCX z51Tz_IQZ}X#l16n7dc5@+P=2YnEmjD$8TM(#;$cOatd~hE7x#2Z5n-emR-u>zU1^n zLT!@|ME}3IS8k=9lYi~HjpkeC9r*M~+F9$Sg^ON-t&98b8s|+vR~?l1)jTBTKlh-r ziot=>FBkWQxV&*R>a^d&z;M8BcbAh&Gg#L|K{wlVqj>ntqY6P zbxT=mcq9U?`J78A_mHCJYP=E>N)$keDN%KpT@I zpF}fr0G~kw7oUU+pMWDDha)%Bel9)2zhXOaPbMa@^N@`LruV>K>lT6_z21>7?R9bdQ_nBU_ugy`I(=A0ThM|4j?x& zFu?r{E>{^?88pyLmj?4$8Faujf=~oASs5(AG=fkEGg%pIz%+sYw@evW86bT-gt#%7 z$qEiXFcV5xf@xL;Sp0ywpactMurh$+3Cx5Nu3(y#!2?Vq2yZZxmB9y0BZxpSla(O= zOe2VJFcXy8zzjGM17@*;(<7J(B@)3jD>!|DnNT7POtZq%Bbdv;z>p1Qurf%1X#`OK zX0pQ5D45H@z)%WiurhFfX#`OPX0kHyfN2C#4`#B0^9+~?B_Q1)Rt6O)A4YY88LSLz zz%+vB2Qyh2LclbFm9D+L7WCNSs7q? z7|dm0V7Lfouri<)Vhjw|q2iEm1#`f}T`h{s?iE5j5pjUZlvnXC*mz%+t* z4`#A5%mLE~;wzZR%FqF(5d^4B2P!3d5JF%UWax#JVF8$jAlN|#3Ii*{5`++##S0Z* z0p=kHVW{{Wgb^;z8=hHWl#Xq z2=T38J}ZL?m_~^22J=}NG{7`M{2-Xm%3uJd5#qDk zl|cqfBgAil`K$~&U>YHQAIxWEFagsD@uy%uD}x1?Mu@)#^H~{ez%)YqBbd+1-~gr( z;@`o1Rt8Yt4k60G@E0l`0;Ul%%;5T-l_3I6oD(XZfF{ll6?Z`s7ln#@povRE#eLAk z6`|rWXyWQn@f0+1U8r~lnz%7kyaY|$5-MJSCT_)ISD?pfpyGSb#1})w51@&!f{L#}6W<6GKY}K{11i1&O?*F8 z`~;f#F{t z$N(aZz@#adGy{|7VA29i8iPp_Flh-QjSRpfSTC3fW`Pxe%>Ww#HUVrfSU=b(ux=Bu zLL;!05m?R$ticGP1FX;ptkMXg5^Sb1*dk-FO~zoo#$dh1U^T{Iy~bd@#$dfB5cLqf zVDnADdQHH3O~86h!Q!T1y=GupGq9`~Sk?@z*A#4~DcDRiu$g9H8_mFa&A@t1z$#6^ zBBo$9reM=d!KRsl)tf+6f=x34n`R2uWeT>-60Fh;ENcdqH3y5EgY}w&RholMFbA7& z4mRH$tjip1uQ^z+Iasd+Sd9f(jRjb*1z3#**aQoR8n9jquq_r~TP(mPSc3Ihg7sR0 z^;&}UT7vajLezjwFf;%wH8cRLH8cPlXlMX7(a->Fq@e-C1hAMTR0wR4p#j)bLj$mZ zhK67jhK5ij5c3Venhgyh))+!GKvS$C#1un_rG^#^S%zs0X^Bb2X$-}gd1(yE`5;zd zQArv@rC}OFPJTMLs|6Y(0A&+Ub_Vs{{``jkO^_hC&&$97Dm7u^hDhR|tOgT@^gBU) zWCn1b3nuP}q#o3_hKYM3iE}Y9Fu=rvkiRWwk~nBu3nqRQNn8!doO?*(pfMYm`e#Vups^sB_&X$V zP@aN`e?t-nP2t1D{~?KMBiYLi@(?sXg2t3!>IIO*L1RTQaY-a`JtT9Kki_+o#I=#c zL1RZSb5fARL3tl04rzZu;@1etoKht9pfM_#`dTD$&=?dZv|B56I8mokf|3wn_MKXsKGzbpOM}A1+d`RN{NaEs1;-E24nE47w;-E26n7AgA zIH)dzi5nt`2P2tpg(MCdGlZ%4MG_B1QXhsS9)=_yha?Ufi-nn!h9nLedxVMSA&EyK znNx-&9)%=ck0cJNi(%$;Ac=#<7-8ZQk;G$>%$bEG9)~2p2uVC1NqjYuIB2XAX8t`S zapd&&4Jr1929P~ zNa`OUiPs^Ci-H=343K#yWN~+>IH+6#jZwqQ--09#YMa5t_d&%$_JYRXVd7Vy;vjR7 z)jx!aqpSZ36$hzDwl^NsNQK6G9+LY@ki_$m#OEN1Bd3S$NaCO|c9=U)B8e9wnR69M zya-ABA(D78lK5LBanRU1%>187;-EPVm^dqRVguw~P@5JeE{G&vj%2FpX+9ArLnyt9Bh8(7k3KU5r~9ywht!6Cj8Dh_fFa{2_dQ9(5@$Q%#`u|XKrwgJ%~ zF%X8$7lP_OWO3N|2yA`?q!xr>;};Bi#g(}wiAfB4#U(`$Is?WkO3g{sD@m;=VbDuS zEJ!_@ zP?TSgT2xZWpa(WQH6uQ)C@~jQV1XP>0S1K=s7VXWo^X>uZ5$BiDKvaRY!C+Zy+AY! zgZdz#u!pIKiD!U1Aq)%*7NAZa0|R(I4`dHCIl$)$L2Y-CIJ7wc)6Sp@>U6?+2nI+k zg2w=!zXh2|u6|IP8Du7?kBDrp2Gss5AW0+%kY7Pu7!7JWf|Q`^2YZ+Sb8HJ1elQx; zCIaaPwdq0T!mt3S6V1TD0O|w4#6UDiEiw&id%(m%;xKFv)eqytXmqupBm^qLKxrGM z21GkR^`pBB6xJYl7zULAAT!bR7eMu+&%2=O2bFc8utZNk3qYMQ1_t>2C&)NZl)&_Z z`p_UZV6z(}ZU9Yp1|W?L3=AMHs60g14@%zXX$Pb~0n`}>tx, a continued fraction approximation to + * j(n,x)/j(n-1,x) is evaluated and then backward + * recursion is used starting from a supposed value + * for j(n,x). The resulting value of j(0,x) is + * compared with the actual value to correct the + * supposed value of j(n,x). + * + * yn(n,x) is similar in all respects, except + * that forward recursion is used for all + * values of n>1. + * + */ + +#include + +#include "math_private.h" + +static const double +invsqrtpi= 5.64189583547756279280e-01, /* 0x3FE20DD7, 0x50429B6D */ +two = 2.00000000000000000000e+00, /* 0x40000000, 0x00000000 */ +one = 1.00000000000000000000e+00; /* 0x3FF00000, 0x00000000 */ + +static const double zero = 0.00000000000000000000e+00; + +OLM_DLLEXPORT double +__ieee754_jn(int n, double x) +{ + int32_t i,hx,ix,lx, sgn; + double a, b, temp, di; + double z, w; + + /* J(-n,x) = (-1)^n * J(n, x), J(n, -x) = (-1)^n * J(n, x) + * Thus, J(-n,x) = J(n,-x) + */ + EXTRACT_WORDS(hx,lx,x); + ix = 0x7fffffff&hx; + /* if J(n,NaN) is NaN */ + if((ix|((u_int32_t)(lx|-lx))>>31)>0x7ff00000) return x+x; + if(n<0){ + n = -n; + x = -x; + hx ^= 0x80000000; + } + if(n==0) return(__ieee754_j0(x)); + if(n==1) return(__ieee754_j1(x)); + sgn = (n&1)&(hx>>31); /* even n -- 0, odd n -- sign(x) */ + x = fabs(x); + if((ix|lx)==0||ix>=0x7ff00000) /* if x is 0 or inf */ + b = zero; + else if((double)n<=x) { + /* Safe to use J(n+1,x)=2n/x *J(n,x)-J(n-1,x) */ + if(ix>=0x52D00000) { /* x > 2**302 */ + /* (x >> n**2) + * Jn(x) = cos(x-(2n+1)*pi/4)*sqrt(2/x*pi) + * Yn(x) = sin(x-(2n+1)*pi/4)*sqrt(2/x*pi) + * Let s=sin(x), c=cos(x), + * xn=x-(2n+1)*pi/4, sqt2 = sqrt(2),then + * + * n sin(xn)*sqt2 cos(xn)*sqt2 + * ---------------------------------- + * 0 s-c c+s + * 1 -s-c -c+s + * 2 -s+c -c-s + * 3 s+c c-s + */ + switch(n&3) { + case 0: temp = cos(x)+sin(x); break; + case 1: temp = -cos(x)+sin(x); break; + case 2: temp = -cos(x)-sin(x); break; + case 3: temp = cos(x)-sin(x); break; + } + b = invsqrtpi*temp/sqrt(x); + } else { + a = __ieee754_j0(x); + b = __ieee754_j1(x); + for(i=1;i33) /* underflow */ + b = zero; + else { + temp = x*0.5; b = temp; + for (a=one,i=2;i<=n;i++) { + a *= (double)i; /* a = n! */ + b *= temp; /* b = (x/2)^n */ + } + b = b/a; + } + } else { + /* use backward recurrence */ + /* x x^2 x^2 + * J(n,x)/J(n-1,x) = ---- ------ ------ ..... + * 2n - 2(n+1) - 2(n+2) + * + * 1 1 1 + * (for large x) = ---- ------ ------ ..... + * 2n 2(n+1) 2(n+2) + * -- - ------ - ------ - + * x x x + * + * Let w = 2n/x and h=2/x, then the above quotient + * is equal to the continued fraction: + * 1 + * = ----------------------- + * 1 + * w - ----------------- + * 1 + * w+h - --------- + * w+2h - ... + * + * To determine how many terms needed, let + * Q(0) = w, Q(1) = w(w+h) - 1, + * Q(k) = (w+k*h)*Q(k-1) - Q(k-2), + * When Q(k) > 1e4 good for single + * When Q(k) > 1e9 good for double + * When Q(k) > 1e17 good for quadruple + */ + /* determine k */ + double t,v; + double q0,q1,h,tmp; int32_t k,m; + w = (n+n)/(double)x; h = 2.0/(double)x; + q0 = w; z = w+h; q1 = w*z - 1.0; k=1; + while(q1<1.0e9) { + k += 1; z += h; + tmp = z*q1 - q0; + q0 = q1; + q1 = tmp; + } + m = n+n; + for(t=zero, i = 2*(n+k); i>=m; i -= 2) t = one/(i/x-t); + a = t; + b = one; + /* estimate log((2/x)^n*n!) = n*log(2/x)+n*ln(n) + * Hence, if n*(log(2n/x)) > ... + * single 8.8722839355e+01 + * double 7.09782712893383973096e+02 + * long double 1.1356523406294143949491931077970765006170e+04 + * then recurrent value may overflow and the result is + * likely underflow to zero + */ + tmp = n; + v = two/x; + tmp = tmp*__ieee754_log(fabs(v*tmp)); + if(tmp<7.09782712893383973096e+02) { + for(i=n-1,di=(double)(i+i);i>0;i--){ + temp = b; + b *= di; + b = b/x - a; + a = temp; + di -= two; + } + } else { + for(i=n-1,di=(double)(i+i);i>0;i--){ + temp = b; + b *= di; + b = b/x - a; + a = temp; + di -= two; + /* scale b to avoid spurious overflow */ + if(b>1e100) { + a /= b; + t /= b; + b = one; + } + } + } + z = __ieee754_j0(x); + w = __ieee754_j1(x); + if (fabs(z) >= fabs(w)) + b = (t*z/b); + else + b = (t*w/a); + } + } + if(sgn==1) return -b; else return b; +} + +OLM_DLLEXPORT double +__ieee754_yn(int n, double x) +{ + int32_t i,hx,ix,lx; + int32_t sign; + double a, b, temp; + + EXTRACT_WORDS(hx,lx,x); + ix = 0x7fffffff&hx; + /* if Y(n,NaN) is NaN */ + if((ix|((u_int32_t)(lx|-lx))>>31)>0x7ff00000) return x+x; + if((ix|lx)==0) return -one/zero; + if(hx<0) return zero/zero; + sign = 1; + if(n<0){ + n = -n; + sign = 1 - ((n&1)<<1); + } + if(n==0) return(__ieee754_y0(x)); + if(n==1) return(sign*__ieee754_y1(x)); + if(ix==0x7ff00000) return zero; + if(ix>=0x52D00000) { /* x > 2**302 */ + /* (x >> n**2) + * Jn(x) = cos(x-(2n+1)*pi/4)*sqrt(2/x*pi) + * Yn(x) = sin(x-(2n+1)*pi/4)*sqrt(2/x*pi) + * Let s=sin(x), c=cos(x), + * xn=x-(2n+1)*pi/4, sqt2 = sqrt(2),then + * + * n sin(xn)*sqt2 cos(xn)*sqt2 + * ---------------------------------- + * 0 s-c c+s + * 1 -s-c -c+s + * 2 -s+c -c-s + * 3 s+c c-s + */ + switch(n&3) { + case 0: temp = sin(x)-cos(x); break; + case 1: temp = -sin(x)-cos(x); break; + case 2: temp = -sin(x)+cos(x); break; + case 3: temp = sin(x)+cos(x); break; + } + b = invsqrtpi*temp/sqrt(x); + } else { + u_int32_t high; + a = __ieee754_y0(x); + b = __ieee754_y1(x); + /* quit if b is -inf */ + GET_HIGH_WORD(high,b); + for(i=1;i0) return b; else return -b; +} diff --git a/src/openlibm/src/e_jn.c.o b/src/openlibm/src/e_jn.c.o new file mode 100644 index 0000000000000000000000000000000000000000..bf3233bd3bc91bb75d33caf60ffdb69023330c65 GIT binary patch literal 5704 zcmb<-^>JfjWMqH=Mg}_u1P><4z|bLtU^{@B4h;MZd<>4Ejv;BD{B=h{T{<5G`*c43 ze#7J7YXuk12acV055AChY<&9v|NnZA<~J5DoG)w{7(UdO7kB<`{a@kA-y+Y*z|j1c zvBduc$i#!MDc)9|Nr;(WpQcz?+>)zF5yVy4`&4_^JqR|5gqFo z;~0CGU!LLnU6^>|VFm_IaLoh)f6%LqG#EDP*k-Q*_K?*+c3;L*VpeTzwk;boa z@Fmax|NqnY%r}5jBr-Oo}`L7~>|AT-3|9|3-6a|_3iC+M0dh=1n z9ZU=i3?N(5()8e-MKEDPpZFsWrSZSN{fS@eM)Lv2PyCUmEnk$r{KOx3@MYV-|NmWj zQ*;^9_}~Bk#4n%=wL%q4JMwG&*#Sx_pIo4}e&Ub&k;boa^b>#Fp)`Jt?`ixR_doGR zeE7s4dG8Z{%$+nBe*M$sf-jqx85m&pr}1mt1gU90z?jCbaSmkvC;pi8Y5W?$LCQ~- z-(!5icp#1c{YmWpfV=$#({TocY8bciPeNNZo@^j{K1aKJg2Ns7N?A zzhP>A%Lop2fln@=h=T+^BnDjg1zc1(()izh`@}EcqayIhkzeZzIN~He@e4rw>;g7S z0GtkC0Rl-kZOM$_;69kfukq)#E)K_HhCkS&;BW$m(O0M^Zlv*R9B+QhSb856gFBqeu0rnBzWCu!?pTJ%MdoRs{zwRiQ57Cw8!Jqf`6Tbl1L;)Wag*1Ns z7yM1SjG!b93W!hq0$_V04}Rj0JN&Zh&;S3Rd<03}jBmk)fpZFt>ed3P+h5eyV{4vMDaRMq0()cxQl<`25 z^_@@raVJ1ga^_{mKagX{uWM9DgU35zomc)lttbjX#5GP2KZZMFfcGQ{`~(RRMLK7U|?u| z&I}5q=KoCmEj&yN49)+U`CCqdQ>0*s3Pwpo)NTIFh*HaF zM8_VU@ClyW-k$^&iie@;_7i`^1(0K5{O|X{zU^hPZ+^g}dH5ywe^3%}02Q4FKJmvL zfT{CnKB5sF3ogsS-gUC*FPt{Hiz27Q&iV_ZVG{@`>-EE!%1-20Oq+nJ6kDexch}_Dj1sR z8R;1+7#SFu8W6c`v7Kvj&pUnm0;1LFaZ7$_@& z%wvS|IYAr-1_lu*%~%!0z*r%`D9yvpF@ceRp@4ybK?W*!1Z0>KpFl5@6Q4v6vm2j6 z8;c8{Ml)+HUjmai7oUbBpMoQwgcF~D6CZ~QcO;sKC$|e1pN1=v8ZU09C1{G=xEUBc z7#J8PK<)elYJSx73A8ae@<}u^yYM+Mo#2yjc6$ zg^N$Z@i3o&<1s!CFK(zY7!)WRSQtK{#2QQyGnSSs2UwB~Od=ED5|M$G0V0o(fi!bj z83YhQV3s(T1O+6R0Vg0~%*r4E7lAMo!4xYvF2PJFp$4W|88pB&g3tytSs4t#G=hNe zSs5%4LSU9D0|SE)l7GQ*%)kIvhwgTe23rOO3_pRyK?xh1dKVn(L2-;ty)O>+0XW1# z83*M43(z11rxykWhHxC}qi~2bq{e6E=_NDh`8XSa2xAao0wN4RgeizH0}{mZPeKw0p+1HwHK6UVd^I%iSr@Zy97xb*_~T(i2pd}i6!1`ckgh%NgO#n_~Q^yK@vwcrv*tI*_@e3;>hZk zL&ZVv1bGn_Zl$2ez~as>BynW(XF$c#%~^#c4hj;O`8%QFATi{0dj%?vZq5@VaZqId zGshp42%zo+b$MapDM;dCNa4>2N~}=z$l)M{B#!Jab0l$O^*%`A$m;WPh_@h#Bb&1s zNgUao3!vo&D14C9RW>v~g2a*2p*fO&k;4Jhb^sX#3QrIQu|aqWh=ArVkT|T|WzZ|G z%q>YwV$drtDT2@$Fji4&PNH5(YDEcyUP@v~B7^ z&&^HED`C*f%P&dQbN36?EiOq+&W7^S^Gfv!it-Cmi%KdP^uUIvX2hozCFZ6=9Y+BL z@;4}`pveYq5~zLyaSlPl9mED%xqK z)%&1&9b`W!Pl3#XVJ1*v2IC;nAhk$b1|0?la9f02{h-PUWF{z$Ae+kpwIAJIF!#e~ zJE*_V^#?%pgVHdvxiCJA_JQh$v{w)+6QKI_5kg=V$gLm-j1GnB2Z0|(^aJt_y4@hFW`GnkFfeF9B|*s%WCpr^kTcQK4oLq2kYWY~hFA~>34`oI W;xd4oiA_HPG(of@D~5&@vJe1zGCoZJ literal 0 HcmV?d00001 diff --git a/src/openlibm/src/e_jnf.c b/src/openlibm/src/e_jnf.c new file mode 100644 index 0000000..cb73e86 --- /dev/null +++ b/src/openlibm/src/e_jnf.c @@ -0,0 +1,200 @@ +/* e_jnf.c -- float version of e_jn.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/e_jnf.c,v 1.11 2010/11/13 10:54:10 uqs Exp $"); + +#include + +#include "math_private.h" + +static const float +two = 2.0000000000e+00, /* 0x40000000 */ +one = 1.0000000000e+00; /* 0x3F800000 */ + +static const float zero = 0.0000000000e+00; + +OLM_DLLEXPORT float +__ieee754_jnf(int n, float x) +{ + int32_t i,hx,ix, sgn; + float a, b, temp, di; + float z, w; + + /* J(-n,x) = (-1)^n * J(n, x), J(n, -x) = (-1)^n * J(n, x) + * Thus, J(-n,x) = J(n,-x) + */ + GET_FLOAT_WORD(hx,x); + ix = 0x7fffffff&hx; + /* if J(n,NaN) is NaN */ + if(ix>0x7f800000) return x+x; + if(n<0){ + n = -n; + x = -x; + hx ^= 0x80000000; + } + if(n==0) return(__ieee754_j0f(x)); + if(n==1) return(__ieee754_j1f(x)); + sgn = (n&1)&(hx>>31); /* even n -- 0, odd n -- sign(x) */ + x = fabsf(x); + if(ix==0||ix>=0x7f800000) /* if x is 0 or inf */ + b = zero; + else if((float)n<=x) { + /* Safe to use J(n+1,x)=2n/x *J(n,x)-J(n-1,x) */ + a = __ieee754_j0f(x); + b = __ieee754_j1f(x); + for(i=1;i33) /* underflow */ + b = zero; + else { + temp = x*(float)0.5; b = temp; + for (a=one,i=2;i<=n;i++) { + a *= (float)i; /* a = n! */ + b *= temp; /* b = (x/2)^n */ + } + b = b/a; + } + } else { + /* use backward recurrence */ + /* x x^2 x^2 + * J(n,x)/J(n-1,x) = ---- ------ ------ ..... + * 2n - 2(n+1) - 2(n+2) + * + * 1 1 1 + * (for large x) = ---- ------ ------ ..... + * 2n 2(n+1) 2(n+2) + * -- - ------ - ------ - + * x x x + * + * Let w = 2n/x and h=2/x, then the above quotient + * is equal to the continued fraction: + * 1 + * = ----------------------- + * 1 + * w - ----------------- + * 1 + * w+h - --------- + * w+2h - ... + * + * To determine how many terms needed, let + * Q(0) = w, Q(1) = w(w+h) - 1, + * Q(k) = (w+k*h)*Q(k-1) - Q(k-2), + * When Q(k) > 1e4 good for single + * When Q(k) > 1e9 good for double + * When Q(k) > 1e17 good for quadruple + */ + /* determine k */ + float t,v; + float q0,q1,h,tmp; int32_t k,m; + w = (n+n)/(float)x; h = (float)2.0/(float)x; + q0 = w; z = w+h; q1 = w*z - (float)1.0; k=1; + while(q1<(float)1.0e9) { + k += 1; z += h; + tmp = z*q1 - q0; + q0 = q1; + q1 = tmp; + } + m = n+n; + for(t=zero, i = 2*(n+k); i>=m; i -= 2) t = one/(i/x-t); + a = t; + b = one; + /* estimate log((2/x)^n*n!) = n*log(2/x)+n*ln(n) + * Hence, if n*(log(2n/x)) > ... + * single 8.8722839355e+01 + * double 7.09782712893383973096e+02 + * long double 1.1356523406294143949491931077970765006170e+04 + * then recurrent value may overflow and the result is + * likely underflow to zero + */ + tmp = n; + v = two/x; + tmp = tmp*__ieee754_logf(fabsf(v*tmp)); + if(tmp<(float)8.8721679688e+01) { + for(i=n-1,di=(float)(i+i);i>0;i--){ + temp = b; + b *= di; + b = b/x - a; + a = temp; + di -= two; + } + } else { + for(i=n-1,di=(float)(i+i);i>0;i--){ + temp = b; + b *= di; + b = b/x - a; + a = temp; + di -= two; + /* scale b to avoid spurious overflow */ + if(b>(float)1e10) { + a /= b; + t /= b; + b = one; + } + } + } + z = __ieee754_j0f(x); + w = __ieee754_j1f(x); + if (fabsf(z) >= fabsf(w)) + b = (t*z/b); + else + b = (t*w/a); + } + } + if(sgn==1) return -b; else return b; +} + +OLM_DLLEXPORT float +__ieee754_ynf(int n, float x) +{ + int32_t i,hx,ix,ib; + int32_t sign; + float a, b, temp; + + GET_FLOAT_WORD(hx,x); + ix = 0x7fffffff&hx; + /* if Y(n,NaN) is NaN */ + if(ix>0x7f800000) return x+x; + if(ix==0) return -one/zero; + if(hx<0) return zero/zero; + sign = 1; + if(n<0){ + n = -n; + sign = 1 - ((n&1)<<1); + } + if(n==0) return(__ieee754_y0f(x)); + if(n==1) return(sign*__ieee754_y1f(x)); + if(ix==0x7f800000) return zero; + + a = __ieee754_y0f(x); + b = __ieee754_y1f(x); + /* quit if b is -inf */ + GET_FLOAT_WORD(ib,b); + for(i=1;i0) return b; else return -b; +} diff --git a/src/openlibm/src/e_jnf.c.o b/src/openlibm/src/e_jnf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..e40478c505d4efe8d703ee4e2911194beb6813a8 GIT binary patch literal 4176 zcmb<-^>JfjWMqH=Mg}_u1P><4z%YRa!FB*M9T@l-_!t~RLeu!`js`n+zHw}P^8f$; zdXMHe3XY9`7#JGr`P-i|FferfZvD^Sv6+E^fxo4ek%6K4HzR+`9tH-67a(&EzLi(J z%dc_4we<;q%P|H92AJNKoeT^NX|DY54}5mv*E;OTuYZ8Qc`ro4|Nr#{{Ot~m3=C=f z?+-NpR^;#RXJBCX%pWNVGV?RP056DcKFqj-31qLvp|mtTe)$%VAOkXU!e{=-Luvf) zZ-3_3y3u@q@iTwqY0Dd>FF*6g9ei!iFVFD(Hh(xPNL%Ak1_p)(klR~b{{R2)(R@T9 zI@U4fB}k56p5Zfp!~vMtVSahAyIS9tyn*V5OMT`SbW!19ybbpIXMTYY6&|pV0Kdi| zm{^R807M4tcx2}yJOTF%|NE2t8V^46Yn^C5!1S3v?$l@g$P=IWV@~sH+~L7q6Fc}v0m; zoCAgKXa1P;{2ISq`1MbgKVrPWcp#1c{YhMYbO41TByL`SJa_9ef6PsOjWeJ5<4!wT z9;tiy*^xi;z-NBJ5ET)}<~K~uuNgn{3;L)Ce0BkcGdM)S1jrXIDm-cY@4tQK7XYbn zs16GvAUw8O3zkrJhL{A!j-s{i&0$}3=d{iX(^_y0dqn56O79pcwG(Ro1?R2JAmN`dbT3=FLY_*<@n z=u7+^{EQ3?p&rd|1V9DDD+UIJy`Y4~-@* z2o5?9a2SB&kpmV`2f<=#{B;NTH7AV{KG?6lBKFOXm^81x zelm#$FfcUi2TMZ;a5(^BGB7Z>J3Ct`Xt?`@YAP6-=o#r5Di|3UnHm@x8YpN4rKTu& zB$hxWbj>vx7+4q>7!(*77(kwN_X}lUVqiP~5(9-U$V^5kpA*DkU|42%^5 zjM6;p91|EB7!nv57-XPwtRMrN_yl^G9Qh>Lm|gi4npyn#9GISQ@hLd+NjUNeIPr0K zaC;zgUATjhxsKdSEy#QiZUzPh3s8v-wWAW`z$`w2HYOK71*SuM0*-tf?#D9t6xx^~ z_&AOQfEX@Zd;*Tg_&B^lnxXp8DUdNN3?Kiai-Y*gSZYp4IIx1l4WtH!`M?ZND1sSq zLKw_q1Cz*v1en9hzyYQage;iJ%D@Ar5rh($$;u!ArV)fXn8^x{7ciHBfk6k%U}b>V z1LlAULk0#0AtZl+OG+L3V_lE0|Ns%{ume- zd~m1_z#-0%8lRPyrkBj1=i_V)A`C!;5r{AW5vCx*3`CfN2n&X+yflWi#H8XhhAhK0 zhAe|LhMfHLG=|E&G=@rpG=@sUG?23yY{4WXKY+si&wmJ*2o(o4JD3?57+~Tvk;Fk> zf{B9~NFXVYdQfVBi7SH=8Uq6Zy0|4&9ApM44Z+m=B8h|AJ}~h!P;rnspi~7Dzk(zV zG7BdD97&uV$^G*|1~6dycL|a>Ka%R&-5e{~~?3n7XBfQo~>fgF!KAP&_1 zTuADxpyD8H$mYPB;vjKk_wR(p3rHNXoEclrZR}B$gyH=p_{wGw2oNgE)H0#U&=l978h( zz2yAd+|;}h2EDxel2ko+zfj%clEma}C_g=~RIi{YzaX`!q>@1oYu~`7{H|^G+BY9!1yGZy;C}Nk6wnu_%Iq&K7;Hx02zvmp%J2wEC#g;Bm~j}qC=6yKztb1hw6v% zVKhu1j1NjepmGZuO)y~w1E_v + +#include "math_private.h" + +OLM_DLLEXPORT double +__ieee754_lgamma(double x) +{ +#ifdef OPENLIBM_ONLY_THREAD_SAFE + int signgam; +#endif + + return __ieee754_lgamma_r(x,&signgam); +} diff --git a/src/openlibm/src/e_lgamma.c.o b/src/openlibm/src/e_lgamma.c.o new file mode 100644 index 0000000000000000000000000000000000000000..12c9c3fcc49298cc53de53775b924cb8950ae7a2 GIT binary patch literal 1472 zcmb<-^>JfjWMqH=Mg}_u1P><4z|g>iU^{@B4h*~uJPaP)wjkb15W(Q?>};i=;qDiz zsbFZLXQXGSU}RuqYG7z+pr8?ynxf#5SOS&MHP-~|U|?ZjU{GLSU|?lnU~u;fWnf}p zJOC1d$TBc6LisQ^i9jV7tAZF9D+Cy&dDuB7FfuTJ#ATpzJWv`R1u~C?;p2a7YM8Nv z0LV-sBykWQq*s`Mfk6PoK*J#KVG}pRp`IZ%J|{gfH#bo)nE}FJh8S!aFiMgp@>nJ5a{s6@#$ZyDI zLDDD#11z3ka_Dg)&A!N9<<0!ni;Fff4P2wguXR2-@dPIZ6`W?*0dg)dwX>Q`jGAP)TkP)Fq; IE5@Q90B1dE^#A|> literal 0 HcmV?d00001 diff --git a/src/openlibm/src/e_lgamma_r.c b/src/openlibm/src/e_lgamma_r.c new file mode 100644 index 0000000..df3ae23 --- /dev/null +++ b/src/openlibm/src/e_lgamma_r.c @@ -0,0 +1,298 @@ + +/* @(#)e_lgamma_r.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + * + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/e_lgamma_r.c,v 1.11 2011/10/15 07:00:28 das Exp $"); + +/* __ieee754_lgamma_r(x, signgamp) + * Reentrant version of the logarithm of the Gamma function + * with user provide pointer for the sign of Gamma(x). + * + * Method: + * 1. Argument Reduction for 0 < x <= 8 + * Since gamma(1+s)=s*gamma(s), for x in [0,8], we may + * reduce x to a number in [1.5,2.5] by + * lgamma(1+s) = log(s) + lgamma(s) + * for example, + * lgamma(7.3) = log(6.3) + lgamma(6.3) + * = log(6.3*5.3) + lgamma(5.3) + * = log(6.3*5.3*4.3*3.3*2.3) + lgamma(2.3) + * 2. Polynomial approximation of lgamma around its + * minimun ymin=1.461632144968362245 to maintain monotonicity. + * On [ymin-0.23, ymin+0.27] (i.e., [1.23164,1.73163]), use + * Let z = x-ymin; + * lgamma(x) = -1.214862905358496078218 + z^2*poly(z) + * where + * poly(z) is a 14 degree polynomial. + * 2. Rational approximation in the primary interval [2,3] + * We use the following approximation: + * s = x-2.0; + * lgamma(x) = 0.5*s + s*P(s)/Q(s) + * with accuracy + * |P/Q - (lgamma(x)-0.5s)| < 2**-61.71 + * Our algorithms are based on the following observation + * + * zeta(2)-1 2 zeta(3)-1 3 + * lgamma(2+s) = s*(1-Euler) + --------- * s - --------- * s + ... + * 2 3 + * + * where Euler = 0.5771... is the Euler constant, which is very + * close to 0.5. + * + * 3. For x>=8, we have + * lgamma(x)~(x-0.5)log(x)-x+0.5*log(2pi)+1/(12x)-1/(360x**3)+.... + * (better formula: + * lgamma(x)~(x-0.5)*(log(x)-1)-.5*(log(2pi)-1) + ...) + * Let z = 1/x, then we approximation + * f(z) = lgamma(x) - (x-0.5)(log(x)-1) + * by + * 3 5 11 + * w = w0 + w1*z + w2*z + w3*z + ... + w6*z + * where + * |w - f(z)| < 2**-58.74 + * + * 4. For negative x, since (G is gamma function) + * -x*G(-x)*G(x) = pi/sin(pi*x), + * we have + * G(x) = pi/(sin(pi*x)*(-x)*G(-x)) + * since G(-x) is positive, sign(G(x)) = sign(sin(pi*x)) for x<0 + * Hence, for x<0, signgam = sign(sin(pi*x)) and + * lgamma(x) = log(|Gamma(x)|) + * = log(pi/(|x*sin(pi*x)|)) - lgamma(-x); + * Note: one should avoid compute pi*(-x) directly in the + * computation of sin(pi*(-x)). + * + * 5. Special Cases + * lgamma(2+s) ~ s*(1-Euler) for tiny s + * lgamma(1) = lgamma(2) = 0 + * lgamma(x) ~ -log(|x|) for tiny x + * lgamma(0) = lgamma(neg.integer) = inf and raise divide-by-zero + * lgamma(inf) = inf + * lgamma(-inf) = inf (bug for bug compatible with C99!?) + * + */ + +#include + +#include "math_private.h" + +static const double +two52= 4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */ +half= 5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */ +one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */ +pi = 3.14159265358979311600e+00, /* 0x400921FB, 0x54442D18 */ +a0 = 7.72156649015328655494e-02, /* 0x3FB3C467, 0xE37DB0C8 */ +a1 = 3.22467033424113591611e-01, /* 0x3FD4A34C, 0xC4A60FAD */ +a2 = 6.73523010531292681824e-02, /* 0x3FB13E00, 0x1A5562A7 */ +a3 = 2.05808084325167332806e-02, /* 0x3F951322, 0xAC92547B */ +a4 = 7.38555086081402883957e-03, /* 0x3F7E404F, 0xB68FEFE8 */ +a5 = 2.89051383673415629091e-03, /* 0x3F67ADD8, 0xCCB7926B */ +a6 = 1.19270763183362067845e-03, /* 0x3F538A94, 0x116F3F5D */ +a7 = 5.10069792153511336608e-04, /* 0x3F40B6C6, 0x89B99C00 */ +a8 = 2.20862790713908385557e-04, /* 0x3F2CF2EC, 0xED10E54D */ +a9 = 1.08011567247583939954e-04, /* 0x3F1C5088, 0x987DFB07 */ +a10 = 2.52144565451257326939e-05, /* 0x3EFA7074, 0x428CFA52 */ +a11 = 4.48640949618915160150e-05, /* 0x3F07858E, 0x90A45837 */ +tc = 1.46163214496836224576e+00, /* 0x3FF762D8, 0x6356BE3F */ +tf = -1.21486290535849611461e-01, /* 0xBFBF19B9, 0xBCC38A42 */ +/* tt = -(tail of tf) */ +tt = -3.63867699703950536541e-18, /* 0xBC50C7CA, 0xA48A971F */ +t0 = 4.83836122723810047042e-01, /* 0x3FDEF72B, 0xC8EE38A2 */ +t1 = -1.47587722994593911752e-01, /* 0xBFC2E427, 0x8DC6C509 */ +t2 = 6.46249402391333854778e-02, /* 0x3FB08B42, 0x94D5419B */ +t3 = -3.27885410759859649565e-02, /* 0xBFA0C9A8, 0xDF35B713 */ +t4 = 1.79706750811820387126e-02, /* 0x3F9266E7, 0x970AF9EC */ +t5 = -1.03142241298341437450e-02, /* 0xBF851F9F, 0xBA91EC6A */ +t6 = 6.10053870246291332635e-03, /* 0x3F78FCE0, 0xE370E344 */ +t7 = -3.68452016781138256760e-03, /* 0xBF6E2EFF, 0xB3E914D7 */ +t8 = 2.25964780900612472250e-03, /* 0x3F6282D3, 0x2E15C915 */ +t9 = -1.40346469989232843813e-03, /* 0xBF56FE8E, 0xBF2D1AF1 */ +t10 = 8.81081882437654011382e-04, /* 0x3F4CDF0C, 0xEF61A8E9 */ +t11 = -5.38595305356740546715e-04, /* 0xBF41A610, 0x9C73E0EC */ +t12 = 3.15632070903625950361e-04, /* 0x3F34AF6D, 0x6C0EBBF7 */ +t13 = -3.12754168375120860518e-04, /* 0xBF347F24, 0xECC38C38 */ +t14 = 3.35529192635519073543e-04, /* 0x3F35FD3E, 0xE8C2D3F4 */ +u0 = -7.72156649015328655494e-02, /* 0xBFB3C467, 0xE37DB0C8 */ +u1 = 6.32827064025093366517e-01, /* 0x3FE4401E, 0x8B005DFF */ +u2 = 1.45492250137234768737e+00, /* 0x3FF7475C, 0xD119BD6F */ +u3 = 9.77717527963372745603e-01, /* 0x3FEF4976, 0x44EA8450 */ +u4 = 2.28963728064692451092e-01, /* 0x3FCD4EAE, 0xF6010924 */ +u5 = 1.33810918536787660377e-02, /* 0x3F8B678B, 0xBF2BAB09 */ +v1 = 2.45597793713041134822e+00, /* 0x4003A5D7, 0xC2BD619C */ +v2 = 2.12848976379893395361e+00, /* 0x40010725, 0xA42B18F5 */ +v3 = 7.69285150456672783825e-01, /* 0x3FE89DFB, 0xE45050AF */ +v4 = 1.04222645593369134254e-01, /* 0x3FBAAE55, 0xD6537C88 */ +v5 = 3.21709242282423911810e-03, /* 0x3F6A5ABB, 0x57D0CF61 */ +s0 = -7.72156649015328655494e-02, /* 0xBFB3C467, 0xE37DB0C8 */ +s1 = 2.14982415960608852501e-01, /* 0x3FCB848B, 0x36E20878 */ +s2 = 3.25778796408930981787e-01, /* 0x3FD4D98F, 0x4F139F59 */ +s3 = 1.46350472652464452805e-01, /* 0x3FC2BB9C, 0xBEE5F2F7 */ +s4 = 2.66422703033638609560e-02, /* 0x3F9B481C, 0x7E939961 */ +s5 = 1.84028451407337715652e-03, /* 0x3F5E26B6, 0x7368F239 */ +s6 = 3.19475326584100867617e-05, /* 0x3F00BFEC, 0xDD17E945 */ +r1 = 1.39200533467621045958e+00, /* 0x3FF645A7, 0x62C4AB74 */ +r2 = 7.21935547567138069525e-01, /* 0x3FE71A18, 0x93D3DCDC */ +r3 = 1.71933865632803078993e-01, /* 0x3FC601ED, 0xCCFBDF27 */ +r4 = 1.86459191715652901344e-02, /* 0x3F9317EA, 0x742ED475 */ +r5 = 7.77942496381893596434e-04, /* 0x3F497DDA, 0xCA41A95B */ +r6 = 7.32668430744625636189e-06, /* 0x3EDEBAF7, 0xA5B38140 */ +w0 = 4.18938533204672725052e-01, /* 0x3FDACFE3, 0x90C97D69 */ +w1 = 8.33333333333329678849e-02, /* 0x3FB55555, 0x5555553B */ +w2 = -2.77777777728775536470e-03, /* 0xBF66C16C, 0x16B02E5C */ +w3 = 7.93650558643019558500e-04, /* 0x3F4A019F, 0x98CF38B6 */ +w4 = -5.95187557450339963135e-04, /* 0xBF4380CB, 0x8C0FE741 */ +w5 = 8.36339918996282139126e-04, /* 0x3F4B67BA, 0x4CDAD5D1 */ +w6 = -1.63092934096575273989e-03; /* 0xBF5AB89D, 0x0B9E43E4 */ + +static const double zero= 0.00000000000000000000e+00; + + static double sin_pi(double x) +{ + double y,z; + int n,ix; + + GET_HIGH_WORD(ix,x); + ix &= 0x7fffffff; + + if(ix<0x3fd00000) return __kernel_sin(pi*x,zero,0); + y = -x; /* x is assume negative */ + + /* + * argument reduction, make sure inexact flag not raised if input + * is an integer + */ + z = floor(y); + if(z!=y) { /* inexact anyway */ + y *= 0.5; + y = 2.0*(y - floor(y)); /* y = |x| mod 2.0 */ + n = (int) (y*4.0); + } else { + if(ix>=0x43400000) { + y = zero; n = 0; /* y must be even */ + } else { + if(ix<0x43300000) z = y+two52; /* exact */ + GET_LOW_WORD(n,z); + n &= 1; + y = n; + n<<= 2; + } + } + switch (n) { + case 0: y = __kernel_sin(pi*y,zero,0); break; + case 1: + case 2: y = __kernel_cos(pi*(0.5-y),zero); break; + case 3: + case 4: y = __kernel_sin(pi*(one-y),zero,0); break; + case 5: + case 6: y = -__kernel_cos(pi*(y-1.5),zero); break; + default: y = __kernel_sin(pi*(y-2.0),zero,0); break; + } + return -y; +} + + +OLM_DLLEXPORT double +__ieee754_lgamma_r(double x, int *signgamp) +{ + double t,y,z,nadj,p,p1,p2,p3,q,r,w; + int32_t hx; + int i,lx,ix; + + EXTRACT_WORDS(hx,lx,x); + + /* purge off +-inf, NaN, +-0, tiny and negative arguments */ + *signgamp = 1; + ix = hx&0x7fffffff; + if(ix>=0x7ff00000) return x*x; + if((ix|lx)==0) return one/zero; + if(ix<0x3b900000) { /* |x|<2**-70, return -log(|x|) */ + if(hx<0) { + *signgamp = -1; + return -__ieee754_log(-x); + } else return -__ieee754_log(x); + } + if(hx<0) { + if(ix>=0x43300000) /* |x|>=2**52, must be -integer */ + return one/zero; + t = sin_pi(x); + if(t==zero) return one/zero; /* -integer */ + nadj = __ieee754_log(pi/fabs(t*x)); + if(t=0x3FE76944) {y = one-x; i= 0;} + else if(ix>=0x3FCDA661) {y= x-(tc-one); i=1;} + else {y = x; i=2;} + } else { + r = zero; + if(ix>=0x3FFBB4C3) {y=2.0-x;i=0;} /* [1.7316,2] */ + else if(ix>=0x3FF3B4C4) {y=x-tc;i=1;} /* [1.23,1.73] */ + else {y=x-one;i=2;} + } + switch(i) { + case 0: + z = y*y; + p1 = a0+z*(a2+z*(a4+z*(a6+z*(a8+z*a10)))); + p2 = z*(a1+z*(a3+z*(a5+z*(a7+z*(a9+z*a11))))); + p = y*p1+p2; + r += (p-0.5*y); break; + case 1: + z = y*y; + w = z*y; + p1 = t0+w*(t3+w*(t6+w*(t9 +w*t12))); /* parallel comp */ + p2 = t1+w*(t4+w*(t7+w*(t10+w*t13))); + p3 = t2+w*(t5+w*(t8+w*(t11+w*t14))); + p = z*p1-(tt-w*(p2+y*p3)); + r += (tf + p); break; + case 2: + p1 = y*(u0+y*(u1+y*(u2+y*(u3+y*(u4+y*u5))))); + p2 = one+y*(v1+y*(v2+y*(v3+y*(v4+y*v5)))); + r += (-0.5*y + p1/p2); + } + } + else if(ix<0x40200000) { /* x < 8.0 */ + i = (int)x; + y = x-(double)i; + p = y*(s0+y*(s1+y*(s2+y*(s3+y*(s4+y*(s5+y*s6)))))); + q = one+y*(r1+y*(r2+y*(r3+y*(r4+y*(r5+y*r6))))); + r = half*y+p/q; + z = one; /* lgamma(1+s) = log(s) + lgamma(s) */ + switch(i) { + case 7: z *= (y+6.0); /* FALLTHRU */ + case 6: z *= (y+5.0); /* FALLTHRU */ + case 5: z *= (y+4.0); /* FALLTHRU */ + case 4: z *= (y+3.0); /* FALLTHRU */ + case 3: z *= (y+2.0); /* FALLTHRU */ + r += __ieee754_log(z); break; + } + /* 8.0 <= x < 2**58 */ + } else if (ix < 0x43900000) { + t = __ieee754_log(x); + z = one/x; + y = z*z; + w = w0+z*(w1+y*(w2+y*(w3+y*(w4+y*(w5+y*w6))))); + r = (x-half)*(t-one)+w; + } else + /* 2**58 <= x <= inf */ + r = x*(__ieee754_log(x)-one); + if(hx<0) r = nadj - r; + return r; +} diff --git a/src/openlibm/src/e_lgamma_r.c.o b/src/openlibm/src/e_lgamma_r.c.o new file mode 100644 index 0000000000000000000000000000000000000000..33d8c6054193ed6715aa2a62c403b1262922d2d9 GIT binary patch literal 9888 zcmb<-^>JfjWMqH=Mg}_u1P><4z>uJXU^{@B4h(_}0t}9!Y5W=&97EDP`Rk7Oc0LXD zJor{2*roGr&xpqU$}5SD2eds{0$Q6w=UOpZGFq% zF@=$V;RVRtG=7Z}Y5d{5Aht*I5sm2BG=7bPjxmn0hxz3l7+hQ5Rz`z#>O1qd^)oUs zq^0Tc%eR13Gl1kj@e6>prt!Z&@QFX}1jq=G0nxEwBPM{12Z?>+k30bp1IZpvgPGCW z%D^CSAdUb1Nsu!Sg18I^K+J89-;XjdFgWnHW->7_H2ytv=8ZjnTL2q~eQ3*Xd;T_i zRtAPo`~s>Vx1{mEzx|0n=205I#+y(40<0jhPy7O+5IXYBC;rHzpZFuMe&UaS%0(P51HaIP`g3)MLhk)A9n|o-kN`~@VB@B{r}&i7aSZO z$t+DCj2HetNaNQyittm!t55uqFAyFAC0J1Af%zFG56eJ;KA@Npi~&Vg)+V|NsBQ z9|_JW5VfG>ha;tb;*U9jWaY_E{E-Jg@#`D_g-732CI*J)7p%=c82Q^5fa5#{YN~)K zB#t4;T(AU^#6b!C6My6}Sh9pB@|SYZB-QWC-~JU;O!9+MH`w!nA&C43O$`DeVB?U2 zS-=OBCpEr&;*WXri9hbsC;k|4EP+aoG=7bHpZFs|_%Nab17(^RXlVvw!%8*~8!mnW zkrF}r;i>Z0%i7|Y=~QNi$`4j#1AqT zQbmBO2T0Kib9=;%mleO@1rcggHU4$Zd~Od;a?nJa#*Zk=_}i8L4UtL#;zk-LNA3r3Kgp5a)u@$S3|7 zQ2fBmgoXyVr~?&&P;rzZkc#54cm&%A%`D*J4wNP@eBzI|^>W4!P>?|!-1s+P*;#x3 zHg9mnib(7)g&-x<>6iB3|NjSNdYt%!y@aky$ZthXNRy1=fjva20F-aw4B`KPiZeL; z`4QEd*nQXDeqUJfjim4PLBD#ON(z42`92kR`{t95eXM=H;FPXl`xo!~xA{BN*)LBD zm13~lXn$fu?c?+#o9)dbmQ3htWw&SlT|1*AK*pY7&d$zb+Z^n(Cv87-V{N*9b;zVO zO2Sj^*YYnr;_1BB?(h2-X7BR2;PHb$752j0P4BNbxxjvr#k&*Q z-|yLfxqRq_-CtAtHxG*E2rP577dk5kv-Jv$}$ z+jFkg-rt?xZLh+~_-&ovS^I#NS1x6q@9p#VN?wd{|8D<3mZ4kD;fa0X`3vE@qq6Kf zYJ#tYuG?k5J|N)9@3}ARze;E?QDtXzn3K5o(DkLv(C~e*-}R;V-8cIg>@7cK6mL_D zvrn8kxlYDow*B`{PxsB)eaJp?zOaA)%`5g59FNSpTTa_MG;Ut{eb+s^=#`GAZq<6) zmtN5;c_lvCUj6>>GjAD>+26Tyd9sAmbNiCjN0OGieuKuF1k^qeD9z#U#Caa~+#ON- zFJ8Unvn$=(-tjqq&*=td`)wBIXUu2xvX9Z*AeM75&E7f`1h(2|)}Ea3`1~!Xc?=DZ zbiu&D;O^{frJ&*N7pkdXXrgDNXQ*IgU}S1wXlS6I5tN#u;E`AYmC!ZUWME)nU|>*S zU|;}cC3nA21||l^10XR_6CY$IBb3hx;xI5Uh(Kw^svri&3IRrG9(Ilij0_Ah3=9l1 zP`N~qVkbUX8bL&Ynd}S& zU>ZThgPH6M3&1pjNCh+583e#Ig2)0h*}-WM%!Cs8V49r)J!VRv;vJv_0A@poDlo;) zumepTl0n!RKxq}M1WL4lX?BJKXzF{Q;xo|1Cqczepov4mg`Hsmn)p1Z`U_~{OQ7N_ z(8O0k#c!aAZ-9z#Koj2v6@P#xz6UD)0Zsf6R2-6i!5lDg989t^{6JHG7ApP%P5d%c zTmwuah#O!gI|Bm~m;op5fm!Sf9BATCpyC2(;;*3M5@_NdpyCQ>;@_a+pq3_>2_^o3 zX?6xse+$fn5=>zKurojlV5leq0|!)m1zZHe;Dd@o;sGKCB1NF$J3t&HECm%mfFuTD zDnP|gfH+844Jv*CNesl)fr>-I6(j<|Mo{qw5H6gwfQp0r4{%Wi20N%YB>WH(E>Q6w z2q7@b3o4FYga$yxA>jm83MRs!;sRhAECeQEzJitO=A_FR} z0j9x1U?LC9XJ;?~(_kSmQ3B?(Gem%Cun?H20`u7!AmITP0uv2T@dPjp76KD(U_Lv8 z1DFO2fr%b4pPd2XF0c@om;@E~0MlS0Faaqq*cl4Y#OHze>Yn0 zCRTy@>%HBSb%v5Vk;v9gAh_=f$Lxf28Ml%3>alCNY^18;-GR3y=(@l zzluZsEga$usqs1KiMhFn@kM&c40=A!Mj*lvL|A|bLon0O9L$EuLBx&0B9>s%1VkDc zfJj4A5NQO_Wd>%0b%B+D`CyHvUF}U|l9)GflvHO~HCC8DKHSkdvRzkd~95U&Ig}pPgEimzon_oSDavmY7tG5J}E2 zW?+D{7a;9O5c>~kxa|M`|B!Y8q#6LVCt>1KK#7R~A`WVE!o-Ea=^Y}@#=yV;6IVwP z2erar;`&J9ptb=_+!;w6)C`4*dn1W+A(YtC7Toki>T*iG$jzFms+Di6e*qcc?f>3^~63 zL&ZVWDo74yjtWQs8ehobmQZn!m>-gRVxi(73e;DCnbQgqfSLp9O2fpLK*d4k_#>IK z4JrGsDC`A&DdV%Yqq_;6T#I=2Rewiy_(DfFv%CB;J7}j+}01 zBZ(u2|7s+0P+JS;&do^Tl1SzsM-rDp5%xIB_LKPa%E@dfH1!pspz5?4f0uZ|>+oNnEb#6ecU%!xq~2Teu6#B-3uL478e zcny-c3X;7&NaD!l#!{#_h(b;eCqM#Fe}RURVCLUJ5=Ty--=X3l3ORl9ff51K9OQUc zhKhsKBj*cis5mGcBKs=^Nn8!dUpYwP$nNQcii6A#L{h&KNgUa~2chC1dqGT?e=mbL zQ1`1Nne!G&9NAy2pumNy2etWO<_IE*gZi>CaakmBEhO_bk;Ju;#7&XJb&$jzk;Fkm zvoQ0Mki_+n)E6O%gZj`g^<7BfpgucHd>WFtA(AfMmUL4#8;^(jzsP`X7yI#e9w ze&qaH2^9yqA0!8}w+%@g*1jRQEE=2UP)?234>lrVo4%{UQ%%} zgC1D4C?6sMq4koBODq`l5FA4@2EF9`+}zZ>5(d4z{E}2XcfU~G;*!MVY$!iHuT-y~ zD8C@JsH75VW@<)!T2W#yWaJL)HVO!ke?d)6P~Ji|29$` zf)1u0BnH9-phg@61H%bWPH{nN7vs9EmP3rZv!;`VDSWsKai0y{V;Kmf6(m)x$Oo> zF#`j`29W0%7#Ki(O& + +#include "math_private.h" + +OLM_DLLEXPORT float +__ieee754_lgammaf(float x) +{ +#ifdef OPENLIBM_ONLY_THREAD_SAFE + int signgam; +#endif + + return __ieee754_lgammaf_r(x,&signgam); +} diff --git a/src/openlibm/src/e_lgammaf.c.o b/src/openlibm/src/e_lgammaf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..d60533df65b211e93e6245bf89cb481077f8e2f2 GIT binary patch literal 1472 zcmb<-^>JfjWMqH=Mg}_u1P><4z|g>iU^{@B4h*~uJPaP)wjkb15W(Q?>};i=;qDiz zsbFZLXQXGSU}RuqYG7z+pr8?ynxf#5SOS&MHP-~|U|?ZjU{GLSU|?lnU~u;fWnf}p zJOC1d$TBc6LisQ^i9jV7tAZF9D+Cy&dDuB7FfuTJ#ATpzJWv`R1u~C?;p2a7YM8Nv z051argAkH9%nnfo1_l8vhG^puH^w2(kQ$$po|v1Pn5LJ^0A(@6yZiV%Ir_x=ySW9s zhQx{!n2C z9~c9Th8hbO)nR~`Nv?iFsQoZ^!VHGluMZP|(lGmBv=vl8R2oiI!&#^dm_C@O7Xt$W zI|Bm)N*ZEdU}%6UKzA1`{GiedNl^RI^>2VGAf!JQNBsSOIusU9p!fsX4Z + +#include "math_private.h" + +static const float +two23= 8.3886080000e+06, /* 0x4b000000 */ +half= 5.0000000000e-01, /* 0x3f000000 */ +one = 1.0000000000e+00, /* 0x3f800000 */ +pi = 3.1415927410e+00, /* 0x40490fdb */ +a0 = 7.7215664089e-02, /* 0x3d9e233f */ +a1 = 3.2246702909e-01, /* 0x3ea51a66 */ +a2 = 6.7352302372e-02, /* 0x3d89f001 */ +a3 = 2.0580807701e-02, /* 0x3ca89915 */ +a4 = 7.3855509982e-03, /* 0x3bf2027e */ +a5 = 2.8905137442e-03, /* 0x3b3d6ec6 */ +a6 = 1.1927076848e-03, /* 0x3a9c54a1 */ +a7 = 5.1006977446e-04, /* 0x3a05b634 */ +a8 = 2.2086278477e-04, /* 0x39679767 */ +a9 = 1.0801156895e-04, /* 0x38e28445 */ +a10 = 2.5214456400e-05, /* 0x37d383a2 */ +a11 = 4.4864096708e-05, /* 0x383c2c75 */ +tc = 1.4616321325e+00, /* 0x3fbb16c3 */ +tf = -1.2148628384e-01, /* 0xbdf8cdcd */ +/* tt = -(tail of tf) */ +tt = 6.6971006518e-09, /* 0x31e61c52 */ +t0 = 4.8383611441e-01, /* 0x3ef7b95e */ +t1 = -1.4758771658e-01, /* 0xbe17213c */ +t2 = 6.4624942839e-02, /* 0x3d845a15 */ +t3 = -3.2788541168e-02, /* 0xbd064d47 */ +t4 = 1.7970675603e-02, /* 0x3c93373d */ +t5 = -1.0314224288e-02, /* 0xbc28fcfe */ +t6 = 6.1005386524e-03, /* 0x3bc7e707 */ +t7 = -3.6845202558e-03, /* 0xbb7177fe */ +t8 = 2.2596477065e-03, /* 0x3b141699 */ +t9 = -1.4034647029e-03, /* 0xbab7f476 */ +t10 = 8.8108185446e-04, /* 0x3a66f867 */ +t11 = -5.3859531181e-04, /* 0xba0d3085 */ +t12 = 3.1563205994e-04, /* 0x39a57b6b */ +t13 = -3.1275415677e-04, /* 0xb9a3f927 */ +t14 = 3.3552918467e-04, /* 0x39afe9f7 */ +u0 = -7.7215664089e-02, /* 0xbd9e233f */ +u1 = 6.3282704353e-01, /* 0x3f2200f4 */ +u2 = 1.4549225569e+00, /* 0x3fba3ae7 */ +u3 = 9.7771751881e-01, /* 0x3f7a4bb2 */ +u4 = 2.2896373272e-01, /* 0x3e6a7578 */ +u5 = 1.3381091878e-02, /* 0x3c5b3c5e */ +v1 = 2.4559779167e+00, /* 0x401d2ebe */ +v2 = 2.1284897327e+00, /* 0x4008392d */ +v3 = 7.6928514242e-01, /* 0x3f44efdf */ +v4 = 1.0422264785e-01, /* 0x3dd572af */ +v5 = 3.2170924824e-03, /* 0x3b52d5db */ +s0 = -7.7215664089e-02, /* 0xbd9e233f */ +s1 = 2.1498242021e-01, /* 0x3e5c245a */ +s2 = 3.2577878237e-01, /* 0x3ea6cc7a */ +s3 = 1.4635047317e-01, /* 0x3e15dce6 */ +s4 = 2.6642270386e-02, /* 0x3cda40e4 */ +s5 = 1.8402845599e-03, /* 0x3af135b4 */ +s6 = 3.1947532989e-05, /* 0x3805ff67 */ +r1 = 1.3920053244e+00, /* 0x3fb22d3b */ +r2 = 7.2193557024e-01, /* 0x3f38d0c5 */ +r3 = 1.7193385959e-01, /* 0x3e300f6e */ +r4 = 1.8645919859e-02, /* 0x3c98bf54 */ +r5 = 7.7794247773e-04, /* 0x3a4beed6 */ +r6 = 7.3266842264e-06, /* 0x36f5d7bd */ +w0 = 4.1893854737e-01, /* 0x3ed67f1d */ +w1 = 8.3333335817e-02, /* 0x3daaaaab */ +w2 = -2.7777778450e-03, /* 0xbb360b61 */ +w3 = 7.9365057172e-04, /* 0x3a500cfd */ +w4 = -5.9518753551e-04, /* 0xba1c065c */ +w5 = 8.3633989561e-04, /* 0x3a5b3dd2 */ +w6 = -1.6309292987e-03; /* 0xbad5c4e8 */ + +static const float zero= 0.0000000000e+00; + + static float sin_pif(float x) +{ + float y,z; + int n,ix; + + GET_FLOAT_WORD(ix,x); + ix &= 0x7fffffff; + + if(ix<0x3e800000) return __kernel_sindf(pi*x); + y = -x; /* x is assume negative */ + + /* + * argument reduction, make sure inexact flag not raised if input + * is an integer + */ + z = floorf(y); + if(z!=y) { /* inexact anyway */ + y *= (float)0.5; + y = (float)2.0*(y - floorf(y)); /* y = |x| mod 2.0 */ + n = (int) (y*(float)4.0); + } else { + if(ix>=0x4b800000) { + y = zero; n = 0; /* y must be even */ + } else { + if(ix<0x4b000000) z = y+two23; /* exact */ + GET_FLOAT_WORD(n,z); + n &= 1; + y = n; + n<<= 2; + } + } + switch (n) { + case 0: y = __kernel_sindf(pi*y); break; + case 1: + case 2: y = __kernel_cosdf(pi*((float)0.5-y)); break; + case 3: + case 4: y = __kernel_sindf(pi*(one-y)); break; + case 5: + case 6: y = -__kernel_cosdf(pi*(y-(float)1.5)); break; + default: y = __kernel_sindf(pi*(y-(float)2.0)); break; + } + return -y; +} + + +OLM_DLLEXPORT float +__ieee754_lgammaf_r(float x, int *signgamp) +{ + float t,y,z,nadj,p,p1,p2,p3,q,r,w; + int32_t hx; + int i,ix; + + GET_FLOAT_WORD(hx,x); + + /* purge off +-inf, NaN, +-0, tiny and negative arguments */ + *signgamp = 1; + ix = hx&0x7fffffff; + if(ix>=0x7f800000) return x*x; + if(ix==0) return one/zero; + if(ix<0x35000000) { /* |x|<2**-21, return -log(|x|) */ + if(hx<0) { + *signgamp = -1; + return -__ieee754_logf(-x); + } else return -__ieee754_logf(x); + } + if(hx<0) { + if(ix>=0x4b000000) /* |x|>=2**23, must be -integer */ + return one/zero; + t = sin_pif(x); + if(t==zero) return one/zero; /* -integer */ + nadj = __ieee754_logf(pi/fabsf(t*x)); + if(t=0x3f3b4a20) {y = one-x; i= 0;} + else if(ix>=0x3e6d3308) {y= x-(tc-one); i=1;} + else {y = x; i=2;} + } else { + r = zero; + if(ix>=0x3fdda618) {y=(float)2.0-x;i=0;} /* [1.7316,2] */ + else if(ix>=0x3F9da620) {y=x-tc;i=1;} /* [1.23,1.73] */ + else {y=x-one;i=2;} + } + switch(i) { + case 0: + z = y*y; + p1 = a0+z*(a2+z*(a4+z*(a6+z*(a8+z*a10)))); + p2 = z*(a1+z*(a3+z*(a5+z*(a7+z*(a9+z*a11))))); + p = y*p1+p2; + r += (p-(float)0.5*y); break; + case 1: + z = y*y; + w = z*y; + p1 = t0+w*(t3+w*(t6+w*(t9 +w*t12))); /* parallel comp */ + p2 = t1+w*(t4+w*(t7+w*(t10+w*t13))); + p3 = t2+w*(t5+w*(t8+w*(t11+w*t14))); + p = z*p1-(tt-w*(p2+y*p3)); + r += (tf + p); break; + case 2: + p1 = y*(u0+y*(u1+y*(u2+y*(u3+y*(u4+y*u5))))); + p2 = one+y*(v1+y*(v2+y*(v3+y*(v4+y*v5)))); + r += (-(float)0.5*y + p1/p2); + } + } + else if(ix<0x41000000) { /* x < 8.0 */ + i = (int)x; + y = x-(float)i; + p = y*(s0+y*(s1+y*(s2+y*(s3+y*(s4+y*(s5+y*s6)))))); + q = one+y*(r1+y*(r2+y*(r3+y*(r4+y*(r5+y*r6))))); + r = half*y+p/q; + z = one; /* lgamma(1+s) = log(s) + lgamma(s) */ + switch(i) { + case 7: z *= (y+(float)6.0); /* FALLTHRU */ + case 6: z *= (y+(float)5.0); /* FALLTHRU */ + case 5: z *= (y+(float)4.0); /* FALLTHRU */ + case 4: z *= (y+(float)3.0); /* FALLTHRU */ + case 3: z *= (y+(float)2.0); /* FALLTHRU */ + r += __ieee754_logf(z); break; + } + /* 8.0 <= x < 2**58 */ + } else if (ix < 0x5c800000) { + t = __ieee754_logf(x); + z = one/x; + y = z*z; + w = w0+z*(w1+y*(w2+y*(w3+y*(w4+y*(w5+y*w6))))); + r = (x-half)*(t-one)+w; + } else + /* 2**58 <= x <= inf */ + r = x*(__ieee754_logf(x)-one); + if(hx<0) r = nadj - r; + return r; +} diff --git a/src/openlibm/src/e_lgammaf_r.c.o b/src/openlibm/src/e_lgammaf_r.c.o new file mode 100644 index 0000000000000000000000000000000000000000..a75fe998d2f687ff24318e4ca294e3f2067f66e5 GIT binary patch literal 9624 zcmb<-^>JfjWMqH=Mg}_u1P><4z!0H`U^{@B4h(_}0t}8}{2C`hgVXry4tL&deER?Y z|9X$+HwwquL54K`{r|tdzC642ZHYUG{okZqz4bPKM>-<|!wZlh{2CYd!$m`8i%4| zq53}aN1gzQfdu$9F7j&}I?ONc!obkm%D~WYAdUb1rIr8x*Z(g${{1im1A_y9D>pL( zL*w7Hv^0DEw)?Cgw)nEU_WW(9Sr|Z;se)`x<9~nqGk?rOevLCQ`#b-Km&OJ?55-F z|NsC0&mVq@U*jM+=wTk=55Mqo`@jGH`Q;lx{_*InQ4s(Ie7zliTR$@c10sq(^9#DD z@bGIK`phpFqQU_)B}9eeGrxe33Xey3jfw!j-Ua@yODqfw{HR;_sJY0|&G%+;&LR3i_z3%r6+D!UOV_1lRz6jSHXo1zbQz z#=(t@0of(sqawhsaRF?Y{^2rikbfi~;RZ=P;FQDP(h0I6oEL1dBY)jBXi93?_V@pP zP{{pv;BWiN017#XGvFZwb}KlnIQTUlz)}#u#_P}gF^@m<$G!Z_9|JZPl&JVMu72i^ z1mQzS>FLmC{upq8e&&zFC4K>s4ng|iY4Rc@U-5UI`1AjNnj?SSx6k}BpZGPdz1;o> z9{&&zlv#l2`WXH;^Z)<p=4h=Fj{wCtw~2X@w+TxD#Psqjk1{nvd|pXa0yIpyC9{ZJ_LYq4@_3fBT7l|NndR zg1zgJ%+ln+c;Wv8evKmtuSGok%pVDl(9ir42S4*iVv&!4#x5xPK;jsl7s0tG;=;=q zP*&79^7;_MB@qW-Pf0_BFRa{wWDr4cN(PlZQ3t^38=StNc~RrW%ZK2obzo@xE5B^6 zJ%8IRMo?~pBr{O42F@#xA{7)D;B*-Y^3Ijd{P5rbl_+5Ef98+GB@W6}u;@F2luC~v zrCwa(2S4)*K!XNUn!){)x~0F&7bTkGTAj^Y8!v@bCls zSI`Gqd^P@+_p-JJ2N?%Hyg1=+O9h7#Eak>Le980+lno-mfdDE?1i%Fhp~CPpe+*Kv zL|lSoTAc%+RMoeLk%6K41#9yUM*enhuzj%b7C@AR5NjZ1Ah_g>JpP#cY75)Z=Da65zf7y+5?fBcg!Nml`1$`o$YWS>gZ*uOPf&Bqo`InOM0+zZ9Iyv9TzI12*c}$zZNI4bvU&RSbjyVy zbFAu^K3Ow<=(M$0o@ZOCV`Jgk^2owu8>`i^JX>qgnJaA4q?X!cS1+|J`?B4N{rPcg zcV9N!xSikazQ0^=*=oRRHB(H)`rjW78_}p1TlJrdcc%YHv-($FXl-jg*~Ugu+%8Dw znc>;9KWyV{qHQWlv+Oo`SJ^+e+GYQRLCOC1)gbHjMOSU_zjv|Mwd8QvrzZY7_GoeHjm}Y0N0MiH}0nB7)2msRvA`Q%BXFw0> zY^b;Zm_`r-WM?=5rV+$OFq56(0hmS*+rdnB zhBIIqLF@%H*%_XIX#@f4 z;xbV26oe3%r34kv0P_%p22?x;Ap~aWLB%2Y04xM1OrYW=U><_7f{IrlgupBZsCW&S zhalXb;;5Ad1A`A#95Tv)P#**p??4EFSrJh29xx9<#6iU;AcVlI6sY(VFb_dwLB%2E zEaai377Gz*x*v81fAcRyH zg6muc28IKS3=HUHDoD>!9O7qih~LH`{t$;aLu!0ZdSY&FVp@EWUNVE8kFyboFa!}6 zAi@yLG&BdZA#xCLW3Y%Nm^1;AMg}0#&=f=(L3Ejc*Nx&R2(FR9AA5(;-K&W$-&e=$07b3 zDh^T$YCFQzD}xMRfcO_wmczuokiGra)~> znD~Aqab$n}f{KGEWOG!RAqf{GhOAx}Dh^VQoIdT4#Kn-@8Hgl~9R3+d;^Ii^OOV7t zeF&KQ8<507eGHg*50bbPk~uSw#HEqMmmrCQ>I#@Suc6}T{`~_LNB6G`NFg*HLF2VB zb5xMTk;BIvNgUJ{f~j{$5|>AEr$3T7sNV@wACDvsnreZGrz43gA(>N-B(97kUXLUW z>Vv_|=|>U=4ama8rz450A(^urNn9OCd_9sls1FA-XFrlSa{j%HB#xX;UL%Qvq5@{l zeIfAFS%aMZW1-@p^Z@E>!ptv05=YLz zy-;zGImr2U2UHwn4rss%X3lXWaXln=-a``CM-qR9Bo6A!!p!-GByNbLo(behX!sZ* ziSr?e8zYH>W?euf0mz-8zAwytH6-<>Na~G{#6f*>n0h-TadRZ~UP$7gzA{XG7?QXp zlKLbhaZud~Q=f+K(SLB&Dwh@2iSK*d4f z1CoQOzlS6aiVB$cdn9q>bj|^)yrJbba($r+6$hD*oSyxV#6bgnF!RHZ#F5isIaD0v z#z3U-nFJLFnUCzwMM&bHu@;#5tB}MUk<8hJBn}!|fvG=)B<_r){t}Wns4WCje+x<6 z6-oUoByl$+@lQzN?nvTHphgcgorA`5VCHiniF+ccmqHRpE|=7h#J!NzJ0poBhg&$3 zxHppe6eMwE^*Ko5$niB3NgR}9VD4XtB#x~95L6r#zsTjxb*MNfenE0DbN(WUBd0@F zP@@nUZph}VL&ZU6Ag3Q2s5rX$pfUr5LE<2+4e~TJeItuQX22QX<6a=OAS?`34{BQ? zt7n0VgW811;+ar!P+f^E4q}6`UU6k^Nn#R%UU5kggwBAmic)hD^-5AJN*MG~5=#;p z^pc8;8T7!SMfngB2(6b~Tw=nYhu|2RG3X`d=jNv7l`!b#<(H)Dx%-9c7MCO@XG8hv zd8K*;yR5Qc>thz-J^ zwh<^!Vd_C*AZ!7OdPle_%Irz z7RCnApgI&}Cb{}SbqvT%P?`am2g4mu`$27Nm>7r#`4vRNFsN<>iJ|-702Htc3=FXG zB9Q+o!*ihaL&m#cqL6+dhzGJ0M1#r*Z2AvC!yP@o zV0;)I$p9JZ1=al^^I-S_R6nS#022ezAiI$1B&dFn7&873)sHL&V#D-<*dScQ02(!g z^k+bPI0khV85l6e*J0rYQ`ZHxA3gpIp!(6r1JU)jLdz8N_*(&uKUh40;ty1o!1Tk! zLHlaYp6f}2(t{)W5=xG==uQwAe}b= literal 0 HcmV?d00001 diff --git a/src/openlibm/src/e_lgammal.c b/src/openlibm/src/e_lgammal.c new file mode 100644 index 0000000..c1bfb25 --- /dev/null +++ b/src/openlibm/src/e_lgammal.c @@ -0,0 +1,15 @@ +#include "cdefs-compat.h" + +#include + +#include "math_private.h" + +OLM_DLLEXPORT long double +lgammal(long double x) +{ +#ifdef OPENLIBM_ONLY_THREAD_SAFE + int signgam; +#endif + + return (lgammal_r(x, &signgam)); +} diff --git a/src/openlibm/src/e_lgammal.c.o b/src/openlibm/src/e_lgammal.c.o new file mode 100644 index 0000000000000000000000000000000000000000..6536c61b34983b0e5276e92de41700738579bb1b GIT binary patch literal 1472 zcmb<-^>JfjWMqH=Mg}_u1P><4z|g>iU^{@B4h*~uJPaP)wjkb15W(Q?>};i=;qDiz zsbFZLXQXGSU}RuqYG7z+pr8?ynxf#5SOS&MHP-~|U|?ZjU{GLSU|?lnU~u;fWnf}p zJOC1d$TBc6LisQ^i9jV7tAZF9D+Cy&dDuB7FfuTJ#ATpzJWv`R1u~C?;p2a7YM8Nv z051argAkH9%nnfo1_l8vhG^puH^w2(kQ$$po|v1Pn4_1>0A(@6yZiV%Ir_x=ySW9s zhQx{!n2C z9~c9Th8hbO)nR~`Nv?iFsQoZ^!VHGluMZP|(lGmBv=vl8R2oiI!&#^dm_C@O7Xt$W zI|Bm)N*ZEdU}%6UKzA1`{GiedNl^RI^>2VGAf!JQNBsSOIusU9p!fsX4Z +#include + +#include "math_private.h" + +static const double +ln2_hi = 6.93147180369123816490e-01, /* 3fe62e42 fee00000 */ +ln2_lo = 1.90821492927058770002e-10, /* 3dea39ef 35793c76 */ +two54 = 1.80143985094819840000e+16, /* 43500000 00000000 */ +Lg1 = 6.666666666666735130e-01, /* 3FE55555 55555593 */ +Lg2 = 3.999999999940941908e-01, /* 3FD99999 9997FA04 */ +Lg3 = 2.857142874366239149e-01, /* 3FD24924 94229359 */ +Lg4 = 2.222219843214978396e-01, /* 3FCC71C5 1D8E78AF */ +Lg5 = 1.818357216161805012e-01, /* 3FC74664 96CB03DE */ +Lg6 = 1.531383769920937332e-01, /* 3FC39A09 D078C69F */ +Lg7 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */ + +static const double zero = 0.0; + +OLM_DLLEXPORT double +__ieee754_log(double x) +{ + double hfsq,f,s,z,R,w,t1,t2,dk; + int32_t k,hx,i,j; + u_int32_t lx; + + EXTRACT_WORDS(hx,lx,x); + + k=0; + if (hx < 0x00100000) { /* x < 2**-1022 */ + if (((hx&0x7fffffff)|lx)==0) + return -two54/zero; /* log(+-0)=-inf */ + if (hx<0) return (x-x)/zero; /* log(-#) = NaN */ + k -= 54; x *= two54; /* subnormal number, scale up x */ + GET_HIGH_WORD(hx,x); + } + if (hx >= 0x7ff00000) return x+x; + k += (hx>>20)-1023; + hx &= 0x000fffff; + i = (hx+0x95f64)&0x100000; + SET_HIGH_WORD(x,hx|(i^0x3ff00000)); /* normalize x or x/2 */ + k += (i>>20); + f = x-1.0; + if((0x000fffff&(2+hx))<3) { /* -2**-20 <= f < 2**-20 */ + if(f==zero) { + if(k==0) { + return zero; + } else { + dk=(double)k; + return dk*ln2_hi+dk*ln2_lo; + } + } + R = f*f*(0.5-0.33333333333333333*f); + if(k==0) return f-R; else {dk=(double)k; + return dk*ln2_hi-((R-dk*ln2_lo)-f);} + } + s = f/(2.0+f); + dk = (double)k; + z = s*s; + i = hx-0x6147a; + w = z*z; + j = 0x6b851-hx; + t1= w*(Lg2+w*(Lg4+w*Lg6)); + t2= z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7))); + i |= j; + R = t2+t1; + if(i>0) { + hfsq=0.5*f*f; + if(k==0) return f-(hfsq-s*(hfsq+R)); else + return dk*ln2_hi-((hfsq-(s*(hfsq+R)+dk*ln2_lo))-f); + } else { + if(k==0) return f-s*(f-R); else + return dk*ln2_hi-((s*(f-R)-dk*ln2_lo)-f); + } +} + +#if (LDBL_MANT_DIG == 53) +openlibm_weak_reference(log, logl); +#endif diff --git a/src/openlibm/src/e_log.c.o b/src/openlibm/src/e_log.c.o new file mode 100644 index 0000000000000000000000000000000000000000..e9a585b3fde3b55c22cf22638165774a622df0c6 GIT binary patch literal 3160 zcmb<-^>JfjWMqH=Mg}_u1P><4z;J^D!FB*M9T@l+cp1_>`0EaObe`}y_(GxcknR8f z{0#j4*BKZX8Xx`t|G%E|6o1P~Mh1q~1N>li zYp%(_z{0@5puoVu07{8?ayyxz3_KLbd=`d}|FJ1y#!^y1>}O>_DlWiU`M@MAg8-OD5W-+4D}w}>Mi3A_ zE7;EnQ3eKZ!eU@$us{}MU|>)J^H~`nWfPbKCe*VugYT z237_QFpVIh7#J9Ykis7xm#OhN`RRJe40=A!Mj*l%M3{gGQxIVRA}m3Kp#hjQ1e0K; zhG4aZV8w=D)#hMH5MjoUlb_DOzyJv!1_n^lVP;@p`12nE=0KeW5(lMAnD`|maggs| z;*XHT*^tcP0VOyFi23YD;^s)=ptJ=uCm2Z_l=fia@kruaNakcCiE|@~mm`VuAc;34 ziGxaJnECxk;-It*69-jxAg_VKfgj17D@f`=c>t#V4U)JZlKL-5;>hMmfDDF)4{~^F zAc-S~X9$uwvibxhab)#Vki?PIFF+DURu3wZVE%rFsQL`30#(C6x?%VB=CV;?s%}b5kLfQ%-{X1&RWYUy)6Nl`ru829*TG zDU=DOq!}P(HcUNOkb!~00BWEBG_XKv5M&Q1O@q`x$~^`KH3kN7?gr&CkT?wggzAIw zVKm4L7#l?EFff42U~=^vLhTm<8HS9Z238=8LG1zw!Tezd)sJ4zRY3LYgA^lSnEPS0 zJ5)cC5-@W)R6m%5M8NdHgu)pZ7(nF*dT_0P>PL4M%-t~k`B3}O_1_>;e-@7TcYs<1 zi)T>$gUT(aFuWcF`3K!@klQ#wg)0LC!wHZA1_lODSp|wCbp0SRp-u&9gX0UJOwGW+ f5C<25FrdakI1CI7pt1;?{s^c=m2j012D*L#!){oO literal 0 HcmV?d00001 diff --git a/src/openlibm/src/e_log10.c b/src/openlibm/src/e_log10.c new file mode 100644 index 0000000..8e3c4e0 --- /dev/null +++ b/src/openlibm/src/e_log10.c @@ -0,0 +1,93 @@ + +/* @(#)e_log10.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/e_log10.c,v 1.15 2011/10/15 05:23:28 das Exp $"); + +/* + * Return the base 10 logarithm of x. See e_log.c and k_log.h for most + * comments. + * + * log10(x) = (f - 0.5*f*f + k_log1p(f)) / ln10 + k * log10(2) + * in not-quite-routine extra precision. + */ + +#include +#include + +#include "math_private.h" +#include "k_log.h" + +static const double +two54 = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */ +ivln10hi = 4.34294481878168880939e-01, /* 0x3fdbcb7b, 0x15200000 */ +ivln10lo = 2.50829467116452752298e-11, /* 0x3dbb9438, 0xca9aadd5 */ +log10_2hi = 3.01029995663611771306e-01, /* 0x3FD34413, 0x509F6000 */ +log10_2lo = 3.69423907715893078616e-13; /* 0x3D59FEF3, 0x11F12B36 */ + +static const double zero = 0.0; + +OLM_DLLEXPORT double +__ieee754_log10(double x) +{ + double f,hfsq,hi,lo,r,val_hi,val_lo,w,y,y2; + int32_t i,k,hx; + u_int32_t lx; + + EXTRACT_WORDS(hx,lx,x); + + k=0; + if (hx < 0x00100000) { /* x < 2**-1022 */ + if (((hx&0x7fffffff)|lx)==0) + return -two54/zero; /* log(+-0)=-inf */ + if (hx<0) return (x-x)/zero; /* log(-#) = NaN */ + k -= 54; x *= two54; /* subnormal number, scale up x */ + GET_HIGH_WORD(hx,x); + } + if (hx >= 0x7ff00000) return x+x; + if (hx == 0x3ff00000 && lx == 0) + return zero; /* log(1) = +0 */ + k += (hx>>20)-1023; + hx &= 0x000fffff; + i = (hx+0x95f64)&0x100000; + SET_HIGH_WORD(x,hx|(i^0x3ff00000)); /* normalize x or x/2 */ + k += (i>>20); + y = (double)k; + f = x - 1.0; + hfsq = 0.5*f*f; + r = k_log1p(f); + + /* See e_log2.c for most details. */ + hi = f - hfsq; + SET_LOW_WORD(hi,0); + lo = (f - hi) - hfsq + r; + val_hi = hi*ivln10hi; + y2 = y*log10_2hi; + val_lo = y*log10_2lo + (lo+hi)*ivln10lo + lo*ivln10hi; + + /* + * Extra precision in for adding y*log10_2hi is not strictly needed + * since there is no very large cancellation near x = sqrt(2) or + * x = 1/sqrt(2), but we do it anyway since it costs little on CPUs + * with some parallelism and it reduces the error for many args. + */ + w = y2 + val_hi; + val_lo += (y2 - w) + val_hi; + val_hi = w; + + return val_lo + val_hi; +} + +#if (LDBL_MANT_DIG == 53) +openlibm_weak_reference(log10, log10l); +#endif diff --git a/src/openlibm/src/e_log10.c.o b/src/openlibm/src/e_log10.c.o new file mode 100644 index 0000000000000000000000000000000000000000..36f330b9568247055d385b31a23a49ce93f75ada GIT binary patch literal 2896 zcmb<-^>JfjWMqH=Mg}_u1P><4z;J;b!FB*M9T@l+cp1_>`0EaObe{4!_)4MkLgTOh z|M?mC`?oPNFsT0j|G%E|1b@p(Mh1q~OZ*)-85tNp@kg?PbniO#|NnoG-UA*7UntoA z|Np+8zrUA}fx(u6;e&lCPa6OGldUKDTbdXd7&;HCf=vCyFTe}Zn#TYB|G}RkpZEnt zLEPRwT#SGI|L^TciRT2n=1}891_l9!&T|KUiZp%$8OQjO^VlbTt)HD2JPtln@ZkKA z=E0wL;1hog*eM=6K*s$4|Ns9d{)iK4{2DLP_%&{P;*Y%Wi9hZo%vK0L<`&4!_dOJk zgN(TUi9hD>C;pg2Y5W>bKk-LCP2<=2@`*nZgwK8Aj{rOO6MrNw_L)!o0;(X(Kk-LC z`@|oCi+v`IU*qv7{)kgBKY!wny#9$l^6V%6NLz^hh!daq1;F0<#2@+K6Mw|bPyCUx z5V=T@r;dE$k2v&+KLX_D3n2M4evMO~_#@7I;*U5D_4vWVX%h@DK_a8C_}~BkY5W=| z5OVzTE}#g6$HIY6{Ba1XZXY)b0CfX{UwN&xKpoBgDi*PfWr`0fHQ>tU=N`m zKxqaCmms_QLLU#=-(x;KEyeA)edJ`NDJq_q>?enUz*GDA$0{yx&N^(rzM@a|XyF-q zmS59n&YXGEo`FF@wEFaIdxnJh0m3eq?XRw#b;@GOZd)_$kAk27McOjBJ3Ct`Xt?`@ zYAP6-=o#r5Di|3UnHm@x8YpN4rKTu&B$hxWbj>vx7+4q>7!(*77(ij^?ib3y#K3p} zBnHb9j8Hx&!~+Z>P@1tSh=H*}fKi%g!@Bq^Y!V=76We5P%2m+E&SQ#P^LSU9F zm}F(h0MiJ<8_Z;7r~uOlA`r}EWk>+i2qGNJWMwD-(+DCK%mk$dFau5`F)%O)A;k+k zj#J}v^3x3s^pY9$e4LFygeizH0TIR^!VE;1g9r-{VF@A(4Zx%!m;`Gw1Zyw^D>ek{ zGX$Gs$N)B;0TO-;44|aN%)r3#2ULLl|NlP^>Ozn>DBZ%uYmvl3zJZDFLlS30GUo}B zIH>4{sh0&MR0fE>ptJ`Q*F+Kr=V<|OKsq*jzL=%plb zdHE%&dhULqy2T}l$=OhTdS0nsK~a7|YEelggC5wp)QtGFqQu-(u-#N3K>h-G8I%@~ zjf3T1cshqlg2E8W1XI!skTMje9xTYfz_0_9=olCn8bF3KFff4P9K-~rA&?qaxunLx z0M1pQGz}7m;V6_qhKWMdB6ti8It&cpGLc;UhEV%KagA(l0@VHnWI?E1AR(AP?4bJ5 z%f|;${rVuqNEj3bATEq{hw2B3A!B}Y4?!hi`k-6}P&o$5uTbk?!VCgX{pjw3xf`Z1 zA8J3keg`7;XW@u{3y`B27~u5}DE>j^1k8R|{Db_1Za2tn1yK7RfD|w=Fo4PiVWjYf m=?9q!RSMDu#{tmvhh9%Wjf1NL<$bLBq3*AQtAsGn^#cGmTlAd( literal 0 HcmV?d00001 diff --git a/src/openlibm/src/e_log10f.c b/src/openlibm/src/e_log10f.c new file mode 100644 index 0000000..1f6e31a --- /dev/null +++ b/src/openlibm/src/e_log10f.c @@ -0,0 +1,75 @@ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/e_log10f.c,v 1.13 2011/10/16 05:36:23 das Exp $"); + +/* + * Float version of e_log10.c. See the latter for most comments. + */ + +#include + +#include "math_private.h" +#include "k_logf.h" + +// VBS +#define float_t float + +static const float +two25 = 3.3554432000e+07, /* 0x4c000000 */ +ivln10hi = 4.3432617188e-01, /* 0x3ede6000 */ +ivln10lo = -3.1689971365e-05, /* 0xb804ead9 */ +log10_2hi = 3.0102920532e-01, /* 0x3e9a2080 */ +log10_2lo = 7.9034151668e-07; /* 0x355427db */ + +static const float zero = 0.0; + +OLM_DLLEXPORT float +__ieee754_log10f(float x) +{ + float f,hfsq,hi,lo,r,y; + int32_t i,k,hx; + + GET_FLOAT_WORD(hx,x); + + k=0; + if (hx < 0x00800000) { /* x < 2**-126 */ + if ((hx&0x7fffffff)==0) + return -two25/zero; /* log(+-0)=-inf */ + if (hx<0) return (x-x)/zero; /* log(-#) = NaN */ + k -= 25; x *= two25; /* subnormal number, scale up x */ + GET_FLOAT_WORD(hx,x); + } + if (hx >= 0x7f800000) return x+x; + if (hx == 0x3f800000) + return zero; /* log(1) = +0 */ + k += (hx>>23)-127; + hx &= 0x007fffff; + i = (hx+(0x4afb0d))&0x800000; + SET_FLOAT_WORD(x,hx|(i^0x3f800000)); /* normalize x or x/2 */ + k += (i>>23); + y = (float)k; + f = x - (float)1.0; + hfsq = (float)0.5*f*f; + r = k_log1pf(f); + + /* See e_log2f.c and e_log2.c for details. */ + if (sizeof(float_t) > sizeof(float)) + return (r - hfsq + f) * ((float_t)ivln10lo + ivln10hi) + + y * ((float_t)log10_2lo + log10_2hi); + hi = f - hfsq; + GET_FLOAT_WORD(hx,hi); + SET_FLOAT_WORD(hi,hx&0xfffff000); + lo = (f - hi) - hfsq + r; + return y*log10_2lo + (lo+hi)*ivln10lo + lo*ivln10hi + hi*ivln10hi + + y*log10_2hi; +} diff --git a/src/openlibm/src/e_log10f.c.o b/src/openlibm/src/e_log10f.c.o new file mode 100644 index 0000000000000000000000000000000000000000..fec208bb1123ec4e1a6be8f7fb21dc74756826ff GIT binary patch literal 2536 zcmb<-^>JfjWMqH=Mg}_u1P><4z>vX)U^{@B4h(z@ybNjlbq8$!|F37@?+;{TU|9M8 z|NnaamN-TRhSmf89eIol44?TUSwR|hJ^%mzKTLT&f4@E>14A1B`vbNN3=Q`DE!>O@ z44ns6K}MzVzkmCgUw{{+>)=oE&-?2XV;Z&-@VwVWIJvKjILQ7Lc*GAo39)bw>~L%Qt|u z8(sp1ZashB#ee_*f98)ka5#-$-USq@0$@L;@xMR$nLq9zO#Ns6m;-PzkO2$~XBZe5 zd_ZBuz`$V7z`)?3Hm|}?_}m%0cP}T}ty-mJfAbZ~j@#-XrVI)9>>3ni*)g~~J6kDe zxch}_Dj1sR8R;1+7#SFu8WTgV5|^el;&aQn83&Y7MFp_&4p=(^084MB`gdd|6`M5 z#*&hGzzSIzKyCvwp@blqW@Qin(+ENg%w%PN=mT@Wgfy6BW#9nQ2m%xapiqGM4<-Xn z!3?Yn5-*FVG1Hl zK!h=fFar_hAi@GfSb_*cLof-JH#7jV!CDO&Af_>>L2YJYU|?WoU|{(39|B^K#6fWg z6HiAH2e}?5J_AV{RD{9AHzA3$BbomaNgNcnF!f)N#6f8oCjJ*moD0buUQohhU|;~b zpBqVB7D*hGreNlnAc=#@8ko2Pk~kldIW^72bk z_1yhJb&E?9le3}x^t@8Nf};F_)S{9~20gHGsTuKUMTxnoaQi7_fcypWGAIs_je?|a z1_pR~gi504V^Dqtr5Bibs4|8bAVCHO1`Ckk3=9mQxB@XjaSu`h%depH2oeXSMUXfQ z-vtT6I7l?QFesma%p_O8Ap-+A_X#1{0b)LYS_CNL40?peh?cOJ45v&i-FiM{UA07hchrRfbto-au28gy1PJO1=0t@`B3|z z%3;C`6;J^}`m-1qz+r(N{}(`o1p@=TTn5EID1XE3hs8h0KTxaSc7qrzpn@|%3K$r` s^#myGq3Z{ki5~YL{SMHGiU4ttFw{7>2&jI-rvC-h{grT)5C*z_0D#GY-v9sr literal 0 HcmV?d00001 diff --git a/src/openlibm/src/e_log2.c b/src/openlibm/src/e_log2.c new file mode 100644 index 0000000..1570233 --- /dev/null +++ b/src/openlibm/src/e_log2.c @@ -0,0 +1,116 @@ + +/* @(#)e_log10.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/e_log2.c,v 1.4 2011/10/15 05:23:28 das Exp $"); + +/* + * Return the base 2 logarithm of x. See e_log.c and k_log.h for most + * comments. + * + * This reduces x to {k, 1+f} exactly as in e_log.c, then calls the kernel, + * then does the combining and scaling steps + * log2(x) = (f - 0.5*f*f + k_log1p(f)) / ln2 + k + * in not-quite-routine extra precision. + */ + +#include +#include + +#include "math_private.h" +#include "k_log.h" + +static const double +two54 = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */ +ivln2hi = 1.44269504072144627571e+00, /* 0x3ff71547, 0x65200000 */ +ivln2lo = 1.67517131648865118353e-10; /* 0x3de705fc, 0x2eefa200 */ + +static const double zero = 0.0; + +OLM_DLLEXPORT double +__ieee754_log2(double x) +{ + double f,hfsq,hi,lo,r,val_hi,val_lo,w,y; + int32_t i,k,hx; + u_int32_t lx; + + EXTRACT_WORDS(hx,lx,x); + + k=0; + if (hx < 0x00100000) { /* x < 2**-1022 */ + if (((hx&0x7fffffff)|lx)==0) + return -two54/zero; /* log(+-0)=-inf */ + if (hx<0) return (x-x)/zero; /* log(-#) = NaN */ + k -= 54; x *= two54; /* subnormal number, scale up x */ + GET_HIGH_WORD(hx,x); + } + if (hx >= 0x7ff00000) return x+x; + if (hx == 0x3ff00000 && lx == 0) + return zero; /* log(1) = +0 */ + k += (hx>>20)-1023; + hx &= 0x000fffff; + i = (hx+0x95f64)&0x100000; + SET_HIGH_WORD(x,hx|(i^0x3ff00000)); /* normalize x or x/2 */ + k += (i>>20); + y = (double)k; + f = x - 1.0; + hfsq = 0.5*f*f; + r = k_log1p(f); + + /* + * f-hfsq must (for args near 1) be evaluated in extra precision + * to avoid a large cancellation when x is near sqrt(2) or 1/sqrt(2). + * This is fairly efficient since f-hfsq only depends on f, so can + * be evaluated in parallel with R. Not combining hfsq with R also + * keeps R small (though not as small as a true `lo' term would be), + * so that extra precision is not needed for terms involving R. + * + * Compiler bugs involving extra precision used to break Dekker's + * theorem for spitting f-hfsq as hi+lo, unless double_t was used + * or the multi-precision calculations were avoided when double_t + * has extra precision. These problems are now automatically + * avoided as a side effect of the optimization of combining the + * Dekker splitting step with the clear-low-bits step. + * + * y must (for args near sqrt(2) and 1/sqrt(2)) be added in extra + * precision to avoid a very large cancellation when x is very near + * these values. Unlike the above cancellations, this problem is + * specific to base 2. It is strange that adding +-1 is so much + * harder than adding +-ln2 or +-log10_2. + * + * This uses Dekker's theorem to normalize y+val_hi, so the + * compiler bugs are back in some configurations, sigh. And I + * don't want to used double_t to avoid them, since that gives a + * pessimization and the support for avoiding the pessimization + * is not yet available. + * + * The multi-precision calculations for the multiplications are + * routine. + */ + hi = f - hfsq; + SET_LOW_WORD(hi,0); + lo = (f - hi) - hfsq + r; + val_hi = hi*ivln2hi; + val_lo = (lo+hi)*ivln2lo + lo*ivln2hi; + + /* spadd(val_hi, val_lo, y), except for not using double_t: */ + w = y + val_hi; + val_lo += (y - w) + val_hi; + val_hi = w; + + return val_lo + val_hi; +} + +#if (LDBL_MANT_DIG == 53) +openlibm_weak_reference(log2, log2l); +#endif diff --git a/src/openlibm/src/e_log2.c.o b/src/openlibm/src/e_log2.c.o new file mode 100644 index 0000000000000000000000000000000000000000..2a31331e4440f9c3ab769ad4c70b3dd45b54166c GIT binary patch literal 2760 zcmb<-^>JfjWMqH=Mg}_u1P><4z~I4-U^{@B4h(z@ybNg`{B;LCI!}2Ve5KHNq4C%M z|NIR6{mU2`7*zlN|6k8}g1==aBLhS0CH{_+j0_B)_#;^v7#J9Ko%;X(KS=KZkAp81 zZ2$j%U(erP%gDfB%fRr#zLY18|NY6Wm zLz)MF-i1&6F`^*zJa&M{|NsC0|HL10D2-p^QyRaZzU_{1M`AdUb1C6Mw@{BfsVp9UKTB?1mZ7y-@@`hz`$egLHz z99)9z?hAc9WPgwO^t2SW{)(I zpE+~pO?w6gg;aOZ@AeFf-s}BgeQwL(?(A%(pyBQps;OXTqGzOMs9ATd~)XN2-OAr58`fzpgsK@5x) z0*ul;>>Lvq8NlK)P&qCpC<6}#GM|Ov<9}>Qn6czIF0evY1`aTdAo#&dRt5<$jUXWI zWCi;TAAqQr%GH8Hl1fdLOvN9NeX#@dL$I4)V5CXHnX_kSN0a7M_ zg}{Unm}F(}0MiHpqMwx^03ifs*?~z`h6pf?AY8yqR)z#HjUc?hOjd>rFpVG}=7M4u zAqHZFGB7X*A%!zM&QjxZ^3#px(4LgCrh_ zBn~S7VCGaJiSr?;pNJ$5O4~5?PmshxX%{9A%DW&hgZu@;AT}856<6k#BqlNF6_*r2 z=nNREC^aWhuOzjigh4MQu_Tc}FR8egL9Zwu#L-JGF0o+HOU}>DP0cG|(96p&N!4@r z3)L+yNlea$^3(H5^$Lpe3sQ?pDjD>^#-(P&rxhjUrh@IJ0s-C=oF*Fa&@MXJB9e#UY3ZN)sS8uyRC=fdQO5Kxq^t z4#Qq3feaIcs73G?7<3pIz-1M=`VFD>3n3c{ayQie0yJ@$`(ZSw`~dk2z1%tg)vu4H zAEXu}1f$)d_JhQb@q4I#WHAsMrVqph;cx~922lP(SN;JifbK4syFq$EI3H?1R5?fp zj1`~(N=Sbej`-gIO;E6S2E{)p-^1*OiG%!uZa2sQ0Z{ulfD|w=Fo5#9AT+K)@-Y1% mGoeaB!Uzmae^Ce#FbirNm<=L8W@6KS0_y%skRl|Et{(sae9)W# literal 0 HcmV?d00001 diff --git a/src/openlibm/src/e_log2f.c b/src/openlibm/src/e_log2f.c new file mode 100644 index 0000000..58977ac --- /dev/null +++ b/src/openlibm/src/e_log2f.c @@ -0,0 +1,85 @@ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/e_log2f.c,v 1.5 2011/10/15 05:23:28 das Exp $"); + +/* + * Float version of e_log2.c. See the latter for most comments. + */ + +#include + +#include "math_private.h" +#include "k_logf.h" + +// VBS +#define float_t float + +static const float +two25 = 3.3554432000e+07, /* 0x4c000000 */ +ivln2hi = 1.4428710938e+00, /* 0x3fb8b000 */ +ivln2lo = -1.7605285393e-04; /* 0xb9389ad4 */ + +static const float zero = 0.0; + +OLM_DLLEXPORT float +__ieee754_log2f(float x) +{ + float f,hfsq,hi,lo,r,y; + int32_t i,k,hx; + + GET_FLOAT_WORD(hx,x); + + k=0; + if (hx < 0x00800000) { /* x < 2**-126 */ + if ((hx&0x7fffffff)==0) + return -two25/zero; /* log(+-0)=-inf */ + if (hx<0) return (x-x)/zero; /* log(-#) = NaN */ + k -= 25; x *= two25; /* subnormal number, scale up x */ + GET_FLOAT_WORD(hx,x); + } + if (hx >= 0x7f800000) return x+x; + if (hx == 0x3f800000) + return zero; /* log(1) = +0 */ + k += (hx>>23)-127; + hx &= 0x007fffff; + i = (hx+(0x4afb0d))&0x800000; + SET_FLOAT_WORD(x,hx|(i^0x3f800000)); /* normalize x or x/2 */ + k += (i>>23); + y = (float)k; + f = x - (float)1.0; + hfsq = (float)0.5*f*f; + r = k_log1pf(f); + + /* + * We no longer need to avoid falling into the multi-precision + * calculations due to compiler bugs breaking Dekker's theorem. + * Keep avoiding this as an optimization. See e_log2.c for more + * details (some details are here only because the optimization + * is not yet available in double precision). + * + * Another compiler bug turned up. With gcc on i386, + * (ivln2lo + ivln2hi) would be evaluated in float precision + * despite runtime evaluations using double precision. So we + * must cast one of its terms to float_t. This makes the whole + * expression have type float_t, so return is forced to waste + * time clobbering its extra precision. + */ + if (sizeof(float_t) > sizeof(float)) + return (r - hfsq + f) * ((float_t)ivln2lo + ivln2hi) + y; + + hi = f - hfsq; + GET_FLOAT_WORD(hx,hi); + SET_FLOAT_WORD(hi,hx&0xfffff000); + lo = (f - hi) - hfsq + r; + return (lo+hi)*ivln2lo + lo*ivln2hi + hi*ivln2hi + y; +} diff --git a/src/openlibm/src/e_log2f.c.o b/src/openlibm/src/e_log2f.c.o new file mode 100644 index 0000000000000000000000000000000000000000..5ef8b27becda441d69c9d9ceef81f5acf345351a GIT binary patch literal 2392 zcmb<-^>JfjWMqH=Mg}_u1P><4z;J^V!FB*M9T@l+cp1|8>kiod|6k9*-*3psz_9ZF z|Nr&;Eq06y46O(FJNy_K7(Vkyg7xlt{{R1fnDTo5ett#q`D4KLeCCfh!LRXxU*pDS{>TTP`Qu(9%meXb?xgY8-B4xt0CG*+2`#%2r|Nk?8#DT+U z{PHfKP!j;_g6N1lc$i-~iJILLSUy1^WZcgc2%Xnw3EUOd|+L@Ub$${0x)P12b5`VG3qK31cwL z%Af(J5rid}$;tq+2h0HzpooUV3YZHgTo@P_gpk4q9@eSxIr-^EX?n>FdOprZAi@+x zn1Bdl5Mc%)%t3?&h_D0^hK69$08BD~4S?FD2Bn!87#Nrt7#RNihkytqaZp^q#1oLj zL1_sl-iIX4hGfnPByn~m@%u>Ppg4k=^BPGUlony)pOM75kj!BQB`^jC29WzfX$PiW z4M`l7Helj0NaCPU0VWR08z3t{=72DW4aR!KmANH}Nep_$B}EWA1I8*!%}LZNNv$Yh z&`U`yNo3GVDlTTwE6N9P^pcB9Oc?Z%^K)}k^GX=>^72bk_1yhJb&E?9le3}x^t@8N zf};F_)S{9~20gHGsTuKUMTxnoV7sY6fcypWGAK@vjf0f^3=Hse1(ih4U(yT=;JgS^ z4^_rs0ZJ4M3=A9~!xO=B{e}z-;9MkxteJs<;Q-Vkkom|`P;Y_#3=+44>Nfy!knkI*etje{5ECj4wiCp6 zhw2Bhk+C#NB16c)^ut8L85kHq`37CN0#pFqU9j+n>CcDS4^<8mW(a@^5YnH8BmNyg znV*3HUS5LYACzBV_QT>I + +#include "math_private.h" + +static const float +ln2_hi = 6.9313812256e-01, /* 0x3f317180 */ +ln2_lo = 9.0580006145e-06, /* 0x3717f7d1 */ +two25 = 3.355443200e+07, /* 0x4c000000 */ +/* |(log(1+s)-log(1-s))/s - Lg(s)| < 2**-34.24 (~[-4.95e-11, 4.97e-11]). */ +Lg1 = 0xaaaaaa.0p-24, /* 0.66666662693 */ +Lg2 = 0xccce13.0p-25, /* 0.40000972152 */ +Lg3 = 0x91e9ee.0p-25, /* 0.28498786688 */ +Lg4 = 0xf89e26.0p-26; /* 0.24279078841 */ + +static const float zero = 0.0; + +OLM_DLLEXPORT float +__ieee754_logf(float x) +{ + float hfsq,f,s,z,R,w,t1,t2,dk; + int32_t k,ix,i,j; + + GET_FLOAT_WORD(ix,x); + + k=0; + if (ix < 0x00800000) { /* x < 2**-126 */ + if ((ix&0x7fffffff)==0) + return -two25/zero; /* log(+-0)=-inf */ + if (ix<0) return (x-x)/zero; /* log(-#) = NaN */ + k -= 25; x *= two25; /* subnormal number, scale up x */ + GET_FLOAT_WORD(ix,x); + } + if (ix >= 0x7f800000) return x+x; + k += (ix>>23)-127; + ix &= 0x007fffff; + i = (ix+(0x95f64<<3))&0x800000; + SET_FLOAT_WORD(x,ix|(i^0x3f800000)); /* normalize x or x/2 */ + k += (i>>23); + f = x-(float)1.0; + if((0x007fffff&(0x8000+ix))<0xc000) { /* -2**-9 <= f < 2**-9 */ + if(f==zero) { + if(k==0) { + return zero; + } else { + dk=(float)k; + return dk*ln2_hi+dk*ln2_lo; + } + } + R = f*f*((float)0.5-(float)0.33333333333333333*f); + if(k==0) return f-R; else {dk=(float)k; + return dk*ln2_hi-((R-dk*ln2_lo)-f);} + } + s = f/((float)2.0+f); + dk = (float)k; + z = s*s; + i = ix-(0x6147a<<3); + w = z*z; + j = (0x6b851<<3)-ix; + t1= w*(Lg2+w*Lg4); + t2= z*(Lg1+w*Lg3); + i |= j; + R = t2+t1; + if(i>0) { + hfsq=(float)0.5*f*f; + if(k==0) return f-(hfsq-s*(hfsq+R)); else + return dk*ln2_hi-((hfsq-(s*(hfsq+R)+dk*ln2_lo))-f); + } else { + if(k==0) return f-s*(f-R); else + return dk*ln2_hi-((s*(f-R)-dk*ln2_lo)-f); + } +} diff --git a/src/openlibm/src/e_logf.c.o b/src/openlibm/src/e_logf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..4d4ed08e42ddbc08d900af562f81c9867075a465 GIT binary patch literal 2840 zcmb<-^>JfjWMqH=Mg}_u1P><4z%YXy!FB*M9T@l+cp1|8>kiod|6k9*-+z#SfnnwU z|NraxThbUA7+MeTcknSWFns2ZWCdy1_5A<;|1jnC{QdJ87#KPas)F<${3+gB!qwQ@ zq43*_q4U(im*S0&7#JED7(X_CVqj>n=RB0gpLeKt0z(7HxEQc;jgLS&8-M-Z&%jWh zn8yG9B){H4{w@|q1_u7te+&!^{2B*aPx80aGBPlLWIyu@fc1Um*E;!`Kl0#b{zzVs zvp(}j96X$+$1mRk;xQOr0{Nz%zc2Cs|No!)BMux+2N@FsG9SW>Jk@%#Br}cw{iV zE#}l`{+JV=`D1SKYaBid4F{0bkyrRNK>9U5^TVu(y!x3xQWs)Q%vq?ui~Jgg;QByr zWBAM;a{$S$3<%33?;;F{c=?$>=IUqumZTlftjofFh78~3=9m)USb>?W3=&`(L4YC`5-SKX5X%KbFtEbo0nBA!VDMyM zU=TtIH+USR#^>axr|Bg#==nGsfe2#|VFDsdL4*Z}umll?24K<1jRQEE=2UP)?234>lrVo4%{UQ%%}gI-ZSh@+QWTw=nYmzJ=2_7o--IR5Iv+jZ4jlPb*5yO$FOc1p?$RP>_QB zifkOD?q*Y>UQEI@(Ez`$?QUlAsp!@+6 z2jvZrI1H~q31pZk15%EKh=IxnkeTG_H)MdADFiVNPQvUrfQvvFpu7rV!Dvv$0&+jP zx*JgU>w^>{VUSu77e>27?FWe=V|H{8K_y}Opj?J<1_lODzK2=|6K3Fm>PL4MD6HU$ z7#JAxq4uNew;)n~7LND_JBon;UQUDJA5`AJ?1#la$Uo?IgWQ(^wZ8$RfPn#AFM;YV wbp0SRp-Ms8;P?eJg8bkj5C+sZ2#0}zL6Cug0h@jaP@pm}FjT@-LKx`!0Xr%8od5s; literal 0 HcmV?d00001 diff --git a/src/openlibm/src/e_pow.c b/src/openlibm/src/e_pow.c new file mode 100644 index 0000000..a891552 --- /dev/null +++ b/src/openlibm/src/e_pow.c @@ -0,0 +1,317 @@ +/* @(#)e_pow.c 1.5 04/04/22 SMI */ +/* + * ==================================================== + * Copyright (C) 2004 by Sun Microsystems, Inc. All rights reserved. + * + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/e_pow.c,v 1.14 2011/10/21 06:26:07 das Exp $"); + +/* __ieee754_pow(x,y) return x**y + * + * n + * Method: Let x = 2 * (1+f) + * 1. Compute and return log2(x) in two pieces: + * log2(x) = w1 + w2, + * where w1 has 53-24 = 29 bit trailing zeros. + * 2. Perform y*log2(x) = n+y' by simulating muti-precision + * arithmetic, where |y'|<=0.5. + * 3. Return x**y = 2**n*exp(y'*log2) + * + * Special cases: + * 1. (anything) ** 0 is 1 + * 2. (anything) ** 1 is itself + * 3. (anything) ** NAN is NAN + * 4. NAN ** (anything except 0) is NAN + * 5. +-(|x| > 1) ** +INF is +INF + * 6. +-(|x| > 1) ** -INF is +0 + * 7. +-(|x| < 1) ** +INF is +0 + * 8. +-(|x| < 1) ** -INF is +INF + * 9. +-1 ** +-INF is NAN + * 10. +0 ** (+anything except 0, NAN) is +0 + * 11. -0 ** (+anything except 0, NAN, odd integer) is +0 + * 12. +0 ** (-anything except 0, NAN) is +INF + * 13. -0 ** (-anything except 0, NAN, odd integer) is +INF + * 14. -0 ** (odd integer) = -( +0 ** (odd integer) ) + * 15. +INF ** (+anything except 0,NAN) is +INF + * 16. +INF ** (-anything except 0,NAN) is +0 + * 17. -INF ** (anything) = -0 ** (-anything) + * 18. (-anything) ** (integer) is (-1)**(integer)*(+anything**integer) + * 19. (-anything except 0 and inf) ** (non-integer) is NAN + * + * Accuracy: + * pow(x,y) returns x**y nearly rounded. In particular + * pow(integer,integer) + * always returns the correct integer provided it is + * representable. + * + * Constants : + * The hexadecimal values are the intended ones for the following + * constants. The decimal values may be used, provided that the + * compiler will convert from decimal to binary accurately enough + * to produce the hexadecimal values shown. + */ + +#include +#include + +#include "math_private.h" + +static const double +bp[] = {1.0, 1.5,}, +dp_h[] = { 0.0, 5.84962487220764160156e-01,}, /* 0x3FE2B803, 0x40000000 */ +dp_l[] = { 0.0, 1.35003920212974897128e-08,}, /* 0x3E4CFDEB, 0x43CFD006 */ +zero = 0.0, +one = 1.0, +two = 2.0, +two53 = 9007199254740992.0, /* 0x43400000, 0x00000000 */ +huge = 1.0e300, +tiny = 1.0e-300, + /* poly coefs for (3/2)*(log(x)-2s-2/3*s**3 */ +L1 = 5.99999999999994648725e-01, /* 0x3FE33333, 0x33333303 */ +L2 = 4.28571428578550184252e-01, /* 0x3FDB6DB6, 0xDB6FABFF */ +L3 = 3.33333329818377432918e-01, /* 0x3FD55555, 0x518F264D */ +L4 = 2.72728123808534006489e-01, /* 0x3FD17460, 0xA91D4101 */ +L5 = 2.30660745775561754067e-01, /* 0x3FCD864A, 0x93C9DB65 */ +L6 = 2.06975017800338417784e-01, /* 0x3FCA7E28, 0x4A454EEF */ +P1 = 1.66666666666666019037e-01, /* 0x3FC55555, 0x5555553E */ +P2 = -2.77777777770155933842e-03, /* 0xBF66C16C, 0x16BEBD93 */ +P3 = 6.61375632143793436117e-05, /* 0x3F11566A, 0xAF25DE2C */ +P4 = -1.65339022054652515390e-06, /* 0xBEBBBD41, 0xC5D26BF1 */ +P5 = 4.13813679705723846039e-08, /* 0x3E663769, 0x72BEA4D0 */ +lg2 = 6.93147180559945286227e-01, /* 0x3FE62E42, 0xFEFA39EF */ +lg2_h = 6.93147182464599609375e-01, /* 0x3FE62E43, 0x00000000 */ +lg2_l = -1.90465429995776804525e-09, /* 0xBE205C61, 0x0CA86C39 */ +ovt = 8.0085662595372944372e-0017, /* -(1024-log2(ovfl+.5ulp)) */ +cp = 9.61796693925975554329e-01, /* 0x3FEEC709, 0xDC3A03FD =2/(3ln2) */ +cp_h = 9.61796700954437255859e-01, /* 0x3FEEC709, 0xE0000000 =(float)cp */ +cp_l = -7.02846165095275826516e-09, /* 0xBE3E2FE0, 0x145B01F5 =tail of cp_h*/ +ivln2 = 1.44269504088896338700e+00, /* 0x3FF71547, 0x652B82FE =1/ln2 */ +ivln2_h = 1.44269502162933349609e+00, /* 0x3FF71547, 0x60000000 =24b 1/ln2*/ +ivln2_l = 1.92596299112661746887e-08; /* 0x3E54AE0B, 0xF85DDF44 =1/ln2 tail*/ + +OLM_DLLEXPORT double +__ieee754_pow(double x, double y) +{ + double z,ax,z_h,z_l,p_h,p_l; + double y1,t1,t2,r,s,t,u,v,w; + int32_t i,j,k,yisint,n; + int32_t hx,hy,ix,iy; + u_int32_t lx,ly; + + EXTRACT_WORDS(hx,lx,x); + EXTRACT_WORDS(hy,ly,y); + ix = hx&0x7fffffff; iy = hy&0x7fffffff; + + /* y==zero: x**0 = 1 */ + if((iy|ly)==0) return one; + + /* x==1: 1**y = 1, even if y is NaN */ + if (hx==0x3ff00000 && lx == 0) return one; + + /* y!=zero: result is NaN if either arg is NaN */ + if(ix > 0x7ff00000 || ((ix==0x7ff00000)&&(lx!=0)) || + iy > 0x7ff00000 || ((iy==0x7ff00000)&&(ly!=0))) + return (x+0.0)+(y+0.0); + + /* determine if y is an odd int when x < 0 + * yisint = 0 ... y is not an integer + * yisint = 1 ... y is an odd int + * yisint = 2 ... y is an even int + */ + yisint = 0; + if(hx<0) { + if(iy>=0x43400000) yisint = 2; /* even integer y */ + else if(iy>=0x3ff00000) { + k = (iy>>20)-0x3ff; /* exponent */ + if(k>20) { + j = ly>>(52-k); + if((j<<(52-k))==ly) yisint = 2-(j&1); + } else if(ly==0) { + j = iy>>(20-k); + if((j<<(20-k))==iy) yisint = 2-(j&1); + } + } + } + + /* special value of y */ + if(ly==0) { + if (iy==0x7ff00000) { /* y is +-inf */ + if(((ix-0x3ff00000)|lx)==0) + return one; /* (-1)**+-inf is NaN */ + else if (ix >= 0x3ff00000)/* (|x|>1)**+-inf = inf,0 */ + return (hy>=0)? y: zero; + else /* (|x|<1)**-,+inf = inf,0 */ + return (hy<0)?-y: zero; + } + if(iy==0x3ff00000) { /* y is +-1 */ + if(hy<0) return one/x; else return x; + } + if(hy==0x40000000) return x*x; /* y is 2 */ + if(hy==0x40080000) return x*x*x; /* y is 3 */ + if(hy==0x40100000) { /* y is 4 */ + u = x*x; + return u*u; + } + if(hy==0x3fe00000) { /* y is 0.5 */ + if(hx>=0) /* x >= +0 */ + return sqrt(x); + } + } + + ax = fabs(x); + /* special value of x */ + if(lx==0) { + if(ix==0x7ff00000||ix==0||ix==0x3ff00000){ + z = ax; /*x is +-0,+-inf,+-1*/ + if(hy<0) z = one/z; /* z = (1/|x|) */ + if(hx<0) { + if(((ix-0x3ff00000)|yisint)==0) { + z = (z-z)/(z-z); /* (-1)**non-int is NaN */ + } else if(yisint==1) + z = -z; /* (x<0)**odd = -(|x|**odd) */ + } + return z; + } + } + + /* CYGNUS LOCAL + fdlibm-5.3 fix: This used to be + n = (hx>>31)+1; + but ANSI C says a right shift of a signed negative quantity is + implementation defined. */ + n = ((u_int32_t)hx>>31)-1; + + /* (x<0)**(non-int) is NaN */ + if((n|yisint)==0) return (x-x)/(x-x); + + s = one; /* s (sign of result -ve**odd) = -1 else = 1 */ + if((n|(yisint-1))==0) s = -one;/* (-ve)**(odd int) */ + + /* |y| is huge */ + if(iy>0x41e00000) { /* if |y| > 2**31 */ + if(iy>0x43f00000){ /* if |y| > 2**64, must o/uflow */ + if(ix<=0x3fefffff) return (hy<0)? huge*huge:tiny*tiny; + if(ix>=0x3ff00000) return (hy>0)? huge*huge:tiny*tiny; + } + /* over/underflow if x is not close to one */ + if(ix<0x3fefffff) return (hy<0)? s*huge*huge:s*tiny*tiny; + if(ix>0x3ff00000) return (hy>0)? s*huge*huge:s*tiny*tiny; + /* now |1-x| is tiny <= 2**-20, suffice to compute + log(x) by x-x^2/2+x^3/3-x^4/4 */ + t = ax-one; /* t has 20 trailing zeros */ + w = (t*t)*(0.5-t*(0.3333333333333333333333-t*0.25)); + u = ivln2_h*t; /* ivln2_h has 21 sig. bits */ + v = t*ivln2_l-w*ivln2; + t1 = u+v; + SET_LOW_WORD(t1,0); + t2 = v-(t1-u); + } else { + double ss,s2,s_h,s_l,t_h,t_l; + n = 0; + /* take care subnormal number */ + if(ix<0x00100000) + {ax *= two53; n -= 53; GET_HIGH_WORD(ix,ax); } + n += ((ix)>>20)-0x3ff; + j = ix&0x000fffff; + /* determine interval */ + ix = j|0x3ff00000; /* normalize ix */ + if(j<=0x3988E) k=0; /* |x|>1)|0x20000000)+0x00080000+(k<<18)); + t_l = ax - (t_h-bp[k]); + s_l = v*((u-s_h*t_h)-s_h*t_l); + /* compute log(ax) */ + s2 = ss*ss; + r = s2*s2*(L1+s2*(L2+s2*(L3+s2*(L4+s2*(L5+s2*L6))))); + r += s_l*(s_h+ss); + s2 = s_h*s_h; + t_h = 3.0+s2+r; + SET_LOW_WORD(t_h,0); + t_l = r-((t_h-3.0)-s2); + /* u+v = ss*(1+...) */ + u = s_h*t_h; + v = s_l*t_h+t_l*ss; + /* 2/(3log2)*(ss+...) */ + p_h = u+v; + SET_LOW_WORD(p_h,0); + p_l = v-(p_h-u); + z_h = cp_h*p_h; /* cp_h+cp_l = 2/(3*log2) */ + z_l = cp_l*p_h+p_l*cp+dp_l[k]; + /* log2(ax) = (ss+..)*2/(3*log2) = n + dp_h + z_h + z_l */ + t = (double)n; + t1 = (((z_h+z_l)+dp_h[k])+t); + SET_LOW_WORD(t1,0); + t2 = z_l-(((t1-t)-dp_h[k])-z_h); + } + + /* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */ + y1 = y; + SET_LOW_WORD(y1,0); + p_l = (y-y1)*t1+y*t2; + p_h = y1*t1; + z = p_l+p_h; + EXTRACT_WORDS(j,i,z); + if (j>=0x40900000) { /* z >= 1024 */ + if(((j-0x40900000)|i)!=0) /* if z > 1024 */ + return s*huge*huge; /* overflow */ + else { + if(p_l+ovt>z-p_h) return s*huge*huge; /* overflow */ + } + } else if((j&0x7fffffff)>=0x4090cc00 ) { /* z <= -1075 */ + if(((j-0xc090cc00)|i)!=0) /* z < -1075 */ + return s*tiny*tiny; /* underflow */ + else { + if(p_l<=z-p_h) return s*tiny*tiny; /* underflow */ + } + } + /* + * compute 2**(p_h+p_l) + */ + i = j&0x7fffffff; + k = (i>>20)-0x3ff; + n = 0; + if(i>0x3fe00000) { /* if |z| > 0.5, set n = [z+0.5] */ + n = j+(0x00100000>>(k+1)); + k = ((n&0x7fffffff)>>20)-0x3ff; /* new k for n */ + t = zero; + SET_HIGH_WORD(t,n&~(0x000fffff>>k)); + n = ((n&0x000fffff)|0x00100000)>>(20-k); + if(j<0) n = -n; + p_h -= t; + } + t = p_l+p_h; + SET_LOW_WORD(t,0); + u = t*lg2_h; + v = (p_l-(t-p_h))*lg2+t*lg2_l; + z = u+v; + w = v-(z-u); + t = z*z; + t1 = z - t*(P1+t*(P2+t*(P3+t*(P4+t*P5)))); + r = (z*t1)/(t1-two)-(w+z*w); + z = one-(r-z); + GET_HIGH_WORD(j,z); + j += (n<<20); + if((j>>20)<=0) z = scalbn(z,n); /* subnormal output */ + else SET_HIGH_WORD(z,j); + return s*z; +} + +#if (LDBL_MANT_DIG == 53) +openlibm_weak_reference(pow, powl); +#endif diff --git a/src/openlibm/src/e_pow.c.o b/src/openlibm/src/e_pow.c.o new file mode 100644 index 0000000000000000000000000000000000000000..66d2199a8a12e18af772e669d0e7181ac8049ee0 GIT binary patch literal 6848 zcmb<-^>JfjWMqH=Mg}_u1P><4z`!7mU^{@B4h;MZd<=R3#7XCRG^jsF-JKGc`X^G`Y0`j&s{p_YrK!i~SdV%(*ktp`e6`Q=?0 z7}EIPANa%{ap4nx#KBMe5r;gQk7z{4I>tE0I>tH1AD#d+9ZfuqU%mxoDT8b0ch}ap z6%K}%S`YBI<}orbKrG>J5oUt2?Mt)M_%#l>wmzv`_=#VD7o_hKf841wevN~#`}yS? zKmv`w|Npml=5Id&HsSyO_x5GlowpAD5@~$(pP7N7`IiWP-#vB)hMgu13=EnVI}crc z)p`B$bIarWEn7Jl7(kXgurV+gUUF>w!@$7cz~9oz&cFcXa5(U{IB`HZ0uKBw+3XAq zo*-op>`OUaTi^0`ws3$#LgP?ph>FN3enB4a2`1Fx7mWd$-wZznZHe(4dk|eAV2fBhp;m+xVApw?*K7Ck@GU^-~a!e7j`i* zFfcSfVAMR6mZk>_e13TbP{JnkNi(dx+|NkEx|1O;`RR90~Z*L1qOeLJIt>5@t zmH+?$4~i`Tq}VzEiY;(h-TM3gzhmP&ka|bXYy7Q0*ccc-@y8ta#2`=l}onGaURS;?nuEcZvYxpa1_GPl6rZ_`h!kGee!2W8?qIZQKm}ecxCa7@7|; zHojzF5McPkFQ5yKGXD4948NuEYy3-d;n#Qz%7Odb4{1JyiA#)t$cn|)(<6zrC9{vDw;8zg$2FOG2K(2fR_D~wX z2G}3BLB@gH909WF7RZ?UpZEo2K|u#Mjz97S$g~R}(=Njz8)VF-PyCUhAf=$Jb?K7} zzZS@p3u*ishd=R0Tn80rpZFt=fn0eAWHj7`Y5W>LKnDE!#2@qT6MxL_Py8|0Kk-Li z1gQe0^qU^LK<0vC&qMJ7D3U&W;*Yuai9hnjC;rG|pZFtgfxW=5aT-*3g0x-o=)B-@ z@P&fy|Ns3C{Czx33=F*;3=9SPIWO|JK4${u5s1G&@yCEl+nZ_p`nUMo&oVJE>|$VI zU|>A7kAdOC|1^G$i;kTaIBKzmAO${%Bb%H!~?E9_O1NJ|LwVaNvI8k2&{=KN4I!fIJN{GmT&4)F=L!(`oz~pyYJx6MxJ>L}3wm z`V)T)w3r96BaqnG#UbXz+=Q45(h~!A=_md;m>oAj>Fg7K%!yC@F(A8Ng1q#?qw`?r z0gr<(6&O!>bY2AKJ5I2d4mAD(<$eCXd~nc59(k$s^Z);}381V5bq=Ih1_^-k#><3X z|3Sfj2&L%%#1AU=`CChVgG#-pprXu({E-Jf@yFZ;6?dQbBM-xK8YI2`0)_W~Sf)(l*SG=65iyrv z9{K~WFZes1|APYn9Gsw>ecyM(oHzn*Dv>gIT}Yl@e8Iv+Yg`k z1yWQvUY7rb_`LttzyJSVO8kTPR_Vw8|6m`zbpHPTKd6-jDp(OMu$Q1HWME*JQ_9d` z^TfOk!u?OQ^hK63X z|Gzr__O{&H_RPj0@EB?i2dHWLfb;k}`@hUqcR=)4#%PfT`gZ#u=1;c)neVLk%>KRQ zuYXQ@&+IL8R`4XoDD1niWM5IHd79nF>`O--_wKgSxu?25D@@RS^4@)7IS141?ZECm z3bls;WDm$F7zVcqz#MmHXDbB_cfU|g1w#`(BRxX}BLgE-14Bat1&yH86a|mO5~zf( zxh5#885k587#KjY=k6EEz{J3KfQ5kp-iBv{@;SkVGcbUPTo9A7Du{uxLV!`4hn-^r zBLhPX0|SE$NP>ZZL6wVvfx(?mpr6T!Poj_6iBF-I#feX&ht-46ppDIu&!U;#pD%$a zpNr4JktEY8Zn0j3dz1egg5RWJiifQxkoR)!3?2!x>wrdSykfN2Dw z31+e~6o6?2p$}%VGE{(R1OYDc7+4t)2?8Q#4W?KbI>0o7a0D}1876>f1mO;5vNFs7 z(+I*B%w%O)0j3c|Fqp~80B-ex*$^TUOtCU-0MiH}9?WEAH~^**L@Joc%5VZqBZzD; zla=8Dm_`tVU?wZW4KR%$%E3%lh6i98LDYhotPJ3u4VVofn!yw+!v`>pAUeTJR)!y7 z8bS1fnXHJ60_HO?Oa;@d3>=_@2WCTv*fG6aBW1hEm!WM!}b(+FZan8}J!VC;p8M}TPraTv^GWk>+i2;wA|$qFtjz)UD{ z4otH$Xn<)1aT&~HWiSBK2m%yOLP+@zTvjkJFx+7P)msR4FxEpH;-L6L4>Pcy)cAt@ za=l~*Js)Rd5Mc=-j6j4Tm@os8MqnvJa}e9m0!%{G8GzVEV3kH-O-3eQ5r{5RFdMAP z2&~Hptjidz%NVT77_7?}Y`!sAuQ6DcG1vq!6D(>7R%ZxSX9(7B2-a^1kp(LRYXRG4 z!BCK2&XAUvRLoGEoS2i8$532YR08s^8;D?F0JWgOW%wUZoBjX)|4VR)f5ss`ADUi4 zWj`n`VdmU}ii5h}pwbT}{tQVRRLa4`LqQ4|AoU8eISZlUAPQN%J2S*VAaQmE1_qcp zGm*rR)oXzq2=y)cGs3{B+KZhhPhGhONByrHt9ZdZ*Bymt#1{42;Brb_$&Oan^DI{?zP-H{hFO4K# ziX;w70xK+Ep;~vyj9Uk<>RKi7O$A&qERiwGCkATtyNG1uaaR5tQhm?g#l9 zCSHmpj;y{7Nn8cV-aaI8(6AlMoHMii5;JZ5x>RilEF1 zEjP4~%m;-bsDuE;7YKvcV60bMnOl;W#GqGPQUswhV639loJ75n)QS=Yy_Cd~L007mjL+>RFs0^2H6Z)10PmD!sI|@28<1&L3sxhmN4}o zF%WJ56(XRX4M>uKfdN#Of$V`MA9yd=9dpzCh{73x^p4zTcp(LPZ7(c38#p!y;0 zY?!MM%{`EvAkk2$eh?cO?}zF~76Y+i`ao;C}NkKTSq*AMDHfRYG$`bhv)1`G`FbOK60peTXq2bKLG`?1*#67K+M0HqC( z;S3B6pgL0>#0NguVk~h503RL@ A-v9sr literal 0 HcmV?d00001 diff --git a/src/openlibm/src/e_powf.c b/src/openlibm/src/e_powf.c new file mode 100644 index 0000000..9527ef0 --- /dev/null +++ b/src/openlibm/src/e_powf.c @@ -0,0 +1,253 @@ +/* e_powf.c -- float version of e_pow.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/e_powf.c,v 1.16 2011/10/21 06:26:07 das Exp $"); + +#include + +#include "math_private.h" + +static const float +bp[] = {1.0, 1.5,}, +dp_h[] = { 0.0, 5.84960938e-01,}, /* 0x3f15c000 */ +dp_l[] = { 0.0, 1.56322085e-06,}, /* 0x35d1cfdc */ +zero = 0.0, +half = 0.5, +qrtr = 0.25, +thrd = 3.33333343e-01, /* 0x3eaaaaab */ +one = 1.0, +two = 2.0, +two24 = 16777216.0, /* 0x4b800000 */ +huge = 1.0e30, +tiny = 1.0e-30, + /* poly coefs for (3/2)*(log(x)-2s-2/3*s**3 */ +L1 = 6.0000002384e-01, /* 0x3f19999a */ +L2 = 4.2857143283e-01, /* 0x3edb6db7 */ +L3 = 3.3333334327e-01, /* 0x3eaaaaab */ +L4 = 2.7272811532e-01, /* 0x3e8ba305 */ +L5 = 2.3066075146e-01, /* 0x3e6c3255 */ +L6 = 2.0697501302e-01, /* 0x3e53f142 */ +P1 = 1.6666667163e-01, /* 0x3e2aaaab */ +P2 = -2.7777778450e-03, /* 0xbb360b61 */ +P3 = 6.6137559770e-05, /* 0x388ab355 */ +P4 = -1.6533901999e-06, /* 0xb5ddea0e */ +P5 = 4.1381369442e-08, /* 0x3331bb4c */ +lg2 = 6.9314718246e-01, /* 0x3f317218 */ +lg2_h = 6.93145752e-01, /* 0x3f317200 */ +lg2_l = 1.42860654e-06, /* 0x35bfbe8c */ +ovt = 4.2995665694e-08, /* -(128-log2(ovfl+.5ulp)) */ +cp = 9.6179670095e-01, /* 0x3f76384f =2/(3ln2) */ +cp_h = 9.6191406250e-01, /* 0x3f764000 =12b cp */ +cp_l = -1.1736857402e-04, /* 0xb8f623c6 =tail of cp_h */ +ivln2 = 1.4426950216e+00, /* 0x3fb8aa3b =1/ln2 */ +ivln2_h = 1.4426879883e+00, /* 0x3fb8aa00 =16b 1/ln2*/ +ivln2_l = 7.0526075433e-06; /* 0x36eca570 =1/ln2 tail*/ + +OLM_DLLEXPORT float +__ieee754_powf(float x, float y) +{ + float z,ax,z_h,z_l,p_h,p_l; + float y1,t1,t2,r,s,sn,t,u,v,w; + int32_t i,j,k,yisint,n; + int32_t hx,hy,ix,iy,is; + + GET_FLOAT_WORD(hx,x); + GET_FLOAT_WORD(hy,y); + ix = hx&0x7fffffff; iy = hy&0x7fffffff; + + /* y==zero: x**0 = 1 */ + if(iy==0) return one; + + /* x==1: 1**y = 1, even if y is NaN */ + if (hx==0x3f800000) return one; + + /* y!=zero: result is NaN if either arg is NaN */ + if(ix > 0x7f800000 || + iy > 0x7f800000) + return nan_mix(x, y); + + /* determine if y is an odd int when x < 0 + * yisint = 0 ... y is not an integer + * yisint = 1 ... y is an odd int + * yisint = 2 ... y is an even int + */ + yisint = 0; + if(hx<0) { + if(iy>=0x4b800000) yisint = 2; /* even integer y */ + else if(iy>=0x3f800000) { + k = (iy>>23)-0x7f; /* exponent */ + j = iy>>(23-k); + if((j<<(23-k))==iy) yisint = 2-(j&1); + } + } + + /* special value of y */ + if (iy==0x7f800000) { /* y is +-inf */ + if (ix==0x3f800000) + return one; /* (-1)**+-inf is NaN */ + else if (ix > 0x3f800000)/* (|x|>1)**+-inf = inf,0 */ + return (hy>=0)? y: zero; + else /* (|x|<1)**-,+inf = inf,0 */ + return (hy<0)?-y: zero; + } + if(iy==0x3f800000) { /* y is +-1 */ + if(hy<0) return one/x; else return x; + } + if(hy==0x40000000) return x*x; /* y is 2 */ + if(hy==0x3f000000) { /* y is 0.5 */ + if(hx>=0) /* x >= +0 */ + return __ieee754_sqrtf(x); + } + + ax = fabsf(x); + /* special value of x */ + if(ix==0x7f800000||ix==0||ix==0x3f800000){ + z = ax; /*x is +-0,+-inf,+-1*/ + if(hy<0) z = one/z; /* z = (1/|x|) */ + if(hx<0) { + if(((ix-0x3f800000)|yisint)==0) { + z = (z-z)/(z-z); /* (-1)**non-int is NaN */ + } else if(yisint==1) + z = -z; /* (x<0)**odd = -(|x|**odd) */ + } + return z; + } + + n = ((u_int32_t)hx>>31)-1; + + /* (x<0)**(non-int) is NaN */ + if((n|yisint)==0) return (x-x)/(x-x); + + sn = one; /* s (sign of result -ve**odd) = -1 else = 1 */ + if((n|(yisint-1))==0) sn = -one;/* (-ve)**(odd int) */ + + /* |y| is huge */ + if(iy>0x4d000000) { /* if |y| > 2**27 */ + /* over/underflow if x is not close to one */ + if(ix<0x3f7ffff6) return (hy<0)? sn*huge*huge:sn*tiny*tiny; + if(ix>0x3f800007) return (hy>0)? sn*huge*huge:sn*tiny*tiny; + /* now |1-x| is tiny <= 2**-20, suffice to compute + log(x) by x-x^2/2+x^3/3-x^4/4 */ + t = ax-1; /* t has 20 trailing zeros */ + w = (t*t)*(half-t*(thrd-t*qrtr)); + u = ivln2_h*t; /* ivln2_h has 16 sig. bits */ + v = t*ivln2_l-w*ivln2; + t1 = u+v; + GET_FLOAT_WORD(is,t1); + SET_FLOAT_WORD(t1,is&0xfffff000); + t2 = v-(t1-u); + } else { + float s2,s_h,s_l,t_h,t_l; + n = 0; + /* take care subnormal number */ + if(ix<0x00800000) + {ax *= two24; n -= 24; GET_FLOAT_WORD(ix,ax); } + n += ((ix)>>23)-0x7f; + j = ix&0x007fffff; + /* determine interval */ + ix = j|0x3f800000; /* normalize ix */ + if(j<=0x1cc471) k=0; /* |x|>1)&0xfffff000)|0x20000000; + SET_FLOAT_WORD(t_h,is+0x00400000+(k<<21)); + t_l = ax - (t_h-bp[k]); + s_l = v*((u-s_h*t_h)-s_h*t_l); + /* compute log(ax) */ + s2 = s*s; + r = s2*s2*(L1+s2*(L2+s2*(L3+s2*(L4+s2*(L5+s2*L6))))); + r += s_l*(s_h+s); + s2 = s_h*s_h; + t_h = 3+s2+r; + GET_FLOAT_WORD(is,t_h); + SET_FLOAT_WORD(t_h,is&0xfffff000); + t_l = r-((t_h-3)-s2); + /* u+v = s*(1+...) */ + u = s_h*t_h; + v = s_l*t_h+t_l*s; + /* 2/(3log2)*(s+...) */ + p_h = u+v; + GET_FLOAT_WORD(is,p_h); + SET_FLOAT_WORD(p_h,is&0xfffff000); + p_l = v-(p_h-u); + z_h = cp_h*p_h; /* cp_h+cp_l = 2/(3*log2) */ + z_l = cp_l*p_h+p_l*cp+dp_l[k]; + /* log2(ax) = (s+..)*2/(3*log2) = n + dp_h + z_h + z_l */ + t = n; + t1 = (((z_h+z_l)+dp_h[k])+t); + GET_FLOAT_WORD(is,t1); + SET_FLOAT_WORD(t1,is&0xfffff000); + t2 = z_l-(((t1-t)-dp_h[k])-z_h); + } + + /* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */ + GET_FLOAT_WORD(is,y); + SET_FLOAT_WORD(y1,is&0xfffff000); + p_l = (y-y1)*t1+y*t2; + p_h = y1*t1; + z = p_l+p_h; + GET_FLOAT_WORD(j,z); + if (j>0x43000000) /* if z > 128 */ + return sn*huge*huge; /* overflow */ + else if (j==0x43000000) { /* if z == 128 */ + if(p_l+ovt>z-p_h) return sn*huge*huge; /* overflow */ + } + else if ((j&0x7fffffff)>0x43160000) /* z <= -150 */ + return sn*tiny*tiny; /* underflow */ + else if (j==0xc3160000){ /* z == -150 */ + if(p_l<=z-p_h) return sn*tiny*tiny; /* underflow */ + } + /* + * compute 2**(p_h+p_l) + */ + i = j&0x7fffffff; + k = (i>>23)-0x7f; + n = 0; + if(i>0x3f000000) { /* if |z| > 0.5, set n = [z+0.5] */ + n = j+(0x00800000>>(k+1)); + k = ((n&0x7fffffff)>>23)-0x7f; /* new k for n */ + SET_FLOAT_WORD(t,n&~(0x007fffff>>k)); + n = ((n&0x007fffff)|0x00800000)>>(23-k); + if(j<0) n = -n; + p_h -= t; + } + t = p_l+p_h; + GET_FLOAT_WORD(is,t); + SET_FLOAT_WORD(t,is&0xffff8000); + u = t*lg2_h; + v = (p_l-(t-p_h))*lg2+t*lg2_l; + z = u+v; + w = v-(z-u); + t = z*z; + t1 = z - t*(P1+t*(P2+t*(P3+t*(P4+t*P5)))); + r = (z*t1)/(t1-two)-(w+z*w); + z = one-(r-z); + GET_FLOAT_WORD(j,z); + j += (n<<23); + if((j>>23)<=0) z = scalbnf(z,n); /* subnormal output */ + else SET_FLOAT_WORD(z,j); + return sn*z; +} diff --git a/src/openlibm/src/e_powf.c.o b/src/openlibm/src/e_powf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..d8ad3ed9db21883822ec18f07b30fdb8172b4f64 GIT binary patch literal 6536 zcmb<-^>JfjWMqH=Mg}_u1P><4z;Hqo!FB*M9T@l-_!u0+9mCQb`RmR(hB}6Xx^#XG zPUEjT-1zkW|Nr$K&2JDc&}fuW(kybem2xpuy9 zz0KdTnt_1%ukZ*gX3U~p{w$H2hgz~3^BnSsI8@Ck%(&)<5Dfq}uJ`G`bx ztYeI0tYe&G{7aA<`Q;ft^9!(on5eRc)A;3EK*9`Z{O=EZ<`)c6;kfCd!tt3u;>2fu zK^GN{8(^NG4}^6y1|%ooqQZe@&V_O_sqnpd?DZbg3*QZ0e{Ou zCP=U{`0}@LfP?by*Z=kQ{B8Vfpm6=m&d^}b-(JPW017c#kS(A21yn(Fnk)bNlb`to zbU~cY`~s#BI_B_aegSZz`0N4=j6 zDO3&E%+ zdarQHR#G5q!x)-(#3=Gcv{hwGE82DSf zSQ!{P4?6N|9Bh0DN|TL085qQz`P<+8{r}&VfkEsrf6EG11_r}RhW|lQ4EFr(_gNVj zR2drn|A%=xjXw|Mr+54s$3FAN9Qn*22@8W0pZO!9QTX&Tf5f@Z{1FfNHI97dk2%V( z0dm`$&-^hbU@74`0H*kUP$B5J7D|&e?0?#-v$;?oJJmc`SZ{J{}cE%4uR5I=bJxZ|A8I`OMn zGob^2YvAAi|0jIrkG#aMap+~wA5ao@V1TCW&YC~}|G$*~3lapUYe?30C^_Hw7?hSF znGT$~AteTXOBg7R!_qZ>i#s#O8!?wY^T&ZL&<0z;;M)4FlK(Tm0L&vN_%#l;-sbP* z`Sbt3W8+&;7IEc#%HR6uH^{#+2R`%19eDZvH{2bc`31nK9g@mnDVbm6vf+Wo$DjhL zROmB*BsiLOya44-NB+9wE}g#|8=r%M_uwz_UKfEzm(E{}r$BZ&HvTU>BE!Jn*9IyN z8vkG09LvDp$H2@0Drnv|A7E^J#lXT7yi8apB?$*9=Y&qT>tFCA9*Fsg}?3^ zBxitRpSkjDeEICkANl#SD}T&gS5WG41?3V){+Poc1OI_CD!`ph5s2PyA9_{<*x&99*RO$-~9*AeQV21kH$&hgLu5l0;PHJ*HS z;g7fha{m3s=b(%Yaz4m&k-uH}H6DYU{|w|9FzYGE=|@1^LoVQwA>#OFegRNEX8;*< z0b~qPC|m=n{N>88aSIeiurey<4#dXuKjIK5;xB!6;n%wGnLpy#XZ{F~ zcR?0LJVGmxzJT<9`ph5m^)r9W_s{$>$6hA?1{GKGE({FN!gww?*+FZm4}bpucjmysUBLk38^_?I%e5{aeG6pv1Bk|At5r5M7 z>wdgk_Y15QT695bkev(+3ZU47)GIGPL+q{ZdHL(d|Ns0Nhmq<#NY(bz9Fm3K@awByyWsuU@4EG8587 z1J%?ZmqKU=>F(@orJ&*N7pkdXXrgDNXQ*IgU}S1wXlS6I5tN#u;E`AYmC!ZUWME)n z0L2pn11Rj={X!X-7#I(L#9(biMkt>XVmgBelxD07VqmNgV3g)z=a|6Az)-`$z#s#a z;{hpl;uGj+a^jQdV|M3L=w)%@)97J!gBGGl28bAc7Ifk|Y7AI!lN2bVq! ztl)42D}fSHV49Ud2TUUf1u&D9!2nDn2sJR1l|cneBM69oRt61(5SV2ICPA?VX21z^ zFpHJJ1WY3caAC^8%3y&I0<)aKBr8J(m_`tuU?wX=0hmS*{$M66Lk^fm5TRfuD?s?pfrPq21OqFB3z$X_6TwVY1`jZeAf|(vtPDP2 z8bQnjGg%n|z%+tb3}&)2M1W}ou@cN=Wk>+i2x2{$$;uD|rV+$eFq4&m2TUV~U0^0F z0|%H!5c|PQR)!QXjUbMKnXC+ubPDExiPK<`l|cYZBZv!NCM&#L0CO1_7_NdDtPB!h z8bRCwGg;wf1(?ggz;K^|fk6l z1ITX-#f3#BX$)zJNyTXl#mR{|NqK1uOF)6ez`y`%qku|_KmQ>>4pcB=5qCfm2h{^G z^#xFIkeC(&0|QL_8dMzJ{Ch~^pi&d2{xy;~JCZq{k;Fl16{h|_k~pYZfr)c~EQGor zRA$4(6_CV1H3LlC0!bW{M_}R)ki>bB-18ktoDWHynHdtGAZbvY05eAeNgR|%VB#i7 z;(|!#I3S4&A&L7Si3=l%M<9uV>R_1pMM&bHx(FtI07)D<-u*xk$N;JLk>jxwDh~1& zvic)9#4jO=V<|OKsq*jzL z=%plJ$JuQ-QtqOemPBLJ%OeARdecwXb1pkT?v>gEB3QgG8gN1tlR+mPSe2puQheKf1d>VU1)Q zLoGD?(DesE_0K?7%)o%r-UPM(L1BrWel$Rp76Su3oq+0QkdZL^L3IMiXpn!bAT#w1_p*7APy1+*@whs0M*^t^gBS^-;S&p I8dk_c040lO9{>OV literal 0 HcmV?d00001 diff --git a/src/openlibm/src/e_rem_pio2.c b/src/openlibm/src/e_rem_pio2.c new file mode 100644 index 0000000..c09e38a --- /dev/null +++ b/src/openlibm/src/e_rem_pio2.c @@ -0,0 +1,183 @@ + +/* @(#)e_rem_pio2.c 1.4 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + * + * Optimized by Bruce D. Evans. + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/e_rem_pio2.c,v 1.22 2011/06/19 17:07:58 kargl Exp $"); + +/* __ieee754_rem_pio2(x,y) + * + * return the remainder of x rem pi/2 in y[0]+y[1] + * use __kernel_rem_pio2() + */ + +#include +#include + +#include "math_private.h" + +/* + * invpio2: 53 bits of 2/pi + * pio2_1: first 33 bit of pi/2 + * pio2_1t: pi/2 - pio2_1 + * pio2_2: second 33 bit of pi/2 + * pio2_2t: pi/2 - (pio2_1+pio2_2) + * pio2_3: third 33 bit of pi/2 + * pio2_3t: pi/2 - (pio2_1+pio2_2+pio2_3) + */ + +static const double +zero = 0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */ +two24 = 1.67772160000000000000e+07, /* 0x41700000, 0x00000000 */ +invpio2 = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */ +pio2_1 = 1.57079632673412561417e+00, /* 0x3FF921FB, 0x54400000 */ +pio2_1t = 6.07710050650619224932e-11, /* 0x3DD0B461, 0x1A626331 */ +pio2_2 = 6.07710050630396597660e-11, /* 0x3DD0B461, 0x1A600000 */ +pio2_2t = 2.02226624879595063154e-21, /* 0x3BA3198A, 0x2E037073 */ +pio2_3 = 2.02226624871116645580e-21, /* 0x3BA3198A, 0x2E000000 */ +pio2_3t = 8.47842766036889956997e-32; /* 0x397B839A, 0x252049C1 */ + +__inline int +__ieee754_rem_pio2(double x, double *y) +{ + double z,w,t,r,fn; + double tx[3],ty[2]; + int32_t e0,i,j,nx,n,ix,hx; + u_int32_t low; + + GET_HIGH_WORD(hx,x); /* high word of x */ + ix = hx&0x7fffffff; +#if 0 /* Must be handled in caller. */ + if(ix<=0x3fe921fb) /* |x| ~<= pi/4 , no need for reduction */ + {y[0] = x; y[1] = 0; return 0;} +#endif + if (ix <= 0x400f6a7a) { /* |x| ~<= 5pi/4 */ + if ((ix & 0xfffff) == 0x921fb) /* |x| ~= pi/2 or 2pi/2 */ + goto medium; /* cancellation -- use medium case */ + if (ix <= 0x4002d97c) { /* |x| ~<= 3pi/4 */ + if (hx > 0) { + z = x - pio2_1; /* one round good to 85 bits */ + y[0] = z - pio2_1t; + y[1] = (z-y[0])-pio2_1t; + return 1; + } else { + z = x + pio2_1; + y[0] = z + pio2_1t; + y[1] = (z-y[0])+pio2_1t; + return -1; + } + } else { + if (hx > 0) { + z = x - 2*pio2_1; + y[0] = z - 2*pio2_1t; + y[1] = (z-y[0])-2*pio2_1t; + return 2; + } else { + z = x + 2*pio2_1; + y[0] = z + 2*pio2_1t; + y[1] = (z-y[0])+2*pio2_1t; + return -2; + } + } + } + if (ix <= 0x401c463b) { /* |x| ~<= 9pi/4 */ + if (ix <= 0x4015fdbc) { /* |x| ~<= 7pi/4 */ + if (ix == 0x4012d97c) /* |x| ~= 3pi/2 */ + goto medium; + if (hx > 0) { + z = x - 3*pio2_1; + y[0] = z - 3*pio2_1t; + y[1] = (z-y[0])-3*pio2_1t; + return 3; + } else { + z = x + 3*pio2_1; + y[0] = z + 3*pio2_1t; + y[1] = (z-y[0])+3*pio2_1t; + return -3; + } + } else { + if (ix == 0x401921fb) /* |x| ~= 4pi/2 */ + goto medium; + if (hx > 0) { + z = x - 4*pio2_1; + y[0] = z - 4*pio2_1t; + y[1] = (z-y[0])-4*pio2_1t; + return 4; + } else { + z = x + 4*pio2_1; + y[0] = z + 4*pio2_1t; + y[1] = (z-y[0])+4*pio2_1t; + return -4; + } + } + } + if(ix<0x413921fb) { /* |x| ~< 2^20*(pi/2), medium size */ +medium: + /* Use a specialized rint() to get fn. Assume round-to-nearest. */ + STRICT_ASSIGN(double,fn,x*invpio2+0x1.8p52); + fn = fn-0x1.8p52; +#ifdef HAVE_EFFICIENT_IRINT + n = irint(fn); +#else + n = (int32_t)fn; +#endif + r = x-fn*pio2_1; + w = fn*pio2_1t; /* 1st round good to 85 bit */ + { + u_int32_t high; + j = ix>>20; + y[0] = r-w; + GET_HIGH_WORD(high,y[0]); + i = j-((high>>20)&0x7ff); + if(i>16) { /* 2nd iteration needed, good to 118 */ + t = r; + w = fn*pio2_2; + r = t-w; + w = fn*pio2_2t-((t-r)-w); + y[0] = r-w; + GET_HIGH_WORD(high,y[0]); + i = j-((high>>20)&0x7ff); + if(i>49) { /* 3rd iteration need, 151 bits acc */ + t = r; /* will cover all possible cases */ + w = fn*pio2_3; + r = t-w; + w = fn*pio2_3t-((t-r)-w); + y[0] = r-w; + } + } + } + y[1] = (r-y[0])-w; + return n; + } + /* + * all other (large) arguments + */ + if(ix>=0x7ff00000) { /* x is inf or NaN */ + y[0]=y[1]=x-x; return 0; + } + /* set z = scalbn(|x|,ilogb(x)-23) */ + GET_LOW_WORD(low,x); + e0 = (ix>>20)-1046; /* e0 = ilogb(z)-23; */ + INSERT_WORDS(z, ix - ((int32_t)(e0<<20)), low); + for(i=0;i<2;i++) { + tx[i] = (double)((int32_t)(z)); + z = (z-tx[i])*two24; + } + tx[2] = z; + nx = 3; + while(tx[nx-1]==zero) nx--; /* skip zero term */ + n = __kernel_rem_pio2(tx,ty,e0,nx,1); + if(hx<0) {y[0] = -ty[0]; y[1] = -ty[1]; return -n;} + y[0] = ty[0]; y[1] = ty[1]; return n; +} diff --git a/src/openlibm/src/e_rem_pio2.c.o b/src/openlibm/src/e_rem_pio2.c.o new file mode 100644 index 0000000000000000000000000000000000000000..e9249133e80f677fb5625f8a56e1c0e847e54e3a GIT binary patch literal 3856 zcmb<-^>JfjWMqH=Mg}_u1P><4z%YRu!FB*M9T@l+cp1_>`0EaZdURe5_UQcWaqz7| z=L^;U|Nqx}G{3R1t;*teC{OKt)%fWDe}0C>U%wSO8TeZ`nHU&sYi=?*@VDnNGBC8h zkenEE*kLDv5 zofo2G5A(}6fK=OByU93|N80ZBE9$`C9>xf^Ldb!?Wj53bYiw39GcYi8UchS!*a`;* z+h2;7j{I%DAcOz^e_zkv?!?5v(0MG4|NY4{{`Z$UFCF|R()dn{g@K{-pLgIBzs`YA{8}fV&i7Fffcf$hf8;@^EXboEPll*SfJ7lC>w&!MqN2dx z^@@>!fxq<$BLhS855}FKz-hkuzw?tvZ;gt8;|>ttqx0DdP*|k#Yp|$v9%_Bd-*FVA zNs#&F*?<54^UJ$HLi-dWme6J*Dkvt{{#KN9DDebEnhX;bV_1kXCQXlDz6In|21Gar zh=K$T{t)Rr_K838#3%lUQ=j-_PJQBsNPOaty!eS<2bvNPVrl#uH$L&l+yW)Un;r*W znlwKA&(6T0d9L}NKwTY7cN)LO1BeMRk3R9o97*HXxC2R32$MeX$AFT;5p1TNX#QbX zX8r|>$n-Ox_+xIS@oRwGdiWE+pmZlJYMsI9Hahlj8p8iE2MjNz z@rxYb7i52__V@q)G;loa1SQRvvj1RwSU7#ZmBue}GL1j{Aip5<%Wr@F|Nq1vftqjr z{Re3R<(mkQ3qVOq{1bl!C?UCXygZCe%YVFDCScR@7q6CBY+C-{)uQ$1|9?;la0vOW z_|x7nIY}yU%LQ8o1`waq0m6S^%fMhzUvpE);nbAL%O~=^gvv`o42%^5jM6;p91|EB7-AS07-XPwejo$f_ypRRT=*oKnS=NO zm=d`7B%JvK9QimrxS1lk_#_;`99M2;7DhPFiJQq8&hh4E`U2;8A(h@xOQ00Uoh%F= z!66S7f>X>`Y63p6EXcQD2AmKEvsf88z%+u805e$`Kw$)CLJ3(g&B~wwrV)e^n90ge z0HzTHL>()G073}N(gl;O3=n(3957)7CRrH_z%+s|2Qyh2EWk8^umLk!86b5Vm;)vt z34@iv1I$AZZeS)WLjagY5I$fgD?l4otE#RDfv& zk;1^hAcPbz;IzWPz);S>fDtxeU8(U!sk!k5nfXR~$qafv&ITaD5JZ@O2vZPY2xc0A zn8qN&3`CfN2n!Hl2_g(38o@dZ!AcFmY7Na9;^Q+@Q&Y`NP2g5B#K&i+7UiYpAVk29 zVPNos(xB=FRK$VG1W@S{h9nM3{xI>4NaCPW2NU0kB+kabzyK4s0VQY#1_qG%>`3CE zJOc!Ve0oFsRyN9nD`MSaZuici8F%?hMLcXWIi{NI4HBh)Vm;w^B}4BK@tbm zBQW);NaD!hQ;8%F@&io$VkB`;-h_!CMiS>oviBpBI4Cc{)c-{i7erE@19Ak^zd}gj zZAjwC;ns&FjvQ{_`V49gND0i|gCGu69NAxQki?PW{R@&fa=gofG(*inju&+#apZV` zl}8|NgD@yJ$JuQ-QtqO +#include + +#include "math_private.h" + +/* + * invpio2: 53 bits of 2/pi + * pio2_1: first 33 bit of pi/2 + * pio2_1t: pi/2 - pio2_1 + */ + +static const double +invpio2 = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */ +pio2_1 = 1.57079631090164184570e+00, /* 0x3FF921FB, 0x50000000 */ +pio2_1t = 1.58932547735281966916e-08; /* 0x3E5110b4, 0x611A6263 */ + +__inline int +__ieee754_rem_pio2f(float x, double *y) +{ + double w,r,fn; + double tx[1],ty[1]; + float z; + int32_t e0,n,ix,hx; + + GET_FLOAT_WORD(hx,x); + ix = hx&0x7fffffff; + /* 33+53 bit pi is good enough for medium size */ + if(ix<0x4dc90fdb) { /* |x| ~< 2^28*(pi/2), medium size */ + /* Use a specialized rint() to get fn. Assume round-to-nearest. */ + STRICT_ASSIGN(double,fn,x*invpio2+0x1.8p52); + fn = fn-0x1.8p52; +#ifdef HAVE_EFFICIENT_IRINT + n = irint(fn); +#else + n = (int32_t)fn; +#endif + r = x-fn*pio2_1; + w = fn*pio2_1t; + *y = r-w; + return n; + } + /* + * all other (large) arguments + */ + if(ix>=0x7f800000) { /* x is inf or NaN */ + *y=x-x; return 0; + } + /* set z = scalbn(|x|,ilogb(|x|)-23) */ + e0 = (ix>>23)-150; /* e0 = ilogb(|x|)-23; */ + SET_FLOAT_WORD(z, ix - ((int32_t)(e0<<23))); + tx[0] = z; + n = __kernel_rem_pio2(tx,ty,e0,1,0); + if(hx<0) {*y = -ty[0]; return -n;} + *y = ty[0]; return n; +} diff --git a/src/openlibm/src/e_rem_pio2f.c.o b/src/openlibm/src/e_rem_pio2f.c.o new file mode 100644 index 0000000000000000000000000000000000000000..c2afa7063992c7950426a1c3d6101aa9d72eee1c GIT binary patch literal 2096 zcmb<-^>JfjWMqH=Mg}_u1P><4z)-+~U^{@B4h;MZd<>y!{B=izJ70Ko{#O0}|9`zl z^BW1nGjsN`t zkKPg$4v)^~2Y-pX8XjnTHI0FRq4VOwhvJ$ic7j}!#-DfNGk?_KPyB)`Dlb49Kk*B= zsBpBttz4DHAI=IA`F`W|ytE0Q_yu@DJcxY)q9FDs{>T%b_#;kz;*UA?i61U@@e{w! z!B6~=VD+E)V-9`dk2#3sMvzv9<`XA#4dS2JgEW=3^Gu; z+aTJJPoRy-l~1CX*^kd4fs0SVkx#&pkHd?bX$Fi9QicnI>}O&4_#c}*GnN#>4_3$q zCXoq{ z=)%O0Ac?ahnGZ@!ASsZ&APi!Iv0iayZb@PigI;k-5rocwv5Hc267@<_D@qvjQW8rN z8T68hiy8Ea@lK0i5Q^)o%#3UkG6Z zn56)<2oyeG0Vn};Ka2(ySRke7`W--mSn>=k{9v>X)P4h~`7kN~s$U-_0HvYA;IIS< zg+ld%*vPmZrVv>Wi&{_;0;PA9w9UZ4&;Zqs?k#x9( zel9>G6qZgv>4ys%*C3-{;vj3#?FPv+Km|X5ISdS-N(p2)2!n)R`axw3)GClL9Dji7 g_k)W-7$Ex~EC?wGEsr2P1o;ALXgfj(%tF@>05_lm<^TWy literal 0 HcmV?d00001 diff --git a/src/openlibm/src/e_remainder.c b/src/openlibm/src/e_remainder.c new file mode 100644 index 0000000..a72631c --- /dev/null +++ b/src/openlibm/src/e_remainder.c @@ -0,0 +1,79 @@ + +/* @(#)e_remainder.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/e_remainder.c,v 1.12 2008/03/30 20:47:42 das Exp $"); + +/* __ieee754_remainder(x,p) + * Return : + * returns x REM p = x - [x/p]*p as if in infinite + * precise arithmetic, where [x/p] is the (infinite bit) + * integer nearest x/p (in half way case choose the even one). + * Method : + * Based on fmod() return x-[x/p]chopped*p exactlp. + */ + +#include +#include + +#include "math_private.h" + +static const double zero = 0.0; + + +OLM_DLLEXPORT double +__ieee754_remainder(double x, double p) +{ + int32_t hx,hp; + u_int32_t sx,lx,lp; + double p_half; + + EXTRACT_WORDS(hx,lx,x); + EXTRACT_WORDS(hp,lp,p); + sx = hx&0x80000000; + hp &= 0x7fffffff; + hx &= 0x7fffffff; + + /* purge off exception values */ + if((hp|lp)==0) return (x*p)/(x*p); /* p = 0 */ + if((hx>=0x7ff00000)|| /* x not finite */ + ((hp>=0x7ff00000)&& /* p is NaN */ + (((hp-0x7ff00000)|lp)!=0))) + return ((long double)x*p)/((long double)x*p); + + + if (hp<=0x7fdfffff) x = __ieee754_fmod(x,p+p); /* now x < 2p */ + if (((hx-hp)|(lx-lp))==0) return zero*x; + x = fabs(x); + p = fabs(p); + if (hp<0x00200000) { + if(x+x>p) { + x-=p; + if(x+x>=p) x -= p; + } + } else { + p_half = 0.5*p; + if(x>p_half) { + x-=p; + if(x>=p_half) x -= p; + } + } + GET_HIGH_WORD(hx,x); + if ((hx&0x7fffffff)==0) hx = 0; + SET_HIGH_WORD(x,hx^sx); + return x; +} + +#if LDBL_MANT_DIG == 53 +openlibm_weak_reference(remainder, remainderl); +#endif diff --git a/src/openlibm/src/e_remainderf.c b/src/openlibm/src/e_remainderf.c new file mode 100644 index 0000000..ac0d153 --- /dev/null +++ b/src/openlibm/src/e_remainderf.c @@ -0,0 +1,66 @@ +/* e_remainderf.c -- float version of e_remainder.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/e_remainderf.c,v 1.8 2008/02/12 17:11:36 bde Exp $"); + +#include + +#include "math_private.h" + +static const float zero = 0.0; + + +OLM_DLLEXPORT float +__ieee754_remainderf(float x, float p) +{ + int32_t hx,hp; + u_int32_t sx; + float p_half; + + GET_FLOAT_WORD(hx,x); + GET_FLOAT_WORD(hp,p); + sx = hx&0x80000000; + hp &= 0x7fffffff; + hx &= 0x7fffffff; + + /* purge off exception values */ + if(hp==0) return (x*p)/(x*p); /* p = 0 */ + if((hx>=0x7f800000)|| /* x not finite */ + ((hp>0x7f800000))) /* p is NaN */ + return ((long double)x*p)/((long double)x*p); + + + if (hp<=0x7effffff) x = __ieee754_fmodf(x,p+p); /* now x < 2p */ + if ((hx-hp)==0) return zero*x; + x = fabsf(x); + p = fabsf(p); + if (hp<0x01000000) { + if(x+x>p) { + x-=p; + if(x+x>=p) x -= p; + } + } else { + p_half = (float)0.5*p; + if(x>p_half) { + x-=p; + if(x>=p_half) x -= p; + } + } + GET_FLOAT_WORD(hx,x); + if ((hx&0x7fffffff)==0) hx = 0; + SET_FLOAT_WORD(x,hx^sx); + return x; +} diff --git a/src/openlibm/src/e_remainderl.c b/src/openlibm/src/e_remainderl.c new file mode 100644 index 0000000..5f1ee61 --- /dev/null +++ b/src/openlibm/src/e_remainderl.c @@ -0,0 +1,39 @@ +/*- + * Copyright (c) 2008 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/e_remainderl.c,v 1.1 2008/03/30 20:47:42 das Exp $"); + +#include +#include "math_private.h" + +OLM_DLLEXPORT long double +remainderl(long double x, long double y) +{ + int quo; + + return (remquol(x, y, &quo)); +} diff --git a/src/openlibm/src/e_sinh.c b/src/openlibm/src/e_sinh.c new file mode 100644 index 0000000..7f3a2bf --- /dev/null +++ b/src/openlibm/src/e_sinh.c @@ -0,0 +1,79 @@ + +/* @(#)e_sinh.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/e_sinh.c,v 1.11 2011/10/21 06:28:47 das Exp $"); + +/* __ieee754_sinh(x) + * Method : + * mathematically sinh(x) if defined to be (exp(x)-exp(-x))/2 + * 1. Replace x by |x| (sinh(-x) = -sinh(x)). + * 2. + * E + E/(E+1) + * 0 <= x <= 22 : sinh(x) := --------------, E=expm1(x) + * 2 + * + * 22 <= x <= lnovft : sinh(x) := exp(x)/2 + * lnovft <= x <= ln2ovft: sinh(x) := exp(x/2)/2 * exp(x/2) + * ln2ovft < x : sinh(x) := x*shuge (overflow) + * + * Special cases: + * sinh(x) is |x| if x is +INF, -INF, or NaN. + * only sinh(0)=0 is exact for finite x. + */ + +#include +#include + +#include "math_private.h" + +static const double one = 1.0, shuge = 1.0e307; + +OLM_DLLEXPORT double +__ieee754_sinh(double x) +{ + double t,h; + int32_t ix,jx; + + /* High word of |x|. */ + GET_HIGH_WORD(jx,x); + ix = jx&0x7fffffff; + + /* x is INF or NaN */ + if(ix>=0x7ff00000) return x+x; + + h = 0.5; + if (jx<0) h = -h; + /* |x| in [0,22], return sign(x)*0.5*(E+E/(E+1))) */ + if (ix < 0x40360000) { /* |x|<22 */ + if (ix<0x3e300000) /* |x|<2**-28 */ + if(shuge+x>one) return x;/* sinh(tiny) = tiny with inexact */ + t = expm1(fabs(x)); + if(ix<0x3ff00000) return h*(2.0*t-t*t/(t+one)); + return h*(t+t/(t+one)); + } + + /* |x| in [22, log(maxdouble)] return 0.5*exp(|x|) */ + if (ix < 0x40862E42) return h*__ieee754_exp(fabs(x)); + + /* |x| in [log(maxdouble), overflowthresold] */ + if (ix<=0x408633CE) + return h*2.0*__ldexp_exp(fabs(x), -1); + + /* |x| > overflowthresold, sinh(x) overflow */ + return x*shuge; +} + +#if (LDBL_MANT_DIG == 53) +openlibm_weak_reference(sinh, sinhl); +#endif diff --git a/src/openlibm/src/e_sinh.c.o b/src/openlibm/src/e_sinh.c.o new file mode 100644 index 0000000000000000000000000000000000000000..2df9b08a4ab26bbf20ddbc663df06519947f53cd GIT binary patch literal 2552 zcmb<-^>JfjWMqH=Mg}_u1P><4z)-=4U^{@B4h(z@ybNg`{B;L{Jr2H5=seu``2YX^ z^&ZV{1R8(;|Np+8zx^Ep14HWp{*Gx33=E(61$aRkKk*BQf@qK$QwRQbkQ|7uZ^z$$ z4WdpKB>#zDKovp@hNy6)@oSv;#2<0v6ThH}N*cfZopRF`AXzZ+iC;iPAzFj7$v-4Gk1Df>KiyJQ7Qw61wJ^3=Av`3=9ek3=FIc3=Hmm zp$tq6j0Zqsur$U9<#R$TVi1ASj8#Dlj1>Zm(md=O6Brp7Y#10AWT0|~K$_k71e%!w z_!OAtaq$Vb@^QFxGdXba2{`g`_;Y(eguJ;cAdFycs7_1@WE2a-N0d;2sba>G6S%;V zAm4x)aDpGqVrAd}(+C3MA69S}AVe7$B*7e31_3aQAmqSIRt5<$jUbd67#M_*+yf2+ z1_lNV1_lf>K)Q5sh+E?jH^w2(kQ!f{nU|rL%%JDvYyct*L4*m2FaiILJMqA`K>f21%S9$(=ut#F5>j2TC{$ zko1jguQ8H1vb}Clage>p?yrN2qr1NuNgR}VVeVXpB#vzF1|)GFB=>{z9>@zIdqEh) z24lVA%G{E~BnG|Wk|GG50b>=V<|OKsq*jzL=%plbdHE%&dhULqy2T}l$=OhTdS0nsK~a7|YEelggC5wp)QtGFqQu-(u-#N3 zK>h-G85D=e#zE>P1_oIEfXSifGihkt!PLXlC4eG=fq|g`WH@7$YLNiOdp61!r=@I44{05t~>!MfbK4s zyFq$EI3H?1R5?fpj3+<^BEUQZfv!IbNBlnkWpV}vc=-#8e^5Sy>4(KX$Uji45SB17 zFuZ^YT7VQVFff4fB1kU?gA~H_gUm#adyu>WH2py + +#include "math_private.h" + +static const float one = 1.0, shuge = 1.0e37; + +OLM_DLLEXPORT float +__ieee754_sinhf(float x) +{ + float t,h; + int32_t ix,jx; + + GET_FLOAT_WORD(jx,x); + ix = jx&0x7fffffff; + + /* x is INF or NaN */ + if(ix>=0x7f800000) return x+x; + + h = 0.5; + if (jx<0) h = -h; + /* |x| in [0,9], return sign(x)*0.5*(E+E/(E+1))) */ + if (ix < 0x41100000) { /* |x|<9 */ + if (ix<0x39800000) /* |x|<2**-12 */ + if(shuge+x>one) return x;/* sinh(tiny) = tiny with inexact */ + t = expm1f(fabsf(x)); + if(ix<0x3f800000) return h*((float)2.0*t-t*t/(t+one)); + return h*(t+t/(t+one)); + } + + /* |x| in [9, logf(maxfloat)] return 0.5*exp(|x|) */ + if (ix < 0x42b17217) return h*__ieee754_expf(fabsf(x)); + + /* |x| in [logf(maxfloat), overflowthresold] */ + if (ix<=0x42b2d4fc) + return h*2.0F*__ldexp_expf(fabsf(x), -1); + + /* |x| > overflowthresold, sinh(x) overflow */ + return x*shuge; +} diff --git a/src/openlibm/src/e_sinhf.c.o b/src/openlibm/src/e_sinhf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..5937e7887f46cd4d28a6f9d68b16394d0b7eae5b GIT binary patch literal 2528 zcmb<-^>JfjWMqH=Mg}_u1P><4z>vU(U^{@B4h(z@ybQr<{B;L94>vyk|NnozNAnwj z#^3+{*Vps6zh+=yXg$E+F`0pZ;WNJgFG$a4egRPs4N}AJ$lnf<1F`EZ`P(l;)X9S6 zKl2NyLTJGd6&`+#6QB7bZhYn!Oi|(B*S}M4@&Y6YCO-2Eq^NLw<`)2~y8%`jdE+yG z1W3z~&-`&WKJ&+%{>&eF%A@&+0Kdk;=)-CJ@-8@?)Rz1I|Nq9{VnrLB_}eBhFfcU! z{&QuM6Mx$pi1WbS02vkinLqLbzsAAC{PGPT*YInc011O^j)n-gfP@)7^9zQkaDd$k zCSYCzd)prDa1MSAkc;o|w^{xF{~vBp-05hLX&|>l3#|4v4=`y%hid|3A!s zf<91t_y7O@|3A!fA5dsTo_P88-~ay%3=Q@S3=H-R3=R7k7#Q{++WVn~!QI)}N(&_vHj&rre0z{u3V(9l3ZBPcaR!6UH*Dxqtx$-uzEz`&ruz`(%Dz`)?{7s|lI zz<2;821`SXP(CL(G#D5}pfqDu5Cda{0HZVyJI4e@1_m1j1_l|Z+#Zl-M?QgOrT{(# zra4@E0xosDV?p%BVu6!Im+!YW;FgH{uCIvEzh2i6WOc@3SW-KWk zViL$Vs5%6|Tvo7u!AvLtPR|Ui3=ny!AOiz~6qw1%zyYQaggltZ%D@Ar5rhf@1A`Ef zd%$79z`&rzz<^;kNS6T)aZrS!y9K1)9EW;_)cE4eyo@xxWClGSX9Eyn2qH{Cgb|1^ zW&kT-NJ~sAPGd-|D9ANTV~CH>NlC3Jh)=C3NCO$qpa~`!7?>D9;mW}92bAdk|Nn1@ zBo0a!F!4YnaZqT(#3PZ!nHdn~ltINoW`NQXOno(yI2V%oJy3Cwdq71OO#Klgadss2 zACSb6-J=dlKn##{j%=?Ek~p%xCQxyZy~yq_hl-=SzXnMhl=fimoR1`qZ0|}WaZnn9 zsR!jjkQYGqf-r~;#(Kq-xh08740^>SMG!gz#wtq9Nz^Mzttes8OGzwAWY9}0E@sdx z$_H`ul8Z}B81$0!b8}PkN*MI=@=H?n-2Fmzi%Sxdv!VR-yi&b_qWpr?qLNAmJ+N`9 z8S!aFiMgp@yQx5c`~~tdC=QX0gVaF`46u9xlS5DY($KhrsfVfa07V1?149GIa0Uhj zP}qZ*u>2|kRj9_m0M3=5xP%IUsXrjaU=}KYF08}A04@W_)ep))ATxzftzm%K4=Yb$ z(ok=~%PBjk`$6ReObv(@fF=@s5C;i^>;iFNv^!KkNDLX +#include + +#include "math_private.h" + +static const double one = 1.0, tiny=1.0e-300; + +OLM_DLLEXPORT double +__ieee754_sqrt(double x) +{ + double z; + int32_t sign = (int)0x80000000; + int32_t ix0,s0,q,m,t,i; + u_int32_t r,t1,s1,ix1,q1; + + EXTRACT_WORDS(ix0,ix1,x); + + /* take care of Inf and NaN */ + if((ix0&0x7ff00000)==0x7ff00000) { + return x*x+x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf + sqrt(-inf)=sNaN */ + } + /* take care of zero */ + if(ix0<=0) { + if(((ix0&(~sign))|ix1)==0) return x;/* sqrt(+-0) = +-0 */ + else if(ix0<0) + return (x-x)/(x-x); /* sqrt(-ve) = sNaN */ + } + /* normalize x */ + m = (ix0>>20); + if(m==0) { /* subnormal x */ + while(ix0==0) { + m -= 21; + ix0 |= (ix1>>11); ix1 <<= 21; + } + for(i=0;(ix0&0x00100000)==0;i++) ix0<<=1; + m -= i-1; + ix0 |= (ix1>>(32-i)); + ix1 <<= i; + } + m -= 1023; /* unbias exponent */ + ix0 = (ix0&0x000fffff)|0x00100000; + if(m&1){ /* odd m, double x to make it even */ + ix0 += ix0 + ((ix1&sign)>>31); + ix1 += ix1; + } + m >>= 1; /* m = [m/2] */ + + /* generate sqrt(x) bit by bit */ + ix0 += ix0 + ((ix1&sign)>>31); + ix1 += ix1; + q = q1 = s0 = s1 = 0; /* [q,q1] = sqrt(x) */ + r = 0x00200000; /* r = moving bit from right to left */ + + while(r!=0) { + t = s0+r; + if(t<=ix0) { + s0 = t+r; + ix0 -= t; + q += r; + } + ix0 += ix0 + ((ix1&sign)>>31); + ix1 += ix1; + r>>=1; + } + + r = sign; + while(r!=0) { + t1 = s1+r; + t = s0; + if((t>31); + ix1 += ix1; + r>>=1; + } + + /* use floating add to find out rounding direction */ + if((ix0|ix1)!=0) { + z = one-tiny; /* trigger inexact flag */ + if (z>=one) { + z = one+tiny; + if (q1==(u_int32_t)0xffffffff) { q1=0; q += 1;} + else if (z>one) { + if (q1==(u_int32_t)0xfffffffe) q+=1; + q1+=2; + } else + q1 += (q1&1); + } + } + ix0 = (q>>1)+0x3fe00000; + ix1 = q1>>1; + if ((q&1)==1) ix1 |= sign; + ix0 += (m <<20); + INSERT_WORDS(z,ix0,ix1); + return z; +} + +#if (LDBL_MANT_DIG == 53) +openlibm_weak_reference(sqrt, sqrtl); +#endif + +/* +Other methods (use floating-point arithmetic) +------------- +(This is a copy of a drafted paper by Prof W. Kahan +and K.C. Ng, written in May, 1986) + + Two algorithms are given here to implement sqrt(x) + (IEEE double precision arithmetic) in software. + Both supply sqrt(x) correctly rounded. The first algorithm (in + Section A) uses newton iterations and involves four divisions. + The second one uses reciproot iterations to avoid division, but + requires more multiplications. Both algorithms need the ability + to chop results of arithmetic operations instead of round them, + and the INEXACT flag to indicate when an arithmetic operation + is executed exactly with no roundoff error, all part of the + standard (IEEE 754-1985). The ability to perform shift, add, + subtract and logical AND operations upon 32-bit words is needed + too, though not part of the standard. + +A. sqrt(x) by Newton Iteration + + (1) Initial approximation + + Let x0 and x1 be the leading and the trailing 32-bit words of + a floating point number x (in IEEE double format) respectively + + 1 11 52 ...widths + ------------------------------------------------------ + x: |s| e | f | + ------------------------------------------------------ + msb lsb msb lsb ...order + + + ------------------------ ------------------------ + x0: |s| e | f1 | x1: | f2 | + ------------------------ ------------------------ + + By performing shifts and subtracts on x0 and x1 (both regarded + as integers), we obtain an 8-bit approximation of sqrt(x) as + follows. + + k := (x0>>1) + 0x1ff80000; + y0 := k - T1[31&(k>>15)]. ... y ~ sqrt(x) to 8 bits + Here k is a 32-bit integer and T1[] is an integer array containing + correction terms. Now magically the floating value of y (y's + leading 32-bit word is y0, the value of its trailing word is 0) + approximates sqrt(x) to almost 8-bit. + + Value of T1: + static int T1[32]= { + 0, 1024, 3062, 5746, 9193, 13348, 18162, 23592, + 29598, 36145, 43202, 50740, 58733, 67158, 75992, 85215, + 83599, 71378, 60428, 50647, 41945, 34246, 27478, 21581, + 16499, 12183, 8588, 5674, 3403, 1742, 661, 130,}; + + (2) Iterative refinement + + Apply Heron's rule three times to y, we have y approximates + sqrt(x) to within 1 ulp (Unit in the Last Place): + + y := (y+x/y)/2 ... almost 17 sig. bits + y := (y+x/y)/2 ... almost 35 sig. bits + y := y-(y-x/y)/2 ... within 1 ulp + + + Remark 1. + Another way to improve y to within 1 ulp is: + + y := (y+x/y) ... almost 17 sig. bits to 2*sqrt(x) + y := y - 0x00100006 ... almost 18 sig. bits to sqrt(x) + + 2 + (x-y )*y + y := y + 2* ---------- ...within 1 ulp + 2 + 3y + x + + + This formula has one division fewer than the one above; however, + it requires more multiplications and additions. Also x must be + scaled in advance to avoid spurious overflow in evaluating the + expression 3y*y+x. Hence it is not recommended uless division + is slow. If division is very slow, then one should use the + reciproot algorithm given in section B. + + (3) Final adjustment + + By twiddling y's last bit it is possible to force y to be + correctly rounded according to the prevailing rounding mode + as follows. Let r and i be copies of the rounding mode and + inexact flag before entering the square root program. Also we + use the expression y+-ulp for the next representable floating + numbers (up and down) of y. Note that y+-ulp = either fixed + point y+-1, or multiply y by nextafter(1,+-inf) in chopped + mode. + + I := FALSE; ... reset INEXACT flag I + R := RZ; ... set rounding mode to round-toward-zero + z := x/y; ... chopped quotient, possibly inexact + If(not I) then { ... if the quotient is exact + if(z=y) { + I := i; ... restore inexact flag + R := r; ... restore rounded mode + return sqrt(x):=y. + } else { + z := z - ulp; ... special rounding + } + } + i := TRUE; ... sqrt(x) is inexact + If (r=RN) then z=z+ulp ... rounded-to-nearest + If (r=RP) then { ... round-toward-+inf + y = y+ulp; z=z+ulp; + } + y := y+z; ... chopped sum + y0:=y0-0x00100000; ... y := y/2 is correctly rounded. + I := i; ... restore inexact flag + R := r; ... restore rounded mode + return sqrt(x):=y. + + (4) Special cases + + Square root of +inf, +-0, or NaN is itself; + Square root of a negative number is NaN with invalid signal. + + +B. sqrt(x) by Reciproot Iteration + + (1) Initial approximation + + Let x0 and x1 be the leading and the trailing 32-bit words of + a floating point number x (in IEEE double format) respectively + (see section A). By performing shifs and subtracts on x0 and y0, + we obtain a 7.8-bit approximation of 1/sqrt(x) as follows. + + k := 0x5fe80000 - (x0>>1); + y0:= k - T2[63&(k>>14)]. ... y ~ 1/sqrt(x) to 7.8 bits + + Here k is a 32-bit integer and T2[] is an integer array + containing correction terms. Now magically the floating + value of y (y's leading 32-bit word is y0, the value of + its trailing word y1 is set to zero) approximates 1/sqrt(x) + to almost 7.8-bit. + + Value of T2: + static int T2[64]= { + 0x1500, 0x2ef8, 0x4d67, 0x6b02, 0x87be, 0xa395, 0xbe7a, 0xd866, + 0xf14a, 0x1091b,0x11fcd,0x13552,0x14999,0x15c98,0x16e34,0x17e5f, + 0x18d03,0x19a01,0x1a545,0x1ae8a,0x1b5c4,0x1bb01,0x1bfde,0x1c28d, + 0x1c2de,0x1c0db,0x1ba73,0x1b11c,0x1a4b5,0x1953d,0x18266,0x16be0, + 0x1683e,0x179d8,0x18a4d,0x19992,0x1a789,0x1b445,0x1bf61,0x1c989, + 0x1d16d,0x1d77b,0x1dddf,0x1e2ad,0x1e5bf,0x1e6e8,0x1e654,0x1e3cd, + 0x1df2a,0x1d635,0x1cb16,0x1be2c,0x1ae4e,0x19bde,0x1868e,0x16e2e, + 0x1527f,0x1334a,0x11051,0xe951, 0xbe01, 0x8e0d, 0x5924, 0x1edd,}; + + (2) Iterative refinement + + Apply Reciproot iteration three times to y and multiply the + result by x to get an approximation z that matches sqrt(x) + to about 1 ulp. To be exact, we will have + -1ulp < sqrt(x)-z<1.0625ulp. + + ... set rounding mode to Round-to-nearest + y := y*(1.5-0.5*x*y*y) ... almost 15 sig. bits to 1/sqrt(x) + y := y*((1.5-2^-30)+0.5*x*y*y)... about 29 sig. bits to 1/sqrt(x) + ... special arrangement for better accuracy + z := x*y ... 29 bits to sqrt(x), with z*y<1 + z := z + 0.5*z*(1-z*y) ... about 1 ulp to sqrt(x) + + Remark 2. The constant 1.5-2^-30 is chosen to bias the error so that + (a) the term z*y in the final iteration is always less than 1; + (b) the error in the final result is biased upward so that + -1 ulp < sqrt(x) - z < 1.0625 ulp + instead of |sqrt(x)-z|<1.03125ulp. + + (3) Final adjustment + + By twiddling y's last bit it is possible to force y to be + correctly rounded according to the prevailing rounding mode + as follows. Let r and i be copies of the rounding mode and + inexact flag before entering the square root program. Also we + use the expression y+-ulp for the next representable floating + numbers (up and down) of y. Note that y+-ulp = either fixed + point y+-1, or multiply y by nextafter(1,+-inf) in chopped + mode. + + R := RZ; ... set rounding mode to round-toward-zero + switch(r) { + case RN: ... round-to-nearest + if(x<= z*(z-ulp)...chopped) z = z - ulp; else + if(x<= z*(z+ulp)...chopped) z = z; else z = z+ulp; + break; + case RZ:case RM: ... round-to-zero or round-to--inf + R:=RP; ... reset rounding mod to round-to-+inf + if(x=(z+ulp)*(z+ulp) ...rounded up) z = z+ulp; + break; + case RP: ... round-to-+inf + if(x>(z+ulp)*(z+ulp)...chopped) z = z+2*ulp; else + if(x>z*z ...chopped) z = z+ulp; + break; + } + + Remark 3. The above comparisons can be done in fixed point. For + example, to compare x and w=z*z chopped, it suffices to compare + x1 and w1 (the trailing parts of x and w), regarding them as + two's complement integers. + + ...Is z an exact square root? + To determine whether z is an exact square root of x, let z1 be the + trailing part of z, and also let x0 and x1 be the leading and + trailing parts of x. + + If ((z1&0x03ffffff)!=0) ... not exact if trailing 26 bits of z!=0 + I := 1; ... Raise Inexact flag: z is not exact + else { + j := 1 - [(x0>>20)&1] ... j = logb(x) mod 2 + k := z1 >> 26; ... get z's 25-th and 26-th + fraction bits + I := i or (k&j) or ((k&(j+j+1))!=(x1&3)); + } + R:= r ... restore rounded mode + return sqrt(x):=z. + + If multiplication is cheaper then the foregoing red tape, the + Inexact flag can be evaluated by + + I := i; + I := (z*z!=x) or I. + + Note that z*z can overwrite I; this value must be sensed if it is + True. + + Remark 4. If z*z = x exactly, then bit 25 to bit 0 of z1 must be + zero. + + -------------------- + z1: | f2 | + -------------------- + bit 31 bit 0 + + Further more, bit 27 and 26 of z1, bit 0 and 1 of x1, and the odd + or even of logb(x) have the following relations: + + ------------------------------------------------- + bit 27,26 of z1 bit 1,0 of x1 logb(x) + ------------------------------------------------- + 00 00 odd and even + 01 01 even + 10 10 odd + 10 00 even + 11 01 even + ------------------------------------------------- + + (4) Special cases (see (4) of Section A). + + */ + diff --git a/src/openlibm/src/e_sqrtf.c b/src/openlibm/src/e_sqrtf.c new file mode 100644 index 0000000..2aeaa9f --- /dev/null +++ b/src/openlibm/src/e_sqrtf.c @@ -0,0 +1,86 @@ +/* e_sqrtf.c -- float version of e_sqrt.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include + +#include "math_private.h" + +static const float one = 1.0, tiny=1.0e-30; + +OLM_DLLEXPORT float +__ieee754_sqrtf(float x) +{ + float z; + int32_t sign = (int)0x80000000; + int32_t ix,s,q,m,t,i; + u_int32_t r; + + GET_FLOAT_WORD(ix,x); + + /* take care of Inf and NaN */ + if((ix&0x7f800000)==0x7f800000) { + return x*x+x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf + sqrt(-inf)=sNaN */ + } + /* take care of zero */ + if(ix<=0) { + if((ix&(~sign))==0) return x;/* sqrt(+-0) = +-0 */ + else if(ix<0) + return (x-x)/(x-x); /* sqrt(-ve) = sNaN */ + } + /* normalize x */ + m = (ix>>23); + if(m==0) { /* subnormal x */ + for(i=0;(ix&0x00800000)==0;i++) ix<<=1; + m -= i-1; + } + m -= 127; /* unbias exponent */ + ix = (ix&0x007fffff)|0x00800000; + if(m&1) /* odd m, double x to make it even */ + ix += ix; + m >>= 1; /* m = [m/2] */ + + /* generate sqrt(x) bit by bit */ + ix += ix; + q = s = 0; /* q = sqrt(x) */ + r = 0x01000000; /* r = moving bit from right to left */ + + while(r!=0) { + t = s+r; + if(t<=ix) { + s = t+r; + ix -= t; + q += r; + } + ix += ix; + r>>=1; + } + + /* use floating add to find out rounding direction */ + if(ix!=0) { + z = one-tiny; /* trigger inexact flag */ + if (z>=one) { + z = one+tiny; + if (z>one) + q += 2; + else + q += (q&1); + } + } + ix = (q>>1)+0x3f000000; + ix += (m <<23); + SET_FLOAT_WORD(z,ix); + return z; +} diff --git a/src/openlibm/src/e_sqrtl.c b/src/openlibm/src/e_sqrtl.c new file mode 100644 index 0000000..a073bf9 --- /dev/null +++ b/src/openlibm/src/e_sqrtl.c @@ -0,0 +1,162 @@ +/*- + * Copyright (c) 2007 Steven G. Kargl + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/e_sqrtl.c,v 1.1 2008/03/02 01:47:58 das Exp $"); + +#include +#include +#include + +#include "fpmath.h" +#include "math_private.h" + +/* Return (x + ulp) for normal positive x. Assumes no overflow. */ +static inline long double +inc(long double x) +{ + union IEEEl2bits u; + + u.e = x; + if (++u.bits.manl == 0) { + if (++u.bits.manh == 0) { + u.bits.exp++; + u.bits.manh |= LDBL_NBIT; + } + } + return (u.e); +} + +/* Return (x - ulp) for normal positive x. Assumes no underflow. */ +static inline long double +dec(long double x) +{ + union IEEEl2bits u; + + u.e = x; + if (u.bits.manl-- == 0) { + if (u.bits.manh-- == LDBL_NBIT) { + u.bits.exp--; + u.bits.manh |= LDBL_NBIT; + } + } + return (u.e); +} + +#ifndef __GNUC__ +#pragma STDC FENV_ACCESS ON +#endif + +/* + * This is slow, but simple and portable. You should use hardware sqrt + * if possible. + */ + +OLM_DLLEXPORT long double +sqrtl(long double x) +{ + union IEEEl2bits u; + int k, r; + long double lo, xn; + fenv_t env; + + u.e = x; + + /* If x = NaN, then sqrt(x) = NaN. */ + /* If x = Inf, then sqrt(x) = Inf. */ + /* If x = -Inf, then sqrt(x) = NaN. */ + if (u.bits.exp == LDBL_MAX_EXP * 2 - 1) + return (x * x + x); + + /* If x = +-0, then sqrt(x) = +-0. */ + if ((u.bits.manh | u.bits.manl | u.bits.exp) == 0) + return (x); + + /* If x < 0, then raise invalid and return NaN */ + if (u.bits.sign) + return ((x - x) / (x - x)); + + feholdexcept(&env); + + if (u.bits.exp == 0) { + /* Adjust subnormal numbers. */ + u.e *= 0x1.0p514; + k = -514; + } else { + k = 0; + } + /* + * u.e is a normal number, so break it into u.e = e*2^n where + * u.e = (2*e)*2^2k for odd n and u.e = (4*e)*2^2k for even n. + */ + if ((u.bits.exp - 0x3ffe) & 1) { /* n is odd. */ + k += u.bits.exp - 0x3fff; /* 2k = n - 1. */ + u.bits.exp = 0x3fff; /* u.e in [1,2). */ + } else { + k += u.bits.exp - 0x4000; /* 2k = n - 2. */ + u.bits.exp = 0x4000; /* u.e in [2,4). */ + } + + /* + * Newton's iteration. + * Split u.e into a high and low part to achieve additional precision. + */ + xn = sqrt(u.e); /* 53-bit estimate of sqrtl(x). */ +#if LDBL_MANT_DIG > 100 + xn = (xn + (u.e / xn)) * 0.5; /* 106-bit estimate. */ +#endif + lo = u.e; + u.bits.manl = 0; /* Zero out lower bits. */ + lo = (lo - u.e) / xn; /* Low bits divided by xn. */ + xn = xn + (u.e / xn); /* High portion of estimate. */ + u.e = xn + lo; /* Combine everything. */ + u.bits.exp += (k >> 1) - 1; + + feclearexcept(FE_INEXACT); + r = fegetround(); + fesetround(FE_TOWARDZERO); /* Set to round-toward-zero. */ + xn = x / u.e; /* Chopped quotient (inexact?). */ + + if (!fetestexcept(FE_INEXACT)) { /* Quotient is exact. */ + if (xn == u.e) { + fesetenv(&env); + return (u.e); + } + /* Round correctly for inputs like x = y**2 - ulp. */ + xn = dec(xn); /* xn = xn - ulp. */ + } + + if (r == FE_TONEAREST) { + xn = inc(xn); /* xn = xn + ulp. */ + } else if (r == FE_UPWARD) { + u.e = inc(u.e); /* u.e = u.e + ulp. */ + xn = inc(xn); /* xn = xn + ulp. */ + } + u.e = u.e + xn; /* Chopped sum. */ + feupdateenv(&env); /* Restore env and raise inexact */ + u.bits.exp--; + return (u.e); +} diff --git a/src/openlibm/src/fpmath.h b/src/openlibm/src/fpmath.h new file mode 100644 index 0000000..eb824d7 --- /dev/null +++ b/src/openlibm/src/fpmath.h @@ -0,0 +1,124 @@ +/*- + * Copyright (c) 2003 Mike Barcroft + * Copyright (c) 2002 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libc/include/fpmath.h,v 1.4 2008/12/23 22:20:59 marcel Exp $ + */ +#ifndef _FPMATH_H_ +#define _FPMATH_H_ + +#if defined(__aarch64__) +#include "aarch64_fpmath.h" +#elif defined(__i386__) || defined(__x86_64__) +#ifdef __LP64__ +#include "amd64_fpmath.h" +#else +#include "i386_fpmath.h" +#endif +#elif defined(__powerpc__) || defined(__POWERPC__) +#include "powerpc_fpmath.h" +#elif defined(__mips__) +#include "mips_fpmath.h" +#elif defined(__s390__) +#include "s390_fpmath.h" +#elif defined(__riscv) +#include "riscv_fpmath.h" +#elif defined(__loongarch64) +#include "loongarch64_fpmath.h" +#endif + +/* Definitions provided directly by GCC and Clang. */ +#if !(defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && defined(__ORDER_BIG_ENDIAN__)) + +#if defined(__GLIBC__) + +#include +#include +#define __ORDER_LITTLE_ENDIAN__ __LITTLE_ENDIAN +#define __ORDER_BIG_ENDIAN__ __BIG_ENDIAN +#define __BYTE_ORDER__ __BYTE_ORDER + +#elif defined(__APPLE__) + +#include +#define __ORDER_LITTLE_ENDIAN__ LITTLE_ENDIAN +#define __ORDER_BIG_ENDIAN__ BIG_ENDIAN +#define __BYTE_ORDER__ BYTE_ORDER + +#elif defined(_WIN32) + +#define __ORDER_LITTLE_ENDIAN__ 1234 +#define __ORDER_BIG_ENDIAN__ 4321 +#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__ + +#endif + +#endif /* __BYTE_ORDER__, __ORDER_LITTLE_ENDIAN__ and __ORDER_BIG_ENDIAN__ */ + +#ifndef __FLOAT_WORD_ORDER__ +#define __FLOAT_WORD_ORDER__ __BYTE_ORDER__ +#endif + +union IEEEf2bits { + float f; + struct { +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + unsigned int man :23; + unsigned int exp :8; + unsigned int sign :1; +#else /* _BIG_ENDIAN */ + unsigned int sign :1; + unsigned int exp :8; + unsigned int man :23; +#endif + } bits; +}; + +#define DBL_MANH_SIZE 20 +#define DBL_MANL_SIZE 32 + +union IEEEd2bits { + double d; + struct { +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +#if __FLOAT_WORD_ORDER__ == __ORDER_LITTLE_ENDIAN__ + unsigned int manl :32; +#endif + unsigned int manh :20; + unsigned int exp :11; + unsigned int sign :1; +#if __FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__ + unsigned int manl :32; +#endif +#else /* _BIG_ENDIAN */ + unsigned int sign :1; + unsigned int exp :11; + unsigned int manh :20; + unsigned int manl :32; +#endif + } bits; +}; + +#endif diff --git a/src/openlibm/src/i386_fpmath.h b/src/openlibm/src/i386_fpmath.h new file mode 100644 index 0000000..455631c --- /dev/null +++ b/src/openlibm/src/i386_fpmath.h @@ -0,0 +1,54 @@ +/*- + * Copyright (c) 2002, 2003 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libc/i386/_fpmath.h,v 1.6 2008/01/17 16:39:06 bde Exp $ + */ + +union IEEEl2bits { + long double e; + struct { + unsigned int manl :32; + unsigned int manh :32; + unsigned int exp :15; + unsigned int sign :1; + unsigned int junk :16; + } bits; + struct { + unsigned long long man :64; + unsigned int expsign :16; + unsigned int junk :16; + } xbits; +}; + +#define LDBL_NBIT 0x80000000 +#define mask_nbit_l(u) ((u).bits.manh &= ~LDBL_NBIT) + +#define LDBL_MANH_SIZE 32 +#define LDBL_MANL_SIZE 32 + +#define LDBL_TO_ARRAY32(u, a) do { \ + (a)[0] = (uint32_t)(u).bits.manl; \ + (a)[1] = (uint32_t)(u).bits.manh; \ +} while (0) diff --git a/src/openlibm/src/k_cos.c b/src/openlibm/src/k_cos.c new file mode 100644 index 0000000..f3054ef --- /dev/null +++ b/src/openlibm/src/k_cos.c @@ -0,0 +1,80 @@ + +/* @(#)k_cos.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/k_cos.c,v 1.12 2008/02/19 12:54:14 bde Exp $"); + +/* + * __kernel_cos( x, y ) + * kernel cos function on [-pi/4, pi/4], pi/4 ~ 0.785398164 + * Input x is assumed to be bounded by ~pi/4 in magnitude. + * Input y is the tail of x. + * + * Algorithm + * 1. Since cos(-x) = cos(x), we need only to consider positive x. + * 2. if x < 2^-27 (hx<0x3e400000 0), return 1 with inexact if x!=0. + * 3. cos(x) is approximated by a polynomial of degree 14 on + * [0,pi/4] + * 4 14 + * cos(x) ~ 1 - x*x/2 + C1*x + ... + C6*x + * where the remez error is + * + * | 2 4 6 8 10 12 14 | -58 + * |cos(x)-(1-.5*x +C1*x +C2*x +C3*x +C4*x +C5*x +C6*x )| <= 2 + * | | + * + * 4 6 8 10 12 14 + * 4. let r = C1*x +C2*x +C3*x +C4*x +C5*x +C6*x , then + * cos(x) ~ 1 - x*x/2 + r + * since cos(x+y) ~ cos(x) - sin(x)*y + * ~ cos(x) - x*y, + * a correction term is necessary in cos(x) and hence + * cos(x+y) = 1 - (x*x/2 - (r - x*y)) + * For better accuracy, rearrange to + * cos(x+y) ~ w + (tmp + (r-x*y)) + * where w = 1 - x*x/2 and tmp is a tiny correction term + * (1 - x*x/2 == w + tmp exactly in infinite precision). + * The exactness of w + tmp in infinite precision depends on w + * and tmp having the same precision as x. If they have extra + * precision due to compiler bugs, then the extra precision is + * only good provided it is retained in all terms of the final + * expression for cos(). Retention happens in all cases tested + * under FreeBSD, so don't pessimize things by forcibly clipping + * any extra precision in w. + */ + +#include + +#include "math_private.h" + +static const double +one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */ +C1 = 4.16666666666666019037e-02, /* 0x3FA55555, 0x5555554C */ +C2 = -1.38888888888741095749e-03, /* 0xBF56C16C, 0x16C15177 */ +C3 = 2.48015872894767294178e-05, /* 0x3EFA01A0, 0x19CB1590 */ +C4 = -2.75573143513906633035e-07, /* 0xBE927E4F, 0x809C52AD */ +C5 = 2.08757232129817482790e-09, /* 0x3E21EE9E, 0xBDB4B1C4 */ +C6 = -1.13596475577881948265e-11; /* 0xBDA8FAE9, 0xBE8838D4 */ + +OLM_DLLEXPORT double +__kernel_cos(double x, double y) +{ + double hz,z,r,w; + + z = x*x; + w = z*z; + r = z*(C1+z*(C2+z*C3)) + w*w*(C4+z*(C5+z*C6)); + hz = 0.5*z; + w = one-hz; + return w + (((one-w)-hz) + (z*r-x*y)); +} diff --git a/src/openlibm/src/k_cos.c.o b/src/openlibm/src/k_cos.c.o new file mode 100644 index 0000000000000000000000000000000000000000..2453bfe6f2b823d727129752d2012ef4e818c756 GIT binary patch literal 2024 zcmb<-^>JfjWMqH=Mg}_u1P><4z>vX$U^{@B4h(z@ybNjl8W+;|H6DE87qA5hf8rO= zh0u`~KJg2%LfH?~_%*(M;*UI(#;%j9Z`hW8Qz_k3r%`AhQoc%{lUkKjP>o{)l6TK^npMfjyXF_+WpTM`8(7Lf2fAfdLdu3JeSkAkVn_g)%TPFdhJj z!NQag%IAbQh(QEOGgbvLFjfdKO7pODOkiXHi_1Xe=0a(F6v%uQhL8WTsbR(vqY(Q+ zu0++r2j;ReaDZt9Aq-}+G6;Za1R()tvNAwuFb7P4BZh&M0TdQs0Vtsardb&@z%+tT z2Qyh248Syk&;c`987#mwf-q!YU=Tv`7d(uz|y4VAc=$G3?|-yB+i9o4zhbdZh|UfV9+bB%q>YwV$drt zDT2@$Fji4&PNH5(YDEcyUP@v~B7P)YQ3D$M}Nn=tiIWeftKNM>MQH~NN z0J#-e6qJrZW|FHPl-@yR3LzWHz`*bT%18GX$S#l+jJAWiA3c95fDC0|V9*CCM#4~G za9DtZ-J$wHY-H>YQ-~~xMQu0(0|O|%qohd&28IBresp)i+zm4}A8IDL{stoTXW@wd z3(yFG#WN`WLHP`3KTI5C4Z7VRw`~APFfcH{!Vy${fXqPG4>A*K6-XN#Uw|44iXXTj b)UU{VL1=k|ECyn~fEro};viwDv*02Cfjsoc literal 0 HcmV?d00001 diff --git a/src/openlibm/src/k_cosf.c b/src/openlibm/src/k_cosf.c new file mode 100644 index 0000000..6774db4 --- /dev/null +++ b/src/openlibm/src/k_cosf.c @@ -0,0 +1,48 @@ +/* k_cosf.c -- float version of k_cos.c + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + * Debugged and optimized by Bruce D. Evans. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#ifndef INLINE_KERNEL_COSDF +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/k_cosf.c,v 1.18 2009/06/03 08:16:34 ed Exp $"); +#endif + +#include + +#include "math_private.h" + +/* |cos(x) - c(x)| < 2**-34.1 (~[-5.37e-11, 5.295e-11]). */ +static const double +one = 1.0, +C0 = -0x1ffffffd0c5e81.0p-54, /* -0.499999997251031003120 */ +C1 = 0x155553e1053a42.0p-57, /* 0.0416666233237390631894 */ +C2 = -0x16c087e80f1e27.0p-62, /* -0.00138867637746099294692 */ +C3 = 0x199342e0ee5069.0p-68; /* 0.0000243904487962774090654 */ + +#ifndef INLINE_KERNEL_COSDF +extern +#endif +//__inline float +OLM_DLLEXPORT float +__kernel_cosdf(double x) +{ + double r, w, z; + + /* Try to optimize for parallel evaluation as in k_tanf.c. */ + z = x*x; + w = z*z; + r = C2+z*C3; + return ((one+z*C0) + w*C1) + (w*z)*r; +} diff --git a/src/openlibm/src/k_cosf.c.o b/src/openlibm/src/k_cosf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..b8cd5e29d5c9daec6bb93880fba1edd455c3d041 GIT binary patch literal 1776 zcmb<-^>JfjWMqH=Mg}_u1P><4z)--9U^{@B4h(z@ybPcCBM*Gy7Z3#rec~73h0u{F z()cxQeBzJ1@rgeICU*G~f5a(-+Q&4amziGhIul!X5LhX9zrK;oeA zhl#5|^?}4ezJ!UJAc?avFfhQxU691tk;Fl943Yww1HvFS80!^R=9VNTG3XVS6hY_= z7^^5XCsD5?wW5SUFD0=gkwGu1xR^n&C?CYpOD-<4V9-m>&&^HED`C*f%P&dQbN36? zEiOq+&W7^S^Gfv!it-Cmi%KdP^uWfYX2hozCFZ7r?WO_&@)syAfx-aUI7pskV1UOL zR1y}>P%eWs10)Z?)WgIRpn+5Y72sxI0H*?2{K3+X8dMws zDg$Bm!^A<>K$XIr1f~N(5)2FsH^4jw1|DcUqw5Emi5~YLEgDcmjX)eE3^f)mA_y%< S-~v#_2dMr^C?7_l>jwZyz_LsL literal 0 HcmV?d00001 diff --git a/src/openlibm/src/k_exp.c b/src/openlibm/src/k_exp.c new file mode 100644 index 0000000..4739e20 --- /dev/null +++ b/src/openlibm/src/k_exp.c @@ -0,0 +1,108 @@ +/*- + * Copyright (c) 2011 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/k_exp.c,v 1.1 2011/10/21 06:27:56 das Exp $"); + +#include +#include + +#include "math_private.h" + +static const u_int32_t k = 1799; /* constant for reduction */ +static const double kln2 = 1246.97177782734161156; /* k * ln2 */ + +/* + * Compute exp(x), scaled to avoid spurious overflow. An exponent is + * returned separately in 'expt'. + * + * Input: ln(DBL_MAX) <= x < ln(2 * DBL_MAX / DBL_MIN_DENORM) ~= 1454.91 + * Output: 2**1023 <= y < 2**1024 + */ +static double +__frexp_exp(double x, int *expt) +{ + double exp_x; + u_int32_t hx; + + /* + * We use exp(x) = exp(x - kln2) * 2**k, carefully chosen to + * minimize |exp(kln2) - 2**k|. We also scale the exponent of + * exp_x to MAX_EXP so that the result can be multiplied by + * a tiny number without losing accuracy due to denormalization. + */ + exp_x = exp(x - kln2); + GET_HIGH_WORD(hx, exp_x); + *expt = (hx >> 20) - (0x3ff + 1023) + k; + SET_HIGH_WORD(exp_x, (hx & 0xfffff) | ((0x3ff + 1023) << 20)); + return (exp_x); +} + +/* + * __ldexp_exp(x, expt) and __ldexp_cexp(x, expt) compute exp(x) * 2**expt. + * They are intended for large arguments (real part >= ln(DBL_MAX)) + * where care is needed to avoid overflow. + * + * The present implementation is narrowly tailored for our hyperbolic and + * exponential functions. We assume expt is small (0 or -1), and the caller + * has filtered out very large x, for which overflow would be inevitable. + */ + +OLM_DLLEXPORT double +__ldexp_exp(double x, int expt) +{ + double exp_x, scale; + int ex_expt; + + exp_x = __frexp_exp(x, &ex_expt); + expt += ex_expt; + INSERT_WORDS(scale, (0x3ff + expt) << 20, 0); + return (exp_x * scale); +} + +OLM_DLLEXPORT double complex +__ldexp_cexp(double complex z, int expt) +{ + double x, y, exp_x, scale1, scale2; + int ex_expt, half_expt; + + x = creal(z); + y = cimag(z); + exp_x = __frexp_exp(x, &ex_expt); + expt += ex_expt; + + /* + * Arrange so that scale1 * scale2 == 2**expt. We use this to + * compensate for scalbn being horrendously slow. + */ + half_expt = expt / 2; + INSERT_WORDS(scale1, (0x3ff + half_expt) << 20, 0); + half_expt = expt - half_expt; + INSERT_WORDS(scale2, (0x3ff + half_expt) << 20, 0); + + return (CMPLX(cos(y) * exp_x * scale1 * scale2, + sin(y) * exp_x * scale1 * scale2)); +} diff --git a/src/openlibm/src/k_exp.c.o b/src/openlibm/src/k_exp.c.o new file mode 100644 index 0000000000000000000000000000000000000000..2fe85165c0c64779427c59b493ef39d9ab92d075 GIT binary patch literal 2232 zcmb<-^>JfjWMqH=Mg}_u1P><4z+l0OU^{@B4h(z@ybQsg_+!9Qoxfjzgws6u>kfEy z9_&2eaqy*rN9U=7FGU(3{r}I;;L&)Bf#E^D$H7Mm9-J3?r*LyHGcZISd?b?Q!Jl^m zBn)C4`otf3@Nk+QzkCbGI0nZs#}LQPKcT@M&2J<=@eA^(eBu{$QQ-hv_K9C0M1|uM zzW|R4$lk+g{2GVA5^0|Nb;m%)9fmm%BJ9CmcQnnDKkt}F=c~@Q9tU43cywMk_)0_- z>_A?K`yMEGa2|E+Z4u%8|NnpIp@XmF84q3jrFp@nchP@l28P}lAky*R6A_r1d3QYz zK2i9@A9)yL_LGB;MLZ5ZRsdQ5`V)WTkx%@QM?dikvZ#P$kHIya1#!QCRQ>+MA9>;v zzW|GhNAnSh=vc=X$GA`Yk>@_~N1i_n4h05=CA_;NA6HLyU~qSKwo=e=_Y2ijFf`FK z(lb;rGB7eVFf=q!&g`El!1wX@c>8+7RQWG zJ}1;35h%@A6~w?;A;2ij!_F~*k%2*ifq_8=Di;Q#9r*;Bndh%qoQ2%stj^Q55a6TmzM2C#n^7#P%XsMp0IZj3|R z9EUhVc6@3@fnG9$o{zHuLwtNrN@_&`NC?hOPOT_lNG?iE%wb5*%uP&ZNX{>2D9+4- zI27h{CI$uuW(Ed^KmQ?s2Ot@k%6db|m$akiS zMG!gz#wtq9Nz^Mzttes8OGzwAWY9}0E@sdx$_H`ul8Z|$81$0!b8}PkN*MI=@=H?n z-2Fmzi%Sxdv!VR-yi&b_qWpr?qLNAmJ+N`98S!aFiMgpz=TJ<6{0j;SHZ+qUWh(NkX%DFiYM39o?K4>B7`7;G1a4->b8>NfxhBH;~C{rX5^ASP58 z92OwHJ5)c2jg0TZ6e0^^Q5(*{zyQiOpfriB^Z`^qy1QWRhN;bmnu)Go04h)bQwXKe z^=ILT{|-<_WME)`*$;|;Q2vAIhs8h0nNX{sHbAHbs2~SO0RsaAsQdsKiLM`HCVJe1 nOz40LT7x)97-}3`L=aj|!3Cg<9U#jX7#LvX6I2);Z!kUp9ECk8 literal 0 HcmV?d00001 diff --git a/src/openlibm/src/k_expf.c b/src/openlibm/src/k_expf.c new file mode 100644 index 0000000..bbf094c --- /dev/null +++ b/src/openlibm/src/k_expf.c @@ -0,0 +1,87 @@ +/*- + * Copyright (c) 2011 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/k_expf.c,v 1.1 2011/10/21 06:27:56 das Exp $"); + +#include +#include + +#include "math_private.h" + +static const u_int32_t k = 235; /* constant for reduction */ +static const float kln2 = 162.88958740F; /* k * ln2 */ + +/* + * See k_exp.c for details. + * + * Input: ln(FLT_MAX) <= x < ln(2 * FLT_MAX / FLT_MIN_DENORM) ~= 192.7 + * Output: 2**127 <= y < 2**128 + */ +static float +__frexp_expf(float x, int *expt) +{ + double exp_x; + u_int32_t hx; + + exp_x = expf(x - kln2); + GET_FLOAT_WORD(hx, exp_x); + *expt = (hx >> 23) - (0x7f + 127) + k; + SET_FLOAT_WORD(exp_x, (hx & 0x7fffff) | ((0x7f + 127) << 23)); + return (exp_x); +} + +OLM_DLLEXPORT float +__ldexp_expf(float x, int expt) +{ + float exp_x, scale; + int ex_expt; + + exp_x = __frexp_expf(x, &ex_expt); + expt += ex_expt; + SET_FLOAT_WORD(scale, (0x7f + expt) << 23); + return (exp_x * scale); +} + +OLM_DLLEXPORT float complex +__ldexp_cexpf(float complex z, int expt) +{ + float x, y, exp_x, scale1, scale2; + int ex_expt, half_expt; + + x = crealf(z); + y = cimagf(z); + exp_x = __frexp_expf(x, &ex_expt); + expt += ex_expt; + + half_expt = expt / 2; + SET_FLOAT_WORD(scale1, (0x7f + half_expt) << 23); + half_expt = expt - half_expt; + SET_FLOAT_WORD(scale2, (0x7f + half_expt) << 23); + + return (CMPLXF(cosf(y) * exp_x * scale1 * scale2, + sinf(y) * exp_x * scale1 * scale2)); +} diff --git a/src/openlibm/src/k_expf.c.o b/src/openlibm/src/k_expf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..d97ce21e44ee5d377ff5c464df19fb7d2dc61706 GIT binary patch literal 2216 zcmb<-^>JfjWMqH=Mg}_u1P><4z@Wj3U^{@B4h(z@ybQsg`D4IRoxfjzgwy!z4s;$; z{r|t7;ovKAUIqq+`rZ)XoHYKt6VV4BiKp@B9s0~4dGIj5d<#f9gJW2l2Y=lG#}JQ$ zFBC#M{|0+BztQM)QIYw~FX*Bo0VY{K^VhkkNOZEOfUWqL{i9b+8h4m0d|tmMq#?(A%(pyBQps;OXTqGzOMs98JHLt4}ipAamfhfb3&9eh(Kw^svri&3IRrG9(Ili zj0_AC3=9l1P&o?_?Z_w4%#_W?!N9-(;)5_qm>*=Y6Q4jIlRKY853?(uLK}-SpGGsQ z3ts@!XFd%_J_ScU2`4@QC$LtK7OWU#3=6}@|JWp%v7|&UutJb8!3;RT&%nSSgrpwk zPH_eX1_8J#1Owzpka|d3W?%sOhk=1X3x|3`9O58*u$ga*Lp?)wd}>8OnqD%4o{zHu zLwtNrN@_&`SPafd2B~03E=o~PGcy}%u9oM0Tu#G3=9m+3=9l^ z{zCu{R2~%fAT==Yd?aypB=u8~#6fWkQ@;!KNvfW^U#MdYIB3 zpvY%nU^oC3;AUU|=K@e%f`mZ%8APi=#i7bULSWpFW-nL}susou(K-wa3?MVf)ep)) zAghExh9O~4nFHd2(i4b=VHh7q+d^r+^G)U|`UP@?jKI7#tQLF?Xnb5E~gE zhABiA#G*Ewfq?;(Z$N1hS?LL=esp(%!U|a(DF1= 0 or (e0-3)/24 >= jv + * Hence jv = max(0,(e0-3)/24). + * + * jp jp+1 is the number of terms in PIo2[] needed, jp = jk. + * + * q[] double array with integral value, representing the + * 24-bits chunk of the product of x and 2/pi. + * + * q0 the corresponding exponent of q[0]. Note that the + * exponent for q[i] would be q0-24*i. + * + * PIo2[] double precision array, obtained by cutting pi/2 + * into 24 bits chunks. + * + * f[] ipio2[] in floating point + * + * iq[] integer array by breaking up q[] in 24-bits chunk. + * + * fq[] final product of x*(2/pi) in fq[0],..,fq[jk] + * + * ih integer. If >0 it indicates q[] is >= 0.5, hence + * it also indicates the *sign* of the result. + * + */ + + +/* + * Constants: + * The hexadecimal values are the intended ones for the following + * constants. The decimal values may be used, provided that the + * compiler will convert from decimal to binary accurately enough + * to produce the hexadecimal values shown. + */ + +#include +#include + +#include "math_private.h" + +static const int init_jk[] = {3,4,4,6}; /* initial value for jk */ + +/* + * Table of constants for 2/pi, 396 Hex digits (476 decimal) of 2/pi + * + * integer array, contains the (24*i)-th to (24*i+23)-th + * bit of 2/pi after binary point. The corresponding + * floating value is + * + * ipio2[i] * 2^(-24(i+1)). + * + * NB: This table must have at least (e0-3)/24 + jk terms. + * For quad precision (e0 <= 16360, jk = 6), this is 686. + */ +static const int32_t ipio2[] = { +0xA2F983, 0x6E4E44, 0x1529FC, 0x2757D1, 0xF534DD, 0xC0DB62, +0x95993C, 0x439041, 0xFE5163, 0xABDEBB, 0xC561B7, 0x246E3A, +0x424DD2, 0xE00649, 0x2EEA09, 0xD1921C, 0xFE1DEB, 0x1CB129, +0xA73EE8, 0x8235F5, 0x2EBB44, 0x84E99C, 0x7026B4, 0x5F7E41, +0x3991D6, 0x398353, 0x39F49C, 0x845F8B, 0xBDF928, 0x3B1FF8, +0x97FFDE, 0x05980F, 0xEF2F11, 0x8B5A0A, 0x6D1F6D, 0x367ECF, +0x27CB09, 0xB74F46, 0x3F669E, 0x5FEA2D, 0x7527BA, 0xC7EBE5, +0xF17B3D, 0x0739F7, 0x8A5292, 0xEA6BFB, 0x5FB11F, 0x8D5D08, +0x560330, 0x46FC7B, 0x6BABF0, 0xCFBC20, 0x9AF436, 0x1DA9E3, +0x91615E, 0xE61B08, 0x659985, 0x5F14A0, 0x68408D, 0xFFD880, +0x4D7327, 0x310606, 0x1556CA, 0x73A8C9, 0x60E27B, 0xC08C6B, + +#if LDBL_MAX_EXP > 1024 +#if LDBL_MAX_EXP > 16384 +#error "ipio2 table needs to be expanded" +#endif +0x47C419, 0xC367CD, 0xDCE809, 0x2A8359, 0xC4768B, 0x961CA6, +0xDDAF44, 0xD15719, 0x053EA5, 0xFF0705, 0x3F7E33, 0xE832C2, +0xDE4F98, 0x327DBB, 0xC33D26, 0xEF6B1E, 0x5EF89F, 0x3A1F35, +0xCAF27F, 0x1D87F1, 0x21907C, 0x7C246A, 0xFA6ED5, 0x772D30, +0x433B15, 0xC614B5, 0x9D19C3, 0xC2C4AD, 0x414D2C, 0x5D000C, +0x467D86, 0x2D71E3, 0x9AC69B, 0x006233, 0x7CD2B4, 0x97A7B4, +0xD55537, 0xF63ED7, 0x1810A3, 0xFC764D, 0x2A9D64, 0xABD770, +0xF87C63, 0x57B07A, 0xE71517, 0x5649C0, 0xD9D63B, 0x3884A7, +0xCB2324, 0x778AD6, 0x23545A, 0xB91F00, 0x1B0AF1, 0xDFCE19, +0xFF319F, 0x6A1E66, 0x615799, 0x47FBAC, 0xD87F7E, 0xB76522, +0x89E832, 0x60BFE6, 0xCDC4EF, 0x09366C, 0xD43F5D, 0xD7DE16, +0xDE3B58, 0x929BDE, 0x2822D2, 0xE88628, 0x4D58E2, 0x32CAC6, +0x16E308, 0xCB7DE0, 0x50C017, 0xA71DF3, 0x5BE018, 0x34132E, +0x621283, 0x014883, 0x5B8EF5, 0x7FB0AD, 0xF2E91E, 0x434A48, +0xD36710, 0xD8DDAA, 0x425FAE, 0xCE616A, 0xA4280A, 0xB499D3, +0xF2A606, 0x7F775C, 0x83C2A3, 0x883C61, 0x78738A, 0x5A8CAF, +0xBDD76F, 0x63A62D, 0xCBBFF4, 0xEF818D, 0x67C126, 0x45CA55, +0x36D9CA, 0xD2A828, 0x8D61C2, 0x77C912, 0x142604, 0x9B4612, +0xC459C4, 0x44C5C8, 0x91B24D, 0xF31700, 0xAD43D4, 0xE54929, +0x10D5FD, 0xFCBE00, 0xCC941E, 0xEECE70, 0xF53E13, 0x80F1EC, +0xC3E7B3, 0x28F8C7, 0x940593, 0x3E71C1, 0xB3092E, 0xF3450B, +0x9C1288, 0x7B20AB, 0x9FB52E, 0xC29247, 0x2F327B, 0x6D550C, +0x90A772, 0x1FE76B, 0x96CB31, 0x4A1679, 0xE27941, 0x89DFF4, +0x9794E8, 0x84E6E2, 0x973199, 0x6BED88, 0x365F5F, 0x0EFDBB, +0xB49A48, 0x6CA467, 0x427271, 0x325D8D, 0xB8159F, 0x09E5BC, +0x25318D, 0x3974F7, 0x1C0530, 0x010C0D, 0x68084B, 0x58EE2C, +0x90AA47, 0x02E774, 0x24D6BD, 0xA67DF7, 0x72486E, 0xEF169F, +0xA6948E, 0xF691B4, 0x5153D1, 0xF20ACF, 0x339820, 0x7E4BF5, +0x6863B2, 0x5F3EDD, 0x035D40, 0x7F8985, 0x295255, 0xC06437, +0x10D86D, 0x324832, 0x754C5B, 0xD4714E, 0x6E5445, 0xC1090B, +0x69F52A, 0xD56614, 0x9D0727, 0x50045D, 0xDB3BB4, 0xC576EA, +0x17F987, 0x7D6B49, 0xBA271D, 0x296996, 0xACCCC6, 0x5414AD, +0x6AE290, 0x89D988, 0x50722C, 0xBEA404, 0x940777, 0x7030F3, +0x27FC00, 0xA871EA, 0x49C266, 0x3DE064, 0x83DD97, 0x973FA3, +0xFD9443, 0x8C860D, 0xDE4131, 0x9D3992, 0x8C70DD, 0xE7B717, +0x3BDF08, 0x2B3715, 0xA0805C, 0x93805A, 0x921110, 0xD8E80F, +0xAF806C, 0x4BFFDB, 0x0F9038, 0x761859, 0x15A562, 0xBBCB61, +0xB989C7, 0xBD4010, 0x04F2D2, 0x277549, 0xF6B6EB, 0xBB22DB, +0xAA140A, 0x2F2689, 0x768364, 0x333B09, 0x1A940E, 0xAA3A51, +0xC2A31D, 0xAEEDAF, 0x12265C, 0x4DC26D, 0x9C7A2D, 0x9756C0, +0x833F03, 0xF6F009, 0x8C402B, 0x99316D, 0x07B439, 0x15200C, +0x5BC3D8, 0xC492F5, 0x4BADC6, 0xA5CA4E, 0xCD37A7, 0x36A9E6, +0x9492AB, 0x6842DD, 0xDE6319, 0xEF8C76, 0x528B68, 0x37DBFC, +0xABA1AE, 0x3115DF, 0xA1AE00, 0xDAFB0C, 0x664D64, 0xB705ED, +0x306529, 0xBF5657, 0x3AFF47, 0xB9F96A, 0xF3BE75, 0xDF9328, +0x3080AB, 0xF68C66, 0x15CB04, 0x0622FA, 0x1DE4D9, 0xA4B33D, +0x8F1B57, 0x09CD36, 0xE9424E, 0xA4BE13, 0xB52333, 0x1AAAF0, +0xA8654F, 0xA5C1D2, 0x0F3F0B, 0xCD785B, 0x76F923, 0x048B7B, +0x721789, 0x53A6C6, 0xE26E6F, 0x00EBEF, 0x584A9B, 0xB7DAC4, +0xBA66AA, 0xCFCF76, 0x1D02D1, 0x2DF1B1, 0xC1998C, 0x77ADC3, +0xDA4886, 0xA05DF7, 0xF480C6, 0x2FF0AC, 0x9AECDD, 0xBC5C3F, +0x6DDED0, 0x1FC790, 0xB6DB2A, 0x3A25A3, 0x9AAF00, 0x9353AD, +0x0457B6, 0xB42D29, 0x7E804B, 0xA707DA, 0x0EAA76, 0xA1597B, +0x2A1216, 0x2DB7DC, 0xFDE5FA, 0xFEDB89, 0xFDBE89, 0x6C76E4, +0xFCA906, 0x70803E, 0x156E85, 0xFF87FD, 0x073E28, 0x336761, +0x86182A, 0xEABD4D, 0xAFE7B3, 0x6E6D8F, 0x396795, 0x5BBF31, +0x48D784, 0x16DF30, 0x432DC7, 0x356125, 0xCE70C9, 0xB8CB30, +0xFD6CBF, 0xA200A4, 0xE46C05, 0xA0DD5A, 0x476F21, 0xD21262, +0x845CB9, 0x496170, 0xE0566B, 0x015299, 0x375550, 0xB7D51E, +0xC4F133, 0x5F6E13, 0xE4305D, 0xA92E85, 0xC3B21D, 0x3632A1, +0xA4B708, 0xD4B1EA, 0x21F716, 0xE4698F, 0x77FF27, 0x80030C, +0x2D408D, 0xA0CD4F, 0x99A520, 0xD3A2B3, 0x0A5D2F, 0x42F9B4, +0xCBDA11, 0xD0BE7D, 0xC1DB9B, 0xBD17AB, 0x81A2CA, 0x5C6A08, +0x17552E, 0x550027, 0xF0147F, 0x8607E1, 0x640B14, 0x8D4196, +0xDEBE87, 0x2AFDDA, 0xB6256B, 0x34897B, 0xFEF305, 0x9EBFB9, +0x4F6A68, 0xA82A4A, 0x5AC44F, 0xBCF82D, 0x985AD7, 0x95C7F4, +0x8D4D0D, 0xA63A20, 0x5F57A4, 0xB13F14, 0x953880, 0x0120CC, +0x86DD71, 0xB6DEC9, 0xF560BF, 0x11654D, 0x6B0701, 0xACB08C, +0xD0C0B2, 0x485551, 0x0EFB1E, 0xC37295, 0x3B06A3, 0x3540C0, +0x7BDC06, 0xCC45E0, 0xFA294E, 0xC8CAD6, 0x41F3E8, 0xDE647C, +0xD8649B, 0x31BED9, 0xC397A4, 0xD45877, 0xC5E369, 0x13DAF0, +0x3C3ABA, 0x461846, 0x5F7555, 0xF5BDD2, 0xC6926E, 0x5D2EAC, +0xED440E, 0x423E1C, 0x87C461, 0xE9FD29, 0xF3D6E7, 0xCA7C22, +0x35916F, 0xC5E008, 0x8DD7FF, 0xE26A6E, 0xC6FDB0, 0xC10893, +0x745D7C, 0xB2AD6B, 0x9D6ECD, 0x7B723E, 0x6A11C6, 0xA9CFF7, +0xDF7329, 0xBAC9B5, 0x5100B7, 0x0DB2E2, 0x24BA74, 0x607DE5, +0x8AD874, 0x2C150D, 0x0C1881, 0x94667E, 0x162901, 0x767A9F, +0xBEFDFD, 0xEF4556, 0x367ED9, 0x13D9EC, 0xB9BA8B, 0xFC97C4, +0x27A831, 0xC36EF1, 0x36C594, 0x56A8D8, 0xB5A8B4, 0x0ECCCF, +0x2D8912, 0x34576F, 0x89562C, 0xE3CE99, 0xB920D6, 0xAA5E6B, +0x9C2A3E, 0xCC5F11, 0x4A0BFD, 0xFBF4E1, 0x6D3B8E, 0x2C86E2, +0x84D4E9, 0xA9B4FC, 0xD1EEEF, 0xC9352E, 0x61392F, 0x442138, +0xC8D91B, 0x0AFC81, 0x6A4AFB, 0xD81C2F, 0x84B453, 0x8C994E, +0xCC2254, 0xDC552A, 0xD6C6C0, 0x96190B, 0xB8701A, 0x649569, +0x605A26, 0xEE523F, 0x0F117F, 0x11B5F4, 0xF5CBFC, 0x2DBC34, +0xEEBC34, 0xCC5DE8, 0x605EDD, 0x9B8E67, 0xEF3392, 0xB817C9, +0x9B5861, 0xBC57E1, 0xC68351, 0x103ED8, 0x4871DD, 0xDD1C2D, +0xA118AF, 0x462C21, 0xD7F359, 0x987AD9, 0xC0549E, 0xFA864F, +0xFC0656, 0xAE79E5, 0x362289, 0x22AD38, 0xDC9367, 0xAAE855, +0x382682, 0x9BE7CA, 0xA40D51, 0xB13399, 0x0ED7A9, 0x480569, +0xF0B265, 0xA7887F, 0x974C88, 0x36D1F9, 0xB39221, 0x4A827B, +0x21CF98, 0xDC9F40, 0x5547DC, 0x3A74E1, 0x42EB67, 0xDF9DFE, +0x5FD45E, 0xA4677B, 0x7AACBA, 0xA2F655, 0x23882B, 0x55BA41, +0x086E59, 0x862A21, 0x834739, 0xE6E389, 0xD49EE5, 0x40FB49, +0xE956FF, 0xCA0F1C, 0x8A59C5, 0x2BFA94, 0xC5C1D3, 0xCFC50F, +0xAE5ADB, 0x86C547, 0x624385, 0x3B8621, 0x94792C, 0x876110, +0x7B4C2A, 0x1A2C80, 0x12BF43, 0x902688, 0x893C78, 0xE4C4A8, +0x7BDBE5, 0xC23AC4, 0xEAF426, 0x8A67F7, 0xBF920D, 0x2BA365, +0xB1933D, 0x0B7CBD, 0xDC51A4, 0x63DD27, 0xDDE169, 0x19949A, +0x9529A8, 0x28CE68, 0xB4ED09, 0x209F44, 0xCA984E, 0x638270, +0x237C7E, 0x32B90F, 0x8EF5A7, 0xE75614, 0x08F121, 0x2A9DB5, +0x4D7E6F, 0x5119A5, 0xABF9B5, 0xD6DF82, 0x61DD96, 0x023616, +0x9F3AC4, 0xA1A283, 0x6DED72, 0x7A8D39, 0xA9B882, 0x5C326B, +0x5B2746, 0xED3400, 0x7700D2, 0x55F4FC, 0x4D5901, 0x8071E0, +#endif + +}; + +static const double PIo2[] = { + 1.57079625129699707031e+00, /* 0x3FF921FB, 0x40000000 */ + 7.54978941586159635335e-08, /* 0x3E74442D, 0x00000000 */ + 5.39030252995776476554e-15, /* 0x3CF84698, 0x80000000 */ + 3.28200341580791294123e-22, /* 0x3B78CC51, 0x60000000 */ + 1.27065575308067607349e-29, /* 0x39F01B83, 0x80000000 */ + 1.22933308981111328932e-36, /* 0x387A2520, 0x40000000 */ + 2.73370053816464559624e-44, /* 0x36E38222, 0x80000000 */ + 2.16741683877804819444e-51, /* 0x3569F31D, 0x00000000 */ +}; + +static const double +zero = 0.0, +one = 1.0, +two24 = 1.67772160000000000000e+07, /* 0x41700000, 0x00000000 */ +twon24 = 5.96046447753906250000e-08; /* 0x3E700000, 0x00000000 */ + +OLM_DLLEXPORT int +__kernel_rem_pio2(double *x, double *y, int e0, int nx, int prec) +{ + int32_t jz,jx,jv,jp,jk,carry,n,iq[20],i,j,k,m,q0,ih; + double z,fw,f[20],fq[20],q[20]; + + /* initialize jk*/ + jk = init_jk[prec]; + jp = jk; + + /* determine jx,jv,q0, note that 3>q0 */ + jx = nx-1; + jv = (e0-3)/24; if(jv<0) jv=0; + q0 = e0-24*(jv+1); + + /* set up f[0] to f[jx+jk] where f[jx+jk] = ipio2[jv+jk] */ + j = jv-jx; m = jx+jk; + for(i=0;i<=m;i++,j++) f[i] = (j<0)? zero : (double) ipio2[j]; + + /* compute q[0],q[1],...q[jk] */ + for (i=0;i<=jk;i++) { + for(j=0,fw=0.0;j<=jx;j++) fw += x[j]*f[jx+i-j]; + q[i] = fw; + } + + jz = jk; +recompute: + /* distill q[] into iq[] reversingly */ + for(i=0,j=jz,z=q[jz];j>0;i++,j--) { + fw = (double)((int32_t)(twon24* z)); + iq[i] = (int32_t)(z-two24*fw); + z = q[j-1]+fw; + } + + /* compute n */ + z = scalbn(z,q0); /* actual value of z */ + z -= 8.0*floor(z*0.125); /* trim off integer >= 8 */ + n = (int32_t) z; + z -= (double)n; + ih = 0; + if(q0>0) { /* need iq[jz-1] to determine n */ + i = (iq[jz-1]>>(24-q0)); n += i; + iq[jz-1] -= i<<(24-q0); + ih = iq[jz-1]>>(23-q0); + } + else if(q0==0) ih = iq[jz-1]>>23; + else if(z>=0.5) ih=2; + + if(ih>0) { /* q > 0.5 */ + n += 1; carry = 0; + for(i=0;i0) { /* rare case: chance is 1 in 12 */ + switch(q0) { + case 1: + iq[jz-1] &= 0x7fffff; break; + case 2: + iq[jz-1] &= 0x3fffff; break; + } + } + if(ih==2) { + z = one - z; + if(carry!=0) z -= scalbn(one,q0); + } + } + + /* check if recomputation is needed */ + if(z==zero) { + j = 0; + for (i=jz-1;i>=jk;i--) j |= iq[i]; + if(j==0) { /* need recomputation */ + for(k=1;iq[jk-k]==0;k++); /* k = no. of terms needed */ + + for(i=jz+1;i<=jz+k;i++) { /* add q[jz+1] to q[jz+k] */ + f[jx+i] = (double) ipio2[jv+i]; + for(j=0,fw=0.0;j<=jx;j++) fw += x[j]*f[jx+i-j]; + q[i] = fw; + } + jz += k; + goto recompute; + } + } + + /* chop off zero terms */ + if(z==0.0) { + jz -= 1; q0 -= 24; + while(iq[jz]==0) { jz--; q0-=24;} + } else { /* break z into 24-bit if necessary */ + z = scalbn(z,-q0); + if(z>=two24) { + fw = (double)((int32_t)(twon24*z)); + iq[jz] = (int32_t)(z-two24*fw); + jz += 1; q0 += 24; + iq[jz] = (int32_t) fw; + } else iq[jz] = (int32_t) z ; + } + + /* convert integer "bit" chunk to floating-point value */ + fw = scalbn(one,q0); + for(i=jz;i>=0;i--) { + q[i] = fw*(double)iq[i]; fw*=twon24; + } + + /* compute PIo2[0,...,jp]*q[jz,...,0] */ + for(i=jz;i>=0;i--) { + for(fw=0.0,k=0;k<=jp&&k<=jz-i;k++) fw += PIo2[k]*q[i+k]; + fq[jz-i] = fw; + } + + /* compress fq[] into y[] */ + switch(prec) { + case 0: + fw = 0.0; + for (i=jz;i>=0;i--) fw += fq[i]; + y[0] = (ih==0)? fw: -fw; + break; + case 1: + case 2: + fw = 0.0; + for (i=jz;i>=0;i--) fw += fq[i]; + STRICT_ASSIGN(double,fw,fw); + y[0] = (ih==0)? fw: -fw; + fw = fq[0]-fw; + for (i=1;i<=jz;i++) fw += fq[i]; + y[1] = (ih==0)? fw: -fw; + break; + case 3: /* painful */ + for (i=jz;i>0;i--) { + fw = fq[i-1]+fq[i]; + fq[i] += fq[i-1]-fw; + fq[i-1] = fw; + } + for (i=jz;i>1;i--) { + fw = fq[i-1]+fq[i]; + fq[i] += fq[i-1]-fw; + fq[i-1] = fw; + } + for (fw=0.0,i=jz;i>=2;i--) fw += fq[i]; + if(ih==0) { + y[0] = fq[0]; y[1] = fq[1]; y[2] = fw; + } else { + y[0] = -fq[0]; y[1] = -fq[1]; y[2] = -fw; + } + } + return n&7; +} diff --git a/src/openlibm/src/k_rem_pio2.c.o b/src/openlibm/src/k_rem_pio2.c.o new file mode 100644 index 0000000000000000000000000000000000000000..032d71b20b7500199733ca43a7875f280b8ab67a GIT binary patch literal 10816 zcmb<-^>JfjWMqH=Mg}_u1P><4z~G>U#0E1R7z7yj863ksdRaky&(2SdVUC^GJd-at zhPw1-{&x&<>^u`1?9ut#qw!4#69a=wx6Opk5ETc<=6`SadtR|KFgW&x{q;ybbnutF zN9KXmt5#`w9Q>iAd7;xqMW^`yW3Nan$Y9M22OltZhp6bdbpCf_Jm#YL%7yVge@B`i z14HX2{>~0Q28LcAaYn-ftta{YPgtJnJmJ7U=a}XN%Tqf+9^v;n!QY!A$iUG2gOR@_ zT9ARkvGYV4|N8@u7hmvewx}#%U|?`;{=ryM0pe|d@R&-nK)eGG9&M@4q6`P@5vBgVCek059C43 zgO-xewW^6W>CSy_;Mn|=xx@*qzyR5V1gL@n$L60bC5m7L zAWbk6IvYS1gPqbifq{X+rSoRiTmM&Bdvv>~ zDEKBHap`>N-YcW-(Yr0S=GmV;qi_ zr%NAr^p>aucqSkB=?qb^aOwQz(aX~2(P^UciC;h#thm!f#Q<#nCw>7@kcd~W&H;XT z7X}8O88*Er$Pe1OHH`6b6E{>amx_;o&}@xMR$iC^nn8o$QFPyCUOKJmvK`NXgD z;S;}rBgZHHh=ZL4e>^OIlpc2J{O;4~q9V~5q9X7Dw2;nz9&$&p{{AV`G2?+!Bq zLvPXlof4oBNdD%c`LWw&OF-xG%l{o2e_npRQ=EZ;LGy=;=10fQ!<{Z$0vs>@c5S`Q z-_Oa)zyONaG=9Ak{9W-}3=I6Okz5Q6yM+7Krx%!ecIx`OKg1 zaUqTWH7Ma8ly3gVQo{F{Ki}a%8vpBqpe!Yw#-D$}vGZ5wxitRbn;eeKkN$w9Tr{sW zKW7HXfrME=LTUVU2TD{ulK*kL>8ZQohez`ZmgZxOt^Z3t z_1YMLN>d(b z&(VVa|Np1)3v31ziZG>U7IT)Uft4mem4XUQtV%tTKe$>RDUosP^Mf$bnG_r>AcYTjlbmt0|Uc; z1_lO3&F_w#R^$6hfWJ@uHzaggFY))k_y=Nx z94`oQB#Pr-{`mzm-UZYUImif7zXPlu6cYX%AklwJr3X|&Apj~lUvEu=)eoKLU*7ut z|G(jZm-)Z{|99!MQE};fqeC}E}X3wVHXdNe$zqp4%#Z}wok?lP1ll)inJ*Yjw^V=i& z|0n*)oEq@7i2?fxA3>>|NH;nrQ1g3rS*46_BMR`dY4D?L7(mr6$?-! z#I^G-sIu|sJnGo|PNMZ>shC$UOIvpUq>g#Z2o}9m@($J}0B4#I6%Ln99u<$y5@@TT z^{q=cj|#|84p0MvzatM+{U-l~FpnHp6e8j5k1angghmY5mXNp~J+$fRr~?K?*_X`V+r^ zE{Oe!UjW=}h8G1c`~u*D>5~hrjpG7sufg+6>o@+6ZHx>IpB(uG7(Vew9{$81amcmx zKYz;-Mg|5@Au@-NfuYy&x5o@nQ44O?ed3Qi1BwF2=KqZREj5e`pq2)IOEFmCA5?{B zp$eJ!TY|v~nfP10zzYAODg;*vj?Mp>`CGKW3Yqy^6u}Drp(+H|MUKt?S@>HR!3tUU zTYfNr-1y%k`2xt1S3qsgPmcVNpo;pSWAlI365Hl~tR)s6$rn-NPe2{VRwCQ{kF7+a zH;~aI`4WnfQy?YaIQraq(4+Ynqi6FAj^-b%{H=%n{r}(XqT&E*fc5)<0_y;OzdaKJ zLusHV<86dpHDB=6$$REM%+5DQr)ADeM2#hBH zVmO1uO5cELsn$K92zTTcWb$Y{0`8G^o``OKz#i)u;~480=NNw&l$v@S|G$ie6}XUk zp`PL8qP~zwC>10s>R~0_pEGnQx&H+n}Al(AsDgxBFO5@i*%-{4L zl&av#?fuE#EJnxXV-lbEBQJd7*E#fwU+V;<0UvWPjbG$Y8vnBcX-@ptTv`HN*8chb zzqv-mftkOR>Hq)#t#A2TYM2-pJbPKBJ$mRs~-a)DBqlfX-nfB*l3QVztY zJz$@H;umNEYw*zg>Ct%%)Y1+q6jne#(vH34kjb`h~5=inB*ul)ez|j1cxkePEjO8$hbUDo7 z(R_f(@@VaA*VeZsJfHdNz)kBk{_sN}gPk~DM*ao0L39puUUljO#o^9hpdvUN-1c~B z{`dcXgdUBXAP1%Khu;F}m1=#<-F^KaM`(0_0z%xQ z8|+G$-#j~+UV>USp2tC9%kc8SzyJS1*$;u6e=cHh@ylcQqbbU8F*5)%O|)bPZnk8Y^Tm>(JHCZMoh4D-_L8FXL8Gwf0?WqA7fID>8VM~3f~ z>TCvuJ?9zBzRY5Hyi%4SE^#6Qhx9Xs z)|sgc3q;}>dL1$t8gBe&P%rjnU}H06I29(!aB@X4L-nHshU}gL43bCO8P293X5f5r zhas|Ai=n&h2*Wa&X$&sw?=nb+Uu0Nn$I8IU{-43P&Yt0r(F=wd{`VMm*BUXX*&b$) z%YM%=|3@5ysk{|K{ijn5AKPUaY9=T$WU16JT+RE%V4z#hAZqQ*uvO$3!(qv}3~P@Z zV$kt*WZ+?lWoWB)V|ZMs%P{-cEC%Bw28Jz{Y8bXGpUz+&dX?e2-8Y8C0ul_qWq%k_ z=4vq%Twl$QT=RpWYC|}Kxaf0+1D;_F*4J(_EN`)3P*Fb3aILGHAu2?ffkA#J!$&S@ z2FY{x8Ri@QXGoLFVwf48$gt+OJ40Rl4F;vu?F>dQIvJkrPhfa|~r)l9C34M%xR9M-jdZ$4(hBa6A@ccu;$qLHs}f!)Mv$3=$8b8T5or z7@CEW7@9p88NT*KGpyZE&mi~m6N87BGlM|-WrkIEZ!oNjcVfs&JjcMLv4r9B%qOBQ z3>qsgF&s+lWe_@9&cLE3!XV@}o8d_05rz{-T^M{fO=MsY|IBd3c`bvc=TnBiR|Oat z_Wfayn{tMs;M_X~VY{ykZ$36KY<_;2;rI^?hRLi`7!DTNG3aq_X5e=H%+Mh;hheos zHG|&P`3&xp4lz_4=`-+z<}ws5pTLm)T%N)3^fZP_F)s$k%0~=e?sqc0m@=K=(X$qY znTFFDI^Je8#K)U4?EcHg;4y0pL;8{&hQcBzhTd2shWVm981_8nWau?iW%yoV$zZ@L z!@$eK$l%S9!JzXlg28>&1cs95ObmOksW5!6UB-~-QN%D`>^(!@lw}NCCVpeM7#zrO zp6e5X!VF`EuikYGo02ma?%KsOIK(nDw071rga&Ccn5P_I$h{%JVB}%M5baaS;8%Es z!8Ih0ft&LngVxtf29dO@4C?H28Dd!i7`9m7W_VS0l%f5nID=<)ErYE3E{18DnheLz ztYKIy62dUyQ5HkT%}xfLq5uY#CHol4*{3jkHYi|V_@mD7s&EBE+96Mdln1s9)9*Gj zEViG{;5_9o18-XogQ4R+hDnxl8SWPJFoWWUQc;G))4LgtckW~maM;Um=@ScsXQ?{F>uui{ZY%9( z;1XHI(5a@+kkVYnz-evFz&AyTA<$|SgY4o%4C~*nV~9}`V#qz@%b;5|hv7ijbOvVo zW(Lj=-x#zVdKhvIXEIoBVQ1h`5M{V=IGW+>q$3Q+)_ODeom$GU-25!Vvz2BHt0zri zxa*X`AenrRp{(aULq>NH!=Kyc4C@xIX1FhE$iT2}Ap_6vTMQ|_X$)^!w=-y_8Zd;1 z?PqZRZ^e-Hb0-omOa$1z(ml7Mp%_p)9wwsqQgiH4`n4RTh z@N;^}AiQr0gR$~fh7YTx82nRLFkCvgl!4oxpCP*9EQ9jTGKT7I7KTpoB8Fqjf*JDj z9x=Rs&A>3*D}v$3t?dk}(snVFoj=cTkx7TY51Zm46p z#lD=OY!x3vb>u<@F(EC6JKJ>`em(um(0ThGL+8G~3{T2(7}!?+VX$i`U}((~W%%3v zpFzWpogp#Zm_bXTjlp;CD~8R_*E96z<}pl7w`4HfAI;Em-Gjm4z8J%CU1tW>L{o;7 z1?LzHPVZpYpYxYt3Bw`=)|@8{QFj+GDCWB}Bne$&*csEpP>|@!kRA4bVP+5`LqMoG zgWT2a48|XiFbLQmmY+@xg11gH)b6{$F#GmFhSlPG8BQ%~WZ=k( zVbBW|XHaJdWvCbV!0?d0jX{Jvg<+awFGKsjdknY!YB6N1ZeytKG+|)<{EuPh{&@@; zS^f-OS}Pd*k3=!({@BBCJ!%HSm*Z0zczt^r6s(ppED4Wi5V7CL&|oo@;fw+!L*d;v zhLiWUG3-zH%HW$S$iT>+&Cs)94a24b7Z?IVJs9ME^D#^$ zu4fqhG=DK%J9UEL#b-x`nv{DCvr}#`+}vl#uw?pShVqCj44IFQGJLot%&^PKhQUq3 zjUlu&p5fBouMByUjxns!i)G+*dCMSU=fseBq@6+Y?@NZ~*FG~S)tq9;pJ>X!@!%-K z|LeUBd0CGbHvB!tFqz{ZLrrW6L-yKD3}^G^GT0SWGaM7lV)%Z3C4*-1eTJ%qB;zX5N4bqn=t5vbu!F6 z_n6_D!cKJzm4AM7GFf{(*V)*Tq#h@>9gCTfJ3xnUx9)=L5GYndxcNh*FyT-sRIgLT8 zUJ|MNbj4?Fv<8m z!%6WS42co586Jl3VF+wK#&E+kHG^SZ$N>ib zwqFckY=0P@R<2{{R5D|*SgXX4KKTwq=!;bhO==blr=HJd2;^PDFw=M=!^-P?44JGR z45^zwFw}P}XXx;m&hYc18H3`a%?#B|UJNtND>69Dzr%3HJ(S^Li4{ZoYbS<(bMG_6 zU5RI?PG7>XYfTkH=(j}-+8xRaj=Mq`BJ(&H6t&tIEZv(KIv+n{cslP2gXeDthW}wN z8D#iRF&vHTVwmzvo8j`oqYV5<&okVPTF2miw2h(FIf+5B&6+`{ateb$VmpJDPc=h> zjueCQej$bqwFwLrHk}MBjyz#_db^t8h}9tmwJ)z2zNdFF@J`y#kh)l#!FKXShP^f1 z3`+v6X2^VamtocvNrn}gQyDVOX)tiU-NN89UxC4I#wmt^reub?8f6Clokk4H zzxFYRggs|a{K&zub*>geew{DFQprGutv^>YG~K_(Fzs$4gP0i;!x5|b49$xcG8Dbd zWw7k6Vrbg2k|EnDhQUoent{ROEyE>-a)v)&LKzq%eHk7Uf(CgYZCX%gfrWvA0ffO5 zNnqguJ21si;0U1)*h6Rq2MGND%KreO9eykR1knt-E+rs+4Kv(+*f20KBm|zRux4Oj zXlR!HV9CJ1;Gm#dWdY(VH9a;1nIro-6FlAl5(DwU*xlLLN(&_vHj&rre0 zz{u3V(9l3ZBPcaR!6UH*Dxqtx330aq0|Nu78Sm~F%D}|HcmU)V&`c%BJVq#=6U1R) zU=V@Qj8#Dlj1>Zm(md=O6F_6U3=9l1P`M%@1_lNvK7oEFA3ljbW)D7vUKTe#jUHAP zK7%$kM?Q;Yb}zmItjv@6xcDqw_zYb5G@SSpocJW1_ynBzI2^g5=3t{h?qXs1h}Nrs zsALAs<3gBlk`FY_%)rWUfeRue0HGMfpyE(2!wIN7h|dfT4G;@~A%0^=2tZj%U>Z|g z11ye65nwI@0|R)Vih+%R1112ajleV;1I&G3E&~IDIheu50GdPtGob`1fiN(zF@WL@ zDg>q=366~cVn0|2Ot^tbHUHiir^jUb8{7#M_*;uoC8KywTX z3>aYs($#}QoFO~DC^a{}AT!@cFPR}TFS8^*E1Mw`#And+aW*sulcr!2L>PexV-R5i zBES-6AQo7m1&Cz{A`A_{q#>9DYcd4uGBja`kIzmm%1h0GTg*_LoS2i8$B>qjpI-!W zEHwXtn4o?$C@-FYrpJ|_1kb?002BZ79|9af1rJmll$K!P!ARnq3=9k~aV}7%hL%&H ziC37o7*rf&KFCU#xGGc}M1j&COk5Wv0JRsCPhsMANaD!uaYGVEcF%i|C!ywmm@so9 zK$@ZAJV@@pizE&j(}k)3ibGrsWEmF!YCy$7{sn1;nPY$?4r0Q@XMs3S_aNJ=1#%n~ zaR;b4$lJ)_oB$O^xAzE=IH;_G*?R^_oF6G1ZXk(+$_kkJ2T08hpK~Qm!e?dVAQ(uH6jvW48AV)*Z2bHEU z^@TXZ>u`uKK@ta*zA$svAc-TJ&j1P(sJ+PPFbGK;*_5(d4z{E}2XcfU~G;*!MVY$!iHuT-y~D8C@JsHBoX4{S+lMtoXPVs0wf zMHCSre}al6P?#Va1gj@tYn_zgvfiUZK{3zXbI_JGm|NCs2}foRaO zHjp?}8Au3>H$meC%t0bRYLU1MpjmB@ndIs>1h*R?iYE7mx#~!mJBHWdukDMu$M%kKPVYfa=!= zDMrE|yFgqR9ShYD5<|xRQ2oeaAT~@Nhz-J^`W=*SQ1S=^1495*Kf1eM{s!p_D4V+1}e)z rZA^6ipt2A>?Sb?=K-2#u5C;i^>_g%*fQm6}`Zqw`-;b;qOI!f}v_uuX literal 0 HcmV?d00001 diff --git a/src/openlibm/src/k_sin.c b/src/openlibm/src/k_sin.c new file mode 100644 index 0000000..0b3de39 --- /dev/null +++ b/src/openlibm/src/k_sin.c @@ -0,0 +1,71 @@ + +/* @(#)k_sin.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/k_sin.c,v 1.11 2008/02/19 12:54:14 bde Exp $"); + +/* __kernel_sin( x, y, iy) + * kernel sin function on ~[-pi/4, pi/4] (except on -0), pi/4 ~ 0.7854 + * Input x is assumed to be bounded by ~pi/4 in magnitude. + * Input y is the tail of x. + * Input iy indicates whether y is 0. (if iy=0, y assume to be 0). + * + * Algorithm + * 1. Since sin(-x) = -sin(x), we need only to consider positive x. + * 2. Callers must return sin(-0) = -0 without calling here since our + * odd polynomial is not evaluated in a way that preserves -0. + * Callers may do the optimization sin(x) ~ x for tiny x. + * 3. sin(x) is approximated by a polynomial of degree 13 on + * [0,pi/4] + * 3 13 + * sin(x) ~ x + S1*x + ... + S6*x + * where + * + * |sin(x) 2 4 6 8 10 12 | -58 + * |----- - (1+S1*x +S2*x +S3*x +S4*x +S5*x +S6*x )| <= 2 + * | x | + * + * 4. sin(x+y) = sin(x) + sin'(x')*y + * ~ sin(x) + (1-x*x/2)*y + * For better accuracy, let + * 3 2 2 2 2 + * r = x *(S2+x *(S3+x *(S4+x *(S5+x *S6)))) + * then 3 2 + * sin(x) = x + (S1*x + (x *(r-y/2)+y)) + */ + +#include + +#include "math_private.h" + +static const double +half = 5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */ +S1 = -1.66666666666666324348e-01, /* 0xBFC55555, 0x55555549 */ +S2 = 8.33333333332248946124e-03, /* 0x3F811111, 0x1110F8A6 */ +S3 = -1.98412698298579493134e-04, /* 0xBF2A01A0, 0x19C161D5 */ +S4 = 2.75573137070700676789e-06, /* 0x3EC71DE3, 0x57B1FE7D */ +S5 = -2.50507602534068634195e-08, /* 0xBE5AE5E6, 0x8A2B9CEB */ +S6 = 1.58969099521155010221e-10; /* 0x3DE5D93A, 0x5ACFD57C */ + +OLM_DLLEXPORT double +__kernel_sin(double x, double y, int iy) +{ + double z,r,v,w; + + z = x*x; + w = z*z; + r = S2+z*(S3+z*S4) + z*w*(S5+z*S6); + v = z*x; + if(iy==0) return x+v*(S1+z*r); + else return x-((z*(half*y-v*r)-y)-v*S1); +} diff --git a/src/openlibm/src/k_sin.c.o b/src/openlibm/src/k_sin.c.o new file mode 100644 index 0000000000000000000000000000000000000000..29cc1bee56efefa55513e6d8e7dee1b843839e81 GIT binary patch literal 2008 zcmb<-^>JfjWMqH=Mg}_u1P><4z!1TLU^{@B4h(z@ybNjl8aF=i3#fvG()cxAeBzJ1 z@rgh3aT>qI};i=;qDizsbFZLXQXGSU}RuqYG7z+pr8?ynxf#5SOS&MHP>Wd00ox<0|Nsq z0|SG*Unm0;1LFaZ7%XfVp?pq=1q>oknz1T~fw4k>QJROHV*(=sSX>4ww-!p{qd?}f zFns)vO${@an1$F6awVz`J}{S+fdfn<2w^ajl|cYZBM1pFla&ENgE?SA7EH1-fWiXI zgc3?%nw3EVOd|+&Fq4(R08AqY9R>ylAtd+1!y-GrI5ST#nL*FT*#JZsf(RoJVGJTn zK!hoXFk^_1&rU7MOU(i4fSC;Q9}@!u12Y2y!=L{UpaN9@5(mW_OxyxV929CWaTg?U zHY9Tbki^-M#8Z&OL2iJVQ-dT9iW``C2a-6ldRVxE+zG-^Wef~@#g(}wiAfB4#U(`$ zIs?WkO3g{sD@m;=VbDuSEJ-sc`!#WPtnyO3R?IL^cXi_AoHO z;~y%Co*tzcAbAj`9;yry$qWn(2cQDn3=H5@1qxG;5G?(wLB&C70wfN@Z($5H8st`F zAy9e+nMtmGL#X{i$c8d7FnoaWVd)Uch38X{oggtgsDAW(qycrPK1dM~h6;nj0wnAX z)emAL<8YWlWI-%y!xT5UD>4NBkdvMhGmP zLGcgDXE6I=;vj3#?FPAR2S|c}fq?@`^Dr + +#include "math_private.h" + +/* |sin(x)/x - s(x)| < 2**-37.5 (~[-4.89e-12, 4.824e-12]). */ +static const double +S1 = -0x15555554cbac77.0p-55, /* -0.166666666416265235595 */ +S2 = 0x111110896efbb2.0p-59, /* 0.0083333293858894631756 */ +S3 = -0x1a00f9e2cae774.0p-65, /* -0.000198393348360966317347 */ +S4 = 0x16cd878c3b46a7.0p-71; /* 0.0000027183114939898219064 */ + +#ifndef INLINE_KERNEL_SINDF +extern +#endif +//__inline float +OLM_DLLEXPORT float +__kernel_sindf(double x) +{ + double r, s, w, z; + + /* Try to optimize for parallel evaluation as in k_tanf.c. */ + z = x*x; + w = z*z; + r = S3+z*S4; + s = z*x; + return (x + s*(S1+z*S2)) + s*w*r; +} diff --git a/src/openlibm/src/k_sinf.c.o b/src/openlibm/src/k_sinf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..ba4f74982f156e58c5b95a5406ca36b4bd2d8db9 GIT binary patch literal 1720 zcmb<-^>JfjWMqH=Mg}_u1P><4z+l0QU^{@B4h(z@ybNjl8Yj~DH6DE87mx)Bf8vik z@rgh3VH&^2#ZUZ^Abj%^e>liYp%(_z{0@5puoVuz{0dfz>R~!f-FiR3lvNA}3X#^q1z`!7cWG~zg+404hd1-pd z40=A!1|Y%+L>PhyV}|(n?9`&X)EtnSlr)fOJRpLBfq{vEfdQ06{``jk4J2_;_`<{u zkid2@H78N8B(;f@hv>jAGEIonbK==TNU|?X-hte<#=6)FM4%H8nhtcn03^W?1 z4<;PWz`(!`P4_S{5d8r}FfcHny9?%Ss5C=9)P87m!GswUpcWC*pM@j-7eEb!#WN`W zL1h`tewaAO8mLmZ-5^E)NP>ZZ0Tzy+{0;Iax_*$E=y4CyF90=E7sNrrP-EdDg3$5; RE&yfhfae literal 0 HcmV?d00001 diff --git a/src/openlibm/src/k_tan.c b/src/openlibm/src/k_tan.c new file mode 100644 index 0000000..41f754b --- /dev/null +++ b/src/openlibm/src/k_tan.c @@ -0,0 +1,134 @@ +/* @(#)k_tan.c 1.5 04/04/22 SMI */ + +/* + * ==================================================== + * Copyright 2004 Sun Microsystems, Inc. All Rights Reserved. + * + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* INDENT OFF */ +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/k_tan.c,v 1.13 2008/02/22 02:30:35 das Exp $"); + +/* __kernel_tan( x, y, k ) + * kernel tan function on ~[-pi/4, pi/4] (except on -0), pi/4 ~ 0.7854 + * Input x is assumed to be bounded by ~pi/4 in magnitude. + * Input y is the tail of x. + * Input k indicates whether tan (if k = 1) or -1/tan (if k = -1) is returned. + * + * Algorithm + * 1. Since tan(-x) = -tan(x), we need only to consider positive x. + * 2. Callers must return tan(-0) = -0 without calling here since our + * odd polynomial is not evaluated in a way that preserves -0. + * Callers may do the optimization tan(x) ~ x for tiny x. + * 3. tan(x) is approximated by a odd polynomial of degree 27 on + * [0,0.67434] + * 3 27 + * tan(x) ~ x + T1*x + ... + T13*x + * where + * + * |tan(x) 2 4 26 | -59.2 + * |----- - (1+T1*x +T2*x +.... +T13*x )| <= 2 + * | x | + * + * Note: tan(x+y) = tan(x) + tan'(x)*y + * ~ tan(x) + (1+x*x)*y + * Therefore, for better accuracy in computing tan(x+y), let + * 3 2 2 2 2 + * r = x *(T2+x *(T3+x *(...+x *(T12+x *T13)))) + * then + * 3 2 + * tan(x+y) = x + (T1*x + (x *(r+y)+y)) + * + * 4. For x in [0.67434,pi/4], let y = pi/4 - x, then + * tan(x) = tan(pi/4-y) = (1-tan(y))/(1+tan(y)) + * = 1 - 2*(tan(y) - (tan(y)^2)/(1+tan(y))) + */ + +#include + +#include "math_private.h" + +static const double xxx[] = { + 3.33333333333334091986e-01, /* 3FD55555, 55555563 */ + 1.33333333333201242699e-01, /* 3FC11111, 1110FE7A */ + 5.39682539762260521377e-02, /* 3FABA1BA, 1BB341FE */ + 2.18694882948595424599e-02, /* 3F9664F4, 8406D637 */ + 8.86323982359930005737e-03, /* 3F8226E3, E96E8493 */ + 3.59207910759131235356e-03, /* 3F6D6D22, C9560328 */ + 1.45620945432529025516e-03, /* 3F57DBC8, FEE08315 */ + 5.88041240820264096874e-04, /* 3F4344D8, F2F26501 */ + 2.46463134818469906812e-04, /* 3F3026F7, 1A8D1068 */ + 7.81794442939557092300e-05, /* 3F147E88, A03792A6 */ + 7.14072491382608190305e-05, /* 3F12B80F, 32F0A7E9 */ + -1.85586374855275456654e-05, /* BEF375CB, DB605373 */ + 2.59073051863633712884e-05, /* 3EFB2A70, 74BF7AD4 */ +/* one */ 1.00000000000000000000e+00, /* 3FF00000, 00000000 */ +/* pio4 */ 7.85398163397448278999e-01, /* 3FE921FB, 54442D18 */ +/* pio4lo */ 3.06161699786838301793e-17 /* 3C81A626, 33145C07 */ +}; +#define one xxx[13] +#define pio4 xxx[14] +#define pio4lo xxx[15] +#define T xxx +/* INDENT ON */ + +double +__kernel_tan(double x, double y, int iy) { + double z, r, v, w, s; + int32_t ix, hx; + + GET_HIGH_WORD(hx,x); + ix = hx & 0x7fffffff; /* high word of |x| */ + if (ix >= 0x3FE59428) { /* |x| >= 0.6744 */ + if (hx < 0) { + x = -x; + y = -y; + } + z = pio4 - x; + w = pio4lo - y; + x = z + w; + y = 0.0; + } + z = x * x; + w = z * z; + /* + * Break x^5*(T[1]+x^2*T[2]+...) into + * x^5(T[1]+x^4*T[3]+...+x^20*T[11]) + + * x^5(x^2*(T[2]+x^4*T[4]+...+x^22*[T12])) + */ + r = T[1] + w * (T[3] + w * (T[5] + w * (T[7] + w * (T[9] + + w * T[11])))); + v = z * (T[2] + w * (T[4] + w * (T[6] + w * (T[8] + w * (T[10] + + w * T[12]))))); + s = z * x; + r = y + z * (s * (r + v) + y); + r += T[0] * s; + w = x + r; + if (ix >= 0x3FE59428) { + v = (double) iy; + return (double) (1 - ((hx >> 30) & 2)) * + (v - 2.0 * (x - (w * w / (w + v) - r))); + } + if (iy == 1) + return w; + else { + /* + * if allow error up to 2 ulp, simply return + * -1.0 / (x+r) here + */ + /* compute -1.0 / (x+r) accurately */ + double a, t; + z = w; + SET_LOW_WORD(z,0); + v = r - (z - x); /* z+v = r+x */ + t = a = -1.0 / w; /* a = -1.0/w */ + SET_LOW_WORD(t,0); + s = 1.0 + t * z; + return t + a * (s + t * v); + } +} diff --git a/src/openlibm/src/k_tan.c.o b/src/openlibm/src/k_tan.c.o new file mode 100644 index 0000000000000000000000000000000000000000..04772cde768e161172c815ce046335f6d203bcae GIT binary patch literal 3048 zcmb<-^>JfjWMqH=Mg}_u1P><4z@Wi_U^{@B4h;MZd<Vq4_#^M6@oRkf#2*R5$3F2#K+TGL_lZ9Oto9RsB(24deBzHd z`iVdC@F)IAS&;ia@kbo|#2*O~Kas|-ap)6&#LZ9q5r-juFRyL>#aI&YiC;h!q!=7d z9=kxy|NsC0_fWj>i9hZ^ng@R#Nbk!}{4uXS@yFZ+DSP0dcmX7F;1hr3jZgfMCqD5< z@Paf#EQq`Vvg9zod;>`AGk+a8Fw*$LFQoB@pLjXx-~a#o@(gMG@1LacYn(XvL+%s5 z7AOo)G(TY41&UftkV}tz;*UF##{d4nCw{F%pZH@=f8vk1_=!K_(kK2Hkm@6cL8iko z*e(!HLf0kax8h5C_81XkwPlSqSE}}x6lndnd%66B5&sS$`wW3zsqbnA_M*)X{++lT zZa=vt@8x5)Ci{Pmo27RxTy0+*oN)Ve>F0gRCYdkjs1vbgO#SrfhKsYk26Na+rQBS5 z^J{D^Us9&oSN#(Z6cjvYpBxGTSM5P|GcbJE52fuH+?}1R6g1rZLNyf(P4tZP3>AzF zj7$v-4Gk1Df>KiyJQ7Qw61wJ^3=Av`3=9ek3=E*aa`y{mU}9iA01^WQ2*^xED4!F= zVPIeofzpgsK@5x)0*ul;>>LvqA>uMnxmz&JP(C&aq=bdx<9}>&%vf?7#C|pm<$Pcf zHU^|@2o@0rlWYtEU>ZS4fSGIzkh}`!fC)J;$;JSY2XnxLGMHpz@Bq^YLKDnn1BV@$ z2_^KvG#f(zm_`sLU?v-b2AD<=mS83uLj;&c5RiyvV=zDnfmtqKl8qq&Od|*{Fq4hJ z0!$+ae=w7cAp=Y!h)^(-jiCTcBZz1)lZ~MQOe2UyFq4e|p5VcJ28MJn4N5&=2As%Y zU|bC_-rI`E+li7BZ+e(iEl;{ z=Rp#O77Sqbg9=NS`KOW8gYpne{5q02Kax3*k;FlH3a0)$lDHs}dKFLxXMlv85R!NX zk~k=j!pvzw5(kwrFmX`X1hN7Y{vZrugRx$5Wo}7g5`$iGNfCt3fU$~Fa}xDRQY%Ur z^imQ_5*hT8ii;Wait<4mz2xE&Lo;Na1%qC4er|4RUI~L!_@P?TSgT2xZWpa(WQH6uQ)C^0t`>=KFykpDnl2c;oogJ9(oJl{YiL17PNf+=YR zNEr@O4;Ex#V7LKFtPBhc8$gCLFff491c(VrdmuHia!!qb0h~)gc>yF2!%`@L4HJc^ zMerCHbQl=GWiPq<4Wagf(g?D-3Q+se{R`v6Xizx`@)x>(1E~HEWJ95D1qs2z!3SzT zdO5oTs$U~rZjd89p!N$uB|&8m vsCA33A5`W+m4dXvF{CNWz)%SnfiOV!L0AwHROVpQzX0m~c8D@KiLM_20hR-g literal 0 HcmV?d00001 diff --git a/src/openlibm/src/k_tanf.c b/src/openlibm/src/k_tanf.c new file mode 100644 index 0000000..9c17d1b --- /dev/null +++ b/src/openlibm/src/k_tanf.c @@ -0,0 +1,68 @@ +/* k_tanf.c -- float version of k_tan.c + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + * Optimized by Bruce D. Evans. + */ + +/* + * ==================================================== + * Copyright 2004 Sun Microsystems, Inc. All Rights Reserved. + * + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#ifndef INLINE_KERNEL_TANDF +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/k_tanf.c,v 1.23 2009/06/03 08:16:34 ed Exp $"); +#endif + +#include + +#include "math_private.h" + +/* |tan(x)/x - t(x)| < 2**-25.5 (~[-2e-08, 2e-08]). */ +static const double +T[] = { + 0x15554d3418c99f.0p-54, /* 0.333331395030791399758 */ + 0x1112fd38999f72.0p-55, /* 0.133392002712976742718 */ + 0x1b54c91d865afe.0p-57, /* 0.0533812378445670393523 */ + 0x191df3908c33ce.0p-58, /* 0.0245283181166547278873 */ + 0x185dadfcecf44e.0p-61, /* 0.00297435743359967304927 */ + 0x1362b9bf971bcd.0p-59, /* 0.00946564784943673166728 */ +}; + +#ifndef INLINE_KERNEL_TANDF +extern +#endif +//__inline float +OLM_DLLEXPORT float +__kernel_tandf(double x, int iy) +{ + double z,r,w,s,t,u; + + z = x*x; + /* + * Split up the polynomial into small independent terms to give + * opportunities for parallel evaluation. The chosen splitting is + * micro-optimized for Athlons (XP, X64). It costs 2 multiplications + * relative to Horner's method on sequential machines. + * + * We add the small terms from lowest degree up for efficiency on + * non-sequential machines (the lowest degree terms tend to be ready + * earlier). Apart from this, we don't care about order of + * operations, and don't need to to care since we have precision to + * spare. However, the chosen splitting is good for accuracy too, + * and would give results as accurate as Horner's method if the + * small terms were added from highest degree down. + */ + r = T[4]+z*T[5]; + t = T[2]+z*T[3]; + w = z*z; + s = z*x; + u = T[0]+z*T[1]; + r = (x+s*u)+(s*w)*(t+w*r); + if(iy==1) return r; + else return -1.0/r; +} diff --git a/src/openlibm/src/k_tanf.c.o b/src/openlibm/src/k_tanf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..12286c0e0eadc512b12f3a5f06aeb4322e1d7f56 GIT binary patch literal 1952 zcmb<-^>JfjWMqH=Mg}_u1P><4z@Wf_U^{@B4h(z@ybNjl8Yj~DHEw+37Z3#rf8rNV zh0u{8@zG%92ZbffoLVGtP}+cr!@>__F9<`GF)-*ASLT)^CNbz0mlQ$h3>d2@H78N8 zB(Sm;jW93WLJ}B;*d&4`L%@bC^P8K`d&+ z85kHq=^7f`aMc!2{TS|otAH@_p=P4%&mdBN7LNGufJO)`os%1^LxgNcKzLAM*^ zvKb%=P~1XkP&olAE7A3X%!FD6(gw#1poZGOMIa2QaS#pz1A`#6+<^-~84I9>RzmqO H3SB<{A~@q3 literal 0 HcmV?d00001 diff --git a/src/openlibm/src/loongarch64_fpmath.h b/src/openlibm/src/loongarch64_fpmath.h new file mode 100644 index 0000000..31ea131 --- /dev/null +++ b/src/openlibm/src/loongarch64_fpmath.h @@ -0,0 +1,56 @@ +/*- + * Copyright (c) 2023 Yifan An + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +union IEEEl2bits { + long double e; + struct { + uint64_t manl :64; + uint64_t manh :48; + unsigned int exp :15; + unsigned int sign :1; + } bits; + struct { + uint64_t manl :64; + uint64_t manh :48; + unsigned int expsign :16; + } xbits; +}; + +#define LDBL_NBIT 0 +#define LDBL_IMPLICIT_NBIT +#define mask_nbit_l(u) ((void)0) + +#define LDBL_MANH_SIZE 48 +#define LDBL_MANL_SIZE 64 + +#define LDBL_TO_ARRAY32(u, a) do { \ + (a)[0] = (uint32_t)(u).bits.manl; \ + (a)[1] = (uint32_t)((u).bits.manl >> 32); \ + (a)[2] = (uint32_t)(u).bits.manh; \ + (a)[3] = (uint32_t)((u).bits.manh >> 32); \ +} while(0) diff --git a/src/openlibm/src/math_private.h b/src/openlibm/src/math_private.h new file mode 100644 index 0000000..15a27b2 --- /dev/null +++ b/src/openlibm/src/math_private.h @@ -0,0 +1,375 @@ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * from: @(#)fdlibm.h 5.1 93/09/24 + * $FreeBSD: src/lib/msun/src/math_private.h,v 1.34 2011/10/21 06:27:56 das Exp $ + */ + +#ifndef _MATH_PRIVATE_H_ +#define _MATH_PRIVATE_H_ + +#include +#include +#include "cdefs-compat.h" +#include "types-compat.h" +#include "fpmath.h" +#include +#include "math_private_openbsd.h" + +/* + * The original fdlibm code used statements like: + * n0 = ((*(int*)&one)>>29)^1; * index of high word * + * ix0 = *(n0+(int*)&x); * high word of x * + * ix1 = *((1-n0)+(int*)&x); * low word of x * + * to dig two 32 bit words out of the 64 bit IEEE floating point + * value. That is non-ANSI, and, moreover, the gcc instruction + * scheduler gets it wrong. We instead use the following macros. + * Unlike the original code, we determine the endianness at compile + * time, not at run time; I don't see much benefit to selecting + * endianness at run time. + */ + +/* + * A union which permits us to convert between a double and two 32 bit + * ints. + */ + +#if __FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__ + +typedef union +{ + double value; + struct + { + u_int32_t msw; + u_int32_t lsw; + } parts; + struct + { + u_int64_t w; + } xparts; +} ieee_double_shape_type; + +#endif + +#if __FLOAT_WORD_ORDER__ == __ORDER_LITTLE_ENDIAN__ + +typedef union +{ + double value; + struct + { + u_int32_t lsw; + u_int32_t msw; + } parts; + struct + { + u_int64_t w; + } xparts; +} ieee_double_shape_type; + +#endif + +/* Get two 32 bit ints from a double. */ + +#define EXTRACT_WORDS(ix0,ix1,d) \ +do { \ + ieee_double_shape_type ew_u; \ + ew_u.value = (d); \ + (ix0) = ew_u.parts.msw; \ + (ix1) = ew_u.parts.lsw; \ +} while (0) + +/* Get a 64-bit int from a double. */ +#define EXTRACT_WORD64(ix,d) \ +do { \ + ieee_double_shape_type ew_u; \ + ew_u.value = (d); \ + (ix) = ew_u.xparts.w; \ +} while (0) + +/* Get the more significant 32 bit int from a double. */ + +#define GET_HIGH_WORD(i,d) \ +do { \ + ieee_double_shape_type gh_u; \ + gh_u.value = (d); \ + (i) = gh_u.parts.msw; \ +} while (0) + +/* Get the less significant 32 bit int from a double. */ + +#define GET_LOW_WORD(i,d) \ +do { \ + ieee_double_shape_type gl_u; \ + gl_u.value = (d); \ + (i) = gl_u.parts.lsw; \ +} while (0) + +/* Set a double from two 32 bit ints. */ + +#define INSERT_WORDS(d,ix0,ix1) \ +do { \ + ieee_double_shape_type iw_u; \ + iw_u.parts.msw = (ix0); \ + iw_u.parts.lsw = (ix1); \ + (d) = iw_u.value; \ +} while (0) + +/* Set a double from a 64-bit int. */ +#define INSERT_WORD64(d,ix) \ +do { \ + ieee_double_shape_type iw_u; \ + iw_u.xparts.w = (ix); \ + (d) = iw_u.value; \ +} while (0) + +/* Set the more significant 32 bits of a double from an int. */ + +#define SET_HIGH_WORD(d,v) \ +do { \ + ieee_double_shape_type sh_u; \ + sh_u.value = (d); \ + sh_u.parts.msw = (v); \ + (d) = sh_u.value; \ +} while (0) + +/* Set the less significant 32 bits of a double from an int. */ + +#define SET_LOW_WORD(d,v) \ +do { \ + ieee_double_shape_type sl_u; \ + sl_u.value = (d); \ + sl_u.parts.lsw = (v); \ + (d) = sl_u.value; \ +} while (0) + +/* + * A union which permits us to convert between a float and a 32 bit + * int. + */ + +typedef union +{ + float value; + /* FIXME: Assumes 32 bit int. */ + unsigned int word; +} ieee_float_shape_type; + +/* Get a 32 bit int from a float. */ + +#define GET_FLOAT_WORD(i,d) \ +do { \ + ieee_float_shape_type gf_u; \ + gf_u.value = (d); \ + (i) = gf_u.word; \ +} while (0) + +/* Set a float from a 32 bit int. */ + +#define SET_FLOAT_WORD(d,i) \ +do { \ + ieee_float_shape_type sf_u; \ + sf_u.word = (i); \ + (d) = sf_u.value; \ +} while (0) + +/* Get expsign as a 16 bit int from a long double. */ + +#define GET_LDBL_EXPSIGN(i,d) \ +do { \ + union IEEEl2bits ge_u; \ + ge_u.e = (d); \ + (i) = ge_u.xbits.expsign; \ +} while (0) + +/* Set expsign of a long double from a 16 bit int. */ + +#define SET_LDBL_EXPSIGN(d,v) \ +do { \ + union IEEEl2bits se_u; \ + se_u.e = (d); \ + se_u.xbits.expsign = (v); \ + (d) = se_u.e; \ +} while (0) + + +#ifndef __FreeBSD__ +#define STRICT_ASSIGN(type, lval, rval) ((lval) = (rval)) +#else +#ifdef FLT_EVAL_METHOD +// Attempt to get strict C99 semantics for assignment with non-C99 compilers. +#if FLT_EVAL_METHOD == 0 || __GNUC__ == 0 +#define STRICT_ASSIGN(type, lval, rval) ((lval) = (rval)) +#else +#define STRICT_ASSIGN(type, lval, rval) do { \ + volatile type __lval; \ + \ + if (sizeof(type) >= sizeof(long double)) \ + (lval) = (rval); \ + else { \ + __lval = (rval); \ + (lval) = __lval; \ + } \ +} while (0) +#endif +#endif +#endif + +/* + * Common routine to process the arguments to nan(), nanf(), and nanl(). + */ +void __scan_nan(u_int32_t *__words, int __num_words, const char *__s); + +/* + * Mix 1 or 2 NaNs. First add 0 to each arg. This normally just turns + * signaling NaNs into quiet NaNs by setting a quiet bit. We do this + * because we want to never return a signaling NaN, and also because we + * don't want the quiet bit to affect the result. Then mix the converted + * args using addition. The result is typically the arg whose mantissa + * bits (considered as in integer) are largest. + * + * Technical complications: the result in bits might depend on the precision + * and/or on compiler optimizations, especially when different register sets + * are used for different precisions. Try to make the result not depend on + * at least the precision by always doing the main mixing step in long double + * precision. Try to reduce dependencies on optimizations by adding the + * the 0's in different precisions (unless everything is in long double + * precision). + */ +#define nan_mix(x, y) (((x) + 0.0L) + ((y) + 0)) + +#ifdef __GNUCLIKE_ASM + +/* Asm versions of some functions. */ + +#ifdef __amd64__ +static __inline int +irint(double x) +{ + int n; + + __asm__("cvtsd2si %1,%0" : "=r" (n) : "x" (x)); + return (n); +} +#define HAVE_EFFICIENT_IRINT +#endif + +#ifdef __i386__ +static __inline int +irint(double x) +{ + int n; + + __asm__("fistl %0" : "=m" (n) : "t" (x)); + return (n); +} +#define HAVE_EFFICIENT_IRINT +#endif + +#endif /* __GNUCLIKE_ASM */ + +/* + * ieee style elementary functions + * + * We rename functions here to improve other sources' diffability + * against fdlibm. + */ +#define __ieee754_sqrt sqrt +#define __ieee754_acos acos +#define __ieee754_acosh acosh +#define __ieee754_log log +#define __ieee754_log2 log2 +#define __ieee754_atanh atanh +#define __ieee754_asin asin +#define __ieee754_atan2 atan2 +#define __ieee754_exp exp +#define __ieee754_cosh cosh +#define __ieee754_fmod fmod +#define __ieee754_pow pow +#define __ieee754_lgamma lgamma +#define __ieee754_lgamma_r lgamma_r +#define __ieee754_log10 log10 +#define __ieee754_sinh sinh +#define __ieee754_hypot hypot +#define __ieee754_j0 j0 +#define __ieee754_j1 j1 +#define __ieee754_y0 y0 +#define __ieee754_y1 y1 +#define __ieee754_jn jn +#define __ieee754_yn yn +#define __ieee754_remainder remainder +#define __ieee754_sqrtf sqrtf +#define __ieee754_acosf acosf +#define __ieee754_acoshf acoshf +#define __ieee754_logf logf +#define __ieee754_atanhf atanhf +#define __ieee754_asinf asinf +#define __ieee754_atan2f atan2f +#define __ieee754_expf expf +#define __ieee754_coshf coshf +#define __ieee754_fmodf fmodf +#define __ieee754_powf powf +#define __ieee754_lgammaf lgammaf +#define __ieee754_lgammaf_r lgammaf_r +#define __ieee754_log10f log10f +#define __ieee754_log2f log2f +#define __ieee754_sinhf sinhf +#define __ieee754_hypotf hypotf +#define __ieee754_j0f j0f +#define __ieee754_j1f j1f +#define __ieee754_y0f y0f +#define __ieee754_y1f y1f +#define __ieee754_jnf jnf +#define __ieee754_ynf ynf +#define __ieee754_remainderf remainderf + +/* fdlibm kernel function */ +int __kernel_rem_pio2(double*,double*,int,int,int); + +/* double precision kernel functions */ +#ifdef INLINE_REM_PIO2 +__inline +#endif +int __ieee754_rem_pio2(double,double*); +double __kernel_sin(double,double,int); +double __kernel_cos(double,double); +double __kernel_tan(double,double,int); +double __ldexp_exp(double,int); +double complex __ldexp_cexp(double complex,int); + +/* float precision kernel functions */ +#ifdef INLINE_REM_PIO2F +__inline +#endif +int __ieee754_rem_pio2f(float,double*); +#ifdef INLINE_KERNEL_SINDF +__inline +#endif +float __kernel_sindf(double); +#ifdef INLINE_KERNEL_COSDF +__inline +#endif +float __kernel_cosdf(double); +#ifdef INLINE_KERNEL_TANDF +__inline +#endif +float __kernel_tandf(double,int); +float __ldexp_expf(float,int); +float complex __ldexp_cexpf(float complex,int); + +/* long double precision kernel functions */ +long double __kernel_sinl(long double, long double, int); +long double __kernel_cosl(long double, long double); +long double __kernel_tanl(long double, long double, int); + +#endif /* !_MATH_PRIVATE_H_ */ diff --git a/src/openlibm/src/math_private_openbsd.h b/src/openlibm/src/math_private_openbsd.h new file mode 100644 index 0000000..021670f --- /dev/null +++ b/src/openlibm/src/math_private_openbsd.h @@ -0,0 +1,218 @@ +/* $OpenBSD: math_private.h,v 1.17 2014/06/02 19:31:17 kettenis Exp $ */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * from: @(#)fdlibm.h 5.1 93/09/24 + */ + +#ifndef _MATH_PRIVATE_OPENBSD_H_ +#define _MATH_PRIVATE_OPENBSD_H_ + +#if __FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__ + +typedef union +{ + long double value; + struct { + u_int32_t mswhi; + u_int32_t mswlo; + u_int32_t lswhi; + u_int32_t lswlo; + } parts32; + struct { + u_int64_t msw; + u_int64_t lsw; + } parts64; +} ieee_quad_shape_type; + +#endif + +#if __FLOAT_WORD_ORDER__ == __ORDER_LITTLE_ENDIAN__ + +typedef union +{ + long double value; + struct { + u_int32_t lswlo; + u_int32_t lswhi; + u_int32_t mswlo; + u_int32_t mswhi; + } parts32; + struct { + u_int64_t lsw; + u_int64_t msw; + } parts64; +} ieee_quad_shape_type; + +#endif + +/* Get two 64 bit ints from a long double. */ + +#define GET_LDOUBLE_WORDS64(ix0,ix1,d) \ +do { \ + ieee_quad_shape_type qw_u; \ + qw_u.value = (d); \ + (ix0) = qw_u.parts64.msw; \ + (ix1) = qw_u.parts64.lsw; \ +} while (0) + +/* Set a long double from two 64 bit ints. */ + +#define SET_LDOUBLE_WORDS64(d,ix0,ix1) \ +do { \ + ieee_quad_shape_type qw_u; \ + qw_u.parts64.msw = (ix0); \ + qw_u.parts64.lsw = (ix1); \ + (d) = qw_u.value; \ +} while (0) + +/* Get the more significant 64 bits of a long double mantissa. */ + +#define GET_LDOUBLE_MSW64(v,d) \ +do { \ + ieee_quad_shape_type sh_u; \ + sh_u.value = (d); \ + (v) = sh_u.parts64.msw; \ +} while (0) + +/* Set the more significant 64 bits of a long double mantissa from an int. */ + +#define SET_LDOUBLE_MSW64(d,v) \ +do { \ + ieee_quad_shape_type sh_u; \ + sh_u.value = (d); \ + sh_u.parts64.msw = (v); \ + (d) = sh_u.value; \ +} while (0) + +/* Get the least significant 64 bits of a long double mantissa. */ + +#define GET_LDOUBLE_LSW64(v,d) \ +do { \ + ieee_quad_shape_type sh_u; \ + sh_u.value = (d); \ + (v) = sh_u.parts64.lsw; \ +} while (0) + +/* A union which permits us to convert between a long double and + three 32 bit ints. */ + +#if __FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__ + +typedef union +{ + long double value; + struct { +#ifdef __LP64__ + int padh:32; +#endif + int exp:16; + int padl:16; + u_int32_t msw; + u_int32_t lsw; + } parts; +} ieee_extended_shape_type; + +#endif + +#if __FLOAT_WORD_ORDER__ == __ORDER_LITTLE_ENDIAN__ + +typedef union +{ + long double value; + struct { + u_int32_t lsw; + u_int32_t msw; + int exp:16; + int padl:16; +#ifdef __LP64__ + int padh:32; +#endif + } parts; +} ieee_extended_shape_type; + +#endif + +/* Get three 32 bit ints from a double. */ + +#define GET_LDOUBLE_WORDS(se,ix0,ix1,d) \ +do { \ + ieee_extended_shape_type ew_u; \ + ew_u.value = (d); \ + (se) = ew_u.parts.exp; \ + (ix0) = ew_u.parts.msw; \ + (ix1) = ew_u.parts.lsw; \ +} while (0) + +/* Set a double from two 32 bit ints. */ + +#define SET_LDOUBLE_WORDS(d,se,ix0,ix1) \ +do { \ + ieee_extended_shape_type iw_u; \ + iw_u.parts.exp = (se); \ + iw_u.parts.msw = (ix0); \ + iw_u.parts.lsw = (ix1); \ + (d) = iw_u.value; \ +} while (0) + +/* Get the more significant 32 bits of a long double mantissa. */ + +#define GET_LDOUBLE_MSW(v,d) \ +do { \ + ieee_extended_shape_type sh_u; \ + sh_u.value = (d); \ + (v) = sh_u.parts.msw; \ +} while (0) + +/* Set the more significant 32 bits of a long double mantissa from an int. */ + +#define SET_LDOUBLE_MSW(d,v) \ +do { \ + ieee_extended_shape_type sh_u; \ + sh_u.value = (d); \ + sh_u.parts.msw = (v); \ + (d) = sh_u.value; \ +} while (0) + +/* Get int from the exponent of a long double. */ + +#define GET_LDOUBLE_EXP(se,d) \ +do { \ + ieee_extended_shape_type ge_u; \ + ge_u.value = (d); \ + (se) = ge_u.parts.exp; \ +} while (0) + +/* Set exponent of a long double from an int. */ + +#define SET_LDOUBLE_EXP(d,se) \ +do { \ + ieee_extended_shape_type se_u; \ + se_u.value = (d); \ + se_u.parts.exp = (se); \ + (d) = se_u.value; \ +} while (0) + +/* + * Common routine to process the arguments to nan(), nanf(), and nanl(). + */ +void __scan_nan(uint32_t *__words, int __num_words, const char *__s); + +/* + * Functions internal to the math package, yet not static. + */ +double __exp__D(double, double); +struct Double __log__D(double); +long double __p1evll(long double, void *, int); +long double __polevll(long double, void *, int); + +#endif /* _MATH_PRIVATE_OPENBSD_H_ */ diff --git a/src/openlibm/src/mips_fpmath.h b/src/openlibm/src/mips_fpmath.h new file mode 100644 index 0000000..50f119f --- /dev/null +++ b/src/openlibm/src/mips_fpmath.h @@ -0,0 +1,57 @@ +/*- + * Copyright (c) 2002, 2003 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +union IEEEl2bits { + long double e; + struct { +#ifndef __MIPSEB__ + unsigned int manl :32; + unsigned int manh :20; + unsigned int exp :11; + unsigned int sign :1; +#else + unsigned int sign :1; + unsigned int exp :11; + unsigned int manh :20; + unsigned int manl :32; +#endif + } bits; +}; + +#define LDBL_NBIT 0 +#define mask_nbit_l(u) ((void)0) +#define LDBL_IMPLICIT_NBIT + +#define LDBL_MANH_SIZE 20 +#define LDBL_MANL_SIZE 32 + +#define LDBL_TO_ARRAY32(u, a) do { \ + (a)[0] = (uint32_t)(u).bits.manl; \ + (a)[1] = (uint32_t)(u).bits.manh; \ +} while(0) + diff --git a/src/openlibm/src/polevll.c b/src/openlibm/src/polevll.c new file mode 100644 index 0000000..1c785d8 --- /dev/null +++ b/src/openlibm/src/polevll.c @@ -0,0 +1,104 @@ +/* $OpenBSD: polevll.c,v 1.2 2013/11/12 20:35:09 martynas Exp $ */ + +/* + * Copyright (c) 2008 Stephen L. Moshier + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* polevll.c + * p1evll.c + * + * Evaluate polynomial + * + * + * + * SYNOPSIS: + * + * int N; + * long double x, y, coef[N+1], polevl[]; + * + * y = polevll( x, coef, N ); + * + * + * + * DESCRIPTION: + * + * Evaluates polynomial of degree N: + * + * 2 N + * y = C + C x + C x +...+ C x + * 0 1 2 N + * + * Coefficients are stored in reverse order: + * + * coef[0] = C , ..., coef[N] = C . + * N 0 + * + * The function p1evll() assumes that coef[N] = 1.0 and is + * omitted from the array. Its calling arguments are + * otherwise the same as polevll(). + * + * + * SPEED: + * + * In the interest of speed, there are no checks for out + * of bounds arithmetic. This routine is used by most of + * the functions in the library. Depending on available + * equipment features, the user may wish to rewrite the + * program in microcode or assembly language. + * + */ + +#include + +#include "math_private.h" + +/* + * Polynomial evaluator: + * P[0] x^n + P[1] x^(n-1) + ... + P[n] + */ +long double +__polevll(long double x, void *PP, int n) +{ + long double y; + long double *P; + + P = (long double *)PP; + y = *P++; + do { + y = y * x + *P++; + } while (--n); + + return (y); +} + +/* + * Polynomial evaluator: + * x^n + P[0] x^(n-1) + P[1] x^(n-2) + ... + P[n] + */ +long double +__p1evll(long double x, void *PP, int n) +{ + long double y; + long double *P; + + P = (long double *)PP; + n -= 1; + y = x + *P++; + do { + y = y * x + *P++; + } while (--n); + + return (y); +} diff --git a/src/openlibm/src/polevll.c.o b/src/openlibm/src/polevll.c.o new file mode 100644 index 0000000000000000000000000000000000000000..969a2da436814545b7922097f3620e79412204a1 GIT binary patch literal 1416 zcmb<-^>JfjWMqH=Mg}_u1P><4z|g^jU^{@B4h%dD+zh>8|8M80aCr2(3wSgiV!EyG zaqtm~2jg{q`4+G$kLCjcH%{Kp_;Bx_hvkpb4|i`KPD|5+$)-&JY3>dChoS$*!8Cq( z7X}6_`Wf7vovjo!-2Fl|6%0-EjPwi@j0}uS4Gawp6f}ZTQxrTBOP~_E=9*wvFfgz% zFfb@EFfgz(Ffh3Lg)%TPFdhJjL8TcOp?sL%MW7OlRY44l6#|UXJnS437#SD@7#J92 zpmN4g8YE@_Wy8dvTnq|iJ`2Og{}>Vs3=GUzLY|v}fk6mK9A>^KR2&i)3=A-FhJyT@ z)Uuo$y<~>?cqkjhG6V@i!vJJAC^|tH#0Fs#5W&E}01^XXn7Isk#g(}wiAfB4#U(`$ zIs?WkNv$Yh&`U`yNo3GVDlTTwOU}>DP0cG|(96p&N!4@r3)L+yNlea$^3(H5^$Lpe z3sQ?pDjD>OQgagZQZwSyiV|~Ep_WrXNi#5jLx~N|446NP(ZoS9FeuYYbsaUA}ptJ)PfD#f=i(v5p6$XbDj18hA z7$A8RUEK$$ewh87P + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +union IEEEl2bits { + long double e; + struct { + unsigned int sign :1; + unsigned int exp :11; + unsigned int manh :20; + unsigned int manl :32; + } bits; +}; + +#define mask_nbit_l(u) ((void)0) +#define LDBL_IMPLICIT_NBIT +#define LDBL_NBIT 0 + +#define LDBL_MANH_SIZE 20 +#define LDBL_MANL_SIZE 32 + +#define LDBL_TO_ARRAY32(u, a) do { \ + (a)[0] = (uint32_t)(u).bits.manl; \ + (a)[1] = (uint32_t)(u).bits.manh; \ +} while(0) diff --git a/src/openlibm/src/riscv_fpmath.h b/src/openlibm/src/riscv_fpmath.h new file mode 100644 index 0000000..cfa85ff --- /dev/null +++ b/src/openlibm/src/riscv_fpmath.h @@ -0,0 +1,58 @@ +/*- + * Copyright (c) 2002, 2003 David Schultz + * Copyright (c) 2014 The FreeBSD Foundation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: head/lib/libc/riscv/_fpmath.h 362788 2020-06-29 19:30:35Z mhorne $ + */ + +union IEEEl2bits { + long double e; + struct { + unsigned long manl :64; + unsigned long manh :48; + unsigned int exp :15; + unsigned int sign :1; + } bits; + struct { + unsigned long manl :64; + unsigned long manh :48; + unsigned int expsign :16; + } xbits; +}; + +#define LDBL_NBIT 0 +#define LDBL_IMPLICIT_NBIT +#define mask_nbit_l(u) ((void)0) + +#define LDBL_MANH_SIZE 48 +#define LDBL_MANL_SIZE 64 + +#define LDBL_TO_ARRAY32(u, a) do { \ + (a)[0] = (uint32_t)(u).bits.manl; \ + (a)[1] = (uint32_t)((u).bits.manl >> 32); \ + (a)[2] = (uint32_t)(u).bits.manh; \ + (a)[3] = (uint32_t)((u).bits.manh >> 32); \ +} while(0) + diff --git a/src/openlibm/src/s390_fpmath.h b/src/openlibm/src/s390_fpmath.h new file mode 100644 index 0000000..1e7787c --- /dev/null +++ b/src/openlibm/src/s390_fpmath.h @@ -0,0 +1,51 @@ +/*- + * Copyright (c) 2016 Dan Horák + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + * + * cloned from powerpc_fpmath.h + */ + +union IEEEl2bits { + long double e; + struct { + unsigned int sign :1; + unsigned int exp :11; + unsigned int manh :20; + unsigned int manl :32; + } bits; +}; + +#define mask_nbit_l(u) ((void)0) +#define LDBL_IMPLICIT_NBIT +#define LDBL_NBIT 0 + +#define LDBL_MANH_SIZE 20 +#define LDBL_MANL_SIZE 32 + +#define LDBL_TO_ARRAY32(u, a) do { \ + (a)[0] = (uint32_t)(u).bits.manl; \ + (a)[1] = (uint32_t)(u).bits.manh; \ +} while(0) diff --git a/src/openlibm/src/s_asinh.c b/src/openlibm/src/s_asinh.c new file mode 100644 index 0000000..ca7937c --- /dev/null +++ b/src/openlibm/src/s_asinh.c @@ -0,0 +1,62 @@ +/* @(#)s_asinh.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_asinh.c,v 1.9 2008/02/22 02:30:35 das Exp $"); + +/* asinh(x) + * Method : + * Based on + * asinh(x) = sign(x) * log [ |x| + sqrt(x*x+1) ] + * we have + * asinh(x) := x if 1+x*x=1, + * := sign(x)*(log(x)+ln2)) for large |x|, else + * := sign(x)*log(2|x|+1/(|x|+sqrt(x*x+1))) if|x|>2, else + * := sign(x)*log1p(|x| + x^2/(1 + sqrt(1+x^2))) + */ + +#include +#include + +#include "math_private.h" + +static const double +one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */ +ln2 = 6.93147180559945286227e-01, /* 0x3FE62E42, 0xFEFA39EF */ +huge= 1.00000000000000000000e+300; + +OLM_DLLEXPORT double +asinh(double x) +{ + double t,w; + int32_t hx,ix; + GET_HIGH_WORD(hx,x); + ix = hx&0x7fffffff; + if(ix>=0x7ff00000) return x+x; /* x is inf or NaN */ + if(ix< 0x3e300000) { /* |x|<2**-28 */ + if(huge+x>one) return x; /* return x inexact except 0 */ + } + if(ix>0x41b00000) { /* |x| > 2**28 */ + w = __ieee754_log(fabs(x))+ln2; + } else if (ix>0x40000000) { /* 2**28 > |x| > 2.0 */ + t = fabs(x); + w = __ieee754_log(2.0*t+one/(__ieee754_sqrt(x*x+one)+t)); + } else { /* 2.0 > |x| > 2**-28 */ + t = x*x; + w =log1p(fabs(x)+t/(one+__ieee754_sqrt(one+t))); + } + if(hx>0) return w; else return -w; +} + +#if (LDBL_MANT_DIG == 53) +openlibm_weak_reference(asinh, asinhl); +#endif diff --git a/src/openlibm/src/s_asinh.c.o b/src/openlibm/src/s_asinh.c.o new file mode 100644 index 0000000000000000000000000000000000000000..366b790628cbc859cbdb4eb2fc223ca28754ca80 GIT binary patch literal 2480 zcmb<-^>JfjWMqH=Mg}_u1P><4!0>?;!FB*M9T@l-_!xrIJoxJlr}1l?@HqHdq4S37 z|NsB%J(}Mr*#7_jzMj8*4+8^(?f?J!cKq!V85kHo@e7E8bbsO(kcH3@7t;9kFPCSh z@oPLx8lvV&kHt+(qr()h!{zVK*1q7Z#JjbGk{fx(u6VS{6tCRh!a_{1Lp zR`mKTSpE}##0ju^klPNYO@KMvmVtr6fxpe||NsAB2T4FR3;2K>FJKCCbsE3M3$UcX zC;rHjpZFs{yd1C-Kc?|(9D`{I0eMG&7o_DAf5aiU>p4F0M?hTv()R!V{~&pWIi(C8 zHc!m!z#N7T_U|o!{d3ZLW)I=R$p$#f-PzenLBriIR8zswM9)aiP{GK+$kf2l&_F>W zC^bdFBe4W3p=++mz`(-5z@WguzyJyZcfU{uCI-d>ATd~)V1)8Hp%#chX~wD`2F3~j zMrj^)jtPtm3_1)93^Gu;Y>;M0K7nSY2tEU*`CNPgj(i;M+!-(iR2fzZq?Lu?BgFG) zDwwgPRBo^ukn6z=I3WOLu`+OgX#@dIjSOrE0VqofOtUgT^np2GLY{$vK?uoSu-_OM z7*rV;Fw}xHXyFjo#~}_%IOukQ%wZ^wPb|*N%g{?^(DQLN01<{D!WcvtF@WV5(h`%3 z8Hx*wN*HqT(+vwiBv>y41A{S?!NkD8z|6qF@aI1SSR;vp;u$8M1QiE~fx-+X-iRa) zN&_(QB}n32Nak;Vii7M0#R^RQ38*-_`Dc;DL2(IFe-$bYG6xh}F!3));vlnN;#{DF z!vIOo$nKYbii6BSR&NUx2Z6)p@646yJAr5{i^1k(=_2l)qT z6~qE4*#Q+)04ZQ#U;x#|Ab+Ck2bB%zX$NG)3aFqZh=YWo#=%7dq2(`J0LsXKy1yOD Ihf(PI0Tfkd-2eap literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_asinhf.c b/src/openlibm/src/s_asinhf.c new file mode 100644 index 0000000..c9d3694 --- /dev/null +++ b/src/openlibm/src/s_asinhf.c @@ -0,0 +1,49 @@ +/* s_asinhf.c -- float version of s_asinh.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_asinhf.c,v 1.9 2008/02/22 02:30:35 das Exp $"); + +#include + +#include "math_private.h" + +static const float +one = 1.0000000000e+00, /* 0x3F800000 */ +ln2 = 6.9314718246e-01, /* 0x3f317218 */ +huge= 1.0000000000e+30; + +OLM_DLLEXPORT float +asinhf(float x) +{ + float t,w; + int32_t hx,ix; + GET_FLOAT_WORD(hx,x); + ix = hx&0x7fffffff; + if(ix>=0x7f800000) return x+x; /* x is inf or NaN */ + if(ix< 0x31800000) { /* |x|<2**-28 */ + if(huge+x>one) return x; /* return x inexact except 0 */ + } + if(ix>0x4d800000) { /* |x| > 2**28 */ + w = __ieee754_logf(fabsf(x))+ln2; + } else if (ix>0x40000000) { /* 2**28 > |x| > 2.0 */ + t = fabsf(x); + w = __ieee754_logf((float)2.0*t+one/(__ieee754_sqrtf(x*x+one)+t)); + } else { /* 2.0 > |x| > 2**-28 */ + t = x*x; + w =log1pf(fabsf(x)+t/(one+__ieee754_sqrtf(one+t))); + } + if(hx>0) return w; else return -w; +} diff --git a/src/openlibm/src/s_asinhf.c.o b/src/openlibm/src/s_asinhf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..287da42c465315634abbd3b75f5a35dfef97c6f5 GIT binary patch literal 2448 zcmb<-^>JfjWMqH=Mg}_u1P><4z;J;T!FB*M9T@l-_!xrI`0EbyYn^w{K!#U;r@<`P2kOnl~#0L#C=%rEZ(a%RK{uu^`FgNOO$ zLCyv{*Oq~S!GXWc|NsC0V3+VfH4FHFTrFS`9gpfq~SAv#38t=Sw8beKwSOO_5c6>3=9mXK6w^0Ff`ap6dBrsltXa?l!j35 z&dyc}8t#6fnhJ&{dPaJN3PuJ-rUr(F1_~NMsVNE`i6u}8U2{za1{MYe1_cHN29TfK z{X!X-7#I(L#9(pG2<3A^OlJ^*(u`F>42%^5jM6;p91|EB7<3pI7-XPwks!^Ed;-l( zL3|2Kv$*&K9Qin$xHBLOcW$UMtQ1Hq3&Tf{cQNFdv7|&Euqu%2!3;Pd2xhT@{Rd`3 z2{ACu1}2dSX)uSCfdfn<2vFDvA=wM|8v_G_Is*fP074m@rHez{7>BqO4snL!_{8GO zyo@xxWClGSX9Eyn2qKI@gb@Qok|8ZIsW^?HxUi@sjUgvL-LL>mr7Zf5F!6FEaZnn7iO)h3=Rz`nDO4O}J}6dT z>UTiJL3SdWzZXdylrUiGk3z*k=73@gCjJCT9Ap+u{1;RlB!+B02Pi>d@vk;i9HbuE zUzSjDki8%|nE3%vagZ3YJ3;9KWHm@V2!q&QtXEu_TauW>pjTW{1fervtfJJMM7@&K ziV_CBl*E!m2EC->Vg|jUd=N)3xwymxnPX_ipqHGVo129!N7L +#include + +#include "math_private.h" + +static const double atanhi[] = { + 4.63647609000806093515e-01, /* atan(0.5)hi 0x3FDDAC67, 0x0561BB4F */ + 7.85398163397448278999e-01, /* atan(1.0)hi 0x3FE921FB, 0x54442D18 */ + 9.82793723247329054082e-01, /* atan(1.5)hi 0x3FEF730B, 0xD281F69B */ + 1.57079632679489655800e+00, /* atan(inf)hi 0x3FF921FB, 0x54442D18 */ +}; + +static const double atanlo[] = { + 2.26987774529616870924e-17, /* atan(0.5)lo 0x3C7A2B7F, 0x222F65E2 */ + 3.06161699786838301793e-17, /* atan(1.0)lo 0x3C81A626, 0x33145C07 */ + 1.39033110312309984516e-17, /* atan(1.5)lo 0x3C700788, 0x7AF0CBBD */ + 6.12323399573676603587e-17, /* atan(inf)lo 0x3C91A626, 0x33145C07 */ +}; + +static const double aT[] = { + 3.33333333333329318027e-01, /* 0x3FD55555, 0x5555550D */ + -1.99999999998764832476e-01, /* 0xBFC99999, 0x9998EBC4 */ + 1.42857142725034663711e-01, /* 0x3FC24924, 0x920083FF */ + -1.11111104054623557880e-01, /* 0xBFBC71C6, 0xFE231671 */ + 9.09088713343650656196e-02, /* 0x3FB745CD, 0xC54C206E */ + -7.69187620504482999495e-02, /* 0xBFB3B0F2, 0xAF749A6D */ + 6.66107313738753120669e-02, /* 0x3FB10D66, 0xA0D03D51 */ + -5.83357013379057348645e-02, /* 0xBFADDE2D, 0x52DEFD9A */ + 4.97687799461593236017e-02, /* 0x3FA97B4B, 0x24760DEB */ + -3.65315727442169155270e-02, /* 0xBFA2B444, 0x2C6A6C2F */ + 1.62858201153657823623e-02, /* 0x3F90AD3A, 0xE322DA11 */ +}; + + static const double +one = 1.0, +huge = 1.0e300; + +OLM_DLLEXPORT double +atan(double x) +{ + double w,s1,s2,z; + int32_t ix,hx,id; + + GET_HIGH_WORD(hx,x); + ix = hx&0x7fffffff; + if(ix>=0x44100000) { /* if |x| >= 2^66 */ + u_int32_t low; + GET_LOW_WORD(low,x); + if(ix>0x7ff00000|| + (ix==0x7ff00000&&(low!=0))) + return x+x; /* NaN */ + if(hx>0) return atanhi[3]+*(volatile double *)&atanlo[3]; + else return -atanhi[3]-*(volatile double *)&atanlo[3]; + } if (ix < 0x3fdc0000) { /* |x| < 0.4375 */ + if (ix < 0x3e400000) { /* |x| < 2^-27 */ + if(huge+x>one) return x; /* raise inexact */ + } + id = -1; + } else { + x = fabs(x); + if (ix < 0x3ff30000) { /* |x| < 1.1875 */ + if (ix < 0x3fe60000) { /* 7/16 <=|x|<11/16 */ + id = 0; x = (2.0*x-one)/(2.0+x); + } else { /* 11/16<=|x|< 19/16 */ + id = 1; x = (x-one)/(x+one); + } + } else { + if (ix < 0x40038000) { /* |x| < 2.4375 */ + id = 2; x = (x-1.5)/(one+1.5*x); + } else { /* 2.4375 <= |x| < 2^66 */ + id = 3; x = -1.0/x; + } + }} + /* end of argument reduction */ + z = x*x; + w = z*z; + /* break sum from i=0 to 10 aT[i]z**(i+1) into odd and even poly */ + s1 = z*(aT[0]+w*(aT[2]+w*(aT[4]+w*(aT[6]+w*(aT[8]+w*aT[10]))))); + s2 = w*(aT[1]+w*(aT[3]+w*(aT[5]+w*(aT[7]+w*aT[9])))); + if (id<0) return x - x*(s1+s2); + else { + z = atanhi[id] - ((x*(s1+s2) - atanlo[id]) - x); + return (hx<0)? -z:z; + } +} + +#if LDBL_MANT_DIG == 53 +openlibm_weak_reference(atan, atanl); +#endif diff --git a/src/openlibm/src/s_atan.c.o b/src/openlibm/src/s_atan.c.o new file mode 100644 index 0000000000000000000000000000000000000000..4f3bec1e32ab5ce4f2a7a263adfe4dbb40416000 GIT binary patch literal 4176 zcmb<-^>JfjWMqH=Mg}_u1P><4z!1QLU^{@B4h#Ye{0wOx{B;LH)A%)B1bcKI_Bi-j zq4RFz)Bpef*LyU-;b{E(|3AM=nO5Up28Ivy<$V0DJd6wstq1s9SQr@?KJiDqP2<-% z>d}0JBRcjlzq|_r14zehd;WG6MhM&9j=${(0|P@E|NGlJ{{R2~KaF4Ga2mhH)ld8a zydZac;*Y$V#;@_{6MrNKpZUZe0TU;ced-gxfGE_=E1&pdNMuKx`otf3w)w|@{+4SD zAm7ED{=^@1_7i{1!PeXSonm0ehqHn#fcu!C^)`QB2UxWLSmqOd1ek`Zn1JwR#ECS1 zeX!T~+ur^A|NrIDfB*kacmXmF6lkC9%ZowuQ+xjQ>)-&>c=3r}Ko%r#c;FL%#0!|w zpZH^RL871d<3K9F*1cT$@Be>(c?SlBeK7aL9DErKmTZ7%ig^if8z|-uPiXx6zn{eriY9$T%QVE>x8OvSr;rG237g#~H68}0KHe2$)V-ERNCnPHNO z=OKIEP!PCkub-2pfYo9x-Wc{ZNo9zq5l>Z$o++%;_^^BP_XP$(b z54Dwn0UVcLp1ZTNm4b%5U#O;np^2W6o}q$~fsv_!p`n3-Mo?;sf=6NrR6^HWlYxPS zfq_ARfq?;(YTW%o8JHLt4}io#Q2{cK5z6NTaTpjFM4&WdRS*MXg#e>84?D*MMg|5S z1_lNhsN5n@dU4|uXk&8alW1lR=2OVx;*)UX6L93?aN}lr1?RYM$H3W6+)Ojz95-&L zQ5Y1+T`UYAv8DoMEF~Qm0|Nsi*mn@4Kz@a=7#Nt5#9?BBU#1asIJG{7{1hyyd( z7(BoIPZX&P+}ICW&@MR z#C$M^je!G9BZwso3=Bd@=@y)K7#J8HFA!dQ~fDHtjX9(5}Ccq{b zf=RG3U`<9~mocOzCKWR9Ph@>8r`e5Q~ zk;Fk^2ov9lBn~R0VB$xS#6e{MO#C8}IH-_;iQh#M2Q`gg;xCcJL6tR3{40_;9|Hpe zOdQtq0{NF8N!$oja4|sq3rc%1^*%`ApmG;hzJ?%)gUTeB`V=H_Atdt)ki>wY7Jb9Sp9}j`!TG88VCv>xS`Ot7&6}ysvnfsk;N6D`cEJWLfr}y zf`x+{4*egX`q9H1#)r`%Q2prjG`Qi&z`y`$w}5PfU|9IU=vb(Jh%AEC2SqA^3unRf z!31&{7#KkH0DAZtK=q@$3+8W_eo%c6G80{Y0#rYGy^gLQ)UXCAMNfY#K$Qn5{Xs1P zr9Y4mOh2d$14&`C8zg=LWGF~KG#)^8h&)pK!SsXbG^i4gHaLC&3KRwghIMce2m@pv bgasi%WfwO62SAQxU|@i>Zy;(xB)Wb8D6;YZ literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_atanf.c b/src/openlibm/src/s_atanf.c new file mode 100644 index 0000000..cdba6a3 --- /dev/null +++ b/src/openlibm/src/s_atanf.c @@ -0,0 +1,93 @@ +/* s_atanf.c -- float version of s_atan.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_atanf.c,v 1.10 2008/08/01 01:24:25 das Exp $"); + +#include + +#include "math_private.h" + +static const float atanhi[] = { + 4.6364760399e-01, /* atan(0.5)hi 0x3eed6338 */ + 7.8539812565e-01, /* atan(1.0)hi 0x3f490fda */ + 9.8279368877e-01, /* atan(1.5)hi 0x3f7b985e */ + 1.5707962513e+00, /* atan(inf)hi 0x3fc90fda */ +}; + +static const float atanlo[] = { + 5.0121582440e-09, /* atan(0.5)lo 0x31ac3769 */ + 3.7748947079e-08, /* atan(1.0)lo 0x33222168 */ + 3.4473217170e-08, /* atan(1.5)lo 0x33140fb4 */ + 7.5497894159e-08, /* atan(inf)lo 0x33a22168 */ +}; + +static const float aT[] = { + 3.3333328366e-01, + -1.9999158382e-01, + 1.4253635705e-01, + -1.0648017377e-01, + 6.1687607318e-02, +}; + +static const float +one = 1.0, +huge = 1.0e30; + +OLM_DLLEXPORT float +atanf(float x) +{ + float w,s1,s2,z; + int32_t ix,hx,id; + + GET_FLOAT_WORD(hx,x); + ix = hx&0x7fffffff; + if(ix>=0x4c800000) { /* if |x| >= 2**26 */ + if(ix>0x7f800000) + return x+x; /* NaN */ + if(hx>0) return atanhi[3]+*(volatile float *)&atanlo[3]; + else return -atanhi[3]-*(volatile float *)&atanlo[3]; + } if (ix < 0x3ee00000) { /* |x| < 0.4375 */ + if (ix < 0x39800000) { /* |x| < 2**-12 */ + if(huge+x>one) return x; /* raise inexact */ + } + id = -1; + } else { + x = fabsf(x); + if (ix < 0x3f980000) { /* |x| < 1.1875 */ + if (ix < 0x3f300000) { /* 7/16 <=|x|<11/16 */ + id = 0; x = ((float)2.0*x-one)/((float)2.0+x); + } else { /* 11/16<=|x|< 19/16 */ + id = 1; x = (x-one)/(x+one); + } + } else { + if (ix < 0x401c0000) { /* |x| < 2.4375 */ + id = 2; x = (x-(float)1.5)/(one+(float)1.5*x); + } else { /* 2.4375 <= |x| < 2**26 */ + id = 3; x = -(float)1.0/x; + } + }} + /* end of argument reduction */ + z = x*x; + w = z*z; + /* break sum from i=0 to 10 aT[i]z**(i+1) into odd and even poly */ + s1 = z*(aT[0]+w*(aT[2]+w*aT[4])); + s2 = w*(aT[1]+w*aT[3]); + if (id<0) return x - x*(s1+s2); + else { + z = atanhi[id] - ((x*(s1+s2) - atanlo[id]) - x); + return (hx<0)? -z:z; + } +} diff --git a/src/openlibm/src/s_atanf.c.o b/src/openlibm/src/s_atanf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..7156ad00c46fb8ac0165e3a235039d026bd702de GIT binary patch literal 3768 zcmb<-^>JfjWMqH=Mg}_u1P><4z_5c0!FB*M9T)@{_!&ae`0I`acfM|X{Qv*|dXMHe z9F4#K|F8EcGi&_Kz|c_7-@c21fuZ#+f1eN|1H)&20a1|V&-@W!+N1dh2fxOl=-9*j z@+}|<29WOicKq#g7#P6pddqT&&-?Tgb8n-_4 zM}qL_&-@W!HJ|w-k=dsZ_D5d+%pU`HLv-wCevnASDX^K5CqDDXT;$g{ba(>4#s!cg zKl4Xih>it`@XI%V-0}iMfE+vBzC0R4>)Z3Ut1~h%@N3-o%rBq|l1A7TapN<81S>== zMixTH-FWSlHsLeB08|_jG9b%9u8Fw-vMg-^$Y^N?{@F)`xgI6dyshCjB0z3np^yy_P6*??mzX(vyg$I z!JdJE!GVF{fIS04!+zB@HMYE81?^U@T4m=hbZhU7Q$BW3JHYV^Wiv3iJ3Ct`Xt?`@ zYAP6-=o#r5Di|3UnHm@x8YpN4rKTu&B$hxWbj>vx7+4q>7!(*77(l`4?ib3y#K3p} zBnHbcC)Ld*7$ek<< zA5p>_rj8j)$pA8o5$s!tDgg)uCYh1M!2%2n3_@TA8v_rRMiAm)CL4nam_`tgFkoZQ zKnQ_ZN??+W!2(Pp2#7j11{;JBn573M*+2;Z%z_anUZRr zfSK%I5}8N?bJ!RRz%+u$0W;YckmCs?R0tv%*cf2x5zJ*^U?>AK*cc?hG=iuGGuhy2 z6wGB{U;t$vA*6HyPP+^Y3~dYy7yC66ZrwuY)Ac zk0fq_B#!J~7bJ0z-5@`MoZ^Ed4oZtKdkc`n1(D3JKoSR)Au#m~NaD!x(vKt#vJ<9$ z8Im}1IB!A{M-JzGNaD!hd zIqFE_$l+{*L);xn98|`_%=bqU2jy*;IH>Ld#Scgtgh6aD)+?^eElEsb&?_z}g3uW- zR#9qBqFzaAMG1pmN@7VOgI-c`F@s)FK7<3I^^%KAOkjc_j-eTYUUGhJZfaf$gI->K zNvfW^U#M z5~>U&1jb8H0v#*_CO~F@8BhXLpMcCHSHB_Dest?LKn2kKi_W)%>IdaTsFT3d0jPc- zFb_e1@;-pps0p=7beUQ0M(D~E>K*-6@hw0Q2WvKH$e4QAS-5Iz^L~@^(-hXG14EX z@M2(q*Vmx*2P(H<_QTR2$Uo?IgRJ}kwZ8)@2`c*~k?e=*2bG;rr66r^+yKo`J#Y~S Z17shB1tCFYJ2w3qQ1|ykl)*`K{QwtvdEEd2 literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_atanl.c b/src/openlibm/src/s_atanl.c new file mode 100644 index 0000000..4edfa5a --- /dev/null +++ b/src/openlibm/src/s_atanl.c @@ -0,0 +1,85 @@ +/* @(#)s_atan.c 5.1 93/09/24 */ +/* FreeBSD: head/lib/msun/src/s_atan.c 176451 2008-02-22 02:30:36Z das */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_atanl.c,v 1.1 2008/07/31 22:41:26 das Exp $"); + +/* + * See comments in s_atan.c. + * Converted to long double by David Schultz . + */ + +#include +#include + +#include "invtrig.h" +#include "math_private.h" + +static const long double +one = 1.0, +huge = 1.0e300; + +OLM_DLLEXPORT long double +atanl(long double x) +{ + union IEEEl2bits u; + long double w,s1,s2,z; + int id; + int16_t expsign, expt; + int32_t expman; + + u.e = x; + expsign = u.xbits.expsign; + expt = expsign & 0x7fff; + if(expt >= ATAN_CONST) { /* if |x| is large, atan(x)~=pi/2 */ + if(expt == BIAS + LDBL_MAX_EXP && + ((u.bits.manh&~LDBL_NBIT)|u.bits.manl)!=0) + return x+x; /* NaN */ + if(expsign>0) return atanhi[3]+atanlo[3]; + else return -atanhi[3]-atanlo[3]; + } + /* Extract the exponent and the first few bits of the mantissa. */ + /* XXX There should be a more convenient way to do this. */ + expman = (expt << 8) | ((u.bits.manh >> (MANH_SIZE - 9)) & 0xff); + if (expman < ((BIAS - 2) << 8) + 0xc0) { /* |x| < 0.4375 */ + if (expt < ATAN_LINEAR) { /* if |x| is small, atanl(x)~=x */ + if(huge+x>one) return x; /* raise inexact */ + } + id = -1; + } else { + x = fabsl(x); + if (expman < (BIAS << 8) + 0x30) { /* |x| < 1.1875 */ + if (expman < ((BIAS - 1) << 8) + 0x60) { /* 7/16 <=|x|<11/16 */ + id = 0; x = (2.0*x-one)/(2.0+x); + } else { /* 11/16<=|x|< 19/16 */ + id = 1; x = (x-one)/(x+one); + } + } else { + if (expman < ((BIAS + 1) << 8) + 0x38) { /* |x| < 2.4375 */ + id = 2; x = (x-1.5)/(one+1.5*x); + } else { /* 2.4375 <= |x| < 2^ATAN_CONST */ + id = 3; x = -1.0/x; + } + }} + /* end of argument reduction */ + z = x*x; + w = z*z; + /* break sum aT[i]z**(i+1) into odd and even poly */ + s1 = z*T_even(w); + s2 = w*T_odd(w); + if (id<0) return x - x*(s1+s2); + else { + z = atanhi[id] - ((x*(s1+s2) - atanlo[id]) - x); + return (expsign<0)? -z:z; + } +} diff --git a/src/openlibm/src/s_atanl.c.o b/src/openlibm/src/s_atanl.c.o new file mode 100644 index 0000000000000000000000000000000000000000..3fd280c10532b60de211f0792c2ba054d1524b6d GIT binary patch literal 2616 zcmb<-^>JfjWMqH=Mg}_u1P><4z)-=4U^{@B4h;MZd<>z%9?fq!Ji2pKG&*0Tss67| zv$c09vrM!7U(es7&d9*v(aj1{emlbe!Afg=%ilMNk%8gfL67Dm9MQ3d)A;3EK*|_A zx?@xn__tp;_=v;f;A?aKZMQiuH~!xL*PemDU4fB-AY7|NsBy1E}x$LsS$zIxlz}e4(KF|NsAb z&I|l42mV3)b>qOxEC2rg2l*Fd%*_`!58eTX>iv&*Z}7MM`1k++%gtZ~4F5}1G(h+T z$li#k#^3t??HS5F8-K_D0|j9#0|Ud&1BRDw9K8AB-piXOZ-9-t_w#m*io(mC|Nj5K zc@pBPdk>>y4};v*e1zlPOE4Q0bPSEZ%^4gR$~A6+HSS^pnRoEU!<#4Xox1tr-l2OR z!6xPZ`~N?UU*3g*;pU57%pf%npfaIgXF7nyLCNeUL@!LA`M>}FK@MkNm{ZEoVe`bi zj)8%}fq~(GJ%hWmvz3B|yI-iLf}x3?k)EM~k%5t^fuW&+f<{nkih@UC2~TS<3M~75W&E}z*rT;z*r%`D9yvpF@ceR zA%=m0K?W)p1oEvTpFkUvBcDVwvkRX>9T%U3BcFgHABPt=(QDC zkx!wLi%-HCtjdMk1=# zbE=@?pdpjTW{1fervtfJJMM7@&KiV_CBl*E!m2EC->Vg|jUd=N)3xwymvnPbABmzJ=2_7o--IR5Iv+%}&jTPb*5yO$9rIG6Lj3 zkk`>uHl%K1V1T7tm@VjORGI-&M!?j=)PV~OQ1K5H-~p8h(6j*(k^m753=C>eaZubr zg}~G#l)wfHfeDaX!3-#&12vOe{f1Ecg`noas2NcEL1`H#2BKkn7;T3`{{kHPL1_+T z4vhAO>NfxhBH==Xas@kEw~`mugH8s1_lOf`aggQ5e5c^ KHe|(E^aB8@Pw&D2 literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_cabs.c b/src/openlibm/src/s_cabs.c new file mode 100644 index 0000000..481632a --- /dev/null +++ b/src/openlibm/src/s_cabs.c @@ -0,0 +1,32 @@ +/* $OpenBSD: s_cabs.c,v 1.6 2013/07/03 04:46:36 espie Exp $ */ +/* + * Copyright (c) 2008 Martynas Venckus + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include + +#include "math_private.h" + +double +cabs(double complex z) +{ + return hypot(__real__ z, __imag__ z); +} + +#if LDBL_MANT_DIG == DBL_MANT_DIG +openlibm_strong_reference(cabs, cabsl); +#endif /* LDBL_MANT_DIG == DBL_MANT_DIG */ diff --git a/src/openlibm/src/s_cabsf.c b/src/openlibm/src/s_cabsf.c new file mode 100644 index 0000000..8d9bd96 --- /dev/null +++ b/src/openlibm/src/s_cabsf.c @@ -0,0 +1,25 @@ +/* $OpenBSD: s_cabsf.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */ +/* + * Copyright (c) 2008 Martynas Venckus + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +float +cabsf(float complex z) +{ + return hypotf(__real__ z, __imag__ z); +} diff --git a/src/openlibm/src/s_cabsl.c b/src/openlibm/src/s_cabsl.c new file mode 100644 index 0000000..847ded7 --- /dev/null +++ b/src/openlibm/src/s_cabsl.c @@ -0,0 +1,26 @@ +/* $OpenBSD: s_cabsl.c,v 1.1 2011/07/08 19:25:31 martynas Exp $ */ + +/* + * Copyright (c) 2011 Martynas Venckus + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +long double +cabsl(long double complex z) +{ + return hypotl(__real__ z, __imag__ z); +} diff --git a/src/openlibm/src/s_cacos.c b/src/openlibm/src/s_cacos.c new file mode 100644 index 0000000..e29717b --- /dev/null +++ b/src/openlibm/src/s_cacos.c @@ -0,0 +1,67 @@ +/* $OpenBSD: s_cacos.c,v 1.6 2013/07/03 04:46:36 espie Exp $ */ +/* + * Copyright (c) 2008 Stephen L. Moshier + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* cacos() + * + * Complex circular arc cosine + * + * + * + * SYNOPSIS: + * + * double complex cacos(); + * double complex z, w; + * + * w = cacos (z); + * + * + * + * DESCRIPTION: + * + * + * w = arccos z = PI/2 - arcsin z. + * + * + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * DEC -10,+10 5200 1.6e-15 2.8e-16 + * IEEE -10,+10 30000 1.8e-14 2.2e-15 + */ + +#include +#include +#include + +#include "math_private.h" + +double complex +cacos(double complex z) +{ + double complex w; + + w = casin (z); + w = (M_PI_2 - creal (w)) - cimag (w) * I; + return (w); +} + +#if LDBL_MANT_DIG == DBL_MANT_DIG +openlibm_strong_reference(cacos, cacosl); +#endif /* LDBL_MANT_DIG == DBL_MANT_DIG */ diff --git a/src/openlibm/src/s_cacos.c.o b/src/openlibm/src/s_cacos.c.o new file mode 100644 index 0000000000000000000000000000000000000000..d8ed85e447f278ecbd109a5ae1815ec2627bae75 GIT binary patch literal 1840 zcmb<-^>JfjWMqH=Mg}_u1P><4z)--9U^{@B4h;MZd<-7VZ!}(j_@DR%eN+TK@e8`B zNI(SyVpJqP@e9C&Inwww4#T8ER6yJlpZEn>A-ZD@rt!Z&`H4UBR2qM{C`ins`H03R zevr7vslyVwE+M}af7*j27#J8Dpfm%6yR);Ef`+?asHTFUiJp<3p@NZtk*R^9p@D)% zP-=>TM`8(7Lf2fAfq{jAfkA^rCN>N*pM~M$e{6EhSVEi|tPtc%Fau5qfLUx{ z5}5#nm=KaVU^g)^Fi0~nFhKMmt7c$O#38PZL!6;FJ~=TtzgRDsLC?q807MuufJGRR z6N@wR7?Lw{6Vn-zi&7JFKsLc#4hmb4YybR*05Omx10){U85kH~;)Y1#pg@F)J43~p z7#J8pNf0I;jwBAU111iNTaXk;JqUx?V60bMnOl;W#GqGPQUswhV639loJ75n)QS=Y zy_Cd~LhcCgVF;i zykP2K>LQ?lRRI;?VPF8KCQw{}gd{)&0|SE^R2&o+P$4k20!(5OAh#lm>M$@cfXpOU zKPa7m%oIX4l!1W(Wihd z6~u4OP@k`O50K%)yL%;>9qtNvO04`RoYybcN literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_cacosf.c b/src/openlibm/src/s_cacosf.c new file mode 100644 index 0000000..f3c0eb9 --- /dev/null +++ b/src/openlibm/src/s_cacosf.c @@ -0,0 +1,60 @@ +/* $OpenBSD: s_cacosf.c,v 1.2 2011/07/20 19:28:33 martynas Exp $ */ +/* + * Copyright (c) 2008 Stephen L. Moshier + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* cacosf() + * + * Complex circular arc cosine + * + * + * + * SYNOPSIS: + * + * void cacosf(); + * cmplxf z, w; + * + * cacosf( &z, &w ); + * + * + * + * DESCRIPTION: + * + * + * w = arccos z = PI/2 - arcsin z. + * + * + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE -10,+10 30000 9.2e-6 1.2e-6 + * + */ + +#include +#include + +float complex +cacosf(float complex z) +{ + float complex w; + + w = casinf( z ); + w = ((float)M_PI_2 - crealf (w)) - cimagf (w) * I; + return (w); +} diff --git a/src/openlibm/src/s_cacosf.c.o b/src/openlibm/src/s_cacosf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..a135e6722520c9811b8dc1d89305db15e251d1b1 GIT binary patch literal 1928 zcmb<-^>JfjWMqH=Mg}_u1P><4z;J>Y!FB*M9T@l-_!!bW`0EaMG{3R%IQT;0GrypV zibki4iq2>LIu{j<7a)aT6<`?!xEh{L7Znw-8ih_56%Mev&-?;DDjc8r1!7cqz{*)Z z^9%Z@$b9A(j8TyQE0%yM3{hd>*EsQ+Uw{>4!)N}OgK7NlPk!c)JjEX_3K0?vQ4s-2 zfQ=FWYZvfnK4Nj0f#Ej)NqdkYC~kn#5X#-z*-Amf-7i#A!O%p{NY7Bg$iT?dz|hb@ zK_e(NMZqJn1S+9xuF1f_!oa|wz`(!&a)`TMC<7A%;{lKuEDRZ;d`^hz3?fjPu_}mx zu|j}RnuncZ0wV)hTm~w)2}FDHIWVo@;{Y+SVUYPO3?KhvlVipbgFIk`AXkDJa6%Bw zVgr-Ngct(@gAkHAU^g)^Fvv16FbE(kgtAp|h->2zXDE(OPE5`(PSZab<2vViJR1aY+$`&VaFsQgagZ zN>VFI81zySOA;CMl8TEN^osI99KGb?5))*Op&5f-a(-@ZYF-J0US57ls-C-FsBUpd zVsbW=pPpB$S5TB+kXlqy$)E=|JT)Uettc@!73>m<2$26kX$lmk$Ob|3Is*eN{$XLY}}ET}Ndc!p4@ey}7GVGmP?BnD!l3xkpnDBnP%3#0^$9iR%)-31D3umUJi3$-6z ze*uyDLFoe&mgwn60~(>QbOK60T+p}%Sq&2hS%YpjNPYoGf`NhI28hGJz`zSFt6}bk o=?9h1P^+LSAyfs_P$LKzPC|`^^Fie(HvJAz!FISx2m@U|0Mt&#!vFvP literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_cacosh.c b/src/openlibm/src/s_cacosh.c new file mode 100644 index 0000000..f16c14c --- /dev/null +++ b/src/openlibm/src/s_cacosh.c @@ -0,0 +1,62 @@ +/* $OpenBSD: s_cacosh.c,v 1.6 2013/07/03 04:46:36 espie Exp $ */ +/* + * Copyright (c) 2008 Stephen L. Moshier + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* cacosh + * + * Complex inverse hyperbolic cosine + * + * + * + * SYNOPSIS: + * + * double complex cacosh(); + * double complex z, w; + * + * w = cacosh (z); + * + * + * + * DESCRIPTION: + * + * acosh z = i acos z . + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE -10,+10 30000 1.6e-14 2.1e-15 + * + */ + +#include +#include +#include + +#include "math_private.h" + +double complex +cacosh(double complex z) +{ + double complex w; + + w = I * cacos (z); + return (w); +} + +#if LDBL_MANT_DIG == DBL_MANT_DIG +openlibm_strong_reference(cacosh, cacoshl); +#endif /* LDBL_MANT_DIG == DBL_MANT_DIG */ diff --git a/src/openlibm/src/s_cacosh.c.o b/src/openlibm/src/s_cacosh.c.o new file mode 100644 index 0000000000000000000000000000000000000000..bef1c931665c194aadac014171743f62bf24aa38 GIT binary patch literal 1632 zcmb<-^>JfjWMqH=Mg}_u1P><4!0>aRh9}>jxlV z1_p)?_6+XM&Q=N;Y76t|e z1qKENRt5$JcfU{uCI-d>ATgL<7@>Sls0|`enz1T~fw4k>QJROHV*(=sgA4-%gQWdI zgbSZQJ{KQ{BR7bH8-wg&VfgqTn+j$uA<6?*2y!i$0Vf0*7#M_*)Pvo?z`!8Ez`!5? zSA}56;Sgsij!#ZZ&M(f;OJ>mXaW-Ut@E{aJe0*+cPD-*dB)mYTfx-&pnm_*`zyc)5 zz`y{Cc4h_!2AH@fR2-z94M`jn_8=*cdJqP&!C0@jGPfi#i9xTpqzFQ1z*t48If;5D zsTCy*dMSw|i41y4#l;MIMfo6(UUG4X1%qC4er|4RUI~L!_@P?TSgT2xZWpa(WCH6uQ)C^0t`Y&R7MkiS523-T+nagaQ~zyOOMm>hZ>Ni#sw zCQLm{9XMba7#KXD0-)ptvWEl82gNstsm8znP7RO*N51#>@)c8BVR$;0U5Fa{b8 z(+3j{XJBApho)ng7>GUrA{ZDL(A@=dH&mJ-A8J2Jnr2{N_yJV_%O_ASIILl85S@i1 z{ym@u!r~be|Ddu7WQ@JG ZkT6sjE&?i#u<1{LI;s+`62d^&4*-dGk_`X= literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_cacoshf.c b/src/openlibm/src/s_cacoshf.c new file mode 100644 index 0000000..f3c40ae --- /dev/null +++ b/src/openlibm/src/s_cacoshf.c @@ -0,0 +1,55 @@ +/* $OpenBSD: s_cacoshf.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */ +/* + * Copyright (c) 2008 Stephen L. Moshier + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* cacoshf + * + * Complex inverse hyperbolic cosine + * + * + * + * SYNOPSIS: + * + * float complex cacoshf(); + * float complex z, w; + * + * w = cacoshf (z); + * + * + * + * DESCRIPTION: + * + * acosh z = i acos z . + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE -10,+10 30000 1.6e-14 2.1e-15 + * + */ + +#include +#include + +float complex +cacoshf(float complex z) +{ + float complex w; + + w = I * cacosf (z); + return (w); +} diff --git a/src/openlibm/src/s_cacoshf.c.o b/src/openlibm/src/s_cacoshf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..d81bd895b0c773ae6b4b394c8ac3e6d693b3a0e0 GIT binary patch literal 1696 zcmb<-^>JfjWMqH=Mg}_u1P><4z@Wg4U^{@B4h(z@ybNg`{B;LBn%_ux9DJehnP1RF zg`?9&h37MWor?;`3y{Jz{`?1N{P{1^_}?Gk*SNxe>}}|0{>TfT`6G{h=8w7hnLpwP zzutu^(a-#XA}U}LSU&UDv8Z@7ACWlxnO{H_WC*{;ku?7Im(uw2&%zA-kj9^Xf&bXI z&@}%1W3LZ_R53KzGq^iDTPbL``-N&M7@FuA=@}{*85o%w7#bQVXauFED0n26KqYj| zH5nLK7#J877#J8>85kJc{X!X-7#I(L#9(2-2<3Bv&1YZ`fzpgsK@5x)0*ul;>>Lvq z85m?3AQ&Xw2_iiC6qrJ}_&6N7K|GuoWDg6&$N$(AFk^`cUa&%tYrzaSA;iGIAcUkI z>;?t~1}O#x1_8J#1Va&rI74xKa$<6RaYmY6GJ~FvvmpbN3!&2(;^T8mbBdFVp+?C; zX;7GfT=nNa1SCVnnHU%tKuHHCUJMlnsb^zgV1S8(;s7KCQV+r)HW=#_SLT)^CNbz0 zmlQ$h3>d2@H78N8B(S?8r(2pNT4z>Frd2&6jlgD3=H{D`_c6qKrOOBRtybm zWT7k^@!tV85Ejp%_y?6yF#BQRAZwsXk&R`@07)<~Fsy)z@<8oD*AFriJ?=qT1fYg$ dfjCGQYAjqt5Sstt0#L>RsQyYQA4Z|;2LQIjsTlwO literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_cacoshl.c b/src/openlibm/src/s_cacoshl.c new file mode 100644 index 0000000..5e5ae31 --- /dev/null +++ b/src/openlibm/src/s_cacoshl.c @@ -0,0 +1,56 @@ +/* $OpenBSD: s_cacoshl.c,v 1.1 2011/07/08 19:25:31 martynas Exp $ */ + +/* + * Copyright (c) 2008 Stephen L. Moshier + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* cacoshl + * + * Complex inverse hyperbolic cosine + * + * + * + * SYNOPSIS: + * + * long double complex cacoshl(); + * long double complex z, w; + * + * w = cacoshl (z); + * + * + * + * DESCRIPTION: + * + * acosh z = i acos z . + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE -10,+10 30000 1.6e-14 2.1e-15 + * + */ + +#include +#include + +long double complex +cacoshl(long double complex z) +{ + long double complex w; + + w = I * cacosl(z); + return (w); +} diff --git a/src/openlibm/src/s_cacoshl.c.o b/src/openlibm/src/s_cacoshl.c.o new file mode 100644 index 0000000000000000000000000000000000000000..cb02fcdaa5c050d2c7fdebd6489b1b0c4367a4f0 GIT binary patch literal 1560 zcmb<-^>JfjWMqH=Mg}_u1P><4z;J^J!FB*M9T<2Sco;mI-*EgdQPDugFF^7h%|{e& z9=Q4L&Z(QHZaltu_{QlQhi<>D;=OzO?(MrbJerSi+&p>s?v1-QZl3hm0n)(0z|fHK z-=2XXz@zz%!R;Cqg_|dD*Qf~Gwow5ac=M!3^AU&FM;Y9movjo!-2Fl|6%0-EjPwi@ zj0}uS4Gawp6f}ZTQxrTBOP~_E=9*BG8CVz?7!(*77+4t?7~K6r8JHLt4}ipAer1I6 znV}j)pfqDu5Cda{0HZVyJI4e@1_l!b1_l|ZToH(N;S+G-lW^fvaN*N%;WO~$6NuyD z<8bB<<&$s(2?j*)34qk$z##is7(V{TCe4f`CU_Yb7=)0-!ERt+U=U?sV8CV%$gSAK z8H(eR6O;3cGjjBj8K5i(ox>0xpIe$!k!%cd6UbZ;4GJp|{_`IK(m;X?4B&7Dg(*xN z6viMaP;vob5F3p3iYs$V5|bG8ic5+hbOwx7l$w*MSCU#$!l0LuSdz$~msDKLpqHGV zo12W7;OdB50!>f58*6S223AJ)Qf?E zft`VY0UBH|VFqwfz`($O?kh+7#dc{La{jFF92#FES^B| z2eKQ4LHc3hAZwsXLBepH0g_-~V3+_E;bvf90L2lyeom-3R2iK50oAVx7lAOK!VnGv T1A`zA{TWb4<-k=!80h)|?QWyn literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_cacosl.c b/src/openlibm/src/s_cacosl.c new file mode 100644 index 0000000..8a7b8a1 --- /dev/null +++ b/src/openlibm/src/s_cacosl.c @@ -0,0 +1,63 @@ +/* $OpenBSD: s_cacosl.c,v 1.3 2011/07/20 21:02:51 martynas Exp $ */ + +/* + * Copyright (c) 2008 Stephen L. Moshier + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* cacosl() + * + * Complex circular arc cosine + * + * + * + * SYNOPSIS: + * + * long double complex cacosl(); + * long double complex z, w; + * + * w = cacosl( z ); + * + * + * + * DESCRIPTION: + * + * + * w = arccos z = PI/2 - arcsin z. + * + * + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * DEC -10,+10 5200 1.6e-15 2.8e-16 + * IEEE -10,+10 30000 1.8e-14 2.2e-15 + */ + +#include +#include + +static const long double PIO2L = 1.570796326794896619231321691639751442098585L; + +long double complex +cacosl(long double complex z) +{ + long double complex w; + + w = casinl(z); + w = (PIO2L - creall(w)) - cimagl(w) * I; + return (w); +} diff --git a/src/openlibm/src/s_cacosl.c.o b/src/openlibm/src/s_cacosl.c.o new file mode 100644 index 0000000000000000000000000000000000000000..a79235023a86fa445afea0bcdb53c5f19ce00ada GIT binary patch literal 1736 zcmb<-^>JfjWMqH=Mg}_u1P><4z~I4*U^{@B4h(z@ybK=AZ!G?os6-&+7a;kYCvP6O zU85p!yGF&~=7HNbDz|G?48StCYg80&=cqVuv-`y7$g`N7zE&|5Da-7;%Yd=8H(eR z6O;3cbM%rK^n9ER7$7``rFsQL`30#(C6x?%VDnNl;?s%}b5p^VQ%->V1xgd3ut7ErlGhj*VDSo* zLyuc&Xqdy)!_);p11SM2z|Ft_PA#y+2}&m*DNy`_><5K4h!4Z7U<@=Gq!w97hk=0s zWG1=#4WaH5LN=6vfnfubkM3U>A4Y?U1CW~xpz2}N0Vo5O{-9iN7=YLyJs{cxYCnjL zjNc=3kk~MNFrf$r1_n_2g$6fFnBfDIh3+m;SV5)0Q~}g}bo~lYi_qg0U4J%?_}>6E z5Ejp%_~(Si706 + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_carg.c,v 1.1 2007/12/12 23:43:51 das Exp $"); + +#include +#include + +#include "math_private.h" + +OLM_DLLEXPORT double +carg(double complex z) +{ + + return (atan2(cimag(z), creal(z))); +} diff --git a/src/openlibm/src/s_carg.c.o b/src/openlibm/src/s_carg.c.o new file mode 100644 index 0000000000000000000000000000000000000000..39f730a8c4789bc811b216d82488fb4b625a5c50 GIT binary patch literal 1528 zcmb<-^>JfjWMqH=Mg}_u1P><4z_5b}!FB*M9T<2Sco>2`n%@X~;uqvm`NS{iqQdb4 zB=?D5AVh`Z6TbkDN}30M-QhHTjYD7wkLDu+X&(G}r=wqj)G@d_J6kDexch}_Dj1sR z8R;1+7#SFu8W6c`v7SQ!`?-2Flsm>3ujfW%;K zW`y!N!KxV;M4&WdRS*MXg#e>84?D*MMg|5M1_%a8+kyy3K7nQ?7e0ktJ^?pA4v+{| z46=uX;p2a7lFV2_j*EeTK?q44Y!?Fq13v=;g8&voL~)2q;}B;kj!#Z3O4mzf08tFd zMX8B749S_fiRlc9C5d@PFe?P13{Y5s@Spz>poJt33R9T4C6YKB0|Nt092E8-DNu3% zVGtXP^@=NVOA?b9^omQ0Aan+dRg{{Os8^C&QNo~?l30?+pqEr!%%GQ?pPQSSSHhr| zmtT^q=k6D(TU?TuoDJot=auRe6y+DB7L`;o=z&d0&4^DcO3Y0KTSqAY@&_m`L4HFv z3zD`O7+~=PlS7XyP<(*G5vCrd?ghwD1_lNXr~oMbK|-(;B>@#zV_*QM3T7xDM%BU? zXf((SWFZ{}1_qFsN7w%VEX%-P0i|ISy8c)O1_o^LX8<)27Ehq~ z1L*}}kXbNskbj^`LBen>0g_-~U|0ba;bvf90L2lyeo*-Y5{D{-QwN~>72zTf22>cr XVPIeY + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_cargf.c,v 1.1 2007/12/12 23:43:51 das Exp $"); + +#include +#include + +#include "math_private.h" + +OLM_DLLEXPORT float +cargf(float complex z) +{ + + return (atan2f(cimagf(z), crealf(z))); +} diff --git a/src/openlibm/src/s_cargf.c.o b/src/openlibm/src/s_cargf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..5ea776f1ee81d667a65dfed48fa1bb8c3cabca29 GIT binary patch literal 1560 zcmb<-^>JfjWMqH=Mg}_u1P><4z;J^J!FB*M9T<2Sco@<=`0EaMG{4dCIQT;0GrypV zibSW2iVT>=^O?U6!smDa((;*KAV!7fGrvHH3I|vL%V&PU7!`rf{DL7WB4EV=FoixU zEFR5AG+u)AF}OQBTPbL``-N&M7@FuA=@}{*85o%w7#bQVXauFED0n26KqYj|HNiR< zSQr=>6c`v7SQ!`?-2Flsm>3ujfW%;aV}$ZKA<7v|M?FAfk@(@ zu!M;xAc?avFfhQxL17M(0wos^2C>0duedU|Br%CWuehWLLTA8OMX5Q7dL^k9B@B8g zi6w~)dP&8_40_4=xw)x%B@B9b`6a1(?tY=V#U+W!*-(CZUa4L|QGP*cQAs6(9@vD` zjQF&o#N1S{b(9hye}Li=_ytL+LB*Lt93;F1iH*zzxfPkO!@$4*GLu~WhEV$rkPT&EV1U`Lk0uVYA4Xe2 z^`j|cxQs3U<-_zrxeQ(m3=HfH3=GiVf(bL+fU?lt1@bFY3QQ$I?MK(o0kw#b{#YFG z7XUR77Ehq~1KAD2Ad6w*AZwsXLBeos0g_-~U|0ba0p)*C9HHw6l}jLTs4_V90IDC9 ZKH!2-zasNN + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_cargl.c,v 1.1 2008/07/31 22:41:26 das Exp $"); + +#include +#include + +#include "math_private.h" + +OLM_DLLEXPORT long double +cargl(long double complex z) +{ + + return (atan2l(cimagl(z), creall(z))); +} diff --git a/src/openlibm/src/s_cargl.c.o b/src/openlibm/src/s_cargl.c.o new file mode 100644 index 0000000000000000000000000000000000000000..395bde7e8c71fa37b7300ac429ee869e104ad6b3 GIT binary patch literal 1536 zcmb<-^>JfjWMqH=Mg}_u1P><4z;J*G!FB*M9T<2Sco;mI-$dNbQAxO+qf&75!0j3p zf!j4I4mS_nwo$oVqhjy^r1W-;io)$26$h|vj*7u;8x@Fnj*7zV8kK_EH7W@n%|{|$ zf)q2jJ3Ct`Xt?`@YAP6-=o#r5Di|3UnHm@x8YpN4rKTu&B$hxWbj>vxSQr=>6c`v7 zSQ!`?-2Flsm>3ujfW*K?F)%PNLisR1i9jV7tAZF9D+Cy&dDuB7FfuTJ#ATpzfgsw2 zFM-K}j|0TShC$}BFns)vO^z8$2y!zpFbE-ugY95oU=U+u$qZncA-O0uF(-#1IWspgJ%=H&Br(q@2O3r&>p)=y!hillfCWg9fdL$zps<9A z`yz?6F)%Q|#6e*Wk^&_Q5C*ZqSg*J;wbdHE%&dhULqy2T}l$=OhTdS0nsK~a7|YEelggC5v~)QtGF zqQu-(uyvFYAb)`3667~zvmj}lfdLjzFgf(Nl7@yEOg&892aur*3=AGn0WNS_WMF_L zC{X-@q|~6|%peXDo`}RoW0|Nt0Kf1eM;Rn;71hpSs{|Bf7Li%HI#GeJ!Kv+D1 z;tymu2!o7IbC{xFFQ8 X$b3-wflYq^)KQ>3kE|YQEL;cxC8LeE literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_casin.c b/src/openlibm/src/s_casin.c new file mode 100644 index 0000000..4e5daaa --- /dev/null +++ b/src/openlibm/src/s_casin.c @@ -0,0 +1,136 @@ +/* $OpenBSD: s_casin.c,v 1.6 2013/07/03 04:46:36 espie Exp $ */ +/* + * Copyright (c) 2008 Stephen L. Moshier + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* casin() + * + * Complex circular arc sine + * + * + * + * SYNOPSIS: + * + * double complex casin(); + * double complex z, w; + * + * w = casin (z); + * + * + * + * DESCRIPTION: + * + * Inverse complex sine: + * + * 2 + * w = -i clog( iz + csqrt( 1 - z ) ). + * + * casin(z) = -i casinh(iz) + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * DEC -10,+10 10100 2.1e-15 3.4e-16 + * IEEE -10,+10 30000 2.2e-14 2.7e-15 + * Larger relative error can be observed for z near zero. + * Also tested by csin(casin(z)) = z. + */ + +#include +#include +#include + +#include "math_private.h" + +double complex +casin(double complex z) +{ + double complex w; + static double complex ca, ct, zz, z2; + double x, y; + + x = creal (z); + y = cimag (z); + + if (y == 0.0) { + if (fabs(x) > 1.0) { + w = M_PI_2 + 0.0 * I; + /*mtherr ("casin", DOMAIN);*/ + } + else { + w = asin (x) + 0.0 * I; + } + return (w); + } + + /* Power series expansion */ + /* + b = cabs(z); + if( b < 0.125 ) { + z2.r = (x - y) * (x + y); + z2.i = 2.0 * x * y; + + cn = 1.0; + n = 1.0; + ca.r = x; + ca.i = y; + sum.r = x; + sum.i = y; + do { + ct.r = z2.r * ca.r - z2.i * ca.i; + ct.i = z2.r * ca.i + z2.i * ca.r; + ca.r = ct.r; + ca.i = ct.i; + + cn *= n; + n += 1.0; + cn /= n; + n += 1.0; + b = cn/n; + + ct.r *= b; + ct.i *= b; + sum.r += ct.r; + sum.i += ct.i; + b = fabs(ct.r) + fabs(ct.i); + } + while( b > MACHEP ); + w->r = sum.r; + w->i = sum.i; + return; + } + */ + + ca = x + y * I; + ct = ca * I; + /* sqrt( 1 - z*z) */ + /* cmul( &ca, &ca, &zz ) */ + /*x * x - y * y */ + zz = (x - y) * (x + y) + (2.0 * x * y) * I; + + zz = 1.0 - creal(zz) - cimag(zz) * I; + z2 = csqrt (zz); + + zz = ct + z2; + zz = clog (zz); + /* multiply by 1/i = -i */ + w = zz * (-1.0 * I); + return (w); +} + +#if LDBL_MANT_DIG == DBL_MANT_DIG +openlibm_strong_reference(casin, casinl); +#endif /* LDBL_MANT_DIG == DBL_MANT_DIG */ diff --git a/src/openlibm/src/s_casin.c.o b/src/openlibm/src/s_casin.c.o new file mode 100644 index 0000000000000000000000000000000000000000..93ae74ed36ab37773a3af35c30d1f86d521ed3aa GIT binary patch literal 3200 zcmb<-^>JfjWMqH=Mg}_u1P><4z;J*A!FB*M9T@l-_!vBz-)MZ|7xYmP_{1;hq9XAE zB=?D5AVfvt6TbjVm?Mo};}A?LMFqrtk;ec2KpMZ^iz+t$mN-TRhBW^7m(ut(&VJ&L zJe9_;aqts=#F0<@krzJkN1RCG*SL|!FLIY(Qx;-=%+)l0y^H)^nT!k!pZEo!qJq32 z*))EQGim%9M?UdKocY8bbMzCxpeRWE6Mw|hPyB*0Ag4xxtT~d#|NcoDzsAK+{E=5a z@kbm=LfD4UkU`f8vihg3ahOevyM|{2E~6(;&V)$gc_Iik^ho0W<3XRQ*kUO|Tn2@kic* z_%rg*C;pf_pZFsVrt#|?=I@%y018fx(;m%7G!Ccn%e#QNM_>kmBjEi>h?Dfe#>4zo z4h=a$9~BOmavzW%BM!da2n%RLObModqFFEpqyiMMFfCwV0dPnQ=|G~E3{H5Cj^ z^o;Zj6^smwObrYT4HPtjQd1N>5=)>Gy5^b;3@i)`3XYJmupW~>TgV5|^el;&aQn83)uAj1H`AZZUK1_lNfJ_F{tj9h#i?%W_TTo_~z z3&Tgaf05NOW6gOC49s9xBdcU!09nGwzykIQNJaoeFfcHHXplIF1_{AvP%MMQL1G{b z6PE&U7}&rhG9eG7PVD${iMX8B749S_fiRlc<#f3#B49Pk9=?rO! zNyQBD@wufrDaoL)5rldYlr}*n!k_;Tpo1jN$H2e<6EB2{gOVaMQrc`s5(lMenEHMs zagcggI$w?^&I9G&fYLDYVdmV0ii6yV?4GAkahQ6LJV@v>h+tq~fQiG*`2iINsYCX! z1SrEm)q~O;OuaFZILQ4laSNz8$Q*v8@Nt2P!|a9mD;P~2W=;%L9ApkC-ND3DpyD8N z*pbXHM-oSN&swNB$Q)3d!pu1g6$hDv951Jl#JP~nzXKHqnInWG{sAhEZVo?4fB{n8 z2_vaDf{KGEP#FSqk2OdDi+WI535pt!Gzf#(V60bMnOl;W#GqGPQUswhV639loJ75n z)QS=Yy_Cd~L@&IHey8a1Jdkv5kV=2oFq4tB)6tYs7ewaI9av-}vY#42aL;nV-{pjHZ#x9(eiWbzVc`!-KcMmeD$D>A2l)rxZjfyeQ2QT%6fiI_ wfXY;m8R+^!We-#-NE;kmK+|s=Tm-^^8VBJpFff41G_3le7QyNtm + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* casinf() + * + * Complex circular arc sine + * + * + * + * SYNOPSIS: + * + * void casinf(); + * cmplxf z, w; + * + * casinf( &z, &w ); + * + * + * + * DESCRIPTION: + * + * Inverse complex sine: + * + * 2 + * w = -i clog( iz + csqrt( 1 - z ) ). + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE -10,+10 30000 1.1e-5 1.5e-6 + * Larger relative error can be observed for z near zero. + * + */ + +#include +#include + +float complex +casinf(float complex z) +{ + float complex w; + float x, y; + static float complex ca, ct, zz, z2; + /* + float cn, n; + static float a, b, s, t, u, v, y2; + static cmplxf sum; + */ + + x = crealf(z); + y = cimagf(z); + + if(y == 0.0f) { + if(fabsf(x) > 1.0f) { + w = (float)M_PI_2 + 0.0f * I; + /*mtherr( "casinf", DOMAIN );*/ + } + else { + w = asinf (x) + 0.0f * I; + } + return (w); + } + + /* Power series expansion */ + /* + b = cabsf(z); + if(b < 0.125) { + z2.r = (x - y) * (x + y); + z2.i = 2.0 * x * y; + + cn = 1.0; + n = 1.0; + ca.r = x; + ca.i = y; + sum.r = x; + sum.i = y; + do { + ct.r = z2.r * ca.r - z2.i * ca.i; + ct.i = z2.r * ca.i + z2.i * ca.r; + ca.r = ct.r; + ca.i = ct.i; + + cn *= n; + n += 1.0; + cn /= n; + n += 1.0; + b = cn/n; + + ct.r *= b; + ct.i *= b; + sum.r += ct.r; + sum.i += ct.i; + b = fabsf(ct.r) + fabsf(ct.i); + } + while(b > MACHEPF); + w->r = sum.r; + w->i = sum.i; + return; + } + */ + + + ca = x + y * I; + ct = ca * I; /* iz */ + /* sqrt( 1 - z*z) */ + /* cmul( &ca, &ca, &zz ) */ + /*x * x - y * y */ + zz = (x - y) * (x + y) + (2.0f * x * y) * I; + zz = 1.0f - crealf(zz) - cimagf(zz) * I; + z2 = csqrtf (zz); + + zz = ct + z2; + zz = clogf (zz); + /* multiply by 1/i = -i */ + w = zz * (-1.0f * I); + return (w); +} diff --git a/src/openlibm/src/s_casinf.c.o b/src/openlibm/src/s_casinf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..152e0bdbf6aa93dfc69fb64a3681eeaba9e6be7e GIT binary patch literal 3248 zcmb<-^>JfjWMqH=Mg}_u1P><4!0>?s!FB*M9T@l-_!!bW`0EaMG{5oiIQT;0GrypV zibbc3iVc{>^O?U6!smDa((;*Kz(=AyAQ()KVeCCfl{h2@FAiu^5uv0a_&ePx*ImIu`3(^dAsGy4q%V+*Nuz64+0Us3> zkX8H|7e4a~fMq`ON8aQQ2kZOHA9Lt4$lEHP`C|@))d;$%D1ePu;1{{bFAR1r)T}zN z9!MY`e4&uWpZ9@Z3JXlF4=A)E4!&OYnO^`L zS84q3FY#*}{md_z0!kXlYQX}Kz|8*va(5bk{`HqS|Nj4nY3A2B4|50Dd&mBVf;{%p z_5c6>pg3Y+V7SeH(w>2#0fhHMg&LqVgmQOwwo=e=_Y2ijFf`FK(lb;rGB7eVFf=q! z&8+mS-5Dd`^hz3?fjPu_}mx zu|j}RnuncZ0wV*137aW(-F#vsB7L>PbwQwE3z zhUB8u#GEvSNhZB~%Wv>gupAE5T5hZl?wqkW+I4M2t>W2lE9 z^#wu#=6@I+3e}HL0b%Jw^+R|F5~dF(0!l)ld<=CiOqjs{svq55=;2ojwI5x70#v^R z+(ZZiU4I2M&!MNE0H{J({DI;DR31Qu8DQcd|Df9qvS|j?{s$lh3=9mQvKC|px_(fZ k0aXgp2FDf9^a~0fxFFQ8$b3+lhE0D4)S`A|#aQ$M04k^pLjV8( literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_casinh.c b/src/openlibm/src/s_casinh.c new file mode 100644 index 0000000..4b1154d --- /dev/null +++ b/src/openlibm/src/s_casinh.c @@ -0,0 +1,62 @@ +/* $OpenBSD: s_casinh.c,v 1.6 2013/07/03 04:46:36 espie Exp $ */ +/* + * Copyright (c) 2008 Stephen L. Moshier + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* casinh + * + * Complex inverse hyperbolic sine + * + * + * + * SYNOPSIS: + * + * double complex casinh(); + * double complex z, w; + * + * w = casinh (z); + * + * + * + * DESCRIPTION: + * + * casinh z = -i casin iz . + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE -10,+10 30000 1.8e-14 2.6e-15 + * + */ + +#include +#include +#include + +#include "math_private.h" + +double complex +casinh(double complex z) +{ + double complex w; + + w = -1.0 * I * casin (z * I); + return (w); +} + +#if LDBL_MANT_DIG == DBL_MANT_DIG +openlibm_strong_reference(casinh, casinhl); +#endif /* LDBL_MANT_DIG == DBL_MANT_DIG */ diff --git a/src/openlibm/src/s_casinh.c.o b/src/openlibm/src/s_casinh.c.o new file mode 100644 index 0000000000000000000000000000000000000000..2b1d38bb4fb1fadc7197712365439e7b6b100056 GIT binary patch literal 1848 zcmb<-^>JfjWMqH=Mg}_u1P><4z_5cE!FB*M9T@l+cp1|8-(O1O*LaY|ukq5O`3=V> z{>Ve0_#-cV;*U9)#;h=ORC7KrkQgP-^#PkrK#fhbk* zXg8b`opyxxkC(m)bE2~rKgAM7DCLj#2Vu%E%*+1W}#!`&}b zQ^C+g&q&Wu!N|bK)WFctKtUrYHATTAu>>liYp%(_z{0@5puoVuz{5L!6;FJ~^>CGcQ9gnL*FT*$6}!f(T;y=L%}Gf%2AKuI+8}}f z68`KA3=Dt%LjX(x69WSSC@I3kK`$@ABvsGdFI2auGGcds79VU$}oq)m$rXHql0yK~&Km|al9ApnD4nRT@ zAcBE`L5+a{oXS9P2^9iUXTT&T0Wt$wREL29oYu+JZwR$t2-#2u28IhzKFpm^F4!&* z8|Du?sD1;GAQA?bPz($V`bc6RCd~aX+8wGNB!`T}VG581v8WAaU|;~{4`^`1RZBqi zqq_^{ZkR$){s1XO*Y5!mWME*hfGLF1==!suc@#bV6`&CU3qMf&gUU#lewaAO8g#os zRyBYm7#J9CfH({c44`rilt$6@gUp0l1yu>5BA|wX;uj(UA)&@XI1CI7pmGtLeha7| Ltek*pK-UidBg4gv literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_casinhf.c b/src/openlibm/src/s_casinhf.c new file mode 100644 index 0000000..8894624 --- /dev/null +++ b/src/openlibm/src/s_casinhf.c @@ -0,0 +1,55 @@ +/* $OpenBSD: s_casinhf.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */ +/* + * Copyright (c) 2008 Stephen L. Moshier + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* casinhf + * + * Complex inverse hyperbolic sine + * + * + * + * SYNOPSIS: + * + * float complex casinhf(); + * float complex z, w; + * + * w = casinhf (z); + * + * + * + * DESCRIPTION: + * + * casinh z = -i casin iz . + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE -10,+10 30000 1.8e-14 2.6e-15 + * + */ + +#include +#include + +float complex +casinhf(float complex z) +{ + float complex w; + + w = -1.0f * I * casinf (z * I); + return (w); +} diff --git a/src/openlibm/src/s_casinhf.c.o b/src/openlibm/src/s_casinhf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..2cc579a55991801dd30572610ab8f28ad693cb5e GIT binary patch literal 1912 zcmb<-^>JfjWMqH=Mg}_u1P><4!0>|^!FB*M9T@l+cp1|8^B<(~=f6nfe}BNE`Hcj> z#uff!Z$m%xM_%~MA9?gMf6Ud-{1Hd^^)6J!f94kqQQ`Q^FX*De^O?WSMTO%9$fVEw z0-_)~jX(bb$T)tD8~n$AmKmXik{>Ve0`6KRq=8rkTuXm%$=`+8ej0)Hw zme2fkEGiz&MAzFj7$v-4Gk1D zf>KiyJQ7Qw61wJ^3=Av`3=9ek3=FIc3=Hmmp$tq6j0Zqsu&`x>@;O1)FfcHPKxxLR zAO^+?0Y+&ac8&>*3=A?15Db#O1tJ3Y6qu^G_&6N7K|GuoWDg6&$N$(AFk^{fUa&$| zu)D!bC?N!mXaW(=Gh9JV20V)BZ(-`98b4zoIla0Y0|UdK{}A8~5@cXt zU}9ik03~IZct4UjNDoYWK2#he2J$0Jd=FF{WDY1)VB$xh;^^u@X#gYzQV+r)HW=#_ zSLT)^CNbz0mlQ$h3>d2@H78N8B(L-Gg0E*YprJP08$3zRNE3>a+()o%b2M8X}L=kl%8Q?AU+I-V-tkh1yci}!xbHO?gwp8xvv9 + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* casinhl + * + * Complex inverse hyperbolic sine + * + * + * + * SYNOPSIS: + * + * long double complex casinhf(); + * long double complex z, w; + * + * w = casinhl (z); + * + * + * + * DESCRIPTION: + * + * casinh z = -i casin iz . + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE -10,+10 30000 1.8e-14 2.6e-15 + * + */ + +#include +#include + +long double complex +casinhl(long double complex z) +{ + long double complex w; + + w = -1.0L * I * casinl(z * I); + return (w); +} diff --git a/src/openlibm/src/s_casinhl.c.o b/src/openlibm/src/s_casinhl.c.o new file mode 100644 index 0000000000000000000000000000000000000000..a2a0d8707f252bbb0b6e663684c38b495ea4005a GIT binary patch literal 1656 zcmb<-^>JfjWMqH=Mg}_u1P><4z+l0QU^{@B4h*~uJPaPqZ#Zt}s0iH7QBk=0?&g7; zhi{y^@%ZMc8>ep^x&5lj_U`SwH}2l@Xnvz`yGBLewvEaQkY!9aref}lO8(|I`%U#1i*CMJc;ZCsGg||?#|9u3L5Typ_&SYCVEDC zh6+XoMy3Xah6V~6L8&PU9*HGT30-qd1{MYe1_cHN237_J26w+u1||l^10XS2m@z{6 zu;3Dbx`nYSh=H*}fKi%lIh#mLw)I=oOa~LFfz^t0*-mQLiMmqJ%*&C9x!tK`*Jem_aW& zKQ}iuuY^G_FTW&J&)qLnx40xRIUCAP&nwj{D9SHLEh?#G&;y&0nh~E?l$e_ewvJK) zf9BFat{HFfcHH%p_O8A=G{YsCh67X1_j607}E`htXD0{ZMH*WdKtE7lAO) zg}oRU7}(L%5Ca1POh3B2Kz@ao1R;~4_CtdkBFMnNkN~wP04@SypzDvt5q}$?2EyVA z6n`MSAPh1ICJwR&suUy)#~VNr3=9ktpd#E13=E(+Lf6j;6^AN=Qw~r=RpBBK2Gm#x Vhk=1X5QqK~Q2jY@l@JEHegMOL);|CM literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_casinl.c b/src/openlibm/src/s_casinl.c new file mode 100644 index 0000000..b346272 --- /dev/null +++ b/src/openlibm/src/s_casinl.c @@ -0,0 +1,130 @@ +/* $OpenBSD: s_casinl.c,v 1.3 2011/07/20 21:02:51 martynas Exp $ */ + +/* + * Copyright (c) 2008 Stephen L. Moshier + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* casinl() + * + * Complex circular arc sine + * + * + * + * SYNOPSIS: + * + * long double complex casinl(); + * long double complex z, w; + * + * w = casinl( z ); + * + * + * + * DESCRIPTION: + * + * Inverse complex sine: + * + * 2 + * w = -i clog( iz + csqrt( 1 - z ) ). + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * DEC -10,+10 10100 2.1e-15 3.4e-16 + * IEEE -10,+10 30000 2.2e-14 2.7e-15 + * Larger relative error can be observed for z near zero. + * Also tested by csin(casin(z)) = z. + */ + +#include +#include +#include + +#if LDBL_MANT_DIG == 64 +static const long double MACHEPL= 5.42101086242752217003726400434970855712890625E-20L; +#elif LDBL_MANT_DIG == 113 +static const long double MACHEPL = 9.629649721936179265279889712924636592690508e-35L; +#endif + +static const long double PIO2L = 1.570796326794896619231321691639751442098585L; + +long double complex +casinl(long double complex z) +{ + long double complex w; + long double x, y, b; + static long double complex ca, ct, zz, z2; + + x = creall(z); + y = cimagl(z); + + if (y == 0.0L) { + if (fabsl(x) > 1.0L) { + w = PIO2L + 0.0L * I; + /*mtherr( "casinl", DOMAIN );*/ + } + else { + w = asinl(x) + 0.0L * I; + } + return (w); + } + + /* Power series expansion */ + b = cabsl(z); + if (b < 0.125L) { + long double complex sum; + long double n, cn; + + z2 = (x - y) * (x + y) + (2.0L * x * y) * I; + cn = 1.0L; + n = 1.0L; + ca = x + y * I; + sum = x + y * I; + do { + ct = z2 * ca; + ca = ct; + + cn *= n; + n += 1.0L; + cn /= n; + n += 1.0L; + b = cn/n; + + ct *= b; + sum += ct; + b = cabsl(ct); + } + + while (b > MACHEPL); + w = sum; + return w; + } + + ca = x + y * I; + ct = ca * I; /* iz */ + /* sqrt(1 - z*z) */ + /* cmul(&ca, &ca, &zz) */ + /* x * x - y * y */ + zz = (x - y) * (x + y) + (2.0L * x * y) * I; + zz = 1.0L - creall(zz) - cimagl(zz) * I; + z2 = csqrtl(zz); + + zz = ct + z2; + zz = clogl(zz); + /* multiply by 1/i = -i */ + w = zz * (-1.0L * I); + return (w); +} diff --git a/src/openlibm/src/s_casinl.c.o b/src/openlibm/src/s_casinl.c.o new file mode 100644 index 0000000000000000000000000000000000000000..e99c11bb7de19b99f9d7ec99d0f3ede86b315605 GIT binary patch literal 4264 zcmb<-^>JfjWMqH=Mg}_u1P><4!0>_x!FB*M9T@l-_!vTiJ(}Nm{4Y_dK*ldXDsI=P z7g$X{PGO9!KyIH zo2PG{xq0ZunVUy%oWA$)=HVNsZyvjG?%u)MFZsJNnHU)E-o1PK?wz|gZXUQ@%W(6g zNAnv6Bs&~#oWA+u&XJoZZ+rpU<#6-Ny@Pjt->y*!xOwu%shcP7ow|A8wl%`NAU{KV z3<`xC2SI@d3ar~UD&X(|2PoLbH&5RG2o6*O{&xHS|Nn#80=IQkUUTuwJ22e6efRd= z8y?L^Jfd%&j6IyjFW&<4Kf~RdV6Q`i=eCXt%(XWU-Z*pb;muPJuN?-3&kh5+cfSUsfbV%}eck{uW(>G7wI0*9ojmNiN@^>Hl2MWx)H*TKt z*a7kg0|P@t#{c~c3;`a^Zwx@5ym=DYY*3^hadgLIpS%0DaIO(wq<`0CnjQ{ow3_*c`w{2AZm#An! zF({*ZfL#qU3KUZ}Pv1Ow^VG|CfB*kyFg=u^xab!DNsxA^sdfwu4e|``&dyc}8t#6f znhJ&{dPaJN3PuJ-rUr(F1_~NMsVNE`i6u}8U2{za1{MYe1_cHN22fgd_X}lUVqiP~ z5`&dZj8Hx^)DjUW%~%!0z*r%`D9yvpF@ceR;S2) z3txr{Ux5o>g$rK;qc0lYpD!T>Sw4|3foTO_10z!cUqU_?pM)cyfHNP57k4>d17i+f zf*W6k8()DNUxgb;O+8-%lOtb-Bgpgxj1hbZK70iMd>KxB36T)3j(i;c+%9|to*+dD zk$ejnqxceXK%4?cz6wXa21a+j4n`Ng35+g$GZ1~Uc*1_8J#1Ot?vv5C9jQ1699 zJP?O?I1X`8IAXKc0Ec>p;`rpm;>^4py<~`40gmNaDN<3=A;wY$S0$B=N;iaV7=^1`Z_g-ALk~JQ@S#AA!;! z^&oK@DE~B+hKa-S>}53Z94P-4l!mE?ng0Pz9H#yonmEkfKWO4UP`)`RLoqNgz|4n< zXQPShK-G6c#X;eT96nQ_;vjQ4k;3N|k~nfWJVg_S+4~<&92P#DAcK+I33HDinm8;T zrP0JeaS!r>I#e9we&l#Jg^GhHkUL@JtTjjg$zGT_j%eZ_^FZdiqlv@Z;{z23sRNk- z6VHN*gD8-_F!2(Q02X^2pyD8N_>sc711b)pK<2>G$s~{fk~y$+G6PK<7S0RM#9`sQ z22C91&TVMoAisga;Sf|DhNI!66PQ*CF`@WCzI2V60bMnOl;W#GqGP zQUswhV639loJ75n)QS=Yy_Cd~LBj?Fz}VCe+J1?6v;ewaAOKj?OYtl9u=T0H + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* catan() + * + * Complex circular arc tangent + * + * + * + * SYNOPSIS: + * + * double complex catan(); + * double complex z, w; + * + * w = catan (z); + * + * + * + * DESCRIPTION: + * + * If + * z = x + iy, + * + * then + * 1 ( 2x ) + * Re w = - arctan(-----------) + k PI + * 2 ( 2 2) + * (1 - x - y ) + * + * ( 2 2) + * 1 (x + (y+1) ) + * Im w = - log(------------) + * 4 ( 2 2) + * (x + (y-1) ) + * + * Where k is an arbitrary integer. + * + * catan(z) = -i catanh(iz). + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * DEC -10,+10 5900 1.3e-16 7.8e-18 + * IEEE -10,+10 30000 2.3e-15 8.5e-17 + * The check catan( ctan(z) ) = z, with |x| and |y| < PI/2, + * had peak relative error 1.5e-16, rms relative error + * 2.9e-17. See also clog(). + */ + +#include +#include +#include + +#include "math_private.h" + +#define MAXNUM 1.0e308 + +static const double DP1 = 3.14159265160560607910E0; +static const double DP2 = 1.98418714791870343106E-9; +static const double DP3 = 1.14423774522196636802E-17; + +static double +_redupi(double x) +{ + double t; + long i; + + t = x/M_PI; + if(t >= 0.0) + t += 0.5; + else + t -= 0.5; + + i = t; /* the multiple */ + t = i; + t = ((x - t * DP1) - t * DP2) - t * DP3; + return (t); +} + +double complex +catan(double complex z) +{ + double complex w; + double a, t, x, x2, y; + + x = creal (z); + y = cimag (z); + + if ((x == 0.0) && (y > 1.0)) + goto ovrf; + + x2 = x * x; + a = 1.0 - x2 - (y * y); + if (a == 0.0) + goto ovrf; + + t = 0.5 * atan2 (2.0 * x, a); + w = _redupi (t); + + t = y - 1.0; + a = x2 + (t * t); + if (a == 0.0) + goto ovrf; + + t = y + 1.0; + a = (x2 + (t * t))/a; + w = w + (0.25 * log (a)) * I; + return (w); + +ovrf: + /*mtherr ("catan", OVERFLOW);*/ + w = MAXNUM + MAXNUM * I; + return (w); +} + +#if LDBL_MANT_DIG == DBL_MANT_DIG +openlibm_strong_reference(catan, catanl); +#endif /* LDBL_MANT_DIG == DBL_MANT_DIG */ diff --git a/src/openlibm/src/s_catan.c.o b/src/openlibm/src/s_catan.c.o new file mode 100644 index 0000000000000000000000000000000000000000..b3985b9ea26a41c21866b3147e3bbe1d5005a500 GIT binary patch literal 2528 zcmb<-^>JfjWMqH=Mg}_u1P><4z>vU(U^{@B4h(z@ybK=AZ!|vf3;L)CeBu{$QIU87 zlKaFj5TYXSiC+LF%#p^gaR??Aqr<UqBV4FpXd1LK^@318MwvH>x;F+0yv+uas+~ z@oT&WX-MPOIP-}=^7SYF$U~p_W6pl!k2wKVeWFUNROA!C04vB8kLDvFJtq$H%QJl9 zkGTDbUoZt^ykosiPvd`o@)N&+DM%aGl_04bpZEp9N(I2$BJZW~YaIT> z9|tx(jbHy@8o$N~{-&J_3?SprL7evf+b8~*BcJ#q4}9W}IGV<#2;GiC+L@2!G@Wm~TJvM?U++A9?H(eGc2qe~{q}3=9iSyl(w`=3zaA`@tSUKd_h3bqV>c$O(yJ zh70z22V4!4ld^0W7#LvU0&d)jb`0*$&Q=N;Y76t|e1qKENP?);=g)%TPFdhJj!O|Kdl+Ouq2!jZeW~>TgV5|^e zl;&aQn83)upu)hwAOn@#2-57rXTa3L#mC{n&Ge0nk0Xg2Dv5&vX<=db2nz-jRm@mY zKEyay1`ZUJ3=9HbKFBv<2AmKDvsj_>U=Em&0+Xx^5?~rZ$b*@z;IIKRp#;dEpwQBQ z@?n%Fn8C_m0HzUy9+=6>U;(BPgfRmHgAkIxz+uL~z+lM$^8-RHhy_Xr5Wj(V2<(bO zy*CbVhT{0-#FE53y<`SGA7>*FVE`hGL4*m2Fa;52Ai^9(STKOqGb9(KCgw0CXXYlR zGk^>*V#vu)XJ8P7It7$wco-NM{``jk9VBs3#({}jLB*LE7#Nt5)HfiBgUo`dUkw!p ziSZ$+-wqWAnFES#nEJa&;-I1tChi1EU<{D-&W~hH2vi(o4m*-~43an~jls;xLlOt& z37B{tk~kNVIiS1+auUdV5C*ZqSg*J;wlBR;JtF*g-#Hx&qwzd&9Fg)y>m&;p79mY!j9=xJ9P8W%A2Fm)?H5e+Jn zK!!6gFo5zohzW`VkQ!J%RbyZP=N?cR0*S-$N04F|2Z=@(2BlAsndIs>gxW8JWCw`( z18Nbvzd&|@kD z3}!zp{z3kMS_Lx_Oy7VCHh>f`Fff41B#;^C`ax!*$34h^2x$8A2XT-v)Ht{ZsNBP* P{{htfm2j012D*L#zrT61 literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_catanf.c b/src/openlibm/src/s_catanf.c new file mode 100644 index 0000000..d40cb56 --- /dev/null +++ b/src/openlibm/src/s_catanf.c @@ -0,0 +1,124 @@ +/* $OpenBSD: s_catanf.c,v 1.2 2010/07/18 18:42:26 guenther Exp $ */ +/* + * Copyright (c) 2008 Stephen L. Moshier + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* catanf() + * + * Complex circular arc tangent + * + * + * + * SYNOPSIS: + * + * float complex catanf(); + * float complex z, w; + * + * w = catanf( z ); + * + * + * + * DESCRIPTION: + * + * If + * z = x + iy, + * + * then + * 1 ( 2x ) + * Re w = - arctan(-----------) + k PI + * 2 ( 2 2) + * (1 - x - y ) + * + * ( 2 2) + * 1 (x + (y+1) ) + * Im w = - log(------------) + * 4 ( 2 2) + * (x + (y-1) ) + * + * Where k is an arbitrary integer. + * + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE -10,+10 30000 2.3e-6 5.2e-8 + * + */ + +#include +#include + +#define MAXNUMF 1.0e38F + +static const double DP1 = 3.140625; +static const double DP2 = 9.67502593994140625E-4; +static const double DP3 = 1.509957990978376432E-7; + +static float +_redupif(float xx) +{ + float x, t; + long i; + + x = xx; + t = x/(float)M_PI; + if(t >= 0.0) + t += 0.5; + else + t -= 0.5; + + i = t; /* the multiple */ + t = i; + t = ((x - t * DP1) - t * DP2) - t * DP3; + return(t); +} + +float complex +catanf(float complex z) +{ + float complex w; + float a, t, x, x2, y; + + x = crealf(z); + y = cimagf(z); + + if((x == 0.0f) && (y > 1.0f)) + goto ovrf; + + x2 = x * x; + a = 1.0f - x2 - (y * y); + if (a == 0.0f) + goto ovrf; + + t = 0.5f * atan2f(2.0f * x, a); + w = _redupif(t); + + t = y - 1.0f; + a = x2 + (t * t); + if(a == 0.0f) + goto ovrf; + + t = y + 1.0f; + a = (x2 + (t * t))/a; + w = w + (0.25f * logf (a)) * I; + return (w); + +ovrf: + /*mtherr( "catanf", OVERFLOW );*/ + w = MAXNUMF + MAXNUMF * I; + return (w); +} diff --git a/src/openlibm/src/s_catanf.c.o b/src/openlibm/src/s_catanf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..a41234f22bd19ea254b275cfe0c71329cf01ddf7 GIT binary patch literal 2624 zcmb<-^>JfjWMqH=Mg}_u1P><4z|g>kU^{@B4h;MZd<9DJehnP1RF zMWfS2MF-3h`OIGj;S0O~Y5B}A5TYXTnP0$1MF6aT<1@cthzdxXkBSOdu>wqCj0(qR zegRdGHhzr@Y5eaG@ax^EVlQRo*S}J(!msg~U*izJ#+lFjk*`1VM;`jjA9MCIf6NJp z!V^^*rD~t~1$ZIa4}Rts^ih!jTPXv!M#7`{h{a)kc?X8i{1LZ5^9!bc+$ER;c2|fB z2fxN)utU=L-{1bsFJKBX2kd$devK2K`31lV1;Cmj&+%&<{LCN63R1(bf0$q627l8& z1_qGH_xLpqrSZT2_L)EC$Y=h@1E2XLj`Hgrt77ACiTnTm|7Q<=ox`8`Bd$QK5d;TI z>gYa9Z*=@Y*|j0(pmegRRCjj+&+1l#|KKl1Wt z{-~3m_+w7NRDi@j@kh#nRD;CR_}^dp#2<5-Ujt;xq0ju0w?6Slo&3xnar))ufB*ld z@yok_Tpx4qrS1R!{}~tV_;~oXJBBkzs>LIz`)R82QrO8ffJGxw)or6oZ%*+ z>(XM!;O^{frJ&*N7pkdXXrgDNXQ*IgU}S1wXlS6I5tN#u;E`AYmC!ZUWME)nU|>*S zU|;|_-`y{ifr)|f07wj$1{tAzPOyax3?fjPu_}mxu|j}RnuncZ0wV*13b^g8-BdqqM*bHVpIiq2lQ3O&Ay$gpm9N z4l4!*25SZe46{K-IN=cY#33GlL!6;FJ~^=@F)vLonL*FT*$6}!fCys{VFDt|K!hoX zFb5G93=jm1E-o=a=2$T3CFken zrskC}=;h^?r0Ti*h3XcUBqnD=`RRG3dId%K1*t_Pl?-}dvr{wT(~1&vQ{j#wp8@h8 z$m^i6Mm7afFflN|(l<;FJwJf*At+8@>S5}@g%GH00vXQ00M4f%CMYgIY9v4e0|SE^ z0|PiWfzlFG2uvxW1U6U*On}S)GoXYH0|PkklB?ekYQGTFJQ$?{wI5bq!o)#-1+if? zs2~Tq30=PhR6oq0AUz-q^FNIChT3lcl0?D*Q2mf{2q6Ko3&exbAyEAwF=Sj1)sHL& zV#D--*dUz3z`y{?H|WY6paSUbg1H-{7ldn|_Cu9}gur+MRKNnvLlEft%b{ftdir?) zDijzP7+~QCDw{z05~d#}4)PDwDug8r3=A)zf(;-A3=9mQG7MCcq3Z{g0qAK5WKae) df + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* catanh + * + * Complex inverse hyperbolic tangent + * + * + * + * SYNOPSIS: + * + * double complex catanh(); + * double complex z, w; + * + * w = catanh (z); + * + * + * + * DESCRIPTION: + * + * Inverse tanh, equal to -i catan (iz); + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE -10,+10 30000 2.3e-16 6.2e-17 + * + */ + +#include +#include +#include + +#include "math_private.h" + +double complex +catanh(double complex z) +{ + double complex w; + + w = -1.0 * I * catan (z * I); + return (w); +} + +#if LDBL_MANT_DIG == DBL_MANT_DIG +openlibm_strong_reference(catanh, catanhl); +#endif /* LDBL_MANT_DIG == DBL_MANT_DIG */ diff --git a/src/openlibm/src/s_catanh.c.o b/src/openlibm/src/s_catanh.c.o new file mode 100644 index 0000000000000000000000000000000000000000..caf14da5a19a11e6ae8c7e71d260fcec8559507e GIT binary patch literal 1848 zcmb<-^>JfjWMqH=Mg}_u1P><4z_5cE!FB*M9T@l+cp1|8-(O1O*LaY|ukq5O`3=V> z{>Ve0_#-cV;*U9)#;h=ORC7KrkQgP-^#PkrK#fhbk* zXg8b`opyxxkC(m)bE2~rKgAM7DCLj#2Vu%E%*+1W}#!`&}b zQ^C+g&q&Wu!N|bK)WFctKtUrYHATTAu>>liYp%(_z{0@5puoVuz{5L!6;FJ~^=@F)u?enL*FT*$6}!f(T;y=L%}Gf%2AKuI+8}}f z68`KA3=Dt%LjX(x69WSSC@I3kK`$@ABvsGdFI2auGGcds79VU$}oq)m$rXHql0yK~&Km|al9ApnD4nRT@ zAcBE`L5+a{oXS9P2^9iUXTT&T0Wt$wREL29oYu+JZwR$t2-#2u28IhzKFpm^F4!&* z8|Du?sD1;GAQA?bPz($V`bc6RCd~aX+8wGNB!`T}VG581v8WAaU|;~{4`^`1RZBqi zqq_^{ZkR$){s1XO*Y5!mWME*hfGLF1==!suc@#bV6`&CU3qMf&gUU#lewaAO8g#os zRyBYm7#J9CfH({c44`rilt$6@gUp0l1yu>5BA|wX;uj(UA)&@XI1CI7pmGtLeha7| Ltek*pK-UidzgER} literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_catanhf.c b/src/openlibm/src/s_catanhf.c new file mode 100644 index 0000000..7d43825 --- /dev/null +++ b/src/openlibm/src/s_catanhf.c @@ -0,0 +1,55 @@ +/* $OpenBSD: s_catanhf.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */ +/* + * Copyright (c) 2008 Stephen L. Moshier + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* catanhf + * + * Complex inverse hyperbolic tangent + * + * + * + * SYNOPSIS: + * + * float complex catanhf(); + * float complex z, w; + * + * w = catanhf (z); + * + * + * + * DESCRIPTION: + * + * Inverse tanh, equal to -i catan (iz); + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE -10,+10 30000 2.3e-16 6.2e-17 + * + */ + +#include +#include + +float complex +catanhf(float complex z) +{ + float complex w; + + w = -1.0f * I * catanf (z * I); + return (w); +} diff --git a/src/openlibm/src/s_catanhf.c.o b/src/openlibm/src/s_catanhf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..2a4032bbb5b2918c0178aceea3f727416bcb5509 GIT binary patch literal 1912 zcmb<-^>JfjWMqH=Mg}_u1P><4!0>|^!FB*M9T@l+cp1|8^B<(~=f6nfe}BNE`Hcj> z#uff!Z$m%xM_%~MA9?gMf6Ud-{1Hd^^)6J!f94kqQQ`Q^FX*De^O?WSMTO%9$fVEw z0-_)~jX(bb$T)tD8~n$AmKmXik{>Ve0`6KRq=8rkTuXm%$=`+8ej0)Hw zme2fkEGiz&MAzFj7$v-4Gk1D zf>KiyJQ7Qw61wJ^3=Av`3=9ek3=FIc3=Hmmp$tq6j0Zqsu&`x>@;O1)FfcHPKxxLR zAO^+?0Y+&ac8&>*3=A?15Db#O1tJ3Y6qu^G_&6N7K|GuoWDg6&$N$(AFk^{fUa&$| zu)D!bC?N!mXaW(=Gh9JV20V)BZ(-`98b4zoIla0Y0|UdK{}A8~5@cXt zU}9ik03~IZct4UjNDoYWK2#he2J$0Jd=FF{WDY1)VB$xh;^^u@X#gYzQV+r)HW=#_ zSLT)^CNbz0mlQ$h3>d2@H78N8B(L-Gg0E*YprJP08$3zRNE3>a+()o%b2M8X}L=kl%8Q?AU+I-V-tkh1yci}!xbHO?gwp8xvv9 + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* catanhl + * + * Complex inverse hyperbolic tangent + * + * + * + * SYNOPSIS: + * + * long double complex catanhl(); + * long double complex z, w; + * + * w = catanhl (z); + * + * + * + * DESCRIPTION: + * + * Inverse tanh, equal to -i catan (iz); + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE -10,+10 30000 2.3e-16 6.2e-17 + * + */ + +#include +#include + +long double complex +catanhl(long double complex z) +{ + long double complex w; + + w = -1.0L * I * catanl(z * I); + return (w); +} diff --git a/src/openlibm/src/s_catanhl.c.o b/src/openlibm/src/s_catanhl.c.o new file mode 100644 index 0000000000000000000000000000000000000000..b8853f448db5b2381d8952b394ab7b57866ff00e GIT binary patch literal 1656 zcmb<-^>JfjWMqH=Mg}_u1P><4z+l0QU^{@B4h*~uJPaPqZ#Zt}s0iH7QBk=0?&g7; zhi{y^@%ZMc8>ep^x&5lj_U`SwH}2l@Xnvz`yGBLewvEaQkY!9aref}lO8(|I`%U#1i*CMJc;ZCsGg||?#|9u3L5Typ_&SYCVEDC zh6+XoMy3Xah6V~6L8&PU9*HGT30-qd1{MYe1_cHN237_J26w+u1||l^10XS2m@z{6 zu;3Dbx`nYSh=H*}fKi%lIh#mLw)I=oOa~LFfz^t0*-mQLiMmqJ%*&C9x!tK`*Jem_aW& zKQ}iuuY^G_FTW&J&)qLnx40xRIUCAP&nwj{D9SHLEh?#G&;y&0nh~E?l$e_ewvJK) zf9BFat{HFfcHH%p_O8A=G{YsCh67X1_j607}E`htXD0{ZMH*WdKtE7lAO) zg}oRU7}(L%5Ca1POh3B2Kz@ao1R;~4_CtdkBFMnNkN~wP04@SypzDvt5q}$?2EyVA z6n`MSAPh1ICJwR&suUy)#~VNr3=9ktpd#E13=E(+Lf6j;6^AN=Qw~r=RpBBK2Gm#x Vhk=1X5QqK~Q2jY@l@JEHegJGL)+zu1 literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_catanl.c b/src/openlibm/src/s_catanl.c new file mode 100644 index 0000000..acd51b0 --- /dev/null +++ b/src/openlibm/src/s_catanl.c @@ -0,0 +1,127 @@ +/* $OpenBSD: s_catanl.c,v 1.3 2011/07/20 21:02:51 martynas Exp $ */ + +/* + * Copyright (c) 2008 Stephen L. Moshier + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* catanl() + * + * Complex circular arc tangent + * + * + * + * SYNOPSIS: + * + * long double complex catanl(); + * long double complex z, w; + * + * w = catanl( z ); + * + * + * + * DESCRIPTION: + * + * If + * z = x + iy, + * + * then + * 1 ( 2x ) + * Re w = - arctan(-----------) + k PI + * 2 ( 2 2) + * (1 - x - y ) + * + * ( 2 2) + * 1 (x + (y+1) ) + * Im w = - log(------------) + * 4 ( 2 2) + * (x + (y-1) ) + * + * Where k is an arbitrary integer. + * + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * DEC -10,+10 5900 1.3e-16 7.8e-18 + * IEEE -10,+10 30000 2.3e-15 8.5e-17 + * The check catan( ctan(z) ) = z, with |x| and |y| < PI/2, + * had peak relative error 1.5e-16, rms relative error + * 2.9e-17. See also clog(). + */ + +#include +#include +#include + +static const long double PIL = 3.141592653589793238462643383279502884197169L; +static const long double DP1 = 3.14159265358979323829596852490908531763125L; +static const long double DP2 = 1.6667485837041756656403424829301998703007e-19L; +static const long double DP3 = 1.8830410776607851167459095484560349402753e-39L; + +static long double +redupil(long double x) +{ + long double t; + long i; + + t = x / PIL; + if (t >= 0.0L) + t += 0.5L; + else + t -= 0.5L; + + i = t; /* the multiple */ + t = i; + t = ((x - t * DP1) - t * DP2) - t * DP3; + return (t); +} + +long double complex +catanl(long double complex z) +{ + long double complex w; + long double a, t, x, x2, y; + + x = creall(z); + y = cimagl(z); + + if ((x == 0.0L) && (y > 1.0L)) + goto ovrf; + + x2 = x * x; + a = 1.0L - x2 - (y * y); + if (a == 0.0L) + goto ovrf; + + t = atan2l(2.0L * x, a) * 0.5L; + w = redupil(t); + + t = y - 1.0L; + a = x2 + (t * t); + if (a == 0.0L) + goto ovrf; + + t = y + 1.0L; + a = (x2 + (t * t)) / a; + w = w + (0.25L * logl(a)) * I; + return (w); + +ovrf: + /*mtherr( "catanl", OVERFLOW );*/ + w = LDBL_MAX + LDBL_MAX * I; + return (w); +} diff --git a/src/openlibm/src/s_catanl.c.o b/src/openlibm/src/s_catanl.c.o new file mode 100644 index 0000000000000000000000000000000000000000..b95e20cdf9d4ca3956a9696a2d426f288f0f8954 GIT binary patch literal 2528 zcmb<-^>JfjWMqH=Mg}_u1P><4z@Wf}U^{@B4h;MZd<-7VZ!G?os6-&+7a;lDH7W`o z%|{fFB|vPjBuL`syW2V{w_o19S;bSzb@Ro|Q@20ey;ZJ$^T3UhH(%U%c=Pa$GxuKJ ze0TFCSdBrc>D?O;_*#@-o&m&s&673(L__dxU68dN%||S59=Lh(@XeF2S^4D|Zl1hd zqatwglt=R$1(1^<{2K>u+o*tDa+4LROX1GRo3C&D0$cd;?oE)}a#RHPn^rS0Fx)(K z@9@nRH(uU2apMqJ0m#*CCCxX_yk@$2=4OqG9>fyM4QF`LI$czBZsw@y+_zD= znWLiT(fmf>evXO&Sk;Srhi;y{apK;=dmmwrxWNl@1jGZkb5sQGoP@A%oV=Z*q7V^v z?;(T_^4z^s_a5GSck}R#lQ&P@dwlccy+ij79Zu8Zmu~@?0dnf&mjVC({|ECJ82&@S zzj}zk1;hE8N*0_;>g*wWlS3Jbi*E6sWPn5}!$p}p4c$q{jvRo>GcYjNGcYvRF}OQB zTPbL``-N&M7@FuA=@}{*85o%w7#bQVXauFED0n26KqYj|H5nLK7#J877#J8p!Rzi9 z%D}|HcmN~@OIwUkJ~PA_3?fjPu_}mxu|j}RnuncZ0wV*14+8^(3{-9=NV5x{gA1RB z3txZ>UxW)^f-fr9lh1)Eii?lKl{=U(A&$?1DV{H&n$N?L&%uX_k0YKNY7!;|GMa_q zBP`fZ6fk4S5jRg8-OD5TLLFg&u@P zh^vB`tPBQV8bN3=Ffa%qxf2{#3=9m03=9}%gLGNo5C=s&x?4c%-EgR9D2`7~EJ@7E z(Mx8~^Kmu+5yl|G6hxST2y+l&!2nUlkX)3Sn3KbhoSB=Lp2GmrYLvr}lb@agvW0;` z6heW+iHm`O;SV(Z8X<{;Vi6|Z0~KdtU|;~HC7Adgs5mIif#M1#eh4ZKQV)`Yi93Q4 z00Si5f^s8F+#M`3mK`$@ABvsGdFI2a4@+u)j^=@-O@1`oLW1nEaFFEpU~^+Ae}Fi0(k3!_7!;Rg~!#^F%?$YLNi zOdp61!k{Ds$_MDmBcKB4?n3uZE!2Lfa*&Z=+yNEH0P_$8y8a4in4qVh22f^ZU|@iy z6HxjAl{YZ`FmaH7pjII)0i`>rU;sz~0|Nu7%;1Ek6_7%hevlY?+5yQsKqJT-#6iMP W + +#include "math_private.h" + +/* cbrt(x) + * Return cube root of x + */ +static const u_int32_t + B1 = 715094163, /* B1 = (1023-1023/3-0.03306235651)*2**20 */ + B2 = 696219795; /* B2 = (1023-1023/3-54/3-0.03306235651)*2**20 */ + +/* |1/cbrt(x) - p(x)| < 2**-23.5 (~[-7.93e-8, 7.929e-8]). */ +static const double +P0 = 1.87595182427177009643, /* 0x3ffe03e6, 0x0f61e692 */ +P1 = -1.88497979543377169875, /* 0xbffe28e0, 0x92f02420 */ +P2 = 1.621429720105354466140, /* 0x3ff9f160, 0x4a49d6c2 */ +P3 = -0.758397934778766047437, /* 0xbfe844cb, 0xbee751d9 */ +P4 = 0.145996192886612446982; /* 0x3fc2b000, 0xd4e4edd7 */ + +OLM_DLLEXPORT double +cbrt(double x) +{ + int32_t hx; + union { + double value; + u_int64_t bits; + } u; + double r,s,t=0.0,w; + u_int32_t sign; + u_int32_t high,low; + + EXTRACT_WORDS(hx,low,x); + sign=hx&0x80000000; /* sign= sign(x) */ + hx ^=sign; + if(hx>=0x7ff00000) return(x+x); /* cbrt(NaN,INF) is itself */ + + /* + * Rough cbrt to 5 bits: + * cbrt(2**e*(1+m) ~= 2**(e/3)*(1+(e%3+m)/3) + * where e is integral and >= 0, m is real and in [0, 1), and "/" and + * "%" are integer division and modulus with rounding towards minus + * infinity. The RHS is always >= the LHS and has a maximum relative + * error of about 1 in 16. Adding a bias of -0.03306235651 to the + * (e%3+m)/3 term reduces the error to about 1 in 32. With the IEEE + * floating point representation, for finite positive normal values, + * ordinary integer divison of the value in bits magically gives + * almost exactly the RHS of the above provided we first subtract the + * exponent bias (1023 for doubles) and later add it back. We do the + * subtraction virtually to keep e >= 0 so that ordinary integer + * division rounds towards minus infinity; this is also efficient. + */ + if(hx<0x00100000) { /* zero or subnormal? */ + if((hx|low)==0) + return(x); /* cbrt(0) is itself */ + SET_HIGH_WORD(t,0x43500000); /* set t= 2**54 */ + t*=x; + GET_HIGH_WORD(high,t); + INSERT_WORDS(t,sign|((high&0x7fffffff)/3+B2),0); + } else + INSERT_WORDS(t,sign|(hx/3+B1),0); + + /* + * New cbrt to 23 bits: + * cbrt(x) = t*cbrt(x/t**3) ~= t*P(t**3/x) + * where P(r) is a polynomial of degree 4 that approximates 1/cbrt(r) + * to within 2**-23.5 when |r - 1| < 1/10. The rough approximation + * has produced t such than |t/cbrt(x) - 1| ~< 1/32, and cubing this + * gives us bounds for r = t**3/x. + * + * Try to optimize for parallel evaluation as in k_tanf.c. + */ + r=(t*t)*(t/x); + t=t*((P0+r*(P1+r*P2))+((r*r)*r)*(P3+r*P4)); + + /* + * Round t away from zero to 23 bits (sloppily except for ensuring that + * the result is larger in magnitude than cbrt(x) but not much more than + * 2 23-bit ulps larger). With rounding towards zero, the error bound + * would be ~5/6 instead of ~4/6. With a maximum error of 2 23-bit ulps + * in the rounded t, the infinite-precision error in the Newton + * approximation barely affects third digit in the final error + * 0.667; the error in the rounded t can be up to about 3 23-bit ulps + * before the final error is larger than 0.667 ulps. + */ + u.value=t; + u.bits=(u.bits+0x80000000)&0xffffffffc0000000ULL; + t=u.value; + + /* one step Newton iteration to 53 bits with error < 0.667 ulps */ + s=t*t; /* t*t is exact */ + r=x/s; /* error <= 0.5 ulps; |r| < |t| */ + w=t+t; /* t+t is exact */ + r=(r-t)/(w+r); /* r-t is exact; w+r ~= 3*t */ + t=t+t*r; /* error <= 0.5 + 0.5/3 + epsilon */ + + return(t); +} + +#if (LDBL_MANT_DIG == 53) +openlibm_weak_reference(cbrt, cbrtl); +#endif diff --git a/src/openlibm/src/s_cbrt.c.o b/src/openlibm/src/s_cbrt.c.o new file mode 100644 index 0000000000000000000000000000000000000000..8f0dbf2e0c17fb9f8bcb76f0181d31aa3687f164 GIT binary patch literal 2072 zcmb<-^>JfjWMqH=Mg}_u1P><4z%YXa!FB*M9T@l+cp1_>`0I|P@oQZ0==|t$@TEfM z3Dy7q|JU38|Np+8zg>=zfuZwM<0A$JhKBD485lm)m%4F&;BR4KWMKHjFQ5xDXy@ux zt5$vDk9+|#>V?O_7Ybk#Jowii^f>rJk#%xKy(Z@ckAn{s(meR{4!l<4mv>=c0P8|h zGhYiyO&Y((i8OwV8#_Sue&QEU1=;h7Kkn2g{>U4j_#vx7(mgez`(%3%D}+j?ib3y#K3p}BnFFfMkt>X z>J||w%~%!0z*r%`D9yvpF@ceR0VFO1mGgvYhVrpdASEmeAOB;MW5$x=xWEcQt^_mS z1V5O?%D@4p5d_FRAYTa}gupCGFv-dw0j3dz9GJ<<0168*6G|w9X;uaeFpVHUd?6%v z!u?zvpPW=wqL<8|=i_VuA`C%<5r{Ab5hftQlmVm&WSSj_U|?WiVqjokW?*3W^B)41 zA&GSzlK4B2Ak0T+E(QB^Q@iFz6-c=jNv7 zl`!b#<(H)Dx%-9c7MCO@XG8hvd8K*V5_41G_EX3J`3sch zKw*Py6r}88V1UOTR1!ViNHak43QRpz8AAam(ij*RCO`$a85qE+0u-hoAy_(7gNj3y zgQUQ?6XYl`3za|@)?r`(r*U%i8$#_DLbZkgly^Zw1|R|n!`u&}LFp9aCUkWNK!OYm z4EjiVK}@JHI4nSXcc}d!HZpz>Q-~~xMQu0(0|O}iqNGU%28It%{pjw3xf^C|KGaNf z{R&V4Li)3C#6P$IWnh4pC!qKTm6b62Vet=gCe$jJlfZNURPY0s$H2hDz`%e_KS&Hc q?m=1{pn~A46C?n|Ap4+9FeL~rU%(tBLIPB{FfcGwB8h>R==uRuBP#0v literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_cbrtf.c b/src/openlibm/src/s_cbrtf.c new file mode 100644 index 0000000..6a3a762 --- /dev/null +++ b/src/openlibm/src/s_cbrtf.c @@ -0,0 +1,74 @@ +/* s_cbrtf.c -- float version of s_cbrt.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + * Debugged and optimized by Bruce D. Evans. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_cbrtf.c,v 1.18 2008/02/22 02:30:35 das Exp $"); + +#include + +#include "math_private.h" + +/* cbrtf(x) + * Return cube root of x + */ +static const unsigned + B1 = 709958130, /* B1 = (127-127.0/3-0.03306235651)*2**23 */ + B2 = 642849266; /* B2 = (127-127.0/3-24/3-0.03306235651)*2**23 */ + +OLM_DLLEXPORT float +cbrtf(float x) +{ + double r,T; + float t; + int32_t hx; + u_int32_t sign; + u_int32_t high; + + GET_FLOAT_WORD(hx,x); + sign=hx&0x80000000; /* sign= sign(x) */ + hx ^=sign; + if(hx>=0x7f800000) return(x+x); /* cbrt(NaN,INF) is itself */ + + /* rough cbrt to 5 bits */ + if(hx<0x00800000) { /* zero or subnormal? */ + if(hx==0) + return(x); /* cbrt(+-0) is itself */ + SET_FLOAT_WORD(t,0x4b800000); /* set t= 2**24 */ + t*=x; + GET_FLOAT_WORD(high,t); + SET_FLOAT_WORD(t,sign|((high&0x7fffffff)/3+B2)); + } else + SET_FLOAT_WORD(t,sign|(hx/3+B1)); + + /* + * First step Newton iteration (solving t*t-x/t == 0) to 16 bits. In + * double precision so that its terms can be arranged for efficiency + * without causing overflow or underflow. + */ + T=t; + r=T*T*T; + T=T*((double)x+x+r)/(x+r+r); + + /* + * Second step Newton iteration to 47 bits. In double precision for + * efficiency and accuracy. + */ + r=T*T*T; + T=T*((double)x+x+r)/(x+r+r); + + /* rounding to 24 bits is perfect in round-to-nearest mode */ + return(T); +} diff --git a/src/openlibm/src/s_cbrtf.c.o b/src/openlibm/src/s_cbrtf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..b506f817cc092f91c55a2cadd5011c78129093c8 GIT binary patch literal 1672 zcmb<-^>JfjWMqH=Mg}_u1P><4z`((bU^{@B4h(z@ybNjlbq707sQ&-|zuxx$|N46V z_Dc*544tPMA2Bd6G&DYBU}&i4Z)sy-VA#2O)v8q<{Ob>T9DJe3`bjcSi}O$#f8MJ! z{`a@j_}`!W%pY|(jbG#OXa1-YY5W=&Kk-LC{=^?~F^ym25R`r76My94G=7bnpZFv0 zKyVz0f8!H>Bos$n{=^?~`V)WT1qdB?@e_a4C4P-Vhtv4wT^JbnH7>LsD0%;xU%(XP z3$UX;^GAM22f%_~fLbk~Fz5T#3Tm2;*uf=odIJNrRF5+m84dbFzBTumLxLhB^4Jl=oRIIIC{y& zB_<4d$@#gtsd*&~dU^RJse0~yp}NH-iOJbeetKT1UO`cQL26M+C4(N=xYUgJw4%h^ zRIuGtAVB^Cg*6+RS&+QKzyJ>~s5~eYRwF!f+T1_p)*Xdp>I1wiowvWEl8 zhl#5(Fo0tR6xL8FFl7u<3}&Gc=)yV-3=AMM$<=QNwOS?8r*Qz8BqP`?gE7s zToD5ULq60@bp11k)SrbT{tKW6!r~be|DZAgW +#include +// VBS +//#include + +#include "fpmath.h" +#include "math_private.h" +#if defined(__i386__) +#include "i387/bsd_ieeefp.h" +#endif + +#define BIAS (LDBL_MAX_EXP - 1) + +static const unsigned + B1 = 709958130; /* B1 = (127-127.0/3-0.03306235651)*2**23 */ + +OLM_DLLEXPORT long double +cbrtl(long double x) +{ + union IEEEl2bits u, v; + long double r, s, t, w; + double dr, dt, dx; + float ft, fx; + u_int32_t hx; + u_int16_t expsign; + int k; + + u.e = x; + expsign = u.xbits.expsign; + k = expsign & 0x7fff; + + /* + * If x = +-Inf, then cbrt(x) = +-Inf. + * If x = NaN, then cbrt(x) = NaN. + */ + if (k == BIAS + LDBL_MAX_EXP) + return (x + x); + +#ifdef __i386__ + fp_prec_t oprec; + + oprec = fpgetprec(); + if (oprec != FP_PE) + fpsetprec(FP_PE); +#endif + + if (k == 0) { + /* If x = +-0, then cbrt(x) = +-0. */ + if ((u.bits.manh | u.bits.manl) == 0) { +#ifdef __i386__ + if (oprec != FP_PE) + fpsetprec(oprec); +#endif + return (x); + } + /* Adjust subnormal numbers. */ + u.e *= 0x1.0p514; + k = u.bits.exp; + k -= BIAS + 514; + } else + k -= BIAS; + u.xbits.expsign = BIAS; + v.e = 1; + + x = u.e; + switch (k % 3) { + case 1: + case -2: + x = 2*x; + k--; + break; + case 2: + case -1: + x = 4*x; + k -= 2; + break; + } + v.xbits.expsign = (expsign & 0x8000) | (BIAS + k / 3); + + /* + * The following is the guts of s_cbrtf, with the handling of + * special values removed and extra care for accuracy not taken, + * but with most of the extra accuracy not discarded. + */ + + /* ~5-bit estimate: */ + fx = x; + GET_FLOAT_WORD(hx, fx); + SET_FLOAT_WORD(ft, ((hx & 0x7fffffff) / 3 + B1)); + + /* ~16-bit estimate: */ + dx = x; + dt = ft; + dr = dt * dt * dt; + dt = dt * (dx + dx + dr) / (dx + dr + dr); + + /* ~47-bit estimate: */ + dr = dt * dt * dt; + dt = dt * (dx + dx + dr) / (dx + dr + dr); + +#if LDBL_MANT_DIG == 64 + /* + * dt is cbrtl(x) to ~47 bits (after x has been reduced to 1 <= x < 8). + * Round it away from zero to 32 bits (32 so that t*t is exact, and + * away from zero for technical reasons). + */ + volatile double vd2 = 0x1.0p32; + volatile double vd1 = 0x1.0p-31; + #define vd ((long double)vd2 + vd1) + + t = dt + vd - 0x1.0p32; +#elif LDBL_MANT_DIG == 113 + /* + * Round dt away from zero to 47 bits. Since we don't trust the 47, + * add 2 47-bit ulps instead of 1 to round up. Rounding is slow and + * might be avoidable in this case, since on most machines dt will + * have been evaluated in 53-bit precision and the technical reasons + * for rounding up might not apply to either case in cbrtl() since + * dt is much more accurate than needed. + */ + t = dt + 0x2.0p-46 + 0x1.0p60L - 0x1.0p60; +#else +#error "Unsupported long double format" +#endif + + /* + * Final step Newton iteration to 64 or 113 bits with + * error < 0.667 ulps + */ + s=t*t; /* t*t is exact */ + r=x/s; /* error <= 0.5 ulps; |r| < |t| */ + w=t+t; /* t+t is exact */ + r=(r-t)/(w+r); /* r-t is exact; w+r ~= 3*t */ + t=t+t*r; /* error <= 0.5 + 0.5/3 + epsilon */ + + t *= v.e; +#ifdef __i386__ + if (oprec != FP_PE) + fpsetprec(oprec); +#endif + return (t); +} diff --git a/src/openlibm/src/s_cbrtl.c.o b/src/openlibm/src/s_cbrtl.c.o new file mode 100644 index 0000000000000000000000000000000000000000..1ba849a0035d1bbbce2a52515cee928129acd5d4 GIT binary patch literal 2248 zcmb<-^>JfjWMqH=Mg}_u1P><4z`((ZU^{@B4h;MZd<-7lB`N~9b5uAwKcuPtufKWV zc8$u7G~566{4Ez585r)~NNYX7-;&12z`(!#fbM^L28LZA;^vFa<7u5CDi1u8FC6?Y z?~!>bEHpIqc8$u5+c_#XJPy88(EQnJ7?;jsN`tkIYLTlRxnb_^2GX36kO0xao25 zmBJ_fh?|;+x?MnO5B<02{G|H-|Nr_levQi@cYWBkdey2`9{lSMc^rJ9$ofe#P%Di; z@5N{SsH1888V^44M?!JLl~4SUhtl{pE`H(%u|YTv#J})~KN5-~Zhhj9IQ5A?@&<$! z0Egu#enA(N6QB5zco*)vsGPX#qH^IAf85P`2S4!(#;6>)lqky8J!pyUKafO|38gi-i3jo`32JruriP23op0-`~M$mUh@ma8wWsQ zi@{(&_vHj&rre0 zz{u3V(9l3ZBPcaR!6UH*Dxqtx$-uzEz`&ruz`y_s8h5`?1||l^10XS2T4aRsIiVJb zKxxLRAO^+?0Y+&ac8&>*3=AM~8K~S>m}V#+8wFCr!tn7wHaTW2Ie{Cjkd=W0Od|*Z zFq4%5LW4PALKIB0f&B+&LJ27_4e~9R0Vm|aEH*HSOsFt0FbE;J2ky7x_~fLbk{rEc z20b5VV-R5iB1}Pq0f;bS04snRW(M*w0|NsS0|Nsy0|UdK{}AAUBn}F9n0N+~ILNgy z@nuNjAlJgg&mxJlBbg71TaXh#_JS~o4aR!KmANH}Nep_$B}EWA1I8*!%}LZNNv$Yh z&`U`yNo3GVDlTTwE6N9P^pcB9ERZ=S40_4=xw)x%B@B9b`6a1(?tY=V#U+W!*-(CZ zUa4L|QGP*cQAs6(9@y;EjQF&o#N1S{LntFa{sVa(6c)%PLCQ)726%iyCDGG~Gy^0L zz|=#PF?;|;5(5K61yq2CfdQNfVChc+Dy{|NkYiFNAC;0|SEv)P9&dVbU=7!)QAk`U9Z)Vd`M|L1`4khSAbq@N6E0Kvi^lzzCNaSgHnCJyos)GClL9KV1H-hhgL>IjhAK^P + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* ccos() + * + * Complex circular cosine + * + * + * + * SYNOPSIS: + * + * double complex ccos(); + * double complex z, w; + * + * w = ccos (z); + * + * + * + * DESCRIPTION: + * + * If + * z = x + iy, + * + * then + * + * w = cos x cosh y - i sin x sinh y. + * + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * DEC -10,+10 8400 4.5e-17 1.3e-17 + * IEEE -10,+10 30000 3.8e-16 1.0e-16 + */ + +#include +#include +#include + +#include "math_private.h" + +/* calculate cosh and sinh */ + +static void +_cchsh(double x, double *c, double *s) +{ + double e, ei; + + if (fabs(x) <= 0.5) { + *c = cosh(x); + *s = sinh(x); + } + else { + e = exp(x); + ei = 0.5/e; + e = 0.5 * e; + *s = e - ei; + *c = e + ei; + } +} + +double complex +ccos(double complex z) +{ + double complex w; + double ch, sh; + + _cchsh( cimag(z), &ch, &sh ); + w = cos(creal (z)) * ch - (sin (creal (z)) * sh) * I; + return (w); +} + +#if LDBL_MANT_DIG == DBL_MANT_DIG +openlibm_strong_reference(ccos, ccosl); +#endif /* LDBL_MANT_DIG == DBL_MANT_DIG */ diff --git a/src/openlibm/src/s_ccosf.c b/src/openlibm/src/s_ccosf.c new file mode 100644 index 0000000..ce382f0 --- /dev/null +++ b/src/openlibm/src/s_ccosf.c @@ -0,0 +1,84 @@ +/* $OpenBSD: s_ccosf.c,v 1.2 2010/07/18 18:42:26 guenther Exp $ */ +/* + * Copyright (c) 2008 Stephen L. Moshier + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* ccosf() + * + * Complex circular cosine + * + * + * + * SYNOPSIS: + * + * void ccosf(); + * cmplxf z, w; + * + * ccosf( &z, &w ); + * + * + * + * DESCRIPTION: + * + * If + * z = x + iy, + * + * then + * + * w = cos x cosh y - i sin x sinh y. + * + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE -10,+10 30000 1.8e-7 5.5e-8 + */ + +#include +#include + +/* calculate cosh and sinh */ + +static void +_cchshf(float xx, float *c, float *s) +{ + float x, e, ei; + + x = xx; + if(fabsf(x) <= 0.5f) { + *c = coshf(x); + *s = sinhf(x); + } + else { + e = expf(x); + ei = 0.5f/e; + e = 0.5f * e; + *s = e - ei; + *c = e + ei; + } +} + +float complex +ccosf(float complex z) +{ + float complex w; + float ch, sh; + + _cchshf( cimagf(z), &ch, &sh ); + w = cosf( crealf(z) ) * ch + ( -sinf( crealf(z) ) * sh) * I; + return (w); +} diff --git a/src/openlibm/src/s_ccosh.c b/src/openlibm/src/s_ccosh.c new file mode 100644 index 0000000..110494a --- /dev/null +++ b/src/openlibm/src/s_ccosh.c @@ -0,0 +1,155 @@ +/*- + * Copyright (c) 2005 Bruce D. Evans and Steven G. Kargl + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Hyperbolic cosine of a complex argument z = x + i y. + * + * cosh(z) = cosh(x+iy) + * = cosh(x) cos(y) + i sinh(x) sin(y). + * + * Exceptional values are noted in the comments within the source code. + * These values and the return value were taken from n1124.pdf. + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_ccosh.c,v 1.2 2011/10/21 06:29:32 das Exp $"); + +#include +#include + +#include "math_private.h" + +static const double huge = 0x1p1023; + +OLM_DLLEXPORT double complex +ccosh(double complex z) +{ + double x, y, h; + int32_t hx, hy, ix, iy, lx, ly; + + x = creal(z); + y = cimag(z); + + EXTRACT_WORDS(hx, lx, x); + EXTRACT_WORDS(hy, ly, y); + + ix = 0x7fffffff & hx; + iy = 0x7fffffff & hy; + + /* Handle the nearly-non-exceptional cases where x and y are finite. */ + if (ix < 0x7ff00000 && iy < 0x7ff00000) { + if ((iy | ly) == 0) + return (CMPLX(cosh(x), x * y)); + if (ix < 0x40360000) /* small x: normal case */ + return (CMPLX(cosh(x) * cos(y), sinh(x) * sin(y))); + + /* |x| >= 22, so cosh(x) ~= exp(|x|) */ + if (ix < 0x40862e42) { + /* x < 710: exp(|x|) won't overflow */ + h = exp(fabs(x)) * 0.5; + return (CMPLX(h * cos(y), copysign(h, x) * sin(y))); + } else if (ix < 0x4096bbaa) { + /* x < 1455: scale to avoid overflow */ + z = __ldexp_cexp(CMPLX(fabs(x), y), -1); + return (CMPLX(creal(z), cimag(z) * copysign(1, x))); + } else { + /* x >= 1455: the result always overflows */ + h = huge * x; + return (CMPLX(h * h * cos(y), h * sin(y))); + } + } + + /* + * cosh(+-0 +- I Inf) = dNaN + I sign(d(+-0, dNaN))0. + * The sign of 0 in the result is unspecified. Choice = normally + * the same as dNaN. Raise the invalid floating-point exception. + * + * cosh(+-0 +- I NaN) = d(NaN) + I sign(d(+-0, NaN))0. + * The sign of 0 in the result is unspecified. Choice = normally + * the same as d(NaN). + */ + if ((ix | lx) == 0 && iy >= 0x7ff00000) + return (CMPLX(y - y, copysign(0, x * (y - y)))); + + /* + * cosh(+-Inf +- I 0) = +Inf + I (+-)(+-)0. + * + * cosh(NaN +- I 0) = d(NaN) + I sign(d(NaN, +-0))0. + * The sign of 0 in the result is unspecified. + */ + if ((iy | ly) == 0 && ix >= 0x7ff00000) { + if (((hx & 0xfffff) | lx) == 0) + return (CMPLX(x * x, copysign(0, x) * y)); + return (CMPLX(x * x, copysign(0, (x + x) * y))); + } + + /* + * cosh(x +- I Inf) = dNaN + I dNaN. + * Raise the invalid floating-point exception for finite nonzero x. + * + * cosh(x + I NaN) = d(NaN) + I d(NaN). + * Optionally raises the invalid floating-point exception for finite + * nonzero x. Choice = don't raise (except for signaling NaNs). + */ + if (ix < 0x7ff00000 && iy >= 0x7ff00000) + return (CMPLX(y - y, x * (y - y))); + + /* + * cosh(+-Inf + I NaN) = +Inf + I d(NaN). + * + * cosh(+-Inf +- I Inf) = +Inf + I dNaN. + * The sign of Inf in the result is unspecified. Choice = always +. + * Raise the invalid floating-point exception. + * + * cosh(+-Inf + I y) = +Inf cos(y) +- I Inf sin(y) + */ + if (ix >= 0x7ff00000 && ((hx & 0xfffff) | lx) == 0) { + if (iy >= 0x7ff00000) + return (CMPLX(x * x, x * (y - y))); + return (CMPLX((x * x) * cos(y), x * sin(y))); + } + + /* + * cosh(NaN + I NaN) = d(NaN) + I d(NaN). + * + * cosh(NaN +- I Inf) = d(NaN) + I d(NaN). + * Optionally raises the invalid floating-point exception. + * Choice = raise. + * + * cosh(NaN + I y) = d(NaN) + I d(NaN). + * Optionally raises the invalid floating-point exception for finite + * nonzero y. Choice = don't raise (except for signaling NaNs). + */ + return (CMPLX((x * x) * (y - y), (x + x) * (y - y))); +} + +OLM_DLLEXPORT double complex +ccos(double complex z) +{ + + /* ccos(z) = ccosh(I * z) */ + return (ccosh(CMPLX(-cimag(z), creal(z)))); +} diff --git a/src/openlibm/src/s_ccosh.c.o b/src/openlibm/src/s_ccosh.c.o new file mode 100644 index 0000000000000000000000000000000000000000..e52b594c143a4679edc6424627dd8142953e752c GIT binary patch literal 3952 zcmb<-^>JfjWMqH=Mg}_u1P><4z_5WE!FB*M9T@l-_!vBz-)MZ|7xYo#_{1;hq9X7D zB=?D5AVx*t6TbjNm_;RxU*j-LMnomegTL-r8o$O35aW_Z=Le62uM|8EzEJ4AsQUl^ z|N6#B+?IJErdZ`r}Xz`*%|zvTua14HA_|Nl)L_}g-r zKx{|7HV6K;2VnNf-P0WS+jSTj7(Vd}f}L>a6Te`HiUiCdGAjH3|Ns9#jbGz5R7j9V z1=SZRU|&E*InwwwjzCokgs4b>js3(gzzXtm8o$OVm|TnsNa=}B{E<9hpL;YP(KyU6 z-vCzU$zONDvGb%W=fP5AsK+cA85q*|H6DH9k9_orKj!u){)kH;J)ig^AAjPHybQ7z zWd31(c?Qm7{H-AW!_q;Q;c+Cvcz%eBzG;u}t8`sHlKrnd1|G zzaZFK@Q48OPJmqZvf>}egAU;I^1hzGt>@qW|43n0 z`wyHDPJtW>b|Qb96*%R@+)m@yIQWS_@)jtayfg$G0}dxa7jQJAC8`*3XoHj6;ZOX6 zF^C)i4lr=C0S6dJUy2F`%y%)Mlmr;9%D}|HcmN~@D`OdQJROH zV*(=sg9QTvgA7zIA7p?Fp8>N9BNrcs2X_t^A4do`(u3^ zf`Ne{0;<;^M7!`A)bVkESU54reJl(g|6^0YjHQNvR1d5S=%xyQ4Pa$}&|nUj07nNn zRKQ#~Aq8f!fk|XSo`Hcu2+3Y>7%(s}s4_5Mm<`gWjYHfJhqxIIac3OjVK~HnaEOD_ z0D2gJ+!=sFJt!e!Qy&TqhXPOhtn2T2?`oveb2 zgWL})Jz(zN4HXAb>`3tf%8#I=1yT>fAT|icfCy;10*S-&8G~MNWo}7g5`$iGNfCt3 zfU$~Fa}xDRQY%Ur^imQ_5*hT8ii;Wait<4mz2xE&3uKO=8G~MOer|4RUI~L!_@P?TSgT2xZWpa(WQH6uQ)C^0t`>NpB0kiS7m8x%&!#z5Ni z3=I200fi(1N^3}525D#60IGvPYSkDRz@<1e znSg}A_&=JxU_q!_7#l?EFff4Y7;^Q4%72i%gg}NNV^E@JV1T<5CIxdpjJAWi30=Pe zR6lxn!T2y5R6l_1H-K3Hr469^^`U$i1yT!Q!)Q?X4`YMGVK^SDAI68#=xRYp2$T?k#x9(etv)oDFy}xnEjyi0}_Jihov8o zf6(m)TLn$fCqN1q7#Kih49K78`axw0dfEZ$KLJwAz`zg%;viwDac~h(nTbum2B +#include + +#include "math_private.h" + +static const float huge = 0x1p127; + +OLM_DLLEXPORT float complex +ccoshf(float complex z) +{ + float x, y, h; + int32_t hx, hy, ix, iy; + + x = crealf(z); + y = cimagf(z); + + GET_FLOAT_WORD(hx, x); + GET_FLOAT_WORD(hy, y); + + ix = 0x7fffffff & hx; + iy = 0x7fffffff & hy; + + if (ix < 0x7f800000 && iy < 0x7f800000) { + if (iy == 0) + return (CMPLXF(coshf(x), x * y)); + if (ix < 0x41100000) /* small x: normal case */ + return (CMPLXF(coshf(x) * cosf(y), sinhf(x) * sinf(y))); + + /* |x| >= 9, so cosh(x) ~= exp(|x|) */ + if (ix < 0x42b17218) { + /* x < 88.7: expf(|x|) won't overflow */ + h = expf(fabsf(x)) * 0.5f; + return (CMPLXF(h * cosf(y), copysignf(h, x) * sinf(y))); + } else if (ix < 0x4340b1e7) { + /* x < 192.7: scale to avoid overflow */ + z = __ldexp_cexpf(CMPLXF(fabsf(x), y), -1); + return (CMPLXF(crealf(z), cimagf(z) * copysignf(1, x))); + } else { + /* x >= 192.7: the result always overflows */ + h = huge * x; + return (CMPLXF(h * h * cosf(y), h * sinf(y))); + } + } + + if (ix == 0 && iy >= 0x7f800000) + return (CMPLXF(y - y, copysignf(0, x * (y - y)))); + + if (iy == 0 && ix >= 0x7f800000) { + if ((hx & 0x7fffff) == 0) + return (CMPLXF(x * x, copysignf(0, x) * y)); + return (CMPLXF(x * x, copysignf(0, (x + x) * y))); + } + + if (ix < 0x7f800000 && iy >= 0x7f800000) + return (CMPLXF(y - y, x * (y - y))); + + if (ix >= 0x7f800000 && (hx & 0x7fffff) == 0) { + if (iy >= 0x7f800000) + return (CMPLXF(x * x, x * (y - y))); + return (CMPLXF((x * x) * cosf(y), x * sinf(y))); + } + + return (CMPLXF((x * x) * (y - y), (x + x) * (y - y))); +} + +OLM_DLLEXPORT float complex +ccosf(float complex z) +{ + + return (ccoshf(CMPLXF(-cimagf(z), crealf(z)))); +} diff --git a/src/openlibm/src/s_ccoshf.c.o b/src/openlibm/src/s_ccoshf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..619022151446503daa0796fc4c01e3c7fc0cd886 GIT binary patch literal 3880 zcmb<-^>JfjWMqH=Mg}_u1P><4z>vX>U^{@B4h;MZd=QF=RhzbW-0n2B8!59^T&-{WRDkfmX z1~7#_DlBRIb%)dV>rQsw>O9f-=>Px!^{ODk_W%F-dI$b##~OcuSp4lb7#J8FTE6kO zoM&KQXuZVWa-NZa!S?@uen@^v%QVEzcA5a(wx~Q;x<`-ZEg$r1MU*kj?f8OEG{Elr@t3&?^PpZOzi z@@qT>dy3;Te zk30o&EZmuJC-Q3?dKvTo|9^gY2T*K*{qUJz0Gu*FK8ZZ{(iSZ30*?O@X@{2oC1Maa z#2om{A9>=XEKHtX<02?rz-gyU3ldPJN|4ayZ{q_8Q{HWGfW+MX%pZCB<)eT9|EEnz zXMV8oWsnreT}S>w+y#T=>i% zd6{41FgW}nIrMcCG~Gcp`hYVkdVJ!JXdh5S-+%?u{J;PIr={t^(h?{h!MVw!`HclU zFKKkTsOW$L2vS^t_z=f{a}=n!fVcvjVFY7T6u_w!n*Crt4pCv@4;O``R6!RN8L*!u zz$se7qxp!%OOO-<+cPjU*fTIN)I+!o;BbVp85rE1ovjo!-2Fl|6%0-EjPwi@j0}uS z4Gawp6f}ZTQxrTBOP~_E=9&x)EDQ_`3JeSkpnUA^7s|lIz<2;81}j4up?prL1tL(I zu_}mxu|j}RnuncZ0wcr>8K|5h$N)z^fo3LOz5wPEj9h#Ij(i-R+!CO24yvXWM0@f% zFy-@cfS9;2$Q>*UAOB;MXU0;}^MDnyg8c<%LJ2`I&B}monHW?YOd%1{U^W|=L?%FC zC4^)z*slx>4C)LF3=I;-)ynt#OEZ;t-F=As&oFToH$O1P*Z*9O7{d3=E)f zFaX6h0|Ns%K0$sij!#a`FV0BQOJ>mXaW(`IMj*lfM3^u@BpH&6QWJC17?Lw{6VuZe z(h`%3(-`98b5c?(3gVMfD+#F6dwM-m66dzd@pki?PQ(}g6C9RB@C;-EYVGiN$f9OPV3*#r|`1r-N{4YGSq zBZ(vX_a%}zvU(!_@P?TSg zT2xZWpa(WQH6uQ)C^0t` + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* ccoshl + * + * Complex hyperbolic cosine + * + * + * + * SYNOPSIS: + * + * long double complex ccoshl(); + * long double complex z, w; + * + * w = ccoshl (z); + * + * + * + * DESCRIPTION: + * + * ccosh(z) = cosh x cos y + i sinh x sin y . + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE -10,+10 30000 2.9e-16 8.1e-17 + * + */ + +#include +#include + +long double complex +ccoshl(long double complex z) +{ + long double complex w; + long double x, y; + + x = creall(z); + y = cimagl(z); + w = coshl(x) * cosl(y) + (sinhl(x) * sinl(y)) * I; + return (w); +} diff --git a/src/openlibm/src/s_ccoshl.c.o b/src/openlibm/src/s_ccoshl.c.o new file mode 100644 index 0000000000000000000000000000000000000000..875c6ba32d2f8a94c757e0cd6f27b82fb66a9e1d GIT binary patch literal 1832 zcmb<-^>JfjWMqH=Mg}_u1P><4!0>_@!FB*M9T<2Sco;mI-&p)FQHemtFF^9QYg80G znvWz5T#3Tm2;*uf= zodIJNrRF5+m84dbFzBTumLxLhB^4Jl=q2ap=BDPAFzDswm!#^s`-SQjmn0@ zrFsQL`30#(C6x?%U=va^;?s%}b5p_AQA&XP0ZMD2FhVv9QWh{Uz|s*+4m~YNL-Q6) zJxtvNXrN4h3UGn)5(5JRC~QGO5+H(sfk6!_j#LbRW$uGXOakOqWKmE$1DQ##enY7J z2FQjoFfhRE*GChF*$<>;_?wUYIz@8g#os@+&|R3=9k(KpX}J y25trh29S~H`ayXLBo0*ur)EG61;r0s5b9TCz97_GWHAuC0%|C{009YN(GLJNF5B7w literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_ccosl.c b/src/openlibm/src/s_ccosl.c new file mode 100644 index 0000000..0d50483 --- /dev/null +++ b/src/openlibm/src/s_ccosl.c @@ -0,0 +1,82 @@ +/* $OpenBSD: s_ccosl.c,v 1.2 2011/07/20 19:28:33 martynas Exp $ */ + +/* + * Copyright (c) 2008 Stephen L. Moshier + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* ccosl() + * + * Complex circular cosine + * + * + * + * SYNOPSIS: + * + * long double complex ccosl(); + * long double complex z, w; + * + * w = ccosl( z ); + * + * + * + * DESCRIPTION: + * + * If + * z = x + iy, + * + * then + * + * w = cos x cosh y - i sin x sinh y. + * + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * DEC -10,+10 8400 4.5e-17 1.3e-17 + * IEEE -10,+10 30000 3.8e-16 1.0e-16 + */ + +#include +#include + +static void +cchshl(long double x, long double *c, long double *s) +{ + long double e, ei; + + if(fabsl(x) <= 0.5L) { + *c = coshl(x); + *s = sinhl(x); + } else { + e = expl(x); + ei = 0.5L/e; + e = 0.5L * e; + *s = e - ei; + *c = e + ei; + } +} + +long double complex +ccosl(long double complex z) +{ + long double complex w; + long double ch, sh; + + cchshl(cimagl(z), &ch, &sh); + w = cosl(creall(z)) * ch + (-sinl(creall(z)) * sh) * I; + return (w); +} diff --git a/src/openlibm/src/s_ccosl.c.o b/src/openlibm/src/s_ccosl.c.o new file mode 100644 index 0000000000000000000000000000000000000000..5ce2e596759676858e4c71798e308dfc18f0b475 GIT binary patch literal 2368 zcmb<-^>JfjWMqH=Mg}_u1P><4z|g>oU^{@B4h;MZd<-7VZ#4dwsCXdb7a;j~$B3H; zZriBbu2B&H3)}>o;27x`b^qht8@F{-_?xCPFn|mYfGJb}EA(i7BXGM$Md5aiiotCg z6{y$|1&~R|)_~Yx$%rVJvYQWX=cp*$I|fXV_Y5ejo5NE*^>ViCU^T3TyH&5L=dGo-HM<9hD=S0T6O#A=;KS-K^ z!5%_^$%cP0p1ZTNm4b%5U#O;np^2W6o}q$~fsv_!p`n3-Mo?;sf=6NrR6^HWlYxPS zfq_ARfq?-OSnhtI3``7+2S8%5IAMhHnZedDFo-~D#;PC&#tH#OX&!ct35*O3DGUq@ zGEg~IkY*P?0~bCE7d{6UJ`WeZ05?7lCq9QTJ_{#4gFrrqAijVQJ_8R_1&(|U5n#nG zd=V~u37#M>hcCz+hh#nrM?M3n`Pe9sl`IS&p+SSHf*DH+;|41M`5MfC69Qls8<<2U zL>U+ugpkYu`;mcxL7IVq0ip+4H3NeZ4si_};(9p5O>l@?;}93aAr8tz*xbob9G{$= zU!0?t%%JDvYycvR8Neb8$(gx{={XE(iAlvd49WS$895BanRyvG49P{Qi8)|S4nt~1 zK@Q00pzs0FptJ)Dy+8jUKn*0w07+-;3=9k~aUG~Q69WSSC~d*S{h{I@b2yOHCnJe- zB8fL3iE|-|cOi*`;u>cDY9w)F_1lred63L`fF#a~B>oI44st)ptuXUJc?l#15(i-r z8;tdeD|1T{lNj`hONtmdnv_cu z%^38O^K)}k^GX=>^72bk_1yhJb&E?9le3}x^t@8Nf};F_)S{9~20gIhsTuKUMTxno zV3$xtfcyu_YoItrHVBlyKzvxf0I@+BJOpEi_y#BuFfcH1fDC6~U;xDd zhzUvqAbAN8!N9-(N>3nhsB)+%1A{9_5Y9s|(1k(i4rC^|`VAQvz@>l?!U{0U18Nb- zZ(so^0pr7HI~@80p!(6n3&w}hK2ZJWWnltTzdqDn7zGsuyBQ=F3e^u{BjbLULS#WK zYC%Z|l#fx;HUk3#s15*WMRyk{tU=;1TnjZ5UH<{7{jmHDQ;)8{0$P@!r=JJV0EVR# zQ2GJoZ +#include + +#include "math_private.h" + +static const double huge = 1.0e300; + +OLM_DLLEXPORT double +ceil(double x) +{ + int32_t i0,i1,j0; + u_int32_t i,j; + EXTRACT_WORDS(i0,i1,x); + j0 = ((i0>>20)&0x7ff)-0x3ff; + if(j0<20) { + if(j0<0) { /* raise inexact if x != 0 */ + if(huge+x>0.0) {/* return 0*sign(x) if |x|<1 */ + if(i0<0) {i0=0x80000000;i1=0;} + else if((i0|i1)!=0) { i0=0x3ff00000;i1=0;} + } + } else { + i = (0x000fffff)>>j0; + if(((i0&i)|i1)==0) return x; /* x is integral */ + if(huge+x>0.0) { /* raise inexact flag */ + if(i0>0) i0 += (0x00100000)>>j0; + i0 &= (~i); i1=0; + } + } + } else if (j0>51) { + if(j0==0x400) return x+x; /* inf or NaN */ + else return x; /* x is integral */ + } else { + i = ((u_int32_t)(0xffffffff))>>(j0-20); + if((i1&i)==0) return x; /* x is integral */ + if(huge+x>0.0) { /* raise inexact flag */ + if(i0>0) { + if(j0==20) i0+=1; + else { + j = i1 + (1<<(52-j0)); + if(jJfjWMqH=Mg}_u1P><4z_5ZD!FB*M9T@l+cp1_>`0EaNbY5`myx?*0g+k}S z&f|`qhYtP}X?*yfoq?fuBjca{|C|2_*Qd39mMwWYduiM=eUc3K>(!Z@-IimLyq4sx*8sE={)bE zc-^J*fXBh-3Lc!t(>(a|&ZqHf96X#hq4}S2oixbk#(xYf3=E|&KJiDKc>O4iU%mxo zI78!0VHO4kkPH6*2Pt#B{L-=YV#z@a+ZVJRsFQ2{CsLBS(}aP6!EpyDRGJSkYJPOQ z{J@d%0>9G_kZTlAye$3?G74%wx;gx9A^-pXZ#__<)_L94@Brs={ubx||Nrl2VEADF z((?cR|NQa|AcyrTFVEm=cwj#R14F}0+5i9lGcYjBDP`!ed17A2;O^{frJ&*N z7pkdXXrgDNXQ*IgU}S1wXlS6I5tN#u;E`AYmC!ZUWB~b{L4kpR0TiU}exVFZ42%a@ z7#QGj%LwIjf-GlXU=V@Qj8#Dlj1>Zm(md=O6Br@lGEli#P!K@bxG0bk7KV=?r(-B# zhTD#i;sP^4t^_mS1U~}xZTC^$*Gw+ddUoWKF$UVAU0T!ADCodU}9ik043Ew z{~_QE4sj8XLm4pDgTf4?1!N8ggVK`$@ABvsGdFI2aNh}E#K6F?0;*phO&lr=Pr>d`{b2P z=TiNYCkl(V8RR>Pys^vvv9<}05n2i@eGQ8P?-X=A0`fRCe$jp-5`bqRImcX zVPIh3f!c$vA7m!fDyT{bwE?OhR(?T55#=0=F9D?u9bJ6ae3j B1lRxo literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_ceilf.c b/src/openlibm/src/s_ceilf.c new file mode 100644 index 0000000..5e2a568 --- /dev/null +++ b/src/openlibm/src/s_ceilf.c @@ -0,0 +1,53 @@ +/* s_ceilf.c -- float version of s_ceil.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_ceilf.c,v 1.8 2008/02/22 02:30:35 das Exp $"); + +#include + +#include "math_private.h" + +static const float huge = 1.0e30; + +OLM_DLLEXPORT float +ceilf(float x) +{ + int32_t i0,j0; + u_int32_t i; + + GET_FLOAT_WORD(i0,x); + j0 = ((i0>>23)&0xff)-0x7f; + if(j0<23) { + if(j0<0) { /* raise inexact if x != 0 */ + if(huge+x>(float)0.0) {/* return 0*sign(x) if |x|<1 */ + if(i0<0) {i0=0x80000000;} + else if(i0!=0) { i0=0x3f800000;} + } + } else { + i = (0x007fffff)>>j0; + if((i0&i)==0) return x; /* x is integral */ + if(huge+x>(float)0.0) { /* raise inexact flag */ + if(i0>0) i0 += (0x00800000)>>j0; + i0 &= (~i); + } + } + } else { + if(j0==0x80) return x+x; /* inf or NaN */ + else return x; /* x is integral */ + } + SET_FLOAT_WORD(x,i0); + return x; +} diff --git a/src/openlibm/src/s_ceilf.c.o b/src/openlibm/src/s_ceilf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..9054728965b72532ca9f8b530e46469d233ac2c0 GIT binary patch literal 1728 zcmb<-^>JfjWMqH=Mg}_u1P><4z~I1)#0E1R82A`?8PfRc4s;$o_*0yJ+sWpa_02!U z>TOz2R(S0C|G%E$@~_qlC8nSG1w=tQ()iz>{LCM5fnWb(nL_JN~MFqAkP=9dRC7_e!6{Fz^X6=Y)Tfr{&C{B(&_vHj&rre0z{u3V(9l3ZBPcaR!6UH* zDxqtx3DL~Lz`&ruz`y{qz}+vDfr)|f07wiLMvPECCqy}e2$W{53SwZa5MY$%Vdt2@ z$N(0Xfy&K=()cKl`78_{|6^0bj3tJ+!3tR!IKVW55CAhlt_L&V1UN<*SQ$WmfeSJ) zFi0^lFbE-;4|i*Ed~#}LPMTgagPxDGF^Dh#5k?GPVFq=mAxsPm44|a)=RX9b;1I7w z5(l{froID79OP=4I4BN4QXum|7{mr+z2eH;lEfqiz2cH02%Q0A6{Y4R>XoEclrZR} zB$gyH=p_{wGw2oNgE)H0#U&;Tddc~@xv6<240?I_C8>JuexbU>C5g$|P=0z|sa`=* zenDzcNhO0G*tpb;__U(L+*GjLR3Je90>w2OnpqA|K0N%Pd`NskISdR8(hLmXIE1N( z$#_5mDFG?~N*^G5VCh2wDz3)B0FG@?oI!=a)Lk%%Nr22i7S&;30H--}^&3L%7eY3a zfq~%xl+OdDVH7B>fY>nF4yxY(B#4CHK-v0G8b-m~52M|o`eE`gS{kMRCIF?;g~J&b z7}yyY7@)xoRmH%d09A +#include +#include + +#include "fpmath.h" +#include "math_private.h" + +#ifdef LDBL_IMPLICIT_NBIT +#define MANH_SIZE (LDBL_MANH_SIZE + 1) +#define INC_MANH(u, c) do { \ + u_int64_t o = u.bits.manh; \ + u.bits.manh += (c); \ + if (u.bits.manh < o) \ + u.bits.exp++; \ +} while (0) +#else +#define MANH_SIZE LDBL_MANH_SIZE +#define INC_MANH(u, c) do { \ + u_int64_t o = u.bits.manh; \ + u.bits.manh += (c); \ + if (u.bits.manh < o) { \ + u.bits.exp++; \ + u.bits.manh |= 1llu << (LDBL_MANH_SIZE - 1); \ + } \ +} while (0) +#endif + +static const long double huge = 1.0e300; + +OLM_DLLEXPORT long double +ceill(long double x) +{ + union IEEEl2bits u = { .e = x }; + int e = u.bits.exp - LDBL_MAX_EXP + 1; + + if (e < MANH_SIZE - 1) { + if (e < 0) { /* raise inexact if x != 0 */ + if (huge + x > 0.0) + if (u.bits.exp > 0 || + (u.bits.manh | u.bits.manl) != 0) + u.e = u.bits.sign ? -0.0 : 1.0; + } else { + u_int64_t m = ((1llu << MANH_SIZE) - 1) >> (e + 1); + if (((u.bits.manh & m) | u.bits.manl) == 0) + return (x); /* x is integral */ + if (!u.bits.sign) { +#ifdef LDBL_IMPLICIT_NBIT + if (e == 0) + u.bits.exp++; + else +#endif + INC_MANH(u, 1llu << (MANH_SIZE - e - 1)); + } + if (huge + x > 0.0) { /* raise inexact flag */ + u.bits.manh &= ~m; + u.bits.manl = 0; + } + } + } else if (e < LDBL_MANT_DIG - 1) { + u_int64_t m = (u_int64_t)-1 >> (64 - LDBL_MANT_DIG + e + 1); + if ((u.bits.manl & m) == 0) + return (x); /* x is integral */ + if (!u.bits.sign) { + if (e == MANH_SIZE - 1) + INC_MANH(u, 1); + else { + u_int64_t o = u.bits.manl; + u.bits.manl += 1llu << (LDBL_MANT_DIG - e - 1); + if (u.bits.manl < o) /* got a carry */ + INC_MANH(u, 1); + } + } + if (huge + x > 0.0) /* raise inexact flag */ + u.bits.manl &= ~m; + } + return (u.e); +} diff --git a/src/openlibm/src/s_ceill.c.o b/src/openlibm/src/s_ceill.c.o new file mode 100644 index 0000000000000000000000000000000000000000..55b8a0cb4cca9d7a25322d21d91ed1b86fd07b26 GIT binary patch literal 2056 zcmb<-^>JfjWMqH=Mg}_u1P><4z|g^hU^{@B4h(z@ybQNao(nIm12j@@zmI$Z@9~FU?w-vTK*hFU`$hGXmD&i$-uzS0C9p#r;o}T7tRA|oh~XLK-S!0 z1$p4+yPGHPf4qC6Oz``)<1Q*MKw>V6=Q>MN-rUYnd2u+6U)}}eP>_!1Uv~Wc7a15B zJi1F@uJ$;70OW3u%P%@Vc79hp=+SzTzhx~0NQ*}|#HmTmzvTH_9x^a6cKQEFfhQ}|I+dQ|Njhg zN*OwAo|xA$xH~&rDQLL+g=#7on&=tn87deV7?~Ov8X72Q1f`}ZcqEoUC3MX-85lsx zQGtPh0Th+)exVFZ42%arVxU9;vX~LdX9jT?7#KvLG-Fi|17n2%qcjgY#{@=*xC~Uz zo(ampLxId^VfgqTn-XR$Ifomp5adcQ15OAqFfa%qsfXKL9G{$;nUkZJ%%JDvY{UTO zFfcG|gX#o15#*;optSe@|Nl0SgBTbX(8br_5C?@B$S9C{5C*ZqSg*J;wlBR;JtF*g-#Hx&qwzd&AQLo*9fRxvQZ z!xt(K3V$dQOi439(iBWRSdf8%VFf6#K^Y$^0E$nLJseQJ1e8`|U;xJ^R5?_XfuSBH zkm15$wFn*qgAM}&1ISEr^&3L%7eY1^RNg@C2bqm51>?hLJE(pGWJL@N3>{GY`e@>y zFaQa`Xm_Z7kQg%F4%Lq=24chXf!H7%&cMLH4o$}(J`C@G>PL4M%-t|``B3|z%3;C` zFQ5X1^k?CS{}0dzfyFZ@{yCv>1+oMt4)PDwDv&T7OF;EkKt*_<_Q2c^(+@HesuZdc rLQQ}Qib1$=5@a8o!@$5G$iTn=Rf;UkzyT^085kHUQA8nW6 + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_cexp.c,v 1.3 2011/10/21 06:27:56 das Exp $"); + +#include +#include + +#include "math_private.h" + +static const u_int32_t +exp_ovfl = 0x40862e42, /* high bits of MAX_EXP * ln2 ~= 710 */ +cexp_ovfl = 0x4096b8e4; /* (MAX_EXP - MIN_DENORM_EXP) * ln2 */ + +OLM_DLLEXPORT double complex +cexp(double complex z) +{ + double x, y, exp_x; + u_int32_t hx, hy, lx, ly; + + x = creal(z); + y = cimag(z); + + EXTRACT_WORDS(hy, ly, y); + hy &= 0x7fffffff; + + /* cexp(x + I 0) = exp(x) + I 0 */ + if ((hy | ly) == 0) + return (CMPLX(exp(x), y)); + EXTRACT_WORDS(hx, lx, x); + /* cexp(0 + I y) = cos(y) + I sin(y) */ + if (((hx & 0x7fffffff) | lx) == 0) + return (CMPLX(cos(y), sin(y))); + + if (hy >= 0x7ff00000) { + if (lx != 0 || (hx & 0x7fffffff) != 0x7ff00000) { + /* cexp(finite|NaN +- I Inf|NaN) = NaN + I NaN */ + return (CMPLX(y - y, y - y)); + } else if (hx & 0x80000000) { + /* cexp(-Inf +- I Inf|NaN) = 0 + I 0 */ + return (CMPLX(0.0, 0.0)); + } else { + /* cexp(+Inf +- I Inf|NaN) = Inf + I NaN */ + return (CMPLX(x, y - y)); + } + } + + if (hx >= exp_ovfl && hx <= cexp_ovfl) { + /* + * x is between 709.7 and 1454.3, so we must scale to avoid + * overflow in exp(x). + */ + return (__ldexp_cexp(z, 0)); + } else { + /* + * Cases covered here: + * - x < exp_ovfl and exp(x) won't overflow (common case) + * - x > cexp_ovfl, so exp(x) * s overflows for all s > 0 + * - x = +-Inf (generated by exp()) + * - x = NaN (spurious inexact exception from y) + */ + exp_x = exp(x); + return (CMPLX(exp_x * cos(y), exp_x * sin(y))); + } +} diff --git a/src/openlibm/src/s_cexp.c.o b/src/openlibm/src/s_cexp.c.o new file mode 100644 index 0000000000000000000000000000000000000000..8c187d32301774f29d735607713e6e22eb258d38 GIT binary patch literal 2168 zcmb<-^>JfjWMqH=Mg}_u1P><4z+l0OU^{@B4h*~uJPeLuX`cLb$AUeY-$;Do7vxcS z0h0X0FTkUc=D}ZgIL(tk?-;7sp)`Jt3m%;pJPy84Q2qb^e?8}+k^+y;TOJ2rDRf?I zd%%wDb4Uk!n@+}}`44?P~T~s*IJopg`LsU2*y7@H@!8FULeBu`XOGMrPJIjN= z?lxF5jbGygSo>liYpx0QFAD<$g8~Bs11P%P{X!X-7#I(L#9(QH5z6NTt7c#jfzpgs zK@5x)0*ul;>>Lvq85m+17#L)ra&tkNo%jU$nB4dznweer447)T_#_VgF3_?ia zV7D?bFmN$2FbH6n01?9`E`~$BJPvVX9OCLY#2Jd?lT#}S^pY8pi&7JF7?Lw{6Vn;u z<8x9{D+<6;49WS$48@sw5Jw9^Cab<2v zViJR1aY+$`&VaFsQgagZN>VFI81zySOA;CMl8TEN^pf*)b5rw581(Y;OH%dR{X%t% zOA?c_q5Sl`QoVwr{DRb?l1c_WunDOd@o7bgxv605C?!Dt0C^qcH)OLQWh(;%EFHq+ z(9@hWG>l>DVd`!$Ls&N;6gVA&>;Z*2NJs)iFfcHH(g8>usvIiHz;G8N2<^i*$<4kuZHAHVAt$Fff49 zIl6KIr~taVKz;@3gW)8o{ZQpFVFm}NKm}X`!a&y_izEIvfHD*V0|P9cK;;lfF9?H7 zf{BCt1GNey497d5f*+tFpt2GaN9g)Nc?~2ERR*V4Kn1noA`k}1J_rj!3NkP-K$SuS QpyUat`*Wat7=^AM00OE)>i_@% literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_cexpf.c b/src/openlibm/src/s_cexpf.c new file mode 100644 index 0000000..05f4544 --- /dev/null +++ b/src/openlibm/src/s_cexpf.c @@ -0,0 +1,89 @@ +/*- + * Copyright (c) 2011 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_cexpf.c,v 1.3 2011/10/21 06:27:56 das Exp $"); + +#include +#include + +#include "math_private.h" + +static const u_int32_t +exp_ovfl = 0x42b17218, /* MAX_EXP * ln2 ~= 88.722839355 */ +cexp_ovfl = 0x43400074; /* (MAX_EXP - MIN_DENORM_EXP) * ln2 */ + +OLM_DLLEXPORT float complex +cexpf(float complex z) +{ + float x, y, exp_x; + u_int32_t hx, hy; + + x = crealf(z); + y = cimagf(z); + + GET_FLOAT_WORD(hy, y); + hy &= 0x7fffffff; + + /* cexp(x + I 0) = exp(x) + I 0 */ + if (hy == 0) + return (CMPLXF(expf(x), y)); + GET_FLOAT_WORD(hx, x); + /* cexp(0 + I y) = cos(y) + I sin(y) */ + if ((hx & 0x7fffffff) == 0) + return (CMPLXF(cosf(y), sinf(y))); + + if (hy >= 0x7f800000) { + if ((hx & 0x7fffffff) != 0x7f800000) { + /* cexp(finite|NaN +- I Inf|NaN) = NaN + I NaN */ + return (CMPLXF(y - y, y - y)); + } else if (hx & 0x80000000) { + /* cexp(-Inf +- I Inf|NaN) = 0 + I 0 */ + return (CMPLXF(0.0, 0.0)); + } else { + /* cexp(+Inf +- I Inf|NaN) = Inf + I NaN */ + return (CMPLXF(x, y - y)); + } + } + + if (hx >= exp_ovfl && hx <= cexp_ovfl) { + /* + * x is between 88.7 and 192, so we must scale to avoid + * overflow in expf(x). + */ + return (__ldexp_cexpf(z, 0)); + } else { + /* + * Cases covered here: + * - x < exp_ovfl and exp(x) won't overflow (common case) + * - x > cexp_ovfl, so exp(x) * s overflows for all s > 0 + * - x = +-Inf (generated by exp()) + * - x = NaN (spurious inexact exception from y) + */ + exp_x = expf(x); + return (CMPLXF(exp_x * cosf(y), exp_x * sinf(y))); + } +} diff --git a/src/openlibm/src/s_cexpf.c.o b/src/openlibm/src/s_cexpf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..4714e931107113fda0135f19e80f19ff1deafa52 GIT binary patch literal 2128 zcmb<-^>JfjWMqH=Mg}_u1P><4z#zbiU^{@B4h*~uJPeK@X&(G_2SOb?k9Zt>p%CoR z{KlZuMMdW`zo3hX#%KOI7Zr_87Zr{dAU&V?1!7b(Xj(+ABj8Rbmt5E>U zr}5Vv?!49b=>Px!^(DETFFRi}J_ND(Tb?p7Ff{)9|G&PzOt$eS14Bc7X>IFU{*JE< z3=I4lC(`)yu72i^Iq}*pEtBwQK4K6Z z>lpJA3bGLnVi<9}?@%ve&YA_D`15Ry39O$-bSAZrA$7$U^Lz<^C$ z5{I}F4smrH;yO6Q8H(eRQ!5J6^pY8pi&7JF(ioC6a}(3k7~`1*#ibIt{MHv{5fE)$qAsFbwp!5ndlU)6VQ2PxK zR)ASB`}M&*1Oc-jMq5GkBUC_GpJ56hTsVm??8U&q07}m&X^4S=;RjS9y1PJrg&W4e zz>oyBA6>r&R3HIaF#`hwy8c)k@z(*$m<$XIuy_K+A4o3 + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* cexpl() + * + * Complex exponential function + * + * + * + * SYNOPSIS: + * + * long double complex cexpl(); + * long double complex z, w; + * + * w = cexpl( z ); + * + * + * + * DESCRIPTION: + * + * Returns the exponential of the complex argument z + * into the complex result w. + * + * If + * z = x + iy, + * r = exp(x), + * + * then + * + * w = r cos y + i r sin y. + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * DEC -10,+10 8700 3.7e-17 1.1e-17 + * IEEE -10,+10 30000 3.0e-16 8.7e-17 + * + */ + +#include +#include + +long double complex +cexpl(long double complex z) +{ + long double complex w; + long double r; + + r = expl(creall(z)); + w = r * cosl(cimagl(z)) + (r * sinl(cimagl(z))) * I; + return (w); +} diff --git a/src/openlibm/src/s_cexpl.c.o b/src/openlibm/src/s_cexpl.c.o new file mode 100644 index 0000000000000000000000000000000000000000..0f19b970b7b9506c7c3c1926ff126ea119897048 GIT binary patch literal 1776 zcmb<-^>JfjWMqH=Mg}_u1P><4z_5WC!FB*M9T<2Sco;mI-)Q_VQSm^=FF^7UQMYYW zz^vOfDgysYR3eZuSi+>liYpw}$A_%iEFfb@E zFfgz(Ffh3Lg)%TPFdhJjf#g7#5z2>!i3muLfq{XsDu{uxLV!`4hn-^rBLjmA0|SE$ zRIUp|yYLyf@L9O&E_@L#d4q>R=2tE#wPOKPYKMTXh z|JWp%vBVfR0|SE)k~r8+3=9l{3=9kcSPbF8AufSKTpowG3J!6G;`rp$ih>-yWCk$J zkX)3Sn3KbhoSB=Lp2JX_nU}+moL`&+bDAiW0g4L{{_`IKK=y*9Kw_XcgNa*!1Q{3@ zK;mo+3=A-FP`rSoK;rC3;>jREEb8--#6htEGY6DLKvGN$3=AL)VuP_>ab<2vViJR1 zaY+$`&VaFsQgagZN>VFI81zySOA;CMl8TEN^pf*)b5rw581(Y;OH%dR{X%t%OA?c_ zq5Sl`QoVwr{DRb?l1c_WunDOd@o7bgxv605C?!Dt0Hq~R7$KVl$AB$<=QN zwch~QPzDCL{rYI)F#BP&6;wZ(GKQb%0#H6oAC$}B#lXM-N{7(kf(bLgvMRc}VBrT- zm;|*SUB3a;q6C;iD2=W^7DxPPKm!yOPoVe%=>=hsQ800kHRyJO + +#include "math_private.h" + +OLM_DLLEXPORT double +cimag(double complex z) +{ + return (__imag__ z); +} diff --git a/src/openlibm/src/s_cimag.c.o b/src/openlibm/src/s_cimag.c.o new file mode 100644 index 0000000000000000000000000000000000000000..38c956dbb69726b4b95496305a89c49065ccb73d GIT binary patch literal 1232 zcmb<-^>JfjWMqH=Mg}_u1P><4z;FRc&;cy$z`(=6&5*{gaquvMyR);Ef`+?asHTFU ziJp<3p@NZtk*R^9p@D)%P-=>TM`8(7Lf2dqteb^_fkA8+ zW(^~h&k0t|z#syp8LNUA7%K!ArFqynCNM(8WuS5(v!G0z6v%uQhL8WTDPYFpb8ZF( z1|cMIxE;mu$(gx{>3YcwU>ar~$WI_P69WSS2!q&QtXEu_TauW>pjTW{1fervtdi7< z5(d4L#F9h?y`5(d4z{E}2XcfU~G;*!MVY$!iHuT-y~D8C@JsHBoX zuP8MqQ7<(kKCLJ*Hx+CXMT9g11K780Xr@5o91>s1QUb^v1_lO2sD5TNaaS}xj0=hn z7#l>ZGcYi4FfcHXt6v9dzX8ZFBn-1(A4v?vgxL?HO`-Zha>%#@nS;cJ>4OP@>|sZb zdj$?-Q2SBR4g&+j3a~5#10nqp3=9mQd<2Uxs5XWGs6!>70-$^a zawp7wm^eroy4@fxH$Vgf149Co=7Po%x_*$k=y3^FaQ8~{6}{H literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_cimagf.c b/src/openlibm/src/s_cimagf.c new file mode 100644 index 0000000..8287412 --- /dev/null +++ b/src/openlibm/src/s_cimagf.c @@ -0,0 +1,37 @@ +/*- + * Copyright (c) 2004 Stefan Farfeleder + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/msun/src/s_cimagf.c,v 1.3 2009/03/14 18:24:15 das Exp $ + */ + +#include + +#include "math_private.h" + +OLM_DLLEXPORT float +cimagf(float complex z) +{ + return (__imag__ z); +} diff --git a/src/openlibm/src/s_cimagf.c.o b/src/openlibm/src/s_cimagf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..470374bb3788323375fbeb73980cdf03258207a8 GIT binary patch literal 1232 zcmb<-^>JfjWMqH=Mg}_u1P><4z;FRc&;cy$z`(=6&A@-`K^72bk_1yhJb&E?9le3}x^t@8Nf};F_)S{9~ z2EC%xoJ76UjQF&o#N1S{O%xH*3=Cl3vZ0v*iE~JNAxjA$a~K#H6ruW=(ZpTR_%JRg zK45GRtSB?1hR)6 zJ?{D^v3ke T0#HT + +#include "math_private.h" + +OLM_DLLEXPORT long double +cimagl(long double complex z) +{ + return (__imag__ z); +} diff --git a/src/openlibm/src/s_cimagl.c.o b/src/openlibm/src/s_cimagl.c.o new file mode 100644 index 0000000000000000000000000000000000000000..e6492939c0e9d7bb81351b48f4b8618d3ebdd15d GIT binary patch literal 1232 zcmb<-^>JfjWMqH=Mg}_u1P><4z;FRc&;cy$z`(=6&2T$MMdC1nyR);Ef`+?asHTFU ziJp<3p@NZtk*R^9p@D)%P-=>TM`8(7Lf2dqteb^_fkA8+ zEXlyYzzF5TtQCPuFjfUIFjfdKO7pODOkiYS0Ex>$_G3=9k)3}S<^UU6k^Nn#R%UU5kggwBAm zN>VFI81zySOA;CMl8TEN^pf*)b5rw581(Y;OH%dR{X%t%OA?c_q5Sl`QoVwr{DRb? zl1c`>qSTy3z0{2Ow4%h^RIp7H5z^qWXJBAMGX)aokoZED5 + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* clog.c + * + * Complex natural logarithm + * + * + * + * SYNOPSIS: + * + * double complex clog(); + * double complex z, w; + * + * w = clog (z); + * + * + * + * DESCRIPTION: + * + * Returns complex logarithm to the base e (2.718...) of + * the complex argument x. + * + * If z = x + iy, r = sqrt( x**2 + y**2 ), + * then + * w = log(r) + i arctan(y/x). + * + * The arctangent ranges from -PI to +PI. + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * DEC -10,+10 7000 8.5e-17 1.9e-17 + * IEEE -10,+10 30000 5.0e-15 1.1e-16 + * + * Larger relative error can be observed for z near 1 +i0. + * In IEEE arithmetic the peak absolute error is 5.2e-16, rms + * absolute error 1.0e-16. + */ + +#include +#include +#include + +#include "math_private.h" + +double complex +clog(double complex z) +{ + double complex w; + double p, rr; + + /*rr = sqrt( z->r * z->r + z->i * z->i );*/ + rr = cabs(z); + p = log(rr); + rr = atan2 (cimag (z), creal (z)); + w = p + rr * I; + return (w); +} + +#if LDBL_MANT_DIG == DBL_MANT_DIG +openlibm_strong_reference(clog, clogl); +#endif /* LDBL_MANT_DIG == DBL_MANT_DIG */ diff --git a/src/openlibm/src/s_clog.c.o b/src/openlibm/src/s_clog.c.o new file mode 100644 index 0000000000000000000000000000000000000000..325a8857b71217d2cdadbb4c07ab5016ea0faccd GIT binary patch literal 1672 zcmb<-^>JfjWMqH=Mg}_u1P><4z~I4*U^{@B4h*~uJPeLu!D$}+b%#Bg-$;Do7xYo# zcma|H6QB46d{j6-@e8u3qIFZKx{=g^x$b+Bw zBUn^CnvY0CJH{PmaCdgLQqXYs3)NIGG|@BCGgL4#FfuhTG&E4q2ue*+@JK9yO6Zzv zGO#c(FeorEFt9Q(Fu41LGB7bP9sr5K{Kg37bAnvUz`!5^r5US&7#J%A7^QjGIVLbN zFsLvvFvvjVGC{NxpFkgzBcDVwvnQVcQzV~+BcFg19|uSZ8wT0O!tn7wHaTW2A25`LH@y}UJ8eLP*`D8&rlqnoRgofm&^d77?Kl{iW!oN zQWJ9+k~4D?(-{&=67!507#M`1ZUcoe2>mrG>F)%Q|#GR1D*^$J3 zki1jRQEE=2UP)?234>lrVo4%{ zUQ%%}gI;oeZflK$U`o;n)Kt!N36b2dKON#SyxGP&o(^hiil~6rhHJ(g#!s bOhJtWvq6L)0|Ns#{WqZcb3lraFuHyKwD_R! literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_clogf.c b/src/openlibm/src/s_clogf.c new file mode 100644 index 0000000..e157aae --- /dev/null +++ b/src/openlibm/src/s_clogf.c @@ -0,0 +1,72 @@ +/* $OpenBSD: s_clogf.c,v 1.2 2010/07/18 18:42:26 guenther Exp $ */ +/* + * Copyright (c) 2008 Stephen L. Moshier + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* clogf.c + * + * Complex natural logarithm + * + * + * + * SYNOPSIS: + * + * void clogf(); + * cmplxf z, w; + * + * clogf( &z, &w ); + * + * + * + * DESCRIPTION: + * + * Returns complex logarithm to the base e (2.718...) of + * the complex argument x. + * + * If z = x + iy, r = sqrt( x**2 + y**2 ), + * then + * w = log(r) + i arctan(y/x). + * + * The arctangent ranges from -PI to +PI. + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE -10,+10 30000 1.9e-6 6.2e-8 + * + * Larger relative error can be observed for z near 1 +i0. + * In IEEE arithmetic the peak absolute error is 3.1e-7. + * + */ + +#include +#include + +float complex +clogf(float complex z) +{ + float complex w; + float p, rr, x, y; + + x = crealf(z); + y = cimagf(z); + rr = atan2f(y, x); + p = cabsf(z); + p = logf(p); + w = p + rr * I; + return (w); +} diff --git a/src/openlibm/src/s_clogf.c.o b/src/openlibm/src/s_clogf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..847aaf5610d21c6ff8db25e430f4bd06dd7bb876 GIT binary patch literal 1736 zcmb<-^>JfjWMqH=Mg}_u1P><4z|g^rU^{@B4h*~uJPg5U9{hC&IuCmse4*gc{KlZu zMMdW`zo3hX#%KOI7Zr_87ZsitAoZX51wvGKI%8B6z|tI_`2|B%RKSW9U6c`v7 zSQ!`?-2Flsm>3ujfW%;7!wBVbf>kpxh(Kw^svri&3IRrG9(Ilij0_Ai3=j;GUJ4={ z`2?Do{P`T1Ci4k6@^OHKuwjrrEDRt2W0PaX5<}b!3=Bd@;$XWN7#IW@7#IYw7$Si~ zTpowG8V+$D9O4Yc@yR*)>1le&3}BiexhOR;CygOFGdD3kjUlllG0!NCAvrOrI1TJN zRWQi_4tG#E|M?FAZb;&wxPXZVB8jsxFfhQxi;%?Gk;Kc9#6f`$QxA$`kQ5UG0|N+y z*kG(zT$x*vn8cu0Tv7y~GhnQu)SN`UlGKV42ECNTl0*i*q~c-*z2yAd+|;}h2EDxe zl2ko+zfj%clEma}C_g=~RIi{YzaX`!q>@1oY(i>Ad|FXrZYtP1N(qoZKxqaP7RY8n z@+t!ZEIq*F(9?u810?KW>S5|Spn*~W72slE0H-og7=naA=?FxF(g(TQw3Pq= literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_clogl.c b/src/openlibm/src/s_clogl.c new file mode 100644 index 0000000..c337103 --- /dev/null +++ b/src/openlibm/src/s_clogl.c @@ -0,0 +1,73 @@ +/* $OpenBSD: s_clogl.c,v 1.2 2011/07/20 19:28:33 martynas Exp $ */ + +/* + * Copyright (c) 2008 Stephen L. Moshier + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* clogl.c + * + * Complex natural logarithm + * + * + * + * SYNOPSIS: + * + * long double complex clogl(); + * long double complex z, w; + * + * w = clogl( z ); + * + * + * + * DESCRIPTION: + * + * Returns complex logarithm to the base e (2.718...) of + * the complex argument x. + * + * If z = x + iy, r = sqrt( x**2 + y**2 ), + * then + * w = log(r) + i arctan(y/x). + * + * The arctangent ranges from -PI to +PI. + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * DEC -10,+10 7000 8.5e-17 1.9e-17 + * IEEE -10,+10 30000 5.0e-15 1.1e-16 + * + * Larger relative error can be observed for z near 1 +i0. + * In IEEE arithmetic the peak absolute error is 5.2e-16, rms + * absolute error 1.0e-16. + */ + +#include +#include + +long double complex +clogl(long double complex z) +{ + long double complex w; + long double p, rr; + + /*rr = sqrt(z->r * z->r + z->i * z->i);*/ + p = cabsl(z); + p = logl(p); + rr = atan2l(cimagl(z), creall(z)); + w = p + rr * I; + return (w); +} diff --git a/src/openlibm/src/s_clogl.c.o b/src/openlibm/src/s_clogl.c.o new file mode 100644 index 0000000000000000000000000000000000000000..d1f250f35b31a56dcece8478b01ed482c6a5f994 GIT binary patch literal 1736 zcmb<-^>JfjWMqH=Mg}_u1P><4z|g^rU^{@B4h*~uJPaPqZ#4dwsCXdb7a;kFsM|Iw zVAky#6@~vLDiO#SCSl;we8d1*FNh71%u!LeU85oZGv(%ioA2(Ox}Bo}(&BON(9M&F z8Qh(ntrRre{X#Vr3{CWm^b8e@42(<-3=ItwG=fr76g(13pc1;~njl9pFt9K%FeorE zFt9Q(Fu41LGB7bP9sr3!WEmJ3p?p{vh(IM6tAZF9D+Cy&dDuB7FfuT>FfcI4K;>#c zvlIh#mLw)I=oOa~LFfz^t0*-mQLiMmqJ%*& zC9x!tK`*Jem_aW&KQ}iuuY^G_FTW&J&)qLnx40xRIUCAP&nwj{D9SHLEh?#G&;y&0 znh~E?l$Z;18Q4~`36MWPX$BM)$c8}jDgy&7J;3D9(}XkwBh#;9>yf z5e5cO7=nZ(Km-E=gBnyEsh9xE>;aRQ1jwz(qB;x^Gs)F&2({k;*-!=s2AKW&XyP#Y zVYC%gKbkUz*XROJK1?5!%izVpzyL~b(BOgzGkk!u(A@n%!La;84^%INGSmogoYJ@$G`vp!JNJO literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_conj.c b/src/openlibm/src/s_conj.c new file mode 100644 index 0000000..a7c0940 --- /dev/null +++ b/src/openlibm/src/s_conj.c @@ -0,0 +1,38 @@ +/*- + * Copyright (c) 2004 Stefan Farfeleder + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/msun/src/s_conj.c,v 1.2 2008/08/07 14:39:56 das Exp $ + */ + +#include + +#include "math_private.h" + +OLM_DLLEXPORT double complex +conj(double complex z) +{ + + return (CMPLX(creal(z), -cimag(z))); +} diff --git a/src/openlibm/src/s_conj.c.o b/src/openlibm/src/s_conj.c.o new file mode 100644 index 0000000000000000000000000000000000000000..897081fc9a9c5719ec3960353fda4e2db9e4e4c0 GIT binary patch literal 1632 zcmb<-^>JfjWMqH=Mg}_u1P><4!0>vf}eqbK?q4b*bNK}3?TOkz*Qj_ zQVa|X*u)u%FHoFPU4J%?`1gPs2#aS>{DaCQn0}Zz$Qr0p zge43N3>F{>1_p)|P*EPJJ?Q#DW}?SENXrALeo*=b@nIM$4C8{!2W + +#include "math_private.h" + +OLM_DLLEXPORT float complex +conjf(float complex z) +{ + + return (CMPLXF(crealf(z), -cimagf(z))); +} diff --git a/src/openlibm/src/s_conjf.c.o b/src/openlibm/src/s_conjf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..a37d046c72938bae740450aa12385a64165f801d GIT binary patch literal 1680 zcmb<-^>JfjWMqH=Mg}_u1P><4z#zbkU^{@B4h(z@ybNg`{B;LBn%`J>9DJehnP1RF zMWfS2MF-3h`OIGj;S0O~Y5B}A5ThdUnP0$1MF6aT=QF=xj0#AbkBSOdu>wqChzbvX zI4eY#V2FwYSiKBbjf6+@5sSkhDF|+WP*Bp{+1W}#!`&}bQ^C+g&q&Wu!N|bK)WFct zKtUrYHATTAu>>liYp%(_z{0@5puoVu0J6&6FO-3af$;!H3>F5AP(CNrco8VgSQW&; zSRueD&BM+yfsug$BrXG$s|3-Wd=5kMqHViVKh2i6WY;w$4Vt^a05adcQ15OAq zFfa%qsR!H5z`!8Jz`y{KgDZqGWO0Zy6vrp$=VhhoB{S&xI2$m4ISk1~sfjsh49S_f ziRo!z6EwgiB-}u*`STwF0+Gbo7#J8};&D)MCI$uuP!fWPgTfpn1ri5g5F3p3iYs$V z5|bG8ic5+hbOwx7l$w*MSCU#$!l0LuSdz$~msDKLpjVU+;^-w8ml&Ec=q2ap=BDPA zFzDswm!#^s`-SQjmn0@rFsQL`30#(C6x?%VDnNl;?s%}b5p^VQ%->V1&Uix z7$BPl$ukTLu=s(=p~sOl10-x=>S5{(pn>E86#%6NkUg*jCIJ;!V_*QM22fZ-g}~HK zFo{Wk%s>{^VPIeYnMtmGL#X{i$c8d7FdTsL(fteK!)SY`egmj_74(1+463g&(o z4GJF^8>R+C{|6CRFuK|Z1_lOp1_lOba3gd;6{5Qf6jlgD3=9QO_oM4KAX0xej`**D z8VHMLQ2c|+B$)j$aga4orO3`=NB~JNFfgouit<41LDvs56Fu%hS~#GFs(?617-}qB WL=c+K;Q~;`1gQQhC?7_l>jwbSwv+Av literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_conjl.c b/src/openlibm/src/s_conjl.c new file mode 100644 index 0000000..e4d7a01 --- /dev/null +++ b/src/openlibm/src/s_conjl.c @@ -0,0 +1,38 @@ +/*- + * Copyright (c) 2004 Stefan Farfeleder + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/msun/src/s_conjl.c,v 1.2 2008/08/07 14:39:56 das Exp $ + */ + +#include + +#include "math_private.h" + +OLM_DLLEXPORT long double complex +conjl(long double complex z) +{ + + return (CMPLXL(creall(z), -cimagl(z))); +} diff --git a/src/openlibm/src/s_conjl.c.o b/src/openlibm/src/s_conjl.c.o new file mode 100644 index 0000000000000000000000000000000000000000..9385a4b5fdd8db26b16050b6b1a8ff4c2495e3ea GIT binary patch literal 1496 zcmb<-^>JfjWMqH=Mg}_u1P><4z%YXe!FB*M9T<2Sco;mI-$?u~QL#YAFF^9QYg80G znvW85kJc{X!X-7#I(L#6VVpFe8)?^MeRTkb!}Lu_}mxu|j}R znuncZ0wV*12?GOz3{=h$M7!`QxbSJX@EN%9S-9{y_@Z+C`8Ys|aAS~tEDRt2V^hJ5 zB}BOy7#M_*#KCT0U|9KB=)FwKx$l$w~6!;qYro0y)% zz#s}W3lv5m{O3Oe7$J#+!V)G93R{pAD7rxy#0F!%;>z5T#3Tm2;*uf=odIJNrRF5+ zm84dbFzBTumLxLhB^4Jl=q2ap=BDPAFzDswm!#^s`-SQjmn0@rFsQL`30#( zC6x?%U=va^;?s%}b5p_AQA&XP0g4kgG=m^%mw^Em-Y{wOFqdXv0H-yWdYHNgAVV1# z7!05ST%feYz`y`Y9-w#vNvT1_nL!*R+=#?RW*d@Bjb+ literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_copysign.c b/src/openlibm/src/s_copysign.c new file mode 100644 index 0000000..a52701f --- /dev/null +++ b/src/openlibm/src/s_copysign.c @@ -0,0 +1,34 @@ +/* @(#)s_copysign.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_copysign.c,v 1.10 2008/02/22 02:30:35 das Exp $"); + +/* + * copysign(double x, double y) + * copysign(x,y) returns a value with the magnitude of x and + * with the sign bit of y. + */ + +#include + +#include "math_private.h" + +OLM_DLLEXPORT double +copysign(double x, double y) +{ + u_int32_t hx,hy; + GET_HIGH_WORD(hx,x); + GET_HIGH_WORD(hy,y); + SET_HIGH_WORD(x,(hx&0x7fffffff)|(hy&0x80000000)); + return x; +} diff --git a/src/openlibm/src/s_copysign.c.o b/src/openlibm/src/s_copysign.c.o new file mode 100644 index 0000000000000000000000000000000000000000..eb86a949f011e3729ee06a666e6fea8dacbbda70 GIT binary patch literal 1280 zcmb<-^>JfjWMqH=Mg}_u1P><4z`($SU^{@B4h%dD+ze?R{B;LF#7U3NLmmfTDs&$3 zIQUAT@gV~PLqp@E|NsBjbDr`z_(;Kn^Fo>jf8K$^4DQa(Rtg&KexaHQh9-JOdWH%{ z21cd^hK2?T8bPTk3Lc3iPzhagO|VrA3=Av`3=9ek3=FIc3=Hmmp$tq6j0ZqsFt;*7 z`J7MnKOJ;yEA$|gx4GLZm2C>0duedU|Br%CWuehWLLTA8OC8-r940JuexbU>C5g$|P=0z|sa`=*enDzcNhO0`QEE=2 zUTQ{sT2W$dD%d892x$feuy5JWOo5~k1_rqQq4EMy8b&EX^)tf+pmY(GMyEjWfh?xZ zz`(%4z`#JRejTX&2FQjoFfhRE*GChF*$<;lq59F3F)TzEfbwDbpj-x51_lOp)a(V8 zS^*{*7|`7X@+(vdOvOU&M@c&j3=B8GvV`?VK=T$XzM$F|8lVo9fC_-}708`1`(ffB zW$1Q;v~YkV7#J85KpX}J1}P=)DG LK8%72!?+9px$t2y literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_copysignf.c b/src/openlibm/src/s_copysignf.c new file mode 100644 index 0000000..945b3fd --- /dev/null +++ b/src/openlibm/src/s_copysignf.c @@ -0,0 +1,37 @@ +/* s_copysignf.c -- float version of s_copysign.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_copysignf.c,v 1.10 2008/02/22 02:30:35 das Exp $"); + +/* + * copysignf(float x, float y) + * copysignf(x,y) returns a value with the magnitude of x and + * with the sign bit of y. + */ + +#include + +#include "math_private.h" + +OLM_DLLEXPORT float +copysignf(float x, float y) +{ + u_int32_t ix,iy; + GET_FLOAT_WORD(ix,x); + GET_FLOAT_WORD(iy,y); + SET_FLOAT_WORD(x,(ix&0x7fffffff)|(iy&0x80000000)); + return x; +} diff --git a/src/openlibm/src/s_copysignf.c.o b/src/openlibm/src/s_copysignf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..7636a1474c14bf74e301017c70d4919a5a8dbc67 GIT binary patch literal 1264 zcmb<-^>JfjWMqH=Mg}_u1P><4!0-V{&;cy$z`(=6&5*`lcOZ?w?v(2P|NrY7A2Bd6 zG;m%>YY-`5CG`(a7I2&dz$ZsGv z69WSS2!q&QtXEu_TauW>pjTW{1fervtdi7<5(d4L#F9h?y`5(d4z z{E}2XcfU~G;*!MVY$!iHuT-y~D8C@JsHBoXuP8MqQ7<(kKCLJ*Hx+CXMT9g11K8JW zXr@5Y1Oo#+9H8<7P#Q)lLiIDl1fX;jlt!mO@q#R-&cMLH!N9;ku6`Y;{RYT}GB7Z} z?AJ#VhuIIKO`-bHlreOo3qbiWeNZlgD+2=qJ9^wRFfdGjDnNG^$gfZ-Fck~6A0_QD zFfbed%Q7$!(jNiMW3c#wYGWvXI#dEG0Lot=cf#z4iG!4(+YQq40Yoq`FeE@}E@&K~ t>j#;O9(N!u0U(1J7#Ji$93%`ChKmS7&4mj<868lC=} + +#include "fpmath.h" +#include "math_private.h" + +OLM_DLLEXPORT long double +copysignl(long double x, long double y) +{ + union IEEEl2bits ux, uy; + + ux.e = x; + uy.e = y; + ux.bits.sign = uy.bits.sign; + return (ux.e); +} diff --git a/src/openlibm/src/s_copysignl.c.o b/src/openlibm/src/s_copysignl.c.o new file mode 100644 index 0000000000000000000000000000000000000000..69f7ee935c8ea397e90ade6b153e6fed306400d7 GIT binary patch literal 1280 zcmb<-^>JfjWMqH=Mg}_u1P><4z`($SU^{@B4h%dD+zhvKR5)(esNA@nqawk-%|+#5 z^Mm@^H7YOow}q&DY<|?hd7;Ba<>Bodl^cf{+?}1R6g1rZLNyf(P4tZP3>AzFj7$v- z4Gk1Df>KiyJQ7Qw61wJ^U^^HXSQr=>6c`v7SQ!`?-2Flsm>3ujfW)BE42)1d%*`TD z3C5}*2F3~jMrj^)jtPtm3?OkCsGK&G#z%q7V`2FCADbFxEFr|tz`!7cBo4QuI6gVQ zpt3kKJugQunE}p*nG5n8hz$x}5C*ZqSg*J;wUY zgMop8T>Uyw`wfr{Wnf@{*{_c#4znLdn?m)YDPx$0E&%1j^g+1{t_%ze?5NobEVTek zGBBXK3*=X*6qt&I+K-ZU7#J8XfMp5mk6?i0F<5*-wJ|h69V!78;DovpWn8U!p1&t$g{UCGE;|`=H0jggT#6iMPVYrAO)Lgg#lraOUFdfQ=QBYwR GmjM96p +#include + +//#define INLINE_REM_PIO2 +#include "math_private.h" +//#include "e_rem_pio2.c" + +OLM_DLLEXPORT double +cos(double x) +{ + double y[2],z=0.0; + int32_t n, ix; + + /* High word of x. */ + GET_HIGH_WORD(ix,x); + + /* |x| ~< pi/4 */ + ix &= 0x7fffffff; + if(ix <= 0x3fe921fb) { + if(ix<0x3e46a09e) /* if x < 2**-27 * sqrt(2) */ + if(((int)x)==0) return 1.0; /* generate inexact */ + return __kernel_cos(x,z); + } + + /* cos(Inf or NaN) is NaN */ + else if (ix>=0x7ff00000) return x-x; + + /* argument reduction needed */ + else { + n = __ieee754_rem_pio2(x,y); + switch(n&3) { + case 0: return __kernel_cos(y[0],y[1]); + case 1: return -__kernel_sin(y[0],y[1],1); + case 2: return -__kernel_cos(y[0],y[1]); + default: + return __kernel_sin(y[0],y[1],1); + } + } +} + +#if (LDBL_MANT_DIG == 53) +openlibm_weak_reference(cos, cosl); +#endif diff --git a/src/openlibm/src/s_cos.c.o b/src/openlibm/src/s_cos.c.o new file mode 100644 index 0000000000000000000000000000000000000000..c8701ea1872c2adda59de01fe5258e950c6e4f81 GIT binary patch literal 2056 zcmb<-^>JfjWMqH=Mg}_u1P><4z~I4xU^{@B4h;MZd<!)qxp!$;WU1E7Y2qj{`V(e zf;92VH-M=9AV-50rSXS@ZF_wYWIjUt^+6CHRmnP#Rt5%!5B5+7i~^ep=D0gMTPbL` z`-N&M7@FuA=@}{*85o%w7#bQVXauFED0n26KqYj|H5nK{!KA>zzyNZByI&{+69eM` zkQm5$AoCcZd`=LDfq_8;N;6gkF)&sLFiP{Vb4*}lV31*eV372F5W(car;y9X5zYrP z9VCDqgY02p`1l{2EHjpvg}4LcT2vi;U@jY&L?-kZ7#M_*%mKTNfq_Aofq_8)Ss|3I zhC|#Khd4uVd~$xVUNVE8kFx=YFk*<0&rD5CH8(YhFG|ggFUZUX31z1i<)!9;)H1}! zLpjBnc?=p*dzly*7?>Ft82dJu*xV_?uLuFNe-Ok&V0E-8Z088B8+ zYEGhFNoqw2gI-EvNg{(@QgJbZUQs@XqnBJb6(#1T!d*i)1LQwY+6Bc8vLTSNhJgW= z&R}xrX-%2|lJ{WhVd^eG1M3DN1_lNTm_jIxuD=3D`dI;uP*^$vr5`S6T!V~)iG!>`w;LqC10=z~zyM2sywJJ< rW +#include + +//#define INLINE_KERNEL_COSDF +//#define INLINE_KERNEL_SINDF +//#define INLINE_REM_PIO2F +#include "math_private.h" +//#include "e_rem_pio2f.c" +//#include "k_cosf.c" +//#include "k_sinf.c" + +/* Small multiples of pi/2 rounded to double precision. */ +static const double +c1pio2 = 1*M_PI_2, /* 0x3FF921FB, 0x54442D18 */ +c2pio2 = 2*M_PI_2, /* 0x400921FB, 0x54442D18 */ +c3pio2 = 3*M_PI_2, /* 0x4012D97C, 0x7F3321D2 */ +c4pio2 = 4*M_PI_2; /* 0x401921FB, 0x54442D18 */ + +OLM_DLLEXPORT float +cosf(float x) +{ + double y; + int32_t n, hx, ix; + + GET_FLOAT_WORD(hx,x); + ix = hx & 0x7fffffff; + + if(ix <= 0x3f490fda) { /* |x| ~<= pi/4 */ + if(ix<0x39800000) /* |x| < 2**-12 */ + if(((int)x)==0) return 1.0; /* 1 with inexact if x != 0 */ + return __kernel_cosdf(x); + } + if(ix<=0x407b53d1) { /* |x| ~<= 5*pi/4 */ + if(ix<=0x4016cbe3) { /* |x| ~> 3*pi/4 */ + if(hx>0) + return __kernel_sindf(c1pio2 - x); + else + return __kernel_sindf(x + c1pio2); + } else + return -__kernel_cosdf(x + (hx > 0 ? -c2pio2 : c2pio2)); + } + if(ix<=0x40e231d5) { /* |x| ~<= 9*pi/4 */ + if(ix<=0x40afeddf) { /* |x| ~> 7*pi/4 */ + if(hx>0) + return __kernel_sindf(x - c3pio2); + else + return __kernel_sindf(-c3pio2 - x); + } else + return __kernel_cosdf(x + (hx > 0 ? -c4pio2 : c4pio2)); + } + + /* cos(Inf or NaN) is NaN */ + else if (ix>=0x7f800000) return x-x; + + /* general argument reduction needed */ + else { + n = __ieee754_rem_pio2f(x,&y); + switch(n&3) { + case 0: return __kernel_cosdf(y); + case 1: return __kernel_sindf(-y); + case 2: return -__kernel_cosdf(y); + default: + return __kernel_sindf(y); + } + } +} diff --git a/src/openlibm/src/s_cosf.c.o b/src/openlibm/src/s_cosf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..389fd2bdbceb232f66851ae47ee79a112f574181 GIT binary patch literal 3128 zcmb<-^>JfjWMqH=Mg}_u1P><4z+l0FU^{@B4h#Ye{0wRQb%#1HsQ&-|zuxv1zo&h< zobCVr^_J!3pZRqTv>qtU|I9DI3Q~VKjbGk{fx)BsjfCyR;A)3*)6e`-2W%go7IWZl zZ)0F!XuZVWw~m2<;S;|AFGzz&^AU+p{4poe_%#l`1POrk+g>$%^-I9Su`32A!#@-X!gU@;_v!1j9d)~IlRHGSe2a8coCe!$%PgR#V+`3Dn! zOFPIV2TF^<@-OZG|NozcFb}8i!RDqx-2lz4lCHNU?!A+_=lB21ImX{l3)fa15!2xi^zdVP-uY}a6%c(Vh5AR z1jJlc1_NY41_lOQFrS@408AqYBQTSdK>|!82y-x#6+=BJ+=Ya!b zMg-sxkH;a-P#m9}U!10w%%JDvYyu)oL4-MoFa!|>Ai@kpSbzvi5Mc}=j2J)~8RFx! zQ;YIabK;9L^HS0f+~oXXFgG(bHPzhIB)%v$H@+Y<-zW{_N(Kg12*tp}z`(%Fz`*e5 zKLms!iG$K9Onf(zI4E{t;#ZKwL8$^J{s2iF6l*YXaN)%O$rqqB0~7y%q#l$eVB##G z1j@hwb|uyRU`fdO0!f$}Oy9EJs<`e1w*4Kf492GKeU z4B)bsT>XYn`-MP;Az=xq{T4`KASTTHFxn1>{s5?cP z5Dg1|7##`Kk6uqSK=tc`G$CPF_`&ETsD30RVCH(LelQ1#fa!w?6)`X{fXYF17|MrHAp2l!5G@F;r$B6Eya4L{DaeA* IutF9B0Q-*bpa1{> literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_cosl.c b/src/openlibm/src/s_cosl.c new file mode 100644 index 0000000..886d3e3 --- /dev/null +++ b/src/openlibm/src/s_cosl.c @@ -0,0 +1,90 @@ +/*- + * Copyright (c) 2007 Steven G. Kargl + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_cosl.c,v 1.3 2011/05/30 19:41:28 kargl Exp $"); + +/* + * Limited testing on pseudorandom numbers drawn within [-2e8:4e8] shows + * an accuracy of <= 0.7412 ULP. + */ + +#include +#include + +#include "math_private.h" +#if LDBL_MANT_DIG == 64 +#include "../ld80/e_rem_pio2l.h" +#elif LDBL_MANT_DIG == 113 +#include "../ld128/e_rem_pio2l.h" +#else +#error "Unsupported long double format" +#endif + +OLM_DLLEXPORT long double +cosl(long double x) +{ + union IEEEl2bits z; + int e0; + long double y[2]; + long double hi, lo; + + z.e = x; + z.bits.sign = 0; + + /* If x = +-0 or x is a subnormal number, then cos(x) = 1 */ + if (z.bits.exp == 0) + return (1.0); + + /* If x = NaN or Inf, then cos(x) = NaN. */ + if (z.bits.exp == 32767) + return ((x - x) / (x - x)); + + /* Optimize the case where x is already within range. */ + if (z.e < M_PI_4) + return (__kernel_cosl(z.e, 0)); + + e0 = __ieee754_rem_pio2l(x, y); + hi = y[0]; + lo = y[1]; + + switch (e0 & 3) { + case 0: + hi = __kernel_cosl(hi, lo); + break; + case 1: + hi = - __kernel_sinl(hi, lo, 1); + break; + case 2: + hi = - __kernel_cosl(hi, lo); + break; + case 3: + hi = __kernel_sinl(hi, lo, 1); + break; + } + + return (hi); +} diff --git a/src/openlibm/src/s_cosl.c.o b/src/openlibm/src/s_cosl.c.o new file mode 100644 index 0000000000000000000000000000000000000000..6267b8919a08b88d1a6a5358d100d96233cc6ab7 GIT binary patch literal 3760 zcmb<-^>JfjWMqH=Mg}_u1P><4z_5V}!FB*M9T)@{_!)vdn%@-MUZc{$z`$_x!0j3p zg@zOr&3gXrE-D&ns{iZxTe=t-7}9J(tOraC40mtb&QVdg%L+2${zv}y8b*+qNB10+ z4h9B>&KsS#K)MLn_rd_>{qgV%g%di?S&Ae$KO-njX~qxncd^x-sqc^3wT zEQTzw_S-fpa2?3<9^EbAxb-;rLcw<7E&h}I?alxG|4)ON2Z{wqY(mJ+Yv2ICcMuvI zuu#8q5)!(14&8f&7OLGWDmM?@;RQMG-YbYH5c1x^8z*lby7BO~jfzLNj|xZQLr|*F zJlFhBtgig-4VWg75{L!}dGqXzNB17zJ96{%jZ^m?f@IMQICb+-^Do;vo4Yq}9)#F? z=OsidguHq7#^ZaBKnC191&W882W~vNZKHDYw5 z`7-|B|NrptH~>;d^ikJ2MvZB55VyXiYRPx^fD7{gbRVFeCY%UdZ;>VCf$7S zQWl~J65l(S85kH|w*3W1nF|BM_Zv4Kfc)~{<;uVR|AWGufq~(`%`Ink{k~C`9lirB zqS0XPWx{U$V9^UJFrP!lYQ1rK`p)M?d%^q-ZF`zeoXjk{%?@ufY31Bm`< z&)@)6=K$015YNES;LYIf>};i=;qDizsbFZLXQXGSU}RuqYG7z+pr8?ynxf#5SOS&M zHP>WdU}0cjP+(wS0A)#czfcAy2F3#*F;FT8xq%VN=LT^Y7#KvLG-Fi|17n2%qcjgY z#{@KY{tmNC*TZH6T~-x(H%*%ADUtQX!1}u;G#hOVqy3QixCuM z%veffP;t!2z{+3&RmlORLE!)rH-PeC;&KcO3?Ok0G;t6gBn}E|kQ7Y45mdbdNRWYn z0VZw(6&FAgcY}(<)WPTgs5n$P+#C>}863MH76M0snQUMZnTQ8-*um)n%!CptV459F zA`_Wl4jYPnAfY@E!NA4L;Fjh`J14tm=up}cB#)63%!NrV9U}DB_ zF=LRJo{zI3gPxDGIfyU@5hftQ6hxRY#K&i+7UiYp#22OJ#)GUuh!kh$l$Swi6{h|Sl6p}j z^=u%6q2`0~x(P@#0|NsOnz#;BTn9;<56K)aByoNu@gO8|kohW5b0W~hVP!}?k~k<0 z!Q9`8Bn~nM1|P1r*0HHi(vnhBZt* zNDPEEpatFokl_pr44}LKVnT)C<%$}(JY-;iMgvGI82>{T0E>dkY$yXtfzmn1OmyYM z>NkYij}pfqv!MwM-CrQPK+-U53DqwI6M)hVQ2n6rg$jWwn0^=ysV6{XDp(p$BtZ4U z)WIa6!tioG7-~PPeuJsYfGX672|#I39DtZGItHpAB!-NqL-iwzf!Hv8AT|i+FfcHH zY8&+Mn*r62?k;ryfLdiBGtu>*fa+fXvIGgE>#xU={y0Dl0tNIYQ27DV53AR( z*$uL;0MyU|)lpD~fyz!$9HZ;!WWY?jApH%XKw)5DSO(%CVUT@DTn12Chn{vp@(NJ* L_klP_7+pUA34q6z literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_cpow.c b/src/openlibm/src/s_cpow.c new file mode 100644 index 0000000..dae6251 --- /dev/null +++ b/src/openlibm/src/s_cpow.c @@ -0,0 +1,78 @@ +/* $OpenBSD: s_cpow.c,v 1.6 2013/07/03 04:46:36 espie Exp $ */ +/* + * Copyright (c) 2008 Stephen L. Moshier + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* cpow + * + * Complex power function + * + * + * + * SYNOPSIS: + * + * double complex cpow(); + * double complex a, z, w; + * + * w = cpow (a, z); + * + * + * + * DESCRIPTION: + * + * Raises complex A to the complex Zth power. + * Definition is per AMS55 # 4.2.8, + * analytically equivalent to cpow(a,z) = cexp(z clog(a)). + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE -10,+10 30000 9.4e-15 1.5e-15 + * + */ + +#include +#include +#include + +#include "math_private.h" + +OLM_DLLEXPORT double complex +cpow(double complex a, double complex z) +{ + double complex w; + double x, y, r, theta, absa, arga; + + x = creal (z); + y = cimag (z); + absa = cabs (a); + if (absa == 0.0) { + return (0.0 + 0.0 * I); + } + arga = carg (a); + r = pow (absa, x); + theta = x * arga; + if (y != 0.0) { + r = r * exp (-y * arga); + theta = theta + y * log (absa); + } + w = r * cos (theta) + (r * sin (theta)) * I; + return (w); +} + +#if LDBL_MANT_DIG == DBL_MANT_DIG +openlibm_strong_reference(cpow, cpowl); +#endif /* LDBL_MANT_DIG == DBL_MANT_DIG */ diff --git a/src/openlibm/src/s_cpow.c.o b/src/openlibm/src/s_cpow.c.o new file mode 100644 index 0000000000000000000000000000000000000000..8a592590a530d50cb7e8238d996e4dacfa62542b GIT binary patch literal 2360 zcmb<-^>JfjWMqH=Mg}_u1P><4z_5cA!FB*M9T@l+co`hS9mCQ*`RmT5@oSt8PV?Ze zJDkR^amb_jjlw5>K^c`#{DL7W94|mRKJg2LsBnDZ7vNC=={OEj2bM_lUK zCC!6B?=VD+U*kd=|N8@J{CXFvq)H_`nvW=e_|a+n8Ydj%9ODnC@yoj~Fo5-fwPDx< zk~;s1U(iKG0%R3fUI1+PCw>7FkQ?&uf8rNNQIP;E;s6;BcB8;2{>VFN{CXd%0!#hV z_%#lH;unljfot^vdm=^!r0fJ#nnwj@Fpo+a|NBdy_#<6ZI6#j6#2BD?UdH_Y z{~r{(sJH>nb$52QQqXYs3)NIGG|@BCGgL4#FfuhTG&E4q2ue*+@JK9yO6ZzvGBB_( zFfb@EFff4J=k6EEz{J3K03-%W6O2$kC)5HFD9uZ-Uu!*bU zP!CcI!U&TgEG-=B^>BzA;Se{&AFOZi(afNIeEFNL`049f?R;8g~4pR?PX8;OV1_p)? zPytY!fb0RqF-S-PL@+Qgs4*~ra~(6352KEP6vH@3G`g@30|NudOmg)bLhTnqvIE4t z0JR9+zc4k;Fhus4&>iAif7wKZuQt`B4%XLI$QECKAEGzyQim z=*k740_g4ng%wOMh%SKI4^<8l0%HfLKmwSDAkg(^jwb(bvxVu literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_cpowf.c b/src/openlibm/src/s_cpowf.c new file mode 100644 index 0000000..764053d --- /dev/null +++ b/src/openlibm/src/s_cpowf.c @@ -0,0 +1,73 @@ +/* $OpenBSD: s_cpowf.c,v 1.2 2010/07/18 18:42:26 guenther Exp $ */ +/* + * Copyright (c) 2008 Stephen L. Moshier + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* cpowf + * + * Complex power function + * + * + * + * SYNOPSIS: + * + * float complex cpowf(); + * float complex a, z, w; + * + * w = cpowf (a, z); + * + * + * + * DESCRIPTION: + * + * Raises complex A to the complex Zth power. + * Definition is per AMS55 # 4.2.8, + * analytically equivalent to cpow(a,z) = cexp(z clog(a)). + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE -10,+10 30000 9.4e-15 1.5e-15 + * + */ + +#include +#include + +#include "math_private.h" + +OLM_DLLEXPORT float complex +cpowf(float complex a, float complex z) +{ + float complex w; + float x, y, r, theta, absa, arga; + + x = crealf(z); + y = cimagf(z); + absa = cabsf (a); + if (absa == 0.0f) { + return (0.0f + 0.0f * I); + } + arga = cargf (a); + r = powf (absa, x); + theta = x * arga; + if (y != 0.0f) { + r = r * expf (-y * arga); + theta = theta + y * logf (absa); + } + w = r * cosf (theta) + (r * sinf (theta)) * I; + return (w); +} diff --git a/src/openlibm/src/s_cpowf.c.o b/src/openlibm/src/s_cpowf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..b3f6c95adf5a77504611cd98cb0487f6c499c9cf GIT binary patch literal 2416 zcmb<-^>JfjWMqH=Mg}_u1P><4!0>?;!FB*M9T@l+co`hS(>(a=4mgGdcOLdQ_(H+4 z^B73r1c>d?{KlcvMaAYbzo3tb#b^FH7Zr<67ZnaLpXUY0l+XMEAs_((9~GW7NB+9w zpZNttR7}7s48S@J!0I|Eun6bX;!BM#AyagOna)A;3G7#KQZR1`o4s(_^xK7*`9auUcfdFR2#i12G1 z0!s^k?fc9xP@}?;=E$FS|1-Zpii!wW5f8{>uxA85^GDv{*ZWZwS{lr+ariU8V2lb} zr;iHHXMTYg6_BD65Lq7;4w$(ZW~>TgV5|^el;&aQn83)uV8Xz_ zAOn><3exPvC(zI2&L`2w?8v9k%o4_zz|_OVr{KsZ;lwB4#K+;z4ONYu0vW-=@Da_c z5Vg!$Qar>okS`!=V59&81A`Efda&CV7#PGD7#KiuFm*6m7KgYB4sk6U;(|ED4RDB? z;t;pOA#RUDoS`^AxgfthO)r^2&&S!20nA}YE=o1hnb znR#gp$@#@;45<|bX$(2}>1p7gum+Qm^Z^RhKmQ>h8A+Utfq?-gUW+8ojwF5#Nt^>o z{4J6=C~d*aQ3pjl1H@h~B=xRH;-I*Osjq~JGchnQFe9n&gNlRFG7pmY8YFREBymt4 z067U{4hVzTV60bMnOl;W#GqGPQUswhV639loJ75n)QS=Yy_Cd~LjI5W&E}pvJ%e&V8V`feL{sR+K;n3xNrc8DIvK&|zR;0GUayenY7JLQwNylmOIz zbpOKmFdCH4KyCu%TbN!DtpL@p58@zUkXjHIMteZ*2ZA>~0BS!}IZT+L0V)sx7lAO)^=IRV{|Hc_z`(!&i)T>$gYq#< zKTI6tAE;Fj3!vl$s9*p{0RsaAD35}Y6uN$pndos3GC~2Qn1O-81;jzZP~+etpmG?S P{sO4`tKcdj40Qbf$D~n+ literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_cpowl.c b/src/openlibm/src/s_cpowl.c new file mode 100644 index 0000000..81c9afd --- /dev/null +++ b/src/openlibm/src/s_cpowl.c @@ -0,0 +1,74 @@ +/* $OpenBSD: s_cpowl.c,v 1.2 2011/07/20 19:28:33 martynas Exp $ */ + +/* + * Copyright (c) 2008 Stephen L. Moshier + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* cpowl + * + * Complex power function + * + * + * + * SYNOPSIS: + * + * long double complex cpowl(); + * long double complex a, z, w; + * + * w = cpowl (a, z); + * + * + * + * DESCRIPTION: + * + * Raises complex A to the complex Zth power. + * Definition is per AMS55 # 4.2.8, + * analytically equivalent to cpow(a,z) = cexp(z clog(a)). + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE -10,+10 30000 9.4e-15 1.5e-15 + * + */ + +#include +#include + +#include "math_private.h" + +OLM_DLLEXPORT long double complex +cpowl(long double complex a, long double complex z) +{ + long double complex w; + long double x, y, r, theta, absa, arga; + + x = creall(z); + y = cimagl(z); + absa = cabsl(a); + if (absa == 0.0L) { + return (0.0L + 0.0L * I); + } + arga = cargl(a); + r = powl(absa, x); + theta = x * arga; + if (y != 0.0L) { + r = r * expl(-y * arga); + theta = theta + y * logl(absa); + } + w = r * cosl(theta) + (r * sinl(theta)) * I; + return (w); +} diff --git a/src/openlibm/src/s_cpowl.c.o b/src/openlibm/src/s_cpowl.c.o new file mode 100644 index 0000000000000000000000000000000000000000..c5324337aa1a6f8da853cf3f0438070d6471a768 GIT binary patch literal 2280 zcmb<-^>JfjWMqH=Mg}_u1P><4z_5Z9!FB*M9T<2Sco;mI-$eZ1qB4VlfdMP^0;KkK zjf#Rt^AQECDxiWeg$7`SB`OvFkuX>iByscI%>y@2-F|iVRuy-t@ZFm?4|p^mi8y@s z#%qo=et8!LhPyXFmLcl}vBCOp*Qg|b%=llT!U4j!b5smGn%@ZAJaF4a<#vrq08Ev` z?Hm<_+c^-`cTV1XcRNQ#;Qq_IH$Xb7d`rFW-ne@MS*HR-C)B)qCqYgCsl9EZ0+VsL z2Qdd64j?z*IeGKcy@Q8u*QglWJP9)Fc8!Vv$l{w1?wv%^2zDaaNRYDvkY(E6MYIsgCvXK;6Rwo=e=_Y2ijFf`FK(lb;rGB7eVFf=q!&*3=Ay{ z3=A?*xn7WF7rq2{z6^K10(ZU&cfJNjUrfFWUxo``feT-S3tt1HCtpGs7axZscL=hm zFJA&gl?Pt~V;o;X3|~PQUjt(jUxEu4ABQ`)7hgdPUjt(TUjo!_TolMjEDRt2W0Pmb zlH$1;7#M_*#KC@IU|*V#hH0I49WS$ISi>41vv~k`RO?f z42sY&0i_)f{_`IKypY5}X$&TwjwH^;z`y_#UydZsjwF5-Nt^>ooE;Rg3=H6O%!wqf zh$PO1Bp!t%4vJ%#y(LKEpg4eugYpK*Y9O4S^ z&A`BL11bOtYmhylI06ZQ@&$-iV_*R1CRjNF5(DA0AjKdC8b%k^VPIeYnMtmGL#X|r z{DN#1%zk}jL8w}g5X>E*d;?>H#9{akHbEr)Fm<4O07}m&X$T|<6+m|v$gd!27*2wk z2~`dgW-x#XEP#tZ80h+Aam1ejC{r>pFu>vo6n`MSAPh1ICJyo@)GClL9AAJ6T7VQV wFff4f6ey0+^@H*zNF1&a%HV*eAA2YtMnR2(alz#-HvJY*_vgS>LKx`!0R*yk(EtDd literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_cproj.c b/src/openlibm/src/s_cproj.c new file mode 100644 index 0000000..b9faa24 --- /dev/null +++ b/src/openlibm/src/s_cproj.c @@ -0,0 +1,47 @@ +/*- + * Copyright (c) 2008 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_cproj.c,v 1.1 2008/08/07 15:07:48 das Exp $"); + +#include +#include + +#include "math_private.h" + +OLM_DLLEXPORT double complex +cproj(double complex z) +{ + + if (!isinf(creal(z)) && !isinf(cimag(z))) + return (z); + else + return (CMPLX(INFINITY, copysign(0.0, cimag(z)))); +} + +#if LDBL_MANT_DIG == 53 +openlibm_weak_reference(cproj, cprojl); +#endif diff --git a/src/openlibm/src/s_cproj.c.o b/src/openlibm/src/s_cproj.c.o new file mode 100644 index 0000000000000000000000000000000000000000..072a8438a9c03f1ab046f30c5f5fb50d4c0f273a GIT binary patch literal 1856 zcmb<-^>JfjWMqH=Mg}_u1P><4z;J*W!FB*M9T@l+co~AzJoxJldo;fh_{1;hqr&k5 zBnKuw@eBBQn6bnNH&`La z^og398|^gO8b41!PwDC|ML`STwFK<))efyCJu z7#LvU1|UHONc^!QiJKycBdhmB5=T}ah9nM(8<_b?P;n*(1_n@)hlzvI3P=hh4#FTd z80!^R=9VNTG3XVS6hY_=7^^5XCsD5?wW5SUFD0=gkwGu1xR^n&C?CYpOD-<4V9-m> z&&^HED`C*f%P&dQbN36?EiOq+&W7^S^Gfv!it-Cmi%KdP^uWfYX2hozCFZ7r?WO_& z@)s!Wfx-;gI7l96V1T6`m>haqk%qjAGEM0;X zF)%QkfHL%n3|A4a=F^~2<0^miBojfUxi35PQUju592TUQ9M%SN(BmOm@5dw>6Q2c|+QkZ_2ILI1wyFpeJfFu|g7;b<#3=9lB uP5JfMbx;uj(UA)&@XI1CKn@&}uK2dH2rTqT5ot{(s_A;BvE literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_cprojf.c b/src/openlibm/src/s_cprojf.c new file mode 100644 index 0000000..717c165 --- /dev/null +++ b/src/openlibm/src/s_cprojf.c @@ -0,0 +1,43 @@ +/*- + * Copyright (c) 2008 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_cprojf.c,v 1.1 2008/08/07 15:07:48 das Exp $"); + +#include +#include + +#include "math_private.h" + +OLM_DLLEXPORT float complex +cprojf(float complex z) +{ + + if (!isinf(crealf(z)) && !isinf(cimagf(z))) + return (z); + else + return (CMPLXF(INFINITY, copysignf(0.0, cimagf(z)))); +} diff --git a/src/openlibm/src/s_cprojf.c.o b/src/openlibm/src/s_cprojf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..a59d9da102ed7719d45d857632b7f7cd227cc87e GIT binary patch literal 1912 zcmb<-^>JfjWMqH=Mg}_u1P><4!0>|^!FB*M9T@l+cp1_>`0EaMG{3R%IQT;0GrypV zibki4iVm2?^O?U6!smDa(gG$v^9%T>aD3($2vOl_Jy7cZnO`tOMdCBRppS|SSUrdx zqQV0f!L3gmtWN-}N(8J=z@zzy#bK~8$RR!|Dqvv+u&w+WC(`)e9{{sI^9zWAoWrki z;`L4jhK70ucV}lS1r2wSlh;jxID9u|tT}_#c}BW-Kwt16BxfEtml(1Q{3@gpkyO-N3-W zAi==EAOKf|V94VT*T5mJk3*cHI6k?cC_gJrFPTBl$Jvkp!edA-N=?j3V~CH>EY8eJ zOJhjR%uP&BV@S>~s4UJ*&r5^31Y{qG4GMFRum1dp09}wE10;Uf7#J8};t5FN>`3CN zNaD!q7bA%yt6z^K&VgjkcBnWL0|NsntHA69r4f)6NF0PgY%ta;Z)}NC=cJL9`kJ131-!!WzVfV~}Dv2f;uW z)?r{^0GUayenY7JLI^7$ET~1GbO{lFkT5=swu9<7fJnnh7N~wuzJUuu)q?m?X$E&B zF_1V68^aX91fVp!a5w`411McXgBz-ffx!Z*5Zzs%u!1XMU|`6H+K;Y31FGKwSur%M zk%h8w#D4-bLSXR>ihocU3bP+34zdQ_Zjkv4KoSfL3^za=1_lODxd#e!bp0SRp;kdv fLZ}L;p_ULXoP-(+=Yz^ktoosXm2j012D*L#n`PCA literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_cprojl.c b/src/openlibm/src/s_cprojl.c new file mode 100644 index 0000000..753ab4c --- /dev/null +++ b/src/openlibm/src/s_cprojl.c @@ -0,0 +1,43 @@ +/*- + * Copyright (c) 2008 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_cprojl.c,v 1.1 2008/08/07 15:07:48 das Exp $"); + +#include +#include + +#include "math_private.h" + +OLM_DLLEXPORT long double complex +cprojl(long double complex z) +{ + + if (!isinf(creall(z)) && !isinf(cimagl(z))) + return (z); + else + return (CMPLXL(INFINITY, copysignl(0.0, cimagl(z)))); +} diff --git a/src/openlibm/src/s_cprojl.c.o b/src/openlibm/src/s_cprojl.c.o new file mode 100644 index 0000000000000000000000000000000000000000..a9657e42aee50f5b81916b6b1fc3731c144bea6e GIT binary patch literal 1944 zcmb<-^>JfjWMqH=Mg}_u1P><4z#zebU^{@B4h(z@ybK=AZ#e#!sAwSL7a)1ZNXMw# zHYyNybX4nsQdML%AU0So0+c_#=ftx1}GcYhT)HAp{J6kDexch}_Dj1sR8R;1+7#SFu8Wk@->(N zCj=Q77=)12gZ;w5z#zfEz#srug<#0z5ZAyVu8%{Up*TLdpeR2pM=zN{&&S!20m5TQ zE=o&M=!a!#DqaFIX^cyHLrw0 zFE76&RnOfoRJXV!F*zH`PtPmWD=5k@NG&Rj;Brn3$!_?h?2GR{!)fT?f>1_n^Nh6XoS3`7V(^`pBB7XBbLAe;|16J5Up zRDT0V5fVn%pM@j-8=w&ai)T>$b3)?^WE@N!WDUCAAo&9z38Z)cm3yEthuII)4>A*K l6-XN#&wv_g2^WDdpvFQt3=9mQauch5s9+^rC4_;l9{{FA-lzZo literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_creal.c b/src/openlibm/src/s_creal.c new file mode 100644 index 0000000..28a0fbf --- /dev/null +++ b/src/openlibm/src/s_creal.c @@ -0,0 +1,37 @@ +/*- + * Copyright (c) 2004 Stefan Farfeleder + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/msun/src/s_creal.c,v 1.1 2004/05/30 09:21:56 stefanf Exp $ + */ + +#include + +#include "math_private.h" + +OLM_DLLEXPORT double +creal(double complex z) +{ + return z; +} diff --git a/src/openlibm/src/s_creal.c.o b/src/openlibm/src/s_creal.c.o new file mode 100644 index 0000000000000000000000000000000000000000..a46b83e37987a27c7d496067b43e7e45b703cab7 GIT binary patch literal 1224 zcmb<-^>JfjWMqH=Mg}_u1P><4z;FUd&;cy$z`(=6&2X5(-PzenLBriIR8zswM9)ai zP{GK+$kf2l&_F>WC^bdFBe4W3p=++mz{0@5puoVuz{ICjymVtO{aatPo(7=3(cUz{tP=5|@F=L1}yx$UGK?kN>f$VaDQPZUzPhAtZ5- zez4x+_~fG0#2me31~3g4gZc@?W@2Dq0AUatjP;5ub4wDF81#xuiXe0bj8&3aQNo~? zl30?+pqEr!%%GQ?pPQSSSHhr|mtT^q=k6D(TU?TuoDJot=auRe6y+DB7L`;o=oO{r zBNq7s5@cy!^A<# z(Cr3kxd0*<7#I?uG#50E(Dj4NMUOj>76XvM3=9l{APy3S3d2P}^4RnzKozFLRYDk0 KVF-tTfdK$+3q{BP literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_crealf.c b/src/openlibm/src/s_crealf.c new file mode 100644 index 0000000..9aaed5f --- /dev/null +++ b/src/openlibm/src/s_crealf.c @@ -0,0 +1,37 @@ +/*- + * Copyright (c) 2004 Stefan Farfeleder + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/msun/src/s_crealf.c,v 1.1 2004/05/30 09:21:56 stefanf Exp $ + */ + +#include + +#include "math_private.h" + +OLM_DLLEXPORT float +crealf(float complex z) +{ + return z; +} diff --git a/src/openlibm/src/s_crealf.c.o b/src/openlibm/src/s_crealf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..97b76c8abae4ff57f607991a82fc589238ee557d GIT binary patch literal 1224 zcmb<-^>JfjWMqH=Mg}_u1P><4z;FUd&;cy$z`(=6&2X5(-PzenLBriIR8zswM9)ai zP{GK+$kf2l&_F>WC^bdFBe4W3p=++mz{0@5puoVuz{ICjymVtO{aatPo(7=3(cUz{tP=5|@F=L1}yx$UGK?kN>f$VaDQP9tH*mAtZ5- zez4x+_~fG0#GEv}WCjQWEDH7$h{eRfzyQJ^HW=#_SLT)^CNbz0mlQ$h3>d2Aip2tv(;3qTnOP=)DG LK8%72!?+9pLpny6 literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_creall.c b/src/openlibm/src/s_creall.c new file mode 100644 index 0000000..576666e --- /dev/null +++ b/src/openlibm/src/s_creall.c @@ -0,0 +1,37 @@ +/*- + * Copyright (c) 2004 Stefan Farfeleder + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/msun/src/s_creall.c,v 1.1 2004/05/30 09:21:56 stefanf Exp $ + */ + +#include + +#include "math_private.h" + +OLM_DLLEXPORT long double +creall(long double complex z) +{ + return z; +} diff --git a/src/openlibm/src/s_creall.c.o b/src/openlibm/src/s_creall.c.o new file mode 100644 index 0000000000000000000000000000000000000000..81022883a7e79617d440c9497909d693986fc28d GIT binary patch literal 1232 zcmb<-^>JfjWMqH=Mg}_u1P><4z;FRc&;cy$z`(=6&2T$Mh2t=TyR);Ef`+?asHTFU ziJp<3p@NZtk*R^9p@D)%P-=>TM`8(7Lf2dqteb^_fkA8+ zEXlyYzzF5TtQCPuFjfUIFjfdKO7pODOkiYS0Ex>$^pY7M42X#!KY>_G3=9k)3}S<^UU6k^Nn#R%UU5kggwBAm zN>VFI81zySOA;CMl8TEN^pf*)b5rw581(Y;OH%dR{X%t%OA?c_q5Sl`QoVwr{DRb? zl1c`>qSTy3z0{2Ow4%h^RIp7H5z^qWXJBAMGX)aokoZED5 + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* csin() + * + * Complex circular sine + * + * + * + * SYNOPSIS: + * + * double complex csin(); + * double complex z, w; + * + * w = csin (z); + * + * + * + * DESCRIPTION: + * + * If + * z = x + iy, + * + * then + * + * w = sin x cosh y + i cos x sinh y. + * + * csin(z) = -i csinh(iz). + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * DEC -10,+10 8400 5.3e-17 1.3e-17 + * IEEE -10,+10 30000 3.8e-16 1.0e-16 + * Also tested by csin(casin(z)) = z. + * + */ + +#include +#include +#include + +#include "math_private.h" + +/* calculate cosh and sinh */ + +static void +cchsh(double x, double *c, double *s) +{ + double e, ei; + + if (fabs(x) <= 0.5) { + *c = cosh(x); + *s = sinh(x); + } + else { + e = exp(x); + ei = 0.5/e; + e = 0.5 * e; + *s = e - ei; + *c = e + ei; + } +} + +double complex +csin(double complex z) +{ + double complex w; + double ch, sh; + + cchsh( cimag (z), &ch, &sh ); + w = sin (creal(z)) * ch + (cos (creal(z)) * sh) * I; + return (w); +} + +#if LDBL_MANT_DIG == DBL_MANT_DIG +openlibm_strong_reference(csin, csinl); +#endif /* LDBL_MANT_DIG == DBL_MANT_DIG */ diff --git a/src/openlibm/src/s_csinf.c b/src/openlibm/src/s_csinf.c new file mode 100644 index 0000000..42aa981 --- /dev/null +++ b/src/openlibm/src/s_csinf.c @@ -0,0 +1,85 @@ +/* $OpenBSD: s_csinf.c,v 1.2 2010/07/18 18:42:26 guenther Exp $ */ +/* + * Copyright (c) 2008 Stephen L. Moshier + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* csinf() + * + * Complex circular sine + * + * + * + * SYNOPSIS: + * + * void csinf(); + * cmplxf z, w; + * + * csinf( &z, &w ); + * + * + * + * DESCRIPTION: + * + * If + * z = x + iy, + * + * then + * + * w = sin x cosh y + i cos x sinh y. + * + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE -10,+10 30000 1.9e-7 5.5e-8 + * + */ + +#include +#include + +/* calculate cosh and sinh */ + +static void +cchshf(float xx, float *c, float *s) +{ + float x, e, ei; + + x = xx; + if(fabsf(x) <= 0.5f) { + *c = coshf(x); + *s = sinhf(x); + } + else { + e = expf(x); + ei = 0.5f/e; + e = 0.5f * e; + *s = e - ei; + *c = e + ei; + } +} + +float complex +csinf(float complex z) +{ + float complex w; + float ch, sh; + + cchshf(cimagf(z), &ch, &sh); + w = sinf(crealf(z)) * ch + (cosf(crealf(z)) * sh) * I; + return (w); +} diff --git a/src/openlibm/src/s_csinh.c b/src/openlibm/src/s_csinh.c new file mode 100644 index 0000000..3838f25 --- /dev/null +++ b/src/openlibm/src/s_csinh.c @@ -0,0 +1,157 @@ +/*- + * Copyright (c) 2005 Bruce D. Evans and Steven G. Kargl + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Hyperbolic sine of a complex argument z = x + i y. + * + * sinh(z) = sinh(x+iy) + * = sinh(x) cos(y) + i cosh(x) sin(y). + * + * Exceptional values are noted in the comments within the source code. + * These values and the return value were taken from n1124.pdf. + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_csinh.c,v 1.2 2011/10/21 06:29:32 das Exp $"); + +#include +#include + +#include "math_private.h" + +static const double huge = 0x1p1023; + +OLM_DLLEXPORT double complex +csinh(double complex z) +{ + double x, y, h; + int32_t hx, hy, ix, iy, lx, ly; + + x = creal(z); + y = cimag(z); + + EXTRACT_WORDS(hx, lx, x); + EXTRACT_WORDS(hy, ly, y); + + ix = 0x7fffffff & hx; + iy = 0x7fffffff & hy; + + /* Handle the nearly-non-exceptional cases where x and y are finite. */ + if (ix < 0x7ff00000 && iy < 0x7ff00000) { + if ((iy | ly) == 0) + return (CMPLX(sinh(x), y)); + if (ix < 0x40360000) /* small x: normal case */ + return (CMPLX(sinh(x) * cos(y), cosh(x) * sin(y))); + + /* |x| >= 22, so cosh(x) ~= exp(|x|) */ + if (ix < 0x40862e42) { + /* x < 710: exp(|x|) won't overflow */ + h = exp(fabs(x)) * 0.5; + return (CMPLX(copysign(h, x) * cos(y), h * sin(y))); + } else if (ix < 0x4096bbaa) { + /* x < 1455: scale to avoid overflow */ + z = __ldexp_cexp(CMPLX(fabs(x), y), -1); + return (CMPLX(creal(z) * copysign(1, x), cimag(z))); + } else { + /* x >= 1455: the result always overflows */ + h = huge * x; + return (CMPLX(h * cos(y), h * h * sin(y))); + } + } + + /* + * sinh(+-0 +- I Inf) = sign(d(+-0, dNaN))0 + I dNaN. + * The sign of 0 in the result is unspecified. Choice = normally + * the same as dNaN. Raise the invalid floating-point exception. + * + * sinh(+-0 +- I NaN) = sign(d(+-0, NaN))0 + I d(NaN). + * The sign of 0 in the result is unspecified. Choice = normally + * the same as d(NaN). + */ + if ((ix | lx) == 0 && iy >= 0x7ff00000) + return (CMPLX(copysign(0, x * (y - y)), y - y)); + + /* + * sinh(+-Inf +- I 0) = +-Inf + I +-0. + * + * sinh(NaN +- I 0) = d(NaN) + I +-0. + */ + if ((iy | ly) == 0 && ix >= 0x7ff00000) { + if (((hx & 0xfffff) | lx) == 0) + return (CMPLX(x, y)); + return (CMPLX(x, copysign(0, y))); + } + + /* + * sinh(x +- I Inf) = dNaN + I dNaN. + * Raise the invalid floating-point exception for finite nonzero x. + * + * sinh(x + I NaN) = d(NaN) + I d(NaN). + * Optionally raises the invalid floating-point exception for finite + * nonzero x. Choice = don't raise (except for signaling NaNs). + */ + if (ix < 0x7ff00000 && iy >= 0x7ff00000) + return (CMPLX(y - y, x * (y - y))); + + /* + * sinh(+-Inf + I NaN) = +-Inf + I d(NaN). + * The sign of Inf in the result is unspecified. Choice = normally + * the same as d(NaN). + * + * sinh(+-Inf +- I Inf) = +Inf + I dNaN. + * The sign of Inf in the result is unspecified. Choice = always +. + * Raise the invalid floating-point exception. + * + * sinh(+-Inf + I y) = +-Inf cos(y) + I Inf sin(y) + */ + if (ix >= 0x7ff00000 && ((hx & 0xfffff) | lx) == 0) { + if (iy >= 0x7ff00000) + return (CMPLX(x * x, x * (y - y))); + return (CMPLX(x * cos(y), INFINITY * sin(y))); + } + + /* + * sinh(NaN + I NaN) = d(NaN) + I d(NaN). + * + * sinh(NaN +- I Inf) = d(NaN) + I d(NaN). + * Optionally raises the invalid floating-point exception. + * Choice = raise. + * + * sinh(NaN + I y) = d(NaN) + I d(NaN). + * Optionally raises the invalid floating-point exception for finite + * nonzero y. Choice = don't raise (except for signaling NaNs). + */ + return (CMPLX((x * x) * (y - y), (x + x) * (y - y))); +} + +OLM_DLLEXPORT double complex +csin(double complex z) +{ + + /* csin(z) = -I * csinh(I * z) */ + z = csinh(CMPLX(-cimag(z), creal(z))); + return (CMPLX(cimag(z), -creal(z))); +} diff --git a/src/openlibm/src/s_csinh.c.o b/src/openlibm/src/s_csinh.c.o new file mode 100644 index 0000000000000000000000000000000000000000..b784ef21ad0e5ea8e4f9a3117f7089f5657ee798 GIT binary patch literal 4048 zcmb<-^>JfjWMqH=Mg}_u1P><4z#zbbU^{@B4h;MZd<-7VZ!|vf3;L*VeBu{$Q4x3n zlKaFj5ThdSiC+LB%%YOUuW=YABchV#!C!YQjbGyih;hlI^Ml91R|*~nUnq25RQ><| ze|_UaF!}TU|M&F{{L_xxf*Abm6B!s799sVKw{$QtFmQh0Z&|^}z|i>f|9?{l{x%gR z5Zh6&&4ItI0?b~ydzu4(+ZhH1hEM#Fq7Y|+T=Icr+i;I6NWElfUkQW9La%&V!}KP=^{YGBBj^ zYaIH-A9MQ?f8?Q0{1KNv@kd_%#2(fy6pZEpA!FlKtzhH=p1k4{YD*ONc|NkGP6e@%nB_S#j zVBMei1z15=gPa0YEFc5&a1J=mz#$NMBaL6 z<&l5?|AXTDeLa8M91t53R=xlJ{|7sTzm1C#6yq_sAu#|7{m5Hj?XCa*|DOO(rJ#sJ z3&0p~yn}=G@F#x37(_}|0R;^>>>?jP%mgJ8sM7>lR9;^E3krDo7EqWnpqLL$XHc~Q zsvs4g_ys_z3vAY@G=7aE;6#U%Z$KFd;trTTka_{I10yeh!WAtAf8rNNQ4s(|$|wHF zGax6voCR@`3pfFR`~xyVFh+%gNF$+!@q!!-Hqi6$|Ns2*5c5t$;t4$$od7FT0NI?T z#}5sT3BexCZxp}TM`8(7Lf2fA zfq{jAfkA3ujfW%;BEF+Z92{xR8K?F)ORs}IIRtPXk^RRPFU}Ru0 zU|?X7fy#-13~=EyVEV;g?8iE_Fkd;9IOd|*gpOpdKGH`(m4i$u2 z5K9U~Ft9R6fN2CF4`#A~Nn}EWfq_8?$vxn(VPIg;Vqm~<3rHU*93gH3@etSyhx%w7 z;#N4sK?w<)`93(*gUSSK>O*m;_rM_@1q}xUP}*Q%U;xKA$a}@{$;Fv@8G6YKdOprZ zAi@wt7=Q>95MjyyR=|*4l$w~sker#Dn9h)#U(Aq}m{iOVAD@$wT2T<6oLW)9kepvo zS)7@k2a?VJ>tbLK1lhp=N#~$6{0CGG{r~@88%dmtfq?-gz5*)F#K6G7j3f@K13^+C z=Y!G`O#Ne!Ak=(N69gvS07{@xaZoV@6Q7JE&WB|F5+reCcW#G@gWLnM8)nV{s5nTB zAIY5ONaD!;G6ER@bq^>$Vdlgki6fhH5J?-sZhsJK!N-X$|9h+L^cM}XJBC11`RKm94PI>*dSUO z8ul>tATbbj07Vi51A_!KU4YUM$R4OLyuMIlU;x(!P-P&kVEhfuUa%lkEsPDKbr=}H zbrre#4WVX&@*K!K82$mZ9~3??F%S)NKa94+pLkB0M(D~E||YTYCyOa z>VI_o6QKGFK#Gtsy8a3r=_dkI7%@QFQ6TN0^aCnCVESS04Um7(?FOl5fF|e%AO#Ez z44|?Wq!)xi@-Y3NvH?BqfaD*50)>HrAs)m*!cgPjBA~JzoBj@{``h6vAq;f=0HTmP Ay#N3J literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_csinhf.c b/src/openlibm/src/s_csinhf.c new file mode 100644 index 0000000..94954b0 --- /dev/null +++ b/src/openlibm/src/s_csinhf.c @@ -0,0 +1,105 @@ +/*- + * Copyright (c) 2005 Bruce D. Evans and Steven G. Kargl + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Hyperbolic sine of a complex argument z. See s_csinh.c for details. + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_csinhf.c,v 1.2 2011/10/21 06:29:32 das Exp $"); + +#include +#include + +#include "math_private.h" + +static const float huge = 0x1p127; + +OLM_DLLEXPORT float complex +csinhf(float complex z) +{ + float x, y, h; + int32_t hx, hy, ix, iy; + + x = crealf(z); + y = cimagf(z); + + GET_FLOAT_WORD(hx, x); + GET_FLOAT_WORD(hy, y); + + ix = 0x7fffffff & hx; + iy = 0x7fffffff & hy; + + if (ix < 0x7f800000 && iy < 0x7f800000) { + if (iy == 0) + return (CMPLXF(sinhf(x), y)); + if (ix < 0x41100000) /* small x: normal case */ + return (CMPLXF(sinhf(x) * cosf(y), coshf(x) * sinf(y))); + + /* |x| >= 9, so cosh(x) ~= exp(|x|) */ + if (ix < 0x42b17218) { + /* x < 88.7: expf(|x|) won't overflow */ + h = expf(fabsf(x)) * 0.5f; + return (CMPLXF(copysignf(h, x) * cosf(y), h * sinf(y))); + } else if (ix < 0x4340b1e7) { + /* x < 192.7: scale to avoid overflow */ + z = __ldexp_cexpf(CMPLXF(fabsf(x), y), -1); + return (CMPLXF(crealf(z) * copysignf(1, x), cimagf(z))); + } else { + /* x >= 192.7: the result always overflows */ + h = huge * x; + return (CMPLXF(h * cosf(y), h * h * sinf(y))); + } + } + + if (ix == 0 && iy >= 0x7f800000) + return (CMPLXF(copysignf(0, x * (y - y)), y - y)); + + if (iy == 0 && ix >= 0x7f800000) { + if ((hx & 0x7fffff) == 0) + return (CMPLXF(x, y)); + return (CMPLXF(x, copysignf(0, y))); + } + + if (ix < 0x7f800000 && iy >= 0x7f800000) + return (CMPLXF(y - y, x * (y - y))); + + if (ix >= 0x7f800000 && (hx & 0x7fffff) == 0) { + if (iy >= 0x7f800000) + return (CMPLXF(x * x, x * (y - y))); + return (CMPLXF(x * cosf(y), INFINITY * sinf(y))); + } + + return (CMPLXF((x * x) * (y - y), (x + x) * (y - y))); +} + +OLM_DLLEXPORT float complex +csinf(float complex z) +{ + + z = csinhf(CMPLXF(-cimagf(z), crealf(z))); + return (CMPLXF(cimagf(z), -crealf(z))); +} diff --git a/src/openlibm/src/s_csinhf.c.o b/src/openlibm/src/s_csinhf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..9487ae185d8f4dce7c00a232094c0f64c7c91bdd GIT binary patch literal 4112 zcmb<-^>JfjWMqH=Mg}_u1P><4z!1QLU^{@B4h;MZd<N`g#ZcX~!CWfmrG)^G7}bJC5Zuzo3c=*!dj%8i!yCMLob4Mt7vxL_27ZlGkgyO$O=uVR zHSWA*0Q;o@6amQgLsi18(uK$ifZ{Ro1;54_evPBx$bdTr$(1loVE2K=LGA-N9uZ;S zXcYiQ+h_jBt1l}-ZUuV~WQAY|+#_HsL3tONF(9FUFh~^YGLU7F7hW2I%#m*a3F0ju zc)*DWR9?V+-~&o&0x{rJ=>p1Gf=|G~E3{H5Cj^^o;Zj6^smwObrYT4HPtjQd1N>5=)>Gy5^b; z3@i)`3QJROHV*(=sg9HNu zgA7zo0%U+EUjTC$BNrcsBR5FS0xI_nM0@fDFumd905Nf4ko_zSAOB;MXU0;aK&lf~ z26RIO!3MB`{Rw752{AAY@->(NC#1nFRtAW9U=El7g%JY-8<>qufC_yfB=>;*&cMK+ z!@$5GfUFS8HpU@tg+n|Ahd3x9U^Cwphx%X~;%Yd=V{wT4;Sf(|U|;}+g90e-85kJA z@eJ~FaeQ)dW?n{`UNVE8kFyboFa!|>Ai@Mhm@+_AFeDeHCg!9uBxmL(rl&C^=NG3j zq$MU5r!mCG=cJ@o6vQW|Ruq6F3Mz{;)AK;A;*2z~?lh29Aglo*7$E5ylxF{c>b3v> z{|6w6b1^V5z{K}J#hDlw7?_d7&p^dN-r+_P|B56IN+U3H@<9m}YA-L6dQjc~X#ttT zha|oONjGKU4E5Na>7zjTqrk=1)5iG$J)%=`y9#D5}* zBZq?+D6pXRg7O&598)B5WP9V0#F4`%1xZ{8$zM58agg<(TnaP44JwWv4l|L&k=?l! zNgO%8?jwmKtN({2j;x*yWFZ3s1IRs~QUK;252!eZLJt2zkN`A%kmI)=Dh@J-9m&5l zq2eG4REELKKL`?lnuBcqDgl#|s)L$TRSpH?uE3V8f zNlaqUD=sO5&>1jRQEE=2UP)?234>lrVo4%{UQ%%}gI-ZSh@+QWTw;REF*IY)OU}>D zP0cG|(96p&N!4@r3)L+yNlea$^3(H5^$Lpe3sQ?pDjD>^hNou4rxhjUra~P@0R{3m zDC>aY4A~e+pM!xx43xN#BtUrriOT@04?sZ*QxB7C07Vi51A_!Ky@1jR$R4OLxIP4_ z1(mNLai}to5EzG{*$WnAU_h!#AR?f81Y{<;`VFCGg7Ox`LmM7>PHp>v0?f_Y!C(|Ay7U8 zrEL%&hBrXk6u8zgQ3P0$ZO3K$p|KxHaOF9?I=VfsO31A5v4$qPUgW`a0K7-}3` U1XQ+T(|-c${&u)Z2m@U|067LyV*mgE literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_csinhl.c b/src/openlibm/src/s_csinhl.c new file mode 100644 index 0000000..57b577f --- /dev/null +++ b/src/openlibm/src/s_csinhl.c @@ -0,0 +1,58 @@ +/* $OpenBSD: s_csinhl.c,v 1.2 2011/07/20 19:28:33 martynas Exp $ */ + +/* + * Copyright (c) 2008 Stephen L. Moshier + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* csinhl + * + * Complex hyperbolic sine + * + * + * + * SYNOPSIS: + * + * long double complex csinhl(); + * long double complex z, w; + * + * w = csinhl (z); + * + * DESCRIPTION: + * + * csinh z = (cexp(z) - cexp(-z))/2 + * = sinh x * cos y + i cosh x * sin y . + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE -10,+10 30000 3.1e-16 8.2e-17 + * + */ + +#include +#include + +long double complex +csinhl(long double complex z) +{ + long double complex w; + long double x, y; + + x = creall(z); + y = cimagl(z); + w = sinhl(x) * cosl(y) + (coshl(x) * sinl(y)) * I; + return (w); +} diff --git a/src/openlibm/src/s_csinhl.c.o b/src/openlibm/src/s_csinhl.c.o new file mode 100644 index 0000000000000000000000000000000000000000..141c3a3f357d6168e8f63dff1af2adc1f13a2b42 GIT binary patch literal 1832 zcmb<-^>JfjWMqH=Mg}_u1P><4!0>_@!FB*M9T<2Sco;mI-&p)FQHemtFF^9QYg80G znvWM9GmsS{g+EL<7DxOgKm!yOPoVe%*$u)Vy)bc*HRyJO + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* csinl() + * + * Complex circular sine + * + * + * + * SYNOPSIS: + * + * long double complex csinl(); + * long double complex z, w; + * + * w = csinl( z ); + * + * + * + * DESCRIPTION: + * + * If + * z = x + iy, + * + * then + * + * w = sin x cosh y + i cos x sinh y. + * + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * DEC -10,+10 8400 5.3e-17 1.3e-17 + * IEEE -10,+10 30000 3.8e-16 1.0e-16 + * Also tested by csin(casin(z)) = z. + * + */ + +#include +#include + +static void +cchshl(long double x, long double *c, long double *s) +{ + long double e, ei; + + if(fabsl(x) <= 0.5L) { + *c = coshl(x); + *s = sinhl(x); + } else { + e = expl(x); + ei = 0.5L/e; + e = 0.5L * e; + *s = e - ei; + *c = e + ei; + } +} + +long double complex +csinl(long double complex z) +{ + long double complex w; + long double ch, sh; + + cchshl(cimagl(z), &ch, &sh); + w = sinl(creall(z)) * ch + (cosl(creall(z)) * sh) * I; + return (w); +} diff --git a/src/openlibm/src/s_csinl.c.o b/src/openlibm/src/s_csinl.c.o new file mode 100644 index 0000000000000000000000000000000000000000..113b4d031110de48a0d6622fef83f93bb15475a4 GIT binary patch literal 2368 zcmb<-^>JfjWMqH=Mg}_u1P><4z|g>oU^{@B4h;MZd<-7VZ#4dwsCXdb7a;j~$B3H; zZriBbu2B&H3)}>o;27x`b^qht8@F{-_?!9}7(fOHz!WNg6?!zk5x8BWqHsG$#o)G$ z3RLWf0>~s}Yd~zUWJDB9+3g$^g?lGKn*W!mL?C0ZLXYMn3P?%??w!2(4y47S`H01x zlQ&P@J9rpuIn>hIx*(6-JaFUF%~SVI-aK&Q5l9Kh8If@>^Zx(;50YkJu!m46WWzt0 zsJpYXm4b%5U#O;np^2W6o}q$~fsv_!p`n3-Mo?;sf=6NrR6^HWlYxPSfq_ARfq?-O zSnhtI3``7+2S8%5IAMhHnW5H+KxxLRAO^+?0Y+&ac8&>*3=Am@3=A?*xxXOVh0nl+ z&%%Yz!G+Jmg)hL3&%=q&A&k$$iO(RA&mo8}AcW7r166?|NC8N(3txl_UxFu}Lj)g( zJIEY|WIhW=J_C@sI55b)EDRr^L4>M^8A}S|1}g#i8q9zb0$>&!m_#N-85kIZkjw%5 zk%56hnt_1_c^Nqj$wjG&Ibfk2hSZ9J9FWgJ;RB*U zX$KT~fBr*&8c2`l5^q2f=Ry+i zLJ|kXHO%~#NaD!qw<3x2AenOmNt_o+{2o*sV5_40*E}@73`45!W zKyi$05GZ|t_^^BdVuLVxngit*PTK>8;@1zkZLBn+|-iOV1eE$@)UKR literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_csqrt.c b/src/openlibm/src/s_csqrt.c new file mode 100644 index 0000000..9cf4255 --- /dev/null +++ b/src/openlibm/src/s_csqrt.c @@ -0,0 +1,114 @@ +/*- + * Copyright (c) 2007 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_csqrt.c,v 1.4 2008/08/08 00:15:16 das Exp $"); + +#include +#include +#include + +#include "math_private.h" + +/* + * gcc doesn't implement complex multiplication or division correctly, + * so we need to handle infinities specially. We turn on this pragma to + * notify conforming c99 compilers that the fast-but-incorrect code that + * gcc generates is acceptable, since the special cases have already been + * handled. + */ +#ifndef __GNUC__ +#pragma STDC CX_LIMITED_RANGE ON +#endif + +/* We risk spurious overflow for components >= DBL_MAX / (1 + sqrt(2)). */ +#define THRESH 0x1.a827999fcef32p+1022 + +OLM_DLLEXPORT double complex +csqrt(double complex z) +{ + double complex result; + double a, b; + double t; + int scale; + + a = creal(z); + b = cimag(z); + + /* Handle special cases. */ + if (z == 0) + return (CMPLX(0, b)); + if (isinf(b)) + return (CMPLX(INFINITY, b)); + if (isnan(a)) { + t = (b - b) / (b - b); /* raise invalid if b is not a NaN */ + return (CMPLX(a, t)); /* return NaN + NaN i */ + } + if (isinf(a)) { + /* + * csqrt(inf + NaN i) = inf + NaN i + * csqrt(inf + y i) = inf + 0 i + * csqrt(-inf + NaN i) = NaN +- inf i + * csqrt(-inf + y i) = 0 + inf i + */ + if (signbit(a)) + return (CMPLX(fabs(b - b), copysign(a, b))); + else + return (CMPLX(a, copysign(b - b, b))); + } + /* + * The remaining special case (b is NaN) is handled just fine by + * the normal code path below. + */ + + /* Scale to avoid overflow. */ + if (fabs(a) >= THRESH || fabs(b) >= THRESH) { + a *= 0.25; + b *= 0.25; + scale = 1; + } else { + scale = 0; + } + + /* Algorithm 312, CACM vol 10, Oct 1967. */ + if (a >= 0) { + t = sqrt((a + hypot(a, b)) * 0.5); + result = CMPLX(t, b / (2 * t)); + } else { + t = sqrt((-a + hypot(a, b)) * 0.5); + result = CMPLX(fabs(b) / (2 * t), copysign(t, b)); + } + + /* Rescale. */ + if (scale) + return (result * 2); + else + return (result); +} + +#if LDBL_MANT_DIG == 53 +openlibm_weak_reference(csqrt, csqrtl); +#endif diff --git a/src/openlibm/src/s_csqrt.c.o b/src/openlibm/src/s_csqrt.c.o new file mode 100644 index 0000000000000000000000000000000000000000..47cf42ea3fc82353a0377fa37b35b8c99f29e167 GIT binary patch literal 3104 zcmb<-^>JfjWMqH=Mg}_u1P><4z_5S=!FB*M9T@l+co~AzJoxJldo;gM_{1;hqr&k5 zB=?D5z(ckbebAR0JSFtp9<(X&D0p1IXqyevM-& zVG#iioJg=~U}r(BN#obJ@rgg;z$gB=3u*ishe3K#`6Mw|*Py7*}usZxQ z=HLJS;P3*e02=`E7sRVCo&SM6rhyz^XufGS`v3p`OTYghLm>VKnFDvF1lYt+{4rQv zDFIGkps z{Q6S(|NsBsxL{!TP;d19&&QJROHV*(=sg9!rzgA7#eIuio}gCn0nGm|Hu0aGj&pMWDDhX;2m z7oUJDABP)vCPc)K8>$`~1+t%o;Umn$C`y>Ilmrm7K)ygx${+ydvN9kQ6JQZhFv$v) z2XnxL6qsaXkO0#NLY{$vK?uoSupb#17*rV;Fw6ky(#9cfh(p{Qhqx^cad#ZzJ~+ff zafpNB9uh_%S0mx#_~hckq7uDi20b5VLl9vEB8)+V2?JP;A-O0uF^3^JGdD4vA+tC$ zFO4CyI4?1eAwIr1Gd(XUvxFfnF{zj#IlrJ1B*2hSS&&}>u|p6-fzux-ZvOm-0CgmB zP@02@S0jmYF)%Q|#CxIQpd`nPB)%3Z4ob_Qv;kB96iFP}oIgn7JV@q9gAyVGB%kmi ziJKyc^C5}HB8elbPlbwu+zE0M%srJz;-J(E6W<9H2dU*pGXFSK9Apj~lK2^@I7mGx zK4IqYf)qmCkL*ruBynVS8bifF6v!-?Iq@I?s5!{)$%Tr8C}j5(fdruHk=@gaB#vzF z9wc#OcY@L5(d4z{E}2XcfU~G;*!MVY$!iHuT-y~D8C@JsHBoX z4{Tg&MtoXPVs0wfZYmHUe}SS56lTcALE11346yPACI<>b7#l=OL&FxP9wY|B4?u~C zfq_8-8d#vT53&c8$3XJ1a!rka0bH7a@(f5EhQ-kZpb{W6piD5O!@vM8Q_+zibf|t9 zA4a3A4QF6rU}s=pfCe*68AAqCKf1eM?uIGMhq@nK{|u=90GL83jjlfnNBna@6~f{f z6#t-d6eD3#k1wKnfTb7(itq$e-x?L1sdgg0#VL12p|b!$lwrsBsVu W0|Nu7{KuwW0cuetTqT5ot{(u&?;>;n literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_csqrtf.c b/src/openlibm/src/s_csqrtf.c new file mode 100644 index 0000000..a131829 --- /dev/null +++ b/src/openlibm/src/s_csqrtf.c @@ -0,0 +1,90 @@ +/*- + * Copyright (c) 2007 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_csqrtf.c,v 1.3 2008/08/08 00:15:16 das Exp $"); + +#include +#include + +#include "math_private.h" + +/* + * gcc doesn't implement complex multiplication or division correctly, + * so we need to handle infinities specially. We turn on this pragma to + * notify conforming c99 compilers that the fast-but-incorrect code that + * gcc generates is acceptable, since the special cases have already been + * handled. + */ +#ifndef __GNUC__ +#pragma STDC CX_LIMITED_RANGE ON +#endif + +OLM_DLLEXPORT float complex +csqrtf(float complex z) +{ + float a = crealf(z), b = cimagf(z); + double t; + + /* Handle special cases. */ + if (z == 0) + return (CMPLXF(0, b)); + if (isinf(b)) + return (CMPLXF(INFINITY, b)); + if (isnan(a)) { + t = (b - b) / (b - b); /* raise invalid if b is not a NaN */ + return (CMPLXF(a, t)); /* return NaN + NaN i */ + } + if (isinf(a)) { + /* + * csqrtf(inf + NaN i) = inf + NaN i + * csqrtf(inf + y i) = inf + 0 i + * csqrtf(-inf + NaN i) = NaN +- inf i + * csqrtf(-inf + y i) = 0 + inf i + */ + if (signbit(a)) + return (CMPLXF(fabsf(b - b), copysignf(a, b))); + else + return (CMPLXF(a, copysignf(b - b, b))); + } + /* + * The remaining special case (b is NaN) is handled just fine by + * the normal code path below. + */ + + /* + * We compute t in double precision to avoid overflow and to + * provide correct rounding in nearly all cases. + * This is Algorithm 312, CACM vol 10, Oct 1967. + */ + if (a >= 0) { + t = sqrt((a + hypot(a, b)) * 0.5); + return (CMPLXF(t, b / (2.0 * t))); + } else { + t = sqrt((-a + hypot(a, b)) * 0.5); + return (CMPLXF(fabsf(b) / (2.0 * t), copysignf(t, b))); + } +} diff --git a/src/openlibm/src/s_csqrtf.c.o b/src/openlibm/src/s_csqrtf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..ef225284b6790bc72111609ad9c0aad2f258357c GIT binary patch literal 3064 zcmb<-^>JfjWMqH=Mg}_u1P><4!0>||!FB*M9T)@{_!%6-(meR<4g_}|_Bi-L!K3+& zMW>63&S!o>7Zr`q{Bx|ZLK^@31N?d~_-7yBcRkc{pu_^AnP1}uzup75sM2SC!59^Z&-{WRDl%Y` zBs`jrSVTL<9p;yB0U5=>uW<-04R?YpNcc0qK!^%Q>w(gJX^#APAg6>N90`^w5&O&^ za|tAS?=yegrPovW(^GBWf%pY~X zC?t(v>K@3lpMU@V2Zb6#Lp_)R6A$dc6odfB8-&Tgz~JueY^9*#?iZ@5U}&Oeq-UsL zWME`!U}$Kdpb?asqTrEO0+rA;*JNN|VPIfTU|?VX1+cqcC<7A%;{lKuERQfk`J7M- zM4&WdRS*MXg#e>84?D*MMg|5Q1_lNhs9Y-(0|SE-pFkgz8=piovlm|gQxg}Tgd?AT z6CZ~sH&hjN3S=(}!$*jh(UdS_$+a1^FcmATt=! z5|fJ47?Se~DvLAI^FV4qbW&zX8iP7C&_HPl6zYHeLx4MyI0pj*15A7sk~k>M!NfN~ z#X(7n8A<&as5r=cE+p|kNaD!m*n$!m10>ypQXVt_dg^GjJBb&b&Dh^T)l7p$=0Tl;{A)9{&Nt_qSUu+-)pzh~G5?4bK=SLEE zLJ~(dCmKl{*_;v_;-E4D6r><&5C*ZqSg*J;wpmzJ=2_7o--IR5Iv+ZA#6EPb*5yO$9rPQUc^(P!yn-Adt2J0|TslfZ2myMu5r_ zP@KZl!_+l^5(@(Z!wHb#3=9mQH~}$1c>ttF0z@z{FsLywfJ-A#T89dOsiP=?4;BIw zATz)WC;=*uL1vPx-wGI!!SOK_Qs+A z0aQPFc*FQGIufcMR35|Z0MQ?y`t?B^Bn%5b7@Y*wkE8_5lt&LxuqY(1piD4T#K6D+ zD(|4yfyF?C0#rY`yI}qXsR7|GsQu{r1EBgr^#e#945RCBg_aTM>CXe?Ci#Kkl@JEHegNDu1l9lm literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_csqrtl.c b/src/openlibm/src/s_csqrtl.c new file mode 100644 index 0000000..da97fb2 --- /dev/null +++ b/src/openlibm/src/s_csqrtl.c @@ -0,0 +1,109 @@ +/*- + * Copyright (c) 2007-2008 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "cdefs-compat.h" + +#include +#include +#include + +#include "math_private.h" + +/* + * gcc doesn't implement complex multiplication or division correctly, + * so we need to handle infinities specially. We turn on this pragma to + * notify conforming c99 compilers that the fast-but-incorrect code that + * gcc generates is acceptable, since the special cases have already been + * handled. + */ +#ifndef __GNUC__ +#pragma STDC CX_LIMITED_RANGE ON +#endif + +/* We risk spurious overflow for components >= LDBL_MAX / (1 + sqrt(2)). */ +#define THRESH (LDBL_MAX / 2.414213562373095048801688724209698L) + +OLM_DLLEXPORT long double complex +csqrtl(long double complex z) +{ + long double complex result; + long double a, b; + long double t; + int scale; + + a = creall(z); + b = cimagl(z); + + /* Handle special cases. */ + if (z == 0) + return (CMPLXL(0, b)); + if (isinf(b)) + return (CMPLXL(INFINITY, b)); + if (isnan(a)) { + t = (b - b) / (b - b); /* raise invalid if b is not a NaN */ + return (CMPLXL(a, t)); /* return NaN + NaN i */ + } + if (isinf(a)) { + /* + * csqrt(inf + NaN i) = inf + NaN i + * csqrt(inf + y i) = inf + 0 i + * csqrt(-inf + NaN i) = NaN +- inf i + * csqrt(-inf + y i) = 0 + inf i + */ + if (signbit(a)) + return (CMPLXL(fabsl(b - b), copysignl(a, b))); + else + return (CMPLXL(a, copysignl(b - b, b))); + } + /* + * The remaining special case (b is NaN) is handled just fine by + * the normal code path below. + */ + + /* Scale to avoid overflow. */ + if (fabsl(a) >= THRESH || fabsl(b) >= THRESH) { + a *= 0.25; + b *= 0.25; + scale = 1; + } else { + scale = 0; + } + + /* Algorithm 312, CACM vol 10, Oct 1967. */ + if (a >= 0) { + t = sqrtl((a + hypotl(a, b)) * 0.5); + result = CMPLXL(t, b / (2 * t)); + } else { + t = sqrtl((-a + hypotl(a, b)) * 0.5); + result = CMPLXL(fabsl(b) / (2 * t), copysignl(t, b)); + } + + /* Rescale. */ + if (scale) + return (result * 2); + else + return (result); +} diff --git a/src/openlibm/src/s_csqrtl.c.o b/src/openlibm/src/s_csqrtl.c.o new file mode 100644 index 0000000000000000000000000000000000000000..0a58f7a4e5b426857a89c8c8cb863f0cf9adf1ba GIT binary patch literal 3384 zcmb<-^>JfjWMqH=Mg}_u1P><4z)-=7U^{@B4h;MZdA~f1cr?EexOw2VjS9#CV9Ok%9HVdN zs0g$kC=s~H3Ni*_0>8Wi!|fUsf&V2c93Tu)9N`!VRV;kt!EGHCu-cmk?|nLqRefAM zM0MxklH|KLK*oSD*r?k%Dhg4NHxJx+*m{7!R#Ql$VZ-5-b-?R*57uct_ zbyRkP;`7GI+cqlqPTqWXTSw*g$GbQAn?S*T^Q1@f8-<$(K&IXXxdQ5{$T*NW_YU6R z1sM)=>&*iJ6djJ3be`$vZhr6ip{J%s+0))Zg77+z@ z{YzBWgKPqY{_PwU1DK5lVD%su-8^vP;Jsgv_yMWF=HigMU2r(QDs|NozX zfuW(EfuX^Ufq}su6iy&4IH~ga`7^>-{?>zd3=9nJ&dyc}8t#6fnhJ&{dPaJN3PuJ- zrUr(F1_~NMsVNE`i6u}8U2{za1{MYe1_cHN22kX=`-L(vF)$tgiGkt}WFjM!&kW)) zFffQfX~wD`2F3~jMrj^)jtPtm3}+Y^7-XPwznK^q7##Tonwebq99;N3T=)W9_##~R z5`0m)o_r3qTzmqKd>roFVSE7rd>&4G4nYtRS8flmMt87aAVkm;D(J@N;mGF@09N1y zW{2?w`0yq8^JTd375MTwgn*^|!BQ1`3Bi03j(h>JV59Q+5<>VKy!Zklz}y7B0AH}% z+`wug_!8>)Amt6zGiVejTv!-Bf+7P=hJk?@OG(B9Rs{-OFau5qf>~@}5}6PKb6COg z0%k%9X)w*ozyYQa1Ssx=kn9DAJp%)SIs*fP074m@rH4b@6o)t{v0*dE9f$fL9O4l; z#FKD{E8-AmD2`7qE-Wg^(Mx8~^Kmu=5k?@w7(|#bKqMKGi&7JFau|{`a}(2Z7~MhXoEc zlrZR}B$gyH=p_{wGw2oNgE)H0#U&=l978h(z2yAd+|;}h2EDxel2ko+zfj%clEma} zC_g=~RIi{YzaX`!q>@1oYf#fAX1Oo$u8Uq8klmq1*s1TU4Mi&5!LexT; zU`mI90bF*XD<@XJA=G{$uxSXw25KP4-3U=g{si$seg@H?aunn*bo~KP{pjHZEh73z-gu>IaD-<9?`qWHAsMrXR!xVNeocXJBA}MiWQ~j3+?# zqq_?he_%xn3=FkU`_c6ufa(V~j9`kPafQTXsDS2C^z?HBY7s1*fZ_pEUP6T#VB#SE zpxX^He+4vxW`GnhFff4fI>?{s`axwp)TtnCaO?n0znO3m2m@*ygu}qV0IKh?>Hh$= Ms2#2n!a&y#0BcIMg#Z8m literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_ctan.c b/src/openlibm/src/s_ctan.c new file mode 100644 index 0000000..9420095 --- /dev/null +++ b/src/openlibm/src/s_ctan.c @@ -0,0 +1,159 @@ +/* $OpenBSD: s_ctan.c,v 1.6 2013/07/03 04:46:36 espie Exp $ */ +/* + * Copyright (c) 2008 Stephen L. Moshier + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* ctan() + * + * Complex circular tangent + * + * + * + * SYNOPSIS: + * + * double complex ctan(); + * double complex z, w; + * + * w = ctan (z); + * + * + * + * DESCRIPTION: + * + * If + * z = x + iy, + * + * then + * + * sin 2x + i sinh 2y + * w = --------------------. + * cos 2x + cosh 2y + * + * On the real axis the denominator is zero at odd multiples + * of PI/2. The denominator is evaluated by its Taylor + * series near these points. + * + * ctan(z) = -i ctanh(iz). + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * DEC -10,+10 5200 7.1e-17 1.6e-17 + * IEEE -10,+10 30000 7.2e-16 1.2e-16 + * Also tested by ctan * ccot = 1 and catan(ctan(z)) = z. + */ + +#include +#include +#include + +#include "math_private.h" + +#define MACHEP 1.1e-16 +#define MAXNUM 1.0e308 + +static const double DP1 = 3.14159265160560607910E0; +static const double DP2 = 1.98418714791870343106E-9; +static const double DP3 = 1.14423774522196636802E-17; + +static double +_redupi(double x) +{ + double t; + long i; + + t = x/M_PI; + if (t >= 0.0) + t += 0.5; + else + t -= 0.5; + + i = t; /* the multiple */ + t = i; + t = ((x - t * DP1) - t * DP2) - t * DP3; + return (t); +} + +/* Taylor series expansion for cosh(2y) - cos(2x) */ + +static double +_ctans(double complex z) +{ + double f, x, x2, y, y2, rn, t; + double d; + + x = fabs (2.0 * creal (z)); + y = fabs (2.0 * cimag(z)); + + x = _redupi(x); + + x = x * x; + y = y * y; + x2 = 1.0; + y2 = 1.0; + f = 1.0; + rn = 0.0; + d = 0.0; + do { + rn += 1.0; + f *= rn; + rn += 1.0; + f *= rn; + x2 *= x; + y2 *= y; + t = y2 + x2; + t /= f; + d += t; + + rn += 1.0; + f *= rn; + rn += 1.0; + f *= rn; + x2 *= x; + y2 *= y; + t = y2 - x2; + t /= f; + d += t; + } + while (fabs(t/d) > MACHEP) + ; + return (d); +} + +double complex +ctan(double complex z) +{ + double complex w; + double d; + + d = cos (2.0 * creal (z)) + cosh (2.0 * cimag (z)); + + if (fabs(d) < 0.25) + d = _ctans (z); + + if (d == 0.0) { + /*mtherr ("ctan", OVERFLOW);*/ + w = MAXNUM + MAXNUM * I; + return (w); + } + + w = sin (2.0 * creal(z)) / d + (sinh (2.0 * cimag(z)) / d) * I; + return (w); +} + +#if LDBL_MANT_DIG == DBL_MANT_DIG +openlibm_strong_reference(ctan, ctanl); +#endif /* LDBL_MANT_DIG == DBL_MANT_DIG */ diff --git a/src/openlibm/src/s_ctanf.c b/src/openlibm/src/s_ctanf.c new file mode 100644 index 0000000..3bb3742 --- /dev/null +++ b/src/openlibm/src/s_ctanf.c @@ -0,0 +1,148 @@ +/* $OpenBSD: s_ctanf.c,v 1.2 2011/07/20 19:28:33 martynas Exp $ */ +/* + * Copyright (c) 2008 Stephen L. Moshier + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* ctanf() + * + * Complex circular tangent + * + * + * + * SYNOPSIS: + * + * void ctanf(); + * cmplxf z, w; + * + * ctanf( &z, &w ); + * + * + * + * DESCRIPTION: + * + * If + * z = x + iy, + * + * then + * + * sin 2x + i sinh 2y + * w = --------------------. + * cos 2x + cosh 2y + * + * On the real axis the denominator is zero at odd multiples + * of PI/2. The denominator is evaluated by its Taylor + * series near these points. + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE -10,+10 30000 3.3e-7 5.1e-8 + */ + +#include +#include + +#define MACHEPF 3.0e-8 +#define MAXNUMF 1.0e38f + +static const double DP1 = 3.140625; +static const double DP2 = 9.67502593994140625E-4; +static const double DP3 = 1.509957990978376432E-7; + +static float +_redupif(float xx) +{ + float x, t; + long i; + + x = xx; + t = x/(float)M_PI; + if(t >= 0.0) + t += 0.5; + else + t -= 0.5; + + i = t; /* the multiple */ + t = i; + t = ((x - t * DP1) - t * DP2) - t * DP3; + return(t); +} + +/* Taylor series expansion for cosh(2y) - cos(2x) */ + +static float +_ctansf(float complex z) +{ + float f, x, x2, y, y2, rn, t, d; + + x = fabsf(2.0f * crealf(z)); + y = fabsf(2.0f * cimagf(z)); + + x = _redupif(x); + + x = x * x; + y = y * y; + x2 = 1.0f; + y2 = 1.0f; + f = 1.0f; + rn = 0.0f; + d = 0.0f; + do { + rn += 1.0f; + f *= rn; + rn += 1.0f; + f *= rn; + x2 *= x; + y2 *= y; + t = y2 + x2; + t /= f; + d += t; + + rn += 1.0f; + f *= rn; + rn += 1.0f; + f *= rn; + x2 *= x; + y2 *= y; + t = y2 - x2; + t /= f; + d += t; + } + while (fabsf(t/d) > MACHEPF) + ; + return(d); +} + +float complex +ctanf(float complex z) +{ + float complex w; + float d; + + d = cosf( 2.0f * crealf(z) ) + coshf( 2.0f * cimagf(z) ); + + if(fabsf(d) < 0.25f) + d = _ctansf(z); + + if (d == 0.0f) { + /*mtherr( "ctanf", OVERFLOW );*/ + w = MAXNUMF + MAXNUMF * I; + return (w); + } + w = sinf (2.0f * crealf(z)) / d + (sinhf (2.0f * cimagf(z)) / d) * I; + return (w); +} diff --git a/src/openlibm/src/s_ctanh.c b/src/openlibm/src/s_ctanh.c new file mode 100644 index 0000000..8d452ee --- /dev/null +++ b/src/openlibm/src/s_ctanh.c @@ -0,0 +1,144 @@ +/*- + * Copyright (c) 2011 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Hyperbolic tangent of a complex argument z = x + i y. + * + * The algorithm is from: + * + * W. Kahan. Branch Cuts for Complex Elementary Functions or Much + * Ado About Nothing's Sign Bit. In The State of the Art in + * Numerical Analysis, pp. 165 ff. Iserles and Powell, eds., 1987. + * + * Method: + * + * Let t = tan(x) + * beta = 1/cos^2(y) + * s = sinh(x) + * rho = cosh(x) + * + * We have: + * + * tanh(z) = sinh(z) / cosh(z) + * + * sinh(x) cos(y) + i cosh(x) sin(y) + * = --------------------------------- + * cosh(x) cos(y) + i sinh(x) sin(y) + * + * cosh(x) sinh(x) / cos^2(y) + i tan(y) + * = ------------------------------------- + * 1 + sinh^2(x) / cos^2(y) + * + * beta rho s + i t + * = ---------------- + * 1 + beta s^2 + * + * Modifications: + * + * I omitted the original algorithm's handling of overflow in tan(x) after + * verifying with nearpi.c that this can't happen in IEEE single or double + * precision. I also handle large x differently. + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_ctanh.c,v 1.2 2011/10/21 06:30:16 das Exp $"); + +#include +#include + +#include "math_private.h" + +OLM_DLLEXPORT double complex +ctanh(double complex z) +{ + double x, y; + double t, beta, s, rho, denom; + u_int32_t hx, ix, lx; + + x = creal(z); + y = cimag(z); + + EXTRACT_WORDS(hx, lx, x); + ix = hx & 0x7fffffff; + + /* + * ctanh(NaN + i 0) = NaN + i 0 + * + * ctanh(NaN + i y) = NaN + i NaN for y != 0 + * + * The imaginary part has the sign of x*sin(2*y), but there's no + * special effort to get this right. + * + * ctanh(+-Inf +- i Inf) = +-1 +- 0 + * + * ctanh(+-Inf + i y) = +-1 + 0 sin(2y) for y finite + * + * The imaginary part of the sign is unspecified. This special + * case is only needed to avoid a spurious invalid exception when + * y is infinite. + */ + if (ix >= 0x7ff00000) { + if ((ix & 0xfffff) | lx) /* x is NaN */ + return (CMPLX(x, (y == 0 ? y : x * y))); + SET_HIGH_WORD(x, hx - 0x40000000); /* x = copysign(1, x) */ + return (CMPLX(x, copysign(0, isinf(y) ? y : sin(y) * cos(y)))); + } + + /* + * ctanh(x + i NAN) = NaN + i NaN + * ctanh(x +- i Inf) = NaN + i NaN + */ + if (!isfinite(y)) + return (CMPLX(y - y, y - y)); + + /* + * ctanh(+-huge + i +-y) ~= +-1 +- i 2sin(2y)/exp(2x), using the + * approximation sinh^2(huge) ~= exp(2*huge) / 4. + * We use a modified formula to avoid spurious overflow. + */ + if (ix >= 0x40360000) { /* x >= 22 */ + double exp_mx = exp(-fabs(x)); + return (CMPLX(copysign(1, x), + 4 * sin(y) * cos(y) * exp_mx * exp_mx)); + } + + /* Kahan's algorithm */ + t = tan(y); + beta = 1.0 + t * t; /* = 1 / cos^2(y) */ + s = sinh(x); + rho = sqrt(1 + s * s); /* = cosh(x) */ + denom = 1 + beta * s * s; + return (CMPLX((beta * rho * s) / denom, t / denom)); +} + +OLM_DLLEXPORT double complex +ctan(double complex z) +{ + + /* ctan(z) = -I * ctanh(I * z) */ + z = ctanh(CMPLX(-cimag(z), creal(z))); + return (CMPLX(cimag(z), -creal(z))); +} diff --git a/src/openlibm/src/s_ctanh.c.o b/src/openlibm/src/s_ctanh.c.o new file mode 100644 index 0000000000000000000000000000000000000000..7492bc4c9242cd3ee5745f1b3d5f6a08fc6cb185 GIT binary patch literal 3496 zcmb<-^>JfjWMqH=Mg}_u1P><4!0>_-!FB*M9T@l-_!vTiJ(}NWeBu}MQQ`Q+FX*Bo z@B$?JiC-W@Mc@;^fR74Cng@T~;WU1YLtq(?&RZS_Un!*VYh38O+W7SU|Nr%kfB*k~ zUtdv4{EP z85&X}U`XTFI0Z5jECte@#;mvLSs530|Ur$rVjk=lNrEi9Zrz%qRW`UWm^HeV~Dm#;?i`Uh=H*xh=H*}fKi%mXaW(=Gh9JV20W8drT$Gxa!;qYro0!g!S)7@d#*my} zP+6Rrp2rX$pIMxinU`6T%21q{m%&h6SX9E0mY7t`kXlgy5@JZsF9sXKz`!63vWo$d z57-$P82iLk&NrZ}{tM7q|gVggQshV5_40bj-!AA`5P3~pfE)?2GSN}VE6{|G?D};4I*(F zq@i&FQxB7y05xy{R6i*1f$Rar5lD>$h+tq~0F}=maZnnD3V|szbOEp^15(Kk5df9r zAT!aG6RY2l0b(X7%|c9skPc7-(fteK!)Q>00OWpj{Q)@igWL+T0Y-!BbC7-mkRTFH zfa=#r5(6g@zxx z{sU0`9WaGZ8eM+{j`U*yD)bo`7-05;(hsOSgXxE*ACQ00?FL!p0m|GA3=9uI3K$p| zKxH{7NuuiqSp#({NE;k$fE0te25=Dw18N+E!@$4*Dg&|UPXHOrz`)QBR|#RD>jwa8 CX>K6^ literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_ctanhf.c b/src/openlibm/src/s_ctanhf.c new file mode 100644 index 0000000..b2f8f19 --- /dev/null +++ b/src/openlibm/src/s_ctanhf.c @@ -0,0 +1,84 @@ +/*- + * Copyright (c) 2011 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Hyperbolic tangent of a complex argument z. See s_ctanh.c for details. + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_ctanhf.c,v 1.2 2011/10/21 06:30:16 das Exp $"); + +#include +#include + +#include "math_private.h" + +OLM_DLLEXPORT float complex +ctanhf(float complex z) +{ + float x, y; + float t, beta, s, rho, denom; + u_int32_t hx, ix; + + x = crealf(z); + y = cimagf(z); + + GET_FLOAT_WORD(hx, x); + ix = hx & 0x7fffffff; + + if (ix >= 0x7f800000) { + if (ix & 0x7fffff) + return (CMPLXF(x, (y == 0 ? y : x * y))); + SET_FLOAT_WORD(x, hx - 0x40000000); + return (CMPLXF(x, + copysignf(0, isinf(y) ? y : sinf(y) * cosf(y)))); + } + + if (!isfinite(y)) + return (CMPLXF(y - y, y - y)); + + if (ix >= 0x41300000) { /* x >= 11 */ + float exp_mx = expf(-fabsf(x)); + return (CMPLXF(copysignf(1, x), + 4 * sinf(y) * cosf(y) * exp_mx * exp_mx)); + } + + t = tanf(y); + beta = 1.0 + t * t; + s = sinhf(x); + rho = sqrtf(1 + s * s); + denom = 1 + beta * s * s; + return (CMPLXF((beta * rho * s) / denom, t / denom)); +} + +OLM_DLLEXPORT float complex +ctanf(float complex z) +{ + + z = ctanhf(CMPLXF(-cimagf(z), crealf(z))); + return (CMPLXF(cimagf(z), -crealf(z))); +} + diff --git a/src/openlibm/src/s_ctanhf.c.o b/src/openlibm/src/s_ctanhf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..58cd59763fe8c2fe4696a1df0cbcde256b9d5355 GIT binary patch literal 3576 zcmb<-^>JfjWMqH=Mg}_u1P><4z+l0JU^{@B4h;MZd<>y!9{hC&f;|qtQ1EDeW6|lN zqVt(w&_zW9ObUGFuX9n+=yXxxc>&V&nO`78h37NBfRBnm8h_p4&-{WRDk`0KKl2Ov zs3?FHD>Od+|NnnISUJDOg~q@C|JT=-Rdn81`Tu`CLy37B|N8^{dKapgN;uN^^Im`E zkGz`3p9eC@MMdH>$UGUaIT9YtM=YXa5A(}6Kx`ItQQ_&G&A`BL0BknIDXj1E2W?V?ZGh!3vTG%RqwVGrs^>LLfv%gkR$!$fVEwk&i#~ zN1lez5vm{^pZVj?eCCh4!mn}gCBy&!|6%Th*eVzT4RHQ&g!yUwd8c8{6F>+<0s<5p z{2GVA0SIyEXZ}dABCxywSR)U=2E?Oar-I@!Mg_^QU>Ba|*SPpH@8AFbY5ejo;GjV< zQy@eI(=2eBh`jK!>>tP@(D;hE#IJGar3%QTG(DL2CV-QhNAnvGP>KUP3Y6w-z$_kc z#Dn-8hydk)1*o8l3JW+MOu%7p09I@OQy2o06p)1kt)PpF4uAM%u){UL>NLRWz?Orp zQh-~})9Iq30#>8Y>7oL+I0Y2B0zN7nVC5i-Q^3j7M+KTZ!3KiEmgO@)#A5z%P%?%E zkO;Y76t|e1qKENP!zlSg)%TPFdhJj!SX&Ml+OvZNCZkVRs}II zRtPXk^RRPFU}Rv>U|?X7fy$*YF)%PV@(Hvtx$#LfGkfp_F!gisNjUNeIP!6La5G3S zFfe#P)qVrfo_qmJZ}>PsOk5b`9u|g=|FOw4V=1Y4zzW&GBr+ig=74+)X21zCFpCWw z9$+SvkY-?D5JEB^>^BAm1|NIgH2`bAK2kb00D%--ctagZ1&y~D(JLd8Mqk=?%!Dh^VQ96r~O#6fuwX3jmR zILI7Ou7rtyf{KI85khjO7Dyp9Jdw?@LlQ?;KLbe|Ierf!i6f_n^H6aR1+p9Fo|hm2 zsJ)<41tu;C@;p==*?cP`ab)v7pyD9okj)2`!Js4r5(i-r8-#s81Oo#DNDPEw`H4ZV zxH7jSF^NI1xTFX|XTVrRsX2*yC8-r940 z6v*G8s0M{8vN4dhB?ChmG`wJPpfm_$gJ@9s3<^h>dXN|hKY$vz02F8p3=E*W2eJng zM<97n9R#A)7#P5%JDN2N%g_ZtilJ(uOfaRxz`y`96J0s6`VFCGg3>J5Kq#>RY9P9Q zVSE^Ek3;_fsD6;!phkizP*{N&FdCG;K;Z(apFrX;d;+RpA0_~$L25xv7!9glU~G^$ z41b5}hw))Fx>`^Y0_6{AG{KZH{DA65cNe;UYN7r|*RKKfU;^Ak2m@Vz1vKxXr=JE; zq0hj;0J9&Ien90JOg}9Bfc%4QH^`3K$p|KxH{7NuuiqSp)SdNE;kyfD|(@ jFqFYXAPlH+5Do(a1E>tdrhfy-U + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* ctanhl + * + * Complex hyperbolic tangent + * + * + * + * SYNOPSIS: + * + * long double complex ctanhl(); + * long double complex z, w; + * + * w = ctanhl (z); + * + * + * + * DESCRIPTION: + * + * tanh z = (sinh 2x + i sin 2y) / (cosh 2x + cos 2y) . + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE -10,+10 30000 1.7e-14 2.4e-16 + * + */ + +#include +#include + +long double complex +ctanhl(long double complex z) +{ + long double complex w; + long double x, y, d; + + x = creall(z); + y = cimagl(z); + d = coshl(2.0L * x) + cosl(2.0L * y); + w = sinhl(2.0L * x) / d + (sinl(2.0L * y) / d) * I; + return (w); +} diff --git a/src/openlibm/src/s_ctanhl.c.o b/src/openlibm/src/s_ctanhl.c.o new file mode 100644 index 0000000000000000000000000000000000000000..2a78c8cdb87a4763844bf9391b80a7ebeee20a3b GIT binary patch literal 1848 zcmb<-^>JfjWMqH=Mg}_u1P><4!0>|^!FB*M9T<2Sco;mI-&p)FQHemtFF^9QYg80G znvW zI4ELZ>SrN|b0Vn+r6G_M69WSS2!q&QtXEu_TauW>pjTW{1fervtfJJMM7@&KiV_CB zl*E!m2EC->Vg|kB{M_8syb=bzy!?_>J$JuQ-QtqO + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* ctanl() + * + * Complex circular tangent + * + * + * + * SYNOPSIS: + * + * long double complex ctanl(); + * long double complex z, w; + * + * w = ctanl( z ); + * + * + * + * DESCRIPTION: + * + * If + * z = x + iy, + * + * then + * + * sin 2x + i sinh 2y + * w = --------------------. + * cos 2x + cosh 2y + * + * On the real axis the denominator is zero at odd multiples + * of PI/2. The denominator is evaluated by its Taylor + * series near these points. + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * DEC -10,+10 5200 7.1e-17 1.6e-17 + * IEEE -10,+10 30000 7.2e-16 1.2e-16 + * Also tested by ctan * ccot = 1 and catan(ctan(z)) = z. + */ + +#include +#include +#include + +#if LDBL_MANT_DIG == 64 +static const long double MACHEPL= 5.42101086242752217003726400434970855712890625E-20L; +#elif LDBL_MANT_DIG == 113 +static const long double MACHEPL = 9.629649721936179265279889712924636592690508e-35L; +#endif + +static const long double PIL = 3.141592653589793238462643383279502884197169L; +static const long double DP1 = 3.14159265358979323829596852490908531763125L; +static const long double DP2 = 1.6667485837041756656403424829301998703007e-19L; +static const long double DP3 = 1.8830410776607851167459095484560349402753e-39L; + +static long double +redupil(long double x) +{ + long double t; + long i; + + t = x / PIL; + if (t >= 0.0L) + t += 0.5L; + else + t -= 0.5L; + + i = t; /* the multiple */ + t = i; + t = ((x - t * DP1) - t * DP2) - t * DP3; + return (t); +} + +static long double +ctansl(long double complex z) +{ + long double f, x, x2, y, y2, rn, t; + long double d; + + x = fabsl(2.0L * creall(z)); + y = fabsl(2.0L * cimagl(z)); + + x = redupil(x); + + x = x * x; + y = y * y; + x2 = 1.0L; + y2 = 1.0L; + f = 1.0L; + rn = 0.0L; + d = 0.0L; + do { + rn += 1.0L; + f *= rn; + rn += 1.0L; + f *= rn; + x2 *= x; + y2 *= y; + t = y2 + x2; + t /= f; + d += t; + + rn += 1.0L; + f *= rn; + rn += 1.0L; + f *= rn; + x2 *= x; + y2 *= y; + t = y2 - x2; + t /= f; + d += t; + } + while (fabsl(t/d) > MACHEPL); + return(d); +} + +long double complex +ctanl(long double complex z) +{ + long double complex w; + long double d, x, y; + + x = creall(z); + y = cimagl(z); + d = cosl(2.0L * x) + coshl(2.0L * y); + + if (fabsl(d) < 0.25L) { + d = fabsl(d); + d = ctansl(z); + } + if (d == 0.0L) { + /*mtherr( "ctan", OVERFLOW );*/ + w = LDBL_MAX + LDBL_MAX * I; + return (w); + } + + w = sinl(2.0L * x) / d + (sinhl(2.0L * y) / d) * I; + return (w); +} diff --git a/src/openlibm/src/s_ctanl.c.o b/src/openlibm/src/s_ctanl.c.o new file mode 100644 index 0000000000000000000000000000000000000000..7767d88daa1b4b120edb246b80a0c2e0ad93bd03 GIT binary patch literal 3352 zcmb<-^>JfjWMqH=Mg}_u1P><4z!1TSU^{@B4h;MZd<-6qZ&olcF#O-5asn6i0;K$Q zjf#Rt^AQDN6dK&lQBk;Y;O2qbdsHScFfhbBM%=bhff*x!ChO7sMgT6IqoUv#=@@nI z;LQWKZB%a8s0e_y-DCy1!7)1G{>QsFZtJM-z34vz;N^A4RF}p+@ms&fq{X4dkdIuIKz|H*`hKB6iREr)O{P3 zn`^*w_jObtVRhr=y;tb0dnfO`ym8{TjmnJ^AXnaeck{r_7dH>wJb3fa&9kq0C)_-F z^VH4LH_zTYbMw@VgP>5jbLz&yJEuUdyLS#0T=&l0JbL5EjnDUvg2e9~ymRt)jYLNym;Hu!qQBFr2TcWWl+l4$5a>Xs}~oV6bOkXpm=c zcXqZ?&~Wz))l@Jv(KFIBR4_6yGBq$XG*Hk8N=;GlNGyR$=$dOn%wu6-U{GLSU;ss$ zyI&{+69eM`kQgk_GD7*x5akRaP@1tSh=H*}fKi%u1_l|Z+*2k71_pP& z4UF!5I~d*h4lug&onUn5yTIs+MJ$r<1fvt*0mgW~3ygkHb_CxJMn}F4j2T>f9G=`> zP*b9yri6k_;o{@);&$OXz!(S>b?3Xm=+5_m(Ub20V<;A}K&Y8allTrWGDSjpP#0rT zApf&4d_;~axFTjOB^ozamJLiI69QlkD0IOLI3WsVu`z(c8q9bETG+5&hcfuj= zjzioRhj=g!@kkuv48`%uC5d@CddUoWKF-DhZ!A&Dc0!xAKMWc5d&;vn~faskYp zKaj*hxdtZA1X2j~FFTU^d62|GX&R<}8dMw<4#@V-gNlPFP*Ve@{tie0YCf`iKxH5( zNI}vd3}S<^UU6k^Nn#R%UU5kggwBAmic)hD^-5AJN*MG~5=#;p^pc8;8T5+sK^(p0 z;u1qMWS$9wUUGhJZfaf$gI->KNvfW^U#MiU^SZKtT=)Yh;6<)eHly9DvDz(iDshqNSl}3Z@<;2EqrR2EyVKlqNv- zfZ_-wF99ML7#P$T7{H|tC~ZT9z?3Sw09X{F7Rm%uIt&cpvJ720vHA_6_6vbcLl6c~ z1JV5j^FNFRRkt92q3bVz>IeB7VJf6N0P#WT5=8qz?ME-CYoPk|L5h$t$Sx2UMu$T6 zgT#>WYN&o>F%TQ355xvxP!a;=CzQ0!z`(Epsvq55u=oS%1>st#{pk81K=oe$DMG^N z`YUjxpB+$zuyg_nM=oewgN%cTgZzVTH%NX1G=MjN6fiI_fXZNO`axv?)TtnCaGU^5 gzj1I82m@*ygu}qV04htd>AwJVe>+?ygn_Of07av_m;e9( literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_erf.c b/src/openlibm/src/s_erf.c new file mode 100644 index 0000000..67068c4 --- /dev/null +++ b/src/openlibm/src/s_erf.c @@ -0,0 +1,307 @@ +/* @(#)s_erf.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_erf.c,v 1.8 2008/02/22 02:30:35 das Exp $"); + +/* double erf(double x) + * double erfc(double x) + * x + * 2 |\ + * erf(x) = --------- | exp(-t*t)dt + * sqrt(pi) \| + * 0 + * + * erfc(x) = 1-erf(x) + * Note that + * erf(-x) = -erf(x) + * erfc(-x) = 2 - erfc(x) + * + * Method: + * 1. For |x| in [0, 0.84375] + * erf(x) = x + x*R(x^2) + * erfc(x) = 1 - erf(x) if x in [-.84375,0.25] + * = 0.5 + ((0.5-x)-x*R) if x in [0.25,0.84375] + * where R = P/Q where P is an odd poly of degree 8 and + * Q is an odd poly of degree 10. + * -57.90 + * | R - (erf(x)-x)/x | <= 2 + * + * + * Remark. The formula is derived by noting + * erf(x) = (2/sqrt(pi))*(x - x^3/3 + x^5/10 - x^7/42 + ....) + * and that + * 2/sqrt(pi) = 1.128379167095512573896158903121545171688 + * is close to one. The interval is chosen because the fix + * point of erf(x) is near 0.6174 (i.e., erf(x)=x when x is + * near 0.6174), and by some experiment, 0.84375 is chosen to + * guarantee the error is less than one ulp for erf. + * + * 2. For |x| in [0.84375,1.25], let s = |x| - 1, and + * c = 0.84506291151 rounded to single (24 bits) + * erf(x) = sign(x) * (c + P1(s)/Q1(s)) + * erfc(x) = (1-c) - P1(s)/Q1(s) if x > 0 + * 1+(c+P1(s)/Q1(s)) if x < 0 + * |P1/Q1 - (erf(|x|)-c)| <= 2**-59.06 + * Remark: here we use the taylor series expansion at x=1. + * erf(1+s) = erf(1) + s*Poly(s) + * = 0.845.. + P1(s)/Q1(s) + * That is, we use rational approximation to approximate + * erf(1+s) - (c = (single)0.84506291151) + * Note that |P1/Q1|< 0.078 for x in [0.84375,1.25] + * where + * P1(s) = degree 6 poly in s + * Q1(s) = degree 6 poly in s + * + * 3. For x in [1.25,1/0.35(~2.857143)], + * erfc(x) = (1/x)*exp(-x*x-0.5625+R1/S1) + * erf(x) = 1 - erfc(x) + * where + * R1(z) = degree 7 poly in z, (z=1/x^2) + * S1(z) = degree 8 poly in z + * + * 4. For x in [1/0.35,28] + * erfc(x) = (1/x)*exp(-x*x-0.5625+R2/S2) if x > 0 + * = 2.0 - (1/x)*exp(-x*x-0.5625+R2/S2) if -6 x >= 28 + * erf(x) = sign(x) *(1 - tiny) (raise inexact) + * erfc(x) = tiny*tiny (raise underflow) if x > 0 + * = 2 - tiny if x<0 + * + * 7. Special case: + * erf(0) = 0, erf(inf) = 1, erf(-inf) = -1, + * erfc(0) = 1, erfc(inf) = 0, erfc(-inf) = 2, + * erfc/erf(NaN) is NaN + */ + +#include +#include + +#include "math_private.h" + +static const double +tiny = 1e-300, +half= 5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */ +one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */ +two = 2.00000000000000000000e+00, /* 0x40000000, 0x00000000 */ + /* c = (float)0.84506291151 */ +erx = 8.45062911510467529297e-01, /* 0x3FEB0AC1, 0x60000000 */ +/* + * Coefficients for approximation to erf on [0,0.84375] + */ +efx = 1.28379167095512586316e-01, /* 0x3FC06EBA, 0x8214DB69 */ +efx8= 1.02703333676410069053e+00, /* 0x3FF06EBA, 0x8214DB69 */ +pp0 = 1.28379167095512558561e-01, /* 0x3FC06EBA, 0x8214DB68 */ +pp1 = -3.25042107247001499370e-01, /* 0xBFD4CD7D, 0x691CB913 */ +pp2 = -2.84817495755985104766e-02, /* 0xBF9D2A51, 0xDBD7194F */ +pp3 = -5.77027029648944159157e-03, /* 0xBF77A291, 0x236668E4 */ +pp4 = -2.37630166566501626084e-05, /* 0xBEF8EAD6, 0x120016AC */ +qq1 = 3.97917223959155352819e-01, /* 0x3FD97779, 0xCDDADC09 */ +qq2 = 6.50222499887672944485e-02, /* 0x3FB0A54C, 0x5536CEBA */ +qq3 = 5.08130628187576562776e-03, /* 0x3F74D022, 0xC4D36B0F */ +qq4 = 1.32494738004321644526e-04, /* 0x3F215DC9, 0x221C1A10 */ +qq5 = -3.96022827877536812320e-06, /* 0xBED09C43, 0x42A26120 */ +/* + * Coefficients for approximation to erf in [0.84375,1.25] + */ +pa0 = -2.36211856075265944077e-03, /* 0xBF6359B8, 0xBEF77538 */ +pa1 = 4.14856118683748331666e-01, /* 0x3FDA8D00, 0xAD92B34D */ +pa2 = -3.72207876035701323847e-01, /* 0xBFD7D240, 0xFBB8C3F1 */ +pa3 = 3.18346619901161753674e-01, /* 0x3FD45FCA, 0x805120E4 */ +pa4 = -1.10894694282396677476e-01, /* 0xBFBC6398, 0x3D3E28EC */ +pa5 = 3.54783043256182359371e-02, /* 0x3FA22A36, 0x599795EB */ +pa6 = -2.16637559486879084300e-03, /* 0xBF61BF38, 0x0A96073F */ +qa1 = 1.06420880400844228286e-01, /* 0x3FBB3E66, 0x18EEE323 */ +qa2 = 5.40397917702171048937e-01, /* 0x3FE14AF0, 0x92EB6F33 */ +qa3 = 7.18286544141962662868e-02, /* 0x3FB2635C, 0xD99FE9A7 */ +qa4 = 1.26171219808761642112e-01, /* 0x3FC02660, 0xE763351F */ +qa5 = 1.36370839120290507362e-02, /* 0x3F8BEDC2, 0x6B51DD1C */ +qa6 = 1.19844998467991074170e-02, /* 0x3F888B54, 0x5735151D */ +/* + * Coefficients for approximation to erfc in [1.25,1/0.35] + */ +ra0 = -9.86494403484714822705e-03, /* 0xBF843412, 0x600D6435 */ +ra1 = -6.93858572707181764372e-01, /* 0xBFE63416, 0xE4BA7360 */ +ra2 = -1.05586262253232909814e+01, /* 0xC0251E04, 0x41B0E726 */ +ra3 = -6.23753324503260060396e+01, /* 0xC04F300A, 0xE4CBA38D */ +ra4 = -1.62396669462573470355e+02, /* 0xC0644CB1, 0x84282266 */ +ra5 = -1.84605092906711035994e+02, /* 0xC067135C, 0xEBCCABB2 */ +ra6 = -8.12874355063065934246e+01, /* 0xC0545265, 0x57E4D2F2 */ +ra7 = -9.81432934416914548592e+00, /* 0xC023A0EF, 0xC69AC25C */ +sa1 = 1.96512716674392571292e+01, /* 0x4033A6B9, 0xBD707687 */ +sa2 = 1.37657754143519042600e+02, /* 0x4061350C, 0x526AE721 */ +sa3 = 4.34565877475229228821e+02, /* 0x407B290D, 0xD58A1A71 */ +sa4 = 6.45387271733267880336e+02, /* 0x40842B19, 0x21EC2868 */ +sa5 = 4.29008140027567833386e+02, /* 0x407AD021, 0x57700314 */ +sa6 = 1.08635005541779435134e+02, /* 0x405B28A3, 0xEE48AE2C */ +sa7 = 6.57024977031928170135e+00, /* 0x401A47EF, 0x8E484A93 */ +sa8 = -6.04244152148580987438e-02, /* 0xBFAEEFF2, 0xEE749A62 */ +/* + * Coefficients for approximation to erfc in [1/.35,28] + */ +rb0 = -9.86494292470009928597e-03, /* 0xBF843412, 0x39E86F4A */ +rb1 = -7.99283237680523006574e-01, /* 0xBFE993BA, 0x70C285DE */ +rb2 = -1.77579549177547519889e+01, /* 0xC031C209, 0x555F995A */ +rb3 = -1.60636384855821916062e+02, /* 0xC064145D, 0x43C5ED98 */ +rb4 = -6.37566443368389627722e+02, /* 0xC083EC88, 0x1375F228 */ +rb5 = -1.02509513161107724954e+03, /* 0xC0900461, 0x6A2E5992 */ +rb6 = -4.83519191608651397019e+02, /* 0xC07E384E, 0x9BDC383F */ +sb1 = 3.03380607434824582924e+01, /* 0x403E568B, 0x261D5190 */ +sb2 = 3.25792512996573918826e+02, /* 0x40745CAE, 0x221B9F0A */ +sb3 = 1.53672958608443695994e+03, /* 0x409802EB, 0x189D5118 */ +sb4 = 3.19985821950859553908e+03, /* 0x40A8FFB7, 0x688C246A */ +sb5 = 2.55305040643316442583e+03, /* 0x40A3F219, 0xCEDF3BE6 */ +sb6 = 4.74528541206955367215e+02, /* 0x407DA874, 0xE79FE763 */ +sb7 = -2.24409524465858183362e+01; /* 0xC03670E2, 0x42712D62 */ + +OLM_DLLEXPORT double +erf(double x) +{ + int32_t hx,ix,i; + double R,S,P,Q,s,y,z,r; + GET_HIGH_WORD(hx,x); + ix = hx&0x7fffffff; + if(ix>=0x7ff00000) { /* erf(nan)=nan */ + i = ((u_int32_t)hx>>31)<<1; + return (double)(1-i)+one/x; /* erf(+-inf)=+-1 */ + } + + if(ix < 0x3feb0000) { /* |x|<0.84375 */ + if(ix < 0x3e300000) { /* |x|<2**-28 */ + if (ix < 0x00800000) + return 0.125*(8.0*x+efx8*x); /*avoid underflow */ + return x + efx*x; + } + z = x*x; + r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4))); + s = one+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5)))); + y = r/s; + return x + x*y; + } + if(ix < 0x3ff40000) { /* 0.84375 <= |x| < 1.25 */ + s = fabs(x)-one; + P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6))))); + Q = one+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6))))); + if(hx>=0) return erx + P/Q; else return -erx - P/Q; + } + if (ix >= 0x40180000) { /* inf>|x|>=6 */ + if(hx>=0) return one-tiny; else return tiny-one; + } + x = fabs(x); + s = one/(x*x); + if(ix< 0x4006DB6E) { /* |x| < 1/0.35 */ + R=ra0+s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*( + ra5+s*(ra6+s*ra7)))))); + S=one+s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*( + sa5+s*(sa6+s*(sa7+s*sa8))))))); + } else { /* |x| >= 1/0.35 */ + R=rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*( + rb5+s*rb6))))); + S=one+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*( + sb5+s*(sb6+s*sb7)))))); + } + z = x; + SET_LOW_WORD(z,0); + r = __ieee754_exp(-z*z-0.5625)*__ieee754_exp((z-x)*(z+x)+R/S); + if(hx>=0) return one-r/x; else return r/x-one; +} + +OLM_DLLEXPORT double +erfc(double x) +{ + int32_t hx,ix; + double R,S,P,Q,s,y,z,r; + GET_HIGH_WORD(hx,x); + ix = hx&0x7fffffff; + if(ix>=0x7ff00000) { /* erfc(nan)=nan */ + /* erfc(+-inf)=0,2 */ + return (double)(((u_int32_t)hx>>31)<<1)+one/x; + } + + if(ix < 0x3feb0000) { /* |x|<0.84375 */ + if(ix < 0x3c700000) /* |x|<2**-56 */ + return one-x; + z = x*x; + r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4))); + s = one+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5)))); + y = r/s; + if(hx < 0x3fd00000) { /* x<1/4 */ + return one-(x+x*y); + } else { + r = x*y; + r += (x-half); + return half - r ; + } + } + if(ix < 0x3ff40000) { /* 0.84375 <= |x| < 1.25 */ + s = fabs(x)-one; + P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6))))); + Q = one+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6))))); + if(hx>=0) { + z = one-erx; return z - P/Q; + } else { + z = erx+P/Q; return one+z; + } + } + if (ix < 0x403c0000) { /* |x|<28 */ + x = fabs(x); + s = one/(x*x); + if(ix< 0x4006DB6D) { /* |x| < 1/.35 ~ 2.857143*/ + R=ra0+s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*( + ra5+s*(ra6+s*ra7)))))); + S=one+s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*( + sa5+s*(sa6+s*(sa7+s*sa8))))))); + } else { /* |x| >= 1/.35 ~ 2.857143 */ + if(hx<0&&ix>=0x40180000) return two-tiny;/* x < -6 */ + R=rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*( + rb5+s*rb6))))); + S=one+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*( + sb5+s*(sb6+s*sb7)))))); + } + z = x; + SET_LOW_WORD(z,0); + r = __ieee754_exp(-z*z-0.5625)* + __ieee754_exp((z-x)*(z+x)+R/S); + if(hx>0) return r/x; else return two-r/x; + } else { + if(hx>0) return tiny*tiny; else return two-tiny; + } +} + +#if (LDBL_MANT_DIG == 53) +openlibm_weak_reference(erf, erfl); +openlibm_weak_reference(erfc, erfcl); +#endif diff --git a/src/openlibm/src/s_erf.c.o b/src/openlibm/src/s_erf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..648dc272f86fbc5da4ef67a3a02e1094a9fbdef5 GIT binary patch literal 10160 zcmb<-^>JfjWMqH=Mg}_u1P><4!0 z;wSz{UI-m=5GLl)d_*HU_HddWzkCZwjsaxIXM6s(DNGDtwzxxC$|rsSumP>ND@Cd6dSlaRj6f zWa8OR{Bb@i5}@FPYL8@50qX`?bK(v{2l4wu!KbJC;pg&FN6O5{||}RG=7a6 zpZFnh`-wji#0IR6}&F}ENNgBy7I6F)pk4}aoE7Kf)9G;vDQN1pz~4>LF7&?o-56QHnu494U%D890dzx^u%q!@Z-&)TfT z_#c z_5!G&6#xYcQbBtNR)oQd7H|jNsLK}j+0V(V@Ge(!%MIpYv0>Ap1k_y7L{jQE4ZTNQG zF~~-e&!%N+gVr@5$AQXtP|AA=$~lPYCE~)%kU#(bgGwhj{$LMbe%KG86&x~ei!|-Z zgNYxohwu;BuMuMqy7ubFz9$)J$`cor+xtsiza6MG*Isz1OlIxbEA|;+eFy9n5*Il+ z&$+NqKuSjGWUQh+fA-}gN*7A(cbzi}^;x>Xp7YMFvz6sH?d{p8aart7-2Zy&^hh(U zMfPtr>}+Qw@3DWP5ZG`k{)+v_!#jRET)J-WyLr-DhTdED7Ny_!?TAdamlZV)59#i( zm$@65eduksy}W7i^8~d6_RC++zZsLf$=*2s^`sA85ABs7zmrI_+YRzx!a=UrFnWK? zp;^b?FHk=4>C%(%)SwWDO{>qmjuB3GNK?{i+31tv(7X8b6D|XP2es!L99iU49TJLn zJrOf`W^bCpn;>M;VxKgt-JCf^5}c-F6E%J&g0!;jc5lE=7Mm=3snvo8gCRO zwObqtrMj;2YF0ZaKF%6FDux)bD6P&y~Ul`ein5HCPnIHC9+I#(D+m;-0`N_ zVaD5|&aomX4pB4XLpcu_I^1hLRIqFEOM9>U7nWdqbqk#y6__1Jem?(s$%!a&jmecyqM13A&w~YAcVn8R&ZE@nNR|vj+KD}%7;EJ{6SstlgW?p-gc6X1#>y}QO}#5v zo|Rz%nz%Pqdkyhn3+4n)-IAcm$Y65TFh-D0dkkgutvxV3L&~0Zb!^8DJ(W zg9VsI5OcvyR)!2PjUX0-nXC-Zf&t6}5i39h11ke8|A4s+3=HeQ3|0mYFpVHKgPE)h z6<``c>;yAe!TB4^gc6Vnhm`?Q@IWMvf+<#p9bg(koCY&l84iGH1aT3}WM$|8(+J`^ zn90g;0!$-_yI>|O!vrvmAVA$AP&i*e2!UBI!6YjKBwWE9F!3HtvNGHN(+C38K>(Sv z03ifs{RWe)3=hCGf`AOgurffx8zIgPP9Llc8xTTZ7B5sB+ztbaKnP)|_zwsdPD(<> z(TgB?s5l3hhAU@K1@l=M1i&;xTpP@1Wsm^V2ysI&pOrxYOe4h2!F*N*4KR%mw*~WA z84SQQLfje5XJxPe(+F`-FrSsd0Zb#r{lR=z1`jZe5Dx|OSs4PrG(tQY%x7hY0MiKZ zL@=L~ApuMy#M8liR)!2PjS$ZT^H~`Rz%)X<7|ds7_<#@svnrwDKfp9t2u#$2`K$~d zz%*D0OtgaetPBiHU@n~KW@KOxLW)Fi9m&AJ(9g(#QHOvuO~D}!Dt|%dJOI^)3=9n5 zdJ&|dI6k!~O)r^2&&SyaL>Pkz6A)ntA`C!;DTpvJ2a^_H(h@|PLL|ZJOu?E>!MaVs z+D*Z_OwGV5!Fo->dQHK4&A@uizSpCSbiLV7(?_y(VD2CJ?<~m1bZOGq4&nGltZnG={Xq zq+*8DiUJS^TvfS);)nr~ESMP>82*69>;C`$?~f!7ic*+(G?F-|Z3YvEm6M?41*)B3 z;!}{+vm=?m1c&$)BymvN17;4Syo9t1-H^=ri=-aed`S5O@fWB~1T#kwoDU%4TuA2V zB8h{VV=(oWNa8$5>Rpkb* zX9gt@21q=D(jH9Q35R$pR2)Ph+uHyVfTmkXBzt?1#HEnLXCR47BZ)6T5(o7YVD8y~ zBo1ox!o>F=iOV6Ga{@_R9!dNPk~pY812g9VlDHz0`Zq}8pf)v3{SPE@ zBIgT9s5nR)vU)`%anMu@%zRxWaTO%@*dmFmB8htab)$%pvnvy{>bHtHj+4Ud18$uj$EF&BZ(uIC&5VK z$mK~qk~ngCl8q#eT%MF8i6fUM%}CS((C~3W3QtF< zI4D?=%O6juIC}Zhgd~n!FZUsdBiGBbki?Pe}yj(#NM~N>aapZdH1Cls$J@p4k9J!w20A*Tex<#(1 zM3BUh>nQ~!apZbR2T2^cp0Yp^N3N$_k;IYfsX!!g&M=!a!!~&TE>eeRb=jNv7 zl`!b#<(H)Dx%-9c7MCO@XG8hvd8K*V5_40bj-!AA`5V+l zfEJH%lR#kx;v9sA7l;kQpfVUl!!W4M1(jhi^)T@rphA;@fuR9Z_%kptfa(U2J<#L~ zAO8lG5g>7Ba}1`Pfe}>sz24chXgV-PpN + +#include "math_private.h" + +static const float +tiny = 1e-30, +half= 5.0000000000e-01, /* 0x3F000000 */ +one = 1.0000000000e+00, /* 0x3F800000 */ +two = 2.0000000000e+00, /* 0x40000000 */ +/* + * Coefficients for approximation to erf on [0,0.84375] + */ +efx = 1.2837916613e-01, /* 0x3e0375d4 */ +efx8= 1.0270333290e+00, /* 0x3f8375d4 */ +/* + * Domain [0, 0.84375], range ~[-5.4446e-10,5.5197e-10]: + * |(erf(x) - x)/x - p(x)/q(x)| < 2**-31. + */ +pp0 = 1.28379166e-01F, /* 0x1.06eba8p-3 */ +pp1 = -3.36030394e-01F, /* -0x1.58185ap-2 */ +pp2 = -1.86260219e-03F, /* -0x1.e8451ep-10 */ +qq1 = 3.12324286e-01F, /* 0x1.3fd1f0p-2 */ +qq2 = 2.16070302e-02F, /* 0x1.620274p-6 */ +qq3 = -1.98859419e-03F, /* -0x1.04a626p-9 */ +/* + * Domain [0.84375, 1.25], range ~[-1.953e-11,1.940e-11]: + * |(erf(x) - erx) - p(x)/q(x)| < 2**-36. + */ +erx = 8.42697144e-01F, /* 0x1.af7600p-1. erf(1) rounded to 16 bits. */ +pa0 = 3.64939137e-06F, /* 0x1.e9d022p-19 */ +pa1 = 4.15109694e-01F, /* 0x1.a91284p-2 */ +pa2 = -1.65179938e-01F, /* -0x1.5249dcp-3 */ +pa3 = 1.10914491e-01F, /* 0x1.c64e46p-4 */ +qa1 = 6.02074385e-01F, /* 0x1.344318p-1 */ +qa2 = 5.35934687e-01F, /* 0x1.126608p-1 */ +qa3 = 1.68576106e-01F, /* 0x1.593e6ep-3 */ +qa4 = 5.62181212e-02F, /* 0x1.cc89f2p-5 */ +/* + * Domain [1.25,1/0.35], range ~[-7.043e-10,7.457e-10]: + * |log(x*erfc(x)) + x**2 + 0.5625 - r(x)/s(x)| < 2**-30 + */ +ra0 = -9.87132732e-03F, /* -0x1.4376b2p-7 */ +ra1 = -5.53605914e-01F, /* -0x1.1b723cp-1 */ +ra2 = -2.17589188e+00F, /* -0x1.1683a0p+1 */ +ra3 = -1.43268085e+00F, /* -0x1.6ec42cp+0 */ +sa1 = 5.45995426e+00F, /* 0x1.5d6fe4p+2 */ +sa2 = 6.69798088e+00F, /* 0x1.acabb8p+2 */ +sa3 = 1.43113089e+00F, /* 0x1.6e5e98p+0 */ +sa4 = -5.77397496e-02F, /* -0x1.d90108p-5 */ +/* + * Domain [1/0.35, 11], range ~[-2.264e-13,2.336e-13]: + * |log(x*erfc(x)) + x**2 + 0.5625 - r(x)/s(x)| < 2**-42 + */ +rb0 = -9.86494310e-03F, /* -0x1.434124p-7 */ +rb1 = -6.25171244e-01F, /* -0x1.401672p-1 */ +rb2 = -6.16498327e+00F, /* -0x1.8a8f16p+2 */ +rb3 = -1.66696873e+01F, /* -0x1.0ab70ap+4 */ +rb4 = -9.53764343e+00F, /* -0x1.313460p+3 */ +sb1 = 1.26884899e+01F, /* 0x1.96081cp+3 */ +sb2 = 4.51839523e+01F, /* 0x1.6978bcp+5 */ +sb3 = 4.72810211e+01F, /* 0x1.7a3f88p+5 */ +sb4 = 8.93033314e+00F; /* 0x1.1dc54ap+3 */ + + +OLM_DLLEXPORT float +erff(float x) +{ + int32_t hx,ix,i; + float R,S,P,Q,s,y,z,r; + GET_FLOAT_WORD(hx,x); + ix = hx&0x7fffffff; + if(ix>=0x7f800000) { /* erf(nan)=nan */ + i = ((u_int32_t)hx>>31)<<1; + return (float)(1-i)+one/x; /* erf(+-inf)=+-1 */ + } + + if(ix < 0x3f580000) { /* |x|<0.84375 */ + if(ix < 0x38800000) { /* |x|<2**-14 */ + if (ix < 0x04000000) /* |x|<0x1p-119 */ + return (8*x+efx8*x)/8; /* avoid spurious underflow */ + return x + efx*x; + } + z = x*x; + r = pp0+z*(pp1+z*pp2); + s = one+z*(qq1+z*(qq2+z*qq3)); + y = r/s; + return x + x*y; + } + if(ix < 0x3fa00000) { /* 0.84375 <= |x| < 1.25 */ + s = fabsf(x)-one; + P = pa0+s*(pa1+s*(pa2+s*pa3)); + Q = one+s*(qa1+s*(qa2+s*(qa3+s*qa4))); + if(hx>=0) return erx + P/Q; else return -erx - P/Q; + } + if (ix >= 0x40800000) { /* inf>|x|>=4 */ + if(hx>=0) return one-tiny; else return tiny-one; + } + x = fabsf(x); + s = one/(x*x); + if(ix< 0x4036DB6E) { /* |x| < 1/0.35 */ + R=ra0+s*(ra1+s*(ra2+s*ra3)); + S=one+s*(sa1+s*(sa2+s*(sa3+s*sa4))); + } else { /* |x| >= 1/0.35 */ + R=rb0+s*(rb1+s*(rb2+s*(rb3+s*rb4))); + S=one+s*(sb1+s*(sb2+s*(sb3+s*sb4))); + } + SET_FLOAT_WORD(z,hx&0xffffe000); + r = expf(-z*z-0.5625F)*expf((z-x)*(z+x)+R/S); + if(hx>=0) return one-r/x; else return r/x-one; +} + +OLM_DLLEXPORT float +erfcf(float x) +{ + int32_t hx,ix; + float R,S,P,Q,s,y,z,r; + GET_FLOAT_WORD(hx,x); + ix = hx&0x7fffffff; + if(ix>=0x7f800000) { /* erfc(nan)=nan */ + /* erfc(+-inf)=0,2 */ + return (float)(((u_int32_t)hx>>31)<<1)+one/x; + } + + if(ix < 0x3f580000) { /* |x|<0.84375 */ + if(ix < 0x33800000) /* |x|<2**-56 */ + return one-x; + z = x*x; + r = pp0+z*(pp1+z*pp2); + s = one+z*(qq1+z*(qq2+z*qq3)); + y = r/s; + if(hx < 0x3e800000) { /* x<1/4 */ + return one-(x+x*y); + } else { + r = x*y; + r += (x-half); + return half - r ; + } + } + if(ix < 0x3fa00000) { /* 0.84375 <= |x| < 1.25 */ + s = fabsf(x)-one; + P = pa0+s*(pa1+s*(pa2+s*pa3)); + Q = one+s*(qa1+s*(qa2+s*(qa3+s*qa4))); + if(hx>=0) { + z = one-erx; return z - P/Q; + } else { + z = erx+P/Q; return one+z; + } + } + if (ix < 0x41300000) { /* |x|<28 */ + x = fabsf(x); + s = one/(x*x); + if(ix< 0x4036DB6D) { /* |x| < 1/.35 ~ 2.857143*/ + R=ra0+s*(ra1+s*(ra2+s*ra3)); + S=one+s*(sa1+s*(sa2+s*(sa3+s*sa4))); + } else { /* |x| >= 1/.35 ~ 2.857143 */ + if(hx<0&&ix>=0x40a00000) return two-tiny;/* x < -5 */ + R=rb0+s*(rb1+s*(rb2+s*(rb3+s*rb4))); + S=one+s*(sb1+s*(sb2+s*(sb3+s*sb4))); + } + SET_FLOAT_WORD(z,hx&0xffffe000); + r = expf(-z*z-0.5625F)*expf((z-x)*(z+x)+R/S); + if(hx>0) return r/x; else return two-r/x; + } else { + if(hx>0) return tiny*tiny; else return two-tiny; + } +} diff --git a/src/openlibm/src/s_erff.c.o b/src/openlibm/src/s_erff.c.o new file mode 100644 index 0000000000000000000000000000000000000000..20b3ec3408653e601fa58a59bac8feaaf9024d09 GIT binary patch literal 7448 zcmb<-^>JfjWMqH=Mg}_u1P><4zz`vcU^{@B4h;MZd<>z%Y5aAEJMT6={r~@ey+`vK ziN?SG|JT=-mx1VT`*J%FU2nnP{)mx*q46;T149kJ#tHt`W(Ed^&-{_RAhSO6N3ufb zh=VY;NAnSh=-9&`-Sh4F+eDZc7(ncLhq9E<`~qO*t+y-8VeHqsY5ejoAR`4tK}H>X zEx!Zgk2L=GCmC;l=8wCedE+y`)``#j5vTYy4nj>&n*ehHMBp=j#KFU0b6$W9;n%pp zuW{ltf8+(2HJ|z84)JSTX#AUd+suK#jgJXrVSun4OCiQb zAn7H<77S70>AdloU(iQ|LzUsd|Nm+Hc^5ieR9N^m4)KSBgXS}T^>E1&rV zLR45j^9%T>aD3($WKrSQc=VY+;v(1-me2e#5BW8YfOMtt=Ux5G9~Yv+^O-;55L9m@ ziwamP3%|yN&-`&0TW|As%wh!j9TF3t`C|^fT=DP!{|WpWHxM2ZfW_{O&-{^>Kl8&q zcKS1a3``D9JOV=;7Bz9FKJ!O{BJkkhG(CR#7ElZ^KpiL`3*vp|hu8>qCER6~LEiez z9{~=G&-{_6kSsrhDh{_CpZMX={Bb8hA=Xz7 z_KPS9Kk^_fpMB;h%ueI4JBo-hka~EsJcyJO(b1@g?!HL&GZXe2<=6r|9A z=Fga$pZOyXBL&7~SX#yuhZiVl>QTfGf=Yi-eq8|0udw77bL!<3aK?b<7l`=F2Cx_d zY9v7lQd|*CS){&H`v)q)q2(DOJ4Kv&`Q^|5|DbY>p~0SkpGQYIdxvK6MRu(_R}TJ)_lH>9g8ui zeUGA)J;UyB5Z*7Aw0-{tM{WnXoxJvuyA^F(8glmf=x?{b6MD_z)An@^2D2m%wnn!) zcDo;Su;f;-pR_>HX6Yk7$0PE#PH}roocLJ09T^w|KyCpw2kaR{6z#xHWnch@CzQ>= z;O^{frJ&*N7pkdXXrgDNXQ*IgU}S1wXlS6I5tN#u;E`AYmC!ZUWME)nU|>*SU|;|x z26w+u1||l^10XR_T@Esn5z6NTaTpjFM4&WdRS*MXg#e>84?D*MMh1oe1_lNhsN4!> zP{{EKv@tpINi;JD@EI_9bMZ+y@(DQdaX4}_MZ-DH+&*x&7dLZ1Bb*n`&A{Nnz`#%d zHFG1TnbW!WBwWB|I&oKX@kw}t*`D0YIS6BdxS{%SQ6PV^FnokWJDMV9EG;uGuo_kd z4ls=%_`yt81|BetARytz${>Ic0<$2^J63S`g9V_39GC{h2ABaSl))@kc=&_43=9k! zU$Mi5zGCM!5C zgPBkwA560{NPuYs0SPZw1{H)5m{kcTS>b6J%w=F;r~@-tq2UeYfC)&rurla?c?hBl z%w%P-0n-Qq;(u0XxFW=-ftjof24EUN%mFi58C<|Lf>;D*vNAy86U+ey zmrGzKl=uLqSs6fe6PO7lzJY0021s~=Ibh-sm}F&G0;UlJ6C(qI5K{R7F7p@|7}yyZ zF!DM`7cUNRA*eYUK;;_)0|U6618FFZPc2GI(@SR1^Kmu;5yl|G1Vk8u2m=sd3L=aw zL8LKQz!)rN4AB7AVGPz{3|47u23BbfCN01uSTC3fmIHIa@`hmZ48i6Zf^{2$RTzTJ zHiW1F+h7RRZV0x=5Nv=ESeFr4r4d+-5m?p;Y>pAw93!v^Mqs^0V7pAf>P;YQV+N4- z8PXDyiqjZUD+FfcGNFff3E?9YD)@I(>^)n732P$Y3ssR|Q^m5U&A zK&1>!9Fm_Q=Cd;}Fu=rN#6fK%m^m6q;-I=6CT@Zxu8L%i1CqEJ zlDH3&xH^(}1d=$Y?FBPG1xZ{JNqqs5IC6ZoAc<=ssh@)+j;#JIk~ng@{fZ=xoNie` z2?rXU$mv!PNgO%d$|8v)r&~=VapZJsiX@Kg&K?}%Tad)Hk^FlQDh{HM)A>n|0Mz}+ z=Kn?#M=mGXL4`Y1J#slIj3ka+PRb*RBbSrfNaD!lq&bo}ayjXYB#vB8`Xh-Wmy^** z;>hJ>2a-5)c{l}09JxH42^9wg2Xc9M6^Hl_s5mJ5f!eCDbSna?{Gj269L|PNagh1Q z@nQ)T2bqJc-VsS0x%}}#5=Sn7Vvxj<%byG+apdx+1W6pZ{AoZEM=pPQki?P8pBYHv z$mP!#BynA&^mztJ968+XAc-TFOD~Ybk;|noNaD!l5(6j@q2Z5QF7Y6VBbQ4ONaD!l zk_wVIa=B!HB#vAzg&>I|m$#rW0X0!T@e9HrHV8xdOOSRENF3H)WzZ|G%q>YwV$drt zDT2@$Fji4&PNH5(YDEcyUP@v~B7(NQ8zLOahdrVQdf$O2eSM0#gqX17QbHp}@evkN_&I7#P6g10Z`qWhqD=RMvuM zP#lBAp~X2!2#gn^*$WnAU_k15Ktw=k6J#d2`VFCGg32C8jaTxB0 z>WA@RG`d<)5(0S@l(u1NK=cHtesp(1g+WTdxE30I==u*p74875LJ&}4xB#d>0t!>~ z^s@k(Kw$QR>MBtE2Gb9f2B!yfyFrFmK-1j@kl_pr44^s + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_exp2.c,v 1.7 2008/02/22 02:27:34 das Exp $"); + +#include +#include + +#include "math_private.h" + +#define TBLBITS 8 +#define TBLSIZE (1 << TBLBITS) + +static const double + huge = 0x1p1000, + redux = 0x1.8p52 / TBLSIZE, + P1 = 0x1.62e42fefa39efp-1, + P2 = 0x1.ebfbdff82c575p-3, + P3 = 0x1.c6b08d704a0a6p-5, + P4 = 0x1.3b2ab88f70400p-7, + P5 = 0x1.5d88003875c74p-10; + +static volatile double twom1000 = 0x1p-1000; + +static const double tbl[TBLSIZE * 2] = { +/* exp2(z + eps) eps */ + 0x1.6a09e667f3d5dp-1, 0x1.9880p-44, + 0x1.6b052fa751744p-1, 0x1.8000p-50, + 0x1.6c012750bd9fep-1, -0x1.8780p-45, + 0x1.6cfdcddd476bfp-1, 0x1.ec00p-46, + 0x1.6dfb23c651a29p-1, -0x1.8000p-50, + 0x1.6ef9298593ae3p-1, -0x1.c000p-52, + 0x1.6ff7df9519386p-1, -0x1.fd80p-45, + 0x1.70f7466f42da3p-1, -0x1.c880p-45, + 0x1.71f75e8ec5fc3p-1, 0x1.3c00p-46, + 0x1.72f8286eacf05p-1, -0x1.8300p-44, + 0x1.73f9a48a58152p-1, -0x1.0c00p-47, + 0x1.74fbd35d7ccfcp-1, 0x1.f880p-45, + 0x1.75feb564267f1p-1, 0x1.3e00p-47, + 0x1.77024b1ab6d48p-1, -0x1.7d00p-45, + 0x1.780694fde5d38p-1, -0x1.d000p-50, + 0x1.790b938ac1d00p-1, 0x1.3000p-49, + 0x1.7a11473eb0178p-1, -0x1.d000p-49, + 0x1.7b17b0976d060p-1, 0x1.0400p-45, + 0x1.7c1ed0130c133p-1, 0x1.0000p-53, + 0x1.7d26a62ff8636p-1, -0x1.6900p-45, + 0x1.7e2f336cf4e3bp-1, -0x1.2e00p-47, + 0x1.7f3878491c3e8p-1, -0x1.4580p-45, + 0x1.80427543e1b4ep-1, 0x1.3000p-44, + 0x1.814d2add1071ap-1, 0x1.f000p-47, + 0x1.82589994ccd7ep-1, -0x1.1c00p-45, + 0x1.8364c1eb942d0p-1, 0x1.9d00p-45, + 0x1.8471a4623cab5p-1, 0x1.7100p-43, + 0x1.857f4179f5bbcp-1, 0x1.2600p-45, + 0x1.868d99b4491afp-1, -0x1.2c40p-44, + 0x1.879cad931a395p-1, -0x1.3000p-45, + 0x1.88ac7d98a65b8p-1, -0x1.a800p-45, + 0x1.89bd0a4785800p-1, -0x1.d000p-49, + 0x1.8ace5422aa223p-1, 0x1.3280p-44, + 0x1.8be05bad619fap-1, 0x1.2b40p-43, + 0x1.8cf3216b54383p-1, -0x1.ed00p-45, + 0x1.8e06a5e08664cp-1, -0x1.0500p-45, + 0x1.8f1ae99157807p-1, 0x1.8280p-45, + 0x1.902fed0282c0ep-1, -0x1.cb00p-46, + 0x1.9145b0b91ff96p-1, -0x1.5e00p-47, + 0x1.925c353aa2ff9p-1, 0x1.5400p-48, + 0x1.93737b0cdc64ap-1, 0x1.7200p-46, + 0x1.948b82b5f98aep-1, -0x1.9000p-47, + 0x1.95a44cbc852cbp-1, 0x1.5680p-45, + 0x1.96bdd9a766f21p-1, -0x1.6d00p-44, + 0x1.97d829fde4e2ap-1, -0x1.1000p-47, + 0x1.98f33e47a23a3p-1, 0x1.d000p-45, + 0x1.9a0f170ca0604p-1, -0x1.8a40p-44, + 0x1.9b2bb4d53ff89p-1, 0x1.55c0p-44, + 0x1.9c49182a3f15bp-1, 0x1.6b80p-45, + 0x1.9d674194bb8c5p-1, -0x1.c000p-49, + 0x1.9e86319e3238ep-1, 0x1.7d00p-46, + 0x1.9fa5e8d07f302p-1, 0x1.6400p-46, + 0x1.a0c667b5de54dp-1, -0x1.5000p-48, + 0x1.a1e7aed8eb8f6p-1, 0x1.9e00p-47, + 0x1.a309bec4a2e27p-1, 0x1.ad80p-45, + 0x1.a42c980460a5dp-1, -0x1.af00p-46, + 0x1.a5503b23e259bp-1, 0x1.b600p-47, + 0x1.a674a8af46213p-1, 0x1.8880p-44, + 0x1.a799e1330b3a7p-1, 0x1.1200p-46, + 0x1.a8bfe53c12e8dp-1, 0x1.6c00p-47, + 0x1.a9e6b5579fcd2p-1, -0x1.9b80p-45, + 0x1.ab0e521356fb8p-1, 0x1.b700p-45, + 0x1.ac36bbfd3f381p-1, 0x1.9000p-50, + 0x1.ad5ff3a3c2780p-1, 0x1.4000p-49, + 0x1.ae89f995ad2a3p-1, -0x1.c900p-45, + 0x1.afb4ce622f367p-1, 0x1.6500p-46, + 0x1.b0e07298db790p-1, 0x1.fd40p-45, + 0x1.b20ce6c9a89a9p-1, 0x1.2700p-46, + 0x1.b33a2b84f1a4bp-1, 0x1.d470p-43, + 0x1.b468415b747e7p-1, -0x1.8380p-44, + 0x1.b59728de5593ap-1, 0x1.8000p-54, + 0x1.b6c6e29f1c56ap-1, 0x1.ad00p-47, + 0x1.b7f76f2fb5e50p-1, 0x1.e800p-50, + 0x1.b928cf22749b2p-1, -0x1.4c00p-47, + 0x1.ba5b030a10603p-1, -0x1.d700p-47, + 0x1.bb8e0b79a6f66p-1, 0x1.d900p-47, + 0x1.bcc1e904bc1ffp-1, 0x1.2a00p-47, + 0x1.bdf69c3f3a16fp-1, -0x1.f780p-46, + 0x1.bf2c25bd71db8p-1, -0x1.0a00p-46, + 0x1.c06286141b2e9p-1, -0x1.1400p-46, + 0x1.c199bdd8552e0p-1, 0x1.be00p-47, + 0x1.c2d1cd9fa64eep-1, -0x1.9400p-47, + 0x1.c40ab5fffd02fp-1, -0x1.ed00p-47, + 0x1.c544778fafd15p-1, 0x1.9660p-44, + 0x1.c67f12e57d0cbp-1, -0x1.a100p-46, + 0x1.c7ba88988c1b6p-1, -0x1.8458p-42, + 0x1.c8f6d9406e733p-1, -0x1.a480p-46, + 0x1.ca3405751c4dfp-1, 0x1.b000p-51, + 0x1.cb720dcef9094p-1, 0x1.1400p-47, + 0x1.ccb0f2e6d1689p-1, 0x1.0200p-48, + 0x1.cdf0b555dc412p-1, 0x1.3600p-48, + 0x1.cf3155b5bab3bp-1, -0x1.6900p-47, + 0x1.d072d4a0789bcp-1, 0x1.9a00p-47, + 0x1.d1b532b08c8fap-1, -0x1.5e00p-46, + 0x1.d2f87080d8a85p-1, 0x1.d280p-46, + 0x1.d43c8eacaa203p-1, 0x1.1a00p-47, + 0x1.d5818dcfba491p-1, 0x1.f000p-50, + 0x1.d6c76e862e6a1p-1, -0x1.3a00p-47, + 0x1.d80e316c9834ep-1, -0x1.cd80p-47, + 0x1.d955d71ff6090p-1, 0x1.4c00p-48, + 0x1.da9e603db32aep-1, 0x1.f900p-48, + 0x1.dbe7cd63a8325p-1, 0x1.9800p-49, + 0x1.dd321f301b445p-1, -0x1.5200p-48, + 0x1.de7d5641c05bfp-1, -0x1.d700p-46, + 0x1.dfc97337b9aecp-1, -0x1.6140p-46, + 0x1.e11676b197d5ep-1, 0x1.b480p-47, + 0x1.e264614f5a3e7p-1, 0x1.0ce0p-43, + 0x1.e3b333b16ee5cp-1, 0x1.c680p-47, + 0x1.e502ee78b3fb4p-1, -0x1.9300p-47, + 0x1.e653924676d68p-1, -0x1.5000p-49, + 0x1.e7a51fbc74c44p-1, -0x1.7f80p-47, + 0x1.e8f7977cdb726p-1, -0x1.3700p-48, + 0x1.ea4afa2a490e8p-1, 0x1.5d00p-49, + 0x1.eb9f4867ccae4p-1, 0x1.61a0p-46, + 0x1.ecf482d8e680dp-1, 0x1.5500p-48, + 0x1.ee4aaa2188514p-1, 0x1.6400p-51, + 0x1.efa1bee615a13p-1, -0x1.e800p-49, + 0x1.f0f9c1cb64106p-1, -0x1.a880p-48, + 0x1.f252b376bb963p-1, -0x1.c900p-45, + 0x1.f3ac948dd7275p-1, 0x1.a000p-53, + 0x1.f50765b6e4524p-1, -0x1.4f00p-48, + 0x1.f6632798844fdp-1, 0x1.a800p-51, + 0x1.f7bfdad9cbe38p-1, 0x1.abc0p-48, + 0x1.f91d802243c82p-1, -0x1.4600p-50, + 0x1.fa7c1819e908ep-1, -0x1.b0c0p-47, + 0x1.fbdba3692d511p-1, -0x1.0e00p-51, + 0x1.fd3c22b8f7194p-1, -0x1.0de8p-46, + 0x1.fe9d96b2a23eep-1, 0x1.e430p-49, + 0x1.0000000000000p+0, 0x0.0000p+0, + 0x1.00b1afa5abcbep+0, -0x1.3400p-52, + 0x1.0163da9fb3303p+0, -0x1.2170p-46, + 0x1.02168143b0282p+0, 0x1.a400p-52, + 0x1.02c9a3e77806cp+0, 0x1.f980p-49, + 0x1.037d42e11bbcap+0, -0x1.7400p-51, + 0x1.04315e86e7f89p+0, 0x1.8300p-50, + 0x1.04e5f72f65467p+0, -0x1.a3f0p-46, + 0x1.059b0d315855ap+0, -0x1.2840p-47, + 0x1.0650a0e3c1f95p+0, 0x1.1600p-48, + 0x1.0706b29ddf71ap+0, 0x1.5240p-46, + 0x1.07bd42b72a82dp+0, -0x1.9a00p-49, + 0x1.0874518759bd0p+0, 0x1.6400p-49, + 0x1.092bdf66607c8p+0, -0x1.0780p-47, + 0x1.09e3ecac6f383p+0, -0x1.8000p-54, + 0x1.0a9c79b1f3930p+0, 0x1.fa00p-48, + 0x1.0b5586cf988fcp+0, -0x1.ac80p-48, + 0x1.0c0f145e46c8ap+0, 0x1.9c00p-50, + 0x1.0cc922b724816p+0, 0x1.5200p-47, + 0x1.0d83b23395dd8p+0, -0x1.ad00p-48, + 0x1.0e3ec32d3d1f3p+0, 0x1.bac0p-46, + 0x1.0efa55fdfa9a6p+0, -0x1.4e80p-47, + 0x1.0fb66affed2f0p+0, -0x1.d300p-47, + 0x1.1073028d7234bp+0, 0x1.1500p-48, + 0x1.11301d0125b5bp+0, 0x1.c000p-49, + 0x1.11edbab5e2af9p+0, 0x1.6bc0p-46, + 0x1.12abdc06c31d5p+0, 0x1.8400p-49, + 0x1.136a814f2047dp+0, -0x1.ed00p-47, + 0x1.1429aaea92de9p+0, 0x1.8e00p-49, + 0x1.14e95934f3138p+0, 0x1.b400p-49, + 0x1.15a98c8a58e71p+0, 0x1.5300p-47, + 0x1.166a45471c3dfp+0, 0x1.3380p-47, + 0x1.172b83c7d5211p+0, 0x1.8d40p-45, + 0x1.17ed48695bb9fp+0, -0x1.5d00p-47, + 0x1.18af9388c8d93p+0, -0x1.c880p-46, + 0x1.1972658375d66p+0, 0x1.1f00p-46, + 0x1.1a35beb6fcba7p+0, 0x1.0480p-46, + 0x1.1af99f81387e3p+0, -0x1.7390p-43, + 0x1.1bbe084045d54p+0, 0x1.4e40p-45, + 0x1.1c82f95281c43p+0, -0x1.a200p-47, + 0x1.1d4873168b9b2p+0, 0x1.3800p-49, + 0x1.1e0e75eb44031p+0, 0x1.ac00p-49, + 0x1.1ed5022fcd938p+0, 0x1.1900p-47, + 0x1.1f9c18438cdf7p+0, -0x1.b780p-46, + 0x1.2063b88628d8fp+0, 0x1.d940p-45, + 0x1.212be3578a81ep+0, 0x1.8000p-50, + 0x1.21f49917ddd41p+0, 0x1.b340p-45, + 0x1.22bdda2791323p+0, 0x1.9f80p-46, + 0x1.2387a6e7561e7p+0, -0x1.9c80p-46, + 0x1.2451ffb821427p+0, 0x1.2300p-47, + 0x1.251ce4fb2a602p+0, -0x1.3480p-46, + 0x1.25e85711eceb0p+0, 0x1.2700p-46, + 0x1.26b4565e27d16p+0, 0x1.1d00p-46, + 0x1.2780e341de00fp+0, 0x1.1ee0p-44, + 0x1.284dfe1f5633ep+0, -0x1.4c00p-46, + 0x1.291ba7591bb30p+0, -0x1.3d80p-46, + 0x1.29e9df51fdf09p+0, 0x1.8b00p-47, + 0x1.2ab8a66d10e9bp+0, -0x1.27c0p-45, + 0x1.2b87fd0dada3ap+0, 0x1.a340p-45, + 0x1.2c57e39771af9p+0, -0x1.0800p-46, + 0x1.2d285a6e402d9p+0, -0x1.ed00p-47, + 0x1.2df961f641579p+0, -0x1.4200p-48, + 0x1.2ecafa93e2ecfp+0, -0x1.4980p-45, + 0x1.2f9d24abd8822p+0, -0x1.6300p-46, + 0x1.306fe0a31b625p+0, -0x1.2360p-44, + 0x1.31432edeea50bp+0, -0x1.0df8p-40, + 0x1.32170fc4cd7b8p+0, -0x1.2480p-45, + 0x1.32eb83ba8e9a2p+0, -0x1.5980p-45, + 0x1.33c08b2641766p+0, 0x1.ed00p-46, + 0x1.3496266e3fa27p+0, -0x1.c000p-50, + 0x1.356c55f929f0fp+0, -0x1.0d80p-44, + 0x1.36431a2de88b9p+0, 0x1.2c80p-45, + 0x1.371a7373aaa39p+0, 0x1.0600p-45, + 0x1.37f26231e74fep+0, -0x1.6600p-46, + 0x1.38cae6d05d838p+0, -0x1.ae00p-47, + 0x1.39a401b713ec3p+0, -0x1.4720p-43, + 0x1.3a7db34e5a020p+0, 0x1.8200p-47, + 0x1.3b57fbfec6e95p+0, 0x1.e800p-44, + 0x1.3c32dc313a8f2p+0, 0x1.f800p-49, + 0x1.3d0e544ede122p+0, -0x1.7a00p-46, + 0x1.3dea64c1234bbp+0, 0x1.6300p-45, + 0x1.3ec70df1c4eccp+0, -0x1.8a60p-43, + 0x1.3fa4504ac7e8cp+0, -0x1.cdc0p-44, + 0x1.40822c367a0bbp+0, 0x1.5b80p-45, + 0x1.4160a21f72e95p+0, 0x1.ec00p-46, + 0x1.423fb27094646p+0, -0x1.3600p-46, + 0x1.431f5d950a920p+0, 0x1.3980p-45, + 0x1.43ffa3f84b9ebp+0, 0x1.a000p-48, + 0x1.44e0860618919p+0, -0x1.6c00p-48, + 0x1.45c2042a7d201p+0, -0x1.bc00p-47, + 0x1.46a41ed1d0016p+0, -0x1.2800p-46, + 0x1.4786d668b3326p+0, 0x1.0e00p-44, + 0x1.486a2b5c13c00p+0, -0x1.d400p-45, + 0x1.494e1e192af04p+0, 0x1.c200p-47, + 0x1.4a32af0d7d372p+0, -0x1.e500p-46, + 0x1.4b17dea6db801p+0, 0x1.7800p-47, + 0x1.4bfdad53629e1p+0, -0x1.3800p-46, + 0x1.4ce41b817c132p+0, 0x1.0800p-47, + 0x1.4dcb299fddddbp+0, 0x1.c700p-45, + 0x1.4eb2d81d8ab96p+0, -0x1.ce00p-46, + 0x1.4f9b2769d2d02p+0, 0x1.9200p-46, + 0x1.508417f4531c1p+0, -0x1.8c00p-47, + 0x1.516daa2cf662ap+0, -0x1.a000p-48, + 0x1.5257de83f51eap+0, 0x1.a080p-43, + 0x1.5342b569d4edap+0, -0x1.6d80p-45, + 0x1.542e2f4f6ac1ap+0, -0x1.2440p-44, + 0x1.551a4ca5d94dbp+0, 0x1.83c0p-43, + 0x1.56070dde9116bp+0, 0x1.4b00p-45, + 0x1.56f4736b529dep+0, 0x1.15a0p-43, + 0x1.57e27dbe2c40ep+0, -0x1.9e00p-45, + 0x1.58d12d497c76fp+0, -0x1.3080p-45, + 0x1.59c0827ff0b4cp+0, 0x1.dec0p-43, + 0x1.5ab07dd485427p+0, -0x1.4000p-51, + 0x1.5ba11fba87af4p+0, 0x1.0080p-44, + 0x1.5c9268a59460bp+0, -0x1.6c80p-45, + 0x1.5d84590998e3fp+0, 0x1.69a0p-43, + 0x1.5e76f15ad20e1p+0, -0x1.b400p-46, + 0x1.5f6a320dcebcap+0, 0x1.7700p-46, + 0x1.605e1b976dcb8p+0, 0x1.6f80p-45, + 0x1.6152ae6cdf715p+0, 0x1.1000p-47, + 0x1.6247eb03a5531p+0, -0x1.5d00p-46, + 0x1.633dd1d1929b5p+0, -0x1.2d00p-46, + 0x1.6434634ccc313p+0, -0x1.a800p-49, + 0x1.652b9febc8efap+0, -0x1.8600p-45, + 0x1.6623882553397p+0, 0x1.1fe0p-40, + 0x1.671c1c708328ep+0, -0x1.7200p-44, + 0x1.68155d44ca97ep+0, 0x1.6800p-49, + 0x1.690f4b19e9471p+0, -0x1.9780p-45, +}; + +/* + * exp2(x): compute the base 2 exponential of x + * + * Accuracy: Peak error < 0.503 ulp for normalized results. + * + * Method: (accurate tables) + * + * Reduce x: + * x = 2**k + y, for integer k and |y| <= 1/2. + * Thus we have exp2(x) = 2**k * exp2(y). + * + * Reduce y: + * y = i/TBLSIZE + z - eps[i] for integer i near y * TBLSIZE. + * Thus we have exp2(y) = exp2(i/TBLSIZE) * exp2(z - eps[i]), + * with |z - eps[i]| <= 2**-9 + 2**-39 for the table used. + * + * We compute exp2(i/TBLSIZE) via table lookup and exp2(z - eps[i]) via + * a degree-5 minimax polynomial with maximum error under 1.3 * 2**-61. + * The values in exp2t[] and eps[] are chosen such that + * exp2t[i] = exp2(i/TBLSIZE + eps[i]), and eps[i] is a small offset such + * that exp2t[i] is accurate to 2**-64. + * + * Note that the range of i is +-TBLSIZE/2, so we actually index the tables + * by i0 = i + TBLSIZE/2. For cache efficiency, exp2t[] and eps[] are + * virtual tables, interleaved in the real table tbl[]. + * + * This method is due to Gal, with many details due to Gal and Bachelis: + * + * Gal, S. and Bachelis, B. An Accurate Elementary Mathematical Library + * for the IEEE Floating Point Standard. TOMS 17(1), 26-46 (1991). + */ +OLM_DLLEXPORT double +exp2(double x) +{ + double r, t, twopk, twopkp1000, z; + u_int32_t hx, ix, lx, i0; + int k; + + /* Filter out exceptional cases. */ + GET_HIGH_WORD(hx,x); + ix = hx & 0x7fffffff; /* high word of |x| */ + if(ix >= 0x40900000) { /* |x| >= 1024 */ + if(ix >= 0x7ff00000) { + GET_LOW_WORD(lx,x); + if(((ix & 0xfffff) | lx) != 0 || (hx & 0x80000000) == 0) + return (x + x); /* x is NaN or +Inf */ + else + return (0.0); /* x is -Inf */ + } + if(x >= 0x1.0p10) + return (huge * huge); /* overflow */ + if(x <= -0x1.0ccp10) + return (twom1000 * twom1000); /* underflow */ + } else if (ix < 0x3c900000) { /* |x| < 0x1p-54 */ + return (1.0 + x); + } + + /* Reduce x, computing z, i0, and k. */ + STRICT_ASSIGN(double, t, x + redux); + GET_LOW_WORD(i0, t); + i0 += TBLSIZE / 2; + k = (i0 >> TBLBITS) << 20; + i0 = (i0 & (TBLSIZE - 1)) << 1; + t -= redux; + z = x - t; + + /* Compute r = exp2(y) = exp2t[i0] * p(z - eps[i]). */ + t = tbl[i0]; /* exp2t[i0] */ + z -= tbl[i0 + 1]; /* eps[i0] */ + if (k >= -(1021 << 20)) + INSERT_WORDS(twopk, 0x3ff00000 + k, 0); + else + INSERT_WORDS(twopkp1000, 0x3ff00000 + k + (1000 << 20), 0); + r = t + t * z * (P1 + z * (P2 + z * (P3 + z * (P4 + z * P5)))); + + /* Scale by 2**(k>>20). */ + if(k >= -(1021 << 20)) { + if (k == 1024 << 20) + return (r * 2.0 * 0x1p1023); + return (r * twopk); + } else { + return (r * twopkp1000 * twom1000); + } +} + +#if (LDBL_MANT_DIG == 53) +openlibm_weak_reference(exp2, exp2l); +#endif diff --git a/src/openlibm/src/s_exp2.c.o b/src/openlibm/src/s_exp2.c.o new file mode 100644 index 0000000000000000000000000000000000000000..64ebce9df2e063aa7901fb0905a4e603cea92621 GIT binary patch literal 6864 zcmb<-^>JfjWMqH=Mg}_u1P><4z#t%wU^{@B4h;MZd<VIFQD#aUzXh z$>KWqO(`8V|UF4p~$R>J=rYM;*D!|`ukl*&W-2ZU`|&%bJG(ueX5EcOO9 zF7=pY59J?V*!$*B z`4iOkTKku9?Vq9i2$j8l(sm*0EH5DbWiYmtV!ycdk_e2?Z(DcP zXJ)4=lz%{R?**rwaz18I{sm3jt*4aTq}-u=0e9Oy(euT>ghTlWO1A4Ky3D?r0p%Yt z+BUle!&e)xV`n#*n?v~u;Rm?A&bvGNzzhJgk%kSR&rdlYUfpPC*<*Fyf{V=|+EeqSJf{zQJ{3RB9JO2m! z?%o9D$C%nie_Y%&@d%W^L(TT+4sXelYfwJJn>~HXk0p~|K=~KMZJ9o^_s0E#@*Tu% zeV@iwr}4ak_?O}9o^Lz)-d4#$`42d4)%CpI%r=1XZ)n-Za=A5}bb|6fNbQ}iYPX3w z6v|KFwiQnL(&d#7<#$-vF5he*Jg*YUR}i%A)jJscuN%rgz-D{tPi1KKJScyM=H4Co zrixEDK=}pQwvC@J@6SFA}r_wJCr9)0K&l)pe=@5@b&i5hHg zApUU>-1{J?_3ms*DE|Ss?Yop;H)V98dZ zAzbfcI+QOUwRhXWj?NX;5PpMe#9rg)Y*TXkA$$f8slE4)1co~-hVmIs+f148{*JgZ_E&rtpZw!M2g*}Zhx-$MMefYbKZ z2@dUGX(<1J=-$>YUXFHsC|^U?mU+>sS0|jI`~{4*6PNtHBM|}RGu*dX_$=u~Sq_xH zfO)T9^GUJC4N(3Kp1l(i{ujnhh4K%4u~}zyoB7#FD1X9#8`Wm3Yc>0z{Dzk{u3H#C zD_(~36~6A-&nlC0^*NMZAiMX?tZL)wf1rF3vAuD%lG*8k?;!s1;I@6f_^XJU8kB#| z!8Ycdn6_B@}k_Yn7Y{MwVeGuvES70REWv$wS9uE$9$D4$`Kjf!htbXfqD z|KZD?zb+k>Mrlxf!zmk!eRJ0St%maV{IY4XQDM3<5z0@vvZrstyvBpep?n_hy@FRK zneEyO+@cS zIz#yeH*C^Fz7@s$LHYJld!t%KFK>v1@>`hpPL;Re<4T3{6F%BVeZQ-jT>#~)h}!C| zDAK-C4dpL*x#z;{QVG{~DBt0k%?b9jZ+j;}`4tR%n?D~rWj7DXXPB|az*2tp@s&{i zg8w#uI)3IvY=!bq{Myr%^ThSz0Vw~#O&c+fBJD|MpnL^Z+Z(Z#%GNia{0qPKe7<>nZF9q`d6I$G!gqcD`u z@W$q+R@~~_a!~#rG25$#IS2M?LHQ0ZY-(9PiL5Y#@-Oi1eW|;0-7F_4|G^6z3q$|O zQ~jWPhu1cReM?Wwh=TGBSZ(hgE(}?c2IX5Y+X@EN+UzKT@~>#v&fh(??MfY#e}Q%H z^3{s|~wfot!kof(GhSD^fc$2NuzTjHKSfbtK#vaz`NM=9Vfls|#d_WN0j zmV-Z`{0iy4{k=&Y)@+|3;WiMFk>aOI-A+ED%v zN!#a%rFm5rQ2q(Yz3L)OzvW$_d;=z1re&M_&jmvH9>RM!oRceTjf3(FglxrXAEmlx zL-`j3ZTTO_n($RX`R@#E?UKJfyx#)l9}wAVuzOJU*OwYDVicb?LL&R z@MX_=J-e0b-$3~@RQ4)$?De|z6UsLb+pD_Gkn11YXGr*&8SUj>`tGff2!!8ozhLi< z>pp)96d`;D52d|}Uaqj-p$Fy9P~Dp*p0bI<2Fkx6XRH3}aaximl+SQy5C8m0@khg; z{2K;)cXr%cWS9cwpHQ;3TxDgxyb#JyP_X@1BB!iY595pNwYb5WyRHYyf55f(uw9|F z!z?Jj$Yrm>f~O|8mqYmq9JW*Q-t4d63gtK0*?w9fd|3A|jQ`$7>ET$>m zn+W+Vy9ebPsM((Jleu5;2FhRNvA3sg4U6k9DF2Sl-rWn*4=ZtefrQr%Rokh0-xayU zp!@@Jwr*~m>c5qt`~=~>3M&I{el>*hXDHjg-q~XR%O1*S_+=y6nV7)g2jw65wukZ3 zawmlt7@vEu7=!Fv$1EtnL1?d4mhZ@;+v;^t{sYau`NyYU5$c8VIh6PMaQ|25m;>d%@wHVC@wm&r z8p>xlvgb?Hir<2}pnMJkTW+_=F13?T{t30c_I)!axZZ&BXSvxvR9GvT{~XG9kluUh z^&N%9-=O>gaoZht%62|v{RRn-A8NLu-_JhN5{2>^7;Ozhtv1xDK=~I$_iojcl)Y;V z;|uK-K77W+%^AvXc(vzO-=2RvgP{BbjlI*2Lz^s;p!|P@wtYq%#}5`l`3mNH>sI<) z32lV(8=lz|PMNpy%LFLDLUS*q{+|FD(qSm51M|;JH~^;M?SdUnB{A*H4L3sV8Cbq| ztlrdYzia`^b&l*c_N7Og{_ov?&i=jSuYXQ@(0)F{gL(#cXJ;z~4R^m#O$9>}JtI9s z1tS9^Qv*Xo0|kws)D#7e#1g24uDK=y0}BHKg8~Bs188u=-7l1ZiGlF|NDMX>#R%nd zLL9~*0;L(Nf*2Sp1Q?}x*f}OJGJwTppmG~wnxTAb6i5jR!$;I%5vW3DtRrCz49pD7 zP!$M@i-CcG5$t-Xm;i+41B)Znb3lZ_Br~#lum}SKWSET&92QU^Fa_}w8-oUzhaeQe zOg07sFpVJ8z)Us<3owl!w82a^255wXc_0F!pN+u-#6iMlU^W|=L?*1k95x21H^Dp* z0Wp`2K?1}V%NOA0C&*@u?LBMtaE%B}q99CFS|K zh6V-(40=A!rXa!$M3{pJ3lL!mA`HROh9IUfh%f;WhG4!C1IRFteeocIfq{XEfq{XY zfq~)Ae+bAz5(k9>OnefOILPfV@eN4gptK4T--9F$N-Hq&6G-CRNcP@966Zk@|Ar(E zN>wm(L_i4{>VD85AWU2dNgR|GVd5r8;>hOM;1DlC66Z&94=B%poCFFtP+EYQzXVCW zAd-4e9*3z1=>f69Sg*J;wKB3uz-XvI1dI=*VeW^~ZczP@@(iko zfq@|cs$U-=1ZKh952O8|`oWS&L_1VJk`R~)(+B1-Fff415m5O7^Da!h1F9e0T`+gU z)RjZ+N7uiDNc}}P(ocaH#0FS80i_>MIRvvGCJyosy4@h1FQE3H04ZQ#U;vddAR%=9 opfV35?JzJfY=BnSp&-MMFw{7>2&k;UroRK~{zkY;2m@U|0P~>)#sB~S literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_exp2f.c b/src/openlibm/src/s_exp2f.c new file mode 100644 index 0000000..74bc9f3 --- /dev/null +++ b/src/openlibm/src/s_exp2f.c @@ -0,0 +1,136 @@ +/*- + * Copyright (c) 2005 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_exp2f.c,v 1.9 2008/02/22 02:27:34 das Exp $"); + +#include +#include + +#include "math_private.h" + +#define TBLBITS 4 +#define TBLSIZE (1 << TBLBITS) + +static const float + huge = 0x1p100f, + redux = 0x1.8p23f / TBLSIZE, + P1 = 0x1.62e430p-1f, + P2 = 0x1.ebfbe0p-3f, + P3 = 0x1.c6b348p-5f, + P4 = 0x1.3b2c9cp-7f; + +static volatile float twom100 = 0x1p-100f; + +static const double exp2ft[TBLSIZE] = { + 0x1.6a09e667f3bcdp-1, + 0x1.7a11473eb0187p-1, + 0x1.8ace5422aa0dbp-1, + 0x1.9c49182a3f090p-1, + 0x1.ae89f995ad3adp-1, + 0x1.c199bdd85529cp-1, + 0x1.d5818dcfba487p-1, + 0x1.ea4afa2a490dap-1, + 0x1.0000000000000p+0, + 0x1.0b5586cf9890fp+0, + 0x1.172b83c7d517bp+0, + 0x1.2387a6e756238p+0, + 0x1.306fe0a31b715p+0, + 0x1.3dea64c123422p+0, + 0x1.4bfdad5362a27p+0, + 0x1.5ab07dd485429p+0, +}; + +/* + * exp2f(x): compute the base 2 exponential of x + * + * Accuracy: Peak error < 0.501 ulp; location of peak: -0.030110927. + * + * Method: (equally-spaced tables) + * + * Reduce x: + * x = 2**k + y, for integer k and |y| <= 1/2. + * Thus we have exp2f(x) = 2**k * exp2(y). + * + * Reduce y: + * y = i/TBLSIZE + z for integer i near y * TBLSIZE. + * Thus we have exp2(y) = exp2(i/TBLSIZE) * exp2(z), + * with |z| <= 2**-(TBLSIZE+1). + * + * We compute exp2(i/TBLSIZE) via table lookup and exp2(z) via a + * degree-4 minimax polynomial with maximum error under 1.4 * 2**-33. + * Using double precision for everything except the reduction makes + * roundoff error insignificant and simplifies the scaling step. + * + * This method is due to Tang, but I do not use his suggested parameters: + * + * Tang, P. Table-driven Implementation of the Exponential Function + * in IEEE Floating-Point Arithmetic. TOMS 15(2), 144-157 (1989). + */ +OLM_DLLEXPORT float +exp2f(float x) +{ + double tv, twopk, u, z; + float t; + u_int32_t hx, ix, i0; + int32_t k; + + /* Filter out exceptional cases. */ + GET_FLOAT_WORD(hx, x); + ix = hx & 0x7fffffff; /* high word of |x| */ + if(ix >= 0x43000000) { /* |x| >= 128 */ + if(ix >= 0x7f800000) { + if ((ix & 0x7fffff) != 0 || (hx & 0x80000000) == 0) + return (x + x); /* x is NaN or +Inf */ + else + return (0.0); /* x is -Inf */ + } + if(x >= 0x1.0p7f) + return (huge * huge); /* overflow */ + if(x <= -0x1.2cp7f) + return (twom100 * twom100); /* underflow */ + } else if (ix <= 0x33000000) { /* |x| <= 0x1p-25 */ + return (1.0f + x); + } + + /* Reduce x, computing z, i0, and k. */ + STRICT_ASSIGN(float, t, x + redux); + GET_FLOAT_WORD(i0, t); + i0 += TBLSIZE / 2; + k = (i0 >> TBLBITS) << 20; + i0 &= TBLSIZE - 1; + t -= redux; + z = x - t; + INSERT_WORDS(twopk, 0x3ff00000 + k, 0); + + /* Compute r = exp2(y) = exp2ft[i0] * p(z). */ + tv = exp2ft[i0]; + u = tv * z; + tv = tv + u * (P1 + z * P2) + u * (z * z) * (P3 + z * P4); + + /* Scale by 2**(k>>20). */ + return (tv * twopk); +} diff --git a/src/openlibm/src/s_exp2f.c.o b/src/openlibm/src/s_exp2f.c.o new file mode 100644 index 0000000000000000000000000000000000000000..cfcac0e1f0dd95953ffe2492dbcbb1e4a3f92908 GIT binary patch literal 2712 zcmb<-^>JfjWMqH=Mg}_u1P><4z%YXi!FB*M9T)@{_!-jp>kf5ZQ2qb^f4%Mh|NouJ z^lbnCudnBCyUf7A@cq#L|Md)|JZb#zPqtp-@7Tz|z`(C@;xm8534V=(hxz3l7;G6B z7>xPbt}-w%eC8Jr1)0pRal)gQ7sUF^A8{&;zwX3m{+Lsrpt8LI9Gw@MAMt zUx4T0!51tCABeCrFnqB8%pY~&6My7|G=7a69tR&NeBzJ1`H4RQY-*YZf8K*n{E?SG z@kd-t$!Gq^6R!^;L?M1g@FP#YUIH?*0c;G2g$EtCGYGZW`3~e@BEn)vGs#}bzrT{j-rqD7D=UfRTiJ@MYkJr{bT!VuVf=|G~E3{H5Cj^^o;Zj6^smwObrYT4HPtjQd1N>5=)>G zy5^b;3@i)`3XYPkrMW~>TgV5|^el;&aQn83)u z01}sh%Gtp*L;2V!kP;S#kN>gBF=NdM3=GT+%oxhK85kHC!LEl$H9#l^A+R_?J;+Z` zDF$XF^)N9hFoTUj08AqYc`%b5Od=C1U=BM22be|>nqVe7hBUE139SBymsy z02Ai}B}l0IL8%5NE`~!~1xcI_$vq}W;`~VBpgab$8WcVt3}S<^UU6k^Nn#R%UU5kg zgwBAmic)hD^-5AJN*MG~5=#;p^pc8;8T5+sAsh&;mt0(80uuyrEEx2X^K)}k^GX=> z^72bk_1yhJb&E?9le3}x^t@8Nf};F_)S{9~20gGHsTuKUMTxnoU>mWd%qS zfg3=Ip=KjQA$B42br=}Hc@C5Yki}b|`jN#zY;<8msQoB$%)r2~0ICpHK7sUtFeto0 zGz?op^@GYUm>7swfEoxYXF+@zh6W2f-@D<^ZvoYhZXYcCV0184zX8kwC>;USuMg$J zD5$sKB}@!dKTIA*w?p;A_%Ir#AI8stmLKTKJD>vS?t-}+rXSQ=0GSC@4ijeB0Tm#m zzaE-K(9_=sPzA}rzyM2Up!5eSZ(#Pr#Ie~8a>NU${WCxc7#J8pWd56) return 2^k(1-(E-r)) - 1 (or exp(x)-1) + * (vi) if k <= 20, return 2^k((1-2^-k)-(E-r)), else + * (vii) return 2^k(1-((E+2^-k)-r)) + * + * Special cases: + * expm1(INF) is INF, expm1(NaN) is NaN; + * expm1(-INF) is -1, and + * for finite argument, only expm1(0)=0 is exact. + * + * Accuracy: + * according to an error analysis, the error is always less than + * 1 ulp (unit in the last place). + * + * Misc. info. + * For IEEE double + * if x > 7.09782712893383973096e+02 then expm1(x) overflow + * + * Constants: + * The hexadecimal values are the intended ones for the following + * constants. The decimal values may be used, provided that the + * compiler will convert from decimal to binary accurately enough + * to produce the hexadecimal values shown. + */ + +#include +#include + +#include "math_private.h" + +static const double +one = 1.0, +huge = 1.0e+300, +tiny = 1.0e-300, +o_threshold = 7.09782712893383973096e+02,/* 0x40862E42, 0xFEFA39EF */ +ln2_hi = 6.93147180369123816490e-01,/* 0x3fe62e42, 0xfee00000 */ +ln2_lo = 1.90821492927058770002e-10,/* 0x3dea39ef, 0x35793c76 */ +invln2 = 1.44269504088896338700e+00,/* 0x3ff71547, 0x652b82fe */ +/* Scaled Q's: Qn_here = 2**n * Qn_above, for R(2*z) where z = hxs = x*x/2: */ +Q1 = -3.33333333333331316428e-02, /* BFA11111 111110F4 */ +Q2 = 1.58730158725481460165e-03, /* 3F5A01A0 19FE5585 */ +Q3 = -7.93650757867487942473e-05, /* BF14CE19 9EAADBB7 */ +Q4 = 4.00821782732936239552e-06, /* 3ED0CFCA 86E65239 */ +Q5 = -2.01099218183624371326e-07; /* BE8AFDB7 6E09C32D */ + +OLM_DLLEXPORT double +expm1(double x) +{ + double y,hi,lo,c,t,e,hxs,hfx,r1,twopk; + int32_t k,xsb; + u_int32_t hx; + + GET_HIGH_WORD(hx,x); + xsb = hx&0x80000000; /* sign bit of x */ + hx &= 0x7fffffff; /* high word of |x| */ + + /* filter out huge and non-finite argument */ + if(hx >= 0x4043687A) { /* if |x|>=56*ln2 */ + if(hx >= 0x40862E42) { /* if |x|>=709.78... */ + if(hx>=0x7ff00000) { + u_int32_t low; + GET_LOW_WORD(low,x); + if(((hx&0xfffff)|low)!=0) + return x+x; /* NaN */ + else return (xsb==0)? x:-1.0;/* exp(+-inf)-1={inf,-1} */ + } + if(x > o_threshold) return huge*huge; /* overflow */ + } + if(xsb!=0) { /* x < -56*ln2, return -1.0 with inexact */ + if(x+tiny<0.0) /* raise inexact */ + return tiny-one; /* return -1 */ + } + } + + /* argument reduction */ + if(hx > 0x3fd62e42) { /* if |x| > 0.5 ln2 */ + if(hx < 0x3FF0A2B2) { /* and |x| < 1.5 ln2 */ + if(xsb==0) + {hi = x - ln2_hi; lo = ln2_lo; k = 1;} + else + {hi = x + ln2_hi; lo = -ln2_lo; k = -1;} + } else { + k = invln2*x+((xsb==0)?0.5:-0.5); + t = k; + hi = x - t*ln2_hi; /* t*ln2_hi is exact here */ + lo = t*ln2_lo; + } + STRICT_ASSIGN(double, x, hi - lo); + c = (hi-x)-lo; + } + else if(hx < 0x3c900000) { /* when |x|<2**-54, return x */ + t = huge+x; /* return x with inexact flags when x!=0 */ + return x - (t-(huge+x)); + } + else k = 0; + + /* x is now in primary range */ + hfx = 0.5*x; + hxs = x*hfx; + r1 = one+hxs*(Q1+hxs*(Q2+hxs*(Q3+hxs*(Q4+hxs*Q5)))); + t = 3.0-r1*hfx; + e = hxs*((r1-t)/(6.0 - x*t)); + if(k==0) return x - (x*e-hxs); /* c is 0 */ + else { + INSERT_WORDS(twopk,0x3ff00000+(k<<20),0); /* 2^k */ + e = (x*(e-c)-c); + e -= hxs; + if(k== -1) return 0.5*(x-e)-0.5; + if(k==1) { + if(x < -0.25) return -2.0*(e-(x+0.5)); + else return one+2.0*(x-e); + } + if (k <= -2 || k>56) { /* suffice to return exp(x)-1 */ + y = one-(e-x); + if (k == 1024) y = y*2.0*0x1p1023; + else y = y*twopk; + return y-one; + } + t = one; + if(k<20) { + SET_HIGH_WORD(t,0x3ff00000 - (0x200000>>k)); /* t=1-2^-k */ + y = t-(e-x); + y = y*twopk; + } else { + SET_HIGH_WORD(t,((0x3ff-k)<<20)); /* 2^-k */ + y = x-(e+t); + y += one; + y = y*twopk; + } + } + return y; +} + +#if (LDBL_MANT_DIG == 53) +openlibm_weak_reference(expm1, expm1l); +#endif diff --git a/src/openlibm/src/s_expm1.c.o b/src/openlibm/src/s_expm1.c.o new file mode 100644 index 0000000000000000000000000000000000000000..ac971e44f14a30ff479df38ec54600973795e820 GIT binary patch literal 3952 zcmb<-^>JfjWMqH=Mg}_u1P><4!0>?^!FB*M9T@l+cp1_>`0EaObe{4!_)4MkLgzKr z|NsBjH$G!vU}&(d%y4$#Z=1!yz+mgB*XB@WX#4;F`}#7O#z+7E^D}Us;%{MNW?=Zl zA93Jt8ozuC*wi$BeO3^Izuk(NfuZ#qe`^;bNR5CfNc0oGfGUKJypYDPapn_$#HmmG z5VY1;_#=5C>SJ!D@oOCZ#2<6;6MxK&Py8`AU#sxT zJ22Qf>0PtuZ=cG@z+n6Tf4>cX+aZX3V0#QtrtxchNaNSI@QGglYLb91#Kg!ipZFuM zrSWV0`@}C`3Kcu`i9Z6WF7nhT{um@SPVuv!_#=OQ;*a_MiC@4LVouDtPyCS|KJmx= z`@|o2{u6)Xsn(MvC7<|XPIsO-_&|h}f#HMwC;rG29tR&NfJ8s>$DC^Z`Jca~l#zj< z`6nZPiwGkFLvJ8s^Dj&O_6`P+pfG>`az+M*T?`Bg44?R8PNaG8=e@Z6tMlS6kZGEy zJPtlm0Er!f1XARSG=7bvhe5W0Oa}=b=9g!Hg+m(u`%9nrBTl68>tEz=cY=f&ERLYQ zM#R<2;D7)B^UJ${Vlw6g$Y79pjXxP!7#R3l5*Qgk=_v2PC;rF>Y5W>TKJmvK1tkd= z1_s-Wi$2)%x36VjU;ssM>$j5JPy7+GkYIvD$e z`Rm{({z#D1k09Igi9hl}>o@+EUa(CN2g9}7{so0f1IRP2-%2=Ot^n!Z^`Du6LG#qX zM;t)Q}N0A30{D=de_#?r-d^zVIBEUe| z=;f9_|Nnzr0mBdMA*=`c%WNu5-&?-g3#Gy7lY!yG{`Z!@{yFKjIm{_#=&*TWUiYs_ zJJntEyM5&6ABW`gmNGIhJox9N_sm}RFlXNOzg_z*gPygWI)A}#`|VZpB+rT1w}$?c zT)-G*|3yGhP*89o)V>c;ngdeAFi1e@3;QANVK@MxAJj9rJ3Ct`Xt?`@YAP6-=o#r5 zDi|3UnHm@x8YpN4rKTu&B$hxWbj>vxKnaaOfq{Vm6aemip$tq6j0ad47~o|cBb3hx zv4BAYN;6gkF)&sLFiP{Vb4*}l0E^2&B7>FeWA{ba1Jis)90EGc46eJKrU>3NzV_;2UDyJ5nviYKoSlsLjpnw%yI^ktPB}o8bNr1nXC*2 zU>ZUAgPE)hpfU~2gc6}(nw0^XV8A>O5d|U`SQ$9LG=hi+Gg%oR;R@z}i4-u&%3uJd z5kw}K$;vPROe2VVFq4&G2AD<=rC=s2IL(2XP@)PO!Nl8;#Mu}a z7+~Uyki^-M#BU*qBb)OENgNcnFmt{jiG%VoOq>Ih5g8a5KB+iGVJ^)FaA4&WRk~k<0!pz|VIRxrX=V<|OKsq*jzL=%plbdHE%&dhULqy2T}l$=OhTdS0nsK~a7|YEelggC5wp)QtGFqQu-( zh~<=%Ab)|9E+`I>O@o!Y@Nx?(2};{gCYX|DfYik>^Z1H4Gngfb_Om`W`Xk%43HTJ9s`380|U4&AXh)A-UFEl$~(yB3P9~&fh-8M z3nT>dhaJ@Y==IAEsD6ErVk8W*3&e%d?oj<8F=YH4svlVl#D?huu|YVTfq?;(&rs4N z0|UbgsD5;J!Q2hf3&NoK4rC^}ehE literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_expm1f.c b/src/openlibm/src/s_expm1f.c new file mode 100644 index 0000000..cb7ceec --- /dev/null +++ b/src/openlibm/src/s_expm1f.c @@ -0,0 +1,123 @@ +/* s_expm1f.c -- float version of s_expm1.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_expm1f.c,v 1.12 2011/10/21 06:26:38 das Exp $"); + +#include +#include + +#include "math_private.h" + +static const float +one = 1.0, +huge = 1.0e+30, +tiny = 1.0e-30, +o_threshold = 8.8721679688e+01,/* 0x42b17180 */ +ln2_hi = 6.9313812256e-01,/* 0x3f317180 */ +ln2_lo = 9.0580006145e-06,/* 0x3717f7d1 */ +invln2 = 1.4426950216e+00,/* 0x3fb8aa3b */ +/* + * Domain [-0.34568, 0.34568], range ~[-6.694e-10, 6.696e-10]: + * |6 / x * (1 + 2 * (1 / (exp(x) - 1) - 1 / x)) - q(x)| < 2**-30.04 + * Scaled coefficients: Qn_here = 2**n * Qn_for_q (see s_expm1.c): + */ +Q1 = -3.3333212137e-2, /* -0x888868.0p-28 */ +Q2 = 1.5807170421e-3; /* 0xcf3010.0p-33 */ + +OLM_DLLEXPORT float +expm1f(float x) +{ + float y,hi,lo,c,t,e,hxs,hfx,r1,twopk; + int32_t k,xsb; + u_int32_t hx; + + GET_FLOAT_WORD(hx,x); + xsb = hx&0x80000000; /* sign bit of x */ + hx &= 0x7fffffff; /* high word of |x| */ + + /* filter out huge and non-finite argument */ + if(hx >= 0x4195b844) { /* if |x|>=27*ln2 */ + if(hx >= 0x42b17218) { /* if |x|>=88.721... */ + if(hx>0x7f800000) + return x+x; /* NaN */ + if(hx==0x7f800000) + return (xsb==0)? x:-1.0;/* exp(+-inf)={inf,-1} */ + if(x > o_threshold) return huge*huge; /* overflow */ + } + if(xsb!=0) { /* x < -27*ln2, return -1.0 with inexact */ + if(x+tiny<(float)0.0) /* raise inexact */ + return tiny-one; /* return -1 */ + } + } + + /* argument reduction */ + if(hx > 0x3eb17218) { /* if |x| > 0.5 ln2 */ + if(hx < 0x3F851592) { /* and |x| < 1.5 ln2 */ + if(xsb==0) + {hi = x - ln2_hi; lo = ln2_lo; k = 1;} + else + {hi = x + ln2_hi; lo = -ln2_lo; k = -1;} + } else { + k = invln2*x+((xsb==0)?(float)0.5:(float)-0.5); + t = k; + hi = x - t*ln2_hi; /* t*ln2_hi is exact here */ + lo = t*ln2_lo; + } + STRICT_ASSIGN(float, x, hi - lo); + c = (hi-x)-lo; + } + else if(hx < 0x33000000) { /* when |x|<2**-25, return x */ + t = huge+x; /* return x with inexact flags when x!=0 */ + return x - (t-(huge+x)); + } + else k = 0; + + /* x is now in primary range */ + hfx = (float)0.5*x; + hxs = x*hfx; + r1 = one+hxs*(Q1+hxs*Q2); + t = (float)3.0-r1*hfx; + e = hxs*((r1-t)/((float)6.0 - x*t)); + if(k==0) return x - (x*e-hxs); /* c is 0 */ + else { + SET_FLOAT_WORD(twopk,0x3f800000+(k<<23)); /* 2^k */ + e = (x*(e-c)-c); + e -= hxs; + if(k== -1) return (float)0.5*(x-e)-(float)0.5; + if(k==1) { + if(x < (float)-0.25) return -(float)2.0*(e-(x+(float)0.5)); + else return one+(float)2.0*(x-e); + } + if (k <= -2 || k>56) { /* suffice to return exp(x)-1 */ + y = one-(e-x); + if (k == 128) y = y*2.0F*0x1p127F; + else y = y*twopk; + return y-one; + } + t = one; + if(k<23) { + SET_FLOAT_WORD(t,0x3f800000 - (0x1000000>>k)); /* t=1-2^-k */ + y = t-(e-x); + y = y*twopk; + } else { + SET_FLOAT_WORD(t,((0x7f-k)<<23)); /* 2^-k */ + y = x-(e+t); + y += one; + y = y*twopk; + } + } + return y; +} diff --git a/src/openlibm/src/s_expm1f.c.o b/src/openlibm/src/s_expm1f.c.o new file mode 100644 index 0000000000000000000000000000000000000000..a77f869ca0e2919da16e1fc325e440443954771d GIT binary patch literal 3832 zcmb<-^>JfjWMqH=Mg}_u1P><4z)-=BU^{@B4h(z@ybNjlbq6{Rss8`}zrOJi0|P^Y zt@Dnlj%69P;zb*s%H(Vr7#iyN+ufKL82DQnm>C%O^;to>`P-A385mkG@weP&WMKHr zFTe{DP2+!m=`(-C34Z;H{OwB2U1WdtaegRnsKk~xM9gGYN6Ko}lHrnyG*D^3L z*#7_j--y5M5yU{SI)04{2(6JfKJ!Oj=GS8@o>|kJEVEoJ< zb0UpD@6qKSodmt6f0G zfW3A2Gk?rsh&?eU_%)7ztZn?+zyM0#D;XFV()ja!eddq+!LM=rGk?sH!xLbh1o<13 zDyD*+1W65WYu^3)|DRtTWD3KMdIkmtO;Gr!@#p>c%pY+cWW{Ixh$En|h6OCL`ypOC z4Al=+eE_5b;!cSCXZ}cVxV2s?Jp&PsIPjT25*#cq1Hq{RlC}6XPQQ%%_y0dQv>EIf z7#Q|n{4T!z;&*X#28M?H4TT$>PJQw$v|hEtKEY`bZ$qJ>y@0`atBei~P+qrZU~q6? zU^w8wz|gRdfq~%w0|P@ngS)e{m4b%5U#O;np^2W6o}q$~fsv_!p`n3-Mo?;sf=6Nr zR6^HW6Jjw70|SEs0|Nudf$n~x3``7+2S8$==mDudM6%fP@O2xhQ?{Qzb{2{ACu z$^df{n9IPxAPr`)GJyODWL12Bysz@-QSD}x0>2+VQ@ldKFXU>ZSqf|;xg9AFwj_<@_JWP+Kj3@%_ALF6+qFbE;V zBRowM$EQ{lNF+>1_n^_`~#{X{{R0E2~P$FkT@t!z{Hb~)PwQ{Ogsxo zoQ;8j0VZCAB+iZ`J`0EVQY3LuT*Ax&75N}3kb6LR4kmsCB**}9Cl`|W7m&n3O$V6z z2T0hk-0VP%}{=HKBe`=4k~p$|41jRQEE=2UP)?234>lrVo4%{UQ%%} zgI-ZSh@+QWTw=nYmzJ=2_7o--IR5Iv+ zjZ4jlPb*5yO@&xaISKL?C@F%%7}+#f`3Nu9ppu|4gfhVtsJ;P}D=_t7K~Vc06nG2_ z3<=Qi1mz)+J)k@TQUfcm)j&-^Xqg2Phha&Op)d{-4Kf3X3$BMiWSD$2H|i91_n@2qohd&28J0>{pjujg%wC241?-1keTTEPY|geR9}FUqR0OOP+`Zw z0I!!p@ee8&VfMq~ADi7ExBUPa%D})N0CgCsj082v(e;DOM2~xrehyHeFfcHbfjCGQ WWFHb2+`hu5{|D6lmB@;*#1#M*K@05w literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_fabs.c b/src/openlibm/src/s_fabs.c new file mode 100644 index 0000000..43ffc1a --- /dev/null +++ b/src/openlibm/src/s_fabs.c @@ -0,0 +1,28 @@ +/* @(#)s_fabs.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * fabs(x) returns the absolute value of x. + */ + +#include + +#include "math_private.h" + +OLM_DLLEXPORT double +fabs(double x) +{ + u_int32_t high; + GET_HIGH_WORD(high,x); + SET_HIGH_WORD(x,high&0x7fffffff); + return x; +} diff --git a/src/openlibm/src/s_fabs.c.o b/src/openlibm/src/s_fabs.c.o new file mode 100644 index 0000000000000000000000000000000000000000..4ec566f055f9186f33ebb260a68270f06df5ee7b GIT binary patch literal 1232 zcmb<-^>JfjWMqH=Mg}_u1P><4z;FRc&;cy$z`(=6&5-87Uw6QRf7b{5G!Oo~1BV&h zot>=|G~E3{H5Cj^^o;Zj6^smwObrYT4HPtjQd1N>5=)>Gy5^b;3@i)`3lmSYPOzN}3?fjPu_}mxu|j}RnuncZ0wY9R1}Y~2rSVZ9^H~@^ z{>P?<8A}LoF)%O)A&JB7D2`7{Oe)q(W&lwTzktkSVqjnZVGtXP^@=NVOA?b9^omQ0 zAan+dRgzj!!l0LuSdz$~msDKLpqHGVo12ZNAHrxhjUrh;vvh>&Jr0Q-^+%@jzSGcdsY4V6ddD?;@%L*-#q z0E~e~gW>^MNS%R!frEj8fn5DMQ2Py#4P{_pfZ4B)CJwV7Mw>$QqbXykM;CzdVfvt4 z23H0K26ptgXJBAxfGR+D7s#(rDKHfawI3zzFfcG|0LwBk5YivP0LfFZ_=0L<2!J|N z0xAH?Pat=~?1zbil%d-V(((XAFfcGAKxt5Z0L2lyevr8!ai}sl + +#include "math_private.h" + +OLM_DLLEXPORT float +fabsf(float x) +{ + u_int32_t ix; + GET_FLOAT_WORD(ix,x); + SET_FLOAT_WORD(x,ix&0x7fffffff); + return x; +} diff --git a/src/openlibm/src/s_fabsf.c.o b/src/openlibm/src/s_fabsf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..9e29cf9b5bd8db6ea492f50d923de2f33db94b3e GIT binary patch literal 1240 zcmb<-^>JfjWMqH=Mg}_u1P><4z;FXe&;cy$z`(=6&5*`lcR=<3|Nr%A{CNisGq^iD zTPbL``-N&M7@FuA=@}{*85o%w7#bQVXauFED0n26KqYj|H9^L(FfcGEFfcH%GB7Z> z`-L(vF)$tgiNUO6gz`B-iWwLfM4&WdRS*MXg#e>84?D*MMu@l!RE`fyV5_40*Hc>=KGcbUC%Z6qOB<>j);Qoio3qWZYr3lr} z3=@FTeoz{n0>uZim^uRk0|x^G1G)Njp!ORe8_K}I0JC2oO&n%Fj5dYpM^na7i!K1= z!}LM946Y0e4D9G}&%nUY09AnQE|6cLQeY|;YClTaVPIg`0G4H7Af!Knfq?;(k6`fy z)y5D3b*KbX0FO3>N{(W7A&%RhSM}31L8mAshw<1^^jhO^E;i literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_fabsl.c b/src/openlibm/src/s_fabsl.c new file mode 100644 index 0000000..6bc1971 --- /dev/null +++ b/src/openlibm/src/s_fabsl.c @@ -0,0 +1,43 @@ +/*- + * Copyright (c) 2003 Dag-Erling Coïdan Smørgrav + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD: src/lib/msun/src/s_fabsl.c,v 1.2 2003/10/25 19:53:28 des Exp $ + */ + +#include +#include "math_private.h" +#include "fpmath.h" + +OLM_DLLEXPORT long double +fabsl(long double x) +{ + union IEEEl2bits u; + + u.e = x; + u.bits.sign = 0; + return (u.e); +} diff --git a/src/openlibm/src/s_fabsl.c.o b/src/openlibm/src/s_fabsl.c.o new file mode 100644 index 0000000000000000000000000000000000000000..d6d0d2ed3b52cec1086fa5a5f1621c14dbac61fc GIT binary patch literal 1248 zcmb<-^>JfjWMqH=Mg}_u1P><4!0-S`&;cy$z`(=6&2T$Mh2wUO%8P~+m5=qeb5vd& zW^i|Qwo=e=_Y2ijFf`FK(lb;rGB7eVFf=q!&*S zU|?WnU|?|f3uRzpU_1a4gUK^O`7mdQKqVNff*2Sp1Q?}x*f}OJGBAL|WuS6GP#PZv zGLMDf<9}>wn6ZQeHv1jRNoqw2gI-EvNg{(@QgJbZUUGhJZfaf$gI->KNvfW^U#M{~W8Qy^&o6c(rw0;pUD zMW}veH1QxbK8y>B4;ULnt1~b#a4;}1kgHz@YQF)*{qgUm&bJCGI+kiiTL41ypI c5{3%HML_b{^jAO?ro&Z27*Jsdhk=0s0K(!=iU0rr literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_fdim.c b/src/openlibm/src/s_fdim.c new file mode 100644 index 0000000..2f05347 --- /dev/null +++ b/src/openlibm/src/s_fdim.c @@ -0,0 +1,48 @@ +/*- + * Copyright (c) 2004 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_fdim.c,v 1.1 2004/06/30 07:04:01 das Exp $"); +#include +#include "math_private.h" + +#define DECL(type, fn) \ +OLM_DLLEXPORT type \ +fn(type x, type y) \ +{ \ + \ + if (isnan(x)) \ + return (x); \ + if (isnan(y)) \ + return (y); \ + return (x > y ? x - y : 0.0); \ +} + +DECL(double, fdim) +DECL(float, fdimf) +#ifdef OLM_LONG_DOUBLE +DECL(long double, fdiml) +#endif diff --git a/src/openlibm/src/s_fdim.c.o b/src/openlibm/src/s_fdim.c.o new file mode 100644 index 0000000000000000000000000000000000000000..49dc7f78ccb19dd462ce6ffe34883c16fd532822 GIT binary patch literal 2152 zcmb<-^>JfjWMqH=Mg}_u1P><4z@Wj3U^{@B4h*~uJPaPqZzMkP3;L*VeBu{mQF#H9 z`ou3FqSAVxL^zFKAu1ejkqIFCKZES&`OGf}Gx;-EQR{&cLAV28 z_J0Q1&jYvrGsu1(hTM`8(7 zLf2fAfrWvAL4kpR0ThkyexVFZ42%arVz9Vogz~w;vBbb20;L(Nf*2Sp1Q?}x*f}OJ zGB9W`FfhnKd#2^T&EH$DkRJ^>#tJ`P82WRW;7J`QK@ATB-*H|_wi zeIRYPFvy=Q3?KhvlV`?~;<*?Y7=)0-!G2|6VBlw9U=YA!h$vKj15^&|Uj_ySX&mZR zpz2{(fc?zCz@UXgJwtJPT1sZFUNQrSV#qAcOUwf^(-`98!MrpuHwVVefj9)_R#04n z@Spz>U=EQ6rwe59iAdsX3=9k~_1kfX^MV4FfdOm|D9&N(HF1c8(jdqvCI$uu5C*Y9 z*at*F#X#b)aI8QRhlLk|UU6k^Nn#R%UU5kggwBAmic)hD^-5AJN*MG~5=#;p^pc8; z8T69#b8}PkN*MI=@=H?n-2Fmzi%Sxdv!VR-yi&b_qWpr?qLNAmJ+KL>8S!aFiMgpz z7f?ol{0#~cP?#c{1Sv}y7%D-MND{Dkg9(As5h$Ku>S5v!m?5kQ5Q+hmZb3$Y;sPWj z0U{U}7}OXTz(EI94i#l!*a=b$=OGyA!a58L3?MVf)o%#3-vD6+m<6+6AIw7#F#BP& z6;wY$1%&kirU1f)ljy=;3=9nH(DVgY#K6D+(~s^hkYAD2B|+^6rA=gU38=shWIOxbw9MYfhdNC6`aGszyJV~Y$E&s literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_floor.c b/src/openlibm/src/s_floor.c new file mode 100644 index 0000000..4a44bd5 --- /dev/null +++ b/src/openlibm/src/s_floor.c @@ -0,0 +1,78 @@ +/* @(#)s_floor.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_floor.c,v 1.11 2008/02/15 07:01:40 bde Exp $"); + +/* + * floor(x) + * Return x rounded toward -inf to integral value + * Method: + * Bit twiddling. + * Exception: + * Inexact flag raised if x not equal to floor(x). + */ + +#include +#include + +#include "math_private.h" + +static const double huge = 1.0e300; + +OLM_DLLEXPORT double +floor(double x) +{ + int32_t i0,i1,j0; + u_int32_t i,j; + EXTRACT_WORDS(i0,i1,x); + j0 = ((i0>>20)&0x7ff)-0x3ff; + if(j0<20) { + if(j0<0) { /* raise inexact if x != 0 */ + if(huge+x>0.0) {/* return 0*sign(x) if |x|<1 */ + if(i0>=0) {i0=i1=0;} + else if(((i0&0x7fffffff)|i1)!=0) + { i0=0xbff00000;i1=0;} + } + } else { + i = (0x000fffff)>>j0; + if(((i0&i)|i1)==0) return x; /* x is integral */ + if(huge+x>0.0) { /* raise inexact flag */ + if(i0<0) i0 += (0x00100000)>>j0; + i0 &= (~i); i1=0; + } + } + } else if (j0>51) { + if(j0==0x400) return x+x; /* inf or NaN */ + else return x; /* x is integral */ + } else { + i = ((u_int32_t)(0xffffffff))>>(j0-20); + if((i1&i)==0) return x; /* x is integral */ + if(huge+x>0.0) { /* raise inexact flag */ + if(i0<0) { + if(j0==20) i0+=1; + else { + j = i1+(1<<(52-j0)); + if(jJfjWMqH=Mg}_u1P><4z_5cE!FB*M9T@l+cp1_>`0EaNbY5`myx?*0g+k}S z&f|`qhYtP}X?*yfoq?fuBjca{|C|2_*Qd39mMwWYduiO=eUc3K>(!Z@-IimLyq4sx*8sE={)bE zc-^J*fXBh-3Lc!t(>(a|&ZqHf96X#hq4}S2oixbk#(xYf3=E|&KJiDKc>O4iU%mxo zI78!0VHO4kkPH6*2Pt#B{L-=YV#z@a+ZVJRs7M0Yr+DJ^lr%kxZTC^X*v1%MS95$dOpqu3}6le1A`w_Cldn$ z11RbK`40hSaEO1wAr1;NkQB%q5C*ZqSg*J;wlBR;JtF*g-#Hx&qwzd&)rhGrHdZ!<8!!xt(K3V$dQOi439(iBWR zSdf8%;RZC2JfH%g_ypO*0p&|TX*Fot1H}zg2uy7NDF(Ap33Oo{1_lO@ndIs>gxW8J zY7GO-evsM7QZPP@wu9<7Kvu-SzyQv~3=9nVXyP#U!)SM?el%qa&tVGCB+!M!85kJY z85kI#!3|ga0;&+*T`+gU6y`(iN7pX_6(FQP3rGAbKqCYe&!G4Rl_@a$Vd5ZXLal;1 z2~2xH1uMWj1_mCeJ?Q#DW(1wguGCN)QJL Hqw5C%d1w + +#include "math_private.h" + +static const float huge = 1.0e30; + +OLM_DLLEXPORT float +floorf(float x) +{ + int32_t i0,j0; + u_int32_t i; + GET_FLOAT_WORD(i0,x); + j0 = ((i0>>23)&0xff)-0x7f; + if(j0<23) { + if(j0<0) { /* raise inexact if x != 0 */ + if(huge+x>(float)0.0) {/* return 0*sign(x) if |x|<1 */ + if(i0>=0) {i0=0;} + else if((i0&0x7fffffff)!=0) + { i0=0xbf800000;} + } + } else { + i = (0x007fffff)>>j0; + if((i0&i)==0) return x; /* x is integral */ + if(huge+x>(float)0.0) { /* raise inexact flag */ + if(i0<0) i0 += (0x00800000)>>j0; + i0 &= (~i); + } + } + } else { + if(j0==0x80) return x+x; /* inf or NaN */ + else return x; /* x is integral */ + } + SET_FLOAT_WORD(x,i0); + return x; +} diff --git a/src/openlibm/src/s_floorf.c.o b/src/openlibm/src/s_floorf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..0106771a80c81dd23cb679a691bc60ab2a217dfb GIT binary patch literal 1736 zcmb<-^>JfjWMqH=Mg}_u1P><4z~I4*U^{@B4h(z@ybNjlbq6{R9{efJzwKo6%lhV@ zV)ZtyCo4R5{r_LjaQRp3g%Z=x`~spN9cldUPk!c)xWKP}u}q=$Kqcos28ITP%l{ZZ ze7~f4D2+ew(BZTRjXxV07#K<%4)e={7!24nKjzms*m|Jy&S!oBR*=Cf|NsAAUwRhC zJv(npqea7!(*77(f=e`-L(vF)$tgiNV5%5z6O;C}$9X(u`F>42%^5 zjM6;p91|EBz~VAcxw%jp9|ba>h2i6WY-*UX#1IcyAu9t1m_`tSU?wXA$jx9Tln?{c zAYXwQa6+1afk6n#e7IYS0e?3=9mQB=hG# z1f<{)2S+jk0|Q7s$c-@d{YdITu7rt$;sPWEQV+r)HW=#_SLT)^CNbz0mlQ$h3>d2@ zH78N8B(8qlPJ86) zH-y?Rgls4S1H%I-ACkVI90mq>dItF!Bx(oMZvf&T;WtpWK9q)0F!#e~cc^}tJdBox zDS!z;X>{Rm1_lOpXgY=}0aFT4h3M{rg+Evk0|P@o)P87m!GswCh}5424HNYE-vBib z7SEvg2bEPY`(ffBYoJQuc7qrVAPEKrh7}+V0|Nsn9zbanT|dZ7^tcCU(SRDN1mYlJ XsIhPnP&tK7{|Tu6O1Mf016@A=L+rf= literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_floorl.c b/src/openlibm/src/s_floorl.c new file mode 100644 index 0000000..8427edb --- /dev/null +++ b/src/openlibm/src/s_floorl.c @@ -0,0 +1,102 @@ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + * + * From: @(#)s_floor.c 5.1 93/09/24 + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_floorl.c,v 1.8 2008/02/14 15:10:34 bde Exp $"); + +/* + * floorl(x) + * Return x rounded toward -inf to integral value + * Method: + * Bit twiddling. + * Exception: + * Inexact flag raised if x not equal to floorl(x). + */ + +#include +#include +#include + +#include "fpmath.h" +#include "math_private.h" + +#ifdef LDBL_IMPLICIT_NBIT +#define MANH_SIZE (LDBL_MANH_SIZE + 1) +#define INC_MANH(u, c) do { \ + uint64_t o = u.bits.manh; \ + u.bits.manh += (c); \ + if (u.bits.manh < o) \ + u.bits.exp++; \ +} while (0) +#else +#define MANH_SIZE LDBL_MANH_SIZE +#define INC_MANH(u, c) do { \ + uint64_t o = u.bits.manh; \ + u.bits.manh += (c); \ + if (u.bits.manh < o) { \ + u.bits.exp++; \ + u.bits.manh |= 1llu << (LDBL_MANH_SIZE - 1); \ + } \ +} while (0) +#endif + +static const long double huge = 1.0e300; + +OLM_DLLEXPORT long double +floorl(long double x) +{ + union IEEEl2bits u = { .e = x }; + int e = u.bits.exp - LDBL_MAX_EXP + 1; + + if (e < MANH_SIZE - 1) { + if (e < 0) { /* raise inexact if x != 0 */ + if (huge + x > 0.0) + if (u.bits.exp > 0 || + (u.bits.manh | u.bits.manl) != 0) + u.e = u.bits.sign ? -1.0 : 0.0; + } else { + uint64_t m = ((1llu << MANH_SIZE) - 1) >> (e + 1); + if (((u.bits.manh & m) | u.bits.manl) == 0) + return (x); /* x is integral */ + if (u.bits.sign) { +#ifdef LDBL_IMPLICIT_NBIT + if (e == 0) + u.bits.exp++; + else +#endif + INC_MANH(u, 1llu << (MANH_SIZE - e - 1)); + } + if (huge + x > 0.0) { /* raise inexact flag */ + u.bits.manh &= ~m; + u.bits.manl = 0; + } + } + } else if (e < LDBL_MANT_DIG - 1) { + uint64_t m = (uint64_t)-1 >> (64 - LDBL_MANT_DIG + e + 1); + if ((u.bits.manl & m) == 0) + return (x); /* x is integral */ + if (u.bits.sign) { + if (e == MANH_SIZE - 1) + INC_MANH(u, 1); + else { + uint64_t o = u.bits.manl; + u.bits.manl += 1llu << (LDBL_MANT_DIG - e - 1); + if (u.bits.manl < o) /* got a carry */ + INC_MANH(u, 1); + } + } + if (huge + x > 0.0) /* raise inexact flag */ + u.bits.manl &= ~m; + } + return (u.e); +} diff --git a/src/openlibm/src/s_floorl.c.o b/src/openlibm/src/s_floorl.c.o new file mode 100644 index 0000000000000000000000000000000000000000..7b2acef916279de657952356cbb0cfc03ffcd515 GIT binary patch literal 2064 zcmb<-^>JfjWMqH=Mg}_u1P><4z%YRY!FB*M9T@l+co}ZzsBqjoaJxq31^;#zl@FZ< z9Xk&+KKx(Lz>wzH_~3ti??lD}|Nl4tlB+Lmy~N*fmVtrc?hTLb8WoPlm;dY;820`D z|NlS85Rc36JUV}N{`WZeQo*tFq=({156++bEnA=(d{hKl-tu=mWnchXd50C`hMVth zp1l9@?u|0R@7IpIsJsA)xhS6NEKzxLJ4fZkVSagryEj0FH~+G$&-Lgof!XSD`~b*a zkIOGQKX!gsJm}GSvcwnUE~qufuv@e0`vt`xoh~XbUN7L6ZvolHaPt7FQ_A@uHXi1e zZvZLq=yp*NSP2S`QV|fF!=v+%$H7+$oEJ*&+`aLd31q2@ia^T~{*I3f3=B8l9Zuty zcVS@IDbK*bpm}i@C@wrMKXPF_)fuAl#^( z^uOMv(?{hE=Y_OR7nKh$umAi1pI_dAq4}45NwViokW)YkJ1=@(e(BSBit$rth{}u3 z>-^24|NsB@IQUMX`4}T8-1wVWKmrgA4G@bwlzmj*fNWr3@HqHL!GnL-D|rvjQyw4} zy}Syxhylfjga7{j_t*utv*G`L59JV*Hy$7p8{{1r7~nc*|NH-c!p#>q9~@?2V3>liYp%(_07{k$ z3=9mQ^x*Cn%D}|HcmN~@3OA4g7@>S-5Ql+*K?F)ORs}IIRtPXk^RRPFV1$UvK;>MS zpbR_|$b1%tkN>eLVaAe!c)$ult^_mSgdhV0gAkH>xZTC^X*v1%MLBxO40=A!Mhp-h zLnTxv$cZ37{Q;%p|Ns9#z#+~8awr1>1G;)pn1Qr_#6cLu24lVA%G{E~BnG|Wk|GG5 z0b>=V<|OKsq*jzL=%plbdHE%&dhULq zy2T}l$=OhTdS0nsK~a7|YEelggC5wp)QtGFqQu-(u-#N3K>h-GnGMY>NSVdJ01scN zya1GjQPK>MGzC)+6W;&|Yz77f52ye)0|PkLIG}t9D6Iw+hbo7PGBC8F1TtJ0YzBhI zz@WpxzyLCnT>XYn`-PAVWnf_FfZ7i-8(9j*htYOW{RYU27#J8PK=tdRiG#u#Bm|?~ zq545$$ap_gKe8Bz4bul=gK#(l0|PrWy@L2Kd;qE+-CZzu!_?(N?T0Fd2{U|v3J}tt zg(LodKqCYe&!G6{gvJ%f5|}v1KTxYc!f>nr)n5S>0hI@!ath{tn0}C%P^D0n5NZZg m5T*_y3Q2=7Hi!n5Cs3szE*uMhEMs7Rmme?*kb7Zl5DfrNW_|7e literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_fma.c b/src/openlibm/src/s_fma.c new file mode 100644 index 0000000..63e529e --- /dev/null +++ b/src/openlibm/src/s_fma.c @@ -0,0 +1,284 @@ +/*- + * Copyright (c) 2005-2011 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_fma.c,v 1.8 2011/10/21 06:30:43 das Exp $"); + +#include +#include +#include + +#include "math_private.h" + +/* + * A struct dd represents a floating-point number with twice the precision + * of a double. We maintain the invariant that "hi" stores the 53 high-order + * bits of the result. + */ +struct dd { + double hi; + double lo; +}; + +/* + * Compute a+b exactly, returning the exact result in a struct dd. We assume + * that both a and b are finite, but make no assumptions about their relative + * magnitudes. + */ +static inline struct dd +dd_add(double a, double b) +{ + struct dd ret; + double s; + + ret.hi = a + b; + s = ret.hi - a; + ret.lo = (a - (ret.hi - s)) + (b - s); + return (ret); +} + +/* + * Compute a+b, with a small tweak: The least significant bit of the + * result is adjusted into a sticky bit summarizing all the bits that + * were lost to rounding. This adjustment negates the effects of double + * rounding when the result is added to another number with a higher + * exponent. For an explanation of round and sticky bits, see any reference + * on FPU design, e.g., + * + * J. Coonen. An Implementation Guide to a Proposed Standard for + * Floating-Point Arithmetic. Computer, vol. 13, no. 1, Jan 1980. + */ +static inline double +add_adjusted(double a, double b) +{ + struct dd sum; + u_int64_t hibits, lobits; + + sum = dd_add(a, b); + if (sum.lo != 0) { + EXTRACT_WORD64(hibits, sum.hi); + if ((hibits & 1) == 0) { + /* hibits += (int)copysign(1.0, sum.hi * sum.lo) */ + EXTRACT_WORD64(lobits, sum.lo); + hibits += 1 - ((hibits ^ lobits) >> 62); + INSERT_WORD64(sum.hi, hibits); + } + } + return (sum.hi); +} + +/* + * Compute ldexp(a+b, scale) with a single rounding error. It is assumed + * that the result will be subnormal, and care is taken to ensure that + * double rounding does not occur. + */ +static inline double +add_and_denormalize(double a, double b, int scale) +{ + struct dd sum; + u_int64_t hibits, lobits; + int bits_lost; + + sum = dd_add(a, b); + + /* + * If we are losing at least two bits of accuracy to denormalization, + * then the first lost bit becomes a round bit, and we adjust the + * lowest bit of sum.hi to make it a sticky bit summarizing all the + * bits in sum.lo. With the sticky bit adjusted, the hardware will + * break any ties in the correct direction. + * + * If we are losing only one bit to denormalization, however, we must + * break the ties manually. + */ + if (sum.lo != 0) { + EXTRACT_WORD64(hibits, sum.hi); + bits_lost = -((int)(hibits >> 52) & 0x7ff) - scale + 1; + if ((bits_lost != 1) ^ (int)(hibits & 1)) { + /* hibits += (int)copysign(1.0, sum.hi * sum.lo) */ + EXTRACT_WORD64(lobits, sum.lo); + hibits += 1 - (((hibits ^ lobits) >> 62) & 2); + INSERT_WORD64(sum.hi, hibits); + } + } + return (ldexp(sum.hi, scale)); +} + +/* + * Compute a*b exactly, returning the exact result in a struct dd. We assume + * that both a and b are normalized, so no underflow or overflow will occur. + * The current rounding mode must be round-to-nearest. + */ +static inline struct dd +dd_mul(double a, double b) +{ + static const double split = 0x1p27 + 1.0; + struct dd ret; + double ha, hb, la, lb, p, q; + + p = a * split; + ha = a - p; + ha += p; + la = a - ha; + + p = b * split; + hb = b - p; + hb += p; + lb = b - hb; + + p = ha * hb; + q = ha * lb + la * hb; + + ret.hi = p + q; + ret.lo = p - ret.hi + q + la * lb; + return (ret); +} + +/* + * Fused multiply-add: Compute x * y + z with a single rounding error. + * + * We use scaling to avoid overflow/underflow, along with the + * canonical precision-doubling technique adapted from: + * + * Dekker, T. A Floating-Point Technique for Extending the + * Available Precision. Numer. Math. 18, 224-242 (1971). + * + * This algorithm is sensitive to the rounding precision. FPUs such + * as the i387 must be set in double-precision mode if variables are + * to be stored in FP registers in order to avoid incorrect results. + * This is the default on FreeBSD, but not on many other systems. + * + * Hardware instructions should be used on architectures that support it, + * since this implementation will likely be several times slower. + */ +OLM_DLLEXPORT double +fma(double x, double y, double z) +{ + double xs, ys, zs, adj; + struct dd xy, r; + int oround; + int ex, ey, ez; + int spread; + + /* + * Handle special cases. The order of operations and the particular + * return values here are crucial in handling special cases involving + * infinities, NaNs, overflows, and signed zeroes correctly. + */ + if (x == 0.0 || y == 0.0) + return (x * y + z); + if (z == 0.0) + return (x * y); + if (!isfinite(x) || !isfinite(y)) + return (x * y + z); + if (!isfinite(z)) + return (z); + + xs = frexp(x, &ex); + ys = frexp(y, &ey); + zs = frexp(z, &ez); + oround = fegetround(); + spread = ex + ey - ez; + + /* + * If x * y and z are many orders of magnitude apart, the scaling + * will overflow, so we handle these cases specially. Rounding + * modes other than FE_TONEAREST are painful. + */ + if (spread < -DBL_MANT_DIG) { + feraiseexcept(FE_INEXACT); + if (!isnormal(z)) + feraiseexcept(FE_UNDERFLOW); + switch (oround) { + case FE_TONEAREST: + return (z); + case FE_TOWARDZERO: + if ((x > 0.0) ^ (y < 0.0) ^ (z < 0.0)) + return (z); + else + return (nextafter(z, 0)); + case FE_DOWNWARD: + if ((x > 0.0) ^ (y < 0.0)) + return (z); + else + return (nextafter(z, -INFINITY)); + default: /* FE_UPWARD */ + if ((x > 0.0) ^ (y < 0.0)) + return (nextafter(z, INFINITY)); + else + return (z); + } + } + if (spread <= DBL_MANT_DIG * 2) + zs = ldexp(zs, -spread); + else + zs = copysign(DBL_MIN, zs); + + fesetround(FE_TONEAREST); + + /* + * Basic approach for round-to-nearest: + * + * (xy.hi, xy.lo) = x * y (exact) + * (r.hi, r.lo) = xy.hi + z (exact) + * adj = xy.lo + r.lo (inexact; low bit is sticky) + * result = r.hi + adj (correctly rounded) + */ + xy = dd_mul(xs, ys); + r = dd_add(xy.hi, zs); + + spread = ex + ey; + + if (r.hi == 0.0) { + /* + * When the addends cancel to 0, ensure that the result has + * the correct sign. + */ + fesetround(oround); + volatile double vzs = zs; /* XXX gcc CSE bug workaround */ + return (xy.hi + vzs + ldexp(xy.lo, spread)); + } + + if (oround != FE_TONEAREST) { + /* + * There is no need to worry about double rounding in directed + * rounding modes. + */ + fesetround(oround); + adj = r.lo + xy.lo; + return (ldexp(r.hi + adj, spread)); + } + + adj = add_adjusted(r.lo, xy.lo); + if (spread + ilogb(r.hi) > -1023) + return (ldexp(r.hi + adj, spread)); + else + return (add_and_denormalize(r.hi, adj, spread)); +} + +#if (LDBL_MANT_DIG == 53) +openlibm_weak_reference(fma, fmal); +#endif diff --git a/src/openlibm/src/s_fma.c.o b/src/openlibm/src/s_fma.c.o new file mode 100644 index 0000000000000000000000000000000000000000..7ba5b526ede0f64d3f0bc4b57200f1e99b363468 GIT binary patch literal 3728 zcmb<-^>JfjWMqH=Mg}_u1P><4z#zblU^{@B4h(z@ybNjl8aLAT-yhfo5=-OPyTL#E z0Ke;@mII}wY5aO8_-7yDcLDLz)A;o+R0)>yf8vk4nZ~bi_;4D(ybA+ED2N^G(flUj z6Te`Hiohp+K_3;4PyB*1Dlb4re&QF9QTfC#;G@FPdf*ekK!}P!sW!}vPy7*wJerS0 zM8_WHmu~?nXF!%Z%r6ge-@#A(f-zt-dEjR9fXs|Rm|3zWjbGys*m95)MBoZVkQMr< z2$b@H6u$0+*#~mIM{kXa%_n|AkfDMhDiUD(1YpkRQ31(2eBu{$QBg?a*8n-kM}-3> z9ik!ul6L{iYk&;@#4iZ7|7MMfN4JZLLwAje3$u%g4gdBS6_3tCkl^^lFA$?5p!qAU z@i7BW^RLtVJpxP&49&l?`1_wTGB9W!2iuUwukqk!jfz!TV~UE^|IasbRIK>d#i)2R zrl@%Qpa1_q|GE$rk5BvpH7W|9_yu@DVfcw(phQKZJ4eMKjbGz<8o$PM<{Xg!A`hnV zYrOl!A9?N*f6N6?*r)MpT>HcybMX^@%#Tm}5vS7lH7=y_Yux|DAM^4Pf8@na{E_EB z@kbv0#25hoyeA`YeTYh3)qA8|O1U*pav{s>UIc%8-FqF^@j+ z$GrK(A9Lgrf6UcS{1F#GsT7JoxKQeLKWhDgk0$^XPSA^f3J7aqyL$hvtPe z5B|Ippm+r*2kdE)@kJWH#^q1^5f^Ql{`~)6n~}z^@hFX7>fb6{F(Rsn+;0qJg|LhD5j4wJb@J~J1{D9HoV2Lb9`WTXvnjbMi zU3DRCLg#x>5&=i;OUA$d|EKY5ocP2qzzT{uuqY_PUvm8e$$;|Legy^w2Czp!={g3H z?nG4J27TfeKu_lUEgu;e7}6SlGqCWt_<%yT@izkxe+v(Y*?OD5<=Y>S4et-6@$28< zpMEHfU;iNg^aB=$_*?G$`Trl5l;Bpp4E^)}KPVmYZ+B6#YIyRQ^F~^yi;5LIJ$AdO zc<^t(eDD!-!;|@(7dk;)NYWHc0VmK96_3vMpa4f?k5Bv&EGjR5|0ZB^2*~8a2Olsu zJVP}(;wCsW4}-()<>uf2|L+%ogckOK2rLRJiNJ-@%X{EJ1_!|*ND$oMpAHI;gZ$GE z8lJE?#NT@1Hz<@eK&j~v#1>z$2v`$pxV0|%jV;_{fB*jvidzW&0A+uuhwwqpWnf}p zSm4Ou?(A%(pyBQps;OXTqGzOMs9ih;X67~~sA3!x$bJ@vk5GT2Dq_Y`GeO+P z${>NNlz|V-XJr6~5SR@iguxUm0|%H!5D@(!4y=K zPRq>8EJV8}@Uk(oL9=}8R9`3055ndx~9X{kktnZ>E870IauC15>y`9-;j zIShHJ6(xyjC8LCKUEN&E#!0BSF&DFjnr4pIaaM>eMeDh|>H@-s|*FH{^P#)D-3 zCM0oCEeunC07)E_reWezAOjc}K$)Kblxkt(%206-#gAlu1xNskJCEWJe~KiI>>h29 zWl(dF%@2Z#gZ#^eWN$Q79Aq4_dQjN|ieiv@5C*ZqSg*J;wlBR;JtF*g-#Hx&qwzd%U{6b8t~LE6j=46yP8CWl@= zNkhXHrXHp)1C(h%c^Mj5pfm`w2PzCN|I`>5z@-&5*}$|jEP=)YTmZ@dnE_>jDNy+Z zGLu~WhEV&3z@{OH6;S&@;e!xmfS1D{J3->0au4Jt0}uxZpMdJuM-l@uL28j{Q27WG z1Bt`%cc^|CA4a3A4QF6rV29=_m>LlM1F9e0T`+fp)PQh4)c??E0ttb!1~fqgfO!Z4 zU4Isi_^$vJE({Ftcm~BksQiQJhtyw?xJS1eWLpK){syRrL1hofpXmBQW}?SENdFIz jVg?2Vko!P<7={`L<1z>`Ffd@#KLP6gO1Mf016@A=3I<00 literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_fmaf.c b/src/openlibm/src/s_fmaf.c new file mode 100644 index 0000000..b3c8efb --- /dev/null +++ b/src/openlibm/src/s_fmaf.c @@ -0,0 +1,69 @@ +/*- + * Copyright (c) 2005-2011 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_fmaf.c,v 1.3 2011/10/15 04:16:58 das Exp $"); + +#include +#include + +#include "math_private.h" + +/* + * Fused multiply-add: Compute x * y + z with a single rounding error. + * + * A double has more than twice as much precision than a float, so + * direct double-precision arithmetic suffices, except where double + * rounding occurs. + */ +OLM_DLLEXPORT float +fmaf(float x, float y, float z) +{ + double xy, result; + u_int32_t hr, lr; + + xy = (double)x * y; + result = xy + z; + EXTRACT_WORDS(hr, lr, result); + /* Common case: The double precision result is fine. */ + if ((lr & 0x1fffffff) != 0x10000000 || /* not a halfway case */ + (hr & 0x7ff00000) == 0x7ff00000 || /* NaN */ + result - xy == z || /* exact */ + fegetround() != FE_TONEAREST) /* not round-to-nearest */ + return (result); + + /* + * If result is inexact, and exactly halfway between two float values, + * we need to adjust the low-order bit in the direction of the error. + */ + fesetround(FE_TOWARDZERO); + volatile double vxy = xy; /* XXX work around gcc CSE bug */ + double adjusted_result = vxy + z; + fesetround(FE_TONEAREST); + if (result == adjusted_result) + SET_LOW_WORD(adjusted_result, lr + 1); + return (adjusted_result); +} diff --git a/src/openlibm/src/s_fmaf.c.o b/src/openlibm/src/s_fmaf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..989c0802b6ae4627995fb9dfae1c0f368ac72607 GIT binary patch literal 1464 zcmb<-^>JfjWMqH=Mg}_u1P><4z_5b}!FB*M9T<2RxEVh4M;-XgA9eB*f8>eJ{85+E z_%#lF;*U6(=D}ZgsPlsA|NsBxZ5bFC1o&GIGB7ZBbYAc{_(I|Pg_R5pAL{vA)-o_K zr15Lq_{1M`GmT&GaupkY%S;9ahMP4iKfbxB{N&+p?SgQ>q&51ed|}|ZnWOTBe_f2q zk47Jr9}Ec$4E*atRDOKo7xV#<0$?)Y;>{YBPic)QDxdy;zL}%)38djmV~Wa`|MUO< z2Wj|{#;^ zP`R&A8XpBRpM~M$e{5=)vBWeN0|SE)k~rLs;`p@O#5BER1`q}D3&>1RvH)Qa8;tde zD|1T{lNj`hONtmbT2aEFmy%eL$e@>0T+E=CoS&PUnpeW0mzQ6Xs^{((s#{!= zn4Aser{|UG6%^$cq!yJ_GUyeh<|OK+X2hozCFZ7rZK8;fW?%sOk`2uiNZMv#fcqON zF94-slp<6=GfV(Vn}Pxy%0{Nph1D4t7&sUh7|7MH1GV1(*%Af@2AKW&XyP#YVYDe! zKbkUz6qo`u33Ops1_lOp1_lO{xMyHs$bc$DcNfU7$VSFO?MK%?gGl`m3=9mQ`~! + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_fmal.c,v 1.7 2011/10/21 06:30:43 das Exp $"); + +#include +#include +#include + +#include "fpmath.h" +#include "math_private.h" + +/* + * A struct dd represents a floating-point number with twice the precision + * of a long double. We maintain the invariant that "hi" stores the high-order + * bits of the result. + */ +struct dd { + long double hi; + long double lo; +}; + +/* + * Compute a+b exactly, returning the exact result in a struct dd. We assume + * that both a and b are finite, but make no assumptions about their relative + * magnitudes. + */ +static inline struct dd +dd_add(long double a, long double b) +{ + struct dd ret; + long double s; + + ret.hi = a + b; + s = ret.hi - a; + ret.lo = (a - (ret.hi - s)) + (b - s); + return (ret); +} + +/* + * Compute a+b, with a small tweak: The least significant bit of the + * result is adjusted into a sticky bit summarizing all the bits that + * were lost to rounding. This adjustment negates the effects of double + * rounding when the result is added to another number with a higher + * exponent. For an explanation of round and sticky bits, see any reference + * on FPU design, e.g., + * + * J. Coonen. An Implementation Guide to a Proposed Standard for + * Floating-Point Arithmetic. Computer, vol. 13, no. 1, Jan 1980. + */ +static inline long double +add_adjusted(long double a, long double b) +{ + struct dd sum; + union IEEEl2bits u; + + sum = dd_add(a, b); + if (sum.lo != 0) { + u.e = sum.hi; + if ((u.bits.manl & 1) == 0) + sum.hi = nextafterl(sum.hi, INFINITY * sum.lo); + } + return (sum.hi); +} + +/* + * Compute ldexp(a+b, scale) with a single rounding error. It is assumed + * that the result will be subnormal, and care is taken to ensure that + * double rounding does not occur. + */ +static inline long double +add_and_denormalize(long double a, long double b, int scale) +{ + struct dd sum; + int bits_lost; + union IEEEl2bits u; + + sum = dd_add(a, b); + + /* + * If we are losing at least two bits of accuracy to denormalization, + * then the first lost bit becomes a round bit, and we adjust the + * lowest bit of sum.hi to make it a sticky bit summarizing all the + * bits in sum.lo. With the sticky bit adjusted, the hardware will + * break any ties in the correct direction. + * + * If we are losing only one bit to denormalization, however, we must + * break the ties manually. + */ + if (sum.lo != 0) { + u.e = sum.hi; + bits_lost = -u.bits.exp - scale + 1; + if ((bits_lost != 1) ^ (int)(u.bits.manl & 1)) + sum.hi = nextafterl(sum.hi, INFINITY * sum.lo); + } + return (ldexp(sum.hi, scale)); +} + +/* + * Compute a*b exactly, returning the exact result in a struct dd. We assume + * that both a and b are normalized, so no underflow or overflow will occur. + * The current rounding mode must be round-to-nearest. + */ +static inline struct dd +dd_mul(long double a, long double b) +{ +#if LDBL_MANT_DIG == 64 + static const long double split = 0x1p32L + 1.0; +#elif LDBL_MANT_DIG == 113 + static const long double split = 0x1p57L + 1.0; +#endif + struct dd ret; + long double ha, hb, la, lb, p, q; + + p = a * split; + ha = a - p; + ha += p; + la = a - ha; + + p = b * split; + hb = b - p; + hb += p; + lb = b - hb; + + p = ha * hb; + q = ha * lb + la * hb; + + ret.hi = p + q; + ret.lo = p - ret.hi + q + la * lb; + return (ret); +} + +/* + * Fused multiply-add: Compute x * y + z with a single rounding error. + * + * We use scaling to avoid overflow/underflow, along with the + * canonical precision-doubling technique adapted from: + * + * Dekker, T. A Floating-Point Technique for Extending the + * Available Precision. Numer. Math. 18, 224-242 (1971). + */ +OLM_DLLEXPORT long double +fmal(long double x, long double y, long double z) +{ + long double xs, ys, zs, adj; + struct dd xy, r; + int oround; + int ex, ey, ez; + int spread; + + /* + * Handle special cases. The order of operations and the particular + * return values here are crucial in handling special cases involving + * infinities, NaNs, overflows, and signed zeroes correctly. + */ + if (x == 0.0 || y == 0.0) + return (x * y + z); + if (z == 0.0) + return (x * y); + if (!isfinite(x) || !isfinite(y)) + return (x * y + z); + if (!isfinite(z)) + return (z); + + xs = frexpl(x, &ex); + ys = frexpl(y, &ey); + zs = frexpl(z, &ez); + oround = fegetround(); + spread = ex + ey - ez; + + /* + * If x * y and z are many orders of magnitude apart, the scaling + * will overflow, so we handle these cases specially. Rounding + * modes other than FE_TONEAREST are painful. + */ + if (spread < -LDBL_MANT_DIG) { + feraiseexcept(FE_INEXACT); + if (!isnormal(z)) + feraiseexcept(FE_UNDERFLOW); + switch (oround) { + case FE_TONEAREST: + return (z); + case FE_TOWARDZERO: + if ((x > 0.0) ^ (y < 0.0) ^ (z < 0.0)) + return (z); + else + return (nextafterl(z, 0)); + case FE_DOWNWARD: + if ((x > 0.0) ^ (y < 0.0)) + return (z); + else + return (nextafterl(z, -INFINITY)); + default: /* FE_UPWARD */ + if ((x > 0.0) ^ (y < 0.0)) + return (nextafterl(z, INFINITY)); + else + return (z); + } + } + if (spread <= LDBL_MANT_DIG * 2) + zs = ldexpl(zs, -spread); + else + zs = copysignl(LDBL_MIN, zs); + + fesetround(FE_TONEAREST); + + /* + * Basic approach for round-to-nearest: + * + * (xy.hi, xy.lo) = x * y (exact) + * (r.hi, r.lo) = xy.hi + z (exact) + * adj = xy.lo + r.lo (inexact; low bit is sticky) + * result = r.hi + adj (correctly rounded) + */ + xy = dd_mul(xs, ys); + r = dd_add(xy.hi, zs); + + spread = ex + ey; + + if (r.hi == 0.0) { + /* + * When the addends cancel to 0, ensure that the result has + * the correct sign. + */ + fesetround(oround); + volatile long double vzs = zs; /* XXX gcc CSE bug workaround */ + return (xy.hi + vzs + ldexpl(xy.lo, spread)); + } + + if (oround != FE_TONEAREST) { + /* + * There is no need to worry about double rounding in directed + * rounding modes. + */ + fesetround(oround); + adj = r.lo + xy.lo; + return (ldexpl(r.hi + adj, spread)); + } + + adj = add_adjusted(r.lo, xy.lo); + if (spread + ilogbl(r.hi) > -16383) + return (ldexpl(r.hi + adj, spread)); + else + return (add_and_denormalize(r.hi, adj, spread)); +} diff --git a/src/openlibm/src/s_fmal.c.o b/src/openlibm/src/s_fmal.c.o new file mode 100644 index 0000000000000000000000000000000000000000..de9fbc2ffc89dbe829c18ef6b7bb2eef30c95bcf GIT binary patch literal 4080 zcmb<-^>JfjWMqH=Mg}_u1P><4z+k|GU^{@B4h;MZd<>zxK%8KY<~JU*F!A_N`r6bs1)3P$v^uLzYB=(eS3{c0|NuY{g-!dREd>}fTTT|k9b7K-aC1i zUmhgI;L-d>;O2qbHY&GkR0>{z%#Mu$8QglHROK~K+Jw6|UbFGbJ22e60n&Z%B-F@z z2O$O>zI)?;iAn_sgEc!wM?-X%T)2DV{}z=F1_lNw1(A<*gc+}T_r`0%yEk6*-o25Q zrpGVe0gw_=yp-D=&n(*VRlh5;oqL4;?Q|0&M`vsS6bs!2A<|$2l#uc85tNFe}Te?zu%pa z0US`8$8X!HfX#@GxLKp3l-8J{qV)gs%^Vda{&g`b28}5y2LI>(|IfcJM8)7PE678) zbyT`zR5X}lR8(#rxN+*{!5a_n9lZ1Mc8-d`ozpiD+<0>D$c@K058gO)^VE%#H_zNS zeecN4gEx-cd3E#Dy(9Nd-8^~k(9J_P4&FR);}J;jjn_9%-gtZO;LUe8Pu+fX_g0kv ze~S+j1H;`rcW>T2dGpk3ei#cHem4)?I1G;8wAQ!$t+tE|pqSKAx$*Eeh`9Ia-s^jZ z;D#}k2zYd}sH|Y*Z+Q(e^yX`(yEl;oUjgiSkmDIa=|SPn!J8*<9=Khjq7WHp%XHxX zfBqgFkQHD}o%dm(6%qCF?BD(g3|BJll;>U-T!#^2LJQ}7Kiv-`arUfc(PIXU!uYR##>ZoK$0zp0$T@m8`t0e z|L@+ud*kLwP~7uxcTrJlc=DO^MOvqeiV{2xbcd)I@NYkQ@Bwqfv-zACI$cx@z{vsR z-Ol^>4#L7D-ZA3kjz9nZgEN-EjfbE>z47qgtJ^v%_a1^H_~h-EcW+iPmAHeXz@cma zveZKLe?0>O;|-5)7Zm~isfU^$Fj^ccQM-Ba1}`XRJ(}MrfHDTm9$0R8&2jg}YnHn= zAog|Mzbm8iiC=&PlAJ&B3$m!(Wl?#l26oZi8#hnk^&`kr+pivc#N6-%*^eN*Zs&k< z-y4C>`}YprJc;6x92Eh_NXMvq2Vd_04f6PY0ay%!BJ-u$KRi*@`uO+%|2M%=^)le! z|Nqc(;^w>CA3-S}9IdbzJ^&KqpMKErgvBBL*15m`{|^YbZKLuZN4y&S{{J83PI&kU zfE1UgNc=BRkpM?OD1k%#bwuIin?L{mg95tYKLbNUJp%*C6CWHI+?}1R6g1rZLNyf( zP4tZP3>AzFj7$v-4Gk1Df>KiyJQ7Qw61wJ^3=Av`3=E(I4)T$^Unm0;1LFaZ7_2T} zgz~vTRxvOzh(Kw^svri&3IRrG9(Ilij0_BK7#J92pmJ>>!yNep+L+w zmoLEwED_6>;l!7az*pc6R?YO5uOJ!B3WN!T^A))ARXFiAFnaPO#DX=sfmJYtL9GFs z=*gGBhao2gOl9WerzhnwB0gU zrxuieHRk0P;k+pyq?>0ho9QR2-xY6c#Y?BB(e>j1S43N0G#l-6IQ9$iTpWZjLTg z97G|T69f`~x(Ae}VD@fD5=S=w5|TKwzy3qTLH2@jAIuyt5C>{Lvc0iTagchDR+#!i zs5nRrSv{x>1|=bodJqP&!C0@jGPfi#i9xTpqzFQ1z*t48If;5DsTCy*dMSw|i41y4 z#l;MIMfo6(UUG4X2{OlmK`%K!H#aq}gh4Maza&-9-7i$PxFj(-8_G}5E7dC~$}dPQ zDyd}91DlmdC1LuZT!s_|1_n_12aP6}FarlvKf1eM?uIF>f!dF* z-vX+i1Il(7Qp{x&EdMxpBm09Dc#L;wH) literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_fmax.c b/src/openlibm/src/s_fmax.c new file mode 100644 index 0000000..73919c6 --- /dev/null +++ b/src/openlibm/src/s_fmax.c @@ -0,0 +1,54 @@ +/*- + * Copyright (c) 2004 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_fmax.c,v 1.1 2004/06/30 07:04:01 das Exp $"); + +#include + +#include "fpmath.h" +#include "math_private.h" + +OLM_DLLEXPORT double +fmax(double x, double y) +{ + union IEEEd2bits u[2]; + + u[0].d = x; + u[1].d = y; + + /* Check for NaNs to avoid raising spurious exceptions. */ + if (u[0].bits.exp == 2047 && (u[0].bits.manh | u[0].bits.manl) != 0) + return (y); + if (u[1].bits.exp == 2047 && (u[1].bits.manh | u[1].bits.manl) != 0) + return (x); + + /* Handle comparisons of signed zeroes. */ + if (u[0].bits.sign != u[1].bits.sign) + return (u[u[0].bits.sign].d); + + return (x > y ? x : y); +} diff --git a/src/openlibm/src/s_fmax.c.o b/src/openlibm/src/s_fmax.c.o new file mode 100644 index 0000000000000000000000000000000000000000..3b6c40782a2cb39702610df45bcf8e49babe8acd GIT binary patch literal 1376 zcmb<-^>JfjWMqH=Mg}_u1P><4z>vU%U^{@B4h%dD+ze?R{B?)Y_%$wgbY4i~7rE$h z@Pz@tW{Ap*?-$ZmeyA_;2Prt^(Rl$R0Tm18-{zw7o_|}2%J%~=*bls7x42L${)s>S zAjq6FevLzi)Aab|Tfnw7KVbaCFA#F%1w?#8w~NY~G=7bXs{jAGbdHE%&dhULq zy2T}l$=OhTdS0nsK~a7|YEelggI-Z;PNH6FMtoXPVs0wfCW;7Y1_rP%+0aaZq(KG- zxWA$D0#F)8DMIx#!vvu8Jt&P%f#LyKOr3#&frEj8fn5DMQ2Py#4P{_pfZ4B)CJwV7 zMw>$QqbXzHg(*OjKo@ppU|?WpU|>LrdjH<_hKU@UDfC@u63=9l{SmGWe`2(sj9mGMxP+_ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_fmaxf.c,v 1.1 2004/06/30 07:04:01 das Exp $"); + +#include + +#include "fpmath.h" +#include "math_private.h" + +OLM_DLLEXPORT float +fmaxf(float x, float y) +{ + union IEEEf2bits u[2]; + + u[0].f = x; + u[1].f = y; + + /* Check for NaNs to avoid raising spurious exceptions. */ + if (u[0].bits.exp == 255 && u[0].bits.man != 0) + return (y); + if (u[1].bits.exp == 255 && u[1].bits.man != 0) + return (x); + + /* Handle comparisons of signed zeroes. */ + if (u[0].bits.sign != u[1].bits.sign) + return (u[u[0].bits.sign].f); + + return (x > y ? x : y); +} diff --git a/src/openlibm/src/s_fmaxf.c.o b/src/openlibm/src/s_fmaxf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..77277ae660a8c849ad81f2e55d06f00cc0ab75c7 GIT binary patch literal 1368 zcmb<-^>JfjWMqH=Mg}_u1P><4z!1TNU^{@B4h%dD+ze^_bqDx0E*yLzz%O#~`vrdC z5S1TkD;w%d+|u~#P8@t8@cjaq8^XWMMddgDwh)#72VSrrc*SmUp;VY(24+ zhYs`0w}4G;e!%#dUm&FA2SgBR{>7F5|JO5=UPCdnbPb5huWi9aTpjFxS(-_t{-GBdfb7u9DwQ<1aXisR2VJ-lE + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_fmaxl.c,v 1.1 2004/06/30 07:04:01 das Exp $"); + +#include + +#include "fpmath.h" +#include "math_private.h" + +OLM_DLLEXPORT long double +fmaxl(long double x, long double y) +{ + union IEEEl2bits u[2]; + + u[0].e = x; + mask_nbit_l(u[0]); + u[1].e = y; + mask_nbit_l(u[1]); + + /* Check for NaNs to avoid raising spurious exceptions. */ + if (u[0].bits.exp == 32767 && (u[0].bits.manh | u[0].bits.manl) != 0) + return (y); + if (u[1].bits.exp == 32767 && (u[1].bits.manh | u[1].bits.manl) != 0) + return (x); + + /* Handle comparisons of signed zeroes. */ + if (u[0].bits.sign != u[1].bits.sign) + return (u[0].bits.sign ? y : x); + + return (x > y ? x : y); +} diff --git a/src/openlibm/src/s_fmaxl.c.o b/src/openlibm/src/s_fmaxl.c.o new file mode 100644 index 0000000000000000000000000000000000000000..2421f05dc789a0351fed7d3e893f20290be6dead GIT binary patch literal 1400 zcmb<-^>JfjWMqH=Mg}_u1P><4z)-=2U^{@B4h%dD+zhvKR5(1kT~q|VU$|YPa^rT6 zip0$Ww`){hq^WNR1)0KeIE`Q4g#l!~1jvrtA8%c}d-L!FkM0l^4v)?Y9tU42sQ&-|zn=3# z=}Qz_O6P&pfHk42D``H=;O^{frJ&*N7pkdXXrgDNXQ*IgU}S1wXlS6I5tN#u;E`AY zmC!ZU1bLH%fq_ARfq{XQfq}u@FO-3af$;!H3>HR=P(CwAF#`jG2$W{53SwZa5MY$% zVdt2@2oaZo%B_Ra_$ZM1EDRt2V^hP7C5E^e7#M_*#Nl=n$EW2cR^;dZNAHrxhjUrh;vvh>&Jr0Q;5= z%@j!5WMF{%A1W^ZrD2pJR6i`eqqVZ-8tl0|Nuh zetk4?nEf!?6sjLh8G|fL0h$E5uqy)t13Lo)14`V3(mGTjy1PJrMK&@PYCpRE03!8A zFfcHH@)0b)U}pb->X(2Da6;V)vmYi7Qig6fNJ|4qf`Ne{0mNZoVBmtr5xRbmx#)2R f(((YRUl7DW!cbwj2uL2AegUYX(%~v040Qbf%oLw` literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_fmin.c b/src/openlibm/src/s_fmin.c new file mode 100644 index 0000000..9c52739 --- /dev/null +++ b/src/openlibm/src/s_fmin.c @@ -0,0 +1,54 @@ +/*- + * Copyright (c) 2004 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_fmin.c,v 1.1 2004/06/30 07:04:01 das Exp $"); + +#include + +#include "fpmath.h" +#include "math_private.h" + +OLM_DLLEXPORT double +fmin(double x, double y) +{ + union IEEEd2bits u[2]; + + u[0].d = x; + u[1].d = y; + + /* Check for NaNs to avoid raising spurious exceptions. */ + if (u[0].bits.exp == 2047 && (u[0].bits.manh | u[0].bits.manl) != 0) + return (y); + if (u[1].bits.exp == 2047 && (u[1].bits.manh | u[1].bits.manl) != 0) + return (x); + + /* Handle comparisons of signed zeroes. */ + if (u[0].bits.sign != u[1].bits.sign) + return (u[u[1].bits.sign].d); + + return (x < y ? x : y); +} diff --git a/src/openlibm/src/s_fmin.c.o b/src/openlibm/src/s_fmin.c.o new file mode 100644 index 0000000000000000000000000000000000000000..e572999124dfbe3bc9a9334a6694dc2ef5cbecfb GIT binary patch literal 1376 zcmb<-^>JfjWMqH=Mg}_u1P><4z>vU%U^{@B4h%dD+ze?R{B?)Y_%$wgbY4i~7rE$h z@Pz@tW{Ap*?-$ZmeyA_;2Prt^(Rl$R0Tm18-{zw7oqt=1%KHN^*bls7w>VTP{)s>K zAjq6FevLzi)Aab|Tfnw7KVbaCFA#F%1w?#8w~NY~G=7bXs{jAGbdHE%&dhULq zy2T}l$=OhTdS0nsK~a7|YEelggI-Z;PNH6FMtoXPVs0wfCW;7Y1_rP%+0aaZq(KG- zxWA$D0#F)8DMIx#!vvu8Jt&P%f#LyKOr3#&frEj8fn5DMQ2Py#4P{_pfZ4B)CJwV7 zMw>$QqbXzHg(*OjKo@ppU|?WpU|>LrdjH<_hKU@UDfC@u63=9l{SmGWe`2(sj9mGMxP+_ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_fminf.c,v 1.1 2004/06/30 07:04:01 das Exp $"); + +#include + +#include "fpmath.h" +#include "math_private.h" + +OLM_DLLEXPORT float +fminf(float x, float y) +{ + union IEEEf2bits u[2]; + + u[0].f = x; + u[1].f = y; + + /* Check for NaNs to avoid raising spurious exceptions. */ + if (u[0].bits.exp == 255 && u[0].bits.man != 0) + return (y); + if (u[1].bits.exp == 255 && u[1].bits.man != 0) + return (x); + + /* Handle comparisons of signed zeroes. */ + if (u[0].bits.sign != u[1].bits.sign) + return (u[u[1].bits.sign].f); + + return (x < y ? x : y); +} diff --git a/src/openlibm/src/s_fminf.c.o b/src/openlibm/src/s_fminf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..f03ad507215fd0bbbb39ed3e368afd97a9f41c6a GIT binary patch literal 1368 zcmb<-^>JfjWMqH=Mg}_u1P><4z!1TNU^{@B4h%dD+ze^_bqDx0E*yLzz%O#~`vrdC z5S1TkD;w%d+|u~#P8@t8@cjaq8^XWMMdd&Lwh)!y2VSrrc*SmUs8skff9yeijSKu5 zhYs`0w}4G;e!%#dUm&FA2SgBR{>7F5|JO5=UPCdnbPb5huWi9aTpjFxS(-_t{-GBdfb7u9DwQ<1aXisR2VJ-lE literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_fminl.c b/src/openlibm/src/s_fminl.c new file mode 100644 index 0000000..043886d --- /dev/null +++ b/src/openlibm/src/s_fminl.c @@ -0,0 +1,56 @@ +/*- + * Copyright (c) 2004 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_fminl.c,v 1.1 2004/06/30 07:04:01 das Exp $"); + +#include + +#include "fpmath.h" +#include "math_private.h" + +OLM_DLLEXPORT long double +fminl(long double x, long double y) +{ + union IEEEl2bits u[2]; + + u[0].e = x; + mask_nbit_l(u[0]); + u[1].e = y; + mask_nbit_l(u[1]); + + /* Check for NaNs to avoid raising spurious exceptions. */ + if (u[0].bits.exp == 32767 && (u[0].bits.manh | u[0].bits.manl) != 0) + return (y); + if (u[1].bits.exp == 32767 && (u[1].bits.manh | u[1].bits.manl) != 0) + return (x); + + /* Handle comparisons of signed zeroes. */ + if (u[0].bits.sign != u[1].bits.sign) + return (u[1].bits.sign ? y : x); + + return (x < y ? x : y); +} diff --git a/src/openlibm/src/s_fminl.c.o b/src/openlibm/src/s_fminl.c.o new file mode 100644 index 0000000000000000000000000000000000000000..3a23559e783fdcc567474e7570ce0a85e531a79f GIT binary patch literal 1400 zcmb<-^>JfjWMqH=Mg}_u1P><4z)-=2U^{@B4h%dD+zhvKR5(1kT~q|VU$|YPa^rT6 zip0$Ww`){hq^8+7DkLvJ~K!$0|SEylxD07VqmNgV3g)z z=a|3<5to6=t%K6|D3JLq3?KhvQ^SlUhPW9R7=)0-;dT_qr{!km<>)0dfN7X{AU}cF zplAhQ5F3p3iYs$V5|bG8ic5+hbOwx7l3G#1pqG+ZlE|Q!R9wuUmzJ=2_7o--IR5IulrRF5+rDnvZ6(#1Tf^DLRkY->2`<4yO z6iC`+V1WA{DlY(~VU!|NKP=v0;_qM#G#V5i$U^E23=A9$3=HJz*MZt^fNUrO0|U%{ zeKc{H{V>`Tsvk`mgDgw|ngqJAD+2=qI|Bm)O5B6eI#eOLyFh+LHZm4!Kf3+^BK1cw zFff4f5iGu7X8(Zdmw*azLfr|oA0`e`hHf`VO9M!Pfq@|b#9?4y;DW{xx_*$k=y3kP+_ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include +#include "math_private.h" +#include "fpmath.h" + +OLM_DLLEXPORT int +__fpclassifyd(double d) +{ + union IEEEd2bits u; + + u.d = d; + if (u.bits.exp == 2047) { + if (u.bits.manl == 0 && u.bits.manh == 0) { + return FP_INFINITE; + } else { + return FP_NAN; + } + } else if (u.bits.exp != 0) { + return FP_NORMAL; + } else if (u.bits.manl == 0 && u.bits.manh == 0) { + return FP_ZERO; + } else { + return FP_SUBNORMAL; + } +} + + +OLM_DLLEXPORT int +__fpclassifyf(float f) +{ + union IEEEf2bits u; + + u.f = f; + if (u.bits.exp == 255) { + if (u.bits.man == 0) { + return FP_INFINITE; + } else { + return FP_NAN; + } + } else if (u.bits.exp != 0) { + return FP_NORMAL; + } else if (u.bits.man == 0) { + return FP_ZERO; + } else { + return FP_SUBNORMAL; + } +} + +#ifdef OLM_LONG_DOUBLE +OLM_DLLEXPORT int +__fpclassifyl(long double e) +{ + union IEEEl2bits u; + + u.e = e; + mask_nbit_l(u); + if (u.bits.exp == 32767) { + if (u.bits.manl == 0 && u.bits.manh == 0) { + return FP_INFINITE; + } else { + return FP_NAN; + } + } else if (u.bits.exp != 0) { + return FP_NORMAL; + } else if (u.bits.manl == 0 && u.bits.manh == 0) { + return FP_ZERO; + } else { + return FP_SUBNORMAL; + } +} +#endif + diff --git a/src/openlibm/src/s_fpclassify.c.o b/src/openlibm/src/s_fpclassify.c.o new file mode 100644 index 0000000000000000000000000000000000000000..3c21a937cbc8642f2cf9c82f98dbf4efb5e554e3 GIT binary patch literal 1680 zcmb<-^>JfjWMqH=Mg}_u1P><4z%YRs!FB*M9T<2RxEazs`0EaNbYAc{_`)Df^+SD{ z?T7jjt(`0k3=CLq(|!o z{;3C>4>E$~TEMoX@z)*fJazDuKw9IYhWfO|Uk&vo$~z#&Un&)BeE9!=Jwx+PM#%%s z4>+0+a2)2BZvbiRJfRAf`N6mYDP0cG|(96p&N!4@r3)L+yNlea$^3(H5^$Lpe3sQ?pDjD>OQgagZQZwSy ziV}0-o`yPt3`&}T0UYXVXnG-emVrSO6p=`Bpm;*!GAKgzBV~86bSRoWupm?|j18jI z85kHqd4yd3pmYGT3YK0$W`Z!xeti%J34_#vxG>rji R2oFJOKn+bt2!UDX`T=W<(qjMs literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_frexp.c b/src/openlibm/src/s_frexp.c new file mode 100644 index 0000000..0385acf --- /dev/null +++ b/src/openlibm/src/s_frexp.c @@ -0,0 +1,56 @@ +/* @(#)s_frexp.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_frexp.c,v 1.11 2008/02/22 02:30:35 das Exp $"); + +/* + * for non-zero x + * x = frexp(arg,&exp); + * return a double fp quantity x such that 0.5 <= |x| <1.0 + * and the corresponding binary exponent "exp". That is + * arg = x*2^exp. + * If arg is inf, 0.0, or NaN, then frexp(arg,&exp) returns arg + * with *exp=0. + */ + +#include +#include + +#include "math_private.h" + +static const double +two54 = 1.80143985094819840000e+16; /* 0x43500000, 0x00000000 */ + +OLM_DLLEXPORT double +frexp(double x, int *eptr) +{ + int32_t hx, ix, lx; + EXTRACT_WORDS(hx,lx,x); + ix = 0x7fffffff&hx; + *eptr = 0; + if(ix>=0x7ff00000||((ix|lx)==0)) return x; /* 0,inf,nan */ + if (ix<0x00100000) { /* subnormal */ + x *= two54; + GET_HIGH_WORD(hx,x); + ix = hx&0x7fffffff; + *eptr = -54; + } + *eptr += (ix>>20)-1022; + hx = (hx&0x800fffff)|0x3fe00000; + SET_HIGH_WORD(x,hx); + return x; +} + +#if (LDBL_MANT_DIG == 53) +openlibm_weak_reference(frexp, frexpl); +#endif diff --git a/src/openlibm/src/s_frexp.c.o b/src/openlibm/src/s_frexp.c.o new file mode 100644 index 0000000000000000000000000000000000000000..8b515841da7fedd71f7ca66c95ef7a6e30722475 GIT binary patch literal 1560 zcmb<-^>JfjWMqH=Mg}_u1P><4z%YXe!FB*M9T@l+cp1_>`0EZGX9tORbYAc{_(Gxc zVB^F8|NqxF{`~*{eSNtV=cy92l?)6Y>Pw6}4;daf_*10u(f|Ma4ZSTKOn?6WZ#>1o z@W8&49c0h}kAsgCIuCeoUP$xc&pU9KU!LI;evx7+4q> z7!(*77(j-*`-L(vF)$tgiNXBN2<3A^EMO3U(u`F>42%^5jM6;p91|EBz~VAcxdteW zj{=#`!tn7wHZ{yxLY^C}5adcQ15OAqFfa%qsfXKL9G_N{T2Y{v%%JDvY`_5KFfcHr zKy`wmk(q&k;m>~v0EGca3M3A~AT}856<6k#BqlNF6_*r2=nNREC^aWhuOzjigh4MQ zu_Tc}FR8egL9Zwu#L-JGF0o+HOU}>DP0cG|(96p&N!4@r3)L+yNlea$^3(H5^$Lpe z3sQ?pDjD>^#-(P&rxhjUrh@IJ0s-MRgb$7(ix{tKSf6 zzYwya3=9k~`$1+SOTqXs+77DU09g?O1H%a@Umr@tD46?Uv^!KkOddvmhcVD-m_C?r zI0FL%s8m5olMDv5{3%HMFbfb7_jM=fI6xY Kt`fpP*AD>Flbk;Q literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_frexpf.c b/src/openlibm/src/s_frexpf.c new file mode 100644 index 0000000..fe63046 --- /dev/null +++ b/src/openlibm/src/s_frexpf.c @@ -0,0 +1,44 @@ +/* s_frexpf.c -- float version of s_frexp.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_frexpf.c,v 1.10 2008/02/22 02:30:35 das Exp $"); + +#include + +#include "math_private.h" + +static const float +two25 = 3.3554432000e+07; /* 0x4c000000 */ + +OLM_DLLEXPORT float +frexpf(float x, int *eptr) +{ + int32_t hx,ix; + GET_FLOAT_WORD(hx,x); + ix = 0x7fffffff&hx; + *eptr = 0; + if(ix>=0x7f800000||(ix==0)) return x; /* 0,inf,nan */ + if (ix<0x00800000) { /* subnormal */ + x *= two25; + GET_FLOAT_WORD(hx,x); + ix = hx&0x7fffffff; + *eptr = -25; + } + *eptr += (ix>>23)-126; + hx = (hx&0x807fffff)|0x3f000000; + SET_FLOAT_WORD(x,hx); + return x; +} diff --git a/src/openlibm/src/s_frexpf.c.o b/src/openlibm/src/s_frexpf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..ac3323afaa8eb510eb282d3022d703d1d3923f3b GIT binary patch literal 1536 zcmb<-^>JfjWMqH=Mg}_u1P><4z|g>iU^{@B4h(z@ybNjlbq6{RH9q?P|9^e2*Z;=|G~E3{H5Cj^^o;Zj6^smwObrYT4HPtj zQd1N>5=)>Gy5^c7Ees4S3=9kk3=9k)OWgfJ8JHLt4}ipAeq@C5IU&j!M4&WdRS*MX zg#e>84?D*MMh39B3{);1O5>wI=Cd$-{EtlyGnNqM0V@Q#63l=Tf(#4{LP+Z2b{EH| z6{S`br0FFy==nGsFhF<=E>NAI=wfDIVEFSN0zhE^k^+f?Fo+Gtdc~EwC5cH4dc`G0 z5IO_KDoV{s)GJA?C}Ge`Ni0cZ&`T;VX3#6j2XXY0i%U!x^pf*)b5rw581(Y;OH%dR z{X%t%OA?c_q5Sl`QoVwr{DRb?l1c_WuyLsw@o7bgxv5~gsX&1I1qy36G_xRSlz{;r zUQl@fC=H{e86ar{rXD7K0c0ox1A_!qfSZ8<919#!K1^H*3s1%r54kj@PsIhPf z9R>ylkeTG_H-y?R1UC`FSOKBH=^x4jQ=qgDV!&uSsD1;GAQD~!W$Qy}7zJ}bjCP0W zhsnd}+b{+i4buk`4rgFs0A+EMG|9lg@Bpd+-Cdxtf=Yp@e5n2C`URjC5z?Q9BmQ4N z^~2&B6#t+y0%ku<9Hb20Zji$qKoSfL3>6>_0|Nsne}lptT|dZ7^tcCU*#XrLvj-#w Z!cbul6O2LS12+8(P)AjQRUrs;{Qx|LiJJfb literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_frexpl.c b/src/openlibm/src/s_frexpl.c new file mode 100644 index 0000000..ed2d28b --- /dev/null +++ b/src/openlibm/src/s_frexpl.c @@ -0,0 +1,63 @@ +/*- + * Copyright (c) 2004-2005 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/msun/src/s_frexpl.c,v 1.1 2005/03/07 04:54:51 das Exp $ + */ + +#include +#include + +#include "fpmath.h" +#include "math_private.h" + +#if LDBL_MAX_EXP != 0x4000 +#error "Unsupported long double format" +#endif + +OLM_DLLEXPORT long double +frexpl(long double x, int *ex) +{ + union IEEEl2bits u; + + u.e = x; + switch (u.bits.exp) { + case 0: /* 0 or subnormal */ + if ((u.bits.manl | u.bits.manh) == 0) { + *ex = 0; + } else { + u.e *= 0x1.0p514; + *ex = u.bits.exp - 0x4200; + u.bits.exp = 0x3ffe; + } + break; + case 0x7fff: /* infinity or NaN; value of *ex is unspecified */ + break; + default: /* normal */ + *ex = u.bits.exp - 0x3ffe; + u.bits.exp = 0x3ffe; + break; + } + return (u.e); +} diff --git a/src/openlibm/src/s_frexpl.c.o b/src/openlibm/src/s_frexpl.c.o new file mode 100644 index 0000000000000000000000000000000000000000..88aacce095376d99daeabbbdf2c042c7a90de0cb GIT binary patch literal 1568 zcmb<-^>JfjWMqH=Mg}_u1P><4z_5S`!FB*M9T@l+co}ZzsBqk_QF+0?-9_a?=b^O5 zNB`?fw9*=X{jV>v{}whJ#E!43-D6?(l-e5Vn9UVPI%{#o)xi@Om*w5{d;97~Gwm ztrRre{X#Vr3{CWm^b8e@42(<-3=ItwG=fr76g(13pc1;~nhXpq3=9kk3=9mc3=9nJ zexVFZ42%arVo(Da7@>Svn210n7^{L97%K!ArFqynCNMHEfW&2>a?Ma09|baxh2i6W zY-*UX!~hRiA;^_r2AmLNU|I6k6GXn#| zpZ^d53ImW7NF0PgY%ta(diAg|>g-hr#Fff43Bv-#7)P5nji4evK2n9A9$^=s& zyFd&WZ3oqF01`yP7oco?C=H`v?uXItQ2j7@82ul{K%-&$V8Y=H3=E(m0VPd>B%un? z-34 +#include + +#include "math_private.h" + +OLM_DLLEXPORT int +ilogb(double x) +{ + int32_t hx,lx,ix; + + EXTRACT_WORDS(hx,lx,x); + hx &= 0x7fffffff; + if(hx<0x00100000) { + if((hx|lx)==0) + return FP_ILOGB0; + else /* subnormal x */ + if(hx==0) { + for (ix = -1043; lx>0; lx<<=1) ix -=1; + } else { + for (ix = -1022,hx<<=11; hx>0; hx<<=1) ix -=1; + } + return ix; + } + else if (hx<0x7ff00000) return (hx>>20)-1023; + else if (hx>0x7ff00000 || lx!=0) return FP_ILOGBNAN; + else return INT_MAX; +} diff --git a/src/openlibm/src/s_ilogb.c.o b/src/openlibm/src/s_ilogb.c.o new file mode 100644 index 0000000000000000000000000000000000000000..107451c99d36c36f9d1adfda8b1673cb52572e02 GIT binary patch literal 1368 zcmb<-^>JfjWMqH=Mg}_u1P><4z!1TNU^{@B4h%dD+ze?R{B;LBIuCjre5ufRs`1hP z|Nra1A7o(oP+w}&d5!Z}Nk;3XQm@tnoriY3{r&%cU3^-a9>07G*aUug2L{GV%`X^R zFV%lPoW?Kj!objZ;ouJu-T%xC42{1)rtAV4$nSjUFu!~QNYlYb+&h^5{QnO#1EGHh zBLhRj;lm8>&dyc}8t#6fnhJ&{dPaJN3PuJ-rUr(F1_~NMsVNE`i6u}8U2{za76t|e z1qKENRt5$JcfU{uCI-d>ATd}NFhcp9Aj=sT7(}2nV^t6XV}$^tG!Hw+1V)Is3{-9+ zl*UJa%x7Wv_#c}ZW-Kwl&A`AQgd`5Pqc}b@CqF$&FPQ;M!^{Ku3B(3P8wi8gV60bM znOl;W#GqGPQUswhV62kViV_CBl*E!m2EC->Vg|kB{M_8syb=bzy!?_>J$JuQ-QtqO z +#include + +#include "math_private.h" + +OLM_DLLEXPORT int +ilogbf(float x) +{ + int32_t hx,ix; + + GET_FLOAT_WORD(hx,x); + hx &= 0x7fffffff; + if(hx<0x00800000) { + if(hx==0) + return FP_ILOGB0; + else /* subnormal x */ + for (ix = -126,hx<<=8; hx>0; hx<<=1) ix -=1; + return ix; + } + else if (hx<0x7f800000) return (hx>>23)-127; + else if (hx>0x7f800000) return FP_ILOGBNAN; + else return INT_MAX; +} diff --git a/src/openlibm/src/s_ilogbf.c.o b/src/openlibm/src/s_ilogbf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..0beb4694c73f7213083513a3e3a8f70643668ce4 GIT binary patch literal 1304 zcmb<-^>JfjWMqH=Mg}_u1P><4z#zedU^{@B4h%dD+ze^_b%#1HsQ&-|zrOJi14Bc7 zsch?k62pTJICeGt|NnmiP?<8A}NAFfcF(A&JB7D2~s}$xly8(@SQ6Fd!y^`~+fwf*piG zY%taWg(FmNz1Fp#TX2Wr0ovY`wN3^4ok(Zpf) z!)Q~eel%qa`_KiTe3(8cm%){Rfq|WYfdM7%85kH2Koy|73*=X*6qt&I+K;aP16Y=U zfsp +#include +#include + +#include "fpmath.h" +#include "math_private.h" + +OLM_DLLEXPORT int +ilogbl(long double x) +{ + union IEEEl2bits u; + unsigned long m; + int b; + + u.e = x; + if (u.bits.exp == 0) { + if ((u.bits.manl | u.bits.manh) == 0) + return (FP_ILOGB0); + /* denormalized */ + if (u.bits.manh == 0) { + m = 1lu << (LDBL_MANL_SIZE - 1); + for (b = LDBL_MANH_SIZE; !(u.bits.manl & m); m >>= 1) + b++; + } else { + m = 1lu << (LDBL_MANH_SIZE - 1); + for (b = 0; !(u.bits.manh & m); m >>= 1) + b++; + } +#ifdef LDBL_IMPLICIT_NBIT + b++; +#endif + return (LDBL_MIN_EXP - b - 1); + } else if (u.bits.exp < (LDBL_MAX_EXP << 1) - 1) + return (u.bits.exp - LDBL_MAX_EXP + 1); + else if (u.bits.manl != 0 || u.bits.manh != 0) + return (FP_ILOGBNAN); + else + return (INT_MAX); +} diff --git a/src/openlibm/src/s_ilogbl.c.o b/src/openlibm/src/s_ilogbl.c.o new file mode 100644 index 0000000000000000000000000000000000000000..755cd2264f6a50e459d349c62482d2bd499f35e6 GIT binary patch literal 1408 zcmb<-^>JfjWMqH=Mg}_u1P><4z|g>iU^{@B4h%dD+zj0zDgqweE-D-zofkbiT~uCl zhNyfzSPE}^I+#OkAp82IM0=Mx1KBs?mW2*q;&@a14BbaDZji61B1uK7tMzl zJz7tceBHrx;QxQk3x~ntJO2OwU!T_a^M8GbDF1dBl@F@_>lqky|JyS#9Nxjmz|e3w z4Xm#7VC#VjrCkaP3=CjnahmsN|NsAo(};i=;qDizsbFZLXQXGSU}Ruq zYG7z+pr8?ynxf#5SOS&MHP-~WnT3IY0b~g)0|SG*Unm0;1LFaZ7)TC;8KHbw*olAy z85kHCtAZF9D+Cy&dDuB7FfuTJ#ATpz+n_W)3S=G&!^i*F)G%X-DINv}1|cMIxE;mu znK}9CNjZAS3=jsyM3A3AEKu} z0|P?>gv-DMjU#mZAal{<4y5G;RKGBYgM^{Na1lYMxo`m}LjvlkbSNK2q3Z_#PrRCH literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_isfinite.c b/src/openlibm/src/s_isfinite.c new file mode 100644 index 0000000..7c11876 --- /dev/null +++ b/src/openlibm/src/s_isfinite.c @@ -0,0 +1,61 @@ +/*- + * Copyright (c) 2004 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/msun/src/s_isfinite.c,v 1.1 2004/07/09 03:32:39 das Exp $ + */ + +#include + +#include "fpmath.h" +#include "math_private.h" + +OLM_DLLEXPORT int +__isfinite(double d) +{ + union IEEEd2bits u; + + u.d = d; + return (u.bits.exp != 2047); +} + +OLM_DLLEXPORT int +__isfinitef(float f) +{ + union IEEEf2bits u; + + u.f = f; + return (u.bits.exp != 255); +} + +#ifdef OLM_LONG_DOUBLE +OLM_DLLEXPORT int +__isfinitel(long double e) +{ + union IEEEl2bits u; + + u.e = e; + return (u.bits.exp != 32767); +} +#endif diff --git a/src/openlibm/src/s_isfinite.c.o b/src/openlibm/src/s_isfinite.c.o new file mode 100644 index 0000000000000000000000000000000000000000..715a40105cd65cce00ea5a522fce8ecf79ececc8 GIT binary patch literal 1480 zcmb<-^>JfjWMqH=Mg}_u1P><4z;J>I!FB*M9T<2RxEazs`0EaM9DHH${X*Kx5B2<0 z5Abh0a5znmU%mybDviJHz`+*+AlU}EEJAt$|8^G@uP(CMAg9wyntO{aatPo(7=3(cUz{tQLz`(#D1Cy2^M7u!6grGD& z3giwJhL8WTsbR(v;(QDY3_?iaFt^72bk_1yhJb&E?9le3}x z^t@8Nf};F_)S{9~2EC%xoJ76UjQF&o#N1S<f(D(drBg3>*v$4CLz9f!YsCryw&y7-qjdh=YV-_QPmXsD30R zVCF$EiAlip!DL(+7#P^0=>jGOqECPb1_lOncY*v0l>$?-Q2Rk?3M>F6en9C6C=H{~ z^@HR=`5hKtFm)1817YbCl>b5Qgz1-nDg^llsuU^$p#ne>3=9ktAY2A6XdI#I2bqf= jcOWefp!y9#93%`ChKmS7&4mj<83|BFr9=5J3SB<{YRh`q literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_isinf.c b/src/openlibm/src/s_isinf.c new file mode 100644 index 0000000..02eaff3 --- /dev/null +++ b/src/openlibm/src/s_isinf.c @@ -0,0 +1,66 @@ +/*- + * Copyright (c) 2004 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include + +#include "fpmath.h" +#include "math_private.h" + +/* Provided by libc */ +#if 1 +OLM_DLLEXPORT int +(isinf) (double d) +{ + union IEEEd2bits u; + + u.d = d; + return (u.bits.exp == 2047 && u.bits.manl == 0 && u.bits.manh == 0); +} +#endif + +OLM_DLLEXPORT int +__isinff(float f) +{ + union IEEEf2bits u; + + u.f = f; + return (u.bits.exp == 255 && u.bits.man == 0); +} + +#ifdef OLM_LONG_DOUBLE +OLM_DLLEXPORT int +__isinfl(long double e) +{ + union IEEEl2bits u; + + u.e = e; + mask_nbit_l(u); + return (u.bits.exp == 32767 && u.bits.manl == 0 && u.bits.manh == 0); +} +#endif + +openlibm_weak_reference(__isinff, isinff); diff --git a/src/openlibm/src/s_isinf.c.o b/src/openlibm/src/s_isinf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..405646e231adc7d3cc6ad8c30a62804db35776de GIT binary patch literal 1528 zcmb<-^>JfjWMqH=Mg}_u1P><4!0>|!!FB*M9T<2RxEVZlfjJBx>eD><>kfGE@A_cx zVR?an$^rgu2M(uANaL?Np!)y+|9V>nhK72WaGD;!d<$5kM|X${N4JlPfJf&AkIoR4 z7lxNS4!%(6^ilZ$*4F8w^2Vd{#P*UAOB-h!;B?nco`TNlo%Mnegf%%*~`tqz#xQ09ONF5I7lrB!`vV5_40bmQz4UGcbT- zgAL6Lm_KUK#6f8TSx6D8pBY(@fq`K!8Xv|5r3)AvM5{9}FmNz1Fp#TX2Wmeoy@JdH zVVM2;APy3S*$<;lq56@OfSGT=BqjmV2a|DSU|?W}#y?C9M1KGg3=9nD?gIH0Dg~xu zq4tB)6j%UCC_pWWfbwA!x_*#6DBr{43#QHkY9K6qg31AqJ7M}IpbA0OK$Sv8AXEiN zf`Nfy1%%7M1&t$g{UCGE;|`=n0cxl+h=YWo#==Deq2|H`po|Gn{pnCXj6&BB09^%$ Au>b%7 literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_isnan.c b/src/openlibm/src/s_isnan.c new file mode 100644 index 0000000..b9066aa --- /dev/null +++ b/src/openlibm/src/s_isnan.c @@ -0,0 +1,67 @@ +/*- + * Copyright (c) 2004 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/msun/src/s_isnan.c,v 1.9 2010/06/12 17:32:05 das Exp $ + */ + +#include + +#include "fpmath.h" +#include "math_private.h" + +/* Provided by libc */ +#if 1 +OLM_DLLEXPORT int +(isnan) (double d) +{ + union IEEEd2bits u; + + u.d = d; + return (u.bits.exp == 2047 && (u.bits.manl != 0 || u.bits.manh != 0)); +} +#endif + +OLM_DLLEXPORT int +__isnanf(float f) +{ + union IEEEf2bits u; + + u.f = f; + return (u.bits.exp == 255 && u.bits.man != 0); +} + +#ifdef OLM_LONG_DOUBLE +OLM_DLLEXPORT int +__isnanl(long double e) +{ + union IEEEl2bits u; + + u.e = e; + mask_nbit_l(u); + return (u.bits.exp == 32767 && (u.bits.manl != 0 || u.bits.manh != 0)); +} +#endif + +openlibm_weak_reference(__isnanf, isnanf); diff --git a/src/openlibm/src/s_isnan.c.o b/src/openlibm/src/s_isnan.c.o new file mode 100644 index 0000000000000000000000000000000000000000..4287a8c9e391eabd5a65a831b4586ee1839729d3 GIT binary patch literal 1560 zcmb<-^>JfjWMqH=Mg}_u1P><4z#zelU^{@B4h%dD+ze?R{B?&6PkMA-@HqIw;QNKN zl^^O$g*DZ7x^yOpU*3g*Aq}j&^TNRw0wBc=^`+c~CmSFA|6k7l zQI(da$1mRkwt-*Xfx)9YM1`Z!T%+=Wfq&|u&I^Yb+?}1R6g1rZLNyf(P4tZP3>AzFj7$v-4Gk1Df>Kiy zJQ7Qw61wJ^U^`hD7#I{77#LU?7#Q6BLK&DC7!QENU}3@t<#U2nGcbriX~wD`2F3~j zMrj^)jtPtm3<3-c3^GtTZ72;AGk~%cp)^Rp3zTgOrSVZ9cd#&g{EtlyGnSa+Wnf@X zVqj!Ix0joNfk6n1ILJL9ahUlqw@X3QCqO0OZY_?_EY3^J(@SQEhp^HZzydIC4nzYe zOhGIr1_lNY2C+fd1Vli^K;kfWdZ3BJ>}Aj^uFNe-Ok&V0E-8Z088B8!YDEcyUP@v~ zB7DnU9{|6Mobdnv literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_isnormal.c b/src/openlibm/src/s_isnormal.c new file mode 100644 index 0000000..3c721d7 --- /dev/null +++ b/src/openlibm/src/s_isnormal.c @@ -0,0 +1,61 @@ +/*- + * Copyright (c) 2004 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/msun/src/s_isnormal.c,v 1.1 2004/07/09 03:32:39 das Exp $ + */ + +#include + +#include "fpmath.h" +#include "math_private.h" + +OLM_DLLEXPORT int +__isnormal(double d) +{ + union IEEEd2bits u; + + u.d = d; + return (u.bits.exp != 0 && u.bits.exp != 2047); +} + +OLM_DLLEXPORT int +__isnormalf(float f) +{ + union IEEEf2bits u; + + u.f = f; + return (u.bits.exp != 0 && u.bits.exp != 255); +} + +#ifdef OLM_LONG_DOUBLE +OLM_DLLEXPORT int +__isnormall(long double e) +{ + union IEEEl2bits u; + + u.e = e; + return (u.bits.exp != 0 && u.bits.exp != 32767); +} +#endif diff --git a/src/openlibm/src/s_isnormal.c.o b/src/openlibm/src/s_isnormal.c.o new file mode 100644 index 0000000000000000000000000000000000000000..29748dc64246f75a6e51fa100d81748fb86e2f40 GIT binary patch literal 1480 zcmb<-^>JfjWMqH=Mg}_u1P><4z;J>I!FB*M9T<2RxEazs`0EaM9DHGrruw0tf9jz$ zTM%`Cf7=1Y3y1mT8PfRc4jg};i= z;qDizsbFZLXQXGSU}RuqYG7z+pr8?ynxf#5SOS&MHP>WdVPIfTU|?WiWnf@%_X}lU zVqiP~5`+1L5z6NTyPbhS1WGej1u-yI2rx?XuyagcWMB|rU|^7e%E>}$keC6KEe)kX z`dy%GNhpnv0=a{Q;p2a7YM8NvI3EK8gAkH9%q<|hK;j_3g3N-sM-{3b5;qJCAax*l zhT{0l;=KH#+{7HcWQKS+2Z@=6#LfZhfrcfB4T^RU2C+fd1Vk_}Fo48B80HQSG;x?a z81#xOb4wDF81#xuiXe0bj8&3aQNo~?l30?+pqEr!%%GQ?pPQSSSHhr|mtT^q=k6D( zTU?TuoDJot=auRe6y+DB7L`;o=oO{rBW58@zU znEf!?6sjLd37B~TOkxr+eJ~kU1_lOpXu5!jfoPb1ba#RL3X+H6Sg8G=GzAj_(LX>0 z0|P?@l!j60`a$xb{0@sRm^ullfw1%m%KspD!t_f(6@vT&RSFe>Pyrwb1_p)+5H153 rG>*{qgUm&bJCK$KQ2mA=4ibh6!$kz4=E4P_j0C8o(xH49g{~g}#5#Ut literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_llrint.c b/src/openlibm/src/s_llrint.c new file mode 100644 index 0000000..dcd6aed --- /dev/null +++ b/src/openlibm/src/s_llrint.c @@ -0,0 +1,9 @@ +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_llrint.c,v 1.1 2005/01/11 23:12:55 das Exp $"); + +#define type double +#define roundit rint +#define dtype long long +#define fn llrint + +#include "s_lrint.c" diff --git a/src/openlibm/src/s_llrintf.c b/src/openlibm/src/s_llrintf.c new file mode 100644 index 0000000..81ae8f0 --- /dev/null +++ b/src/openlibm/src/s_llrintf.c @@ -0,0 +1,9 @@ +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_llrintf.c,v 1.1 2005/01/11 23:12:55 das Exp $"); + +#define type float +#define roundit rintf +#define dtype long long +#define fn llrintf + +#include "s_lrint.c" diff --git a/src/openlibm/src/s_llrintl.c b/src/openlibm/src/s_llrintl.c new file mode 100644 index 0000000..3b23238 --- /dev/null +++ b/src/openlibm/src/s_llrintl.c @@ -0,0 +1,9 @@ +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_llrintl.c,v 1.1 2008/01/14 02:12:06 das Exp $"); + +#define type long double +#define roundit rintl +#define dtype long long +#define fn llrintl + +#include "s_lrint.c" diff --git a/src/openlibm/src/s_llround.c b/src/openlibm/src/s_llround.c new file mode 100644 index 0000000..717ea96 --- /dev/null +++ b/src/openlibm/src/s_llround.c @@ -0,0 +1,11 @@ +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_llround.c,v 1.2 2005/04/08 00:52:27 das Exp $"); + +#define type double +#define roundit round +#define dtype long long +#define DTYPE_MIN LLONG_MIN +#define DTYPE_MAX LLONG_MAX +#define fn llround + +#include "s_lround.c" diff --git a/src/openlibm/src/s_llround.c.o b/src/openlibm/src/s_llround.c.o new file mode 100644 index 0000000000000000000000000000000000000000..06dabe59037ec2de4ad59307f4948c4943e95e02 GIT binary patch literal 1368 zcmb<-^>JfjWMqH=Mg}_u1P><4z#zedU^{@B4h*~uJPaPqZ#Z6n_#VwiI6iss>l`@D z;O^{frJ&*N7pkdXXrgDNXQ*IgU}S1wXlS6I5tN#u;E`AYmC!ZU1nFg9U|?ZjU{GLS zU|?lnU~u;fWnf}pJOC1dxrGtR=Y*;kfzpgsK@5x)0*ul;>>Lvq85ls~GEg~T5beSz z;K|1UVqwJ~^H~@^{>LWCj3p#^85kIZki@}uFfcIiGcYg+U^ApRJ}0LrzcepJFPQ<# z0x1Le6GVgj2*Q80T+E=CoS&PUnpeW0mzQ6Xs^{((s#{!=n4Aser{|UG6%^$cq!yJ_GU$O# zNX>{(D@x2w1zSfc0rCeZY}wEZf}|Y=23WYkq|w7p8k#0x>S5|CK!!3fFi1cJxEL6~ zu>p%=n7A5LoEfSPMg_wdXf)JVxTp>T0|UrRa`hWR?Kgm%2w}kN*N1T7B+PyoZ3Wd2 zR{&)+L1}afrVl3W#lXP8&cMKcl7<)<7&@Q|(A@>{D^vJfjWMqH=Mg}_u1P><4z#zedU^{@B4h*~uJPaPqZ#Z6n_#VwiI6iyu>l`@D z;O^{frJ&*N7pkdXXrgDNXQ*IgU}S1wXlS6I5tN#u;E`AYmC!ZU1nFg9U|?ZjU{GLS zU|?lnU~u;fWnf}pJOC1dxrGtR=Y*;kfzpgsK@5x)0*ul;>>Lvq85ls~GEg~T5beSz z;K|1UVqwJ~^H~@^{>LWCj3p%a7#J9Yki@}uFfcF(Krx0n#ql{gMfs(9DQSAi3@|3d zpCGj$KZ5X|{}2EQ1CTf=V<|OKsq*jzL=%pl< zBr@nF6&Ew;CFkenrskC}=;h^?r0Ti*h3XcUBqnD=`RRG3dId%K1*t_Pl?-}d6H+tc z(~1&vQ^D3zN`U+U3R^ZbgCJ>#fdLk7FlkWu!Pp>L8k#0x>Oo>4Tmdqafq_8+#9?4y z;9_6^#|A8hVd82~ab~DG7!?d-pwUoc;i5VW3=AMM$<=QNwch}4B7_06UmwDSlQ8>X zv=vl8Tmh8P1f|g_m_C@e7Xt$WI|Bm)N*ZEdVCaAoipVBlt8U;xDtx_(eO0TPEQ rgHs70gBchY#Ni?k22>crVPIeogqjN%fHGD<73M(sFbXOR<1zpMVWwOC literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_llroundl.c b/src/openlibm/src/s_llroundl.c new file mode 100644 index 0000000..7a00657 --- /dev/null +++ b/src/openlibm/src/s_llroundl.c @@ -0,0 +1,11 @@ +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_llroundl.c,v 1.1 2005/04/08 01:24:08 das Exp $"); + +#define type long double +#define roundit roundl +#define dtype long long +#define DTYPE_MIN LLONG_MIN +#define DTYPE_MAX LLONG_MAX +#define fn llroundl + +#include "s_lround.c" diff --git a/src/openlibm/src/s_llroundl.c.o b/src/openlibm/src/s_llroundl.c.o new file mode 100644 index 0000000000000000000000000000000000000000..522e233092b47ee49b6d6518138d44ea2acc937e GIT binary patch literal 1408 zcmb<-^>JfjWMqH=Mg}_u1P><4z~I1y#0E1R76&hVslx~Rz9%u$iKU!x*$Ge}JtI9s z1tS9^Qv*Xo0|kws)D#7e#1g24uDK=y0}BHKg8~Bs11kdqgS%fS0}}(|0gxETN)Tp* z@?mZl0SPiNFfdjHF)&sLFiP{Vb4*}lV31*eV34#0h;ZRkaN*N%;WNnQ;{fq-V34^i z3?KhvlV-*eVtfn?3_?iaV7nL?7zCgg!<^#yoSdTk(!7)$y<`R$lYxO3su1K?5dQNY z0zhE_k^)5w2!q&QtXEu_TauW>pjTW{1fervtfJJMM7@&KiV_CBl*E!m2EC->Vg|kB z{M_8syb=bzy!?_>J$JuQ-QtqOAB$<=QNwch}4B7_06UmwDSlQ8>Xv=vl8Tmh7^97>~8 zFnus_F9rq%b_NCplr+S^z_0?U0Nq`%@PkS-Bth***M9@506qTD^~d6fza3DA!r}=O ze;~ae3^E!f4pN40H%MLpB*DPI01HQM1_lOD9HHyygo=aoAma|GesN?$s9%wV1aauU M0M(y^tQd=a0DUcMh5!Hn literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_log1p.c b/src/openlibm/src/s_log1p.c new file mode 100644 index 0000000..1921b6a --- /dev/null +++ b/src/openlibm/src/s_log1p.c @@ -0,0 +1,179 @@ +/* @(#)s_log1p.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_log1p.c,v 1.10 2008/03/29 16:37:59 das Exp $"); + +/* double log1p(double x) + * + * Method : + * 1. Argument Reduction: find k and f such that + * 1+x = 2^k * (1+f), + * where sqrt(2)/2 < 1+f < sqrt(2) . + * + * Note. If k=0, then f=x is exact. However, if k!=0, then f + * may not be representable exactly. In that case, a correction + * term is need. Let u=1+x rounded. Let c = (1+x)-u, then + * log(1+x) - log(u) ~ c/u. Thus, we proceed to compute log(u), + * and add back the correction term c/u. + * (Note: when x > 2**53, one can simply return log(x)) + * + * 2. Approximation of log1p(f). + * Let s = f/(2+f) ; based on log(1+f) = log(1+s) - log(1-s) + * = 2s + 2/3 s**3 + 2/5 s**5 + ....., + * = 2s + s*R + * We use a special Reme algorithm on [0,0.1716] to generate + * a polynomial of degree 14 to approximate R The maximum error + * of this polynomial approximation is bounded by 2**-58.45. In + * other words, + * 2 4 6 8 10 12 14 + * R(z) ~ Lp1*s +Lp2*s +Lp3*s +Lp4*s +Lp5*s +Lp6*s +Lp7*s + * (the values of Lp1 to Lp7 are listed in the program) + * and + * | 2 14 | -58.45 + * | Lp1*s +...+Lp7*s - R(z) | <= 2 + * | | + * Note that 2s = f - s*f = f - hfsq + s*hfsq, where hfsq = f*f/2. + * In order to guarantee error in log below 1ulp, we compute log + * by + * log1p(f) = f - (hfsq - s*(hfsq+R)). + * + * 3. Finally, log1p(x) = k*ln2 + log1p(f). + * = k*ln2_hi+(f-(hfsq-(s*(hfsq+R)+k*ln2_lo))) + * Here ln2 is split into two floating point number: + * ln2_hi + ln2_lo, + * where n*ln2_hi is always exact for |n| < 2000. + * + * Special cases: + * log1p(x) is NaN with signal if x < -1 (including -INF) ; + * log1p(+INF) is +INF; log1p(-1) is -INF with signal; + * log1p(NaN) is that NaN with no signal. + * + * Accuracy: + * according to an error analysis, the error is always less than + * 1 ulp (unit in the last place). + * + * Constants: + * The hexadecimal values are the intended ones for the following + * constants. The decimal values may be used, provided that the + * compiler will convert from decimal to binary accurately enough + * to produce the hexadecimal values shown. + * + * Note: Assuming log() return accurate answer, the following + * algorithm can be used to compute log1p(x) to within a few ULP: + * + * u = 1+x; + * if(u==1.0) return x ; else + * return log(u)*(x/(u-1.0)); + * + * See HP-15C Advanced Functions Handbook, p.193. + */ + +#include +#include + +#include "math_private.h" + +static const double +ln2_hi = 6.93147180369123816490e-01, /* 3fe62e42 fee00000 */ +ln2_lo = 1.90821492927058770002e-10, /* 3dea39ef 35793c76 */ +two54 = 1.80143985094819840000e+16, /* 43500000 00000000 */ +Lp1 = 6.666666666666735130e-01, /* 3FE55555 55555593 */ +Lp2 = 3.999999999940941908e-01, /* 3FD99999 9997FA04 */ +Lp3 = 2.857142874366239149e-01, /* 3FD24924 94229359 */ +Lp4 = 2.222219843214978396e-01, /* 3FCC71C5 1D8E78AF */ +Lp5 = 1.818357216161805012e-01, /* 3FC74664 96CB03DE */ +Lp6 = 1.531383769920937332e-01, /* 3FC39A09 D078C69F */ +Lp7 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */ + +static const double zero = 0.0; + +OLM_DLLEXPORT double +log1p(double x) +{ + double hfsq,f,c,s,z,R,u; + int32_t k,hx,hu,ax; + + GET_HIGH_WORD(hx,x); + ax = hx&0x7fffffff; + + k = 1; + if (hx < 0x3FDA827A) { /* 1+x < sqrt(2)+ */ + if(ax>=0x3ff00000) { /* x <= -1.0 */ + if(x==-1.0) return -two54/zero; /* log1p(-1)=+inf */ + else return (x-x)/(x-x); /* log1p(x<-1)=NaN */ + } + if(ax<0x3e200000) { /* |x| < 2**-29 */ + if(two54+x>zero /* raise inexact */ + &&ax<0x3c900000) /* |x| < 2**-54 */ + return x; + else + return x - x*x*0.5; + } + if(hx>0||hx<=((int32_t)0xbfd2bec4)) { + k=0;f=x;hu=1;} /* sqrt(2)/2- <= 1+x < sqrt(2)+ */ + } + if (hx >= 0x7ff00000) return x+x; + if(k!=0) { + if(hx<0x43400000) { + STRICT_ASSIGN(double,u,1.0+x); + GET_HIGH_WORD(hu,u); + k = (hu>>20)-1023; + c = (k>0)? 1.0-(u-x):x-(u-1.0);/* correction term */ + c /= u; + } else { + u = x; + GET_HIGH_WORD(hu,u); + k = (hu>>20)-1023; + c = 0; + } + hu &= 0x000fffff; + /* + * The approximation to sqrt(2) used in thresholds is not + * critical. However, the ones used above must give less + * strict bounds than the one here so that the k==0 case is + * never reached from here, since here we have committed to + * using the correction term but don't use it if k==0. + */ + if(hu<0x6a09e) { /* u ~< sqrt(2) */ + SET_HIGH_WORD(u,hu|0x3ff00000); /* normalize u */ + } else { + k += 1; + SET_HIGH_WORD(u,hu|0x3fe00000); /* normalize u/2 */ + hu = (0x00100000-hu)>>2; + } + f = u-1.0; + } + hfsq=0.5*f*f; + if(hu==0) { /* |f| < 2**-20 */ + if(f==zero) { + if(k==0) { + return zero; + } else { + c += k*ln2_lo; + return k*ln2_hi+c; + } + } + R = hfsq*(1.0-0.66666666666666666*f); + if(k==0) return f-R; else + return k*ln2_hi-((R-(k*ln2_lo+c))-f); + } + s = f/(2.0+f); + z = s*s; + R = z*(Lp1+z*(Lp2+z*(Lp3+z*(Lp4+z*(Lp5+z*(Lp6+z*Lp7)))))); + if(k==0) return f-(hfsq-s*(hfsq+R)); else + return k*ln2_hi-((hfsq-(s*(hfsq+R)+(k*ln2_lo+c)))-f); +} + +#if (LDBL_MANT_DIG == 53) +openlibm_weak_reference(log1p, log1pl); +#endif diff --git a/src/openlibm/src/s_log1p.c.o b/src/openlibm/src/s_log1p.c.o new file mode 100644 index 0000000000000000000000000000000000000000..becdb65fe1f2b02322d22be51b2fd9a7e048dfd5 GIT binary patch literal 3376 zcmb<-^>JfjWMqH=Mg}_u1P><4z_5W6!FB*M9T@l+cp1_>`0Ea&@oSv$IQT-L^N?+2 z(=GdYtHwwF|NpOV{Pq9;dwc%27YqyxY5aPuAZ`3zn;01w_*>U7GBAAN7XXW;@xMR$ zi9hb(VSafA+yDRH*Yo#>GBSXe_Rjo$#~2tGIximlA@Ye|Kon#|8vpy-jSv6-=V#FU z&&X zTR~xW0}^%ze~5rR)Ovuw?=3iZVs57KYn=MTA9K3%Vj923%}@MsHy}QTdb*GM|NsA; z5KlKBUK1W+=d4} z@kc&@U|95leSh&2f7~HNlxn>A#2*R5S3mJbKuwIKlzrtBf8>SM1Ep4<_+uV@;*U84 zbs^Y4uqcf@_=!K}!YBU7E3F4gJ<$D;#{d2;EQ~(!Yk^#N^b>!iE+p(CUVq|`c=d@t z=IJN?n1`SEV~)W5pT__G36efg2psvu9|;bVPy7*&Kk>(0`NSV{@e_Z{AyB&i#2<4D z6wxn*{{8<3c}0f(WqGlYI%51~KUm)TUBzPEg3%fRs9pOfA*`%o}=3YBMY za0#-zFZA({{rqDU7dU4fw!g=GdRmIxar^ZZeX>Uj&)7#!R+^&XdC8vT*Yue)XWq1* z90~$Y?HSyiovjo!-2Fl|6%0-EjPwi@j0}uS4Gawp6f}ZTQxrTBOP~_E=9&x)EDQ_` z3ZOL4z`)?{7s|lIz<2;81}jS#p?p{|A_DOM17lSX17n2%qcjgY#{@fFpVG}34xU%0wDxuxq?Ynh6FH;AiTj$R)!2PjUWQSOjd>hFpVI>!Aw?$3NVcz zV!=#S1`9BaAd(mu7=)1G1s=!6@j3bFh6Q@b40=A!h9JTSM3{mI6A)nrBFsUAF^I4P z5rzg}60F=1tlkhTX$aO~2-a)})@Z>1Hl9HT>J%mh1_n^_`tu(GVBriB2c=t>cs`PP zP^y86uSF7PV_;x_iN8b=XGaqMi6jn6V=(mwpajgozyPur+596&;-EYOQ_liY2vv`4 zuM7@xJtT21B=Bykk=Nbv&M=!a!#DYODIX^cyHLrw0FE76& zRnOfoRJXV!F*zH`PtPmWD=5k@NG&R!Tmk`^fKAe#nD z|M2_>l?25RlnJJ!86agnOg&hTfq~%z)IberV1d#U$R1EwgVeyvNi_xraPEf&J4gzQ zr=kmhMImaTOfUt?zaTTwl@qJq5NbatErAV$5;LF%f*UVTF%Si^3z@cq>PIifB|wD+ z0|SFTNHG!yg#m~QqurtUL1M_*9jYH$48(@%1F=CERNjKpDKwZtLSXCx)sOBjnESzs z7#J8pd(Rv{}P}=ih%)MAA;f^Bm}b`7XR4n2Dxno)cyw`1q=)fpt47p vfdO70!}Np9ghmxe8yt5)(;s@h1vL(?4pg>a({BJWn1O+z60Q=$K-UiddNG<3 literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_log1pf.c b/src/openlibm/src/s_log1pf.c new file mode 100644 index 0000000..53c8f49 --- /dev/null +++ b/src/openlibm/src/s_log1pf.c @@ -0,0 +1,114 @@ +/* s_log1pf.c -- float version of s_log1p.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_log1pf.c,v 1.12 2008/03/29 16:37:59 das Exp $"); + +#include +#include + +#include "math_private.h" + +static const float +ln2_hi = 6.9313812256e-01, /* 0x3f317180 */ +ln2_lo = 9.0580006145e-06, /* 0x3717f7d1 */ +two25 = 3.355443200e+07, /* 0x4c000000 */ +Lp1 = 6.6666668653e-01, /* 3F2AAAAB */ +Lp2 = 4.0000000596e-01, /* 3ECCCCCD */ +Lp3 = 2.8571429849e-01, /* 3E924925 */ +Lp4 = 2.2222198546e-01, /* 3E638E29 */ +Lp5 = 1.8183572590e-01, /* 3E3A3325 */ +Lp6 = 1.5313838422e-01, /* 3E1CD04F */ +Lp7 = 1.4798198640e-01; /* 3E178897 */ + +static const float zero = 0.0; + +OLM_DLLEXPORT float +log1pf(float x) +{ + float hfsq,f,c,s,z,R,u; + int32_t k,hx,hu,ax; + + GET_FLOAT_WORD(hx,x); + ax = hx&0x7fffffff; + + k = 1; + if (hx < 0x3ed413d0) { /* 1+x < sqrt(2)+ */ + if(ax>=0x3f800000) { /* x <= -1.0 */ + if(x==(float)-1.0) return -two25/zero; /* log1p(-1)=+inf */ + else return (x-x)/(x-x); /* log1p(x<-1)=NaN */ + } + if(ax<0x38000000) { /* |x| < 2**-15 */ + if(two25+x>zero /* raise inexact */ + &&ax<0x33800000) /* |x| < 2**-24 */ + return x; + else + return x - x*x*(float)0.5; + } + if(hx>0||hx<=((int32_t)0xbe95f619)) { + k=0;f=x;hu=1;} /* sqrt(2)/2- <= 1+x < sqrt(2)+ */ + } + if (hx >= 0x7f800000) return x+x; + if(k!=0) { + if(hx<0x5a000000) { + STRICT_ASSIGN(float,u,(float)1.0+x); + GET_FLOAT_WORD(hu,u); + k = (hu>>23)-127; + /* correction term */ + c = (k>0)? (float)1.0-(u-x):x-(u-(float)1.0); + c /= u; + } else { + u = x; + GET_FLOAT_WORD(hu,u); + k = (hu>>23)-127; + c = 0; + } + hu &= 0x007fffff; + /* + * The approximation to sqrt(2) used in thresholds is not + * critical. However, the ones used above must give less + * strict bounds than the one here so that the k==0 case is + * never reached from here, since here we have committed to + * using the correction term but don't use it if k==0. + */ + if(hu<0x3504f4) { /* u < sqrt(2) */ + SET_FLOAT_WORD(u,hu|0x3f800000);/* normalize u */ + } else { + k += 1; + SET_FLOAT_WORD(u,hu|0x3f000000); /* normalize u/2 */ + hu = (0x00800000-hu)>>2; + } + f = u-(float)1.0; + } + hfsq=(float)0.5*f*f; + if(hu==0) { /* |f| < 2**-20 */ + if(f==zero) { + if(k==0) { + return zero; + } else { + c += k*ln2_lo; + return k*ln2_hi+c; + } + } + R = hfsq*((float)1.0-(float)0.66666666666666666*f); + if(k==0) return f-R; else + return k*ln2_hi-((R-(k*ln2_lo+c))-f); + } + s = f/((float)2.0+f); + z = s*s; + R = z*(Lp1+z*(Lp2+z*(Lp3+z*(Lp4+z*(Lp5+z*(Lp6+z*Lp7)))))); + if(k==0) return f-(hfsq-s*(hfsq+R)); else + return k*ln2_hi-((hfsq-(s*(hfsq+R)+(k*ln2_lo+c)))-f); +} diff --git a/src/openlibm/src/s_log1pf.c.o b/src/openlibm/src/s_log1pf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..d0d13e9ce22d50a2b91f7c6586dbace846988b72 GIT binary patch literal 3232 zcmb<-^>JfjWMqH=Mg}_u1P><4z@Wg1U^{@B4h(z@ybNjlbqDx0PS~CozG7GJ)Oo1! z(f|Md>l=Ul|6gy<-*%0Gfq`F-6{McOtCNv|fxoqxk%8eezW`V)jsN}0&-`%*52xwz z%eR13G1&h9UtiDPugb^(V*Zch?_0;fz|eU}_5c5RWPP^}{t|C~Rd4&5#gu`+{}M>e zvBq-@3=Q^a{CVd-^T(X{%rBq{GV(Kj;{n< zhgvW3w>)3~%btWe?=!#Fsn7h82S4*i@e0xcHer;zAmK-35M)Tb+j>PHw%#-**ih2r)PLHBNlyk2%e+aTDsl zxLXh(_38cp|9>X~LjyzS@#aH}ng<)tGcYjNcb-V&&pUtc2h&Tb|NsB<%R4Z9=8rhR zuK{urB>Z4*2l*1@R(}0MWy<^-2SM(wH!hbr%rD;n@k`7}evO0R&TRqEC5yl)*W&2Gk@Hn&-^f<7oYhfLHO!t{s^$D&-{^;vafvR zkG#-&snq5(f6SxL{4r-h4uho^nAM;8L5`0(#IJGTGk@fj)=QppNKLJ-Vg1^WZcgc4$4nw3ESOd|+sFq4%5Vjh?SCO~1pz`zRj2Uq|~fFq89 zl|cf^hf!K!1}g&xm_`u#U?wX#Ou4pVqddUoWKF)?9!U#l|f(R23VFn`1L4+}gumll?24E7b+z_nZ5G-j3)?oMtXSBis7~hxj)naV{kHaDoB=YA-jExD1jwC=J8x z)j$#lRX#9r6C`myBy${)#QBlLeUQXKc?V`r1d=!?&%wl7aENa}5=Rct14!a1;g2Ma zto{d*II?<3eucyfR0$*o^@=NVOA?b9^omQ0Aan+dRg{{Os8^C&QNo~?l30?+pqEr! z%%E4458~)07nhhY=q2ap=BDPAFzDswm!#^s`-SQjmn0@rFsQL`30#(C6x?% zVB=CV;?s%}b5kLfQ%-{X1xga2w1aFKq?fagc3Bq)xcOfUs1-$3~TrXDQFz`&3I zH4v6gKxqnO4=AibYGCD?8Uq73_k;2tNF0V^(FLFqATyv$Fa;{FKxU#VCsw~9)P5nb zX$T?#YM>252+RWc6~utic2NE3<>MTven|NY(gDFR_rqv+sD6knf;dVEQ0D z28M731_n?%MM;wk3=9{b`qAA53M-gi5S +#include + +#include "math_private.h" + +static const double +two54 = 1.80143985094819840000e+16; /* 43500000 00000000 */ + +OLM_DLLEXPORT double +logb(double x) +{ + int32_t lx,ix; + EXTRACT_WORDS(ix,lx,x); + ix &= 0x7fffffff; /* high |x| */ + if((ix|lx)==0) return -1.0/fabs(x); + if(ix>=0x7ff00000) return x*x; + if(ix<0x00100000) { + x *= two54; /* convert subnormal x to normal */ + GET_HIGH_WORD(ix,x); + ix &= 0x7fffffff; + return (double) ((ix>>20)-1023-54); + } else + return (double) ((ix>>20)-1023); +} + +#if (LDBL_MANT_DIG == 53) +openlibm_weak_reference(logb, logbl); +#endif diff --git a/src/openlibm/src/s_logb.c.o b/src/openlibm/src/s_logb.c.o new file mode 100644 index 0000000000000000000000000000000000000000..c94f7c32cd9f4a6e794285f2e03256e9971b978a GIT binary patch literal 1688 zcmb<-^>JfjWMqH=Mg}_u1P><4z#zelU^{@B4h(z@ybNg`{B?&sIxl)0e5ufRLiPXu z|Mi@QN+NCl|9@X!?)Cj31H*^}JtI9s1tS9^Qv*Xo0|kws)D#7e z#1g24uDK=y0}BHKg8~Bs1IS!=zfcAy2F3#*F<6)|LiwB!3m8P8G-Fi|17n2%qcjgY z#{@@j3bFNqWf)dOpsEAi{tFB*2iCm{iQbz@PYwV$drtDT2@$Fji4& zPNH5(YDEcyUP@v~B7p1_p4f!qR~RR9p=z4vHJ75STg#CNT++TaiU|7#P55i(LJN zQ2T|D4P{_pxB%s&`xoYZ7;OjDZva&fqaHvR`cN81!Q2m{-J$wn@-UhorT``YrO}1M z85kJY85kI#!3|Z#z#srsi0&?!yI~6Rq4uNecOX)K7LNFDfEoykXHfiu$|9KkFmaGI zP^B;@f$0K}1Oo%Z3NVj>fd^XFq3Z{ki5~YLEfP>ejwZw=cS + +#include "math_private.h" + +static const float +two25 = 3.355443200e+07; /* 0x4c000000 */ + +OLM_DLLEXPORT float +logbf(float x) +{ + int32_t ix; + GET_FLOAT_WORD(ix,x); + ix &= 0x7fffffff; /* high |x| */ + if(ix==0) return (float)-1.0/fabsf(x); + if(ix>=0x7f800000) return x*x; + if(ix<0x00800000) { + x *= two25; /* convert subnormal x to normal */ + GET_FLOAT_WORD(ix,x); + ix &= 0x7fffffff; + return (float) ((ix>>23)-127-25); + } else + return (float) ((ix>>23)-127); +} diff --git a/src/openlibm/src/s_logbf.c.o b/src/openlibm/src/s_logbf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..9d5496120e0368949680d75381978b823bdd7c4d GIT binary patch literal 1664 zcmb<-^>JfjWMqH=Mg}_u1P><4z`($aU^{@B4h(z@ybNjlbq6{RH9q?P|9^dnSL3h$ z|Lg0^tyVHHG}M{CdN2b{h%zuR2qBpRb`t{wgERvJ14Iv8DTGlR zpOc@Sl%|)=py%Uk2qFv^z#lBR;JtF*g-#Hx&qwzd&&d3Ik;0AbEs=0TvH1IrO*y#SbW)VCrG&6rh3R0TlqH z2ar9m1SSC$S7TrR$2wB>1j}p%lb8g^3}jIq1_lO@ndIs>gxW8JY$yW*!wx7PWHyuu zra*oLF<`VERKEd85D6cEvh|@fjDoozM!Q4x!{lM~dl&5}3!B`MlE`T{mL<7`Ol}KVBCc1tA DZyKUO literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_logbl.c b/src/openlibm/src/s_logbl.c new file mode 100644 index 0000000..3c1336b --- /dev/null +++ b/src/openlibm/src/s_logbl.c @@ -0,0 +1,52 @@ +/* + * From: @(#)s_ilogb.c 5.1 93/09/24 + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include +#include +#include + +#include "fpmath.h" +#include "math_private.h" + +OLM_DLLEXPORT long double +logbl(long double x) +{ + union IEEEl2bits u; + unsigned long m; + int b; + + u.e = x; + if (u.bits.exp == 0) { + if ((u.bits.manl | u.bits.manh) == 0) { /* x == 0 */ + u.bits.sign = 1; + return (1.0L / u.e); + } + /* denormalized */ + if (u.bits.manh == 0) { + m = 1lu << (LDBL_MANL_SIZE - 1); + for (b = LDBL_MANH_SIZE; !(u.bits.manl & m); m >>= 1) + b++; + } else { + m = 1lu << (LDBL_MANH_SIZE - 1); + for (b = 0; !(u.bits.manh & m); m >>= 1) + b++; + } +#ifdef LDBL_IMPLICIT_NBIT + b++; +#endif + return ((long double)(LDBL_MIN_EXP - b - 1)); + } + if (u.bits.exp < (LDBL_MAX_EXP << 1) - 1) /* normal */ + return ((long double)(u.bits.exp - LDBL_MAX_EXP + 1)); + else /* +/- inf or nan */ + return (x * x); +} diff --git a/src/openlibm/src/s_lrint.c b/src/openlibm/src/s_lrint.c new file mode 100644 index 0000000..e1c5546 --- /dev/null +++ b/src/openlibm/src/s_lrint.c @@ -0,0 +1,61 @@ +/*- + * Copyright (c) 2005 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "cdefs-compat.h" + +#include +#include + +#include "math_private.h" + +#ifndef type +//__FBSDID("$FreeBSD: src/lib/msun/src/s_lrint.c,v 1.1 2005/01/11 23:12:55 das Exp $"); +#define type double +#define roundit rint +#define dtype long +#define fn lrint +#endif + +/* + * C99 says we should not raise a spurious inexact exception when an + * invalid exception is raised. Unfortunately, the set of inputs + * that overflows depends on the rounding mode when 'dtype' has more + * significant bits than 'type'. Hence, we bend over backwards for the + * sake of correctness; an MD implementation could be more efficient. + */ +OLM_DLLEXPORT dtype +fn(type x) +{ + fenv_t env; + dtype d; + + feholdexcept(&env); + d = (dtype)roundit(x); + if (fetestexcept(FE_INVALID)) + feclearexcept(FE_INEXACT); + feupdateenv(&env); + return (d); +} diff --git a/src/openlibm/src/s_lrintf.c b/src/openlibm/src/s_lrintf.c new file mode 100644 index 0000000..f29ad52 --- /dev/null +++ b/src/openlibm/src/s_lrintf.c @@ -0,0 +1,9 @@ +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_lrintf.c,v 1.1 2005/01/11 23:12:55 das Exp $"); + +#define type float +#define roundit rintf +#define dtype long +#define fn lrintf + +#include "s_lrint.c" diff --git a/src/openlibm/src/s_lrintl.c b/src/openlibm/src/s_lrintl.c new file mode 100644 index 0000000..b57c27d --- /dev/null +++ b/src/openlibm/src/s_lrintl.c @@ -0,0 +1,9 @@ +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_lrintl.c,v 1.1 2008/01/14 02:12:06 das Exp $"); + +#define type long double +#define roundit rintl +#define dtype long +#define fn lrintl + +#include "s_lrint.c" diff --git a/src/openlibm/src/s_lround.c b/src/openlibm/src/s_lround.c new file mode 100644 index 0000000..76fa732 --- /dev/null +++ b/src/openlibm/src/s_lround.c @@ -0,0 +1,69 @@ +/*- + * Copyright (c) 2005 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "cdefs-compat.h" + +#include +#include +#include + +#include "math_private.h" + +#ifndef type +//__FBSDID("$FreeBSD: src/lib/msun/src/s_lround.c,v 1.2 2005/04/08 00:52:16 das Exp $"); +#define type double +#define roundit round +#define dtype long +#define DTYPE_MIN LONG_MIN +#define DTYPE_MAX LONG_MAX +#define fn lround +#endif + +/* + * If type has more precision than dtype, the endpoints dtype_(min|max) are + * of the form xxx.5; they are "out of range" because lround() rounds away + * from 0. On the other hand, if type has less precision than dtype, then + * all values that are out of range are integral, so we might as well assume + * that everything is in range. At compile time, INRANGE(x) should reduce to + * two floating-point comparisons in the former case, or TRUE otherwise. + */ +static const type dtype_min = DTYPE_MIN - 0.5; +static const type dtype_max = DTYPE_MAX + 0.5; +#define INRANGE(x) (dtype_max - DTYPE_MAX != 0.5 || \ + ((x) > dtype_min && (x) < dtype_max)) + +OLM_DLLEXPORT dtype +fn(type x) +{ + + if (INRANGE(x)) { + x = roundit(x); + return ((dtype)x); + } else { + feraiseexcept(FE_INVALID); + return (DTYPE_MAX); + } +} diff --git a/src/openlibm/src/s_lround.c.o b/src/openlibm/src/s_lround.c.o new file mode 100644 index 0000000000000000000000000000000000000000..80b51c9dd875876d069e70a34dda5b864da9dc7d GIT binary patch literal 1368 zcmb<-^>JfjWMqH=Mg}_u1P><4z#zedU^{@B4h*~uJPaPqZ#Z6n_#VwiI6iss>l`@D z;O^{frJ&*N7pkdXXrgDNXQ*IgU}S1wXlS6I5tN#u;E`AYmC!ZU1nFg9U|?ZjU{GLS zU|?lnU~u;fWnf}pJOC1dxrGtR=Y*;kfzpgsK@5x)0*ul;>>Lvq85ls~GEg~T5beSz z;K|1UVqwJ~^H~@^{>LWCj3p#^7#J9Yki@}uFfcIiGB7X*U^ApRKBp+ZG%rOjnE}Fp zC<6Ht!~*#dg#Y}908ki!#6iIg!XP#n>lIh#mLw)I=oOa~LFfz^t0*-mQLiMmqJ%*& zC9x!tK`*Jem_aW&KQ}iuuY^G_FTW&J&)qLnx40xRIUCAP&nwj{D9SHLEh?#G&;y&0 znh~E?l$e_ewvJK)NkYiZvZzD!hqSY58=W|nEf!?3aTHj z0Lo~B(&!XSA57effq{XYfq?-f4KXkJfjWMqH=Mg}_u1P><4z#zedU^{@B4h*~uJPaPqZ#Z6n_#VwiI6iyu>l`@D z;O^{frJ&*N7pkdXXrgDNXQ*IgU}S1wXlS6I5tN#u;E`AYmC!ZU1nFg9U|?ZjU{GLS zU|?lnU~u;fWnf}pJOC1dxrGtR=Y*;kfzpgsK@5x)0*ul;>>Lvq85ls~GEg~T5beSz z;K|1UVqwJ~^H~@^{>LWCj3p#^85kIZki@}uFfcIiF)%O)U^ApRKBp+ZG%qDhFPQ<# z0x1Le6GVgj2*Q80T+E=CoS&PUnpeW0mzQ6Xs^{((s#{!=n4Aser{|UG6%^$cq!yJ_GU$O# zNX>{(D@x2w1zSfc0rCeZY}wEZf}|Y=23WYkq|w7p8k#0x>S5|CK!!3fFi1cJxEL6~ zu>p%=n7A5LoEfSPMg_wdXf)JVxTp>T0|UrRa`hWR?Kgm%2w}kN*N1T7B+PyoZ3Wd2 zR{&)+L1}afrVl3W#lXP8&cMKcl7<)<7&@Q|(A@>{D^vJfjWMqH=Mg}_u1P><4z~I1y#0E1R76&hVslx~Rz9%u$iKU!x*$Ge}JtI9s z1tS9^Qv*Xo0|kws)D#7e#1g24uDK=y0}BHKg8~Bs11kdqgS%fS0}}(|0gxETN)Tp* z@?mZl0SPiNFfdjHF)&sLFiP{Vb4*}lV31*eV34#0h;ZRkaN*N%;WNnQ;{fq-V34^i z3?KhvlV-*eV!R9t3_?iaV7nL?82A_%7zD5xQXHRClwX>clB1W*0A+!cfy@EXAisj} zpZ^d53JZ`pC|W=m#0F!%;>z5T#3Tm2;*uf=odIJNrRF5+m84dbFzBTumLxLhB^4Jl z=q2ap=BDPAFzDswm!#^s`-SQjmn0@rFsQL`30#(C6x?%U=va^;?s%}b5p_A zQA&XP0Sa3-G=m(Vd|0?axfo$5%>YRoF!eBX3qXc4Ffd3!1-L+Ifq{Vm7RNAgHK;f< zR2__}fHBZ$sIhQS9jKY)>NkYiZvZzD!hqSY58=W|nEf!?3aTHj0LoYnrO_#vKA5-{ z0|Ns)0|Ns}8e(8zSOHal?k-sPL8Tdzp!TEdzX4T%9)IZiV{yda4yZ$6@dS!LkX{f5 z84VK$DMPm#BrgDxU|?W?g(Eiu0|O|I(Didd#X)+IaR*etD6$~bugF4zIP_nD>d!$| Hj72{HCv|G6 literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_modf.c b/src/openlibm/src/s_modf.c new file mode 100644 index 0000000..e3b517b --- /dev/null +++ b/src/openlibm/src/s_modf.c @@ -0,0 +1,76 @@ +/* @(#)s_modf.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * modf(double x, double *iptr) + * return fraction part of x, and return x's integral part in *iptr. + * Method: + * Bit twiddling. + * + * Exception: + * No exception. + */ + +#include + +#include "math_private.h" + +static const double one = 1.0; + +OLM_DLLEXPORT double +modf(double x, double *iptr) +{ + int32_t i0,i1,j0; + u_int32_t i; + EXTRACT_WORDS(i0,i1,x); + j0 = ((i0>>20)&0x7ff)-0x3ff; /* exponent of x */ + if(j0<20) { /* integer part in high x */ + if(j0<0) { /* |x|<1 */ + INSERT_WORDS(*iptr,i0&0x80000000,0); /* *iptr = +-0 */ + return x; + } else { + i = (0x000fffff)>>j0; + if(((i0&i)|i1)==0) { /* x is integral */ + u_int32_t high; + *iptr = x; + GET_HIGH_WORD(high,x); + INSERT_WORDS(x,high&0x80000000,0); /* return +-0 */ + return x; + } else { + INSERT_WORDS(*iptr,i0&(~i),0); + return x - *iptr; + } + } + } else if (j0>51) { /* no fraction part */ + u_int32_t high; + if (j0 == 0x400) { /* inf/NaN */ + *iptr = x; + return 0.0 / x; + } + *iptr = x*one; + GET_HIGH_WORD(high,x); + INSERT_WORDS(x,high&0x80000000,0); /* return +-0 */ + return x; + } else { /* fraction part in low x */ + i = ((u_int32_t)(0xffffffff))>>(j0-20); + if((i1&i)==0) { /* x is integral */ + u_int32_t high; + *iptr = x; + GET_HIGH_WORD(high,x); + INSERT_WORDS(x,high&0x80000000,0); /* return +-0 */ + return x; + } else { + INSERT_WORDS(*iptr,i0,i1&(~i)); + return x - *iptr; + } + } +} diff --git a/src/openlibm/src/s_modf.c.o b/src/openlibm/src/s_modf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..70576c89502a774eb76340f2608583e637f5c5f5 GIT binary patch literal 1456 zcmb<-^>JfjWMqH=Mg}_u1P><4z_5V{!FB*M9T<2RxEazs`0I{&bpG<_{NT~~-Q(a7 z6OV)M6;%JTGcfdaF#h@fzxk(dy;bW;{*F})3=BK||L148{G;=r;!ntNl*UJa%x7Wv_#c}ZW-Kwx#lXNIgd`5P zqc}b{KP62snE^yW`~or)lpH`9#0F!%;>z5T#3Tm2;*uf=odIK&q*jzL=%plp<-{K(>T|fdOW}KAJepei&^E)sLo(Ar__pO#)rmm4ShQoq>S?CGHs*7!sfg z(cJ~|E3%QXQ2WvKgVH!i9U=V@3=E)hfB_a?AUz;#05wno#9?4y0Oco;J7M<2#6ix4 zDut?qPzOK~Ab&u(450h~iX(LWAag + +#include "math_private.h" + +static const float one = 1.0; + +OLM_DLLEXPORT float +modff(float x, float *iptr) +{ + int32_t i0,j0; + u_int32_t i; + GET_FLOAT_WORD(i0,x); + j0 = ((i0>>23)&0xff)-0x7f; /* exponent of x */ + if(j0<23) { /* integer part in x */ + if(j0<0) { /* |x|<1 */ + SET_FLOAT_WORD(*iptr,i0&0x80000000); /* *iptr = +-0 */ + return x; + } else { + i = (0x007fffff)>>j0; + if((i0&i)==0) { /* x is integral */ + u_int32_t ix; + *iptr = x; + GET_FLOAT_WORD(ix,x); + SET_FLOAT_WORD(x,ix&0x80000000); /* return +-0 */ + return x; + } else { + SET_FLOAT_WORD(*iptr,i0&(~i)); + return x - *iptr; + } + } + } else { /* no fraction part */ + u_int32_t ix; + *iptr = x*one; + if (x != x) /* NaN */ + return x; + GET_FLOAT_WORD(ix,x); + SET_FLOAT_WORD(x,ix&0x80000000); /* return +-0 */ + return x; + } +} diff --git a/src/openlibm/src/s_modff.c.o b/src/openlibm/src/s_modff.c.o new file mode 100644 index 0000000000000000000000000000000000000000..761f85fc261046f0e187dabaf9e17366524b9e44 GIT binary patch literal 1360 zcmb<-^>JfjWMqH=Mg}_u1P><4z!1QMU^{@B4h%dD+ze^_bq6{R9{efJzwKo6%lhV@ zV)ZJmCo3X${r_LjaQRp3p;BE{1_p+P&-{YyY5aK?_%#k4=9hP1;MY6AuW_OJF-ROD z)&e&5`z3yj3yO!*`14ME=8w6^uW=BjB8^|(g@FNV7{A7aH2%B;Fc}7SXJ;z~4R^m# zO$9>}JtI9s1tS9^Qv*Xo0|kws)D#7e#1g24uDK@I8U_{y1_lKN1_o9J1_pP(PzELj z#seTRnBN(pd`^gR1`#ODSQW&;SRueD&BM+yfsp|$E(4W=_yEemL4nL?VfgqTn=~_) zkmqJ#U=TtQhucvcpPQeOmZq1?0H$H)f&2twgQ5$BL2NMAE3V8fNlaqUD=sO5&>1jR zNoqw2gI-EvNg{(@QgJbZUUGhJZfaf$gI->KNvfW^U#M{~W8Qy^)MfdTG+sJsA_hEa-8{md`{D18J< zqf?;xKo(PHU|`^2U|=9uzYf%X17t%P7#Lvo>!XRo?1#~&Q2l7i7(Sy5K>09zP%eWj z0|Ns)0|Ns}+%qsR{D3MzcNfU7P$@7K3$-6zzXsGILi!^Z7{GZ87GGdP85kHYK=n&N z1wi=<y(APy3S3d2P} W^4RphfGSLftAsG1!VnGv0|NklD0|NU literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_modfl.c b/src/openlibm/src/s_modfl.c new file mode 100644 index 0000000..44a9363 --- /dev/null +++ b/src/openlibm/src/s_modfl.c @@ -0,0 +1,101 @@ +/*- + * Copyright (c) 2007 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Derived from s_modf.c, which has the following Copyright: + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + * + * $FreeBSD: src/lib/msun/src/s_modfl.c,v 1.1 2007/01/07 07:54:21 das Exp $ + */ + +#include +#include + +#include "fpmath.h" +#include "math_private.h" + +#if LDBL_MANL_SIZE > 32 +#define MASK ((u_int64_t)-1) +#else +#define MASK ((u_int32_t)-1) +#endif +/* Return the last n bits of a word, representing the fractional part. */ +#define GETFRAC(bits, n) ((bits) & ~(MASK << (n))) +/* The number of fraction bits in manh, not counting the integer bit */ +#define HIBITS (LDBL_MANT_DIG - LDBL_MANL_SIZE) + +static const long double zero[] = { 0.0L, -0.0L }; + +OLM_DLLEXPORT long double +modfl(long double x, long double *iptr) +{ + union IEEEl2bits ux; + int e; + + ux.e = x; + e = ux.bits.exp - LDBL_MAX_EXP + 1; + if (e < HIBITS) { /* Integer part is in manh. */ + if (e < 0) { /* |x|<1 */ + *iptr = zero[ux.bits.sign]; + return (x); + } else { + if ((GETFRAC(ux.bits.manh, HIBITS - 1 - e) | + ux.bits.manl) == 0) { /* X is an integer. */ + *iptr = x; + return (zero[ux.bits.sign]); + } else { + /* Clear all but the top e+1 bits. */ + ux.bits.manh >>= HIBITS - 1 - e; + ux.bits.manh <<= HIBITS - 1 - e; + ux.bits.manl = 0; + *iptr = ux.e; + return (x - ux.e); + } + } + } else if (e >= LDBL_MANT_DIG - 1) { /* x has no fraction part. */ + *iptr = x; + if (x != x) /* Handle NaNs. */ + return (x); + return (zero[ux.bits.sign]); + } else { /* Fraction part is in manl. */ + if (GETFRAC(ux.bits.manl, LDBL_MANT_DIG - 1 - e) == 0) { + /* x is integral. */ + *iptr = x; + return (zero[ux.bits.sign]); + } else { + /* Clear all but the top e+1 bits. */ + ux.bits.manl >>= LDBL_MANT_DIG - 1 - e; + ux.bits.manl <<= LDBL_MANT_DIG - 1 - e; + *iptr = ux.e; + return (x - ux.e); + } + } +} diff --git a/src/openlibm/src/s_modfl.c.o b/src/openlibm/src/s_modfl.c.o new file mode 100644 index 0000000000000000000000000000000000000000..fd59db2b872910a088847aa4fea8c03ff04a4b43 GIT binary patch literal 1784 zcmb<-^>JfjWMqH=Mg}_u1P><4z)-=AU^{@B4h(z@ybQN%3yK#w zKa>`MO|j?S=A!b^qgNDU{DBwj%?}to4nAPHt;2LUO^;u`1tiSS{KKwJ8l?Q@f!p@? zUsRt4v619=+Jh|&QQ?5w_5DKYh0<`4y4&`zXYbQ%_3oz?ZXNbz1+c_#P zKt_U;-FtXA4Q3xsH{G@eDLs7o)n$RzxH~&rDQLL+g=#7on&=tn z87deV7?~Ov8X72Q1f`}ZcqEoUC3MX-85md?7#I{77#LVVTKz&9m>3ujfW%;N#t7xZ zqDuto3dX7+2F3~jMrj^)jtPtm3?OkCsGK-VGn9{w0x4l(`1l{295a>_!_C0JzzB9F zL0T+Ez~=jZ08=9Mt$<>i;8>bd)c>K2zICTBzW>3OAk1x5JRb zQZwSyiV|~E;Z{?^0Qm@4Kgdk +#include +#include +#include +#include +#include //for memset + +#include "math_private.h" + +#if !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__DragonFly__) +static __inline int digittoint(int c) { + if ('0' <= c && c <= '9') + return (c - '0'); + else if ('A' <= c && c <= 'F') + return (c - 'A' + 10); + else if ('a' <= c && c <= 'f') + return (c - 'a' + 10); + return 0; +} +#endif + + +/* + * Scan a string of hexadecimal digits (the format nan(3) expects) and + * make a bit array (using the local endianness). We stop when we + * encounter an invalid character, NUL, etc. If we overflow, we do + * the same as gcc's __builtin_nan(), namely, discard the high order bits. + * + * The format this routine accepts needs to be compatible with what is used + * in contrib/gdtoa/hexnan.c (for strtod/scanf) and what is used in + * __builtin_nan(). In fact, we're only 100% compatible for strings we + * consider valid, so we might be violating the C standard. But it's + * impossible to use nan(3) portably anyway, so this seems good enough. + */ +OLM_DLLEXPORT void +__scan_nan(u_int32_t *words, int num_words, const char *s) +{ + int si; /* index into s */ + int bitpos; /* index into words (in bits) */ + + memset(words, 0, num_words * sizeof(u_int32_t)); + + /* Allow a leading '0x'. (It's expected, but redundant.) */ + if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) + s += 2; + + /* Scan forwards in the string, looking for the end of the sequence. */ + for (si = 0; isxdigit(s[si]); si++) + ; + + /* Scan backwards, filling in the bits in words[] as we go. */ +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + for (bitpos = 0; bitpos < 32 * num_words; bitpos += 4) { +#else + for (bitpos = 32 * num_words - 4; bitpos >= 0; bitpos -= 4) { +#endif + if (--si < 0) + break; + words[bitpos / 32] |= digittoint(s[si]) << (bitpos % 32); + } +} + +OLM_DLLEXPORT double +nan(const char *s) +{ + union { + double d; + u_int32_t bits[2]; + } u; + + __scan_nan(u.bits, 2, s); +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + u.bits[1] |= 0x7ff80000; +#else + u.bits[0] |= 0x7ff80000; +#endif + return (u.d); +} + +OLM_DLLEXPORT float +nanf(const char *s) +{ + union { + float f; + u_int32_t bits[1]; + } u; + + __scan_nan(u.bits, 1, s); + u.bits[0] |= 0x7fc00000; + return (u.f); +} + +#if (LDBL_MANT_DIG == 53) +openlibm_weak_reference(nan, nanl); +#endif diff --git a/src/openlibm/src/s_nan.c.o b/src/openlibm/src/s_nan.c.o new file mode 100644 index 0000000000000000000000000000000000000000..fbd5e871cdcf24213fa1108472f97b6bbb90e55b GIT binary patch literal 1976 zcmb<-^>JfjWMqH=Mg}_u1P><4z)-=0U^{@B4h*~uJPeK@j-6jZJvy&?BwsW97VL5G z5tB#f?-w8y4YdpgrGot1Tp2xjLz$W%+_#DF;CFcimh~{QKBDFE&4v?=85{{ExGI&*f*YFZLFky!`C- zsWh0YqGKIn4)e=17@mAt`v3p`2_DUFBs@BQ?PFqKVDRXzQQ-i4uhB<^hk@Zo{U?3_ z7ZnbV<|7h^`Q;lx-h!zIc^0Ie2duu^MTG~XikE@mKz$m2-hsmm?#|9u3L5Typ_&SY zCVEDCh6+XoMy3Xah6V~6L8&PU9*HGT30-qd1_n^{C@?TEure?(xch}NFflM50EvO@ z0olt4<#U2K3=9k+P@1tSh=H*}fKi%aHOB{}j)8$e6GXf4DWvdmfXz<<@fjExG(fZqpF$KL2Z)6g zgWSo&@DXe!x&me_DH7xlAtZ5_Mv%V*&<$W`d~tGO9*Dz`o0?mkTEY+?pIlN|kQ$#9pOc@=ke8U3#=yWJ4${K_ zi62mW{P_<7#z^9zID?4`LG1&nWoBStfQdWd5C_FM$S6?y17Q#wgabeX0|Ns{41{4p zm4PM>^B;p=ab<2vViJR1aY+$`&VaFsQgagZN>VFI81zySOA;CMl8TEN^pf*)b5rw5 z81(Y;OH%dR{X%t%OA?c_q5Sl`QoVwr{DRb?l1c_WunDOd@o7bgxv5YWP)33L4GI!A zG-DuT69Yp8ND@g7q#lV2P7k0khN*|iC4d5*fq@|bD!|3S01i4>%9VhMt3kz~%AukR z3^UN|g-M_bgYp^3Omg)bLhUzzSpcPB_Ul9WFbZZrjJAU6hsnd}<1hs<0Vs_w?8U&q zzz$7cP$gjM1XLlqyFh*gD}WM7Q2W7Y6DkIxen9nCfH+7PU4JYzPoc-(0ce1FK=p#+ z52P1_K|-+j16hM^H%Pt!DtG|IVPIeYm2n^=(e;DMACNdy8JseJ3hKc{APkUw5Eg_K aWME)`DuoC@Ne)n=WME*(f%0J#x_$t$TLp;# literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_nearbyint.c b/src/openlibm/src/s_nearbyint.c new file mode 100644 index 0000000..95162a5 --- /dev/null +++ b/src/openlibm/src/s_nearbyint.c @@ -0,0 +1,56 @@ +/*- + * Copyright (c) 2004 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_nearbyint.c,v 1.2 2008/01/14 02:12:06 das Exp $"); + +#include +#include + +#include "math_private.h" + +/* + * We save and restore the floating-point environment to avoid raising + * an inexact exception. We can get away with using fesetenv() + * instead of feclearexcept()/feupdateenv() to restore the environment + * because the only exception defined for rint() is overflow, and + * rounding can't overflow as long as emax >= p. + */ +#define DECL(type, fn, rint) \ +OLM_DLLEXPORT type \ +fn(type x) \ +{ \ + type ret; \ + fenv_t env; \ + \ + fegetenv(&env); \ + ret = rint(x); \ + fesetenv(&env); \ + return (ret); \ +} + +DECL(double, nearbyint, rint) +DECL(float, nearbyintf, rintf) diff --git a/src/openlibm/src/s_nearbyint.c.o b/src/openlibm/src/s_nearbyint.c.o new file mode 100644 index 0000000000000000000000000000000000000000..9120f837acda54b417c5f994f4f3dceefe63c790 GIT binary patch literal 1664 zcmb<-^>JfjWMqH=Mg}_u1P><4z~I1)#0E1R7ATgMq z7@>SluxbVd5h%@A6~w?;A;2ij!_F~*5h5-FmD2^$E_@Cdd>ml)CLlfo0|T-+R0x9t z*~`N4@jr$H0|NsymXPLWU|d2@H78N8B(K`$@ABvsGdFI2a{ z3KRwgh6Jbp7Xt%0RdGQ15>Q$VDvp%B!7_8fBqjlJE3&8#0|NudOmg)bLhXmgAJlM| z{rXTojDpz@qphI&Ve&Bg42*$B!}P&~y%-o6KjwZpe3``n literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_nextafter.c b/src/openlibm/src/s_nextafter.c new file mode 100644 index 0000000..8b2ea05 --- /dev/null +++ b/src/openlibm/src/s_nextafter.c @@ -0,0 +1,83 @@ +/* @(#)s_nextafter.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_nextafter.c,v 1.12 2008/02/22 02:30:35 das Exp $"); + +/* IEEE functions + * nextafter(x,y) + * return the next machine floating-point number of x in the + * direction toward y. + * Special cases: + */ + +#include +#include + +#include "math_private.h" + +OLM_DLLEXPORT double +nextafter(double x, double y) +{ + volatile double t; + int32_t hx,hy,ix,iy; + u_int32_t lx,ly; + + EXTRACT_WORDS(hx,lx,x); + EXTRACT_WORDS(hy,ly,y); + ix = hx&0x7fffffff; /* |x| */ + iy = hy&0x7fffffff; /* |y| */ + + if(((ix>=0x7ff00000)&&((ix-0x7ff00000)|lx)!=0) || /* x is nan */ + ((iy>=0x7ff00000)&&((iy-0x7ff00000)|ly)!=0)) /* y is nan */ + return x+y; + if(x==y) return y; /* x=y, return y */ + if((ix|lx)==0) { /* x == 0 */ + INSERT_WORDS(x,hy&0x80000000,1); /* return +-minsubnormal */ + t = x*x; + if(t==x) return t; else return x; /* raise underflow flag */ + } + if(hx>=0) { /* x > 0 */ + if(hx>hy||((hx==hy)&&(lx>ly))) { /* x > y, x -= ulp */ + if(lx==0) hx -= 1; + lx -= 1; + } else { /* x < y, x += ulp */ + lx += 1; + if(lx==0) hx += 1; + } + } else { /* x < 0 */ + if(hy>=0||hx>hy||((hx==hy)&&(lx>ly))){/* x < y, x -= ulp */ + if(lx==0) hx -= 1; + lx -= 1; + } else { /* x > y, x += ulp */ + lx += 1; + if(lx==0) hx += 1; + } + } + hy = hx&0x7ff00000; + if(hy>=0x7ff00000) return x+x; /* overflow */ + if(hy<0x00100000) { /* underflow */ + t = x*x; + if(t!=x) { /* raise underflow flag */ + INSERT_WORDS(y,hx,lx); + return y; + } + } + INSERT_WORDS(x,hx,lx); + return x; +} + +#if (LDBL_MANT_DIG == 53) +openlibm_weak_reference(nextafter, nexttoward); +openlibm_weak_reference(nextafter, nexttowardl); +openlibm_weak_reference(nextafter, nextafterl); +#endif diff --git a/src/openlibm/src/s_nextafter.c.o b/src/openlibm/src/s_nextafter.c.o new file mode 100644 index 0000000000000000000000000000000000000000..16343b8b2c327147f1c6dc5ec1ea31a8b65c0b9b GIT binary patch literal 1664 zcmb<-^>JfjWMqH=Mg}_u1P><4z|g>qU^{@B4h%dD+ze?R{B?)YJo)QRcywO(={)9f z@V$b^!FLLsKRQ3E{{R2KzVRW5wEh48eLa8MJO%~^T?U2^^_&;@Ti-A+Ff{&zNW2BH zUxH*@I1lo-USwckNaNQ#SjEQQa*~080c2Y1fBp_OMg|7U@BDrD7#J8@FY&jWVqjos ze#O{%u<;>CZ{tr8$=~uFWZKXF|M?l}Mbh{+PJH5zJn@NN&`0IRCw>7Rl^-4lA1HWm zUP$xc&pVOEuW|5jnjXJ=3)oi>2bFt(ZD%U+=e$tbhu07+>oB z|NkE(U&`rdd4a!4{{R2~&4(D9e=#;+V0bA4mTUkywDlW*=dXYN|66|N@Baj%Pn4W{ zeKl>uC;o^7ATPh3n#M2h!obk_t#XCs_qqqK7csayJ6kDexch}_Dj1sR8R;1+7#SFu z8WI_T2YdiR+3tzm&^cX!^{Qw4a8<*U|;}Y5F3p3iYs$V5|bG8ic5+hbOwx7l3G#1 zpqG+ZlE|Q!R9wuUmzJ=2_7o--IR5Iul zrRF5+rDnvZ6(#1Tf^DLRkY->2`05A)c zKo?eLU|`^2U|=9uzYf%X15|4mVD{^yiNoxN(WX%SXv!EQQ6du|3)2S^ab;j&U`LO8 zP@0G8M|T&d_R5?fpj02zog!D%+Fff4f6D+>Knn46KKqWwI1_lOD{sOrZ zW0V + +#include "math_private.h" + +OLM_DLLEXPORT float +nextafterf(float x, float y) +{ + volatile float t; + int32_t hx,hy,ix,iy; + + GET_FLOAT_WORD(hx,x); + GET_FLOAT_WORD(hy,y); + ix = hx&0x7fffffff; /* |x| */ + iy = hy&0x7fffffff; /* |y| */ + + if((ix>0x7f800000) || /* x is nan */ + (iy>0x7f800000)) /* y is nan */ + return x+y; + if(x==y) return y; /* x=y, return y */ + if(ix==0) { /* x == 0 */ + SET_FLOAT_WORD(x,(hy&0x80000000)|1);/* return +-minsubnormal */ + t = x*x; + if(t==x) return t; else return x; /* raise underflow flag */ + } + if(hx>=0) { /* x > 0 */ + if(hx>hy) { /* x > y, x -= ulp */ + hx -= 1; + } else { /* x < y, x += ulp */ + hx += 1; + } + } else { /* x < 0 */ + if(hy>=0||hx>hy){ /* x < y, x -= ulp */ + hx -= 1; + } else { /* x > y, x += ulp */ + hx += 1; + } + } + hy = hx&0x7f800000; + if(hy>=0x7f800000) return x+x; /* overflow */ + if(hy<0x00800000) { /* underflow */ + t = x*x; + if(t!=x) { /* raise underflow flag */ + SET_FLOAT_WORD(y,hx); + return y; + } + } + SET_FLOAT_WORD(x,hx); + return x; +} diff --git a/src/openlibm/src/s_nextafterf.c.o b/src/openlibm/src/s_nextafterf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..7ce86f4eb0adbff10f7dff055e9a16059bff0c6c GIT binary patch literal 1448 zcmb<-^>JfjWMqH=Mg}_u1P><4z_5Y|!FB*M9T<2RxEa#;>rSQd*B$J<)_J1w+5i9l z>s3KS<39$5hWc_JTQKFyuXnJDsl>4LK&gAy`ZS46T7nqJ6kDexch}_Dj1sR8R;1+7#SFu8WYo`^pY769Eiyv zzkyhwWB|e-HW=#_SLT)^CNbz0mlQ$h3>d2oipU;yPWkUL@a!^A<>K$SvOLZ}rW2?hp+ y1PGUb3mQl0`a$NR#~nxu2h>nd`U3G`7-}qx%OD6f7cKy0I6(EML-{ZYT|WSxXQ*!g literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_nextafterl.c b/src/openlibm/src/s_nextafterl.c new file mode 100644 index 0000000..bb73141 --- /dev/null +++ b/src/openlibm/src/s_nextafterl.c @@ -0,0 +1,80 @@ +/* @(#)s_nextafter.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_nextafterl.c,v 1.2 2008/02/22 02:30:36 das Exp $"); + +/* IEEE functions + * nextafter(x,y) + * return the next machine floating-point number of x in the + * direction toward y. + * Special cases: + */ + +#include +#include + +#include "fpmath.h" +#include "math_private.h" + +#if LDBL_MAX_EXP != 0x4000 +#error "Unsupported long double format" +#endif + +OLM_DLLEXPORT long double +nextafterl(long double x, long double y) +{ + volatile long double t; + union IEEEl2bits ux, uy; + + ux.e = x; + uy.e = y; + + if ((ux.bits.exp == 0x7fff && + ((ux.bits.manh&~LDBL_NBIT)|ux.bits.manl) != 0) || + (uy.bits.exp == 0x7fff && + ((uy.bits.manh&~LDBL_NBIT)|uy.bits.manl) != 0)) + return x+y; /* x or y is nan */ + if(x==y) return y; /* x=y, return y */ + if(x==0.0) { + ux.bits.manh = 0; /* return +-minsubnormal */ + ux.bits.manl = 1; + ux.bits.sign = uy.bits.sign; + t = ux.e*ux.e; + if(t==ux.e) return t; else return ux.e; /* raise underflow flag */ + } + if((x>0.0) ^ (xJfjWMqH=Mg}_u1P><4!0>|^!FB*M9T<2RxEXHesBn06yQm1Hss69OU88d2 zc8-d~?HZLAX}16C`CE7y85lgeLsS&LUrPIa2qdD+$Nr5M(BQ%RL4L zhTg*ejSm?Z7#cV~cKWE?X@14n8KQCn;{A0D3=C8McZXXp6kIqvb z2VW^PJ_4D-d5XW~=0C7B*y?)+5A(}2fYeD~s5^|IuGfpP(?{h->&enykdeJ!jE#@L zjycsCqH+gf1AlAY|NsB_x4Wo3=nY^@Q)OsKYkc&-p7TOlr;Ex1P{h6T1t|c92PhzJ z95|fDFW&-+4hD#>4gc#I7$6#-{jcZzfYA8w-~ay%?#|9u3L5Typ_&SYCVEDCh6+Xo zMy3Xah6V~6L8&PU9*HGT30-qdu(1p*3=9kk3=9mc3=9nJexVFZ42%arVxTAnsbGZi zVaZMeB*?(Pz*rT;z*r%`D9yvpF@ceR0VFO1m1ALoGVo9!^H~@^{>P?-8B59+U|?Vn zLK27BA&o{WDo|i!C0@jGPfi# zi9xTpqzFQ1z*r@z6(tOMDTyVC40=h$#SD7M`MJ5Nc_j>bdHE%&dhULqy2T}l$=OhT zdS0nsK~a7|YEelggI-Z;PNH6FMtoXPVs0wfCW;7<|3P8NhGq(+Y+zu3g%eB~6pk=9 zh*ku}B?AKkEPg>^Anbw?7$6Y{2H6E+K}dB51_lla^y@(FH-H!iCt>#M!$lwrnEf!? z6sjL0iy(`MbiXSD0|Pq)0|UD93a9|OyFh+L*uuaN3$-7r94@s2DnLko1Oo#&55nRL zWVys7eSG02KtqFGK`F ag6xB^AfzDFTnG +#include + +#include "fpmath.h" +#include "math_private.h" + +#if LDBL_MAX_EXP != 0x4000 +#error "Unsupported long double format" +#endif + +OLM_DLLEXPORT double +nexttoward(double x, long double y) +{ + union IEEEl2bits uy; + volatile double t; + int32_t hx,ix; + u_int32_t lx; + + EXTRACT_WORDS(hx,lx,x); + ix = hx&0x7fffffff; /* |x| */ + uy.e = y; + + if(((ix>=0x7ff00000)&&((ix-0x7ff00000)|lx)!=0) || + (uy.bits.exp == 0x7fff && + ((uy.bits.manh&~LDBL_NBIT)|uy.bits.manl) != 0)) + return x+y; /* x or y is nan */ + if(x==y) return (double)y; /* x=y, return y */ + if(x==0.0) { + INSERT_WORDS(x,uy.bits.sign<<31,1); /* return +-minsubnormal */ + t = x*x; + if(t==x) return t; else return x; /* raise underflow flag */ + } + if((hx>0.0) ^ (x < y)) { /* x -= ulp */ + if(lx==0) hx -= 1; + lx -= 1; + } else { /* x += ulp */ + lx += 1; + if(lx==0) hx += 1; + } + ix = hx&0x7ff00000; + if(ix>=0x7ff00000) return x+x; /* overflow */ + if(ix<0x00100000) { /* underflow */ + t = x*x; + if(t!=x) { /* raise underflow flag */ + INSERT_WORDS(x,hx,lx); + return x; + } + } + INSERT_WORDS(x,hx,lx); + return x; +} diff --git a/src/openlibm/src/s_nexttoward.c.o b/src/openlibm/src/s_nexttoward.c.o new file mode 100644 index 0000000000000000000000000000000000000000..445cda191d13f023a7241fa7816dba948df400f4 GIT binary patch literal 1624 zcmb<-^>JfjWMqH=Mg}_u1P><4z!1TVU^{@B4h%dD+zhvKR5;Q+`0EaNbYAp0_)?+s z#O)fD7pnjN|F5_G|Nnh`8Lut_!-sm#3;eCS7#J8lx?NNRzF$aN`M;jOWdZ{O!zX@0 z7nKVjQ|^N3msM;fId^Zq=D2$^jbGk{fgz3m{mC?by@UK+vlti{_*P@D><1sndmMbA;L&`7G0lTN??4*A#)(h-ktaU!3;L)$_{1;Zqw*k)U+)Be7szt{ z)-7Ng1zc1f9OjpA0D0r?jk_@_7e4U|xTst>%rDR2(Osg#;nDfQ&ea&4*c_v-~V{`h6DffV-6PIOZ=N(GPYjgcRASnim~%x z<3mtjH2wsUB`%FW|NrM_s29QJ>ds4Gk8xfA`|EHTzkCbGxeUz*8JiC=^1B>-y%8Kf zpZFsV9AYY-ywr-4lKk?-q7=Pk1_TFUGRSWr783&l z0|Vg|kB{M_8syb=bzy!?_> zJ$JuQ-QtqONJRG3%pm2gR!IUCYKT@^@iys9=0GNeJpbM)rFfed1Fffp-Uk7Tx0jf0&F#Gk< z#9{WsXj7=O zAHl%D0Lo9W_=1^z1FByFD!>VKC(M4BILMh$rBIa+Dgr8)0O2xlLE{KrKgeA4xC3d~ j0o4ymUm!jVgY1K`L9`&$To4->e}L*wM;3&J6|xWjRBQBo literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_nexttowardf.c b/src/openlibm/src/s_nexttowardf.c new file mode 100644 index 0000000..bf50862 --- /dev/null +++ b/src/openlibm/src/s_nexttowardf.c @@ -0,0 +1,61 @@ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_nexttowardf.c,v 1.3 2011/02/10 07:38:38 das Exp $"); + +#include +#include + +#include "fpmath.h" +#include "math_private.h" + +#define LDBL_INFNAN_EXP (LDBL_MAX_EXP * 2 - 1) + +#ifdef OLM_LONG_DOUBLE +OLM_DLLEXPORT float +nexttowardf(float x, long double y) +{ + union IEEEl2bits uy; + volatile float t; + int32_t hx,ix; + + GET_FLOAT_WORD(hx,x); + ix = hx&0x7fffffff; /* |x| */ + uy.e = y; + + if((ix>0x7f800000) || + (uy.bits.exp == LDBL_INFNAN_EXP && + ((uy.bits.manh&~LDBL_NBIT)|uy.bits.manl) != 0)) + return x+y; /* x or y is nan */ + if(x==y) return (float)y; /* x=y, return y */ + if(ix==0) { /* x == 0 */ + SET_FLOAT_WORD(x,(uy.bits.sign<<31)|1);/* return +-minsubnormal */ + t = x*x; + if(t==x) return t; else return x; /* raise underflow flag */ + } + if((hx>=0) ^ (x < y)) /* x -= ulp */ + hx -= 1; + else /* x += ulp */ + hx += 1; + ix = hx&0x7f800000; + if(ix>=0x7f800000) return x+x; /* overflow */ + if(ix<0x00800000) { /* underflow */ + t = x*x; + if(t!=x) { /* raise underflow flag */ + SET_FLOAT_WORD(x,hx); + return x; + } + } + SET_FLOAT_WORD(x,hx); + return x; +} +#endif diff --git a/src/openlibm/src/s_nexttowardf.c.o b/src/openlibm/src/s_nexttowardf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..fec7210a321067cd8bbc1a563974cd87b8b2bb72 GIT binary patch literal 1552 zcmb<-^>JfjWMqH=Mg}_u1P><4z#zbkU^{@B4h%dD+zg-j1zl9Gbi1frxt*iJ(Rr}( z;s5{t>u=YnylDK%z|c_7-`>H%z~Ipxq9XA9Qrh=J|LaRqKq_y7biAzM;%{kUU|_g= z^EKPuoBZ+)46P^mTN^+kH~6=?sC+!|g8kqF`Q{UhY5aKy_%%*^=8rt_nP1RH<;iD$ z0Uwno{CX$&yB0DqFz~m|W?*3W%rD@g^5ihTJcCDfi3*2D=O>SYuM`>|f!xITsiX~L z^9>i3D>q|Qu7K5EIm|B)vX0^I4HPj3kjlIKJ!N$ILzSg z>};i=;qDizsbFZLXQXGSU}RuqYG7z+pr8?ynxf#5SOS&MHP-}(IRgU=0|SEs0|Nsq z0|SG*Unm0;1LFaZ7%a{hp?q$rdJ!niSQW&;SRueD&BM+yfsug$BrXG$vxaGg^084M zB`gdd|6`M5#*$(L85kIZki_A36vyYKR+N*p32EF2vA_$!UW0j;I@7F91IK$`T zsvk`m!z!2pGzoNJR|W +#include + +#include "math_private.h" + +static const double Zero[] = {0.0, -0.0,}; + +/* + * Return the IEEE remainder and set *quo to the last n bits of the + * quotient, rounded to the nearest integer. We choose n=31 because + * we wind up computing all the integer bits of the quotient anyway as + * a side-effect of computing the remainder by the shift and subtract + * method. In practice, this is far more bits than are needed to use + * remquo in reduction algorithms. + */ +OLM_DLLEXPORT double +remquo(double x, double y, int *quo) +{ + int32_t n,hx,hy,hz,ix,iy,sx,i; + u_int32_t lx,ly,lz,q,sxy; + + EXTRACT_WORDS(hx,lx,x); + EXTRACT_WORDS(hy,ly,y); + sxy = (hx ^ hy) & 0x80000000; + sx = hx&0x80000000; /* sign of x */ + hx ^=sx; /* |x| */ + hy &= 0x7fffffff; /* |y| */ + + /* purge off exception values */ + if((hy|ly)==0||(hx>=0x7ff00000)|| /* y=0,or x not finite */ + ((hy|((ly|-ly)>>31))>0x7ff00000)) /* or y is NaN */ + return (x*y)/(x*y); + if(hx<=hy) { + if((hx>31]; /* |x|=|y| return x*0*/ + } + } + + /* determine ix = ilogb(x) */ + if(hx<0x00100000) { /* subnormal x */ + if(hx==0) { + for (ix = -1043, i=lx; i>0; i<<=1) ix -=1; + } else { + for (ix = -1022,i=(hx<<11); i>0; i<<=1) ix -=1; + } + } else ix = (hx>>20)-1023; + + /* determine iy = ilogb(y) */ + if(hy<0x00100000) { /* subnormal y */ + if(hy==0) { + for (iy = -1043, i=ly; i>0; i<<=1) iy -=1; + } else { + for (iy = -1022,i=(hy<<11); i>0; i<<=1) iy -=1; + } + } else iy = (hy>>20)-1023; + + /* set up {hx,lx}, {hy,ly} and align y to x */ + if(ix >= -1022) + hx = 0x00100000|(0x000fffff&hx); + else { /* subnormal x, shift x to normal */ + n = -1022-ix; + if(n<=31) { + hx = (hx<>(32-n)); + lx <<= n; + } else { + hx = lx<<(n-32); + lx = 0; + } + } + if(iy >= -1022) + hy = 0x00100000|(0x000fffff&hy); + else { /* subnormal y, shift y to normal */ + n = -1022-iy; + if(n<=31) { + hy = (hy<>(32-n)); + ly <<= n; + } else { + hy = ly<<(n-32); + ly = 0; + } + } + + /* fix point fmod */ + n = ix - iy; + q = 0; + while(n--) { + hz=hx-hy;lz=lx-ly; if(lx>31); lx = lx+lx;} + else {hx = hz+hz+(lz>>31); lx = lz+lz; q++;} + q <<= 1; + } + hz=hx-hy;lz=lx-ly; if(lx=0) {hx=hz;lx=lz;q++;} + + /* convert back to floating value and restore the sign */ + if((hx|lx)==0) { /* return sign(x)*0 */ + q &= 0x7fffffff; + *quo = (sxy ? -q : q); + return Zero[(u_int32_t)sx>>31]; + } + while(hx<0x00100000) { /* normalize x */ + hx = hx+hx+(lx>>31); lx = lx+lx; + iy -= 1; + } + if(iy>= -1022) { /* normalize output */ + hx = ((hx-0x00100000)|((iy+1023)<<20)); + } else { /* subnormal output */ + n = -1022 - iy; + if(n<=20) { + lx = (lx>>n)|((u_int32_t)hx<<(32-n)); + hx >>= n; + } else if (n<=31) { + lx = (hx<<(32-n))|(lx>>n); hx = 0; + } else { + lx = hx>>(n-32); hx = 0; + } + } +fixup: + INSERT_WORDS(x,hx,lx); + y = fabs(y); + if (y < 0x1p-1021) { + if (x+x>y || (x+x==y && (q & 1))) { + q++; + x-=y; + } + } else if (x>0.5*y || (x==0.5*y && (q & 1))) { + q++; + x-=y; + } + GET_HIGH_WORD(hx,x); + SET_HIGH_WORD(x,hx^sx); + q &= 0x7fffffff; + *quo = (sxy ? -q : q); + return x; +} + +#if LDBL_MANT_DIG == 53 +openlibm_weak_reference(remquo, remquol); +#endif diff --git a/src/openlibm/src/s_remquof.c b/src/openlibm/src/s_remquof.c new file mode 100644 index 0000000..1983ed5 --- /dev/null +++ b/src/openlibm/src/s_remquof.c @@ -0,0 +1,123 @@ +/* @(#)e_fmod.c 1.3 95/01/18 */ +/*- + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_remquof.c,v 1.1 2005/03/25 04:40:44 das Exp $"); + +#include + +#include "math_private.h" + +static const float Zero[] = {0.0, -0.0,}; + +/* + * Return the IEEE remainder and set *quo to the last n bits of the + * quotient, rounded to the nearest integer. We choose n=31 because + * we wind up computing all the integer bits of the quotient anyway as + * a side-effect of computing the remainder by the shift and subtract + * method. In practice, this is far more bits than are needed to use + * remquo in reduction algorithms. + */ +OLM_DLLEXPORT float +remquof(float x, float y, int *quo) +{ + int32_t n,hx,hy,hz,ix,iy,sx,i; + u_int32_t q,sxy; + + GET_FLOAT_WORD(hx,x); + GET_FLOAT_WORD(hy,y); + sxy = (hx ^ hy) & 0x80000000; + sx = hx&0x80000000; /* sign of x */ + hx ^=sx; /* |x| */ + hy &= 0x7fffffff; /* |y| */ + + /* purge off exception values */ + if(hy==0||hx>=0x7f800000||hy>0x7f800000) /* y=0,NaN;or x not finite */ + return (x*y)/(x*y); + if(hx>31]; /* |x|=|y| return x*0*/ + } + + /* determine ix = ilogb(x) */ + if(hx<0x00800000) { /* subnormal x */ + for (ix = -126,i=(hx<<8); i>0; i<<=1) ix -=1; + } else ix = (hx>>23)-127; + + /* determine iy = ilogb(y) */ + if(hy<0x00800000) { /* subnormal y */ + for (iy = -126,i=(hy<<8); i>0; i<<=1) iy -=1; + } else iy = (hy>>23)-127; + + /* set up {hx,lx}, {hy,ly} and align y to x */ + if(ix >= -126) + hx = 0x00800000|(0x007fffff&hx); + else { /* subnormal x, shift x to normal */ + n = -126-ix; + hx <<= n; + } + if(iy >= -126) + hy = 0x00800000|(0x007fffff&hy); + else { /* subnormal y, shift y to normal */ + n = -126-iy; + hy <<= n; + } + + /* fix point fmod */ + n = ix - iy; + q = 0; + while(n--) { + hz=hx-hy; + if(hz<0) hx = hx << 1; + else {hx = hz << 1; q++;} + q <<= 1; + } + hz=hx-hy; + if(hz>=0) {hx=hz;q++;} + + /* convert back to floating value and restore the sign */ + if(hx==0) { /* return sign(x)*0 */ + q &= 0x7fffffff; + *quo = (sxy ? -q : q); + return Zero[(u_int32_t)sx>>31]; + } + while(hx<0x00800000) { /* normalize x */ + hx <<= 1; + iy -= 1; + } + if(iy>= -126) { /* normalize output */ + hx = ((hx-0x00800000)|((iy+127)<<23)); + } else { /* subnormal output */ + n = -126 - iy; + hx >>= n; + } +fixup: + SET_FLOAT_WORD(x,hx); + y = fabsf(y); + if (y < 0x1p-125f) { + if (x+x>y || (x+x==y && (q & 1))) { + q++; + x-=y; + } + } else if (x>0.5f*y || (x==0.5f*y && (q & 1))) { + q++; + x-=y; + } + GET_FLOAT_WORD(hx,x); + SET_FLOAT_WORD(x,hx^sx); + q &= 0x7fffffff; + *quo = (sxy ? -q : q); + return x; +} diff --git a/src/openlibm/src/s_remquol.c b/src/openlibm/src/s_remquol.c new file mode 100644 index 0000000..b610b67 --- /dev/null +++ b/src/openlibm/src/s_remquol.c @@ -0,0 +1,178 @@ +/* @(#)e_fmod.c 1.3 95/01/18 */ +/*- + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_remquol.c,v 1.2 2008/07/31 20:09:47 das Exp $"); + +#include +#include +#include + +#include "fpmath.h" +#include "math_private.h" + +#define BIAS (LDBL_MAX_EXP - 1) + +#if LDBL_MANL_SIZE > 32 +typedef u_int64_t manl_t; +#else +typedef u_int32_t manl_t; +#endif + +#if LDBL_MANH_SIZE > 32 +typedef u_int64_t manh_t; +#else +typedef u_int32_t manh_t; +#endif + +/* + * These macros add and remove an explicit integer bit in front of the + * fractional mantissa, if the architecture doesn't have such a bit by + * default already. + */ +#ifdef LDBL_IMPLICIT_NBIT +#define SET_NBIT(hx) ((hx) | (1ULL << LDBL_MANH_SIZE)) +#define HFRAC_BITS LDBL_MANH_SIZE +#else +#define SET_NBIT(hx) (hx) +#define HFRAC_BITS (LDBL_MANH_SIZE - 1) +#endif + +#define MANL_SHIFT (LDBL_MANL_SIZE - 1) + +static const long double Zero[] = {0.0L, -0.0L}; + +/* + * Return the IEEE remainder and set *quo to the last n bits of the + * quotient, rounded to the nearest integer. We choose n=31 because + * we wind up computing all the integer bits of the quotient anyway as + * a side-effect of computing the remainder by the shift and subtract + * method. In practice, this is far more bits than are needed to use + * remquo in reduction algorithms. + * + * Assumptions: + * - The low part of the mantissa fits in a manl_t exactly. + * - The high part of the mantissa fits in an int64_t with enough room + * for an explicit integer bit in front of the fractional bits. + */ +OLM_DLLEXPORT long double +remquol(long double x, long double y, int *quo) +{ + union IEEEl2bits ux, uy; + int64_t hx,hz; /* We need a carry bit even if LDBL_MANH_SIZE is 32. */ + manh_t hy; + manl_t lx,ly,lz; + int ix,iy,n,q,sx,sxy; + + ux.e = x; + uy.e = y; + sx = ux.bits.sign; + sxy = sx ^ uy.bits.sign; + ux.bits.sign = 0; /* |x| */ + uy.bits.sign = 0; /* |y| */ + x = ux.e; + + /* purge off exception values */ + if((uy.bits.exp|uy.bits.manh|uy.bits.manl)==0 || /* y=0 */ + (ux.bits.exp == BIAS + LDBL_MAX_EXP) || /* or x not finite */ + (uy.bits.exp == BIAS + LDBL_MAX_EXP && + ((uy.bits.manh&~LDBL_NBIT)|uy.bits.manl)!=0)) /* or y is NaN */ + return (x*y)/(x*y); + if(ux.bits.exp<=uy.bits.exp) { + if((ux.bits.exp>MANL_SHIFT); lx = lx+lx;} + else {hx = hz+hz+(lz>>MANL_SHIFT); lx = lz+lz; q++;} + q <<= 1; + } + hz=hx-hy;lz=lx-ly; if(lx=0) {hx=hz;lx=lz;q++;} + + /* convert back to floating value and restore the sign */ + if((hx|lx)==0) { /* return sign(x)*0 */ + q &= 0x7fffffff; + *quo = (sxy ? -q : q); + return Zero[sx]; + } + while(hx<(1ULL<>MANL_SHIFT); lx = lx+lx; + iy -= 1; + } + ux.bits.manh = hx; /* The integer bit is truncated here if needed. */ + ux.bits.manl = lx; + if (iy < LDBL_MIN_EXP) { + ux.bits.exp = iy + (BIAS + 512); + ux.e *= 0x1p-512; + } else { + ux.bits.exp = iy + BIAS; + } + ux.bits.sign = 0; + x = ux.e; +fixup: + y = fabsl(y); + if (y < LDBL_MIN * 2) { + if (x+x>y || (x+x==y && (q & 1))) { + q++; + x-=y; + } + } else if (x>0.5*y || (x==0.5*y && (q & 1))) { + q++; + x-=y; + } + + ux.e = x; + ux.bits.sign ^= sx; + x = ux.e; + + q &= 0x7fffffff; + *quo = (sxy ? -q : q); + return x; +} diff --git a/src/openlibm/src/s_rint.c b/src/openlibm/src/s_rint.c new file mode 100644 index 0000000..f81e692 --- /dev/null +++ b/src/openlibm/src/s_rint.c @@ -0,0 +1,92 @@ +/* @(#)s_rint.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_rint.c,v 1.16 2008/02/22 02:30:35 das Exp $"); + +/* + * rint(x) + * Return x rounded to integral value according to the prevailing + * rounding mode. + * Method: + * Using floating addition. + * Exception: + * Inexact flag raised if x not equal to rint(x). + */ + +#include +#include + +#include "math_private.h" + +static const double +TWO52[2]={ + 4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */ + -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */ +}; + +OLM_DLLEXPORT double +rint(double x) +{ + int32_t i0,j0,sx; + u_int32_t i,i1; + double w,t; + EXTRACT_WORDS(i0,i1,x); + sx = (i0>>31)&1; + j0 = ((i0>>20)&0x7ff)-0x3ff; + if(j0<20) { + if(j0<0) { + if(((i0&0x7fffffff)|i1)==0) return x; + i1 |= (i0&0x0fffff); + i0 &= 0xfffe0000; + i0 |= ((i1|-i1)>>12)&0x80000; + SET_HIGH_WORD(x,i0); + STRICT_ASSIGN(double,w,TWO52[sx]+x); + t = w-TWO52[sx]; + GET_HIGH_WORD(i0,t); + SET_HIGH_WORD(t,(i0&0x7fffffff)|(sx<<31)); + return t; + } else { + i = (0x000fffff)>>j0; + if(((i0&i)|i1)==0) return x; /* x is integral */ + i>>=1; + if(((i0&i)|i1)!=0) { + /* + * Some bit is set after the 0.5 bit. To avoid the + * possibility of errors from double rounding in + * w = TWO52[sx]+x, adjust the 0.25 bit to a lower + * guard bit. We do this for all j0<=51. The + * adjustment is trickiest for j0==18 and j0==19 + * since then it spans the word boundary. + */ + if(j0==19) i1 = 0x40000000; else + if(j0==18) i1 = 0x80000000; else + i0 = (i0&(~i))|((0x20000)>>j0); + } + } + } else if (j0>51) { + if(j0==0x400) return x+x; /* inf or NaN */ + else return x; /* x is integral */ + } else { + i = ((u_int32_t)(0xffffffff))>>(j0-20); + if((i1&i)==0) return x; /* x is integral */ + i>>=1; + if((i1&i)!=0) i1 = (i1&(~i))|((0x40000000)>>(j0-20)); + } + INSERT_WORDS(x,i0,i1); + STRICT_ASSIGN(double,w,TWO52[sx]+x); + return w-TWO52[sx]; +} + +#if (LDBL_MANT_DIG == 53) +openlibm_weak_reference(rint, rintl); +#endif diff --git a/src/openlibm/src/s_rint.c.o b/src/openlibm/src/s_rint.c.o new file mode 100644 index 0000000000000000000000000000000000000000..f3c52126a3338bd36d92800b45a8099e028a4b7b GIT binary patch literal 1880 zcmb<-^>JfjWMqH=Mg}_u1P><4z;J^Z!FB*M9T@l+cp1_>`0I{&bbfN|{OED;l|ttQ z$Ic6#*AM;>aXk1!UiCja14C~I0e}0C`KO8#`IVxUq z9LQc3x4|aa=IQUS(gY$$( zFE7k|mV+R}PkiE!IPr-;<^(A4PIz=4>^$Ic@TEfIL$D2}JPtlm@Zh`vQhDI;C;o^7 zhxz3hTn$gY^#A|=KiK&VFJ1os{}1*jnD6k?};i=;qDiz zsbFZLXQXGSU}RuqYG7z+pr8?ynxf#5SOS&MHP>VSg(HIk0|NsnNZkEG8JHLt53n#W zz|#aHl+OvVfI$RGGgbvLFjfdKO7pODOkiXHi_1Xey0IlFs2q#}DPdvwi0lcN6azEd zcDN7&7uZc8S3<-DAQYHn2D={2gcBfnAtZC)ZYqv1%FHX#OJ)cO_ct|S0C7N?j)4dU zP=bSm$sbTk`v3pG8pxqo#6e*O(!vCl1F^wauedU|Br%CWuehWLLTA8OMX5Q7dL^k9 zB@B8gi6w~)dP&8_40=WR5KeM_ZflO!WYT}Q_>8OaD%A_3oHuI37Vc1|lEa4g +#include +#include + +#include "math_private.h" + +static const float +TWO23[2]={ + 8.3886080000e+06, /* 0x4b000000 */ + -8.3886080000e+06, /* 0xcb000000 */ +}; + +OLM_DLLEXPORT float +rintf(float x) +{ + int32_t i0,j0,sx; + float w,t; + GET_FLOAT_WORD(i0,x); + sx = (i0>>31)&1; + j0 = ((i0>>23)&0xff)-0x7f; + if(j0<23) { + if(j0<0) { + if((i0&0x7fffffff)==0) return x; + STRICT_ASSIGN(float,w,TWO23[sx]+x); + t = w-TWO23[sx]; + GET_FLOAT_WORD(i0,t); + SET_FLOAT_WORD(t,(i0&0x7fffffff)|(sx<<31)); + return t; + } + STRICT_ASSIGN(float,w,TWO23[sx]+x); + return w-TWO23[sx]; + } + if(j0==0x80) return x+x; /* inf or NaN */ + else return x; /* x is integral */ +} diff --git a/src/openlibm/src/s_rintf.c.o b/src/openlibm/src/s_rintf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..6ca22074b33641c437cd93d71d96731f7b8d83dd GIT binary patch literal 1608 zcmb<-^>JfjWMqH=Mg}_u1P><4z;J>I!FB*M9T@l+cp1|8>kf5ZIQT=Hf7^lP7xm3Q z#Oh@_FCKg;-+G`@`TL>&|NqyQ8Xr#6#}WNU|=YH_nAN9z+rxQ2L_K`R*?8- zegU42&-@VwKl8^NJj^c-6K{OPz`)ReBAdovcR&?nF6V_b{=5T+LE6FCn}LDhG=sad zvz3B|yI-iLf}x3?k)EM~k%5t^fuW&+f<{nkih@UC2~#}{Shm89trBy2KoQbe+Y=iAr1;NkQ7Kg2!q&QtXEu_TauW>pjTW{1fervtfJJMM7@&K ziV_CBl*E!m2EC->Vg|jUdC~I#z3P%ZbcT-VSt!Pu6{$P{ZQw^jXnWo!Q2bw z!rc$!TSE22{0S4k0A=VyX&41_Ka6&Q>W9h0Xsj6oi`pOt1_pKp1_pHZ!?FOnyU_iU z1vL|0zX8;Ng!F?_At>LV$G-*CKv+D3;vZC&!0d;KgRFrng?SxJCx9dv7#Jpic?=9Z q(6S0$Kgdk + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_rintl.c,v 1.5 2008/02/22 11:59:05 bde Exp $"); + +#include +#include +#include + +#include "fpmath.h" + +//VBS +#include "math_private.h" + + +#if LDBL_MAX_EXP != 0x4000 +/* We also require the usual bias, min exp and expsign packing. */ +#error "Unsupported long double format" +#endif + +#define BIAS (LDBL_MAX_EXP - 1) + +static const float +shift[2] = { +#if LDBL_MANT_DIG == 64 + 0x1.0p63, -0x1.0p63 +#elif LDBL_MANT_DIG == 113 + 0x1.0p112, -0x1.0p112 +#else +#error "Unsupported long double format" +#endif +}; +static const float zero[2] = { 0.0, -0.0 }; + +OLM_DLLEXPORT long double +rintl(long double x) +{ + union IEEEl2bits u; + u_int32_t expsign; + int ex, sign; + + u.e = x; + expsign = u.xbits.expsign; + ex = expsign & 0x7fff; + + if (ex >= BIAS + LDBL_MANT_DIG - 1) { + if (ex == BIAS + LDBL_MAX_EXP) + return (x + x); /* Inf, NaN, or unsupported format */ + return (x); /* finite and already an integer */ + } + sign = expsign >> 15; + + /* + * The following code assumes that intermediate results are + * evaluated in long double precision. If they are evaluated in + * greater precision, double rounding may occur, and if they are + * evaluated in less precision (as on i386), results will be + * wildly incorrect. + */ + x += shift[sign]; + x -= shift[sign]; + + /* + * If the result is +-0, then it must have the same sign as x, but + * the above calculation doesn't always give this. Fix up the sign. + */ + if (ex < BIAS && x == 0.0L) + return (zero[sign]); + + return (x); +} + +/* + * We save and restore the floating-point environment to avoid raising + * an inexact exception. We can get away with using fesetenv() + * instead of feclearexcept()/feupdateenv() to restore the environment + * because the only exception defined for rint() is overflow, and + * rounding can't overflow as long as emax >= p. + */ +#define DECL(type, fn, rint) \ +OLM_DLLEXPORT type \ +fn(type x) \ +{ \ + type ret; \ + fenv_t env; \ + \ + fegetenv(&env); \ + ret = rint(x); \ + fesetenv(&env); \ + return (ret); \ +} +DECL(long double, nearbyintl, rintl) diff --git a/src/openlibm/src/s_round.c b/src/openlibm/src/s_round.c new file mode 100644 index 0000000..a982ec3 --- /dev/null +++ b/src/openlibm/src/s_round.c @@ -0,0 +1,55 @@ +/*- + * Copyright (c) 2003, Steven G. Kargl + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_round.c,v 1.4 2005/12/02 13:45:06 bde Exp $"); + +#include + +#include "math_private.h" + +OLM_DLLEXPORT double +round(double x) +{ + double t; + uint32_t hx; + + GET_HIGH_WORD(hx, x); + if ((hx & 0x7fffffff) == 0x7ff00000) + return (x + x); + + if (!(hx & 0x80000000)) { + t = floor(x); + if (t - x <= -0.5) + t += 1; + return (t); + } else { + t = floor(-x); + if (t + x <= -0.5) + t += 1; + return (-t); + } +} diff --git a/src/openlibm/src/s_round.c.o b/src/openlibm/src/s_round.c.o new file mode 100644 index 0000000000000000000000000000000000000000..5d871b1bdbf0dca0ec486fb865c12b53400f9559 GIT binary patch literal 1984 zcmb<-^>JfjWMqH=Mg}_u1P><4z`($QU^{@B4h;MZd<1SYI@MwM`(R!f5{1d;RiwegJkk(K90zN7nY5W=&KJmv~{KPN7 z3ldG^*FROn@rgfz6~yysJ|c0LU!LJJf1N0Z57C~+AAShQh)?_ivLH!>qKFe|{Q5T$ z#(*?HjcNg@Wcb7nQlfG2Fqj7;9_)v(KG;KOh6X6jz~JueY^9*#?iZ@5U}&Oeq-UsL zWME`!U}$Kdpb?asqTrEO0+rA;*MtO<0s{jB$P?~75`Vl~19Zi;u&Fo5`Jz10;YQgY02p`1l{2EHjpv z4QVa|XLP+L=-ORwi0169;S;(px7#NDoF{NgUan*+}9bvtZ_f{11`>nFGQgHW=#_SLT)^ zCNbz0mlQ$h3>d2@H78N8B(i;8>bd)c>K2zICTBzW>3OAk1x5JS0Q#0bziV|~E!7ibQ0QnD; z=Fn3Fq>Nx-fTaVNCFp5E8d|i#)Wg&*fCkn9r~nTG12}cT(xU`aTn#D?N&`?KF!d8m zViF*?B8%!UFo4rIx%v&E_6s2!3SvVoLiaDs{V>`NhkgMZ`eEk5XdkG4SUv$+4Z;dg z{rVsd5{3$c!xAJM3e^u{BV&Jya)sOBjn7?5PYoTVM>u-SS zw}2^x(&+jtaHO9EXoSMj2`K$=LE{=^6iggs4Z7VR`5hn$1_lOL`U6!_pfnD%AEqBv qjzg^iX@lbmsG*?r2^WO=6`3yxEx(Y(K4V-ro5D literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_roundf.c b/src/openlibm/src/s_roundf.c new file mode 100644 index 0000000..784a8a5 --- /dev/null +++ b/src/openlibm/src/s_roundf.c @@ -0,0 +1,53 @@ +/*- + * Copyright (c) 2003, Steven G. Kargl + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_roundf.c,v 1.4 2005/12/02 13:45:06 bde Exp $"); + +#include + +#include "math_private.h" + +OLM_DLLEXPORT float +roundf(float x) +{ + float t; + + if (!isfinite(x)) + return (x); + + if (x >= 0.0) { + t = floorf(x); + if (t - x <= -0.5) + t += 1.0; + return (t); + } else { + t = floorf(-x); + if (t + x <= -0.5) + t += 1.0; + return (-t); + } +} diff --git a/src/openlibm/src/s_roundf.c.o b/src/openlibm/src/s_roundf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..d07fcd165072c8b54360b2ae73519128a5ed2009 GIT binary patch literal 2024 zcmb<-^>JfjWMqH=Mg}_u1P><4z@Wi`U^{@B4h;MZd<-7VZzMkR3%aQAya0)Q<`?i$ z;b}d<-_p#$z>voO{s6!Ji6SF@je|(i{2CWN^T%BL%rC$T(!;NRs)*w=e*`Ot84?D*MMg|5I z1_lNhsN4z=?ZT(P6u`yD;lj=2&c(;!$nDO@0TRc7LH4mQeEg41ni)$B@_-eBTn%Qx z2|+N673?oC6H17IX*Mv4Oh_{@FbE-;4|Y2P1A`I+1A_pvLMU4ghd4uVd{KUBUP_u? zGJ~FvvmuBu0ujax5OIe1_{`$8%)HE!)HH^)oc#QvG?0mdnv_cu%^38O^K)}k^GX=>^72bk_1yhJb&E?9le3}x^t@8N zf};F_)S{9~20gIhsTuKUMTxnoV3$xtfcytav*;-bQkF0gupA3%z*eWsvb^(1Q{3@^x*;! z22>avW+0JJsQn-|GS-JFL>9!N7L + +#include "math_private.h" + +OLM_DLLEXPORT long double +roundl(long double x) +{ + long double t; + + if (!isfinite(x)) + return (x); + + if (x >= 0.0) { + t = floorl(x); + if (t - x <= -0.5) + t += 1.0; + return (t); + } else { + t = floorl(-x); + if (t + x <= -0.5) + t += 1.0; + return (-t); + } +} diff --git a/src/openlibm/src/s_roundl.c.o b/src/openlibm/src/s_roundl.c.o new file mode 100644 index 0000000000000000000000000000000000000000..a61dc9676fe318be011c8906b8c34d7bc06e9c08 GIT binary patch literal 1768 zcmb<-^>JfjWMqH=Mg}_u1P><4z>vX=U^{@B4h(z@ybK=AZ#e#!s7QeD3y^rcW5n$o z6@k_RC3-jC-8^~wj4?FpTXVP*-Amf-7i#A!O%p{NY7Bg$iT?d zz|hb@K_e(NMZqJn1S+9xuF1f_!oa|wz`(!&a)i5IC<7A%;{lKu%-sbIUQ zK!E%ON)w+>spu7uZf+-juM%zL48-QgI#0e-< zA4{BuI%3S<;a9AphtDM%QO8$c2a3=AuvBA{{z6y`Ad nVfsO4qQ^Z*iw4wCZ4d_uLyd)tfXXp!`d>ixSHe|780h)|#`4N3 literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_scalbln.c b/src/openlibm/src/s_scalbln.c new file mode 100644 index 0000000..8239db5 --- /dev/null +++ b/src/openlibm/src/s_scalbln.c @@ -0,0 +1,80 @@ +/*- + * Copyright (c) 2004 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_scalbln.c,v 1.2 2005/03/07 04:57:50 das Exp $"); + +#include +#include + +#include "math_private.h" + +OLM_DLLEXPORT double +scalbln (double x, long n) +{ + int in; + + in = (int)n; + if (in != n) { + if (n > 0) + in = INT_MAX; + else + in = INT_MIN; + } + return (scalbn(x, in)); +} + +OLM_DLLEXPORT float +scalblnf (float x, long n) +{ + int in; + + in = (int)n; + if (in != n) { + if (n > 0) + in = INT_MAX; + else + in = INT_MIN; + } + return (scalbnf(x, in)); +} + +#ifdef OLM_LONG_DOUBLE +OLM_DLLEXPORT long double +scalblnl (long double x, long n) +{ + int in; + + in = (int)n; + if (in != n) { + if (n > 0) + in = INT_MAX; + else + in = INT_MIN; + } + return (scalbnl(x, (int)n)); +} +#endif diff --git a/src/openlibm/src/s_scalbln.c.o b/src/openlibm/src/s_scalbln.c.o new file mode 100644 index 0000000000000000000000000000000000000000..97f0427add0c834190b88eba6d5f1babfe241dde GIT binary patch literal 1688 zcmb<-^>JfjWMqH=Mg}_u1P><4z!1TVU^{@B4h*~uJPaPm*E@fBSpF*EH$33c`k#OP zf$uk185kHEI*-2uDI+8gR>a`$>};i=;qDizsbFZLXQXGSU}RuqYG7z+pr8?ynxf#5 zSOS&MHP-|g%fQ0Gz@WguzyPw#-7l1ZiGlF|NDM5=z`(!=<-`0U0+nE_3SwZa5MY$% zVdt2@$iN`Lz`!5_l>?avVuHjBKn$oIASOt^3y1-=6UxL%f$U{r`1l{20%j~B%*(*Q zAcQ0ibBibg#Et0YfZPmH4^s!DRdJ}-g_;kEJ4m>J%rwKHo}oCtI5{yVDJM@anE}dz z(0LFlCoc`cfYCX5IZ%Ndq%Z}=2?+oB4*@nHOBooz@yEu%zyK3>L=xvf5{LPViGhIu zgrUk9OrQ*q7zo4Ed7z2I{L7$MT$x*vn8cu0Tv7y~GhnQu)SN`UlGKV42ECNTl0*i* zq~c-*z2yAd+|;}h2EDxel2ko+zfj%clEma}C_g=~RIi{YzaX`!q>@1oY(i>Ad|FXr zZYtCTlu;o6fYJ~sjF3%&`NtJm5KA0NL&F%R9;Q436j%%l46tzG0_PP522hxT)JT8` z1_lN-s5nx#2g|gANlXIdR%B5f28fyD>NkYi56g!zvtjn@!vvr-%zhYc1=SCghErSM zEK~+eA57GXfq{V?EzN=Cc7O;51_pF@!NLzJ&5#7O9~#^+VTKn_Rs@uWQRw<(am3#O zsDa4w2ht0|AhTfc2l5Y8DM%QO9Y7Kc3=B7*BHRoN44^nd*Ut$Rhbn_p5>P|!;35zP a)L00Ifq_8~hyE8({h%@et{56t$b0~V8k4aA literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_scalbn.c b/src/openlibm/src/s_scalbn.c new file mode 100644 index 0000000..dc3a0cf --- /dev/null +++ b/src/openlibm/src/s_scalbn.c @@ -0,0 +1,66 @@ +/* @(#)s_scalbn.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * scalbn (double x, int n) + * scalbn(x,n) returns x* 2**n computed by exponent + * manipulation rather than by actually performing an + * exponentiation or a multiplication. + */ + +#include "cdefs-compat.h" + +#include +#include + +#include "math_private.h" + +static const double +two54 = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */ +twom54 = 5.55111512312578270212e-17, /* 0x3C900000, 0x00000000 */ +huge = 1.0e+300, +tiny = 1.0e-300; + +OLM_DLLEXPORT double +scalbn (double x, int n) +{ + int32_t k,hx,lx; + EXTRACT_WORDS(hx,lx,x); + k = (hx&0x7ff00000)>>20; /* extract exponent */ + if (k==0) { /* 0 or subnormal x */ + if ((lx|(hx&0x7fffffff))==0) return x; /* +-0 */ + x *= two54; + GET_HIGH_WORD(hx,x); + k = ((hx&0x7ff00000)>>20) - 54; + if (n< -50000) return tiny*x; /*underflow*/ + } + if (k==0x7ff) return x+x; /* NaN or Inf */ + k = k+n; + if (k > 0x7fe) return huge*copysign(huge,x); /* overflow */ + if (k > 0) /* normal result */ + {SET_HIGH_WORD(x,(hx&0x800fffff)|(k<<20)); return x;} + if (k <= -54) { + if (n > 50000) /* in case integer overflow in n+k */ + return huge*copysign(huge,x); /*overflow*/ + else return tiny*copysign(tiny,x); /*underflow*/ + } + k += 54; /* subnormal result */ + SET_HIGH_WORD(x,(hx&0x800fffff)|(k<<20)); + return x*twom54; +} + +#if (LDBL_MANT_DIG == 53) +openlibm_weak_reference(scalbn, ldexpl); +openlibm_weak_reference(scalbn, scalbnl); +#endif + +openlibm_strong_reference(scalbn, ldexp); diff --git a/src/openlibm/src/s_scalbnf.c b/src/openlibm/src/s_scalbnf.c new file mode 100644 index 0000000..930ab8f --- /dev/null +++ b/src/openlibm/src/s_scalbnf.c @@ -0,0 +1,57 @@ +/* s_scalbnf.c -- float version of s_scalbn.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + + +#include "cdefs-compat.h" + +#include + +#include "math_private.h" + +static const float +two25 = 3.355443200e+07, /* 0x4c000000 */ +twom25 = 2.9802322388e-08, /* 0x33000000 */ +huge = 1.0e+30, +tiny = 1.0e-30; + +OLM_DLLEXPORT float +scalbnf (float x, int n) +{ + int32_t k,ix; + GET_FLOAT_WORD(ix,x); + k = (ix&0x7f800000)>>23; /* extract exponent */ + if (k==0) { /* 0 or subnormal x */ + if ((ix&0x7fffffff)==0) return x; /* +-0 */ + x *= two25; + GET_FLOAT_WORD(ix,x); + k = ((ix&0x7f800000)>>23) - 25; + if (n< -50000) return tiny*x; /*underflow*/ + } + if (k==0xff) return x+x; /* NaN or Inf */ + k = k+n; + if (k > 0xfe) return huge*copysignf(huge,x); /* overflow */ + if (k > 0) /* normal result */ + {SET_FLOAT_WORD(x,(ix&0x807fffff)|(k<<23)); return x;} + if (k <= -25) { + if (n > 50000) /* in case integer overflow in n+k */ + return huge*copysignf(huge,x); /*overflow*/ + else return tiny*copysignf(tiny,x); /*underflow*/ + } + k += 25; /* subnormal result */ + SET_FLOAT_WORD(x,(ix&0x807fffff)|(k<<23)); + return x*twom25; +} + +openlibm_strong_reference(scalbnf, ldexpf); diff --git a/src/openlibm/src/s_scalbnl.c b/src/openlibm/src/s_scalbnl.c new file mode 100644 index 0000000..7732944 --- /dev/null +++ b/src/openlibm/src/s_scalbnl.c @@ -0,0 +1,70 @@ +/* @(#)s_scalbn.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * scalbnl (long double x, int n) + * scalbnl(x,n) returns x* 2**n computed by exponent + * manipulation rather than by actually performing an + * exponentiation or a multiplication. + */ + +/* + * We assume that a long double has a 15-bit exponent. On systems + * where long double is the same as double, scalbnl() is an alias + * for scalbn(), so we don't use this routine. + */ + +#include "cdefs-compat.h" + +#include +#include + +#include "fpmath.h" +#include "math_private.h" + +#if LDBL_MAX_EXP != 0x4000 +#error "Unsupported long double format" +#endif + +static const long double +huge = 0x1p16000L, +tiny = 0x1p-16000L; + +OLM_DLLEXPORT long double +scalbnl (long double x, int n) +{ + union IEEEl2bits u; + int k; + u.e = x; + k = u.bits.exp; /* extract exponent */ + if (k==0) { /* 0 or subnormal x */ + if ((u.bits.manh|u.bits.manl)==0) return x; /* +-0 */ + u.e *= 0x1p+128; + k = u.bits.exp - 128; + if (n< -50000) return tiny*x; /*underflow*/ + } + if (k==0x7fff) return x+x; /* NaN or Inf */ + k = k+n; + if (k >= 0x7fff) return huge*copysignl(huge,x); /* overflow */ + if (k > 0) /* normal result */ + {u.bits.exp = k; return u.e;} + if (k <= -128) { + if (n > 50000) /* in case integer overflow in n+k */ + return huge*copysign(huge,x); /*overflow*/ + else return tiny*copysign(tiny,x); /*underflow*/ + } + k += 128; /* subnormal result */ + u.bits.exp = k; + return u.e*0x1p-128; +} + +openlibm_strong_reference(scalbnl, ldexpl); diff --git a/src/openlibm/src/s_signbit.c b/src/openlibm/src/s_signbit.c new file mode 100644 index 0000000..87f40f2 --- /dev/null +++ b/src/openlibm/src/s_signbit.c @@ -0,0 +1,61 @@ +/*- + * Copyright (c) 2003 Mike Barcroft + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/lib/msun/src/s_signbit.c,v 1.1 2004/07/19 08:16:10 das Exp $ + */ + +#include + +#include "fpmath.h" +#include "math_private.h" + +OLM_DLLEXPORT int +__signbit(double d) +{ + union IEEEd2bits u; + + u.d = d; + return (u.bits.sign); +} + +OLM_DLLEXPORT int +__signbitf(float f) +{ + union IEEEf2bits u; + + u.f = f; + return (u.bits.sign); +} + +#ifdef OLM_LONG_DOUBLE +OLM_DLLEXPORT int +__signbitl(long double e) +{ + union IEEEl2bits u; + + u.e = e; + return (u.bits.sign); +} +#endif diff --git a/src/openlibm/src/s_signbit.c.o b/src/openlibm/src/s_signbit.c.o new file mode 100644 index 0000000000000000000000000000000000000000..5204cb57e85209c711dfa18e1bd9d2dd14738d96 GIT binary patch literal 1440 zcmb<-^>JfjWMqH=Mg}_u1P><4z_5S`!FB*M9T<2RxEazs`0EaM9DHHVzwN+betCv8 z{<;GPU&tTkmu~^9x}BrKal1z41^+e|m5&Eru!EE_xH~&rDQLL+g=#7on&=tn87deV z7?~Ov8X72Q1f`}ZcqEoUC3MX-!NxGKFfcGEFfcH%GB7Z>`-L(vF)$tgiNV~;2<3A^ zlrxAxX~wD`2F3~jMrj^)jtPtm3<3-c3^GtTUMLL`Gk~%=pfpIo3lba3#7TkN!NTzI zKQ;x-SV9zJw-Ayzh!4^$&cMI`5(l{n#D}>@2`UZ>1CTh#eIS~lIKDVDJufMzwn(h$rXkb0PYP;`PYNDPEcKm-E=14s;nVfK5ViNo|W=oMGymLw)I=oOa~LFfz^ zt0c9egh4MQu_Tc}FR8egK`%K!H#aq}gh4Maza&-9-7i$PxFj(-8_G}5E7dC~$}dPQ zDyd}9D@x5t)Jx5XPb*5yO@&%c0VU1A01jm~G&3M+n1KQ2ZZZVFHN5z`(%8z`y{CBXs>Bb3x)zWpL^MRKG4< e1j2v{LpTf!41!Q|;Q~;G1=LaLP(F-8*AD>4u4&Hz literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_signgam.c b/src/openlibm/src/s_signgam.c new file mode 100644 index 0000000..ad72a73 --- /dev/null +++ b/src/openlibm/src/s_signgam.c @@ -0,0 +1,7 @@ +#include + +#include "math_private.h" + +#ifndef OPENLIBM_ONLY_THREAD_SAFE +int signgam = 0; +#endif diff --git a/src/openlibm/src/s_signgam.c.o b/src/openlibm/src/s_signgam.c.o new file mode 100644 index 0000000000000000000000000000000000000000..14d77f970a53c92bfbc3fd5681c3b3f5cb4b5907 GIT binary patch literal 984 zcmb<-^>JfjWMqH=Mg}_u1P><4zz~5X=l~XWVBlilWMFW2cD7Q`aQ6$i;8>bd)c>K2zICTBzW z>3OAk1x5J zqUwi-D?}I^uTUnK(t+A<0OlbGnEm<)AutORpCAT|Hiha3i6P^BWDXJ=rVl3M%D}+D z&cMLH1QUSL1yCB@T_C?grN9)(JaoMvi3K2nfq}sTN`v%))PZP_kOYWeU;yO|jIaYq my#Nsm3=E=B8b*QagRw!hAeOKPiT?!=3=9krP#Q*|>jwZ04?P|L literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_sin.c b/src/openlibm/src/s_sin.c new file mode 100644 index 0000000..cc0a5c6 --- /dev/null +++ b/src/openlibm/src/s_sin.c @@ -0,0 +1,89 @@ +/* @(#)s_sin.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_sin.c,v 1.13 2011/02/10 07:37:50 das Exp $"); + +/* sin(x) + * Return sine function of x. + * + * kernel function: + * __kernel_sin ... sine function on [-pi/4,pi/4] + * __kernel_cos ... cose function on [-pi/4,pi/4] + * __ieee754_rem_pio2 ... argument reduction routine + * + * Method. + * Let S,C and T denote the sin, cos and tan respectively on + * [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2 + * in [-pi/4 , +pi/4], and let n = k mod 4. + * We have + * + * n sin(x) cos(x) tan(x) + * ---------------------------------------------------------- + * 0 S C T + * 1 C -S -1/T + * 2 -S -C T + * 3 -C S -1/T + * ---------------------------------------------------------- + * + * Special cases: + * Let trig be any of sin, cos, or tan. + * trig(+-INF) is NaN, with signals; + * trig(NaN) is that NaN; + * + * Accuracy: + * TRIG(x) returns trig(x) nearly rounded + */ + +#include +#include + +//#define INLINE_REM_PIO2 +#include "math_private.h" +//#include "e_rem_pio2.c" + +OLM_DLLEXPORT double +sin(double x) +{ + double y[2],z=0.0; + int32_t n, ix; + + /* High word of x. */ + GET_HIGH_WORD(ix,x); + + /* |x| ~< pi/4 */ + ix &= 0x7fffffff; + if(ix <= 0x3fe921fb) { + if(ix<0x3e500000) /* |x| < 2**-26 */ + {if((int)x==0) return x;} /* generate inexact */ + return __kernel_sin(x,z,0); + } + + /* sin(Inf or NaN) is NaN */ + else if (ix>=0x7ff00000) return x-x; + + /* argument reduction needed */ + else { + n = __ieee754_rem_pio2(x,y); + switch(n&3) { + case 0: return __kernel_sin(y[0],y[1],1); + case 1: return __kernel_cos(y[0],y[1]); + case 2: return -__kernel_sin(y[0],y[1],1); + default: + return -__kernel_cos(y[0],y[1]); + } + } +} + +#if (LDBL_MANT_DIG == 53) +openlibm_weak_reference(sin, sinl); +#endif diff --git a/src/openlibm/src/s_sin.c.o b/src/openlibm/src/s_sin.c.o new file mode 100644 index 0000000000000000000000000000000000000000..f77a19919cb9c6a2d83c89b7ea1f155d20b2b0b2 GIT binary patch literal 1920 zcmb<-^>JfjWMqH=Mg}_u1P><4z`($QU^{@B4h(z@ybNg`{B;LB4!%%O{r~@ez3p$s zm-gktw*UY8+m(lW;@3IQdZ5(jFuy#5?f?Jp>&rMl@y8rE%rEc2;L-d>!lU!~3y@Kt z_yv4aI6m)&^+2h?evo6psyv#HNF1JE_&<&R{mGXgZT#{s z3=CkY*N@ZqLDE}5L=B%p5g$hoAINYJ9|s26!@}_KKQ?J* zEHMdj2gtRkI!_@P?TSgT2xZWpa(WDH6uQ)C^0t`?f}Xd zAb)|CQAVYEF|zX3=O5*C2!*GCcqF`>fX zumJHrp!z{V=c7zCl^1zZ5iXn-181?9sibo~H{>g8Pk literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_sincos.c b/src/openlibm/src/s_sincos.c new file mode 100644 index 0000000..8628235 --- /dev/null +++ b/src/openlibm/src/s_sincos.c @@ -0,0 +1,159 @@ +/* @(#)s_sincos.c 5.1 13/07/15 */ +/* See openlibm LICENSE.md for full license details. + * + * ==================================================== + * This file is derived from fdlibm: + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * + * ==================================================== + * Copyright (C) 2013 Elliot Saba. All rights reserved. + * + * Developed at the University of Washington. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + #include "cdefs-compat.h" + +/* sincos(x, s, c) + * Several applications need sine and cosine of the same + * angle x. This function computes both at the same time, + * and stores the results in *sin and *cos. + * + * kernel function: + * __kernel_sin ... sine function on [-pi/4,pi/4] + * __kernel_cos ... cose function on [-pi/4,pi/4] + * __ieee754_rem_pio2 ... argument reduction routine + * + * Method. + * Borrow liberally from s_sin.c and s_cos.c, merging + * efforts where applicable and returning their values in + * appropriate variables, thereby slightly reducing the + * amount of work relative to just calling sin/cos(x) + * separately + * + * Special cases: + * Let trig be any of sin, cos, or tan. + * sincos(+-INF, s, c) is NaN, with signals; + * sincos(NaN, s, c) is that NaN; + */ + +#include +#include + +//#define INLINE_REM_PIO2 +#include "math_private.h" +//#include "e_rem_pio2.c" + +/* Constants used in polynomial approximation of sin/cos */ +static const double +one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */ +half = 5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */ +S1 = -1.66666666666666324348e-01, /* 0xBFC55555, 0x55555549 */ +S2 = 8.33333333332248946124e-03, /* 0x3F811111, 0x1110F8A6 */ +S3 = -1.98412698298579493134e-04, /* 0xBF2A01A0, 0x19C161D5 */ +S4 = 2.75573137070700676789e-06, /* 0x3EC71DE3, 0x57B1FE7D */ +S5 = -2.50507602534068634195e-08, /* 0xBE5AE5E6, 0x8A2B9CEB */ +S6 = 1.58969099521155010221e-10, /* 0x3DE5D93A, 0x5ACFD57C */ +C1 = 4.16666666666666019037e-02, /* 0x3FA55555, 0x5555554C */ +C2 = -1.38888888888741095749e-03, /* 0xBF56C16C, 0x16C15177 */ +C3 = 2.48015872894767294178e-05, /* 0x3EFA01A0, 0x19CB1590 */ +C4 = -2.75573143513906633035e-07, /* 0xBE927E4F, 0x809C52AD */ +C5 = 2.08757232129817482790e-09, /* 0x3E21EE9E, 0xBDB4B1C4 */ +C6 = -1.13596475577881948265e-11; /* 0xBDA8FAE9, 0xBE8838D4 */ + +static void +__kernel_sincos( double x, double y, int iy, double * k_s, double * k_c ) +{ + /* Inline calculation of sin/cos, as we can save + some work, and we will always need to calculate + both values, no matter the result of switch */ + double z, w, r, v, hz; + z = x*x; + w = z*z; + + /* cos-specific computation; equivalent to calling + __kernel_cos(x,y) and storing in k_c*/ + r = z*(C1+z*(C2+z*C3)) + w*w*(C4+z*(C5+z*C6)); + hz = 0.5*z; + v = one-hz; + + *k_c = v + (((one-v)-hz) + (z*r-x*y)); + + /* sin-specific computation; equivalent to calling + __kernel_sin(x,y,1) and storing in k_s*/ + r = S2+z*(S3+z*S4) + z*w*(S5+z*S6); + v = z*x; + if(iy == 0) + *k_s = x+v*(S1+z*r); + else + *k_s = x-((z*(half*y-v*r)-y)-v*S1); +} + +OLM_DLLEXPORT void +sincos(double x, double * s, double * c) +{ + double y[2]; + int32_t ix; + + /* Store high word of x in ix */ + GET_HIGH_WORD(ix,x); + + /* |x| ~< pi/4 */ + ix &= 0x7fffffff; + if(ix <= 0x3fe921fb) { + /* Check for small x for sin and cos */ + if(ix<0x3e46a09e) { + /* Check for exact zero */ + if( (int)x==0 ) { + *s = x; + *c = 1.0; + return; + } + } + /* Call kernel function with 0 extra */ + __kernel_sincos(x,0.0,0, s, c); + } else if( ix >= 0x7ff00000 ) { + /* sincos(Inf or NaN) is NaN */ + *s = x-x; + *c = x-x; + } + + /*argument reduction needed*/ + else { + double k_c, k_s; + + /* Calculate remainer, then sub out to kernel */ + int32_t n = __ieee754_rem_pio2(x,y); + __kernel_sincos( y[0], y[1], 1, &k_s, &k_c ); + + /* Figure out permutation of sin/cos outputs to true outputs */ + switch(n&3) { + case 0: + *c = k_c; + *s = k_s; + break; + case 1: + *c = -k_s; + *s = k_c; + break; + case 2: + *c = -k_c; + *s = -k_s; + break; + default: + *c = k_s; + *s = -k_c; + break; + } + } +} + +#if (LDBL_MANT_DIG == 53) +openlibm_weak_reference(sincos, sincosl); +#endif diff --git a/src/openlibm/src/s_sincos.c.o b/src/openlibm/src/s_sincos.c.o new file mode 100644 index 0000000000000000000000000000000000000000..f6eb05b2167a3900f7c853e4bce0a49cc2576a88 GIT binary patch literal 3696 zcmb<-^>JfjWMqH=Mg}_u1P><4z_5V}!FB*M9T@l-_!xrIJoxJlcy#{uIQT+A_5c6> z^&ZV{6l{MhzO?6WmuF;Pu${ZW&90p16Ti-Z)&u-4Qx<%8G}$m~;T{O>P);*Y!lRd)*EuE@)u_#@83 z?E1tXaqbg;q%4KA6U@aTXFsV08x(PLDkGi9g~vl68MR@kjpp zcNRJMW#M-P)iz4gPhL>?Vkw zmR!L2%dR}|pjghqFnga+5Ljwo`)_0TW7*?&R}&9PE@0HMU-m;lP*AYZzUJ!rD65-K zZC}sP?t1n#%FYv{JoG5k9*AuW3=H731m?LrJ6kDexch}_Dj1sR8R;1+7#SFu8W6c`v7K%wLA7s|lIz<2;81}h^Np?prT;S3BSP@1tS zh=H*}fKi%CB;AXCZ zin($_wO~*n`&k%1B7zo41v8csj0Y^w${+xy5riO^$;!Y1rV)e~mvbgfD!g!eZ}#`nR&_i#d^sMdOprZAi@wt7=Q?45Mcr$OhJShh%g5c zh7g5dc}uVWSiK=wt07p2p(z8zWQO?o%+%CWb5oP}qSV~@g3Np)1_m3jyklZPNB+ic{u7V^E z%1bbFvZ3OjFcU^nUkMclg%5H#HzJ9H^uWyNL=s01=L1OM$l-hyNgO$xzaxnwhcgGr zAyEG!hqDNhIC40fAc-S~n+uXSa=67Ii6h5L8j?72c$OfEBga=Kk~nfWZ$J_Um0hrK zJB=ic9ByBb#F5pDfFc7L4#?uL@(ZL5grUiXfkCghGPfi#i9xTpqzFQ1z*t48If;5D zsTCy*dMSw|i41y4#l;MIMfo6(UUG4X1v1Cbj6p9sKQ}iuuY^G_FTW&J&)qLnx40xR zIUCAP&nwj{D9SHLEh?#G&;uKunh~E?l$e_ecMaJLkpDnQ1C)l44S|)Du<{Bf2MT)_ z8$^T3e^7dbsRxOH@DHeg63}o3#U;odP}&2@!|Dq)1_p5H2vr7>0^?M40k9}UEtCnS zbQl=GbrrgDV)YwB?H2-@h9EMa1{NTMz$}>iVYD3%{STn}(ZdVIhtWPz{pj`H2dI8X z{Rg%hOn|}=#DLMEQ2ih=WGoMg6l4J?8>SD+WdJ21P&t8;wn1$isD5;J!Tb%=UkkM# zU4H;nKdhdBsYlljsuw^?(bJCrsL)|xfVV3^=?5eP(+^8OApfA-4YF$i$WR6bh6f-8 z3=9mQvI-Q(==wor9yF*y+TgeWntsdSA`k}DI0%P +#include + +//#define INLINE_KERNEL_COSDF +//#define INLINE_KERNEL_SINDF +//#define INLINE_REM_PIO2F +#include "math_private.h" +//#include "e_rem_pio2f.c" +//#include "k_cosf.c" +//#include "k_sinf.c" + + +/* Constants used in shortcircuits in sincosf */ +static const double +sc1pio2 = 1*M_PI_2, /* 0x3FF921FB, 0x54442D18 */ +sc2pio2 = 2*M_PI_2, /* 0x400921FB, 0x54442D18 */ +sc3pio2 = 3*M_PI_2, /* 0x4012D97C, 0x7F3321D2 */ +sc4pio2 = 4*M_PI_2, /* 0x401921FB, 0x54442D18 */ + +/* Constants used in polynomial approximation of sin/cos */ +one = 1.0, +S1 = -0x15555554cbac77.0p-55, /* -0.166666666416265235595 */ +S2 = 0x111110896efbb2.0p-59, /* 0.0083333293858894631756 */ +S3 = -0x1a00f9e2cae774.0p-65, /* -0.000198393348360966317347 */ +S4 = 0x16cd878c3b46a7.0p-71, /* 0.0000027183114939898219064 */ +C0 = -0x1ffffffd0c5e81.0p-54, /* -0.499999997251031003120 */ +C1 = 0x155553e1053a42.0p-57, /* 0.0416666233237390631894 */ +C2 = -0x16c087e80f1e27.0p-62, /* -0.00138867637746099294692 */ +C3 = 0x199342e0ee5069.0p-68; /* 0.0000243904487962774090654 */ + +static void +__kernel_sincosdf( double x, float * s, float * c ) +{ + double r, w, z, v; + z = x*x; + w = z*z; + + /* cos-specific computation; equivalent to calling + __kernel_cos(x,y) and storing in k_c*/ + r = C2+z*C3; + double k_c = ((one+z*C0) + w*C1) + (w*z)*r; + + /* sin-specific computation; equivalent to calling + __kernel_sin(x,y,1) and storing in k_s*/ + r = S3+z*S4; + v = z*x; + double k_s = (x + v*(S1+z*S2)) + v*w*r; + + *c = k_c; + *s = k_s; +} + +OLM_DLLEXPORT void +sincosf(float x, float * s, float * c) { + // Worst approximation of sin and cos NA + *s = x; + *c = x; + + double y; + float k_c, k_s; + int32_t n, hx, ix; + + GET_FLOAT_WORD(hx,x); + ix = hx & 0x7fffffff; + + if(ix <= 0x3f490fda) { /* |x| ~<= pi/4 */ + if(ix<0x39800000) { /* |x| < 2**-12 */ + /* Check if x is exactly zero */ + if(((int)x)==0) { + *s = x; + *c = 1.0f; + return; + } + } + __kernel_sincosdf(x, s, c); + return; + } + /* |x| ~<= 5*pi/4 */ + if (ix<=0x407b53d1) { + /* |x| ~<= 3pi/4 */ + if(ix<=0x4016cbe3) { + if(hx>0) { + __kernel_sincosdf( sc1pio2 - x, c, s ); + } + else { + __kernel_sincosdf( sc1pio2 + x, c, &k_s ); + *s = -k_s; + } + } else { + + if(hx>0) { + __kernel_sincosdf( sc2pio2 - x, s, &k_c ); + *c = -k_c; + } else { + __kernel_sincosdf( -sc2pio2 - x, s, &k_c ); + *c = -k_c; + } + } + return; + } + + /* |x| ~<= 9*pi/4 */ + if(ix<=0x40e231d5) { + /* |x| ~> 7*pi/4 */ + if(ix<=0x40afeddf) { + if(hx>0) { + __kernel_sincosdf( x - sc3pio2, c, &k_s ); + *s = -k_s; + } else { + __kernel_sincosdf( x + sc3pio2, &k_c, s ); + *c = -k_c; + } + } + else { + if( hx > 0 ) { + __kernel_sincosdf( x - sc4pio2, s, c ); + } else { + __kernel_sincosdf( x + sc4pio2, s, c ); + } + } + return; + } + + /* cos(Inf or NaN) is NaN */ + else if(ix>=0x7f800000) { + *c = *s = x-x; + } else { + /* general argument reduction needed */ + n = __ieee754_rem_pio2f(x,&y); + + switch(n&3) { + case 0: + __kernel_sincosdf( y, s, c ); + break; + case 1: + __kernel_sincosdf( -y, c, s ); + break; + case 2: + __kernel_sincosdf( -y, s, &k_c); + *c = -k_c; + break; + default: + __kernel_sincosdf( -y, &k_c, &k_s ); + *c = -k_c; + *s = -k_s; + break; + } + } + +} diff --git a/src/openlibm/src/s_sincosf.c.o b/src/openlibm/src/s_sincosf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..799da6ceda3c4d4b7c99ceb42b903e7672576a89 GIT binary patch literal 5456 zcmb<-^>JfjWMqH=Mg}_u1P><4z%W4&!FB*M9T@l-_!vUd`0EaNbpGwUp!)y+|9X$+ zHwvHm1=&CI3$oeX;`g-YZ$HJrz+n6Tf4yZn&u4y}1FZ-6Tb?s8Fns2ZI*`V%apDud zfGWtmPy7O+AUcg-c?z|eY$zps#mfdSz%1A(O_haU+diWcx{2Grw@q?l}@(7YgAAaJGfJT4B^H2N{M?g`?-;&16 zz|j1IiNED2D9jJ=xAHQB!aVXED4jx5S0u=9_dfB1{2Fod6Mxk0&-{Y13@;h~{r}G| z4^FPO_usB};BTMF2#L3qj36^&z)nr$*8s)S4W#hA@QFY27Sx%ikir(^?9-q4Bkw>` z7(D!u)trU}5y%XLw?Qcqt{xPJpwz~O2yJlsxblfV0_-M``Dy$br=TesoSON=!BXHv z{Zj4k|NpRr*Lta*1IGTuA9Dd_D98YWCn6t$vLq<3KJi054h_5`kSqzxHjr!#jYn8E z13Bst!u-g~pm+hh0%j4!P`JyH6@wDRX{0<0iYYYTu)U1@1CA$9hPuFjh?ti%euKpk zfdbE9V7GyaAQ}}p;z<6zh~#`|hQnRtAR>wFWfR!>4h%5&zdZ2^?4LA#jb~~6;o!6m zRsV@U@(d){K_wWdB#Sxsi9h1vCw_1V7|H-j>@N+$1|rOJ`io&6l0i2=LkkH0@PnWD z!Din3#2*2QzDxY!7eNIpI2K>t0z1or0oh$(86?9%ss8FGeiT=UyT>)q+7E=;Z~C3rDInNrU%uvaNNDI$ z`{i!dJ?&?Y*_Av$_2?&qmc4|oOUQ4G*SYuv9Qin0xpN^5CvGnY!<8GV9vcO+pM~M$e{6EhSZaK5B4uD@5J1x) z1m=T$2WG$taWIROfdfn<2#6n886*%wV3s17WCe#6mZR{_^b>W2q7>l4otFPgmVf51A`D!ynxdH0|P@20|SOyuo1=a#hH1@ z`Ne5^$qafv&c-0Z5JVV(2on%t3L?xvggJoYWC zfLg#1AD@|;nrd!p5?_>>8()x_Z5=RdIDM;eT;m-_mG}Qf|G7sioVI*;6cWNVvBirkYB#!J~ez` zNgO$RL_m&%x)V8k6p+M`!^Z$g9AqTSURNY>5ECXI2;xA^NA_3P|F} z@uGtyjvOy0NaD!xVuK`(950am1Ef4e4xbz(^~mAVfFurTJHY(gjwFt3&K@LjdW(<1C`MJ5Nc_j>bdHE%&dhULqy2T}l z$=OhTdS0nsK~a7|YEelggC5xM)QtGFqQu-(uuCW+K>h<2?NIN-&4RRV7#Lvf2$%#Y zPs7+CS{hpR!_!2jjzN zkXjfUMC&jxfZLGd>NjLy0JoYzaSk#MhC8747r+FdG|c@l+75?)22du0w(X%>!4xd~ zU^J**2=Wu8T?$qLCKRCh^}##@0a6R%!RSz^{U9-9><`tCECyo3^nutQ3`#;Er6_5e zfq@|aB*?&k(SC;c8>AP6YoYd|>u-SSM{n<<>#x9(em+102$oJj=?9dgVESR=ApfA- z4RY57sQo`c3K$p|KxM5kG_8Q-VfsO38+zIS$)5m8FfcG6I(8sYNLqogAS9^l!ls`C RB*DPI&<;@sC!x-P^8qSuNy`8L literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_sincosl.c b/src/openlibm/src/s_sincosl.c new file mode 100644 index 0000000..e2d3a34 --- /dev/null +++ b/src/openlibm/src/s_sincosl.c @@ -0,0 +1,31 @@ +/* s_sincosl.c -- long double version of s_sincos.c + * + * Copyright (C) 2013 Elliot Saba + * Developed at the University of Washington + * + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== +*/ + +#include "cdefs-compat.h" + +#include +#include + +#include "math_private.h" +#if LDBL_MANT_DIG == 64 +#include "../ld80/e_rem_pio2l.h" +#elif LDBL_MANT_DIG == 113 +#include "../ld128/e_rem_pio2l.h" +#else +#error "Unsupported long double format" +#endif + +OLM_DLLEXPORT void +sincosl( long double x, long double * s, long double * c ) +{ + *s = sinl( x ); + *c = cosl( x ); +} diff --git a/src/openlibm/src/s_sincosl.c.o b/src/openlibm/src/s_sincosl.c.o new file mode 100644 index 0000000000000000000000000000000000000000..d0c2512e65834356cb04094b775c6bf90f2c5b41 GIT binary patch literal 1896 zcmb<-^>JfjWMqH=Mg}_u1P><4!0>_@!FB*M9T@l+co{-HI{yZHbbj_|e#7y|u~36d$;`<;+*v%g-dSM0T zbI4e&H%?FA`MhW^n7^TIPxFbBxd!o1>>1phovjo!-2Fl|6%0-EjPwi@j0}uS4Gawp z6f}ZTQxrTBOP~_E=9&x)EDQ_`3JeSktPBhc?tY;RObm<%Kw@BX85kHCp?sL%MW7Ol zRY44l6#|UXJnS437#SE$7#J92pmIha+L2G7jmd>iqM6y9Pr-#x!-dblhtI-=&%v8d z!jVtFk&gqU3MU5H$HMUOKQ;x-SYm<~>{gI3AUa^Ci$ld>d>E|=6&HXgXMl-oL&YV~ z#7&{%ps)f-!PMJB#Wg^J3=D8{JfY$SXyU<8aSJr@SOx|LAtZl+!;pc2A(erF0p>=i z7BH27L!6;FzBn^4IlnkZFPWhrGv6rQxFjbZ#>&Wqu#DhhMkO#YL%5hBNGvn245U3L zp8?9s$Yg+;45D+uu3%sgh0>rj!^6P9@aI1Ss3M7j;sz!T3qK|X1_ls@Dq~>KE3V8f zNlaqUD=sO5&>1jRQEE=2UP)?234>lrVo4%{UQ%%}gI-ZSgp-_~o12qr@cx149MW5_EsT@(om)!4j$;=1-V7q~K#<(1!^?X_)(Av=dZ6R2oh_hqF)_ zFnuu5AO;2ocJ#E!z`y`5n;94w(A|aZ{w%2d=>C_0S`+}Y2uh>t2c<$#-a!wi2xx@B z;u#eGoY1%e83hvuS%YpjNInB3!N9-}0Hr~B6J!R=ewcocnNX`h+TeHx)KHNB;DS)U VBJ%|q7#OhWFMtY`AS=eA9{`u3vZw$6 literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_sinf.c b/src/openlibm/src/s_sinf.c new file mode 100644 index 0000000..d987369 --- /dev/null +++ b/src/openlibm/src/s_sinf.c @@ -0,0 +1,85 @@ +/* s_sinf.c -- float version of s_sin.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + * Optimized by Bruce D. Evans. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_sinf.c,v 1.17 2008/02/25 22:19:17 bde Exp $"); + +#include +#include + +//#define INLINE_KERNEL_COSDF +//#define INLINE_KERNEL_SINDF +//#define INLINE_REM_PIO2F +#include "math_private.h" +//#include "e_rem_pio2f.c" +//#include "k_cosf.c" +//#include "k_sinf.c" + +/* Small multiples of pi/2 rounded to double precision. */ +static const double +s1pio2 = 1*M_PI_2, /* 0x3FF921FB, 0x54442D18 */ +s2pio2 = 2*M_PI_2, /* 0x400921FB, 0x54442D18 */ +s3pio2 = 3*M_PI_2, /* 0x4012D97C, 0x7F3321D2 */ +s4pio2 = 4*M_PI_2; /* 0x401921FB, 0x54442D18 */ + +OLM_DLLEXPORT float +sinf(float x) +{ + double y; + int32_t n, hx, ix; + + GET_FLOAT_WORD(hx,x); + ix = hx & 0x7fffffff; + + if(ix <= 0x3f490fda) { /* |x| ~<= pi/4 */ + if(ix<0x39800000) /* |x| < 2**-12 */ + if(((int)x)==0) return x; /* x with inexact if x != 0 */ + return __kernel_sindf(x); + } + if(ix<=0x407b53d1) { /* |x| ~<= 5*pi/4 */ + if(ix<=0x4016cbe3) { /* |x| ~<= 3pi/4 */ + if(hx>0) + return __kernel_cosdf(x - s1pio2); + else + return -__kernel_cosdf(x + s1pio2); + } else + return __kernel_sindf((hx > 0 ? s2pio2 : -s2pio2) - x); + } + if(ix<=0x40e231d5) { /* |x| ~<= 9*pi/4 */ + if(ix<=0x40afeddf) { /* |x| ~<= 7*pi/4 */ + if(hx>0) + return -__kernel_cosdf(x - s3pio2); + else + return __kernel_cosdf(x + s3pio2); + } else + return __kernel_sindf(x + (hx > 0 ? -s4pio2 : s4pio2)); + } + + /* sin(Inf or NaN) is NaN */ + else if (ix>=0x7f800000) return x-x; + + /* general argument reduction needed */ + else { + n = __ieee754_rem_pio2f(x,&y); + switch(n&3) { + case 0: return __kernel_sindf(y); + case 1: return __kernel_cosdf(y); + case 2: return __kernel_sindf(-y); + default: + return -__kernel_cosdf(y); + } + } +} diff --git a/src/openlibm/src/s_sinf.c.o b/src/openlibm/src/s_sinf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..ab8f849c64ac2141a9db99ad28f298bcfe5c98a9 GIT binary patch literal 2896 zcmb<-^>JfjWMqH=Mg}_u1P><4z%YRw!FB*M9T@l-_!!do>kf5ZQ2qb^f4%K3eoy;y zG28$D>n+REKlAGxXgyFGe>ja_-i3j|qxp@5?Zx0~hjQJ|{80yNADe^S4c7U|{&nA9Dbt<}g?uWEfO+ z14t8yZ+rjkdI$dYlTgEFA{qVyq=r8nY|-nT{PGN+_yu@DVy&0zIAH8g{4pm$Hl*=u z9E6(9@QFVHtO?nGm!<#z|L2zn+w0L=qrw4}{KPNdqQcSqfVuexV~Iuc52ljr)&nK^ zU^%GGFKzz+{|^Zln7JVPpmu@H11oq~=L0nvZu-~az0-!U*q=(>db zR^)Vm(gz^4B#efN|FplPXk1@&QwS2p5UpVMK$vh6A?EJvY^9*#?iZ@5U}&Oeq-UsL zWME`!U}$Kdpb?asqTrEO0+rA;*JNN|VPIfTU|?VX1*W@SC<7A%;{lKuEX^@O`J7Oz zM4&WdRS*MXg#e>84?D*MMg|5G1_lNhsN5ou<{UnSEG|9{FYYKljxat2CLb<74j*o& z6fl(oCZWo)QXnH(7(PNn3sng-mK?zaR>BJQ3z!Kd_`x(Qg9eyJ5D7xxv5EfQEF~{L1w;D8pv%R><1zk7#Nrs7#Nrt7#RNi zhk(^c;-GW}6W;(82Z`|@soxG22blv3eVFhm#2o*=S z_XkuQ-CjOW!eoHt8$Kj=Y9WauyWbEhj&6<%k~qk2m^&k(;vg|(b8?{KAag)z6Q;fb zNgR|%Vd7Je#6fujCO#7?4l*B9(89#Sq5cJlBiq}GB#x~9Ar5h0B=b?sK@vwc2UPZe zi~{)!gh6aD)+?^eElEsb&?_z}g3uW-R#9qBqFzaAMG1pmN@7VOgI-c`F@s)FK8T~2 zTwG#-%rP`$&`ZwG%}vcKVbIIVFGU8xtU!n5bC?`@c_9r=YcTaNbtga(#lXOz0Sz=zScB{V zr45i8Sb3zzzyK~)KxrN%4#ST?ieVfi8eLe2fdO0=lB?ekYQGSY9U$fls6_@K4ibjB zA4c2Z(60dXHz<6Ow8P6vSUCDX^`qP40M)OLtQo2nBm{LH1E@TOu|eW6oDbCxXO7eEEj-39YE%)DBto1n^J!VC+b0s(Ll2m@Vz1&;Ld0h%CT=>(L1K;;BX zKTI6tAE;Fj3!vl&s9*+20RsaAC{J@k(+WrlOh2ehLQgv&`3PwG%>;3fFw{7>h#<87 VfD1qw9H2mDU|?v6@?jLZegK4I&kFzm literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_sinl.c b/src/openlibm/src/s_sinl.c new file mode 100644 index 0000000..7304fc7 --- /dev/null +++ b/src/openlibm/src/s_sinl.c @@ -0,0 +1,88 @@ +/*- + * Copyright (c) 2007 Steven G. Kargl + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_sinl.c,v 1.3 2011/05/30 19:41:28 kargl Exp $"); + +#include +#include + +#include "math_private.h" +#if LDBL_MANT_DIG == 64 +#include "../ld80/e_rem_pio2l.h" +#elif LDBL_MANT_DIG == 113 +#include "../ld128/e_rem_pio2l.h" +#else +#error "Unsupported long double format" +#endif + +OLM_DLLEXPORT long double +sinl(long double x) +{ + union IEEEl2bits z; + int e0, s; + long double y[2]; + long double hi, lo; + + z.e = x; + s = z.bits.sign; + z.bits.sign = 0; + + /* If x = +-0 or x is a subnormal number, then sin(x) = x */ + if (z.bits.exp == 0) + return (x); + + /* If x = NaN or Inf, then sin(x) = NaN. */ + if (z.bits.exp == 32767) + return ((x - x) / (x - x)); + + /* Optimize the case where x is already within range. */ + if (z.e < M_PI_4) { + hi = __kernel_sinl(z.e, 0, 0); + return (s ? -hi : hi); + } + + e0 = __ieee754_rem_pio2l(x, y); + hi = y[0]; + lo = y[1]; + + switch (e0 & 3) { + case 0: + hi = __kernel_sinl(hi, lo, 1); + break; + case 1: + hi = __kernel_cosl(hi, lo); + break; + case 2: + hi = - __kernel_sinl(hi, lo, 1); + break; + case 3: + hi = - __kernel_cosl(hi, lo); + break; + } + + return (hi); +} diff --git a/src/openlibm/src/s_sinl.c.o b/src/openlibm/src/s_sinl.c.o new file mode 100644 index 0000000000000000000000000000000000000000..4f624f46c698aec132a2bca3a5678c3c6c3048fe GIT binary patch literal 3736 zcmb<-^>JfjWMqH=Mg}_u1P><4z%YXg!FB*M9T)@{_!)vdn%@-MUZc{$z`$_x!0j3p z1^#U=Dw>^#n;+D7xTt9IZ+B7AIPjYN=7BWT|MmPWHH-`lX|^ENB_;-jyEpFMxSgY- zaF-Qi~I=nKg}x zf#GJ2irfw{2L^^T{`Uvc_}`y|x~lONNbq)zia}bZi;4xvL2|cqR16x<@PGtlZXURq zqat%#M&)LXirgoDEf$qe{DLehcT`kvf?f5AU(iJ*0A%Q$lQ&OdRqdi8a3@7Y0IV|N z-pRW$Ahv*uia;8_-a)Wv0)JN)69WT(YYGzsL$i$v<4#Z@H{bm4(OaV8;L%&765zOl ziGhLP1t=iyx~MqZby4xSdGN-;n+I;&sN8vU^W?opX|1>UJB-1>*8G6E`3Dn!%UebU zhUOp4{4Gbo3`YLenT!k!9?fqAZriB*FHw;IVX&DV%|{eoGf%jC)1&!FLG)pM`4*5( z3|S0@|Fd8k;0jxAm)yAd;PsWX2_D@o;JEcT_(H*U;Vu4?{Oyzf{r{f^(+>)DNbEt# z&THTRzIPBB`mj*Ga}pAocMjcqg%*n4EGjn-+~EZ|=iV!bDG>7B!5b%U9=h@HwvCEM zw~q=(<3ms?&^*`tPpq!|?hTkGkP?Un2zm4DjYsz$-#c>i^o>*Z9)e`i3^;Z3Q1dU_ zI-9#UZyto$d*>xYD}=mx_QvCTk3a_8I|T~&n+I+@x^1I!^W-UYi?C>365se0OFB5k22a8@dj}JtI9s z1tS9^Qv*Xo0|kws)D#7e#1g24uDK=y0}BHKg8~Bs11Rgc`-L(vF)$tgiGczQ42%^5jM6;p91|EB7-|?87-XPw+dyIA$S2Uuo$KPJA7VE_@Tf5XM$Jq=-7=Z|55Mcr$Oc~p;bIki_|r%<)1J=SLC`LJ|j=uL3nE0!aoI(-@nFA{0Ki&#HSS{=B9!jL>U3{Cn%|*moSjFD+2>8f5U76#W9QxqNSl> z4O0&i17QJZf%gDpI0FL%C@+ARP+@qvq6RJx85p3^0MZJ^-_QlXqM$Mx%79X!bPh5T zT{*G(4Wag<#4!T{!w;x|=>7uP1+^MXSwi&-fq4kR0-8`k;foMO)Eh8!AoT>OOhs13 zzz_k|4^sz|g$l#V{a~p5u=)+AE&-}gA0_~$L2&?L!sr;NevlY4?uY6}76Y+i`aoHrVHsQm!T{L^VL?bx WS%*zO2dF{Az`)Q4Q3fZ`^#cHXk +#include + +//#define INLINE_REM_PIO2 +#include "math_private.h" +//#include "e_rem_pio2.c" + +OLM_DLLEXPORT double +tan(double x) +{ + double y[2],z=0.0; + int32_t n, ix; + + /* High word of x. */ + GET_HIGH_WORD(ix,x); + + /* |x| ~< pi/4 */ + ix &= 0x7fffffff; + if(ix <= 0x3fe921fb) { + if(ix<0x3e400000) /* x < 2**-27 */ + if((int)x==0) return x; /* generate inexact */ + return __kernel_tan(x,z,1); + } + + /* tan(Inf or NaN) is NaN */ + else if (ix>=0x7ff00000) return x-x; /* NaN */ + + /* argument reduction needed */ + else { + n = __ieee754_rem_pio2(x,y); + return __kernel_tan(y[0],y[1],1-((n&1)<<1)); /* 1 -- n even + -1 -- n odd */ + } +} + +#if (LDBL_MANT_DIG == 53) +openlibm_weak_reference(tan, tanl); +#endif diff --git a/src/openlibm/src/s_tan.c.o b/src/openlibm/src/s_tan.c.o new file mode 100644 index 0000000000000000000000000000000000000000..08cb0b311363de2f2d283786383280be8baf0cfb GIT binary patch literal 1568 zcmb<-^>JfjWMqH=Mg}_u1P><4!0>i&Asr3o`SKU`9qj8K5u$h0&k?5Kw|74w8e3JK+!qg)vA9 zlx#p4#0F!%;>z5T#3Tm2;*uf=odIJNrRF5+m84dbFzBTumLxLhB^4Jl=q2ap=BDPA zFzDswm!#^s`-SQjmn0@rFsQL`30#(C6x?%U=va^;?s%}b5p_AQA&XP0g5{| zG=m^{fPn!PFEDBJIFM#w0H-;adbm1hpm;z9xEL6~u?Rn9s5mo}52NTrZkHryx5l{nR@dS!Lkli2*vKS@~vIeRY zBn-y^APEKrh6zv+ZUzPhP#mG_2jzE=I8+&&dH~fADb?V@;53BbF)#>1%|#Xiu?wJ% N$^mhZFw|JM2moI>oR +#include + +//#define INLINE_KERNEL_TANDF +//#define INLINE_REM_PIO2F +#include "math_private.h" +//#include "e_rem_pio2f.c" +//#include "k_tanf.c" + +/* Small multiples of pi/2 rounded to double precision. */ +static const double +t1pio2 = 1*M_PI_2, /* 0x3FF921FB, 0x54442D18 */ +t2pio2 = 2*M_PI_2, /* 0x400921FB, 0x54442D18 */ +t3pio2 = 3*M_PI_2, /* 0x4012D97C, 0x7F3321D2 */ +t4pio2 = 4*M_PI_2; /* 0x401921FB, 0x54442D18 */ + +OLM_DLLEXPORT float +tanf(float x) +{ + double y; + int32_t n, hx, ix; + + GET_FLOAT_WORD(hx,x); + ix = hx & 0x7fffffff; + + if(ix <= 0x3f490fda) { /* |x| ~<= pi/4 */ + if(ix<0x39800000) /* |x| < 2**-12 */ + if(((int)x)==0) return x; /* x with inexact if x != 0 */ + return __kernel_tandf(x,1); + } + if(ix<=0x407b53d1) { /* |x| ~<= 5*pi/4 */ + if(ix<=0x4016cbe3) /* |x| ~<= 3pi/4 */ + return __kernel_tandf(x + (hx>0 ? -t1pio2 : t1pio2), -1); + else + return __kernel_tandf(x + (hx>0 ? -t2pio2 : t2pio2), 1); + } + if(ix<=0x40e231d5) { /* |x| ~<= 9*pi/4 */ + if(ix<=0x40afeddf) /* |x| ~<= 7*pi/4 */ + return __kernel_tandf(x + (hx>0 ? -t3pio2 : t3pio2), -1); + else + return __kernel_tandf(x + (hx>0 ? -t4pio2 : t4pio2), 1); + } + + /* tan(Inf or NaN) is NaN */ + else if (ix>=0x7f800000) return x-x; + + /* general argument reduction needed */ + else { + n = __ieee754_rem_pio2f(x,&y); + /* integer parameter: 1 -- n even; -1 -- n odd */ + return __kernel_tandf(y,1-((n&1)<<1)); + } +} diff --git a/src/openlibm/src/s_tanf.c.o b/src/openlibm/src/s_tanf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..9406e1fdcbe4ddacfe2bfb877f3732242f06b232 GIT binary patch literal 2352 zcmb<-^>JfjWMqH=Mg}_u1P><4z_5W8!FB*M9T@l+cp1|8>kf5ZQ2qb^f4%K3eoy;y zG28$D>n+R6KlAGxXgyGxe>ja_-i3j|_F{0gL%HE+{-^`Ck57v^l&5{-7vKdM)Ox9o z1IGTuA8~O1|NsC0zXZwf%R4aGUNwB=P@V|ZcmM5rRDBm<`d%O7mu~@SVb~9HJV-Uz zgtQ4T6&SXF)Iroh-1q-~eSMkYXa1N2he7rt=|i$5ZGuPh8wroz8WoNgAnQKy3%ICo zfbC>F(ENZ&^Eg=8qxp!$VURongM_Y2$Zy4;`=PWwgyuW|r5!FQ8rRp{6gmK<9U$V8 zP84?D*MMu@l!R89({ zndu9kLMk5zR0x9tDPdvw_#Z=pfq{V;ON!zGD`aIrH;^AH4yKR@h&x#sG?2tVOi2*I zzzX&=mGt(hd4uVd`V(nnqD%4o{zI3h%f*VrXa!uL>PkzBM@N@BFq>-${FJ0 zvr~)mQgc9>Q_>jX<1l< zeo3mHyI-hoaYBR;JtF*g-#Hx&qwzd%6;ibG`M zAZ0oO11ufGS5|0Fhf`tAj26L7`Pc2z_|ky_aGTqK2(E>LzRQ1z&Hx3 z56nR#(1mpv7{Fx)x%v&E_6s4|0b(XVEkgGf%>6JLl%GIK(aVDcAVCHO27QoWNEj*% z4hxX5JJfy<8yTO6DMS{;qBfj?fdQ1yP|_p=1H%QVesp)i+zm4}A8IDLesIQPV8AHn z(Di5Gh<^!CVZp!vFKb#BKp6&5_g6ysFbZ8i0I}3gD*ylh literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_tanh.c b/src/openlibm/src/s_tanh.c new file mode 100644 index 0000000..1fa734d --- /dev/null +++ b/src/openlibm/src/s_tanh.c @@ -0,0 +1,83 @@ +/* @(#)s_tanh.c 5.1 93/09/24 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_tanh.c,v 1.9 2008/02/22 02:30:36 das Exp $"); + +/* Tanh(x) + * Return the Hyperbolic Tangent of x + * + * Method : + * x -x + * e - e + * 0. tanh(x) is defined to be ----------- + * x -x + * e + e + * 1. reduce x to non-negative by tanh(-x) = -tanh(x). + * 2. 0 <= x < 2**-28 : tanh(x) := x with inexact if x != 0 + * -t + * 2**-28 <= x < 1 : tanh(x) := -----; t = expm1(-2x) + * t + 2 + * 2 + * 1 <= x < 22 : tanh(x) := 1 - -----; t = expm1(2x) + * t + 2 + * 22 <= x <= INF : tanh(x) := 1. + * + * Special cases: + * tanh(NaN) is NaN; + * only tanh(0)=0 is exact for finite argument. + */ + +#include +#include + +#include "math_private.h" + +static const double one = 1.0, two = 2.0, tiny = 1.0e-300, huge = 1.0e300; + +OLM_DLLEXPORT double +tanh(double x) +{ + double t,z; + int32_t jx,ix; + + GET_HIGH_WORD(jx,x); + ix = jx&0x7fffffff; + + /* x is INF or NaN */ + if(ix>=0x7ff00000) { + if (jx>=0) return one/x+one; /* tanh(+-inf)=+-1 */ + else return one/x-one; /* tanh(NaN) = NaN */ + } + + /* |x| < 22 */ + if (ix < 0x40360000) { /* |x|<22 */ + if (ix<0x3e300000) { /* |x|<2**-28 */ + if(huge+x>one) return x; /* tanh(tiny) = tiny with inexact */ + } + if (ix>=0x3ff00000) { /* |x|>=1 */ + t = expm1(two*fabs(x)); + z = one - two/(t+two); + } else { + t = expm1(-two*fabs(x)); + z= -t/(t+two); + } + /* |x| >= 22, return +-1 */ + } else { + z = one - tiny; /* raise inexact flag */ + } + return (jx>=0)? z: -z; +} + +#if (LDBL_MANT_DIG == 53) +openlibm_weak_reference(tanh, tanhl); +#endif diff --git a/src/openlibm/src/s_tanh.c.o b/src/openlibm/src/s_tanh.c.o new file mode 100644 index 0000000000000000000000000000000000000000..f92ad54eb87bd4124def51f7a78b736363061ea2 GIT binary patch literal 2328 zcmb<-^>JfjWMqH=Mg}_u1P><4z!1TTU^{@B4h;MZd+>+Q;iY5d_}b~H%cVSf1rkc933|N3_2kx0g#_{1M^A&p-jY)$#<7a&!i z_#?sY1as2(H9%^>0x&Z{PI*0xU!LI;f6OU}1#ow~w=dfT*7%7(;sBHZan&dOh=XbT z8W&-%{KOx30c5~S-~a#rgY1Rj5B76P89Hp9nAbr?AVI~zZ~)4OQD8rTIquHRRtg&K zexaHQh9-JOdWH%{21cd^hK2?T8bPTk3Lc3iPzhagO$G)Q1_lNN1_lO@uiX7Y8JHLt z4}ipAamEPcbAkZm(md=O6Brp7bQl;IWT0|PAkB_^0?kYnTznkv z+%a5y96sDkphWk4WOk{sQFzkQ7Kg2!q&QtXEu_ zTauW>pjTW{1fervtfJJMM7@&KiV_CBl*E!m2EC->Vg|jUd=N)3xwymvnPX_ipqHGV zo120O!uQdYp!!_;Mf0+E4%Apm4J0|NsO0|Pi$!15O?KdC{* zp~_*}8JwW{-~vzvx-h7G0hvjzeo(dnnJEM{A4YkA1fgXhObkSW>_VpPpzcT4UjWsQ z9$qj$jP`-*Hvk!mgd3px^^wFtOsFt8EJ6HGsD2O|8Lx*aL>9!N7L + +#include "math_private.h" + +static const float one=1.0, two=2.0, tiny = 1.0e-30, huge = 1.0e30; +OLM_DLLEXPORT float +tanhf(float x) +{ + float t,z; + int32_t jx,ix; + + GET_FLOAT_WORD(jx,x); + ix = jx&0x7fffffff; + + /* x is INF or NaN */ + if(ix>=0x7f800000) { + if (jx>=0) return one/x+one; /* tanh(+-inf)=+-1 */ + else return one/x-one; /* tanh(NaN) = NaN */ + } + + /* |x| < 9 */ + if (ix < 0x41100000) { /* |x|<9 */ + if (ix<0x39800000) { /* |x|<2**-12 */ + if(huge+x>one) return x; /* tanh(tiny) = tiny with inexact */ + } + if (ix>=0x3f800000) { /* |x|>=1 */ + t = expm1f(two*fabsf(x)); + z = one - two/(t+two); + } else { + t = expm1f(-two*fabsf(x)); + z= -t/(t+two); + } + /* |x| >= 9, return +-1 */ + } else { + z = one - tiny; /* raise inexact flag */ + } + return (jx>=0)? z: -z; +} diff --git a/src/openlibm/src/s_tanhf.c.o b/src/openlibm/src/s_tanhf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..0172ad727c05d52af6184cac7fb5d7f9b967d20e GIT binary patch literal 2280 zcmb<-^>JfjWMqH=Mg}_u1P><4z@Wj3U^{@B4h;MZdawN|G(b$|Nr{> zGTG1k0-_)l{2He|^T(ZNyj*K z&989~EMIR~9*HpH#Ap793;g%yFOj<1T#Wk2&=+?EnA&Aj23M>`#62 zEM#C{00qGTun+?S*d8dGfx+F`*-Amf-7i#A!O%p{NY7Bg$iT?dz|hb@K_e(NMZqJn z1S+9xuF1f_!oa|wz`(!&@_@TvC<7A%;{lKuEDji^Urj8j) z%7B;$ay_bI0Wg;hOd=EDcw}G&`x{wY3d~_;-~rPJLLSUyW#9nQ2ttK{fk6n#JzzgG zFfeE_Ffc&uMyLg`3~-1u6vvk&=4GVmB{S&xI2(Wn6A)ntB8)+V5d&BOLt0`|aT-Hv zMM17%8Uuqk$WR6b1||ju24)5ZhClxyz#50R8MNk)AoqYm9VT826$h#3LULyZR2-z99Z9?&NgSjHX3h?%I7kfH-h)Wu$mXAf zildu<14$g&U!Xhyk^-p*VGtXP^@=NVOA?b9^omQ0Aan+dRg{{Os8^C&QNo~?l30?+ zpqEr!%%E4458~)07nhhIa}3QG^pf*)b5rw581(Y;OH%dR{X%t%OA?c_q5Sl`QoVwr z{DRb?l1c_Wu;Hm0@o7bgxv5~6P(*17gDRiv&m!0|SE^0|Pj>K$Sy985lG{is3v216>$YzJSam zSHB_Dej$VvV3rQlB6RPL4MD6El<1m$CpQgrU|@iy6HxgJ%EvJKVd5Zb(Cr3U`2!>YvJXmws&bHC5C+M^ s^n=O_^t1z#2N#|U3=HOA4uXIh2Nw{8ma}jHC}RQC{q0abj6&BB049_!BLDyZ literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_tanl.c b/src/openlibm/src/s_tanl.c new file mode 100644 index 0000000..0370e6b --- /dev/null +++ b/src/openlibm/src/s_tanl.c @@ -0,0 +1,90 @@ +/*- + * Copyright (c) 2007 Steven G. Kargl + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_tanl.c,v 1.3 2011/05/30 19:41:28 kargl Exp $"); + +/* + * Limited testing on pseudorandom numbers drawn within [0:4e8] shows + * an accuracy of <= 1.5 ULP where 247024 values of x out of 40 million + * possibles resulted in tan(x) that exceeded 0.5 ULP (ie., 0.6%). + */ + +#include +#include + +#include "math_private.h" +#if LDBL_MANT_DIG == 64 +#include "../ld80/e_rem_pio2l.h" +#elif LDBL_MANT_DIG == 113 +#include "../ld128/e_rem_pio2l.h" +#else +#error "Unsupported long double format" +#endif + +OLM_DLLEXPORT long double +tanl(long double x) +{ + union IEEEl2bits z; + int e0, s; + long double y[2]; + long double hi, lo; + + z.e = x; + s = z.bits.sign; + z.bits.sign = 0; + + /* If x = +-0 or x is subnormal, then tan(x) = x. */ + if (z.bits.exp == 0) + return (x); + + /* If x = NaN or Inf, then tan(x) = NaN. */ + if (z.bits.exp == 32767) + return ((x - x) / (x - x)); + + /* Optimize the case where x is already within range. */ + if (z.e < M_PI_4) { + hi = __kernel_tanl(z.e, 0, 0); + return (s ? -hi : hi); + } + + e0 = __ieee754_rem_pio2l(x, y); + hi = y[0]; + lo = y[1]; + + switch (e0 & 3) { + case 0: + case 2: + hi = __kernel_tanl(hi, lo, 0); + break; + case 1: + case 3: + hi = __kernel_tanl(hi, lo, 1); + break; + } + + return (hi); +} diff --git a/src/openlibm/src/s_tanl.c.o b/src/openlibm/src/s_tanl.c.o new file mode 100644 index 0000000000000000000000000000000000000000..88cf6d778e3b8ce3452957593bfb6b3a5867bd9f GIT binary patch literal 3560 zcmb<-^>JfjWMqH=Mg}_u1P><4!0>_-!FB*M9T)@{_!)vdn%@-MUZc{$z`$_x!0j3p z1^#U=Dw>^#n;+D7xTt9IZ+B7AIPjYN=7BWT|MmPWIgAVpX|^END<%epyEpFMxSgY- zaF-Qi>CUJ6?kWXaysGYa=5AgGcil z0mJ{dZB+i3s7Qb?SieW}5rx<6{PHdg40msOG#@F5KFlxQ0y3E)i^1@J7FgSD8x^?X zmfIyaZa#Q@C2fL7cMCW!Jr2H5uw8hI|0I9=;(!1Dr@{1tLKzZU5VG?cI6&_mgoZXO zRPUUGgx;M)_g#FMLC(4N3StU`ym#=%$(x66JiKkA;?eD+!qNB;6ziJj zn*WK_mEXMq(*#li(EuTDp1twt-s5{mZl1nz>fS?;ESdqQZXRm>Wm{)+_vX!m5PR>u zglL73H_zU9eD4v+fP1Gv;e7MJjYqd_RBoPp%{$@l&DR|K@(v7lZ{NLnTSw*It9vhB z*8lte9~K^<2-pvbOKfof3wjp@hITCo=;B!^?kv!9nZ7zyJ-t8xO$o z{Za*Ng$o12%?ICafZX!nCFj5Y|3P8Kz`$_e=9V+Ne&49e4&MP5(P%LDGGRA=u;_&q zn9m_&wca>AedqI{yc_|l%i0Yv|_XK;Y3bAai0h-YAE z@Mds#cD7Q`aQ6$e@d-Hcad>h&@pUk|@J#?q_<)q! zft30nDRqG;b>nt}Fg#)IfLet?f!xi)@DUc`DDuo$N=PmS1_nk3Rt5{GN)9Lu@+U~# z0Lq7n%R$v^poxR{AoZZI1WCcv8$s1efCL#B7+~TyP;mh?aW|+qOdX64fQmzv!_5Kl znZdCKVj*x8n8^kvk%@RPhaDX6U?!AE0n_YY5}C*ZbJ$Sq0}17U2nIF=nESz81_p*= zFoTT&=3g+Efq`K%0|SE)Quu?@2m=E{1p@<4Y3ra`ciJGV{s`GV_fx zGGVNodoz`*e5KLp%E5(gEXF!4Z8LS=yDKVc;G z6OqJ0X%MD<9}e+vP;rpGpuAxMweJs_xDHfY2BZ+`PCg`it&qg|k;I*l#6jk(K+W+$ z6Nlyfd?ayD+JL#g5=k6n4#;mHqw3MbL170H--IMCh~%DKNa7%KKxGw3{Q)#_n7yK) zvIrW^AUk2=uzU*A2ErgSz*w)iGPfi#i9xTpqzFQ1z*t48If;5DsTCy*dMSw|i41y4 z#l;MIMfng8gw{(gF0p_Kf;c7&ddc~@xv6<240?I_C8>JuexbU>C5g$|P=0z|sa`=* zenDzcNhO0G*pAeU__U(L+*GiGC?i1r1SJLZk^s^cWMF{hLzpd~ID@f4v@|sAVCq3) zAUpwDRBQkl&cMI`O4}eNth|Ede>HHq#lQfK29Q=TUWYCK76p~XPzIC&rCX4h=*o%J zZwR#?C5{;w7&br+ME4iSE~wRD$`Yzy2+TteAE5d{;foMOl_b+?z#srk zxG;4vS*S3)d=7@%537e@>Lj2F^IaD-V|S>2WHAsMrVqphVNkse zifZ)m^ML9{cNe;UK&@Ahndtf}p!z|*1&}>3jIO^PNBVPs_G@7243z#r + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_tgammaf.c,v 1.1 2008/02/18 17:27:10 das Exp $"); + +#include + +#include "math_private.h" + +/* + * We simply call tgamma() rather than bloating the math library with + * a float-optimized version of it. The reason is that tgammaf() is + * essentially useless, since the function is superexponential and + * floats have very limited range. + */ +OLM_DLLEXPORT float +tgammaf(float x) +{ + + return (tgamma(x)); +} diff --git a/src/openlibm/src/s_tgammaf.c.o b/src/openlibm/src/s_tgammaf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..7e7e0fbfbbe807a36c3b34eae60a7ea584373d3c GIT binary patch literal 1376 zcmb<-^>JfjWMqH=Mg}_u1P><4z@Wf{U^{@B4h*~uJPaPqZ#X{lM;&+p67y(2!tsee z>cC+JcV}lS1r2wq0|SEylxD07VqmNgV3g)z=a|3<5to6=iGgSr zJ^^1o4iF0~2AR*o@bN!3NoFh|!OOtFAcQ0iwu6CzL6m`kK>(W}#qlNSiMhFnX?n>F zP!^O1tA_ap^B)30VF6MA3U&|%vB6lcxH7jSF^NI1xTFX|XTVrRsX2*yC8-r9 z40JuexbU>C5g$|P=0z|sa`=*enDzcNhO0G z*o4%K__U(L+*Gi2loB9+fWnv!%^*k`Vqk!UA50oO45b+u7(n3yQx8+u05X(;fk6T) zz{S7-julu;!^G8~;>=KWFe(hjK%=3?!bNo$7#KiilB?ekYQF*8L!( zXe+3GxB@7n6-uL1Fnus_F9rq%b_NCplr+S^z|a9zfbK4kU!hW9DhX;oy8aztSq26| z`eSj#-wdcjVetftKakxZ3^E!f4pN40H%J~_-Y_sQRDd`P3=G^13=E(+Le~$q +#include + +#include "math_private.h" + +static const double huge = 1.0e300; + +OLM_DLLEXPORT double +trunc(double x) +{ + int32_t i0,i1,j0; + u_int32_t i; + EXTRACT_WORDS(i0,i1,x); + j0 = ((i0>>20)&0x7ff)-0x3ff; + if(j0<20) { + if(j0<0) { /* raise inexact if x != 0 */ + if(huge+x>0.0) {/* |x|<1, so return 0*sign(x) */ + i0 &= 0x80000000U; + i1 = 0; + } + } else { + i = (0x000fffff)>>j0; + if(((i0&i)|i1)==0) return x; /* x is integral */ + if(huge+x>0.0) { /* raise inexact flag */ + i0 &= (~i); i1=0; + } + } + } else if (j0>51) { + if(j0==0x400) return x+x; /* inf or NaN */ + else return x; /* x is integral */ + } else { + i = ((u_int32_t)(0xffffffff))>>(j0-20); + if((i1&i)==0) return x; /* x is integral */ + if(huge+x>0.0) /* raise inexact flag */ + i1 &= (~i); + } + INSERT_WORDS(x,i0,i1); + return x; +} + +#if LDBL_MANT_DIG == 53 +openlibm_weak_reference(trunc, truncl); +#endif diff --git a/src/openlibm/src/s_trunc.c.o b/src/openlibm/src/s_trunc.c.o new file mode 100644 index 0000000000000000000000000000000000000000..32a9c293c639e00e86fa786e5df2832e3b273949 GIT binary patch literal 1744 zcmb<-^>JfjWMqH=Mg}_u1P><4z!1QUU^{@B4h(z@ybNg`{B?&sIWE43$BI-6hCwxcj-Lfaqzi<2j}rL5B|LKY5W=o4>$ibu9F6t z(D;*qg@K{;)hGUl6R)47@yoY>OkwElc>DYR{~iDT|NjqCb@@f>g_2{)c6`5}cmZUO z3%@(qbdV)b3trDnn}Dnoq>R6>};i=;qDizsbFZLXQXGSU}RuqYG7z+pr8?ynxf#5SOS&MHP>VS`GG-!fq?-O z2JU{L3``7+2Ur*w;BmkR<#U242%^5jM6;p91|EJ;xbS&&^HED`C*f%P&dQbN36? zEiOq+&W7^S^Gfv!it-Cmi%KdP^uWfYX2hozCFZ7r?WO_&@)sy>*wD;^ + +#include "math_private.h" + +static const float huge = 1.0e30F; + +OLM_DLLEXPORT float +truncf(float x) +{ + int32_t i0,j0; + u_int32_t i; + GET_FLOAT_WORD(i0,x); + j0 = ((i0>>23)&0xff)-0x7f; + if(j0<23) { + if(j0<0) { /* raise inexact if x != 0 */ + if(huge+x>0.0F) /* |x|<1, so return 0*sign(x) */ + i0 &= 0x80000000; + } else { + i = (0x007fffff)>>j0; + if((i0&i)==0) return x; /* x is integral */ + if(huge+x>0.0F) /* raise inexact flag */ + i0 &= (~i); + } + } else { + if(j0==0x80) return x+x; /* inf or NaN */ + else return x; /* x is integral */ + } + SET_FLOAT_WORD(x,i0); + return x; +} diff --git a/src/openlibm/src/s_truncf.c.o b/src/openlibm/src/s_truncf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..ab4842624b3e56a5c661c3451f1ccbb426f8285c GIT binary patch literal 1600 zcmb<-^>JfjWMqH=Mg}_u1P><4z;J*G!FB*M9T@l+cp1|8>kf5ZJora<9~mt@eu<9Lqi&W-l@<0 z5jQ^bAG*xQA99L6^a6j_DUdm*K6w^0xH~&rDQLL+g=#7on&=tn87deV7?~Ov8X72Q z1f`}ZcqEoUC3MX-85md?7#I{77#LU?7#Q6BLK&DC7!QENU}3=s<#U1@!N9;E0;L(N zf*2Sp1Q?}x*f}OJLd0dDa#Nr*J_=+$3&Y3%*wip%i3uLCLXa!L3^*akz`!7cq#kZ} zaePTpXh2ZuN)Y(P>V^&kvlgRx$5Wo}7g z5`$iGNfCt3fU$~Fa}xDRQY%Ur^imQ_5*hT8ii;Wait<4mz2xE&69&EH{M_8syb=bz zy!?_>J$JuQ-QtqOr+JUKuiT?l@%D}*202Sb7U;xJs2b3=XrPZL~pg4dEfvGEC z5|e-$3zq=JBgjm0^&3L%7lNAzVZiJM7v>jAG%%2cd3=B7*41FjKqhRib z(e6{DaC4nEfzukTp=HVE4d?43Go^149K=0F>`RVUDgJWF~stgS0$=>WA3_ b5(8nVFo+4ppmGD7eg~+dD#5A{1iF3zmZhaN literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_truncl.c b/src/openlibm/src/s_truncl.c new file mode 100644 index 0000000..34d7b65 --- /dev/null +++ b/src/openlibm/src/s_truncl.c @@ -0,0 +1,69 @@ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + * + * From: @(#)s_floor.c 5.1 93/09/24 + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_truncl.c,v 1.9 2008/02/14 15:10:34 bde Exp $"); + +/* + * truncl(x) + * Return x rounded toward 0 to integral value + * Method: + * Bit twiddling. + * Exception: + * Inexact flag raised if x not equal to truncl(x). + */ + +#include +#include +#include + +#include "fpmath.h" +#include "math_private.h" + +#ifdef LDBL_IMPLICIT_NBIT +#define MANH_SIZE (LDBL_MANH_SIZE + 1) +#else +#define MANH_SIZE LDBL_MANH_SIZE +#endif + +static const long double huge = 1.0e300; +static const float zero[] = { 0.0, -0.0 }; + +OLM_DLLEXPORT long double +truncl(long double x) +{ + union IEEEl2bits u = { .e = x }; + int e = u.bits.exp - LDBL_MAX_EXP + 1; + + if (e < MANH_SIZE - 1) { + if (e < 0) { /* raise inexact if x != 0 */ + if (huge + x > 0.0) + u.e = zero[u.bits.sign]; + } else { + uint64_t m = ((1llu << MANH_SIZE) - 1) >> (e + 1); + if (((u.bits.manh & m) | u.bits.manl) == 0) + return (x); /* x is integral */ + if (huge + x > 0.0) { /* raise inexact flag */ + u.bits.manh &= ~m; + u.bits.manl = 0; + } + } + } else if (e < LDBL_MANT_DIG - 1) { + uint64_t m = (uint64_t)-1 >> (64 - LDBL_MANT_DIG + e + 1); + if ((u.bits.manl & m) == 0) + return (x); /* x is integral */ + if (huge + x > 0.0) /* raise inexact flag */ + u.bits.manl &= ~m; + } + return (u.e); +} diff --git a/src/openlibm/src/s_truncl.c.o b/src/openlibm/src/s_truncl.c.o new file mode 100644 index 0000000000000000000000000000000000000000..43d027130e4a4f41043c8f48c9048e03862db08d GIT binary patch literal 1896 zcmb<-^>JfjWMqH=Mg}_u1P><4z_5ZD!FB*M9T@l-_!w^IsBqjoaJxq31^;#*l@E;% z|JO4x^fodc`2WB8hg^L^>jD0b6$}gvcW-!fhp2EgzWis;z_8>0|Ns9zF2C^Tyw-Wi z{fURR-V5|yaV5|^el;&aQn83)u01}sh%Kd}V_$ZM1EDRt2V^hP7B?a&> zFfcHJT?x^_0inPoGmXoEclrZR}B$gyH=p_{wGw2oNLpTsxFS)qHf +#include + +typedef uint8_t u_int8_t; +typedef uint16_t u_int16_t; +typedef uint32_t u_int32_t; +typedef uint64_t u_int64_t; + + +#endif diff --git a/src/openlibm/src/w_cabs.c b/src/openlibm/src/w_cabs.c new file mode 100644 index 0000000..6dc9bde --- /dev/null +++ b/src/openlibm/src/w_cabs.c @@ -0,0 +1,25 @@ +/* + * cabs() wrapper for hypot(). + * + * Written by J.T. Conklin, + * Placed into the Public Domain, 1994. + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/w_cabs.c,v 1.7 2008/03/30 20:03:06 das Exp $"); + +#include +#include +#include + +#include "math_private.h" + +OLM_DLLEXPORT double +cabs(double complex z) +{ + return hypot(creal(z), cimag(z)); +} + +#if LDBL_MANT_DIG == 53 +openlibm_weak_reference(cabs, cabsl); +#endif diff --git a/src/openlibm/src/w_cabs.c.o b/src/openlibm/src/w_cabs.c.o new file mode 100644 index 0000000000000000000000000000000000000000..510931ede6593b656ffc181e5f07693d0987665f GIT binary patch literal 1528 zcmb<-^>JfjWMqH=Mg}_u1P><4z_5b}!FB*M9T<2Sco>2`n%@X~;uqvm`NS{iqQdb4 zB=?D5AVh`Z6TbkDN}30M-QhHTjYD7wkLDu+X&(G}r=wqj)G@d_J6kDexch}_Dj1sR z8R;1+7#SFu8W6c`v7SQ!`?-2Flsm>3ujfW%;K zW`y!N!KxV;M4&WdRS*MXg#e>84?D*MMg|5M1_%a8+kyy3K7nQ?7e0ktJ^?pA4v+{| z46=uX;p2a7lFV2_j*EeTK?q44Y!?Fq13v=;g8&voL~)2q;}B;kk55iaD%MM808tFd znYoGS49P{Qi8%}zl?C}FFe?P13{Y5s@Spz>poJt33R9T4C6YKB0|Nt092E8-DNu3% zVGtXP^@=NVOA?b9^omQ0Aan+dRg{{Os8^C&QNo~?l30?+pqEr!%%GQ?pPQSSSHhr| zmtT^q=k6D(TU?TuoDJot=auRe6y+DB7L`;o=z&d0&4^DcO3Y0KTSqAY@&_m`L4HFv z3zD`O7+~=PlS7XyP<(*G5vCrd?ghwD1_lNXr~oMbK|-(;B>@#zV_*QM3T7xDM%BU? zXf((SWFZ{}1_qFsN7w%VEX%-P0i|ISy8c)O1_o^LX8<)27Ehq~ z1L*}}kXbNskbj^`LBen>0g_-~U|0ba;bvf90L2lyeo*-Y5{D{-QwN~>72zTf22>cr XVPIeY + * Placed into the Public Domain, 1994. + */ + +#include +#include + +#include "math_private.h" + +OLM_DLLEXPORT float +cabsf(z) + float complex z; +{ + + return hypotf(crealf(z), cimagf(z)); +} diff --git a/src/openlibm/src/w_cabsf.c.o b/src/openlibm/src/w_cabsf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..07cf2715e73238a2e170a0c1425af7e5f030c010 GIT binary patch literal 1560 zcmb<-^>JfjWMqH=Mg}_u1P><4z;J^J!FB*M9T<2Sco@<=`0EaMG{4dCIQT;0GrypV zibSW2iVT>=^O?U6!smDa((;*KAV!7fGrvHH3I|vL%V&PU7!`rf{DL7WB4EV=FoixU zEFR5AG+u)AF}OQBTPbL``-N&M7@FuA=@}{*85o%w7#bQVXauFED0n26KqYj|HNiR< zSQr=>6c`v7SQ!`?-2Flsm>3ujfW%;aV}$ZKA<7v|M?FAfk@(@ zu!M;xAc?avFfhQxL17M(0wos^2C>0duedU|Br%CWuehWLLTA8OMX5Q7dL^k9B@B8g zi6w~)dP&8_40_4=xw)x%B@B9b`6a1(?tY=V#U+W!*-(CZUa4L|QGP*cQAs6(9@vD` zjQF&o#N1S{b(9hye}Li=_ytL+LB*Lt93;F1iH*zzxfPkO!@$4*GLu~WhEV$rkPT&EV1U`Lk0uVYA4Xe2 z^`j|cxQs3U<-_zrxeQ(m3=HfH3=GiVf(bL+fU?lt1@bFY3QQ$I?MK(o0kw#b{#YFG z7XUR77Ehq~1KAD2Ad6w*AZwsXLBeos0g_-~U|0ba0p)*C9HHw6l}jLTs4_V90IDC9 ZKH!2-zasNN + * Placed into the Public Domain, 1994. + * + * Modified by Steven G. Kargl for the long double type. + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/w_cabsl.c,v 1.1 2008/03/30 20:02:03 das Exp $"); + +#include +#include + +#include "math_private.h" + +OLM_DLLEXPORT long double +cabsl(long double complex z) +{ + return hypotl(creall(z), cimagl(z)); +} diff --git a/src/openlibm/src/w_cabsl.c.o b/src/openlibm/src/w_cabsl.c.o new file mode 100644 index 0000000000000000000000000000000000000000..17d17ed7b43406606dfcf2ab55ec903745010c03 GIT binary patch literal 1536 zcmb<-^>JfjWMqH=Mg}_u1P><4z;J*G!FB*M9T<2Sco;mI-$dNbQAxO+qf&75!0j3p zf!j4I4mS_nwo$oVqhjy^r1W-;io)$26$h|vj*7u;8x@Fnj*7zV8kK_EH7W@n%|{|$ zf)q2jJ3Ct`Xt?`@YAP6-=o#r5Di|3UnHm@x8YpN4rKTu&B$hxWbj>vxSQr=>6c`v7 zSQ!`?-2Flsm>3ujfW*K?F)%PNLisR1i9jV7tAZF9D+Cy&dDuB7FfuTJ#ATpzfgsw2 zFM-K}j|0TShC$}BFns)vO^z8$2y!zpFbE-ugY95oU=Up)=y!hillfCWg9fdL$zps<9A z`yz?6F)%Q|#6e*Wk^&_Q5C*ZqSg*J;wbdHE%&dhULqy2T}l$=OhTdS0nsK~a7|YEelggC5v~)QtGF zqQu-(uyvFYAb)`3667~zvmj}lfdLjzFgf(Nl7@yEOg&892aur*3=AGn0WNS_WMF_L zC{X-@q|~6|%peXDo`}RoW0|Nt0Kf1eM;Rn;71hpSs{|Bf7Li%HI#GeJ!Kv+D1 z;tymu2!o7IbC{xFFQ8 X$b3-wflYq^)KQ>3kE|YQEL;cxl+=z9 literal 0 HcmV?d00001 diff --git a/src/openlibm/test/.gitignore b/src/openlibm/test/.gitignore new file mode 100644 index 0000000..2d85b23 --- /dev/null +++ b/src/openlibm/test/.gitignore @@ -0,0 +1,9 @@ +/test-float +/test-float-system +/test-float.dSYM +/test-double +/test-double-system +/test-double.dSYM +/bench-openlibm +/bench-syslibm +/*.exe diff --git a/src/openlibm/test/Makefile b/src/openlibm/test/Makefile new file mode 100644 index 0000000..a61ce5a --- /dev/null +++ b/src/openlibm/test/Makefile @@ -0,0 +1,37 @@ +OPENLIBM_HOME=$(abspath ..) +include ../Make.inc + +# Set rpath of tests to builddir for loading shared library +OPENLIBM_LIB = -L.. -lopenlibm +ifneq ($(OS),WINNT) +ifneq ($(OS),Darwin) +OPENLIBM_LIB += -Wl,-rpath=$(OPENLIBM_HOME) +endif +else # WINNT +CFLAGS_add += -DIMPORT_EXPORTS +endif + +all: test-double test-float # test-double-system test-float-system + +bench: bench-syslibm bench-openlibm + +test-double: test-double.c libm-test.c libm-test-ulps.h + $(CC) $(CPPFLAGS) $(CFLAGS) $(CFLAGS_add) $(LDFLAGS) $(LDFLAGS_arch) $@.c -D__BSD_VISIBLE -I ../include -I../src $(OPENLIBM_LIB) -o $@ + +test-float: test-float.c libm-test.c libm-test-ulps.h + $(CC) $(CPPFLAGS) $(CFLAGS) $(CFLAGS_add) $(LDFLAGS) $(LDFLAGS_arch) $@.c -D__BSD_VISIBLE -I ../include -I../src $(OPENLIBM_LIB) -o $@ + +test-double-system: test-double.c libm-test.c libm-test-ulps.h + $(CC) $(CPPFLAGS) $(CFLAGS) $(CFLAGS_add) $(LDFLAGS) $(LDFLAGS_arch) $< -DSYS_MATH_H -lm -o $@ + +test-float-system: test-float.c libm-test.c libm-test-ulps.h + $(CC) $(CPPFLAGS) $(CFLAGS) $(CFLAGS_add) $(LDFLAGS) $(LDFLAGS_arch) $< -DSYS_MATH_H -lm -o $@ + +bench-openlibm: libm-bench.cpp + $(CC) $(CPPFLAGS) $(CFLAGS) $(CFLAGS_add) $(LDFLAGS) $(LDFLAGS_arch) $< $(OPENLIBM_LIB) -o $@ + +bench-syslibm: libm-bench.cpp + $(CC) $(CPPFLAGS) $(CFLAGS) $(CFLAGS_add) $(LDFLAGS) $(LDFLAGS_arch) $< -lm -o $@ + +clean: + rm -fr test-double test-float test-double-system test-float-system bench-openlibm bench-syslibm *.dSYM diff --git a/src/openlibm/test/inf_torture.c b/src/openlibm/test/inf_torture.c new file mode 100644 index 0000000..f2b0124 --- /dev/null +++ b/src/openlibm/test/inf_torture.c @@ -0,0 +1,76 @@ +#include +#include + +int main(); +int main2(); +int main3(); +int main4(); + +int main() { + printf("+inf:\n"); + float fx = (float)INFINITY; unsigned int *fxi = (unsigned int*)&fx; + double dx = (double)INFINITY; long unsigned long int *dxi = (long unsigned long int*)&dx; + long double ldx = (long double)INFINITY; long unsigned long int *ldxi1 = (long unsigned long int*)&ldx; long unsigned long int *ldxi2 = &(ldxi1[1]); + printf("\t\tf d ld\n"); + printf("correct:\t%x %x %x\n", isinf(fx), isinf(dx), isinf(ldx)); + printf("as floats:\t%x %x %x\n", isinf(*(float*)fxi), isinf(*(float*)dxi), isinf(*(float*)ldxi1)); + printf("as double:\t%x %x %x\n", isinf(*(double*)fxi), isinf(*(double*)dxi), isinf(*(double*)ldxi1)); + printf("as long double:\t%x %x %x\n", isinf(*(long double*)fxi), isinf(*(long double*)dxi), isinf(*(long double*)ldxi1)); + printf("sizes ?4 8 12?:\t%d %d %d\n", (int)sizeof(fx), (int)sizeof(dx), (int)sizeof(ldx)); + printf("sizes:\t%d %d %d\n", (int)sizeof(*fxi), (int)sizeof(*dxi), (int)sizeof(*ldxi1)*2); + printf("bit repr:\n f: %x\n d: %llx\n ld: %llx%llx\n", *fxi, *dxi, (0xFFFF)&*ldxi2, *ldxi1); + printf("\n"); + main2(); + return 0; +} + +int main2() { + printf("-inf:\n"); + float fx = (float)-INFINITY; unsigned int *fxi = (unsigned int*)&fx; + double dx = (double)-INFINITY; long unsigned long int *dxi = (long unsigned long int*)&dx; + long double ldx = (long double)-INFINITY; long unsigned long int *ldxi1 = (long unsigned long int*)&ldx; long unsigned long int *ldxi2 = &(ldxi1[1]); + printf("\t\tf d ld\n"); + printf("correct:\t%x %x %x\n", isinf(fx), isinf(dx), isinf(ldx)); + printf("as floats:\t%x %x %x\n", isinf(*(float*)fxi), isinf(*(float*)dxi), isinf(*(float*)ldxi1)); + printf("as double:\t%x %x %x\n", isinf(*(double*)fxi), isinf(*(double*)dxi), isinf(*(double*)ldxi1)); + printf("as long double:\t%x %x %x\n", isinf(*(long double*)fxi), isinf(*(long double*)dxi), isinf(*(long double*)ldxi1)); + printf("sizes ?4 8 12?:\t%d %d %d\n", (int)sizeof(fx), (int)sizeof(dx), (int)sizeof(ldx)); + printf("bit repr:\n f: %x\n d: %llx\n ld: %llx%llx\n", *fxi, *dxi, (0xFFFF)&*ldxi2, *ldxi1); + printf("\n"); + main3(); + return 0; +} + +int main3() { + printf("+NaN:\n"); + float fx = (float)NAN; unsigned int *fxi = (unsigned int*)&fx; + double dx = (double)NAN; long unsigned long int *dxi = (long unsigned long int*)&dx; + long double ldx = (long double)NAN; long unsigned long int *ldxi1 = (long unsigned long int*)&ldx; long unsigned long int *ldxi2 = &(ldxi1[1]); + printf("\t\tf d ld\n"); + printf("correct:\t%x %x %x\n", isnan(fx), isnan(dx), isnan(ldx)); + printf("as floats:\t%x %x %x\n", isnan(*(float*)fxi), isnan(*(float*)dxi), isnan(*(float*)ldxi1)); + printf("as double:\t%x %x %x\n", isnan(*(double*)fxi), isnan(*(double*)dxi), isnan(*(double*)ldxi1)); + printf("as long double:\t%x %x %x\n", isnan(*(long double*)fxi), isnan(*(long double*)dxi), isnan(*(long double*)ldxi1)); + printf("sizes ?4 8 12?:\t%d %d %d\n", (int)sizeof(fx), (int)sizeof(dx), (int)sizeof(ldx)); + printf("sizes:\t%d %d %d\n", (int)sizeof(*fxi), (int)sizeof(*dxi), (int)sizeof(*ldxi1)*2); + printf("bit repr:\n f: %x\n d: %llx\n ld: %llx%llx\n", *fxi, *dxi, (0xFFFF)&*ldxi2, *ldxi1); + printf("\n"); + main4(); + return 0; +} + +int main4() { + printf("-NaN:\n"); + float fx = (float)-NAN; unsigned int *fxi = (unsigned int*)&fx; + double dx = (double)-NAN; long unsigned long int *dxi = (long unsigned long int*)&dx; + long double ldx = (long double)-NAN; long unsigned long int *ldxi1 = (long unsigned long int*)&ldx; long unsigned long int *ldxi2 = &(ldxi1[1]); + printf("\t\tf d ld\n"); + printf("correct:\t%x %x %x\n", isnan(fx), isnan(dx), isnan(ldx)); + printf("as floats:\t%x %x %x\n", isnan(*(float*)fxi), isnan(*(float*)dxi), isnan(*(float*)ldxi1)); + printf("as double:\t%x %x %x\n", isnan(*(double*)fxi), isnan(*(double*)dxi), isnan(*(double*)ldxi1)); + printf("as long double:\t%x %x %x\n", isnan(*(long double*)fxi), isnan(*(long double*)dxi), isnan(*(long double*)ldxi1)); + printf("sizes ?4 8 12?:\t%d %d %d\n", (int)sizeof(fx), (int)sizeof(dx), (int)sizeof(ldx)); + printf("bit repr:\n f: %x\n d: %llx\n ld: %llx%llx\n", *fxi, *dxi, (0xFFFF)&*ldxi2, *ldxi1); + printf("\n"); + return 0; +} diff --git a/src/openlibm/test/libm-bench.cpp b/src/openlibm/test/libm-bench.cpp new file mode 100644 index 0000000..04876de --- /dev/null +++ b/src/openlibm/test/libm-bench.cpp @@ -0,0 +1,144 @@ +// Copyright (C) Dahua Lin, 2014. Provided under the MIT license. + +// Benchmark on libm functions + +#include +#include +#include +#include + + +// Timing facilities + +#ifdef __MACH__ + +#include + +class stimer +{ +public: + typedef uint64_t time_type; + + stimer() + { + ::mach_timebase_info(&m_baseinfo); + } + + time_type current() const + { + return ::mach_absolute_time(); + } + + double span(const time_type& t0, const time_type& t1) const + { + uint64_t d = (m_baseinfo.numer * (t1 - t0)) / m_baseinfo.denom; + return static_cast(d) / 1.0e9; + } + +private: + mach_timebase_info_data_t m_baseinfo; +}; + +#else + +class stimer +{ +public: + typedef timespec time_type; + + time_type current() const + { + time_type t; + ::clock_gettime(CLOCK_REALTIME, &t); + return t; + } + + double span(const time_type& t0, const time_type& t1) const + { + return double(t1.tv_sec - t0.tv_sec) + + double(t1.tv_nsec - t0.tv_nsec) * 1.0e-9; + } +}; + +#endif + + +inline double sec2mps(double s, long n) +{ + return n / (s * 1e6); +} + + +const long ARR_LEN = 1024; + +double a[ARR_LEN]; +double b[ARR_LEN]; +double r[ARR_LEN]; + +#define TFUN1(FNAME) \ + void test_##FNAME(long n) { \ + for (int j = 0; j < ARR_LEN; ++j) r[j] = FNAME(a[j]); \ + stimer tm; \ + stimer::time_type t0 = tm.current(); \ + for(int i = 0; i < n; ++i) { \ + for (int j = 0; j < ARR_LEN; ++j) r[j] = FNAME(a[j]); \ + } \ + double s = tm.span(t0, tm.current()); \ + double mps = sec2mps(s, n * ARR_LEN); \ + printf(" %-8s: %7.4f MPS\n", #FNAME, mps); } + +#define TFUN2(FNAME) \ + void test_##FNAME(long n) { \ + for (int j = 0; j < ARR_LEN; ++j) r[j] = FNAME(a[j], b[j]); \ + stimer tm; \ + stimer::time_type t0 = tm.current(); \ + for(int i = 0; i < n; ++i) { \ + for (int j = 0; j < ARR_LEN; ++j) r[j] = FNAME(a[j], b[j]); \ + } \ + double s = tm.span(t0, tm.current()); \ + double mps = sec2mps(s, n * ARR_LEN); \ + printf(" %-8s: %7.4f MPS\n", #FNAME, mps); } + + +#define TCALL(FNAME) test_##FNAME(20000) + +// define benchmark functions + +TFUN2(pow) +TFUN2(hypot) + +TFUN1(exp) +TFUN1(log) +TFUN1(log10) +TFUN1(sin) +TFUN1(cos) +TFUN1(tan) +TFUN1(asin) +TFUN1(acos) +TFUN1(atan) +TFUN2(atan2) + +int main(int argc, char *argv[]) +{ + // initialize array contents + for (int i = 0; i < ARR_LEN; ++i) + { + a[i] = rand() / (double) RAND_MAX; + b[i] = rand() / (double) RAND_MAX; + } + + TCALL(pow); + TCALL(hypot); + TCALL(exp); + TCALL(log); + TCALL(log10); + TCALL(sin); + TCALL(cos); + TCALL(tan); + TCALL(asin); + TCALL(acos); + TCALL(atan); + TCALL(atan2); + + return 0; +} diff --git a/src/openlibm/test/libm-test-ulps.h b/src/openlibm/test/libm-test-ulps.h new file mode 100644 index 0000000..67a415c --- /dev/null +++ b/src/openlibm/test/libm-test-ulps.h @@ -0,0 +1,254 @@ +/* This file is automatically generated + from libm-test-ulps with gen-libm-test.pl. + Don't change it - change instead the master files. */ + + +/* Maximal error of functions. */ +#define DELTAacos CHOOSE(1150, 1, 1, 1150, 0, 0) /* acos */ +#define DELTAacosh CHOOSE(1, 0, 0, 1, 0, 0) /* acosh */ +#define DELTAasin CHOOSE(1, 1, 0, 1, 0, 0) /* asin */ +#define DELTAasinh CHOOSE(656, 0, 0, 656, 0, 0) /* asinh */ +#define DELTAatan CHOOSE(549, 0, 0, 549, 0, 0) /* atan */ +#define DELTAatanh CHOOSE(1605, 1, 0, 1605, 1, 0) /* atanh */ +#define DELTAatan2 CHOOSE(549, 0, 0, 549, 0, 0) /* atan2 */ +#define DELTAcabs CHOOSE(560, 1, 1, 560, 1, 1) /* cabs */ +#define DELTAcacos CHOOSE(BUILD_COMPLEX (151, 329), BUILD_COMPLEX (1, 0), BUILD_COMPLEX (1, 2), BUILD_COMPLEX (151, 329), BUILD_COMPLEX (1, 0), BUILD_COMPLEX (1, 2)) /* cacos */ +#define DELTAcacosh CHOOSE(BUILD_COMPLEX (328, 151), BUILD_COMPLEX (1, 1), BUILD_COMPLEX (4, 4), BUILD_COMPLEX (328, 151), BUILD_COMPLEX (1, 1), BUILD_COMPLEX (4, 4)) /* cacosh */ +#define DELTAcasin CHOOSE(BUILD_COMPLEX (603, 329), BUILD_COMPLEX (3, 0), BUILD_COMPLEX (2, 2), BUILD_COMPLEX (603, 329), BUILD_COMPLEX (3, 0), BUILD_COMPLEX (2, 2)) /* casin */ +#define DELTAcasinh CHOOSE(BUILD_COMPLEX (892, 12), BUILD_COMPLEX (5, 3), BUILD_COMPLEX (1, 6), BUILD_COMPLEX (892, 12), BUILD_COMPLEX (5, 3), BUILD_COMPLEX (1, 6)) /* casinh */ +#define DELTAcatan CHOOSE(BUILD_COMPLEX (251, 474), BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1), BUILD_COMPLEX (251, 474), BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1)) /* catan */ +#define DELTAcatanh CHOOSE(BUILD_COMPLEX (66, 447), BUILD_COMPLEX (2, 0), BUILD_COMPLEX (1, 0), BUILD_COMPLEX (66, 447), BUILD_COMPLEX (2, 0), BUILD_COMPLEX (1, 0)) /* catanh */ +#define DELTAcbrt CHOOSE(716, 1, 0, 716, 1, 0) /* cbrt */ +#define DELTAccos CHOOSE(BUILD_COMPLEX (5, 1901), BUILD_COMPLEX (1, 1), BUILD_COMPLEX (1, 1), BUILD_COMPLEX (5, 1901), BUILD_COMPLEX (1, 1), BUILD_COMPLEX (1, 1)) /* ccos */ +#define DELTAccosh CHOOSE(BUILD_COMPLEX (1467, 1183), BUILD_COMPLEX (1, 1), BUILD_COMPLEX (1, 1), BUILD_COMPLEX (1467, 1183), BUILD_COMPLEX (1, 1), BUILD_COMPLEX (1, 1)) /* ccosh */ +#define DELTAcexp CHOOSE(BUILD_COMPLEX (940, 1067), 0, BUILD_COMPLEX (1, 0), BUILD_COMPLEX (940, 1067), 0, BUILD_COMPLEX (1, 0)) /* cexp */ +#define DELTAclog CHOOSE(BUILD_COMPLEX (0, 1), 0, 0, BUILD_COMPLEX (0, 1), 0, 0) /* clog */ +#define DELTAclog10 CHOOSE(BUILD_COMPLEX (1403, 186), BUILD_COMPLEX (2, 1), BUILD_COMPLEX (1, 1), BUILD_COMPLEX (1403, 186), BUILD_COMPLEX (2, 1), BUILD_COMPLEX (1, 1)) /* clog10 */ +#define DELTAcos CHOOSE(529, 2, 1, 529, 2, 1) /* cos */ +#define DELTAcosh CHOOSE(309, 0, 0, 309, 0, 0) /* cosh */ +#define DELTAcpow CHOOSE(BUILD_COMPLEX (2, 9), BUILD_COMPLEX (1, 1.104), BUILD_COMPLEX (4, 2.5333), BUILD_COMPLEX (2, 9), BUILD_COMPLEX (1, 1.104), BUILD_COMPLEX (4, 2.5333)) /* cpow */ +#define DELTAcsin CHOOSE(BUILD_COMPLEX (966, 168), 0, 0, BUILD_COMPLEX (966, 168), 0, 0) /* csin */ +#define DELTAcsinh CHOOSE(BUILD_COMPLEX (413, 477), BUILD_COMPLEX (1, 1), BUILD_COMPLEX (1, 1), BUILD_COMPLEX (413, 477), BUILD_COMPLEX (1, 1), BUILD_COMPLEX (1, 1)) /* csinh */ +#define DELTAcsqrt CHOOSE(BUILD_COMPLEX (237, 128), BUILD_COMPLEX (1, 0), 0, BUILD_COMPLEX (237, 128), BUILD_COMPLEX (1, 0), 0) /* csqrt */ +#define DELTActan CHOOSE(BUILD_COMPLEX (690, 367), BUILD_COMPLEX (1, 1), BUILD_COMPLEX (1, 1), BUILD_COMPLEX (690, 367), BUILD_COMPLEX (1, 1), BUILD_COMPLEX (1, 1)) /* ctan */ +#define DELTActanh CHOOSE(BUILD_COMPLEX (286, 3074), BUILD_COMPLEX (0, 1), BUILD_COMPLEX (1, 1), BUILD_COMPLEX (286, 3074), BUILD_COMPLEX (0, 1), BUILD_COMPLEX (1, 1)) /* ctanh */ +#define DELTAerfc CHOOSE(36, 24, 12, 36, 24, 12) /* erfc */ +#define DELTAexp CHOOSE(754, 0, 0, 754, 0, 0) /* exp */ +#define DELTAexp10 CHOOSE(1182, 1, 0, 1182, 1, 0) /* exp10 */ +#define DELTAexp2 CHOOSE(462, 0, 0, 462, 0, 0) /* exp2 */ +#define DELTAexpm1 CHOOSE(825, 1, 1, 825, 0, 0) /* expm1 */ +#define DELTAfmod CHOOSE(4096, 2, 1, 4096, 2, 1) /* fmod */ +#define DELTAgamma CHOOSE(1, 1, 0, 1, 1, 0) /* gamma */ +#define DELTAhypot CHOOSE(560, 1, 1, 560, 0, 0) /* hypot */ +#define DELTAj0 CHOOSE(0, 2, 2, 0, 2, 1) /* j0 */ +#define DELTAj1 CHOOSE(2, 2, 2, 2, 2, 1) /* j1 */ +#define DELTAjn CHOOSE(2, 6, 4, 2, 5, 2) /* jn */ +#define DELTAlgamma CHOOSE(1, 1, 2, 1, 1, 2) /* lgamma */ +#define DELTAlog CHOOSE(2341, 1, 1, 2341, 1, 1) /* log */ +#define DELTAlog10 CHOOSE(2033, 1, 1, 2033, 1, 1) /* log10 */ +#define DELTAlog1p CHOOSE(585, 1, 1, 585, 1, 1) /* log1p */ +#define DELTAlog2 CHOOSE(1688, 1, 1, 1688, 1, 1) /* log2 */ +#define DELTApow CHOOSE(725, 0, 0, 725, 0, 0) /* pow */ +#define DELTAsin CHOOSE(627, 0, 0, 627, 0, 0) /* sin */ +#define DELTAsincos CHOOSE(627, 1, 1, 627, 1, 1) /* sincos */ +#define DELTAsinh CHOOSE(1029, 1, 1, 1028, 0, 1) /* sinh */ +#define DELTAsqrt CHOOSE(489, 0, 0, 489, 0, 0) /* sqrt */ +#define DELTAtan CHOOSE(1401, 1, 1, 1401, 0.5, 0) /* tan */ +#define DELTAtanh CHOOSE(521, 1, 1, 521, 0, 0) /* tanh */ +#define DELTAtgamma CHOOSE(2, 2, 1, 2, 2, 1) /* tgamma */ +#define DELTAy0 CHOOSE(2, 3, 1, 2, 3, 1) /* y0 */ +#define DELTAy1 CHOOSE(2, 3, 2, 2, 3, 2) /* y1 */ +#define DELTAyn CHOOSE(7, 6, 3, 7, 6, 3) /* yn */ + +/* Error of single function calls. */ +#define DELTA16 CHOOSE(1, 0, 0, 1, 0, 0) /* acosh (7) == 2.633915793849633417250092694615937 */ +#define DELTA24 CHOOSE(1, 1, 0, 1, 0, 0) /* asin (0.5) == pi/6 */ +#define DELTA25 CHOOSE(1, 1, 0, 1, 0, 0) /* asin (-0.5) == -pi/6 */ +#define DELTA26 CHOOSE(1, 0, 0, 1, 0, 0) /* asin (1.0) == pi/2 */ +#define DELTA27 CHOOSE(1, 0, 0, 1, 0, 0) /* asin (-1.0) == -pi/2 */ +#define DELTA28 CHOOSE(1, 1, 0, 1, 0, 0) /* asin (0.7) == 0.77539749661075306374035335271498708 */ +#define DELTA34 CHOOSE(656, 1, 0, 656, 0, 0) /* asinh (0.7) == 0.652666566082355786 */ +#define DELTA42 CHOOSE(549, 0, 0, 549, 0, 0) /* atan (0.7) == 0.61072596438920861654375887649023613 */ +#define DELTA50 CHOOSE(1605, 1, 0, 1605, 1, 0) /* atanh (0.7) == 0.8673005276940531944 */ +#define DELTA74 CHOOSE(549, 0, 0, 549, 0, 0) /* atan2 (0.7, 1) == 0.61072596438920861654375887649023613 */ +#define DELTA78 CHOOSE(1, 0, 0, 1, 0, 0) /* atan2 (0.4, 0.0003) == 1.5700463269355215717704032607580829 */ +#define DELTA85 CHOOSE(0, 0, 1, 0, 0, 1) /* cabs (0.7 + 12.4 i) == 12.419742348374220601176836866763271 */ +#define DELTA86 CHOOSE(0, 0, 1, 0, 0, 1) /* cabs (-12.4 + 0.7 i) == 12.419742348374220601176836866763271 */ +#define DELTA87 CHOOSE(0, 0, 1, 0, 0, 1) /* cabs (-0.7 + 12.4 i) == 12.419742348374220601176836866763271 */ +#define DELTA88 CHOOSE(0, 0, 1, 0, 0, 1) /* cabs (-12.4 - 0.7 i) == 12.419742348374220601176836866763271 */ +#define DELTA89 CHOOSE(0, 0, 1, 0, 0, 1) /* cabs (-0.7 - 12.4 i) == 12.419742348374220601176836866763271 */ +#define DELTA96 CHOOSE(560, 1, 0, 560, 1, 0) /* cabs (0.7 + 1.2 i) == 1.3892443989449804508432547041028554 */ +#define DELTA130 CHOOSE(BUILD_COMPLEX (151, 329), BUILD_COMPLEX (1, 0), BUILD_COMPLEX (1, 2), BUILD_COMPLEX (151, 329), BUILD_COMPLEX (1, 0), BUILD_COMPLEX (1, 2)) /* cacos (0.7 + 1.2 i) == 1.1351827477151551088992008271819053 - 1.0927647857577371459105272080819308 i */ +#define DELTA131 CHOOSE(BUILD_COMPLEX (0, 1), 0, 0, BUILD_COMPLEX (0, 1), 0, 0) /* cacos (-2 - 3 i) == 2.1414491111159960199416055713254211 + 1.9833870299165354323470769028940395 i */ +#define DELTA165 CHOOSE(BUILD_COMPLEX (328, 151), BUILD_COMPLEX (1, 0), 0, BUILD_COMPLEX (328, 151), BUILD_COMPLEX (1, 0), 0) /* cacosh (0.7 + 1.2 i) == 1.0927647857577371459105272080819308 + 1.1351827477151551088992008271819053 i */ +#define DELTA166 CHOOSE(BUILD_COMPLEX (6, 1), BUILD_COMPLEX (1, 1), BUILD_COMPLEX (4, 4), BUILD_COMPLEX (6, 1), BUILD_COMPLEX (1, 1), BUILD_COMPLEX (4, 4)) /* cacosh (-2 - 3 i) == -1.9833870299165354323470769028940395 + 2.1414491111159960199416055713254211 i */ +#define DELTA225 CHOOSE(BUILD_COMPLEX (603, 329), BUILD_COMPLEX (3, 0), BUILD_COMPLEX (2, 2), BUILD_COMPLEX (603, 329), BUILD_COMPLEX (3, 0), BUILD_COMPLEX (2, 2)) /* casin (0.7 + 1.2 i) == 0.4356135790797415103321208644578462 + 1.0927647857577371459105272080819308 i */ +#define DELTA226 CHOOSE(BUILD_COMPLEX (0, 1), 0, 0, BUILD_COMPLEX (0, 1), 0, 0) /* casin (-2 - 3 i) == -0.57065278432109940071028387968566963 - 1.9833870299165354323470769028940395 i */ +#define DELTA262 CHOOSE(BUILD_COMPLEX (892, 12), 0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (892, 12), 0, BUILD_COMPLEX (0, 1)) /* casinh (0.7 + 1.2 i) == 0.97865459559367387689317593222160964 + 0.91135418953156011567903546856170941 i */ +#define DELTA263 CHOOSE(BUILD_COMPLEX (6, 6), BUILD_COMPLEX (5, 3), BUILD_COMPLEX (1, 6), BUILD_COMPLEX (6, 6), BUILD_COMPLEX (5, 3), BUILD_COMPLEX (1, 6)) /* casinh (-2 - 3 i) == -1.9686379257930962917886650952454982 - 0.96465850440760279204541105949953237 i */ +#define DELTA301 CHOOSE(BUILD_COMPLEX (251, 474), 0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (251, 474), 0, BUILD_COMPLEX (0, 1)) /* catan (0.7 + 1.2 i) == 1.0785743834118921877443707996386368 + 0.57705737765343067644394541889341712 i */ +#define DELTA302 CHOOSE(BUILD_COMPLEX (0, 7), BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 7), BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1)) /* catan (-2 - 3 i) == -1.4099210495965755225306193844604208 - 0.22907268296853876629588180294200276 i */ +#define DELTA340 CHOOSE(BUILD_COMPLEX (66, 447), BUILD_COMPLEX (1, 0), 0, BUILD_COMPLEX (66, 447), BUILD_COMPLEX (1, 0), 0) /* catanh (0.7 + 1.2 i) == 0.2600749516525135959200648705635915 + 0.97024030779509898497385130162655963 i */ +#define DELTA341 CHOOSE(BUILD_COMPLEX (6, 0), BUILD_COMPLEX (2, 0), BUILD_COMPLEX (1, 0), BUILD_COMPLEX (6, 0), BUILD_COMPLEX (2, 0), BUILD_COMPLEX (1, 0)) /* catanh (-2 - 3 i) == -0.14694666622552975204743278515471595 - 1.3389725222944935611241935759091443 i */ +#define DELTA347 CHOOSE(716, 0, 0, 716, 0, 0) /* cbrt (-0.001) == -0.1 */ +#define DELTA349 CHOOSE(1, 0, 0, 1, 0, 0) /* cbrt (-27.0) == -3.0 */ +#define DELTA350 CHOOSE(306, 0, 0, 306, 0, 0) /* cbrt (0.970299) == 0.99 */ +#define DELTA351 CHOOSE(346, 1, 0, 346, 1, 0) /* cbrt (0.7) == 0.8879040017426007084 */ +#define DELTA389 CHOOSE(BUILD_COMPLEX (5, 1901), BUILD_COMPLEX (1, 1), BUILD_COMPLEX (1, 0), BUILD_COMPLEX (5, 1901), BUILD_COMPLEX (1, 1), BUILD_COMPLEX (1, 0)) /* ccos (0.7 + 1.2 i) == 1.3848657645312111080 - 0.97242170335830028619 i */ +#define DELTA390 CHOOSE(BUILD_COMPLEX (0, 1), 0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1), 0, BUILD_COMPLEX (0, 1)) /* ccos (-2 - 3 i) == -4.1896256909688072301 - 9.1092278937553365979 i */ +#define DELTA428 CHOOSE(BUILD_COMPLEX (1467, 1183), BUILD_COMPLEX (1, 0), BUILD_COMPLEX (1, 0), BUILD_COMPLEX (1467, 1183), BUILD_COMPLEX (1, 0), BUILD_COMPLEX (1, 0)) /* ccosh (0.7 + 1.2 i) == 0.4548202223691477654 + 0.7070296600921537682 i */ +#define DELTA429 CHOOSE(BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1)) /* ccosh (-2 - 3 i) == -3.7245455049153225654 + 0.5118225699873846088 i */ +#define DELTA469 CHOOSE(BUILD_COMPLEX (940, 0), 0, BUILD_COMPLEX (1, 0), BUILD_COMPLEX (940, 0), 0, BUILD_COMPLEX (1, 0)) /* cexp (0.7 + 1.2 i) == 0.72969890915032360123451688642930727 + 1.8768962328348102821139467908203072 i */ +#define DELTA470 CHOOSE(BUILD_COMPLEX (4, 18), 0, 0, BUILD_COMPLEX (4, 18), 0, 0) /* cexp (-2.0 - 3.0 i) == -0.13398091492954261346140525546115575 - 0.019098516261135196432576240858800925 i */ +#define DELTA515 CHOOSE(BUILD_COMPLEX (0, 1), 0, 0, BUILD_COMPLEX (0, 1), 0, 0) /* clog (-2 - 3 i) == 1.2824746787307683680267437207826593 - 2.1587989303424641704769327722648368 i */ +#define DELTA520 CHOOSE(0, BUILD_COMPLEX (0, 1), 0, 0, BUILD_COMPLEX (0, 1), 0) /* clog10 (-inf + inf i) == inf + 3/4 pi*log10(e) i */ +#define DELTA521 CHOOSE(0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1), 0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1)) /* clog10 (inf + inf i) == inf + pi/4*log10(e) i */ +#define DELTA522 CHOOSE(0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1), 0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1)) /* clog10 (inf - inf i) == inf - pi/4*log10(e) i */ +#define DELTA523 CHOOSE(0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1), 0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1)) /* clog10 (0 + inf i) == inf + pi/2*log10(e) i */ +#define DELTA524 CHOOSE(0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1), 0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1)) /* clog10 (3 + inf i) == inf + pi/2*log10(e) i */ +#define DELTA525 CHOOSE(0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1), 0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1)) /* clog10 (-0 + inf i) == inf + pi/2*log10(e) i */ +#define DELTA526 CHOOSE(0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1), 0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1)) /* clog10 (-3 + inf i) == inf + pi/2*log10(e) i */ +#define DELTA527 CHOOSE(0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1), 0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1)) /* clog10 (0 - inf i) == inf - pi/2*log10(e) i */ +#define DELTA528 CHOOSE(0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1), 0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1)) /* clog10 (3 - inf i) == inf - pi/2*log10(e) i */ +#define DELTA529 CHOOSE(0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1), 0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1)) /* clog10 (-0 - inf i) == inf - pi/2*log10(e) i */ +#define DELTA530 CHOOSE(0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1), 0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1)) /* clog10 (-3 - inf i) == inf - pi/2*log10(e) i */ +#define DELTA531 CHOOSE(0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1), 0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1)) /* clog10 (-inf + 0 i) == inf + pi*log10(e) i */ +#define DELTA532 CHOOSE(0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1), 0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1)) /* clog10 (-inf + 1 i) == inf + pi*log10(e) i */ +#define DELTA533 CHOOSE(0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1), 0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1)) /* clog10 (-inf - 0 i) == inf - pi*log10(e) i */ +#define DELTA534 CHOOSE(0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1), 0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1)) /* clog10 (-inf - 1 i) == inf - pi*log10(e) i */ +#define DELTA552 CHOOSE(BUILD_COMPLEX (1403, 186), BUILD_COMPLEX (2, 1), BUILD_COMPLEX (1, 0), BUILD_COMPLEX (1403, 186), BUILD_COMPLEX (2, 1), BUILD_COMPLEX (1, 0)) /* clog10 (0.7 + 1.2 i) == 0.1427786545038868803 + 0.4528483579352493248 i */ +#define DELTA553 CHOOSE(BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1), 0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 1), 0) /* clog10 (-2 - 3 i) == 0.5569716761534183846 - 0.9375544629863747085 i */ +#define DELTA582 CHOOSE(0, 1, 0.5, 0, 1, 0.5) /* cos (M_PI_6l * 2.0) == 0.5 */ +#define DELTA583 CHOOSE(0.5, 2, 1, 0.5, 2, 1) /* cos (M_PI_6l * 4.0) == -0.5 */ +#define DELTA584 CHOOSE(0.25, 0.2758, 0.3667, 0.25, 0.2758, 0.3667) /* cos (pi/2) == 0 */ +#define DELTA585 CHOOSE(529, 1, 0, 529, 1, 0) /* cos (0.7) == 0.76484218728448842625585999019186495 */ +#define DELTA591 CHOOSE(309, 0, 0, 309, 0, 0) /* cosh (0.7) == 1.255169005630943018 */ +#define DELTA594 CHOOSE(BUILD_COMPLEX (0, 9), BUILD_COMPLEX (0, 1.104), BUILD_COMPLEX (0, 2.5333), BUILD_COMPLEX (0, 9), BUILD_COMPLEX (0, 1.104), BUILD_COMPLEX (0, 2.5333)) /* cpow (e + 0 i, 0 + 2 * M_PIl i) == 1.0 + 0.0 i */ +#define DELTA595 CHOOSE(BUILD_COMPLEX (2, 5), BUILD_COMPLEX (1, 0), BUILD_COMPLEX (4, 1), BUILD_COMPLEX (2, 5), BUILD_COMPLEX (1, 0), BUILD_COMPLEX (4, 1)) /* cpow (2 + 3 i, 4 + 0 i) == -119.0 - 120.0 i */ +#define DELTA652 CHOOSE(BUILD_COMPLEX (966, 168), 0, 0, BUILD_COMPLEX (966, 168), 0, 0) /* csin (0.7 + 1.2 i) == 1.1664563419657581376 + 1.1544997246948547371 i */ +#define DELTA691 CHOOSE(BUILD_COMPLEX (413, 477), BUILD_COMPLEX (1, 0), BUILD_COMPLEX (1, 0), BUILD_COMPLEX (413, 477), BUILD_COMPLEX (1, 0), BUILD_COMPLEX (1, 0)) /* csinh (0.7 + 1.2 i) == 0.27487868678117583582 + 1.1698665727426565139 i */ +#define DELTA692 CHOOSE(BUILD_COMPLEX (0, 2), BUILD_COMPLEX (1, 1), BUILD_COMPLEX (0, 1), BUILD_COMPLEX (0, 2), BUILD_COMPLEX (1, 1), BUILD_COMPLEX (0, 1)) /* csinh (-2 - 3 i) == 3.5905645899857799520 - 0.5309210862485198052 i */ +#define DELTA732 CHOOSE(BUILD_COMPLEX (237, 128), BUILD_COMPLEX (1, 0), 0, BUILD_COMPLEX (237, 128), BUILD_COMPLEX (1, 0), 0) /* csqrt (0.7 + 1.2 i) == 1.022067610030026450706487883081139 + 0.58704531296356521154977678719838035 i */ +#define DELTA733 CHOOSE(BUILD_COMPLEX (1, 0), 0, 0, BUILD_COMPLEX (1, 0), 0, 0) /* csqrt (-2 - 3 i) == 0.89597747612983812471573375529004348 - 1.6741492280355400404480393008490519 i */ +#define DELTA734 CHOOSE(BUILD_COMPLEX (1, 0), 0, 0, BUILD_COMPLEX (1, 0), 0, 0) /* csqrt (-2 + 3 i) == 0.89597747612983812471573375529004348 + 1.6741492280355400404480393008490519 i */ +#define DELTA766 CHOOSE(BUILD_COMPLEX (690, 367), BUILD_COMPLEX (1, 1), BUILD_COMPLEX (1, 0), BUILD_COMPLEX (690, 367), BUILD_COMPLEX (1, 1), BUILD_COMPLEX (1, 0)) /* ctan (0.7 + 1.2 i) == 0.1720734197630349001 + 0.9544807059989405538 i */ +#define DELTA767 CHOOSE(BUILD_COMPLEX (439, 2), 0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (439, 2), 0, BUILD_COMPLEX (0, 1)) /* ctan (-2 - 3 i) == 0.0037640256415042482 - 1.0032386273536098014 i */ +#define DELTA799 CHOOSE(0, BUILD_COMPLEX (0, 0.5), BUILD_COMPLEX (0, 1), 0, BUILD_COMPLEX (0, 0.5), BUILD_COMPLEX (0, 1)) /* ctanh (0 + pi/4 i) == 0.0 + 1.0 i */ +#define DELTA800 CHOOSE(BUILD_COMPLEX (286, 3074), BUILD_COMPLEX (0, 1), BUILD_COMPLEX (1, 0), BUILD_COMPLEX (286, 3074), BUILD_COMPLEX (0, 1), BUILD_COMPLEX (1, 0)) /* ctanh (0.7 + 1.2 i) == 1.3472197399061191630 + 0.4778641038326365540 i */ +#define DELTA801 CHOOSE(BUILD_COMPLEX (5, 25), 0, BUILD_COMPLEX (0, 1), BUILD_COMPLEX (5, 25), 0, BUILD_COMPLEX (0, 1)) /* ctanh (-2 - 3 i) == -0.9653858790221331242 + 0.0098843750383224937 i */ +#define DELTA817 CHOOSE(1, 1, 0, 1, 1, 0) /* erfc (0.7) == 0.32219880616258152702 */ +#define DELTA818 CHOOSE(3, 1, 2, 3, 1, 2) /* erfc (1.2) == 0.089686021770364619762 */ +#define DELTA819 CHOOSE(0, 1, 1, 0, 1, 0) /* erfc (2.0) == 0.0046777349810472658379 */ +#define DELTA820 CHOOSE(12, 24, 12, 12, 24, 12) /* erfc (4.1) == 0.67000276540848983727e-8 */ +#define DELTA821 CHOOSE(36, 0, 0, 36, 0, 0) /* erfc (9) == 0.41370317465138102381e-36 */ +#define DELTA830 CHOOSE(412, 0, 0, 412, 0, 0) /* exp (0.7) == 2.0137527074704765216 */ +#define DELTA831 CHOOSE(16, 0, 0, 16, 0, 0) /* exp (50.0) == 5184705528587072464087.45332293348538 */ +#define DELTA832 CHOOSE(754, 0, 0, 754, 0, 0) /* exp (1000.0) == 0.197007111401704699388887935224332313e435 */ +#define DELTA838 CHOOSE(8, 0, 0, 8, 0, 0) /* exp10 (3) == 1000 */ +#define DELTA839 CHOOSE(818, 0, 0, 818, 0, 0) /* exp10 (-1) == 0.1 */ +#define DELTA842 CHOOSE(1182, 1, 0, 1182, 1, 0) /* exp10 (0.7) == 5.0118723362727228500155418688494574 */ +#define DELTA852 CHOOSE(462, 0, 0, 462, 0, 0) /* exp2 (0.7) == 1.6245047927124710452 */ +#define DELTA859 CHOOSE(825, 0, 0, 825, 0, 0) /* expm1 (0.7) == 1.0137527074704765216 */ +#define DELTA972 CHOOSE(4096, 2, 1, 4096, 2, 1) /* fmod (6.5, 2.3) == 1.9 */ +#define DELTA973 CHOOSE(4096, 2, 1, 4096, 2, 1) /* fmod (-6.5, 2.3) == -1.9 */ +#define DELTA974 CHOOSE(4096, 2, 1, 4096, 2, 1) /* fmod (6.5, -2.3) == 1.9 */ +#define DELTA975 CHOOSE(4096, 2, 1, 4096, 2, 1) /* fmod (-6.5, -2.3) == -1.9 */ +#define DELTA1004 CHOOSE(1, 1, 0, 1, 1, 0) /* gamma (-0.5) == log(2*sqrt(pi)) */ +#define DELTA1013 CHOOSE(406, 0, 1, 406, 0, 0) /* hypot (0.7, 12.4) == 12.419742348374220601176836866763271 */ +#define DELTA1014 CHOOSE(406, 0, 1, 406, 0, 0) /* hypot (-0.7, 12.4) == 12.419742348374220601176836866763271 */ +#define DELTA1015 CHOOSE(406, 0, 1, 406, 0, 0) /* hypot (0.7, -12.4) == 12.419742348374220601176836866763271 */ +#define DELTA1016 CHOOSE(406, 0, 1, 406, 0, 0) /* hypot (-0.7, -12.4) == 12.419742348374220601176836866763271 */ +#define DELTA1017 CHOOSE(406, 0, 1, 406, 0, 0) /* hypot (12.4, 0.7) == 12.419742348374220601176836866763271 */ +#define DELTA1018 CHOOSE(406, 0, 1, 406, 0, 0) /* hypot (-12.4, 0.7) == 12.419742348374220601176836866763271 */ +#define DELTA1019 CHOOSE(406, 0, 1, 406, 0, 0) /* hypot (12.4, -0.7) == 12.419742348374220601176836866763271 */ +#define DELTA1020 CHOOSE(406, 0, 1, 406, 0, 0) /* hypot (-12.4, -0.7) == 12.419742348374220601176836866763271 */ +#define DELTA1024 CHOOSE(560, 1, 0, 560, 0, 0) /* hypot (0.7, 1.2) == 1.3892443989449804508432547041028554 */ +#define DELTA1053 CHOOSE(0, 2, 2, 0, 1, 1) /* j0 (2.0) == 0.22389077914123566805 */ +#define DELTA1054 CHOOSE(0, 0, 1, 0, 0, 1) /* j0 (8.0) == 0.17165080713755390609 */ +#define DELTA1055 CHOOSE(0, 2, 2, 0, 2, 1) /* j0 (10.0) == -0.24593576445134833520 */ +#define DELTA1064 CHOOSE(0, 1, 0, 0, 1, 0) /* j1 (2.0) == 0.57672480775687338720 */ +#define DELTA1065 CHOOSE(1, 1, 1, 1, 0, 1) /* j1 (8.0) == 0.23463634685391462438 */ +#define DELTA1066 CHOOSE(2, 2, 2, 2, 2, 1) /* j1 (10.0) == 0.043472746168861436670 */ +#define DELTA1075 CHOOSE(0, 2, 2, 0, 1, 1) /* jn (0, 2.0) == 0.22389077914123566805 */ +#define DELTA1076 CHOOSE(1, 0, 1, 1, 0, 1) /* jn (0, 8.0) == 0.17165080713755390609 */ +#define DELTA1077 CHOOSE(2, 2, 1, 2, 2, 1) /* jn (0, 10.0) == -0.24593576445134833520 */ +#define DELTA1086 CHOOSE(0, 1, 0, 0, 1, 0) /* jn (1, 2.0) == 0.57672480775687338720 */ +#define DELTA1087 CHOOSE(1, 1, 1, 1, 0, 1) /* jn (1, 8.0) == 0.23463634685391462438 */ +#define DELTA1088 CHOOSE(2, 2, 2, 2, 2, 1) /* jn (1, 10.0) == 0.043472746168861436670 */ +#define DELTA1091 CHOOSE(1, 0, 0, 1, 0, 0) /* jn (3, -1.0) == -0.019563353982668405919 */ +#define DELTA1093 CHOOSE(1, 1, 0, 1, 1, 0) /* jn (3, 0.1) == 0.000020820315754756261429 */ +#define DELTA1094 CHOOSE(0, 2, 1, 0, 2, 0) /* jn (3, 0.7) == 0.0069296548267508408077 */ +#define DELTA1095 CHOOSE(1, 0, 0, 1, 0, 0) /* jn (3, 1.0) == 0.019563353982668405919 */ +#define DELTA1096 CHOOSE(0, 1, 1, 0, 1, 1) /* jn (3, 2.0) == 0.12894324947440205110 */ +#define DELTA1097 CHOOSE(1, 3, 1, 1, 3, 1) /* jn (3, 10.0) == 0.058379379305186812343 */ +#define DELTA1100 CHOOSE(1, 1, 1, 1, 1, 1) /* jn (10, -1.0) == 0.26306151236874532070e-9 */ +#define DELTA1102 CHOOSE(1, 6, 4, 1, 5, 2) /* jn (10, 0.1) == 0.26905328954342155795e-19 */ +#define DELTA1103 CHOOSE(2, 4, 1, 2, 4, 1) /* jn (10, 0.7) == 0.75175911502153953928e-11 */ +#define DELTA1104 CHOOSE(1, 1, 1, 1, 1, 1) /* jn (10, 1.0) == 0.26306151236874532070e-9 */ +#define DELTA1105 CHOOSE(1, 2, 2, 1, 2, 1) /* jn (10, 2.0) == 0.25153862827167367096e-6 */ +#define DELTA1106 CHOOSE(2, 4, 3, 2, 4, 2) /* jn (10, 10.0) == 0.20748610663335885770 */ +#define DELTA1126 CHOOSE(1, 1, 0, 1, 1, 0) /* lgamma (-0.5) == log(2*sqrt(pi)) */ +#define DELTA1128 CHOOSE(0, 1, 1, 0, 1, 1) /* lgamma (0.7) == 0.26086724653166651439 */ +#define DELTA1130 CHOOSE(1, 1, 2, 1, 1, 2) /* lgamma (1.2) == -0.853740900033158497197e-1 */ +#define DELTA1163 CHOOSE(1, 0, 0.5, 1, 0, 0.5) /* log (e) == 1 */ +#define DELTA1164 CHOOSE(1, 0, 0, 1, 0, 0) /* log (1.0 / M_El) == -1 */ +#define DELTA1167 CHOOSE(2341, 1, 1, 2341, 1, 1) /* log (0.7) == -0.35667494393873237891263871124118447 */ +#define DELTA1178 CHOOSE(1, 0, 1, 1, 0, 1) /* log10 (e) == log10(e) */ +#define DELTA1179 CHOOSE(2033, 1, 0, 2033, 1, 0) /* log10 (0.7) == -0.15490195998574316929 */ +#define DELTA1186 CHOOSE(1, 0, 0, 1, 0, 0) /* log1p (M_El - 1.0) == 1 */ +#define DELTA1187 CHOOSE(585, 1, 1, 585, 1, 1) /* log1p (-0.3) == -0.35667494393873237891263871124118447 */ +#define DELTA1198 CHOOSE(1688, 1, 1, 1688, 1, 1) /* log2 (0.7) == -0.51457317282975824043 */ +#define DELTA1398 CHOOSE(725, 0, 0, 725, 0, 0) /* pow (0.7, 1.2) == 0.65180494056638638188 */ +#define DELTA1524 CHOOSE(627, 0, 0, 627, 0, 0) /* sin (0.7) == 0.64421768723769105367261435139872014 */ +#define DELTA1536 CHOOSE(0.25, 0.2758, 0.3667, 0.25, 0.2758, 0.3667) /* sincos (pi/2, &sin_res, &cos_res) puts 0 in cos_res */ +#define DELTA1539 CHOOSE(1, 1, 1, 1, 1, 1) /* sincos (M_PI_6l*2.0, &sin_res, &cos_res) puts 0.86602540378443864676372317075293616 in sin_res */ +#define DELTA1540 CHOOSE(0, 1, 0.5, 0, 1, 0.5) /* sincos (M_PI_6l*2.0, &sin_res, &cos_res) puts 0.5 in cos_res */ +#define DELTA1541 CHOOSE(627, 0, 0, 627, 0, 0) /* sincos (0.7, &sin_res, &cos_res) puts 0.64421768723769105367261435139872014 in sin_res */ +#define DELTA1542 CHOOSE(528, 1, 0, 528, 1, 0) /* sincos (0.7, &sin_res, &cos_res) puts 0.76484218728448842625585999019186495 in cos_res */ +#define DELTA1548 CHOOSE(1029, 1, 1, 1028, 0, 1) /* sinh (0.7) == 0.75858370183953350346 */ +#define DELTA1562 CHOOSE(325, 0, 0, 325, 0, 0) /* sqrt (15239.9025) == 123.45 */ +#define DELTA1569 CHOOSE(0, 0.5, 0, 0, 0.5, 0) /* tan (pi/4) == 1 */ +#define DELTA1570 CHOOSE(1401, 1, 1, 1401, 0, 0) /* tan (0.7) == 0.84228838046307944812813500221293775 */ +#define DELTA1576 CHOOSE(521, 1, 1, 521, 0, 0) /* tanh (0.7) == 0.60436777711716349631 */ +#define DELTA1577 CHOOSE(1, 1, 1, 1, 0, 0) /* tanh (-0.7) == -0.60436777711716349631 */ +#define DELTA1587 CHOOSE(0, 0, 1, 0, 0, 1) /* tgamma (0.5) == sqrt (pi) */ +#define DELTA1588 CHOOSE(2, 2, 1, 2, 2, 1) /* tgamma (-0.5) == -2 sqrt (pi) */ +#define DELTA1590 CHOOSE(2, 0, 0, 2, 0, 0) /* tgamma (4) == 6 */ +#define DELTA1591 CHOOSE(0, 1, 1, 0, 1, 1) /* tgamma (0.7) == 1.29805533264755778568 */ +#define DELTA1614 CHOOSE(0, 1, 1, 0, 1, 1) /* y0 (0.1) == -1.5342386513503668441 */ +#define DELTA1615 CHOOSE(2, 3, 1, 2, 3, 1) /* y0 (0.7) == -0.19066492933739506743 */ +#define DELTA1616 CHOOSE(0, 2, 1, 0, 2, 1) /* y0 (1.0) == 0.088256964215676957983 */ +#define DELTA1617 CHOOSE(0, 1, 1, 0, 1, 1) /* y0 (1.5) == 0.38244892379775884396 */ +#define DELTA1618 CHOOSE(0, 1, 0, 0, 1, 0) /* y0 (2.0) == 0.51037567264974511960 */ +#define DELTA1619 CHOOSE(1, 1, 1, 1, 1, 1) /* y0 (8.0) == 0.22352148938756622053 */ +#define DELTA1620 CHOOSE(1, 2, 1, 2, 2, 1) /* y0 (10.0) == 0.055671167283599391424 */ +#define DELTA1625 CHOOSE(1, 1, 1, 1, 1, 1) /* y1 (0.1) == -6.4589510947020269877 */ +#define DELTA1626 CHOOSE(0, 1, 1, 0, 1, 0) /* y1 (0.7) == -1.1032498719076333697 */ +#define DELTA1627 CHOOSE(0, 1, 0, 0, 1, 0) /* y1 (1.0) == -0.78121282130028871655 */ +#define DELTA1628 CHOOSE(0, 0, 1, 0, 0, 1) /* y1 (1.5) == -0.41230862697391129595 */ +#define DELTA1629 CHOOSE(1, 1, 2, 1, 1, 2) /* y1 (2.0) == -0.10703243154093754689 */ +#define DELTA1630 CHOOSE(2, 1, 2, 2, 0, 2) /* y1 (8.0) == -0.15806046173124749426 */ +#define DELTA1631 CHOOSE(0, 3, 2, 0, 3, 2) /* y1 (10.0) == 0.24901542420695388392 */ +#define DELTA1636 CHOOSE(0, 1, 1, 0, 1, 1) /* yn (0, 0.1) == -1.5342386513503668441 */ +#define DELTA1637 CHOOSE(2, 3, 1, 2, 3, 1) /* yn (0, 0.7) == -0.19066492933739506743 */ +#define DELTA1638 CHOOSE(0, 2, 1, 0, 2, 1) /* yn (0, 1.0) == 0.088256964215676957983 */ +#define DELTA1639 CHOOSE(0, 1, 1, 0, 1, 1) /* yn (0, 1.5) == 0.38244892379775884396 */ +#define DELTA1640 CHOOSE(0, 1, 0, 0, 1, 0) /* yn (0, 2.0) == 0.51037567264974511960 */ +#define DELTA1641 CHOOSE(1, 1, 1, 1, 1, 1) /* yn (0, 8.0) == 0.22352148938756622053 */ +#define DELTA1642 CHOOSE(1, 2, 1, 1, 2, 1) /* yn (0, 10.0) == 0.055671167283599391424 */ +#define DELTA1647 CHOOSE(1, 1, 1, 1, 1, 1) /* yn (1, 0.1) == -6.4589510947020269877 */ +#define DELTA1648 CHOOSE(0, 1, 1, 0, 1, 0) /* yn (1, 0.7) == -1.1032498719076333697 */ +#define DELTA1649 CHOOSE(0, 1, 0, 0, 1, 0) /* yn (1, 1.0) == -0.78121282130028871655 */ +#define DELTA1650 CHOOSE(0, 0, 1, 0, 0, 1) /* yn (1, 1.5) == -0.41230862697391129595 */ +#define DELTA1651 CHOOSE(1, 1, 2, 1, 1, 2) /* yn (1, 2.0) == -0.10703243154093754689 */ +#define DELTA1652 CHOOSE(2, 1, 2, 2, 0, 2) /* yn (1, 8.0) == -0.15806046173124749426 */ +#define DELTA1653 CHOOSE(0, 3, 2, 0, 3, 2) /* yn (1, 10.0) == 0.24901542420695388392 */ +#define DELTA1656 CHOOSE(2, 1, 2, 2, 1, 1) /* yn (3, 0.1) == -5099.3323786129048894 */ +#define DELTA1657 CHOOSE(2, 3, 1, 2, 3, 1) /* yn (3, 0.7) == -15.819479052819633505 */ +#define DELTA1659 CHOOSE(0, 1, 1, 0, 1, 1) /* yn (3, 2.0) == -1.1277837768404277861 */ +#define DELTA1660 CHOOSE(0, 1, 1, 0, 1, 1) /* yn (3, 10.0) == -0.25136265718383732978 */ +#define DELTA1663 CHOOSE(2, 2, 2, 2, 2, 1) /* yn (10, 0.1) == -0.11831335132045197885e19 */ +#define DELTA1664 CHOOSE(7, 6, 3, 7, 6, 3) /* yn (10, 0.7) == -0.42447194260703866924e10 */ +#define DELTA1665 CHOOSE(0, 1, 2, 0, 1, 1) /* yn (10, 1.0) == -0.12161801427868918929e9 */ +#define DELTA1666 CHOOSE(1, 3, 3, 1, 2, 1) /* yn (10, 2.0) == -129184.54220803928264 */ +#define DELTA1667 CHOOSE(0, 2, 1, 0, 2, 1) /* yn (10, 10.0) == -0.35981415218340272205 */ diff --git a/src/openlibm/test/libm-test.c b/src/openlibm/test/libm-test.c new file mode 100644 index 0000000..0cef025 --- /dev/null +++ b/src/openlibm/test/libm-test.c @@ -0,0 +1,4537 @@ +/* Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Jaeger , 1997. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +/* Part of testsuite for libm. + + This file is processed by a perl script. The resulting file has to + be included by a master file that defines: + + Makros: + FUNC(function): converts general function name (like cos) to + name with correct suffix (e.g. cosl or cosf) + MATHCONST(x): like FUNC but for constants (e.g convert 0.0 to 0.0L) + FLOAT: floating point type to test + - TEST_MSG: informal message to be displayed + CHOOSE(Clongdouble,Cdouble,Cfloat,Cinlinelongdouble,Cinlinedouble,Cinlinefloat): + chooses one of the parameters as delta for testing + equality + PRINTF_EXPR Floating point conversion specification to print a variable + of type FLOAT with printf. PRINTF_EXPR just contains + the specifier, not the percent and width arguments, + e.g. "f". + PRINTF_XEXPR Like PRINTF_EXPR, but print in hexadecimal format. + PRINTF_NEXPR Like PRINTF_EXPR, but print nice. */ + +/* This testsuite has currently tests for: + acos, acosh, asin, asinh, atan, atan2, atanh, + cbrt, ceil, copysign, cos, cosh, erf, erfc, exp, exp10, exp2, expm1, + fabs, fdim, floor, fma, fmax, fmin, fmod, fpclassify, + frexp, gamma, hypot, + ilogb, isfinite, isinf, isnan, isnormal, + isless, islessequal, isgreater, isgreaterequal, islessgreater, isunordered, + j0, j1, jn, + ldexp, lgamma, log, log10, log1p, log2, logb, + modf, nearbyint, nextafter, + pow, remainder, remquo, rint, lrint, llrint, + round, lround, llround, + scalb, scalbn, scalbln, signbit, sin, sincos, sinh, sqrt, tan, tanh, tgamma, trunc, + y0, y1, yn + + and for the following complex math functions: + cabs, cacos, cacosh, carg, casin, casinh, catan, catanh, + ccos, ccosh, cexp, clog, cpow, cproj, csin, csinh, csqrt, ctan, ctanh. + + At the moment the following functions aren't tested: + drem, significand, nan + + Parameter handling is primitive in the moment: + --verbose=[0..3] for different levels of output: + 0: only error count + 1: basic report on failed tests (default) + 2: full report on all tests + -v for full output (equals --verbose=3) + -u for generation of an ULPs file + */ + +/* "Philosophy": + + This suite tests some aspects of the correct implementation of + mathematical functions in libm. Some simple, specific parameters + are tested for correctness but there's no exhaustive + testing. Handling of specific inputs (e.g. infinity, not-a-number) + is also tested. Correct handling of exceptions is checked + against. These implemented tests should check all cases that are + specified in ISO C99. + + Exception testing: At the moment only divide-by-zero and invalid + exceptions are tested. Overflow/underflow and inexact exceptions + aren't checked at the moment. + + NaN values: There exist signalling and quiet NaNs. This implementation + only uses signalling NaN as parameter but does not differenciate + between the two kinds of NaNs as result. + + Inline functions: Inlining functions should give an improvement in + speed - but not in precission. The inlined functions return + reasonable values for a reasonable range of input values. The + result is not necessarily correct for all values and exceptions are + not correctly raised in all cases. Problematic input and return + values are infinity, not-a-number and minus zero. This suite + therefore does not check these specific inputs and the exception + handling for inlined mathematical functions - just the "reasonable" + values are checked. + + Beware: The tests might fail for any of the following reasons: + - Tests are wrong + - Functions are wrong + - Floating Point Unit not working properly + - Compiler has errors + + With e.g. gcc 2.7.2.2 the test for cexp fails because of a compiler error. + + + To Do: All parameter should be numbers that can be represented as + exact floating point values. Currently some values cannot be represented + exactly and therefore the result is not the expected result. +*/ + +#ifndef _GNU_SOURCE +# define _GNU_SOURCE +#endif + +#include "libm-test-ulps.h" +#include +#ifdef SYS_MATH_H +#include +#include +#else +#include +#endif + +#if 0 /* XXX scp XXX */ +#define FE_INEXACT FE_INEXACT +#define FE_DIVBYZERO FE_DIVBYZERO +#define FE_UNDERFLOW FE_UNDERFLOW +#define FE_OVERFLOW FE_OVERFLOW +#define FE_INVALID FE_INVALID +#endif + +#include + +#include +#include +#include +#include +#if 0 /* XXX scp XXX */ +#include +#endif + +// Some native libm implementations don't have sincos defined, so we have to do it ourselves +void FUNC(sincos) (FLOAT x, FLOAT * s, FLOAT * c); + +#ifdef __APPLE__ +#ifdef SYS_MATH_H +void sincos(FLOAT x, FLOAT * s, FLOAT * c) +{ + *s = sin(x); + *c = cos(x); +} +#endif +#endif + +/* Possible exceptions */ +#define NO_EXCEPTION 0x0 +#define INVALID_EXCEPTION 0x1 +#define DIVIDE_BY_ZERO_EXCEPTION 0x2 +/* The next flags signals that those exceptions are allowed but not required. */ +#define INVALID_EXCEPTION_OK 0x4 +#define DIVIDE_BY_ZERO_EXCEPTION_OK 0x8 +#define EXCEPTIONS_OK INVALID_EXCEPTION_OK+DIVIDE_BY_ZERO_EXCEPTION_OK +/* Some special test flags, passed togther with exceptions. */ +#define IGNORE_ZERO_INF_SIGN 0x10 + +/* Various constants (we must supply them precalculated for accuracy). */ +#define M_PI_6l .52359877559829887307710723054658383L +#define M_E2l 7.389056098930650227230427460575008L +#define M_E3l 20.085536923187667740928529654581719L +#define M_2_SQRT_PIl 3.5449077018110320545963349666822903L /* 2 sqrt (M_PIl) */ +#define M_SQRT_PIl 1.7724538509055160272981674833411451L /* sqrt (M_PIl) */ +#define M_LOG_SQRT_PIl 0.57236494292470008707171367567652933L /* log(sqrt(M_PIl)) */ +#define M_LOG_2_SQRT_PIl 1.265512123484645396488945797134706L /* log(2*sqrt(M_PIl)) */ +#define M_PI_34l (M_PIl - M_PI_4l) /* 3*pi/4 */ +#define M_PI_34_LOG10El (M_PIl - M_PI_4l) * M_LOG10El +#define M_PI2_LOG10El M_PI_2l * M_LOG10El +#define M_PI4_LOG10El M_PI_4l * M_LOG10El +#define M_PI_LOG10El M_PIl * M_LOG10El + +#if 1 /* XXX scp XXX */ +# define M_El 2.7182818284590452353602874713526625L /* e */ +# define M_LOG2El 1.4426950408889634073599246810018922L /* log_2 e */ +# define M_LOG10El 0.4342944819032518276511289189166051L /* log_10 e */ +# define M_LN2l 0.6931471805599453094172321214581766L /* log_e 2 */ +# define M_LN10l 2.3025850929940456840179914546843642L /* log_e 10 */ +# define M_PIl 3.1415926535897932384626433832795029L /* pi */ +# define M_PI_2l 1.5707963267948966192313216916397514L /* pi/2 */ +# define M_PI_4l 0.7853981633974483096156608458198757L /* pi/4 */ +# define M_1_PIl 0.3183098861837906715377675267450287L /* 1/pi */ +# define M_2_PIl 0.6366197723675813430755350534900574L /* 2/pi */ +# define M_2_SQRTPIl 1.1283791670955125738961589031215452L /* 2/sqrt(pi) */ +# define M_SQRT2l 1.4142135623730950488016887242096981L /* sqrt(2) */ +# define M_SQRT1_2l 0.7071067811865475244008443621048490L /* 1/sqrt(2) */ +#endif + +static FILE *ulps_file; /* File to document difference. */ +static int output_ulps; /* Should ulps printed? */ + +static int noErrors; /* number of errors */ +static int noTests; /* number of tests (without testing exceptions) */ +static int noExcTests; /* number of tests for exception flags */ +static int noXFails; /* number of expected failures. */ +static int noXPasses; /* number of unexpected passes. */ + +static int verbose; +static int output_max_error; /* Should the maximal errors printed? */ +static int output_points; /* Should the single function results printed? */ +static int ignore_max_ulp; /* Should we ignore max_ulp? */ + +static FLOAT minus_zero, plus_zero; +static FLOAT plus_infty, minus_infty, nan_value; + +static FLOAT max_error, real_max_error, imag_max_error; + + +#if 0 /* XXX scp XXX */ +#define BUILD_COMPLEX(real, imag) \ + ({ __complex__ FLOAT __retval; \ + __real__ __retval = (real); \ + __imag__ __retval = (imag); \ + __retval; }) + +#define BUILD_COMPLEX_INT(real, imag) \ + ({ __complex__ int __retval; \ + __real__ __retval = (real); \ + __imag__ __retval = (imag); \ + __retval; }) +#endif + + +#define MANT_DIG CHOOSE ((LDBL_MANT_DIG-1), (DBL_MANT_DIG-1), (FLT_MANT_DIG-1), \ + (LDBL_MANT_DIG-1), (DBL_MANT_DIG-1), (FLT_MANT_DIG-1)) + + +static void +init_max_error (void) +{ + max_error = 0; + real_max_error = 0; + imag_max_error = 0; + feclearexcept (FE_ALL_EXCEPT); +} + +static void +set_max_error (FLOAT current, FLOAT *curr_max_error) +{ + if (current > *curr_max_error) + *curr_max_error = current; +} + + +/* Should the message print to screen? This depends on the verbose flag, + and the test status. */ +static int +print_screen (int ok, int xfail) +{ + if (output_points + && (verbose > 1 + || (verbose == 1 && ok == xfail))) + return 1; + return 0; +} + + +/* Should the message print to screen? This depends on the verbose flag, + and the test status. */ +static int +print_screen_max_error (int ok, int xfail) +{ + if (output_max_error + && (verbose > 1 + || ((verbose == 1) && (ok == xfail)))) + return 1; + return 0; +} + +/* Update statistic counters. */ +static void +update_stats (int ok, int xfail) +{ + ++noTests; + if (ok && xfail) + ++noXPasses; + else if (!ok && xfail) + ++noXFails; + else if (!ok && !xfail) + ++noErrors; +} + +static void +print_ulps (const char *test_name, FLOAT ulp) +{ + if (output_ulps) + { + fprintf (ulps_file, "Test \"%s\":\n", test_name); + fprintf (ulps_file, "%s: % .4" PRINTF_NEXPR "\n", + CHOOSE("ldouble", "double", "float", + "ildouble", "idouble", "ifloat"), ulp); + } +} + +static void +print_function_ulps (const char *function_name, FLOAT ulp) +{ + if (output_ulps) + { + fprintf (ulps_file, "Function: \"%s\":\n", function_name); + fprintf (ulps_file, "%s: % .4" PRINTF_NEXPR "\n", + CHOOSE("ldouble", "double", "float", + "ildouble", "idouble", "ifloat"), ulp); + } +} + + +#if 0 /* XXX scp XXX */ +static void +print_complex_function_ulps (const char *function_name, FLOAT real_ulp, + FLOAT imag_ulp) +{ + if (output_ulps) + { + if (real_ulp != 0.0) + { + fprintf (ulps_file, "Function: Real part of \"%s\":\n", function_name); + fprintf (ulps_file, "%s: % .4" PRINTF_NEXPR "\n", + CHOOSE("ldouble", "double", "float", + "ildouble", "idouble", "ifloat"), real_ulp); + } + if (imag_ulp != 0.0) + { + fprintf (ulps_file, "Function: Imaginary part of \"%s\":\n", function_name); + fprintf (ulps_file, "%s: % .4" PRINTF_NEXPR "\n", + CHOOSE("ldouble", "double", "float", + "ildouble", "idouble", "ifloat"), imag_ulp); + } + + + } +} +#endif + + +static void +print_max_error (const char *func_name, FLOAT allowed, int xfail) +{ + int ok = 0; + + if (max_error == 0.0 || (max_error <= allowed && !ignore_max_ulp)) + { + ok = 1; + } + + if (!ok) + print_function_ulps (func_name, max_error); + + + if (print_screen_max_error (ok, xfail)) + { + printf ("Maximal error of `%s'\n", func_name); + printf (" is : % .4" PRINTF_NEXPR " ulp\n", max_error); + printf (" accepted: % .4" PRINTF_NEXPR " ulp\n", allowed); + } + + update_stats (ok, xfail); +} + + +#if 0 /* XXX scp XXX */ +static void +print_complex_max_error (const char *func_name, __complex__ FLOAT allowed, + __complex__ int xfail) +{ + int ok = 0; + + if ((real_max_error <= __real__ allowed) + && (imag_max_error <= __imag__ allowed)) + { + ok = 1; + } + + if (!ok) + print_complex_function_ulps (func_name, real_max_error, imag_max_error); + + + if (print_screen_max_error (ok, xfail)) + { + printf ("Maximal error of real part of: %s\n", func_name); + printf (" is : % .4" PRINTF_NEXPR " ulp\n", real_max_error); + printf (" accepted: % .4" PRINTF_NEXPR " ulp\n", __real__ allowed); + printf ("Maximal error of imaginary part of: %s\n", func_name); + printf (" is : % .4" PRINTF_NEXPR " ulp\n", imag_max_error); + printf (" accepted: % .4" PRINTF_NEXPR " ulp\n", __imag__ allowed); + } + + update_stats (ok, xfail); +} +#endif + + +/* Test whether a given exception was raised. */ +static void +test_single_exception (const char *test_name, + int exception, + int exc_flag, + int fe_flag, + const char *flag_name) +{ +/* Don't perform these checks if we're compiling with clang, because clang + doesn't bother to set floating-point exceptions properly */ +#ifndef __clang__ +#ifndef TEST_INLINE + int ok = 1; + if (exception & exc_flag) + { + if (fetestexcept (fe_flag)) + { + if (print_screen (1, 0)) + printf ("Pass: %s: Exception \"%s\" set\n", test_name, flag_name); + } + else + { + ok = 0; + if (print_screen (0, 0)) + printf ("Failure: %s: Exception \"%s\" not set\n", + test_name, flag_name); + } + } + else + { + if (fetestexcept (fe_flag)) + { + ok = 0; + if (print_screen (0, 0)) + printf ("Failure: %s: Exception \"%s\" set\n", + test_name, flag_name); + } + else + { + if (print_screen (1, 0)) + printf ("%s: Exception \"%s\" not set\n", test_name, + flag_name); + } + } + if (!ok) + ++noErrors; + +#endif +#endif // __clang__ +} + + +/* Test whether exceptions given by EXCEPTION are raised. Ignore thereby + allowed but not required exceptions. +*/ +static void +test_exceptions (const char *test_name, int exception) +{ + ++noExcTests; +#ifdef FE_DIVBYZERO + if ((exception & DIVIDE_BY_ZERO_EXCEPTION_OK) == 0) + test_single_exception (test_name, exception, + DIVIDE_BY_ZERO_EXCEPTION, FE_DIVBYZERO, + "Divide by zero"); +#endif +#ifdef FE_INVALID + if ((exception & INVALID_EXCEPTION_OK) == 0) + test_single_exception (test_name, exception, INVALID_EXCEPTION, FE_INVALID, + "Invalid operation"); +#endif + feclearexcept (FE_ALL_EXCEPT); +} + + +static void +check_float_internal (const char *test_name, FLOAT computed, FLOAT expected, + FLOAT max_ulp, int xfail, int exceptions, + FLOAT *curr_max_error) +{ + int ok = 0; + int print_diff = 0; + FLOAT diff = 0; + FLOAT ulp = 0; + + test_exceptions (test_name, exceptions); + if (isnan (computed) && isnan (expected)) + ok = 1; + else if (isinf (computed) && isinf (expected)) + { + /* Test for sign of infinities. */ + if ((exceptions & IGNORE_ZERO_INF_SIGN) == 0 + && signbit (computed) != signbit (expected)) + { + ok = 0; + printf ("infinity has wrong sign.\n"); + } + else + ok = 1; + } + /* Don't calc ulp for NaNs or infinities. */ + else if (isinf (computed) || isnan (computed) || isinf (expected) || isnan (expected)) + ok = 0; + else + { + diff = FUNC(fabs) (computed - expected); + /* ilogb (0) isn't allowed. */ + if (expected == 0.0) + ulp = diff / FUNC(ldexp) (1.0, - MANT_DIG); + else + ulp = diff / FUNC(ldexp) (1.0, FUNC(ilogb) (expected) - MANT_DIG); + set_max_error (ulp, curr_max_error); + print_diff = 1; + if ((exceptions & IGNORE_ZERO_INF_SIGN) == 0 + && computed == 0.0 && expected == 0.0 + && signbit(computed) != signbit (expected)) + ok = 0; + else if (ulp == 0.0 || (ulp <= max_ulp && !ignore_max_ulp)) + ok = 1; + else + { + ok = 0; + print_ulps (test_name, ulp); + } + + } + if (print_screen (ok, xfail)) + { + if (!ok) + printf ("Failure: "); + printf ("Test: %s\n", test_name); + printf ("Result:\n"); + printf (" is: % .20" PRINTF_EXPR " % .20" PRINTF_XEXPR "\n", + computed, computed); + printf (" should be: % .20" PRINTF_EXPR " % .20" PRINTF_XEXPR "\n", + expected, expected); + if (print_diff) + { + printf (" difference: % .20" PRINTF_EXPR " % .20" PRINTF_XEXPR + "\n", diff, diff); + printf (" ulp : % .4" PRINTF_NEXPR "\n", ulp); + printf (" max.ulp : % .4" PRINTF_NEXPR "\n", max_ulp); + } + } + update_stats (ok, xfail); +} + + +static void +check_float (const char *test_name, FLOAT computed, FLOAT expected, + FLOAT max_ulp, int xfail, int exceptions) +{ + check_float_internal (test_name, computed, expected, max_ulp, xfail, + exceptions, &max_error); +} + +#if 0 /* XXX scp XXX */ +static void +check_complex (const char *test_name, __complex__ FLOAT computed, + __complex__ FLOAT expected, + __complex__ FLOAT max_ulp, __complex__ int xfail, + int exception) +{ + FLOAT part_comp, part_exp, part_max_ulp; + int part_xfail; + char str[200]; + + sprintf (str, "Real part of: %s", test_name); + part_comp = __real__ computed; + part_exp = __real__ expected; + part_max_ulp = __real__ max_ulp; + part_xfail = __real__ xfail; + + check_float_internal (str, part_comp, part_exp, part_max_ulp, part_xfail, + exception, &real_max_error); + + sprintf (str, "Imaginary part of: %s", test_name); + part_comp = __imag__ computed; + part_exp = __imag__ expected; + part_max_ulp = __imag__ max_ulp; + part_xfail = __imag__ xfail; + + /* Don't check again for exceptions, just pass through the + zero/inf sign test. */ + check_float_internal (str, part_comp, part_exp, part_max_ulp, part_xfail, + exception & IGNORE_ZERO_INF_SIGN, + &imag_max_error); +} +#endif + +/* Check that computed and expected values are equal (int values). */ +static void +check_int (const char *test_name, int computed, int expected, int max_ulp, + int xfail, int exceptions) +{ + int diff = computed - expected; + int ok = 0; + + test_exceptions (test_name, exceptions); + noTests++; + if (abs (diff) <= max_ulp) + ok = 1; + + if (!ok) + print_ulps (test_name, diff); + + if (print_screen (ok, xfail)) + { + if (!ok) + printf ("Failure: "); + printf ("Test: %s\n", test_name); + printf ("Result:\n"); + printf (" is: %d\n", computed); + printf (" should be: %d\n", expected); + } + + update_stats (ok, xfail); +} + + +/* Check that computed and expected values are equal (long int values). */ +static void +check_long (const char *test_name, long int computed, long int expected, + long int max_ulp, int xfail, int exceptions) +{ + long int diff = computed - expected; + int ok = 0; + + test_exceptions (test_name, exceptions); + noTests++; + if (labs (diff) <= max_ulp) + ok = 1; + + if (!ok) + print_ulps (test_name, diff); + + if (print_screen (ok, xfail)) + { + if (!ok) + printf ("Failure: "); + printf ("Test: %s\n", test_name); + printf ("Result:\n"); + printf (" is: %ld\n", computed); + printf (" should be: %ld\n", expected); + } + + update_stats (ok, xfail); +} + + +/* Check that computed value is true/false. */ +static void +check_bool (const char *test_name, int computed, int expected, + long int max_ulp, int xfail, int exceptions) +{ + int ok = 0; + + test_exceptions (test_name, exceptions); + noTests++; + if ((computed == 0) == (expected == 0)) + ok = 1; + + if (print_screen (ok, xfail)) + { + if (!ok) + printf ("Failure: "); + printf ("Test: %s\n", test_name); + printf ("Result:\n"); + printf (" is: %d\n", computed); + printf (" should be: %d\n", expected); + } + + update_stats (ok, xfail); +} + + +/* check that computed and expected values are equal (long int values) */ +static void +check_longlong (const char *test_name, long long int computed, + long long int expected, + long long int max_ulp, int xfail, + int exceptions) +{ + long long int diff = computed - expected; + int ok = 0; + + test_exceptions (test_name, exceptions); + noTests++; + if (llabs (diff) <= max_ulp) + ok = 1; + + if (!ok) + print_ulps (test_name, diff); + + if (print_screen (ok, xfail)) + { + if (!ok) + printf ("Failure:"); + printf ("Test: %s\n", test_name); + printf ("Result:\n"); + printf (" is: %lld\n", computed); + printf (" should be: %lld\n", expected); + } + + update_stats (ok, xfail); +} + + +#if 0 /* XXX scp XXX */ +/* This is to prevent messages from the SVID libm emulation. */ +int +matherr (struct exception *x __attribute__ ((unused))) +{ + return 1; +} +#endif + +/**************************************************************************** + Tests for single functions of libm. + Please keep them alphabetically sorted! +****************************************************************************/ + +static void +acos_test (void) +{ + errno = 0; + FUNC(acos) (0); + if (errno == ENOSYS) + /* Function not implemented. */ + return; + + init_max_error (); + + check_float ("acos (inf) == NaN plus invalid exception", FUNC(acos) (plus_infty), nan_value, 0, 0, INVALID_EXCEPTION); + check_float ("acos (-inf) == NaN plus invalid exception", FUNC(acos) (minus_infty), nan_value, 0, 0, INVALID_EXCEPTION); + check_float ("acos (NaN) == NaN", FUNC(acos) (nan_value), nan_value, 0, 0, 0); + + /* |x| > 1: */ + check_float ("acos (1.1) == NaN plus invalid exception", FUNC(acos) (1.1L), nan_value, 0, 0, INVALID_EXCEPTION); + check_float ("acos (-1.1) == NaN plus invalid exception", FUNC(acos) (-1.1L), nan_value, 0, 0, INVALID_EXCEPTION); + + check_float ("acos (0) == pi/2", FUNC(acos) (0), M_PI_2l, 0, 0, 0); + check_float ("acos (-0) == pi/2", FUNC(acos) (minus_zero), M_PI_2l, 0, 0, 0); + check_float ("acos (1) == 0", FUNC(acos) (1), 0, 0, 0, 0); + check_float ("acos (-1) == pi", FUNC(acos) (-1), M_PIl, 0, 0, 0); + check_float ("acos (0.5) == M_PI_6l*2.0", FUNC(acos) (0.5), M_PI_6l*2.0, 1, 0, 0); + check_float ("acos (-0.5) == M_PI_6l*4.0", FUNC(acos) (-0.5), M_PI_6l*4.0, 0, 0, 0); + check_float ("acos (0.7) == 0.79539883018414355549096833892476432", FUNC(acos) (0.7L), 0.79539883018414355549096833892476432L, 0, 0, 0); + + print_max_error ("acos", DELTAacos, 0); +} + +static void +acosh_test (void) +{ + errno = 0; + FUNC(acosh) (7); + if (errno == ENOSYS) + /* Function not implemented. */ + return; + + init_max_error (); + + check_float ("acosh (inf) == inf", FUNC(acosh) (plus_infty), plus_infty, 0, 0, 0); + check_float ("acosh (-inf) == NaN plus invalid exception", FUNC(acosh) (minus_infty), nan_value, 0, 0, INVALID_EXCEPTION); + + /* x < 1: */ + check_float ("acosh (-1.1) == NaN plus invalid exception", FUNC(acosh) (-1.1L), nan_value, 0, 0, INVALID_EXCEPTION); + + check_float ("acosh (1) == 0", FUNC(acosh) (1), 0, 0, 0, 0); + check_float ("acosh (7) == 2.633915793849633417250092694615937", FUNC(acosh) (7), 2.633915793849633417250092694615937L, DELTA16, 0, 0); + + print_max_error ("acosh", DELTAacosh, 0); +} + +static void +asin_test (void) +{ + errno = 0; + FUNC(asin) (0); + if (errno == ENOSYS) + /* Function not implemented. */ + return; + + init_max_error (); + + check_float ("asin (inf) == NaN plus invalid exception", FUNC(asin) (plus_infty), nan_value, 0, 0, INVALID_EXCEPTION); + check_float ("asin (-inf) == NaN plus invalid exception", FUNC(asin) (minus_infty), nan_value, 0, 0, INVALID_EXCEPTION); + check_float ("asin (NaN) == NaN", FUNC(asin) (nan_value), nan_value, 0, 0, 0); + + /* asin x == NaN plus invalid exception for |x| > 1. */ + check_float ("asin (1.1) == NaN plus invalid exception", FUNC(asin) (1.1L), nan_value, 0, 0, INVALID_EXCEPTION); + check_float ("asin (-1.1) == NaN plus invalid exception", FUNC(asin) (-1.1L), nan_value, 0, 0, INVALID_EXCEPTION); + + check_float ("asin (0) == 0", FUNC(asin) (0), 0, 0, 0, 0); + check_float ("asin (-0) == -0", FUNC(asin) (minus_zero), minus_zero, 0, 0, 0); + check_float ("asin (0.5) == pi/6", FUNC(asin) (0.5), M_PI_6l, DELTA24, 0, 0); + check_float ("asin (-0.5) == -pi/6", FUNC(asin) (-0.5), -M_PI_6l, DELTA25, 0, 0); + check_float ("asin (1.0) == pi/2", FUNC(asin) (1.0), M_PI_2l, DELTA26, 0, 0); + check_float ("asin (-1.0) == -pi/2", FUNC(asin) (-1.0), -M_PI_2l, DELTA27, 0, 0); + check_float ("asin (0.7) == 0.77539749661075306374035335271498708", FUNC(asin) (0.7L), 0.77539749661075306374035335271498708L, DELTA28, 0, 0); + + print_max_error ("asin", DELTAasin, 0); +} + +static void +asinh_test (void) +{ + errno = 0; + FUNC(asinh) (0.7L); + if (errno == ENOSYS) + /* Function not implemented. */ + return; + + init_max_error (); + + check_float ("asinh (0) == 0", FUNC(asinh) (0), 0, 0, 0, 0); + check_float ("asinh (-0) == -0", FUNC(asinh) (minus_zero), minus_zero, 0, 0, 0); +#ifndef TEST_INLINE + check_float ("asinh (inf) == inf", FUNC(asinh) (plus_infty), plus_infty, 0, 0, 0); + check_float ("asinh (-inf) == -inf", FUNC(asinh) (minus_infty), minus_infty, 0, 0, 0); +#endif + check_float ("asinh (NaN) == NaN", FUNC(asinh) (nan_value), nan_value, 0, 0, 0); + check_float ("asinh (0.7) == 0.652666566082355786", FUNC(asinh) (0.7L), 0.652666566082355786L, DELTA34, 0, 0); + + print_max_error ("asinh", DELTAasinh, 0); +} + +static void +atan_test (void) +{ + errno = 0; + FUNC(atan) (0); + if (errno == ENOSYS) + /* Function not implemented. */ + return; + + init_max_error (); + + check_float ("atan (0) == 0", FUNC(atan) (0), 0, 0, 0, 0); + check_float ("atan (-0) == -0", FUNC(atan) (minus_zero), minus_zero, 0, 0, 0); + + check_float ("atan (inf) == pi/2", FUNC(atan) (plus_infty), M_PI_2l, 0, 0, 0); + check_float ("atan (-inf) == -pi/2", FUNC(atan) (minus_infty), -M_PI_2l, 0, 0, 0); + check_float ("atan (NaN) == NaN", FUNC(atan) (nan_value), nan_value, 0, 0, 0); + + check_float ("atan (1) == pi/4", FUNC(atan) (1), M_PI_4l, 0, 0, 0); + check_float ("atan (-1) == -pi/4", FUNC(atan) (-1), -M_PI_4l, 0, 0, 0); + + check_float ("atan (0.7) == 0.61072596438920861654375887649023613", FUNC(atan) (0.7L), 0.61072596438920861654375887649023613L, DELTA42, 0, 0); + + print_max_error ("atan", DELTAatan, 0); +} + + + +static void +atanh_test (void) +{ + errno = 0; + FUNC(atanh) (0.7L); + if (errno == ENOSYS) + /* Function not implemented. */ + return; + + init_max_error (); + + + check_float ("atanh (0) == 0", FUNC(atanh) (0), 0, 0, 0, 0); + check_float ("atanh (-0) == -0", FUNC(atanh) (minus_zero), minus_zero, 0, 0, 0); + + check_float ("atanh (1) == inf plus division by zero exception", FUNC(atanh) (1), plus_infty, 0, 0, DIVIDE_BY_ZERO_EXCEPTION); + check_float ("atanh (-1) == -inf plus division by zero exception", FUNC(atanh) (-1), minus_infty, 0, 0, DIVIDE_BY_ZERO_EXCEPTION); + check_float ("atanh (NaN) == NaN", FUNC(atanh) (nan_value), nan_value, 0, 0, 0); + + /* atanh (x) == NaN plus invalid exception if |x| > 1. */ + check_float ("atanh (1.1) == NaN plus invalid exception", FUNC(atanh) (1.1L), nan_value, 0, 0, INVALID_EXCEPTION); + check_float ("atanh (-1.1) == NaN plus invalid exception", FUNC(atanh) (-1.1L), nan_value, 0, 0, INVALID_EXCEPTION); + + check_float ("atanh (0.7) == 0.8673005276940531944", FUNC(atanh) (0.7L), 0.8673005276940531944L, DELTA50, 0, 0); + + print_max_error ("atanh", DELTAatanh, 0); +} + +static void +atan2_test (void) +{ + errno = 0; + FUNC(atan2) (-0, 1); + if (errno == ENOSYS) + /* Function not implemented. */ + return; + + init_max_error (); + + /* atan2 (0,x) == 0 for x > 0. */ + check_float ("atan2 (0, 1) == 0", FUNC(atan2) (0, 1), 0, 0, 0, 0); + + /* atan2 (-0,x) == -0 for x > 0. */ + check_float ("atan2 (-0, 1) == -0", FUNC(atan2) (minus_zero, 1), minus_zero, 0, 0, 0); + + check_float ("atan2 (0, 0) == 0", FUNC(atan2) (0, 0), 0, 0, 0, 0); + check_float ("atan2 (-0, 0) == -0", FUNC(atan2) (minus_zero, 0), minus_zero, 0, 0, 0); + + /* atan2 (+0,x) == +pi for x < 0. */ + check_float ("atan2 (0, -1) == pi", FUNC(atan2) (0, -1), M_PIl, 0, 0, 0); + + /* atan2 (-0,x) == -pi for x < 0. */ + check_float ("atan2 (-0, -1) == -pi", FUNC(atan2) (minus_zero, -1), -M_PIl, 0, 0, 0); + + check_float ("atan2 (0, -0) == pi", FUNC(atan2) (0, minus_zero), M_PIl, 0, 0, 0); + check_float ("atan2 (-0, -0) == -pi", FUNC(atan2) (minus_zero, minus_zero), -M_PIl, 0, 0, 0); + + /* atan2 (y,+0) == pi/2 for y > 0. */ + check_float ("atan2 (1, 0) == pi/2", FUNC(atan2) (1, 0), M_PI_2l, 0, 0, 0); + + /* atan2 (y,-0) == pi/2 for y > 0. */ + check_float ("atan2 (1, -0) == pi/2", FUNC(atan2) (1, minus_zero), M_PI_2l, 0, 0, 0); + + /* atan2 (y,+0) == -pi/2 for y < 0. */ + check_float ("atan2 (-1, 0) == -pi/2", FUNC(atan2) (-1, 0), -M_PI_2l, 0, 0, 0); + + /* atan2 (y,-0) == -pi/2 for y < 0. */ + check_float ("atan2 (-1, -0) == -pi/2", FUNC(atan2) (-1, minus_zero), -M_PI_2l, 0, 0, 0); + + /* atan2 (y,inf) == +0 for finite y > 0. */ + check_float ("atan2 (1, inf) == 0", FUNC(atan2) (1, plus_infty), 0, 0, 0, 0); + + /* atan2 (y,inf) == -0 for finite y < 0. */ + check_float ("atan2 (-1, inf) == -0", FUNC(atan2) (-1, plus_infty), minus_zero, 0, 0, 0); + + /* atan2(+inf, x) == pi/2 for finite x. */ + check_float ("atan2 (inf, -1) == pi/2", FUNC(atan2) (plus_infty, -1), M_PI_2l, 0, 0, 0); + + /* atan2(-inf, x) == -pi/2 for finite x. */ + check_float ("atan2 (-inf, 1) == -pi/2", FUNC(atan2) (minus_infty, 1), -M_PI_2l, 0, 0, 0); + + /* atan2 (y,-inf) == +pi for finite y > 0. */ + check_float ("atan2 (1, -inf) == pi", FUNC(atan2) (1, minus_infty), M_PIl, 0, 0, 0); + + /* atan2 (y,-inf) == -pi for finite y < 0. */ + check_float ("atan2 (-1, -inf) == -pi", FUNC(atan2) (-1, minus_infty), -M_PIl, 0, 0, 0); + + check_float ("atan2 (inf, inf) == pi/4", FUNC(atan2) (plus_infty, plus_infty), M_PI_4l, 0, 0, 0); + check_float ("atan2 (-inf, inf) == -pi/4", FUNC(atan2) (minus_infty, plus_infty), -M_PI_4l, 0, 0, 0); + check_float ("atan2 (inf, -inf) == 3/4 pi", FUNC(atan2) (plus_infty, minus_infty), M_PI_34l, 0, 0, 0); + check_float ("atan2 (-inf, -inf) == -3/4 pi", FUNC(atan2) (minus_infty, minus_infty), -M_PI_34l, 0, 0, 0); + check_float ("atan2 (NaN, NaN) == NaN", FUNC(atan2) (nan_value, nan_value), nan_value, 0, 0, 0); + + check_float ("atan2 (0.7, 1) == 0.61072596438920861654375887649023613", FUNC(atan2) (0.7L, 1), 0.61072596438920861654375887649023613L, DELTA74, 0, 0); + check_float ("atan2 (-0.7, 1.0) == -0.61072596438920861654375887649023613", FUNC(atan2) (-0.7L, 1.0L), -0.61072596438920861654375887649023613L, 0, 0, 0); + check_float ("atan2 (0.7, -1.0) == 2.530866689200584621918884506789267", FUNC(atan2) (0.7L, -1.0L), 2.530866689200584621918884506789267L, 0, 0, 0); + check_float ("atan2 (-0.7, -1.0) == -2.530866689200584621918884506789267", FUNC(atan2) (-0.7L, -1.0L), -2.530866689200584621918884506789267L, 0, 0, 0); + check_float ("atan2 (0.4, 0.0003) == 1.5700463269355215717704032607580829", FUNC(atan2) (0.4L, 0.0003L), 1.5700463269355215717704032607580829L, DELTA78, 0, 0); + check_float ("atan2 (1.4, -0.93) == 2.1571487668237843754887415992772736", FUNC(atan2) (1.4L, -0.93L), 2.1571487668237843754887415992772736L, 0, 0, 0); + + print_max_error ("atan2", DELTAatan2, 0); +} + + +#if 0 /* XXX scp XXX */ +static void +cabs_test (void) +{ + errno = 0; + FUNC(cabs) (BUILD_COMPLEX (0.7L, 12.4L)); + if (errno == ENOSYS) + /* Function not implemented. */ + return; + + init_max_error (); + + /* cabs (x + iy) is specified as hypot (x,y) */ + + /* cabs (+inf + i x) == +inf. */ + check_float ("cabs (inf + 1.0 i) == inf", FUNC(cabs) (BUILD_COMPLEX (plus_infty, 1.0)), plus_infty, 0, 0, 0); + /* cabs (-inf + i x) == +inf. */ + check_float ("cabs (-inf + 1.0 i) == inf", FUNC(cabs) (BUILD_COMPLEX (minus_infty, 1.0)), plus_infty, 0, 0, 0); + + check_float ("cabs (-inf + NaN i) == inf", FUNC(cabs) (BUILD_COMPLEX (minus_infty, nan_value)), plus_infty, 0, 0, 0); + check_float ("cabs (-inf + NaN i) == inf", FUNC(cabs) (BUILD_COMPLEX (minus_infty, nan_value)), plus_infty, 0, 0, 0); + + check_float ("cabs (NaN + NaN i) == NaN", FUNC(cabs) (BUILD_COMPLEX (nan_value, nan_value)), nan_value, 0, 0, 0); + + /* cabs (x,y) == cabs (y,x). */ + check_float ("cabs (0.7 + 12.4 i) == 12.419742348374220601176836866763271", FUNC(cabs) (BUILD_COMPLEX (0.7L, 12.4L)), 12.419742348374220601176836866763271L, DELTA85, 0, 0); + /* cabs (x,y) == cabs (-x,y). */ + check_float ("cabs (-12.4 + 0.7 i) == 12.419742348374220601176836866763271", FUNC(cabs) (BUILD_COMPLEX (-12.4L, 0.7L)), 12.419742348374220601176836866763271L, DELTA86, 0, 0); + /* cabs (x,y) == cabs (-y,x). */ + check_float ("cabs (-0.7 + 12.4 i) == 12.419742348374220601176836866763271", FUNC(cabs) (BUILD_COMPLEX (-0.7L, 12.4L)), 12.419742348374220601176836866763271L, DELTA87, 0, 0); + /* cabs (x,y) == cabs (-x,-y). */ + check_float ("cabs (-12.4 - 0.7 i) == 12.419742348374220601176836866763271", FUNC(cabs) (BUILD_COMPLEX (-12.4L, -0.7L)), 12.419742348374220601176836866763271L, DELTA88, 0, 0); + /* cabs (x,y) == cabs (-y,-x). */ + check_float ("cabs (-0.7 - 12.4 i) == 12.419742348374220601176836866763271", FUNC(cabs) (BUILD_COMPLEX (-0.7L, -12.4L)), 12.419742348374220601176836866763271L, DELTA89, 0, 0); + /* cabs (x,0) == fabs (x). */ + check_float ("cabs (-0.7 + 0 i) == 0.7", FUNC(cabs) (BUILD_COMPLEX (-0.7L, 0)), 0.7L, 0, 0, 0); + check_float ("cabs (0.7 + 0 i) == 0.7", FUNC(cabs) (BUILD_COMPLEX (0.7L, 0)), 0.7L, 0, 0, 0); + check_float ("cabs (-1.0 + 0 i) == 1.0", FUNC(cabs) (BUILD_COMPLEX (-1.0L, 0)), 1.0L, 0, 0, 0); + check_float ("cabs (1.0 + 0 i) == 1.0", FUNC(cabs) (BUILD_COMPLEX (1.0L, 0)), 1.0L, 0, 0, 0); + check_float ("cabs (-5.7e7 + 0 i) == 5.7e7", FUNC(cabs) (BUILD_COMPLEX (-5.7e7L, 0)), 5.7e7L, 0, 0, 0); + check_float ("cabs (5.7e7 + 0 i) == 5.7e7", FUNC(cabs) (BUILD_COMPLEX (5.7e7L, 0)), 5.7e7L, 0, 0, 0); + + check_float ("cabs (0.7 + 1.2 i) == 1.3892443989449804508432547041028554", FUNC(cabs) (BUILD_COMPLEX (0.7L, 1.2L)), 1.3892443989449804508432547041028554L, DELTA96, 0, 0); + + print_max_error ("cabs", DELTAcabs, 0); +} + +static void +cacos_test (void) +{ + errno = 0; + FUNC(cacos) (BUILD_COMPLEX (0.7L, 1.2L)); + if (errno == ENOSYS) + /* Function not implemented. */ + return; + + init_max_error (); + + + check_complex ("cacos (0 + 0 i) == pi/2 - 0 i", FUNC(cacos) (BUILD_COMPLEX (0, 0)), BUILD_COMPLEX (M_PI_2l, minus_zero), 0, 0, 0); + check_complex ("cacos (-0 + 0 i) == pi/2 - 0 i", FUNC(cacos) (BUILD_COMPLEX (minus_zero, 0)), BUILD_COMPLEX (M_PI_2l, minus_zero), 0, 0, 0); + check_complex ("cacos (-0 - 0 i) == pi/2 + 0.0 i", FUNC(cacos) (BUILD_COMPLEX (minus_zero, minus_zero)), BUILD_COMPLEX (M_PI_2l, 0.0), 0, 0, 0); + check_complex ("cacos (0 - 0 i) == pi/2 + 0.0 i", FUNC(cacos) (BUILD_COMPLEX (0, minus_zero)), BUILD_COMPLEX (M_PI_2l, 0.0), 0, 0, 0); + + check_complex ("cacos (-inf + inf i) == 3/4 pi - inf i", FUNC(cacos) (BUILD_COMPLEX (minus_infty, plus_infty)), BUILD_COMPLEX (M_PI_34l, minus_infty), 0, 0, 0); + check_complex ("cacos (-inf - inf i) == 3/4 pi + inf i", FUNC(cacos) (BUILD_COMPLEX (minus_infty, minus_infty)), BUILD_COMPLEX (M_PI_34l, plus_infty), 0, 0, 0); + + check_complex ("cacos (inf + inf i) == pi/4 - inf i", FUNC(cacos) (BUILD_COMPLEX (plus_infty, plus_infty)), BUILD_COMPLEX (M_PI_4l, minus_infty), 0, 0, 0); + check_complex ("cacos (inf - inf i) == pi/4 + inf i", FUNC(cacos) (BUILD_COMPLEX (plus_infty, minus_infty)), BUILD_COMPLEX (M_PI_4l, plus_infty), 0, 0, 0); + + check_complex ("cacos (-10.0 + inf i) == pi/2 - inf i", FUNC(cacos) (BUILD_COMPLEX (-10.0, plus_infty)), BUILD_COMPLEX (M_PI_2l, minus_infty), 0, 0, 0); + check_complex ("cacos (-10.0 - inf i) == pi/2 + inf i", FUNC(cacos) (BUILD_COMPLEX (-10.0, minus_infty)), BUILD_COMPLEX (M_PI_2l, plus_infty), 0, 0, 0); + check_complex ("cacos (0 + inf i) == pi/2 - inf i", FUNC(cacos) (BUILD_COMPLEX (0, plus_infty)), BUILD_COMPLEX (M_PI_2l, minus_infty), 0, 0, 0); + check_complex ("cacos (0 - inf i) == pi/2 + inf i", FUNC(cacos) (BUILD_COMPLEX (0, minus_infty)), BUILD_COMPLEX (M_PI_2l, plus_infty), 0, 0, 0); + check_complex ("cacos (0.1 + inf i) == pi/2 - inf i", FUNC(cacos) (BUILD_COMPLEX (0.1L, plus_infty)), BUILD_COMPLEX (M_PI_2l, minus_infty), 0, 0, 0); + check_complex ("cacos (0.1 - inf i) == pi/2 + inf i", FUNC(cacos) (BUILD_COMPLEX (0.1L, minus_infty)), BUILD_COMPLEX (M_PI_2l, plus_infty), 0, 0, 0); + + check_complex ("cacos (-inf + 0 i) == pi - inf i", FUNC(cacos) (BUILD_COMPLEX (minus_infty, 0)), BUILD_COMPLEX (M_PIl, minus_infty), 0, 0, 0); + check_complex ("cacos (-inf - 0 i) == pi + inf i", FUNC(cacos) (BUILD_COMPLEX (minus_infty, minus_zero)), BUILD_COMPLEX (M_PIl, plus_infty), 0, 0, 0); + check_complex ("cacos (-inf + 100 i) == pi - inf i", FUNC(cacos) (BUILD_COMPLEX (minus_infty, 100)), BUILD_COMPLEX (M_PIl, minus_infty), 0, 0, 0); + check_complex ("cacos (-inf - 100 i) == pi + inf i", FUNC(cacos) (BUILD_COMPLEX (minus_infty, -100)), BUILD_COMPLEX (M_PIl, plus_infty), 0, 0, 0); + + check_complex ("cacos (inf + 0 i) == 0.0 - inf i", FUNC(cacos) (BUILD_COMPLEX (plus_infty, 0)), BUILD_COMPLEX (0.0, minus_infty), 0, 0, 0); + check_complex ("cacos (inf - 0 i) == 0.0 + inf i", FUNC(cacos) (BUILD_COMPLEX (plus_infty, minus_zero)), BUILD_COMPLEX (0.0, plus_infty), 0, 0, 0); + check_complex ("cacos (inf + 0.5 i) == 0.0 - inf i", FUNC(cacos) (BUILD_COMPLEX (plus_infty, 0.5)), BUILD_COMPLEX (0.0, minus_infty), 0, 0, 0); + check_complex ("cacos (inf - 0.5 i) == 0.0 + inf i", FUNC(cacos) (BUILD_COMPLEX (plus_infty, -0.5)), BUILD_COMPLEX (0.0, plus_infty), 0, 0, 0); + + check_complex ("cacos (inf + NaN i) == NaN + inf i plus sign of zero/inf not specified", FUNC(cacos) (BUILD_COMPLEX (plus_infty, nan_value)), BUILD_COMPLEX (nan_value, plus_infty), 0, 0, IGNORE_ZERO_INF_SIGN); + check_complex ("cacos (-inf + NaN i) == NaN + inf i plus sign of zero/inf not specified", FUNC(cacos) (BUILD_COMPLEX (minus_infty, nan_value)), BUILD_COMPLEX (nan_value, plus_infty), 0, 0, IGNORE_ZERO_INF_SIGN); + + check_complex ("cacos (0 + NaN i) == pi/2 + NaN i", FUNC(cacos) (BUILD_COMPLEX (0, nan_value)), BUILD_COMPLEX (M_PI_2l, nan_value), 0, 0, 0); + check_complex ("cacos (-0 + NaN i) == pi/2 + NaN i", FUNC(cacos) (BUILD_COMPLEX (minus_zero, nan_value)), BUILD_COMPLEX (M_PI_2l, nan_value), 0, 0, 0); + + check_complex ("cacos (NaN + inf i) == NaN - inf i", FUNC(cacos) (BUILD_COMPLEX (nan_value, plus_infty)), BUILD_COMPLEX (nan_value, minus_infty), 0, 0, 0); + check_complex ("cacos (NaN - inf i) == NaN + inf i", FUNC(cacos) (BUILD_COMPLEX (nan_value, minus_infty)), BUILD_COMPLEX (nan_value, plus_infty), 0, 0, 0); + + check_complex ("cacos (10.5 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(cacos) (BUILD_COMPLEX (10.5, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + check_complex ("cacos (-10.5 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(cacos) (BUILD_COMPLEX (-10.5, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + + check_complex ("cacos (NaN + 0.75 i) == NaN + NaN i plus invalid exception allowed", FUNC(cacos) (BUILD_COMPLEX (nan_value, 0.75)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + check_complex ("cacos (NaN - 0.75 i) == NaN + NaN i plus invalid exception allowed", FUNC(cacos) (BUILD_COMPLEX (nan_value, -0.75)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + + check_complex ("cacos (NaN + NaN i) == NaN + NaN i", FUNC(cacos) (BUILD_COMPLEX (nan_value, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, 0); + + check_complex ("cacos (0.7 + 1.2 i) == 1.1351827477151551088992008271819053 - 1.0927647857577371459105272080819308 i", FUNC(cacos) (BUILD_COMPLEX (0.7L, 1.2L)), BUILD_COMPLEX (1.1351827477151551088992008271819053L, -1.0927647857577371459105272080819308L), DELTA130, 0, 0); + check_complex ("cacos (-2 - 3 i) == 2.1414491111159960199416055713254211 + 1.9833870299165354323470769028940395 i", FUNC(cacos) (BUILD_COMPLEX (-2, -3)), BUILD_COMPLEX (2.1414491111159960199416055713254211L, 1.9833870299165354323470769028940395L), DELTA131, 0, 0); + + print_complex_max_error ("cacos", DELTAcacos, 0); +} + + +static void +cacosh_test (void) +{ + errno = 0; + FUNC(cacosh) (BUILD_COMPLEX (0.7L, 1.2L)); + if (errno == ENOSYS) + /* Function not implemented. */ + return; + + init_max_error (); + + + check_complex ("cacosh (0 + 0 i) == 0.0 + pi/2 i", FUNC(cacosh) (BUILD_COMPLEX (0, 0)), BUILD_COMPLEX (0.0, M_PI_2l), 0, 0, 0); + check_complex ("cacosh (-0 + 0 i) == 0.0 + pi/2 i", FUNC(cacosh) (BUILD_COMPLEX (minus_zero, 0)), BUILD_COMPLEX (0.0, M_PI_2l), 0, 0, 0); + check_complex ("cacosh (0 - 0 i) == 0.0 - pi/2 i", FUNC(cacosh) (BUILD_COMPLEX (0, minus_zero)), BUILD_COMPLEX (0.0, -M_PI_2l), 0, 0, 0); + check_complex ("cacosh (-0 - 0 i) == 0.0 - pi/2 i", FUNC(cacosh) (BUILD_COMPLEX (minus_zero, minus_zero)), BUILD_COMPLEX (0.0, -M_PI_2l), 0, 0, 0); + check_complex ("cacosh (-inf + inf i) == inf + 3/4 pi i", FUNC(cacosh) (BUILD_COMPLEX (minus_infty, plus_infty)), BUILD_COMPLEX (plus_infty, M_PI_34l), 0, 0, 0); + check_complex ("cacosh (-inf - inf i) == inf - 3/4 pi i", FUNC(cacosh) (BUILD_COMPLEX (minus_infty, minus_infty)), BUILD_COMPLEX (plus_infty, -M_PI_34l), 0, 0, 0); + + check_complex ("cacosh (inf + inf i) == inf + pi/4 i", FUNC(cacosh) (BUILD_COMPLEX (plus_infty, plus_infty)), BUILD_COMPLEX (plus_infty, M_PI_4l), 0, 0, 0); + check_complex ("cacosh (inf - inf i) == inf - pi/4 i", FUNC(cacosh) (BUILD_COMPLEX (plus_infty, minus_infty)), BUILD_COMPLEX (plus_infty, -M_PI_4l), 0, 0, 0); + + check_complex ("cacosh (-10.0 + inf i) == inf + pi/2 i", FUNC(cacosh) (BUILD_COMPLEX (-10.0, plus_infty)), BUILD_COMPLEX (plus_infty, M_PI_2l), 0, 0, 0); + check_complex ("cacosh (-10.0 - inf i) == inf - pi/2 i", FUNC(cacosh) (BUILD_COMPLEX (-10.0, minus_infty)), BUILD_COMPLEX (plus_infty, -M_PI_2l), 0, 0, 0); + check_complex ("cacosh (0 + inf i) == inf + pi/2 i", FUNC(cacosh) (BUILD_COMPLEX (0, plus_infty)), BUILD_COMPLEX (plus_infty, M_PI_2l), 0, 0, 0); + check_complex ("cacosh (0 - inf i) == inf - pi/2 i", FUNC(cacosh) (BUILD_COMPLEX (0, minus_infty)), BUILD_COMPLEX (plus_infty, -M_PI_2l), 0, 0, 0); + check_complex ("cacosh (0.1 + inf i) == inf + pi/2 i", FUNC(cacosh) (BUILD_COMPLEX (0.1L, plus_infty)), BUILD_COMPLEX (plus_infty, M_PI_2l), 0, 0, 0); + check_complex ("cacosh (0.1 - inf i) == inf - pi/2 i", FUNC(cacosh) (BUILD_COMPLEX (0.1L, minus_infty)), BUILD_COMPLEX (plus_infty, -M_PI_2l), 0, 0, 0); + + check_complex ("cacosh (-inf + 0 i) == inf + pi i", FUNC(cacosh) (BUILD_COMPLEX (minus_infty, 0)), BUILD_COMPLEX (plus_infty, M_PIl), 0, 0, 0); + check_complex ("cacosh (-inf - 0 i) == inf - pi i", FUNC(cacosh) (BUILD_COMPLEX (minus_infty, minus_zero)), BUILD_COMPLEX (plus_infty, -M_PIl), 0, 0, 0); + check_complex ("cacosh (-inf + 100 i) == inf + pi i", FUNC(cacosh) (BUILD_COMPLEX (minus_infty, 100)), BUILD_COMPLEX (plus_infty, M_PIl), 0, 0, 0); + check_complex ("cacosh (-inf - 100 i) == inf - pi i", FUNC(cacosh) (BUILD_COMPLEX (minus_infty, -100)), BUILD_COMPLEX (plus_infty, -M_PIl), 0, 0, 0); + + check_complex ("cacosh (inf + 0 i) == inf + 0.0 i", FUNC(cacosh) (BUILD_COMPLEX (plus_infty, 0)), BUILD_COMPLEX (plus_infty, 0.0), 0, 0, 0); + check_complex ("cacosh (inf - 0 i) == inf - 0 i", FUNC(cacosh) (BUILD_COMPLEX (plus_infty, minus_zero)), BUILD_COMPLEX (plus_infty, minus_zero), 0, 0, 0); + check_complex ("cacosh (inf + 0.5 i) == inf + 0.0 i", FUNC(cacosh) (BUILD_COMPLEX (plus_infty, 0.5)), BUILD_COMPLEX (plus_infty, 0.0), 0, 0, 0); + check_complex ("cacosh (inf - 0.5 i) == inf - 0 i", FUNC(cacosh) (BUILD_COMPLEX (plus_infty, -0.5)), BUILD_COMPLEX (plus_infty, minus_zero), 0, 0, 0); + + check_complex ("cacosh (inf + NaN i) == inf + NaN i", FUNC(cacosh) (BUILD_COMPLEX (plus_infty, nan_value)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, 0); + check_complex ("cacosh (-inf + NaN i) == inf + NaN i", FUNC(cacosh) (BUILD_COMPLEX (minus_infty, nan_value)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, 0); + + check_complex ("cacosh (0 + NaN i) == NaN + NaN i", FUNC(cacosh) (BUILD_COMPLEX (0, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, 0); + check_complex ("cacosh (-0 + NaN i) == NaN + NaN i", FUNC(cacosh) (BUILD_COMPLEX (minus_zero, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, 0); + + check_complex ("cacosh (NaN + inf i) == inf + NaN i", FUNC(cacosh) (BUILD_COMPLEX (nan_value, plus_infty)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, 0); + check_complex ("cacosh (NaN - inf i) == inf + NaN i", FUNC(cacosh) (BUILD_COMPLEX (nan_value, minus_infty)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, 0); + + check_complex ("cacosh (10.5 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(cacosh) (BUILD_COMPLEX (10.5, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + check_complex ("cacosh (-10.5 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(cacosh) (BUILD_COMPLEX (-10.5, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + + check_complex ("cacosh (NaN + 0.75 i) == NaN + NaN i plus invalid exception allowed", FUNC(cacosh) (BUILD_COMPLEX (nan_value, 0.75)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + check_complex ("cacosh (NaN - 0.75 i) == NaN + NaN i plus invalid exception allowed", FUNC(cacosh) (BUILD_COMPLEX (nan_value, -0.75)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + + check_complex ("cacosh (NaN + NaN i) == NaN + NaN i", FUNC(cacosh) (BUILD_COMPLEX (nan_value, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, 0); + + check_complex ("cacosh (0.7 + 1.2 i) == 1.0927647857577371459105272080819308 + 1.1351827477151551088992008271819053 i", FUNC(cacosh) (BUILD_COMPLEX (0.7L, 1.2L)), BUILD_COMPLEX (1.0927647857577371459105272080819308L, 1.1351827477151551088992008271819053L), DELTA165, 0, 0); + check_complex ("cacosh (-2 - 3 i) == -1.9833870299165354323470769028940395 + 2.1414491111159960199416055713254211 i", FUNC(cacosh) (BUILD_COMPLEX (-2, -3)), BUILD_COMPLEX (-1.9833870299165354323470769028940395L, 2.1414491111159960199416055713254211L), DELTA166, 0, 0); + + print_complex_max_error ("cacosh", DELTAcacosh, 0); +} + +static void +carg_test (void) +{ + init_max_error (); + + /* carg (x + iy) is specified as atan2 (y, x) */ + + /* carg (x + i 0) == 0 for x > 0. */ + check_float ("carg (2.0 + 0 i) == 0", FUNC(carg) (BUILD_COMPLEX (2.0, 0)), 0, 0, 0, 0); + /* carg (x - i 0) == -0 for x > 0. */ + check_float ("carg (2.0 - 0 i) == -0", FUNC(carg) (BUILD_COMPLEX (2.0, minus_zero)), minus_zero, 0, 0, 0); + + check_float ("carg (0 + 0 i) == 0", FUNC(carg) (BUILD_COMPLEX (0, 0)), 0, 0, 0, 0); + check_float ("carg (0 - 0 i) == -0", FUNC(carg) (BUILD_COMPLEX (0, minus_zero)), minus_zero, 0, 0, 0); + + /* carg (x + i 0) == +pi for x < 0. */ + check_float ("carg (-2.0 + 0 i) == pi", FUNC(carg) (BUILD_COMPLEX (-2.0, 0)), M_PIl, 0, 0, 0); + + /* carg (x - i 0) == -pi for x < 0. */ + check_float ("carg (-2.0 - 0 i) == -pi", FUNC(carg) (BUILD_COMPLEX (-2.0, minus_zero)), -M_PIl, 0, 0, 0); + + check_float ("carg (-0 + 0 i) == pi", FUNC(carg) (BUILD_COMPLEX (minus_zero, 0)), M_PIl, 0, 0, 0); + check_float ("carg (-0 - 0 i) == -pi", FUNC(carg) (BUILD_COMPLEX (minus_zero, minus_zero)), -M_PIl, 0, 0, 0); + + /* carg (+0 + i y) == pi/2 for y > 0. */ + check_float ("carg (0 + 2.0 i) == pi/2", FUNC(carg) (BUILD_COMPLEX (0, 2.0)), M_PI_2l, 0, 0, 0); + + /* carg (-0 + i y) == pi/2 for y > 0. */ + check_float ("carg (-0 + 2.0 i) == pi/2", FUNC(carg) (BUILD_COMPLEX (minus_zero, 2.0)), M_PI_2l, 0, 0, 0); + + /* carg (+0 + i y) == -pi/2 for y < 0. */ + check_float ("carg (0 - 2.0 i) == -pi/2", FUNC(carg) (BUILD_COMPLEX (0, -2.0)), -M_PI_2l, 0, 0, 0); + + /* carg (-0 + i y) == -pi/2 for y < 0. */ + check_float ("carg (-0 - 2.0 i) == -pi/2", FUNC(carg) (BUILD_COMPLEX (minus_zero, -2.0)), -M_PI_2l, 0, 0, 0); + + /* carg (inf + i y) == +0 for finite y > 0. */ + check_float ("carg (inf + 2.0 i) == 0", FUNC(carg) (BUILD_COMPLEX (plus_infty, 2.0)), 0, 0, 0, 0); + + /* carg (inf + i y) == -0 for finite y < 0. */ + check_float ("carg (inf - 2.0 i) == -0", FUNC(carg) (BUILD_COMPLEX (plus_infty, -2.0)), minus_zero, 0, 0, 0); + + /* carg(x + i inf) == pi/2 for finite x. */ + check_float ("carg (10.0 + inf i) == pi/2", FUNC(carg) (BUILD_COMPLEX (10.0, plus_infty)), M_PI_2l, 0, 0, 0); + + /* carg(x - i inf) == -pi/2 for finite x. */ + check_float ("carg (10.0 - inf i) == -pi/2", FUNC(carg) (BUILD_COMPLEX (10.0, minus_infty)), -M_PI_2l, 0, 0, 0); + + /* carg (-inf + i y) == +pi for finite y > 0. */ + check_float ("carg (-inf + 10.0 i) == pi", FUNC(carg) (BUILD_COMPLEX (minus_infty, 10.0)), M_PIl, 0, 0, 0); + + /* carg (-inf + i y) == -pi for finite y < 0. */ + check_float ("carg (-inf - 10.0 i) == -pi", FUNC(carg) (BUILD_COMPLEX (minus_infty, -10.0)), -M_PIl, 0, 0, 0); + + check_float ("carg (inf + inf i) == pi/4", FUNC(carg) (BUILD_COMPLEX (plus_infty, plus_infty)), M_PI_4l, 0, 0, 0); + + check_float ("carg (inf - inf i) == -pi/4", FUNC(carg) (BUILD_COMPLEX (plus_infty, minus_infty)), -M_PI_4l, 0, 0, 0); + + check_float ("carg (-inf + inf i) == 3 * M_PI_4l", FUNC(carg) (BUILD_COMPLEX (minus_infty, plus_infty)), 3 * M_PI_4l, 0, 0, 0); + + check_float ("carg (-inf - inf i) == -3 * M_PI_4l", FUNC(carg) (BUILD_COMPLEX (minus_infty, minus_infty)), -3 * M_PI_4l, 0, 0, 0); + + check_float ("carg (NaN + NaN i) == NaN", FUNC(carg) (BUILD_COMPLEX (nan_value, nan_value)), nan_value, 0, 0, 0); + + print_max_error ("carg", 0, 0); +} + +static void +casin_test (void) +{ + errno = 0; + FUNC(casin) (BUILD_COMPLEX (0.7L, 1.2L)); + if (errno == ENOSYS) + /* Function not implemented. */ + return; + + init_max_error (); + + check_complex ("casin (0 + 0 i) == 0.0 + 0.0 i", FUNC(casin) (BUILD_COMPLEX (0, 0)), BUILD_COMPLEX (0.0, 0.0), 0, 0, 0); + check_complex ("casin (-0 + 0 i) == -0 + 0.0 i", FUNC(casin) (BUILD_COMPLEX (minus_zero, 0)), BUILD_COMPLEX (minus_zero, 0.0), 0, 0, 0); + check_complex ("casin (0 - 0 i) == 0.0 - 0 i", FUNC(casin) (BUILD_COMPLEX (0, minus_zero)), BUILD_COMPLEX (0.0, minus_zero), 0, 0, 0); + check_complex ("casin (-0 - 0 i) == -0 - 0 i", FUNC(casin) (BUILD_COMPLEX (minus_zero, minus_zero)), BUILD_COMPLEX (minus_zero, minus_zero), 0, 0, 0); + + check_complex ("casin (inf + inf i) == pi/4 + inf i", FUNC(casin) (BUILD_COMPLEX (plus_infty, plus_infty)), BUILD_COMPLEX (M_PI_4l, plus_infty), 0, 0, 0); + check_complex ("casin (inf - inf i) == pi/4 - inf i", FUNC(casin) (BUILD_COMPLEX (plus_infty, minus_infty)), BUILD_COMPLEX (M_PI_4l, minus_infty), 0, 0, 0); + check_complex ("casin (-inf + inf i) == -pi/4 + inf i", FUNC(casin) (BUILD_COMPLEX (minus_infty, plus_infty)), BUILD_COMPLEX (-M_PI_4l, plus_infty), 0, 0, 0); + check_complex ("casin (-inf - inf i) == -pi/4 - inf i", FUNC(casin) (BUILD_COMPLEX (minus_infty, minus_infty)), BUILD_COMPLEX (-M_PI_4l, minus_infty), 0, 0, 0); + + check_complex ("casin (-10.0 + inf i) == -0 + inf i", FUNC(casin) (BUILD_COMPLEX (-10.0, plus_infty)), BUILD_COMPLEX (minus_zero, plus_infty), 0, 0, 0); + check_complex ("casin (-10.0 - inf i) == -0 - inf i", FUNC(casin) (BUILD_COMPLEX (-10.0, minus_infty)), BUILD_COMPLEX (minus_zero, minus_infty), 0, 0, 0); + check_complex ("casin (0 + inf i) == 0.0 + inf i", FUNC(casin) (BUILD_COMPLEX (0, plus_infty)), BUILD_COMPLEX (0.0, plus_infty), 0, 0, 0); + check_complex ("casin (0 - inf i) == 0.0 - inf i", FUNC(casin) (BUILD_COMPLEX (0, minus_infty)), BUILD_COMPLEX (0.0, minus_infty), 0, 0, 0); + check_complex ("casin (-0 + inf i) == -0 + inf i", FUNC(casin) (BUILD_COMPLEX (minus_zero, plus_infty)), BUILD_COMPLEX (minus_zero, plus_infty), 0, 0, 0); + check_complex ("casin (-0 - inf i) == -0 - inf i", FUNC(casin) (BUILD_COMPLEX (minus_zero, minus_infty)), BUILD_COMPLEX (minus_zero, minus_infty), 0, 0, 0); + check_complex ("casin (0.1 + inf i) == 0.0 + inf i", FUNC(casin) (BUILD_COMPLEX (0.1L, plus_infty)), BUILD_COMPLEX (0.0, plus_infty), 0, 0, 0); + check_complex ("casin (0.1 - inf i) == 0.0 - inf i", FUNC(casin) (BUILD_COMPLEX (0.1L, minus_infty)), BUILD_COMPLEX (0.0, minus_infty), 0, 0, 0); + + check_complex ("casin (-inf + 0 i) == -pi/2 + inf i", FUNC(casin) (BUILD_COMPLEX (minus_infty, 0)), BUILD_COMPLEX (-M_PI_2l, plus_infty), 0, 0, 0); + check_complex ("casin (-inf - 0 i) == -pi/2 - inf i", FUNC(casin) (BUILD_COMPLEX (minus_infty, minus_zero)), BUILD_COMPLEX (-M_PI_2l, minus_infty), 0, 0, 0); + check_complex ("casin (-inf + 100 i) == -pi/2 + inf i", FUNC(casin) (BUILD_COMPLEX (minus_infty, 100)), BUILD_COMPLEX (-M_PI_2l, plus_infty), 0, 0, 0); + check_complex ("casin (-inf - 100 i) == -pi/2 - inf i", FUNC(casin) (BUILD_COMPLEX (minus_infty, -100)), BUILD_COMPLEX (-M_PI_2l, minus_infty), 0, 0, 0); + + check_complex ("casin (inf + 0 i) == pi/2 + inf i", FUNC(casin) (BUILD_COMPLEX (plus_infty, 0)), BUILD_COMPLEX (M_PI_2l, plus_infty), 0, 0, 0); + check_complex ("casin (inf - 0 i) == pi/2 - inf i", FUNC(casin) (BUILD_COMPLEX (plus_infty, minus_zero)), BUILD_COMPLEX (M_PI_2l, minus_infty), 0, 0, 0); + check_complex ("casin (inf + 0.5 i) == pi/2 + inf i", FUNC(casin) (BUILD_COMPLEX (plus_infty, 0.5)), BUILD_COMPLEX (M_PI_2l, plus_infty), 0, 0, 0); + check_complex ("casin (inf - 0.5 i) == pi/2 - inf i", FUNC(casin) (BUILD_COMPLEX (plus_infty, -0.5)), BUILD_COMPLEX (M_PI_2l, minus_infty), 0, 0, 0); + + check_complex ("casin (NaN + inf i) == NaN + inf i", FUNC(casin) (BUILD_COMPLEX (nan_value, plus_infty)), BUILD_COMPLEX (nan_value, plus_infty), 0, 0, 0); + check_complex ("casin (NaN - inf i) == NaN - inf i", FUNC(casin) (BUILD_COMPLEX (nan_value, minus_infty)), BUILD_COMPLEX (nan_value, minus_infty), 0, 0, 0); + + check_complex ("casin (0.0 + NaN i) == 0.0 + NaN i", FUNC(casin) (BUILD_COMPLEX (0.0, nan_value)), BUILD_COMPLEX (0.0, nan_value), 0, 0, 0); + check_complex ("casin (-0 + NaN i) == -0 + NaN i", FUNC(casin) (BUILD_COMPLEX (minus_zero, nan_value)), BUILD_COMPLEX (minus_zero, nan_value), 0, 0, 0); + + check_complex ("casin (inf + NaN i) == NaN + inf i plus sign of zero/inf not specified", FUNC(casin) (BUILD_COMPLEX (plus_infty, nan_value)), BUILD_COMPLEX (nan_value, plus_infty), 0, 0, IGNORE_ZERO_INF_SIGN); + check_complex ("casin (-inf + NaN i) == NaN + inf i plus sign of zero/inf not specified", FUNC(casin) (BUILD_COMPLEX (minus_infty, nan_value)), BUILD_COMPLEX (nan_value, plus_infty), 0, 0, IGNORE_ZERO_INF_SIGN); + + check_complex ("casin (NaN + 10.5 i) == NaN + NaN i plus invalid exception allowed", FUNC(casin) (BUILD_COMPLEX (nan_value, 10.5)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + check_complex ("casin (NaN - 10.5 i) == NaN + NaN i plus invalid exception allowed", FUNC(casin) (BUILD_COMPLEX (nan_value, -10.5)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + + check_complex ("casin (0.75 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(casin) (BUILD_COMPLEX (0.75, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + check_complex ("casin (-0.75 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(casin) (BUILD_COMPLEX (-0.75, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + + check_complex ("casin (NaN + NaN i) == NaN + NaN i", FUNC(casin) (BUILD_COMPLEX (nan_value, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, 0); + + check_complex ("casin (0.7 + 1.2 i) == 0.4356135790797415103321208644578462 + 1.0927647857577371459105272080819308 i", FUNC(casin) (BUILD_COMPLEX (0.7L, 1.2L)), BUILD_COMPLEX (0.4356135790797415103321208644578462L, 1.0927647857577371459105272080819308L), DELTA225, 0, 0); + check_complex ("casin (-2 - 3 i) == -0.57065278432109940071028387968566963 - 1.9833870299165354323470769028940395 i", FUNC(casin) (BUILD_COMPLEX (-2, -3)), BUILD_COMPLEX (-0.57065278432109940071028387968566963L, -1.9833870299165354323470769028940395L), DELTA226, 0, 0); + + print_complex_max_error ("casin", DELTAcasin, 0); +} + + +static void +casinh_test (void) +{ + errno = 0; + FUNC(casinh) (BUILD_COMPLEX (0.7L, 1.2L)); + if (errno == ENOSYS) + /* Function not implemented. */ + return; + + init_max_error (); + + check_complex ("casinh (0 + 0 i) == 0.0 + 0.0 i", FUNC(casinh) (BUILD_COMPLEX (0, 0)), BUILD_COMPLEX (0.0, 0.0), 0, 0, 0); + check_complex ("casinh (-0 + 0 i) == -0 + 0 i", FUNC(casinh) (BUILD_COMPLEX (minus_zero, 0)), BUILD_COMPLEX (minus_zero, 0), 0, 0, 0); + check_complex ("casinh (0 - 0 i) == 0.0 - 0 i", FUNC(casinh) (BUILD_COMPLEX (0, minus_zero)), BUILD_COMPLEX (0.0, minus_zero), 0, 0, 0); + check_complex ("casinh (-0 - 0 i) == -0 - 0 i", FUNC(casinh) (BUILD_COMPLEX (minus_zero, minus_zero)), BUILD_COMPLEX (minus_zero, minus_zero), 0, 0, 0); + + check_complex ("casinh (inf + inf i) == inf + pi/4 i", FUNC(casinh) (BUILD_COMPLEX (plus_infty, plus_infty)), BUILD_COMPLEX (plus_infty, M_PI_4l), 0, 0, 0); + check_complex ("casinh (inf - inf i) == inf - pi/4 i", FUNC(casinh) (BUILD_COMPLEX (plus_infty, minus_infty)), BUILD_COMPLEX (plus_infty, -M_PI_4l), 0, 0, 0); + check_complex ("casinh (-inf + inf i) == -inf + pi/4 i", FUNC(casinh) (BUILD_COMPLEX (minus_infty, plus_infty)), BUILD_COMPLEX (minus_infty, M_PI_4l), 0, 0, 0); + check_complex ("casinh (-inf - inf i) == -inf - pi/4 i", FUNC(casinh) (BUILD_COMPLEX (minus_infty, minus_infty)), BUILD_COMPLEX (minus_infty, -M_PI_4l), 0, 0, 0); + + check_complex ("casinh (-10.0 + inf i) == -inf + pi/2 i", FUNC(casinh) (BUILD_COMPLEX (-10.0, plus_infty)), BUILD_COMPLEX (minus_infty, M_PI_2l), 0, 0, 0); + check_complex ("casinh (-10.0 - inf i) == -inf - pi/2 i", FUNC(casinh) (BUILD_COMPLEX (-10.0, minus_infty)), BUILD_COMPLEX (minus_infty, -M_PI_2l), 0, 0, 0); + check_complex ("casinh (0 + inf i) == inf + pi/2 i", FUNC(casinh) (BUILD_COMPLEX (0, plus_infty)), BUILD_COMPLEX (plus_infty, M_PI_2l), 0, 0, 0); + check_complex ("casinh (0 - inf i) == inf - pi/2 i", FUNC(casinh) (BUILD_COMPLEX (0, minus_infty)), BUILD_COMPLEX (plus_infty, -M_PI_2l), 0, 0, 0); + check_complex ("casinh (-0 + inf i) == -inf + pi/2 i", FUNC(casinh) (BUILD_COMPLEX (minus_zero, plus_infty)), BUILD_COMPLEX (minus_infty, M_PI_2l), 0, 0, 0); + check_complex ("casinh (-0 - inf i) == -inf - pi/2 i", FUNC(casinh) (BUILD_COMPLEX (minus_zero, minus_infty)), BUILD_COMPLEX (minus_infty, -M_PI_2l), 0, 0, 0); + check_complex ("casinh (0.1 + inf i) == inf + pi/2 i", FUNC(casinh) (BUILD_COMPLEX (0.1L, plus_infty)), BUILD_COMPLEX (plus_infty, M_PI_2l), 0, 0, 0); + check_complex ("casinh (0.1 - inf i) == inf - pi/2 i", FUNC(casinh) (BUILD_COMPLEX (0.1L, minus_infty)), BUILD_COMPLEX (plus_infty, -M_PI_2l), 0, 0, 0); + + check_complex ("casinh (-inf + 0 i) == -inf + 0.0 i", FUNC(casinh) (BUILD_COMPLEX (minus_infty, 0)), BUILD_COMPLEX (minus_infty, 0.0), 0, 0, 0); + check_complex ("casinh (-inf - 0 i) == -inf - 0 i", FUNC(casinh) (BUILD_COMPLEX (minus_infty, minus_zero)), BUILD_COMPLEX (minus_infty, minus_zero), 0, 0, 0); + check_complex ("casinh (-inf + 100 i) == -inf + 0.0 i", FUNC(casinh) (BUILD_COMPLEX (minus_infty, 100)), BUILD_COMPLEX (minus_infty, 0.0), 0, 0, 0); + check_complex ("casinh (-inf - 100 i) == -inf - 0 i", FUNC(casinh) (BUILD_COMPLEX (minus_infty, -100)), BUILD_COMPLEX (minus_infty, minus_zero), 0, 0, 0); + + check_complex ("casinh (inf + 0 i) == inf + 0.0 i", FUNC(casinh) (BUILD_COMPLEX (plus_infty, 0)), BUILD_COMPLEX (plus_infty, 0.0), 0, 0, 0); + check_complex ("casinh (inf - 0 i) == inf - 0 i", FUNC(casinh) (BUILD_COMPLEX (plus_infty, minus_zero)), BUILD_COMPLEX (plus_infty, minus_zero), 0, 0, 0); + check_complex ("casinh (inf + 0.5 i) == inf + 0.0 i", FUNC(casinh) (BUILD_COMPLEX (plus_infty, 0.5)), BUILD_COMPLEX (plus_infty, 0.0), 0, 0, 0); + check_complex ("casinh (inf - 0.5 i) == inf - 0 i", FUNC(casinh) (BUILD_COMPLEX (plus_infty, -0.5)), BUILD_COMPLEX (plus_infty, minus_zero), 0, 0, 0); + + check_complex ("casinh (inf + NaN i) == inf + NaN i", FUNC(casinh) (BUILD_COMPLEX (plus_infty, nan_value)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, 0); + check_complex ("casinh (-inf + NaN i) == -inf + NaN i", FUNC(casinh) (BUILD_COMPLEX (minus_infty, nan_value)), BUILD_COMPLEX (minus_infty, nan_value), 0, 0, 0); + + check_complex ("casinh (NaN + 0 i) == NaN + 0.0 i", FUNC(casinh) (BUILD_COMPLEX (nan_value, 0)), BUILD_COMPLEX (nan_value, 0.0), 0, 0, 0); + check_complex ("casinh (NaN - 0 i) == NaN - 0 i", FUNC(casinh) (BUILD_COMPLEX (nan_value, minus_zero)), BUILD_COMPLEX (nan_value, minus_zero), 0, 0, 0); + + check_complex ("casinh (NaN + inf i) == inf + NaN i plus sign of zero/inf not specified", FUNC(casinh) (BUILD_COMPLEX (nan_value, plus_infty)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, IGNORE_ZERO_INF_SIGN); + check_complex ("casinh (NaN - inf i) == inf + NaN i plus sign of zero/inf not specified", FUNC(casinh) (BUILD_COMPLEX (nan_value, minus_infty)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, IGNORE_ZERO_INF_SIGN); + + check_complex ("casinh (10.5 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(casinh) (BUILD_COMPLEX (10.5, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + check_complex ("casinh (-10.5 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(casinh) (BUILD_COMPLEX (-10.5, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + + check_complex ("casinh (NaN + 0.75 i) == NaN + NaN i plus invalid exception allowed", FUNC(casinh) (BUILD_COMPLEX (nan_value, 0.75)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + check_complex ("casinh (-0.75 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(casinh) (BUILD_COMPLEX (-0.75, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + + check_complex ("casinh (NaN + NaN i) == NaN + NaN i", FUNC(casinh) (BUILD_COMPLEX (nan_value, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, 0); + + check_complex ("casinh (0.7 + 1.2 i) == 0.97865459559367387689317593222160964 + 0.91135418953156011567903546856170941 i", FUNC(casinh) (BUILD_COMPLEX (0.7L, 1.2L)), BUILD_COMPLEX (0.97865459559367387689317593222160964L, 0.91135418953156011567903546856170941L), DELTA262, 0, 0); + check_complex ("casinh (-2 - 3 i) == -1.9686379257930962917886650952454982 - 0.96465850440760279204541105949953237 i", FUNC(casinh) (BUILD_COMPLEX (-2, -3)), BUILD_COMPLEX (-1.9686379257930962917886650952454982L, -0.96465850440760279204541105949953237L), DELTA263, 0, 0); + + print_complex_max_error ("casinh", DELTAcasinh, 0); +} + + +static void +catan_test (void) +{ + errno = 0; + FUNC(catan) (BUILD_COMPLEX (0.7L, 1.2L)); + if (errno == ENOSYS) + /* Function not implemented. */ + return; + + init_max_error (); + + check_complex ("catan (0 + 0 i) == 0 + 0 i", FUNC(catan) (BUILD_COMPLEX (0, 0)), BUILD_COMPLEX (0, 0), 0, 0, 0); + check_complex ("catan (-0 + 0 i) == -0 + 0 i", FUNC(catan) (BUILD_COMPLEX (minus_zero, 0)), BUILD_COMPLEX (minus_zero, 0), 0, 0, 0); + check_complex ("catan (0 - 0 i) == 0 - 0 i", FUNC(catan) (BUILD_COMPLEX (0, minus_zero)), BUILD_COMPLEX (0, minus_zero), 0, 0, 0); + check_complex ("catan (-0 - 0 i) == -0 - 0 i", FUNC(catan) (BUILD_COMPLEX (minus_zero, minus_zero)), BUILD_COMPLEX (minus_zero, minus_zero), 0, 0, 0); + + check_complex ("catan (inf + inf i) == pi/2 + 0 i", FUNC(catan) (BUILD_COMPLEX (plus_infty, plus_infty)), BUILD_COMPLEX (M_PI_2l, 0), 0, 0, 0); + check_complex ("catan (inf - inf i) == pi/2 - 0 i", FUNC(catan) (BUILD_COMPLEX (plus_infty, minus_infty)), BUILD_COMPLEX (M_PI_2l, minus_zero), 0, 0, 0); + check_complex ("catan (-inf + inf i) == -pi/2 + 0 i", FUNC(catan) (BUILD_COMPLEX (minus_infty, plus_infty)), BUILD_COMPLEX (-M_PI_2l, 0), 0, 0, 0); + check_complex ("catan (-inf - inf i) == -pi/2 - 0 i", FUNC(catan) (BUILD_COMPLEX (minus_infty, minus_infty)), BUILD_COMPLEX (-M_PI_2l, minus_zero), 0, 0, 0); + + + check_complex ("catan (inf - 10.0 i) == pi/2 - 0 i", FUNC(catan) (BUILD_COMPLEX (plus_infty, -10.0)), BUILD_COMPLEX (M_PI_2l, minus_zero), 0, 0, 0); + check_complex ("catan (-inf - 10.0 i) == -pi/2 - 0 i", FUNC(catan) (BUILD_COMPLEX (minus_infty, -10.0)), BUILD_COMPLEX (-M_PI_2l, minus_zero), 0, 0, 0); + check_complex ("catan (inf - 0 i) == pi/2 - 0 i", FUNC(catan) (BUILD_COMPLEX (plus_infty, minus_zero)), BUILD_COMPLEX (M_PI_2l, minus_zero), 0, 0, 0); + check_complex ("catan (-inf - 0 i) == -pi/2 - 0 i", FUNC(catan) (BUILD_COMPLEX (minus_infty, minus_zero)), BUILD_COMPLEX (-M_PI_2l, minus_zero), 0, 0, 0); + check_complex ("catan (inf + 0.0 i) == pi/2 + 0 i", FUNC(catan) (BUILD_COMPLEX (plus_infty, 0.0)), BUILD_COMPLEX (M_PI_2l, 0), 0, 0, 0); + check_complex ("catan (-inf + 0.0 i) == -pi/2 + 0 i", FUNC(catan) (BUILD_COMPLEX (minus_infty, 0.0)), BUILD_COMPLEX (-M_PI_2l, 0), 0, 0, 0); + check_complex ("catan (inf + 0.1 i) == pi/2 + 0 i", FUNC(catan) (BUILD_COMPLEX (plus_infty, 0.1L)), BUILD_COMPLEX (M_PI_2l, 0), 0, 0, 0); + check_complex ("catan (-inf + 0.1 i) == -pi/2 + 0 i", FUNC(catan) (BUILD_COMPLEX (minus_infty, 0.1L)), BUILD_COMPLEX (-M_PI_2l, 0), 0, 0, 0); + + check_complex ("catan (0.0 - inf i) == pi/2 - 0 i", FUNC(catan) (BUILD_COMPLEX (0.0, minus_infty)), BUILD_COMPLEX (M_PI_2l, minus_zero), 0, 0, 0); + check_complex ("catan (-0 - inf i) == -pi/2 - 0 i", FUNC(catan) (BUILD_COMPLEX (minus_zero, minus_infty)), BUILD_COMPLEX (-M_PI_2l, minus_zero), 0, 0, 0); + check_complex ("catan (100.0 - inf i) == pi/2 - 0 i", FUNC(catan) (BUILD_COMPLEX (100.0, minus_infty)), BUILD_COMPLEX (M_PI_2l, minus_zero), 0, 0, 0); + check_complex ("catan (-100.0 - inf i) == -pi/2 - 0 i", FUNC(catan) (BUILD_COMPLEX (-100.0, minus_infty)), BUILD_COMPLEX (-M_PI_2l, minus_zero), 0, 0, 0); + + check_complex ("catan (0.0 + inf i) == pi/2 + 0 i", FUNC(catan) (BUILD_COMPLEX (0.0, plus_infty)), BUILD_COMPLEX (M_PI_2l, 0), 0, 0, 0); + check_complex ("catan (-0 + inf i) == -pi/2 + 0 i", FUNC(catan) (BUILD_COMPLEX (minus_zero, plus_infty)), BUILD_COMPLEX (-M_PI_2l, 0), 0, 0, 0); + check_complex ("catan (0.5 + inf i) == pi/2 + 0 i", FUNC(catan) (BUILD_COMPLEX (0.5, plus_infty)), BUILD_COMPLEX (M_PI_2l, 0), 0, 0, 0); + check_complex ("catan (-0.5 + inf i) == -pi/2 + 0 i", FUNC(catan) (BUILD_COMPLEX (-0.5, plus_infty)), BUILD_COMPLEX (-M_PI_2l, 0), 0, 0, 0); + + check_complex ("catan (NaN + 0.0 i) == NaN + 0 i", FUNC(catan) (BUILD_COMPLEX (nan_value, 0.0)), BUILD_COMPLEX (nan_value, 0), 0, 0, 0); + check_complex ("catan (NaN - 0 i) == NaN - 0 i", FUNC(catan) (BUILD_COMPLEX (nan_value, minus_zero)), BUILD_COMPLEX (nan_value, minus_zero), 0, 0, 0); + + check_complex ("catan (NaN + inf i) == NaN + 0 i", FUNC(catan) (BUILD_COMPLEX (nan_value, plus_infty)), BUILD_COMPLEX (nan_value, 0), 0, 0, 0); + check_complex ("catan (NaN - inf i) == NaN - 0 i", FUNC(catan) (BUILD_COMPLEX (nan_value, minus_infty)), BUILD_COMPLEX (nan_value, minus_zero), 0, 0, 0); + + check_complex ("catan (0.0 + NaN i) == NaN + NaN i", FUNC(catan) (BUILD_COMPLEX (0.0, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, 0); + check_complex ("catan (-0 + NaN i) == NaN + NaN i", FUNC(catan) (BUILD_COMPLEX (minus_zero, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, 0); + + check_complex ("catan (inf + NaN i) == pi/2 + 0 i plus sign of zero/inf not specified", FUNC(catan) (BUILD_COMPLEX (plus_infty, nan_value)), BUILD_COMPLEX (M_PI_2l, 0), 0, 0, IGNORE_ZERO_INF_SIGN); + check_complex ("catan (-inf + NaN i) == -pi/2 + 0 i plus sign of zero/inf not specified", FUNC(catan) (BUILD_COMPLEX (minus_infty, nan_value)), BUILD_COMPLEX (-M_PI_2l, 0), 0, 0, IGNORE_ZERO_INF_SIGN); + + check_complex ("catan (NaN + 10.5 i) == NaN + NaN i plus invalid exception allowed", FUNC(catan) (BUILD_COMPLEX (nan_value, 10.5)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + check_complex ("catan (NaN - 10.5 i) == NaN + NaN i plus invalid exception allowed", FUNC(catan) (BUILD_COMPLEX (nan_value, -10.5)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + + check_complex ("catan (0.75 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(catan) (BUILD_COMPLEX (0.75, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + check_complex ("catan (-0.75 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(catan) (BUILD_COMPLEX (-0.75, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + + check_complex ("catan (NaN + NaN i) == NaN + NaN i", FUNC(catan) (BUILD_COMPLEX (nan_value, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, 0); + + check_complex ("catan (0.7 + 1.2 i) == 1.0785743834118921877443707996386368 + 0.57705737765343067644394541889341712 i", FUNC(catan) (BUILD_COMPLEX (0.7L, 1.2L)), BUILD_COMPLEX (1.0785743834118921877443707996386368L, 0.57705737765343067644394541889341712L), DELTA301, 0, 0); + + check_complex ("catan (-2 - 3 i) == -1.4099210495965755225306193844604208 - 0.22907268296853876629588180294200276 i", FUNC(catan) (BUILD_COMPLEX (-2, -3)), BUILD_COMPLEX (-1.4099210495965755225306193844604208L, -0.22907268296853876629588180294200276L), DELTA302, 0, 0); + + print_complex_max_error ("catan", DELTAcatan, 0); +} + +static void +catanh_test (void) +{ + errno = 0; + FUNC(catanh) (BUILD_COMPLEX (0.7L, 1.2L)); + if (errno == ENOSYS) + /* Function not implemented. */ + return; + + init_max_error (); + + check_complex ("catanh (0 + 0 i) == 0.0 + 0.0 i", FUNC(catanh) (BUILD_COMPLEX (0, 0)), BUILD_COMPLEX (0.0, 0.0), 0, 0, 0); + check_complex ("catanh (-0 + 0 i) == -0 + 0.0 i", FUNC(catanh) (BUILD_COMPLEX (minus_zero, 0)), BUILD_COMPLEX (minus_zero, 0.0), 0, 0, 0); + check_complex ("catanh (0 - 0 i) == 0.0 - 0 i", FUNC(catanh) (BUILD_COMPLEX (0, minus_zero)), BUILD_COMPLEX (0.0, minus_zero), 0, 0, 0); + check_complex ("catanh (-0 - 0 i) == -0 - 0 i", FUNC(catanh) (BUILD_COMPLEX (minus_zero, minus_zero)), BUILD_COMPLEX (minus_zero, minus_zero), 0, 0, 0); + + check_complex ("catanh (inf + inf i) == 0.0 + pi/2 i", FUNC(catanh) (BUILD_COMPLEX (plus_infty, plus_infty)), BUILD_COMPLEX (0.0, M_PI_2l), 0, 0, 0); + check_complex ("catanh (inf - inf i) == 0.0 - pi/2 i", FUNC(catanh) (BUILD_COMPLEX (plus_infty, minus_infty)), BUILD_COMPLEX (0.0, -M_PI_2l), 0, 0, 0); + check_complex ("catanh (-inf + inf i) == -0 + pi/2 i", FUNC(catanh) (BUILD_COMPLEX (minus_infty, plus_infty)), BUILD_COMPLEX (minus_zero, M_PI_2l), 0, 0, 0); + check_complex ("catanh (-inf - inf i) == -0 - pi/2 i", FUNC(catanh) (BUILD_COMPLEX (minus_infty, minus_infty)), BUILD_COMPLEX (minus_zero, -M_PI_2l), 0, 0, 0); + + check_complex ("catanh (-10.0 + inf i) == -0 + pi/2 i", FUNC(catanh) (BUILD_COMPLEX (-10.0, plus_infty)), BUILD_COMPLEX (minus_zero, M_PI_2l), 0, 0, 0); + check_complex ("catanh (-10.0 - inf i) == -0 - pi/2 i", FUNC(catanh) (BUILD_COMPLEX (-10.0, minus_infty)), BUILD_COMPLEX (minus_zero, -M_PI_2l), 0, 0, 0); + check_complex ("catanh (-0 + inf i) == -0 + pi/2 i", FUNC(catanh) (BUILD_COMPLEX (minus_zero, plus_infty)), BUILD_COMPLEX (minus_zero, M_PI_2l), 0, 0, 0); + check_complex ("catanh (-0 - inf i) == -0 - pi/2 i", FUNC(catanh) (BUILD_COMPLEX (minus_zero, minus_infty)), BUILD_COMPLEX (minus_zero, -M_PI_2l), 0, 0, 0); + check_complex ("catanh (0 + inf i) == 0.0 + pi/2 i", FUNC(catanh) (BUILD_COMPLEX (0, plus_infty)), BUILD_COMPLEX (0.0, M_PI_2l), 0, 0, 0); + check_complex ("catanh (0 - inf i) == 0.0 - pi/2 i", FUNC(catanh) (BUILD_COMPLEX (0, minus_infty)), BUILD_COMPLEX (0.0, -M_PI_2l), 0, 0, 0); + check_complex ("catanh (0.1 + inf i) == 0.0 + pi/2 i", FUNC(catanh) (BUILD_COMPLEX (0.1L, plus_infty)), BUILD_COMPLEX (0.0, M_PI_2l), 0, 0, 0); + check_complex ("catanh (0.1 - inf i) == 0.0 - pi/2 i", FUNC(catanh) (BUILD_COMPLEX (0.1L, minus_infty)), BUILD_COMPLEX (0.0, -M_PI_2l), 0, 0, 0); + + check_complex ("catanh (-inf + 0 i) == -0 + pi/2 i", FUNC(catanh) (BUILD_COMPLEX (minus_infty, 0)), BUILD_COMPLEX (minus_zero, M_PI_2l), 0, 0, 0); + check_complex ("catanh (-inf - 0 i) == -0 - pi/2 i", FUNC(catanh) (BUILD_COMPLEX (minus_infty, minus_zero)), BUILD_COMPLEX (minus_zero, -M_PI_2l), 0, 0, 0); + check_complex ("catanh (-inf + 100 i) == -0 + pi/2 i", FUNC(catanh) (BUILD_COMPLEX (minus_infty, 100)), BUILD_COMPLEX (minus_zero, M_PI_2l), 0, 0, 0); + check_complex ("catanh (-inf - 100 i) == -0 - pi/2 i", FUNC(catanh) (BUILD_COMPLEX (minus_infty, -100)), BUILD_COMPLEX (minus_zero, -M_PI_2l), 0, 0, 0); + + check_complex ("catanh (inf + 0 i) == 0.0 + pi/2 i", FUNC(catanh) (BUILD_COMPLEX (plus_infty, 0)), BUILD_COMPLEX (0.0, M_PI_2l), 0, 0, 0); + check_complex ("catanh (inf - 0 i) == 0.0 - pi/2 i", FUNC(catanh) (BUILD_COMPLEX (plus_infty, minus_zero)), BUILD_COMPLEX (0.0, -M_PI_2l), 0, 0, 0); + check_complex ("catanh (inf + 0.5 i) == 0.0 + pi/2 i", FUNC(catanh) (BUILD_COMPLEX (plus_infty, 0.5)), BUILD_COMPLEX (0.0, M_PI_2l), 0, 0, 0); + check_complex ("catanh (inf - 0.5 i) == 0.0 - pi/2 i", FUNC(catanh) (BUILD_COMPLEX (plus_infty, -0.5)), BUILD_COMPLEX (0.0, -M_PI_2l), 0, 0, 0); + + check_complex ("catanh (0 + NaN i) == 0.0 + NaN i", FUNC(catanh) (BUILD_COMPLEX (0, nan_value)), BUILD_COMPLEX (0.0, nan_value), 0, 0, 0); + check_complex ("catanh (-0 + NaN i) == -0 + NaN i", FUNC(catanh) (BUILD_COMPLEX (minus_zero, nan_value)), BUILD_COMPLEX (minus_zero, nan_value), 0, 0, 0); + + check_complex ("catanh (inf + NaN i) == 0.0 + NaN i", FUNC(catanh) (BUILD_COMPLEX (plus_infty, nan_value)), BUILD_COMPLEX (0.0, nan_value), 0, 0, 0); + check_complex ("catanh (-inf + NaN i) == -0 + NaN i", FUNC(catanh) (BUILD_COMPLEX (minus_infty, nan_value)), BUILD_COMPLEX (minus_zero, nan_value), 0, 0, 0); + + check_complex ("catanh (NaN + 0 i) == NaN + NaN i", FUNC(catanh) (BUILD_COMPLEX (nan_value, 0)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, 0); + check_complex ("catanh (NaN - 0 i) == NaN + NaN i", FUNC(catanh) (BUILD_COMPLEX (nan_value, minus_zero)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, 0); + + check_complex ("catanh (NaN + inf i) == 0.0 + pi/2 i plus sign of zero/inf not specified", FUNC(catanh) (BUILD_COMPLEX (nan_value, plus_infty)), BUILD_COMPLEX (0.0, M_PI_2l), 0, 0, IGNORE_ZERO_INF_SIGN); + check_complex ("catanh (NaN - inf i) == 0.0 - pi/2 i plus sign of zero/inf not specified", FUNC(catanh) (BUILD_COMPLEX (nan_value, minus_infty)), BUILD_COMPLEX (0.0, -M_PI_2l), 0, 0, IGNORE_ZERO_INF_SIGN); + + check_complex ("catanh (10.5 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(catanh) (BUILD_COMPLEX (10.5, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + check_complex ("catanh (-10.5 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(catanh) (BUILD_COMPLEX (-10.5, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + + check_complex ("catanh (NaN + 0.75 i) == NaN + NaN i plus invalid exception allowed", FUNC(catanh) (BUILD_COMPLEX (nan_value, 0.75)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + check_complex ("catanh (NaN - 0.75 i) == NaN + NaN i plus invalid exception allowed", FUNC(catanh) (BUILD_COMPLEX (nan_value, -0.75)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + + check_complex ("catanh (NaN + NaN i) == NaN + NaN i", FUNC(catanh) (BUILD_COMPLEX (nan_value, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, 0); + + check_complex ("catanh (0.7 + 1.2 i) == 0.2600749516525135959200648705635915 + 0.97024030779509898497385130162655963 i", FUNC(catanh) (BUILD_COMPLEX (0.7L, 1.2L)), BUILD_COMPLEX (0.2600749516525135959200648705635915L, 0.97024030779509898497385130162655963L), DELTA340, 0, 0); + check_complex ("catanh (-2 - 3 i) == -0.14694666622552975204743278515471595 - 1.3389725222944935611241935759091443 i", FUNC(catanh) (BUILD_COMPLEX (-2, -3)), BUILD_COMPLEX (-0.14694666622552975204743278515471595L, -1.3389725222944935611241935759091443L), DELTA341, 0, 0); + + print_complex_max_error ("catanh", DELTAcatanh, 0); +} +#endif + +static void +cbrt_test (void) +{ + errno = 0; + FUNC(cbrt) (8); + if (errno == ENOSYS) + /* Function not implemented. */ + return; + + init_max_error (); + + check_float ("cbrt (0.0) == 0.0", FUNC(cbrt) (0.0), 0.0, 0, 0, 0); + check_float ("cbrt (-0) == -0", FUNC(cbrt) (minus_zero), minus_zero, 0, 0, 0); + + check_float ("cbrt (inf) == inf", FUNC(cbrt) (plus_infty), plus_infty, 0, 0, 0); + check_float ("cbrt (-inf) == -inf", FUNC(cbrt) (minus_infty), minus_infty, 0, 0, 0); + check_float ("cbrt (NaN) == NaN", FUNC(cbrt) (nan_value), nan_value, 0, 0, 0); + + check_float ("cbrt (-0.001) == -0.1", FUNC(cbrt) (-0.001L), -0.1L, DELTA347, 0, 0); + check_float ("cbrt (8) == 2", FUNC(cbrt) (8), 2, 0, 0, 0); + check_float ("cbrt (-27.0) == -3.0", FUNC(cbrt) (-27.0), -3.0, DELTA349, 0, 0); + check_float ("cbrt (0.970299) == 0.99", FUNC(cbrt) (0.970299L), 0.99L, DELTA350, 0, 0); + check_float ("cbrt (0.7) == 0.8879040017426007084", FUNC(cbrt) (0.7L), 0.8879040017426007084L, DELTA351, 0, 0); + + print_max_error ("cbrt", DELTAcbrt, 0); +} + +#if 0 /* XXX scp XXX */ +static void +ccos_test (void) +{ + errno = 0; + FUNC(ccos) (BUILD_COMPLEX (0, 0)); + if (errno == ENOSYS) + /* Function not implemented. */ + return; + + init_max_error (); + + check_complex ("ccos (0.0 + 0.0 i) == 1.0 - 0 i", FUNC(ccos) (BUILD_COMPLEX (0.0, 0.0)), BUILD_COMPLEX (1.0, minus_zero), 0, 0, 0); + check_complex ("ccos (-0 + 0.0 i) == 1.0 + 0.0 i", FUNC(ccos) (BUILD_COMPLEX (minus_zero, 0.0)), BUILD_COMPLEX (1.0, 0.0), 0, 0, 0); + check_complex ("ccos (0.0 - 0 i) == 1.0 + 0.0 i", FUNC(ccos) (BUILD_COMPLEX (0.0, minus_zero)), BUILD_COMPLEX (1.0, 0.0), 0, 0, 0); + check_complex ("ccos (-0 - 0 i) == 1.0 - 0 i", FUNC(ccos) (BUILD_COMPLEX (minus_zero, minus_zero)), BUILD_COMPLEX (1.0, minus_zero), 0, 0, 0); + + check_complex ("ccos (inf + 0.0 i) == NaN + 0.0 i plus invalid exception and sign of zero/inf not specified", FUNC(ccos) (BUILD_COMPLEX (plus_infty, 0.0)), BUILD_COMPLEX (nan_value, 0.0), 0, 0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN); + check_complex ("ccos (inf - 0 i) == NaN + 0.0 i plus invalid exception and sign of zero/inf not specified", FUNC(ccos) (BUILD_COMPLEX (plus_infty, minus_zero)), BUILD_COMPLEX (nan_value, 0.0), 0, 0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN); + check_complex ("ccos (-inf + 0.0 i) == NaN + 0.0 i plus invalid exception and sign of zero/inf not specified", FUNC(ccos) (BUILD_COMPLEX (minus_infty, 0.0)), BUILD_COMPLEX (nan_value, 0.0), 0, 0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN); + check_complex ("ccos (-inf - 0 i) == NaN + 0.0 i plus invalid exception and sign of zero/inf not specified", FUNC(ccos) (BUILD_COMPLEX (minus_infty, minus_zero)), BUILD_COMPLEX (nan_value, 0.0), 0, 0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN); + + check_complex ("ccos (0.0 + inf i) == inf - 0 i", FUNC(ccos) (BUILD_COMPLEX (0.0, plus_infty)), BUILD_COMPLEX (plus_infty, minus_zero), 0, 0, 0); + check_complex ("ccos (0.0 - inf i) == inf + 0.0 i", FUNC(ccos) (BUILD_COMPLEX (0.0, minus_infty)), BUILD_COMPLEX (plus_infty, 0.0), 0, 0, 0); + check_complex ("ccos (-0 + inf i) == inf + 0.0 i", FUNC(ccos) (BUILD_COMPLEX (minus_zero, plus_infty)), BUILD_COMPLEX (plus_infty, 0.0), 0, 0, 0); + check_complex ("ccos (-0 - inf i) == inf - 0 i", FUNC(ccos) (BUILD_COMPLEX (minus_zero, minus_infty)), BUILD_COMPLEX (plus_infty, minus_zero), 0, 0, 0); + + check_complex ("ccos (inf + inf i) == inf + NaN i plus invalid exception", FUNC(ccos) (BUILD_COMPLEX (plus_infty, plus_infty)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, INVALID_EXCEPTION); + check_complex ("ccos (-inf + inf i) == inf + NaN i plus invalid exception", FUNC(ccos) (BUILD_COMPLEX (minus_infty, plus_infty)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, INVALID_EXCEPTION); + check_complex ("ccos (inf - inf i) == inf + NaN i plus invalid exception", FUNC(ccos) (BUILD_COMPLEX (plus_infty, minus_infty)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, INVALID_EXCEPTION); + check_complex ("ccos (-inf - inf i) == inf + NaN i plus invalid exception", FUNC(ccos) (BUILD_COMPLEX (minus_infty, minus_infty)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, INVALID_EXCEPTION); + + check_complex ("ccos (4.625 + inf i) == -inf + inf i", FUNC(ccos) (BUILD_COMPLEX (4.625, plus_infty)), BUILD_COMPLEX (minus_infty, plus_infty), 0, 0, 0); + check_complex ("ccos (4.625 - inf i) == -inf - inf i", FUNC(ccos) (BUILD_COMPLEX (4.625, minus_infty)), BUILD_COMPLEX (minus_infty, minus_infty), 0, 0, 0); + check_complex ("ccos (-4.625 + inf i) == -inf - inf i", FUNC(ccos) (BUILD_COMPLEX (-4.625, plus_infty)), BUILD_COMPLEX (minus_infty, minus_infty), 0, 0, 0); + check_complex ("ccos (-4.625 - inf i) == -inf + inf i", FUNC(ccos) (BUILD_COMPLEX (-4.625, minus_infty)), BUILD_COMPLEX (minus_infty, plus_infty), 0, 0, 0); + + check_complex ("ccos (inf + 6.75 i) == NaN + NaN i plus invalid exception", FUNC(ccos) (BUILD_COMPLEX (plus_infty, 6.75)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); + check_complex ("ccos (inf - 6.75 i) == NaN + NaN i plus invalid exception", FUNC(ccos) (BUILD_COMPLEX (plus_infty, -6.75)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); + check_complex ("ccos (-inf + 6.75 i) == NaN + NaN i plus invalid exception", FUNC(ccos) (BUILD_COMPLEX (minus_infty, 6.75)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); + check_complex ("ccos (-inf - 6.75 i) == NaN + NaN i plus invalid exception", FUNC(ccos) (BUILD_COMPLEX (minus_infty, -6.75)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); + + check_complex ("ccos (NaN + 0.0 i) == NaN + 0.0 i plus sign of zero/inf not specified", FUNC(ccos) (BUILD_COMPLEX (nan_value, 0.0)), BUILD_COMPLEX (nan_value, 0.0), 0, 0, IGNORE_ZERO_INF_SIGN); + check_complex ("ccos (NaN - 0 i) == NaN + 0.0 i plus sign of zero/inf not specified", FUNC(ccos) (BUILD_COMPLEX (nan_value, minus_zero)), BUILD_COMPLEX (nan_value, 0.0), 0, 0, IGNORE_ZERO_INF_SIGN); + + check_complex ("ccos (NaN + inf i) == inf + NaN i", FUNC(ccos) (BUILD_COMPLEX (nan_value, plus_infty)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, 0); + check_complex ("ccos (NaN - inf i) == inf + NaN i", FUNC(ccos) (BUILD_COMPLEX (nan_value, minus_infty)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, 0); + + check_complex ("ccos (NaN + 9.0 i) == NaN + NaN i plus invalid exception allowed", FUNC(ccos) (BUILD_COMPLEX (nan_value, 9.0)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + check_complex ("ccos (NaN - 9.0 i) == NaN + NaN i plus invalid exception allowed", FUNC(ccos) (BUILD_COMPLEX (nan_value, -9.0)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + + check_complex ("ccos (0.0 + NaN i) == NaN + 0.0 i plus sign of zero/inf not specified", FUNC(ccos) (BUILD_COMPLEX (0.0, nan_value)), BUILD_COMPLEX (nan_value, 0.0), 0, 0, IGNORE_ZERO_INF_SIGN); + check_complex ("ccos (-0 + NaN i) == NaN + 0.0 i plus sign of zero/inf not specified", FUNC(ccos) (BUILD_COMPLEX (minus_zero, nan_value)), BUILD_COMPLEX (nan_value, 0.0), 0, 0, IGNORE_ZERO_INF_SIGN); + + check_complex ("ccos (10.0 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(ccos) (BUILD_COMPLEX (10.0, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + check_complex ("ccos (-10.0 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(ccos) (BUILD_COMPLEX (-10.0, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + + check_complex ("ccos (inf + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(ccos) (BUILD_COMPLEX (plus_infty, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + check_complex ("ccos (-inf + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(ccos) (BUILD_COMPLEX (minus_infty, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + + check_complex ("ccos (NaN + NaN i) == NaN + NaN i", FUNC(ccos) (BUILD_COMPLEX (nan_value, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, 0); + + check_complex ("ccos (0.7 + 1.2 i) == 1.3848657645312111080 - 0.97242170335830028619 i", FUNC(ccos) (BUILD_COMPLEX (0.7L, 1.2L)), BUILD_COMPLEX (1.3848657645312111080L, -0.97242170335830028619L), DELTA389, 0, 0); + + check_complex ("ccos (-2 - 3 i) == -4.1896256909688072301 - 9.1092278937553365979 i", FUNC(ccos) (BUILD_COMPLEX (-2, -3)), BUILD_COMPLEX (-4.1896256909688072301L, -9.1092278937553365979L), DELTA390, 0, 0); + + print_complex_max_error ("ccos", DELTAccos, 0); +} + + +static void +ccosh_test (void) +{ + errno = 0; + FUNC(ccosh) (BUILD_COMPLEX (0.7L, 1.2L)); + if (errno == ENOSYS) + /* Function not implemented. */ + return; + + init_max_error (); + + check_complex ("ccosh (0.0 + 0.0 i) == 1.0 + 0.0 i", FUNC(ccosh) (BUILD_COMPLEX (0.0, 0.0)), BUILD_COMPLEX (1.0, 0.0), 0, 0, 0); + check_complex ("ccosh (-0 + 0.0 i) == 1.0 - 0 i", FUNC(ccosh) (BUILD_COMPLEX (minus_zero, 0.0)), BUILD_COMPLEX (1.0, minus_zero), 0, 0, 0); + check_complex ("ccosh (0.0 - 0 i) == 1.0 - 0 i", FUNC(ccosh) (BUILD_COMPLEX (0.0, minus_zero)), BUILD_COMPLEX (1.0, minus_zero), 0, 0, 0); + check_complex ("ccosh (-0 - 0 i) == 1.0 + 0.0 i", FUNC(ccosh) (BUILD_COMPLEX (minus_zero, minus_zero)), BUILD_COMPLEX (1.0, 0.0), 0, 0, 0); + + check_complex ("ccosh (0.0 + inf i) == NaN + 0.0 i plus invalid exception and sign of zero/inf not specified", FUNC(ccosh) (BUILD_COMPLEX (0.0, plus_infty)), BUILD_COMPLEX (nan_value, 0.0), 0, 0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN); + check_complex ("ccosh (-0 + inf i) == NaN + 0.0 i plus invalid exception and sign of zero/inf not specified", FUNC(ccosh) (BUILD_COMPLEX (minus_zero, plus_infty)), BUILD_COMPLEX (nan_value, 0.0), 0, 0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN); + check_complex ("ccosh (0.0 - inf i) == NaN + 0.0 i plus invalid exception and sign of zero/inf not specified", FUNC(ccosh) (BUILD_COMPLEX (0.0, minus_infty)), BUILD_COMPLEX (nan_value, 0.0), 0, 0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN); + check_complex ("ccosh (-0 - inf i) == NaN + 0.0 i plus invalid exception and sign of zero/inf not specified", FUNC(ccosh) (BUILD_COMPLEX (minus_zero, minus_infty)), BUILD_COMPLEX (nan_value, 0.0), 0, 0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN); + + check_complex ("ccosh (inf + 0.0 i) == inf + 0.0 i", FUNC(ccosh) (BUILD_COMPLEX (plus_infty, 0.0)), BUILD_COMPLEX (plus_infty, 0.0), 0, 0, 0); + check_complex ("ccosh (-inf + 0.0 i) == inf - 0 i", FUNC(ccosh) (BUILD_COMPLEX (minus_infty, 0.0)), BUILD_COMPLEX (plus_infty, minus_zero), 0, 0, 0); + check_complex ("ccosh (inf - 0 i) == inf - 0 i", FUNC(ccosh) (BUILD_COMPLEX (plus_infty, minus_zero)), BUILD_COMPLEX (plus_infty, minus_zero), 0, 0, 0); + check_complex ("ccosh (-inf - 0 i) == inf + 0.0 i", FUNC(ccosh) (BUILD_COMPLEX (minus_infty, minus_zero)), BUILD_COMPLEX (plus_infty, 0.0), 0, 0, 0); + + check_complex ("ccosh (inf + inf i) == inf + NaN i plus invalid exception", FUNC(ccosh) (BUILD_COMPLEX (plus_infty, plus_infty)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, INVALID_EXCEPTION); + check_complex ("ccosh (-inf + inf i) == inf + NaN i plus invalid exception", FUNC(ccosh) (BUILD_COMPLEX (minus_infty, plus_infty)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, INVALID_EXCEPTION); + check_complex ("ccosh (inf - inf i) == inf + NaN i plus invalid exception", FUNC(ccosh) (BUILD_COMPLEX (plus_infty, minus_infty)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, INVALID_EXCEPTION); + check_complex ("ccosh (-inf - inf i) == inf + NaN i plus invalid exception", FUNC(ccosh) (BUILD_COMPLEX (minus_infty, minus_infty)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, INVALID_EXCEPTION); + + check_complex ("ccosh (inf + 4.625 i) == -inf - inf i", FUNC(ccosh) (BUILD_COMPLEX (plus_infty, 4.625)), BUILD_COMPLEX (minus_infty, minus_infty), 0, 0, 0); + check_complex ("ccosh (-inf + 4.625 i) == -inf + inf i", FUNC(ccosh) (BUILD_COMPLEX (minus_infty, 4.625)), BUILD_COMPLEX (minus_infty, plus_infty), 0, 0, 0); + check_complex ("ccosh (inf - 4.625 i) == -inf + inf i", FUNC(ccosh) (BUILD_COMPLEX (plus_infty, -4.625)), BUILD_COMPLEX (minus_infty, plus_infty), 0, 0, 0); + check_complex ("ccosh (-inf - 4.625 i) == -inf - inf i", FUNC(ccosh) (BUILD_COMPLEX (minus_infty, -4.625)), BUILD_COMPLEX (minus_infty, minus_infty), 0, 0, 0); + + check_complex ("ccosh (6.75 + inf i) == NaN + NaN i plus invalid exception", FUNC(ccosh) (BUILD_COMPLEX (6.75, plus_infty)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); + check_complex ("ccosh (-6.75 + inf i) == NaN + NaN i plus invalid exception", FUNC(ccosh) (BUILD_COMPLEX (-6.75, plus_infty)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); + check_complex ("ccosh (6.75 - inf i) == NaN + NaN i plus invalid exception", FUNC(ccosh) (BUILD_COMPLEX (6.75, minus_infty)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); + check_complex ("ccosh (-6.75 - inf i) == NaN + NaN i plus invalid exception", FUNC(ccosh) (BUILD_COMPLEX (-6.75, minus_infty)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); + + check_complex ("ccosh (0.0 + NaN i) == NaN + 0.0 i plus sign of zero/inf not specified", FUNC(ccosh) (BUILD_COMPLEX (0.0, nan_value)), BUILD_COMPLEX (nan_value, 0.0), 0, 0, IGNORE_ZERO_INF_SIGN); + check_complex ("ccosh (-0 + NaN i) == NaN + 0.0 i plus sign of zero/inf not specified", FUNC(ccosh) (BUILD_COMPLEX (minus_zero, nan_value)), BUILD_COMPLEX (nan_value, 0.0), 0, 0, IGNORE_ZERO_INF_SIGN); + + check_complex ("ccosh (inf + NaN i) == inf + NaN i", FUNC(ccosh) (BUILD_COMPLEX (plus_infty, nan_value)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, 0); + check_complex ("ccosh (-inf + NaN i) == inf + NaN i", FUNC(ccosh) (BUILD_COMPLEX (minus_infty, nan_value)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, 0); + + check_complex ("ccosh (9.0 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(ccosh) (BUILD_COMPLEX (9.0, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + check_complex ("ccosh (-9.0 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(ccosh) (BUILD_COMPLEX (-9.0, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + + check_complex ("ccosh (NaN + 0.0 i) == NaN + 0.0 i plus sign of zero/inf not specified", FUNC(ccosh) (BUILD_COMPLEX (nan_value, 0.0)), BUILD_COMPLEX (nan_value, 0.0), 0, 0, IGNORE_ZERO_INF_SIGN); + check_complex ("ccosh (NaN - 0 i) == NaN + 0.0 i plus sign of zero/inf not specified", FUNC(ccosh) (BUILD_COMPLEX (nan_value, minus_zero)), BUILD_COMPLEX (nan_value, 0.0), 0, 0, IGNORE_ZERO_INF_SIGN); + + check_complex ("ccosh (NaN + 10.0 i) == NaN + NaN i plus invalid exception allowed", FUNC(ccosh) (BUILD_COMPLEX (nan_value, 10.0)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + check_complex ("ccosh (NaN - 10.0 i) == NaN + NaN i plus invalid exception allowed", FUNC(ccosh) (BUILD_COMPLEX (nan_value, -10.0)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + + check_complex ("ccosh (NaN + inf i) == NaN + NaN i plus invalid exception allowed", FUNC(ccosh) (BUILD_COMPLEX (nan_value, plus_infty)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + check_complex ("ccosh (NaN - inf i) == NaN + NaN i plus invalid exception allowed", FUNC(ccosh) (BUILD_COMPLEX (nan_value, minus_infty)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + + check_complex ("ccosh (NaN + NaN i) == NaN + NaN i", FUNC(ccosh) (BUILD_COMPLEX (nan_value, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, 0); + + check_complex ("ccosh (0.7 + 1.2 i) == 0.4548202223691477654 + 0.7070296600921537682 i", FUNC(ccosh) (BUILD_COMPLEX (0.7L, 1.2L)), BUILD_COMPLEX (0.4548202223691477654L, 0.7070296600921537682L), DELTA428, 0, 0); + + check_complex ("ccosh (-2 - 3 i) == -3.7245455049153225654 + 0.5118225699873846088 i", FUNC(ccosh) (BUILD_COMPLEX (-2, -3)), BUILD_COMPLEX (-3.7245455049153225654L, 0.5118225699873846088L), DELTA429, 0, 0); + + print_complex_max_error ("ccosh", DELTAccosh, 0); +} +#endif + + +static void +ceil_test (void) +{ + init_max_error (); + + check_float ("ceil (0.0) == 0.0", FUNC(ceil) (0.0), 0.0, 0, 0, 0); + check_float ("ceil (-0) == -0", FUNC(ceil) (minus_zero), minus_zero, 0, 0, 0); + check_float ("ceil (inf) == inf", FUNC(ceil) (plus_infty), plus_infty, 0, 0, 0); + check_float ("ceil (-inf) == -inf", FUNC(ceil) (minus_infty), minus_infty, 0, 0, 0); + check_float ("ceil (NaN) == NaN", FUNC(ceil) (nan_value), nan_value, 0, 0, 0); + + check_float ("ceil (pi) == 4.0", FUNC(ceil) (M_PIl), 4.0, 0, 0, 0); + check_float ("ceil (-pi) == -3.0", FUNC(ceil) (-M_PIl), -3.0, 0, 0, 0); + + print_max_error ("ceil", 0, 0); +} + + +#if 0 /* XXX scp XXX */ +static void +cexp_test (void) +{ + errno = 0; + FUNC(cexp) (BUILD_COMPLEX (0, 0)); + if (errno == ENOSYS) + /* Function not implemented. */ + return; + + init_max_error (); + + check_complex ("cexp (+0 + +0 i) == 1 + 0.0 i", FUNC(cexp) (BUILD_COMPLEX (plus_zero, plus_zero)), BUILD_COMPLEX (1, 0.0), 0, 0, 0); + check_complex ("cexp (-0 + +0 i) == 1 + 0.0 i", FUNC(cexp) (BUILD_COMPLEX (minus_zero, plus_zero)), BUILD_COMPLEX (1, 0.0), 0, 0, 0); + check_complex ("cexp (+0 - 0 i) == 1 - 0 i", FUNC(cexp) (BUILD_COMPLEX (plus_zero, minus_zero)), BUILD_COMPLEX (1, minus_zero), 0, 0, 0); + check_complex ("cexp (-0 - 0 i) == 1 - 0 i", FUNC(cexp) (BUILD_COMPLEX (minus_zero, minus_zero)), BUILD_COMPLEX (1, minus_zero), 0, 0, 0); + + check_complex ("cexp (inf + +0 i) == inf + 0.0 i", FUNC(cexp) (BUILD_COMPLEX (plus_infty, plus_zero)), BUILD_COMPLEX (plus_infty, 0.0), 0, 0, 0); + check_complex ("cexp (inf - 0 i) == inf - 0 i", FUNC(cexp) (BUILD_COMPLEX (plus_infty, minus_zero)), BUILD_COMPLEX (plus_infty, minus_zero), 0, 0, 0); + + check_complex ("cexp (-inf + +0 i) == 0.0 + 0.0 i", FUNC(cexp) (BUILD_COMPLEX (minus_infty, plus_zero)), BUILD_COMPLEX (0.0, 0.0), 0, 0, 0); + check_complex ("cexp (-inf - 0 i) == 0.0 - 0 i", FUNC(cexp) (BUILD_COMPLEX (minus_infty, minus_zero)), BUILD_COMPLEX (0.0, minus_zero), 0, 0, 0); + + check_complex ("cexp (0.0 + inf i) == NaN + NaN i plus invalid exception", FUNC(cexp) (BUILD_COMPLEX (0.0, plus_infty)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); + check_complex ("cexp (-0 + inf i) == NaN + NaN i plus invalid exception", FUNC(cexp) (BUILD_COMPLEX (minus_zero, plus_infty)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); + + check_complex ("cexp (0.0 - inf i) == NaN + NaN i plus invalid exception", FUNC(cexp) (BUILD_COMPLEX (0.0, minus_infty)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); + check_complex ("cexp (-0 - inf i) == NaN + NaN i plus invalid exception", FUNC(cexp) (BUILD_COMPLEX (minus_zero, minus_infty)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); + + check_complex ("cexp (100.0 + inf i) == NaN + NaN i plus invalid exception", FUNC(cexp) (BUILD_COMPLEX (100.0, plus_infty)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); + check_complex ("cexp (-100.0 + inf i) == NaN + NaN i plus invalid exception", FUNC(cexp) (BUILD_COMPLEX (-100.0, plus_infty)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); + + check_complex ("cexp (100.0 - inf i) == NaN + NaN i plus invalid exception", FUNC(cexp) (BUILD_COMPLEX (100.0, minus_infty)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); + check_complex ("cexp (-100.0 - inf i) == NaN + NaN i plus invalid exception", FUNC(cexp) (BUILD_COMPLEX (-100.0, minus_infty)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); + + check_complex ("cexp (-inf + 2.0 i) == -0 + 0.0 i", FUNC(cexp) (BUILD_COMPLEX (minus_infty, 2.0)), BUILD_COMPLEX (minus_zero, 0.0), 0, 0, 0); + check_complex ("cexp (-inf + 4.0 i) == -0 - 0 i", FUNC(cexp) (BUILD_COMPLEX (minus_infty, 4.0)), BUILD_COMPLEX (minus_zero, minus_zero), 0, 0, 0); + check_complex ("cexp (inf + 2.0 i) == -inf + inf i", FUNC(cexp) (BUILD_COMPLEX (plus_infty, 2.0)), BUILD_COMPLEX (minus_infty, plus_infty), 0, 0, 0); + check_complex ("cexp (inf + 4.0 i) == -inf - inf i", FUNC(cexp) (BUILD_COMPLEX (plus_infty, 4.0)), BUILD_COMPLEX (minus_infty, minus_infty), 0, 0, 0); + + check_complex ("cexp (inf + inf i) == inf + NaN i plus invalid exception and sign of zero/inf not specified", FUNC(cexp) (BUILD_COMPLEX (plus_infty, plus_infty)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN); + check_complex ("cexp (inf - inf i) == inf + NaN i plus invalid exception and sign of zero/inf not specified", FUNC(cexp) (BUILD_COMPLEX (plus_infty, minus_infty)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN); + + check_complex ("cexp (-inf + inf i) == 0.0 + 0.0 i plus sign of zero/inf not specified", FUNC(cexp) (BUILD_COMPLEX (minus_infty, plus_infty)), BUILD_COMPLEX (0.0, 0.0), 0, 0, IGNORE_ZERO_INF_SIGN); + check_complex ("cexp (-inf - inf i) == 0.0 - 0 i plus sign of zero/inf not specified", FUNC(cexp) (BUILD_COMPLEX (minus_infty, minus_infty)), BUILD_COMPLEX (0.0, minus_zero), 0, 0, IGNORE_ZERO_INF_SIGN); + + check_complex ("cexp (-inf + NaN i) == 0 + 0 i plus sign of zero/inf not specified", FUNC(cexp) (BUILD_COMPLEX (minus_infty, nan_value)), BUILD_COMPLEX (0, 0), 0, 0, IGNORE_ZERO_INF_SIGN); + + check_complex ("cexp (inf + NaN i) == inf + NaN i", FUNC(cexp) (BUILD_COMPLEX (plus_infty, nan_value)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, 0); + + check_complex ("cexp (NaN + 0.0 i) == NaN + NaN i plus invalid exception allowed", FUNC(cexp) (BUILD_COMPLEX (nan_value, 0.0)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + check_complex ("cexp (NaN + 1.0 i) == NaN + NaN i plus invalid exception allowed", FUNC(cexp) (BUILD_COMPLEX (nan_value, 1.0)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + + check_complex ("cexp (NaN + inf i) == NaN + NaN i plus invalid exception allowed", FUNC(cexp) (BUILD_COMPLEX (nan_value, plus_infty)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + check_complex ("cexp (0 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(cexp) (BUILD_COMPLEX (0, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + check_complex ("cexp (1 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(cexp) (BUILD_COMPLEX (1, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + check_complex ("cexp (NaN + NaN i) == NaN + NaN i", FUNC(cexp) (BUILD_COMPLEX (nan_value, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, 0); + + check_complex ("cexp (0.7 + 1.2 i) == 0.72969890915032360123451688642930727 + 1.8768962328348102821139467908203072 i", FUNC(cexp) (BUILD_COMPLEX (0.7L, 1.2L)), BUILD_COMPLEX (0.72969890915032360123451688642930727L, 1.8768962328348102821139467908203072L), DELTA469, 0, 0); + check_complex ("cexp (-2.0 - 3.0 i) == -0.13398091492954261346140525546115575 - 0.019098516261135196432576240858800925 i", FUNC(cexp) (BUILD_COMPLEX (-2.0, -3.0)), BUILD_COMPLEX (-0.13398091492954261346140525546115575L, -0.019098516261135196432576240858800925L), DELTA470, 0, 0); + + print_complex_max_error ("cexp", DELTAcexp, 0); +} + +static void +cimag_test (void) +{ + init_max_error (); + check_float ("cimag (1.0 + 0.0 i) == 0.0", FUNC(cimag) (BUILD_COMPLEX (1.0, 0.0)), 0.0, 0, 0, 0); + check_float ("cimag (1.0 - 0 i) == -0", FUNC(cimag) (BUILD_COMPLEX (1.0, minus_zero)), minus_zero, 0, 0, 0); + check_float ("cimag (1.0 + NaN i) == NaN", FUNC(cimag) (BUILD_COMPLEX (1.0, nan_value)), nan_value, 0, 0, 0); + check_float ("cimag (NaN + NaN i) == NaN", FUNC(cimag) (BUILD_COMPLEX (nan_value, nan_value)), nan_value, 0, 0, 0); + check_float ("cimag (1.0 + inf i) == inf", FUNC(cimag) (BUILD_COMPLEX (1.0, plus_infty)), plus_infty, 0, 0, 0); + check_float ("cimag (1.0 - inf i) == -inf", FUNC(cimag) (BUILD_COMPLEX (1.0, minus_infty)), minus_infty, 0, 0, 0); + check_float ("cimag (2.0 + 3.0 i) == 3.0", FUNC(cimag) (BUILD_COMPLEX (2.0, 3.0)), 3.0, 0, 0, 0); + + print_max_error ("cimag", 0, 0); +} + +static void +clog_test (void) +{ + errno = 0; + FUNC(clog) (BUILD_COMPLEX (-2, -3)); + if (errno == ENOSYS) + /* Function not implemented. */ + return; + + init_max_error (); + + check_complex ("clog (-0 + 0 i) == -inf + pi i plus division by zero exception", FUNC(clog) (BUILD_COMPLEX (minus_zero, 0)), BUILD_COMPLEX (minus_infty, M_PIl), 0, 0, DIVIDE_BY_ZERO_EXCEPTION); + check_complex ("clog (-0 - 0 i) == -inf - pi i plus division by zero exception", FUNC(clog) (BUILD_COMPLEX (minus_zero, minus_zero)), BUILD_COMPLEX (minus_infty, -M_PIl), 0, 0, DIVIDE_BY_ZERO_EXCEPTION); + + check_complex ("clog (0 + 0 i) == -inf + 0.0 i plus division by zero exception", FUNC(clog) (BUILD_COMPLEX (0, 0)), BUILD_COMPLEX (minus_infty, 0.0), 0, 0, DIVIDE_BY_ZERO_EXCEPTION); + check_complex ("clog (0 - 0 i) == -inf - 0 i plus division by zero exception", FUNC(clog) (BUILD_COMPLEX (0, minus_zero)), BUILD_COMPLEX (minus_infty, minus_zero), 0, 0, DIVIDE_BY_ZERO_EXCEPTION); + + check_complex ("clog (-inf + inf i) == inf + 3/4 pi i", FUNC(clog) (BUILD_COMPLEX (minus_infty, plus_infty)), BUILD_COMPLEX (plus_infty, M_PI_34l), 0, 0, 0); + check_complex ("clog (-inf - inf i) == inf - 3/4 pi i", FUNC(clog) (BUILD_COMPLEX (minus_infty, minus_infty)), BUILD_COMPLEX (plus_infty, -M_PI_34l), 0, 0, 0); + + check_complex ("clog (inf + inf i) == inf + pi/4 i", FUNC(clog) (BUILD_COMPLEX (plus_infty, plus_infty)), BUILD_COMPLEX (plus_infty, M_PI_4l), 0, 0, 0); + check_complex ("clog (inf - inf i) == inf - pi/4 i", FUNC(clog) (BUILD_COMPLEX (plus_infty, minus_infty)), BUILD_COMPLEX (plus_infty, -M_PI_4l), 0, 0, 0); + + check_complex ("clog (0 + inf i) == inf + pi/2 i", FUNC(clog) (BUILD_COMPLEX (0, plus_infty)), BUILD_COMPLEX (plus_infty, M_PI_2l), 0, 0, 0); + check_complex ("clog (3 + inf i) == inf + pi/2 i", FUNC(clog) (BUILD_COMPLEX (3, plus_infty)), BUILD_COMPLEX (plus_infty, M_PI_2l), 0, 0, 0); + check_complex ("clog (-0 + inf i) == inf + pi/2 i", FUNC(clog) (BUILD_COMPLEX (minus_zero, plus_infty)), BUILD_COMPLEX (plus_infty, M_PI_2l), 0, 0, 0); + check_complex ("clog (-3 + inf i) == inf + pi/2 i", FUNC(clog) (BUILD_COMPLEX (-3, plus_infty)), BUILD_COMPLEX (plus_infty, M_PI_2l), 0, 0, 0); + check_complex ("clog (0 - inf i) == inf - pi/2 i", FUNC(clog) (BUILD_COMPLEX (0, minus_infty)), BUILD_COMPLEX (plus_infty, -M_PI_2l), 0, 0, 0); + check_complex ("clog (3 - inf i) == inf - pi/2 i", FUNC(clog) (BUILD_COMPLEX (3, minus_infty)), BUILD_COMPLEX (plus_infty, -M_PI_2l), 0, 0, 0); + check_complex ("clog (-0 - inf i) == inf - pi/2 i", FUNC(clog) (BUILD_COMPLEX (minus_zero, minus_infty)), BUILD_COMPLEX (plus_infty, -M_PI_2l), 0, 0, 0); + check_complex ("clog (-3 - inf i) == inf - pi/2 i", FUNC(clog) (BUILD_COMPLEX (-3, minus_infty)), BUILD_COMPLEX (plus_infty, -M_PI_2l), 0, 0, 0); + + check_complex ("clog (-inf + 0 i) == inf + pi i", FUNC(clog) (BUILD_COMPLEX (minus_infty, 0)), BUILD_COMPLEX (plus_infty, M_PIl), 0, 0, 0); + check_complex ("clog (-inf + 1 i) == inf + pi i", FUNC(clog) (BUILD_COMPLEX (minus_infty, 1)), BUILD_COMPLEX (plus_infty, M_PIl), 0, 0, 0); + check_complex ("clog (-inf - 0 i) == inf - pi i", FUNC(clog) (BUILD_COMPLEX (minus_infty, minus_zero)), BUILD_COMPLEX (plus_infty, -M_PIl), 0, 0, 0); + check_complex ("clog (-inf - 1 i) == inf - pi i", FUNC(clog) (BUILD_COMPLEX (minus_infty, -1)), BUILD_COMPLEX (plus_infty, -M_PIl), 0, 0, 0); + + check_complex ("clog (inf + 0 i) == inf + 0.0 i", FUNC(clog) (BUILD_COMPLEX (plus_infty, 0)), BUILD_COMPLEX (plus_infty, 0.0), 0, 0, 0); + check_complex ("clog (inf + 1 i) == inf + 0.0 i", FUNC(clog) (BUILD_COMPLEX (plus_infty, 1)), BUILD_COMPLEX (plus_infty, 0.0), 0, 0, 0); + check_complex ("clog (inf - 0 i) == inf - 0 i", FUNC(clog) (BUILD_COMPLEX (plus_infty, minus_zero)), BUILD_COMPLEX (plus_infty, minus_zero), 0, 0, 0); + check_complex ("clog (inf - 1 i) == inf - 0 i", FUNC(clog) (BUILD_COMPLEX (plus_infty, -1)), BUILD_COMPLEX (plus_infty, minus_zero), 0, 0, 0); + + check_complex ("clog (inf + NaN i) == inf + NaN i", FUNC(clog) (BUILD_COMPLEX (plus_infty, nan_value)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, 0); + check_complex ("clog (-inf + NaN i) == inf + NaN i", FUNC(clog) (BUILD_COMPLEX (minus_infty, nan_value)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, 0); + + check_complex ("clog (NaN + inf i) == inf + NaN i", FUNC(clog) (BUILD_COMPLEX (nan_value, plus_infty)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, 0); + check_complex ("clog (NaN - inf i) == inf + NaN i", FUNC(clog) (BUILD_COMPLEX (nan_value, minus_infty)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, 0); + + check_complex ("clog (0 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(clog) (BUILD_COMPLEX (0, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + check_complex ("clog (3 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(clog) (BUILD_COMPLEX (3, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + check_complex ("clog (-0 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(clog) (BUILD_COMPLEX (minus_zero, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + check_complex ("clog (-3 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(clog) (BUILD_COMPLEX (-3, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + + check_complex ("clog (NaN + 0 i) == NaN + NaN i plus invalid exception allowed", FUNC(clog) (BUILD_COMPLEX (nan_value, 0)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + check_complex ("clog (NaN + 5 i) == NaN + NaN i plus invalid exception allowed", FUNC(clog) (BUILD_COMPLEX (nan_value, 5)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + check_complex ("clog (NaN - 0 i) == NaN + NaN i plus invalid exception allowed", FUNC(clog) (BUILD_COMPLEX (nan_value, minus_zero)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + check_complex ("clog (NaN - 5 i) == NaN + NaN i plus invalid exception allowed", FUNC(clog) (BUILD_COMPLEX (nan_value, -5)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + + check_complex ("clog (NaN + NaN i) == NaN + NaN i", FUNC(clog) (BUILD_COMPLEX (nan_value, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, 0); + check_complex ("clog (-2 - 3 i) == 1.2824746787307683680267437207826593 - 2.1587989303424641704769327722648368 i", FUNC(clog) (BUILD_COMPLEX (-2, -3)), BUILD_COMPLEX (1.2824746787307683680267437207826593L, -2.1587989303424641704769327722648368L), DELTA515, 0, 0); + + print_complex_max_error ("clog", DELTAclog, 0); +} + + +static void +clog10_test (void) +{ + errno = 0; + FUNC(clog10) (BUILD_COMPLEX (0.7L, 1.2L)); + if (errno == ENOSYS) + /* Function not implemented. */ + return; + + init_max_error (); + + check_complex ("clog10 (-0 + 0 i) == -inf + pi i plus division by zero exception", FUNC(clog10) (BUILD_COMPLEX (minus_zero, 0)), BUILD_COMPLEX (minus_infty, M_PIl), 0, 0, DIVIDE_BY_ZERO_EXCEPTION); + check_complex ("clog10 (-0 - 0 i) == -inf - pi i plus division by zero exception", FUNC(clog10) (BUILD_COMPLEX (minus_zero, minus_zero)), BUILD_COMPLEX (minus_infty, -M_PIl), 0, 0, DIVIDE_BY_ZERO_EXCEPTION); + + check_complex ("clog10 (0 + 0 i) == -inf + 0.0 i plus division by zero exception", FUNC(clog10) (BUILD_COMPLEX (0, 0)), BUILD_COMPLEX (minus_infty, 0.0), 0, 0, DIVIDE_BY_ZERO_EXCEPTION); + check_complex ("clog10 (0 - 0 i) == -inf - 0 i plus division by zero exception", FUNC(clog10) (BUILD_COMPLEX (0, minus_zero)), BUILD_COMPLEX (minus_infty, minus_zero), 0, 0, DIVIDE_BY_ZERO_EXCEPTION); + + check_complex ("clog10 (-inf + inf i) == inf + 3/4 pi*log10(e) i", FUNC(clog10) (BUILD_COMPLEX (minus_infty, plus_infty)), BUILD_COMPLEX (plus_infty, M_PI_34_LOG10El), DELTA520, 0, 0); + + check_complex ("clog10 (inf + inf i) == inf + pi/4*log10(e) i", FUNC(clog10) (BUILD_COMPLEX (plus_infty, plus_infty)), BUILD_COMPLEX (plus_infty, M_PI4_LOG10El), DELTA521, 0, 0); + check_complex ("clog10 (inf - inf i) == inf - pi/4*log10(e) i", FUNC(clog10) (BUILD_COMPLEX (plus_infty, minus_infty)), BUILD_COMPLEX (plus_infty, -M_PI4_LOG10El), DELTA522, 0, 0); + + check_complex ("clog10 (0 + inf i) == inf + pi/2*log10(e) i", FUNC(clog10) (BUILD_COMPLEX (0, plus_infty)), BUILD_COMPLEX (plus_infty, M_PI2_LOG10El), DELTA523, 0, 0); + check_complex ("clog10 (3 + inf i) == inf + pi/2*log10(e) i", FUNC(clog10) (BUILD_COMPLEX (3, plus_infty)), BUILD_COMPLEX (plus_infty, M_PI2_LOG10El), DELTA524, 0, 0); + check_complex ("clog10 (-0 + inf i) == inf + pi/2*log10(e) i", FUNC(clog10) (BUILD_COMPLEX (minus_zero, plus_infty)), BUILD_COMPLEX (plus_infty, M_PI2_LOG10El), DELTA525, 0, 0); + check_complex ("clog10 (-3 + inf i) == inf + pi/2*log10(e) i", FUNC(clog10) (BUILD_COMPLEX (-3, plus_infty)), BUILD_COMPLEX (plus_infty, M_PI2_LOG10El), DELTA526, 0, 0); + check_complex ("clog10 (0 - inf i) == inf - pi/2*log10(e) i", FUNC(clog10) (BUILD_COMPLEX (0, minus_infty)), BUILD_COMPLEX (plus_infty, -M_PI2_LOG10El), DELTA527, 0, 0); + check_complex ("clog10 (3 - inf i) == inf - pi/2*log10(e) i", FUNC(clog10) (BUILD_COMPLEX (3, minus_infty)), BUILD_COMPLEX (plus_infty, -M_PI2_LOG10El), DELTA528, 0, 0); + check_complex ("clog10 (-0 - inf i) == inf - pi/2*log10(e) i", FUNC(clog10) (BUILD_COMPLEX (minus_zero, minus_infty)), BUILD_COMPLEX (plus_infty, -M_PI2_LOG10El), DELTA529, 0, 0); + check_complex ("clog10 (-3 - inf i) == inf - pi/2*log10(e) i", FUNC(clog10) (BUILD_COMPLEX (-3, minus_infty)), BUILD_COMPLEX (plus_infty, -M_PI2_LOG10El), DELTA530, 0, 0); + + check_complex ("clog10 (-inf + 0 i) == inf + pi*log10(e) i", FUNC(clog10) (BUILD_COMPLEX (minus_infty, 0)), BUILD_COMPLEX (plus_infty, M_PI_LOG10El), DELTA531, 0, 0); + check_complex ("clog10 (-inf + 1 i) == inf + pi*log10(e) i", FUNC(clog10) (BUILD_COMPLEX (minus_infty, 1)), BUILD_COMPLEX (plus_infty, M_PI_LOG10El), DELTA532, 0, 0); + check_complex ("clog10 (-inf - 0 i) == inf - pi*log10(e) i", FUNC(clog10) (BUILD_COMPLEX (minus_infty, minus_zero)), BUILD_COMPLEX (plus_infty, -M_PI_LOG10El), DELTA533, 0, 0); + check_complex ("clog10 (-inf - 1 i) == inf - pi*log10(e) i", FUNC(clog10) (BUILD_COMPLEX (minus_infty, -1)), BUILD_COMPLEX (plus_infty, -M_PI_LOG10El), DELTA534, 0, 0); + + check_complex ("clog10 (inf + 0 i) == inf + 0.0 i", FUNC(clog10) (BUILD_COMPLEX (plus_infty, 0)), BUILD_COMPLEX (plus_infty, 0.0), 0, 0, 0); + check_complex ("clog10 (inf + 1 i) == inf + 0.0 i", FUNC(clog10) (BUILD_COMPLEX (plus_infty, 1)), BUILD_COMPLEX (plus_infty, 0.0), 0, 0, 0); + check_complex ("clog10 (inf - 0 i) == inf - 0 i", FUNC(clog10) (BUILD_COMPLEX (plus_infty, minus_zero)), BUILD_COMPLEX (plus_infty, minus_zero), 0, 0, 0); + check_complex ("clog10 (inf - 1 i) == inf - 0 i", FUNC(clog10) (BUILD_COMPLEX (plus_infty, -1)), BUILD_COMPLEX (plus_infty, minus_zero), 0, 0, 0); + + check_complex ("clog10 (inf + NaN i) == inf + NaN i", FUNC(clog10) (BUILD_COMPLEX (plus_infty, nan_value)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, 0); + check_complex ("clog10 (-inf + NaN i) == inf + NaN i", FUNC(clog10) (BUILD_COMPLEX (minus_infty, nan_value)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, 0); + + check_complex ("clog10 (NaN + inf i) == inf + NaN i", FUNC(clog10) (BUILD_COMPLEX (nan_value, plus_infty)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, 0); + check_complex ("clog10 (NaN - inf i) == inf + NaN i", FUNC(clog10) (BUILD_COMPLEX (nan_value, minus_infty)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, 0); + + check_complex ("clog10 (0 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(clog10) (BUILD_COMPLEX (0, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + check_complex ("clog10 (3 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(clog10) (BUILD_COMPLEX (3, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + check_complex ("clog10 (-0 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(clog10) (BUILD_COMPLEX (minus_zero, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + check_complex ("clog10 (-3 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(clog10) (BUILD_COMPLEX (-3, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + + check_complex ("clog10 (NaN + 0 i) == NaN + NaN i plus invalid exception allowed", FUNC(clog10) (BUILD_COMPLEX (nan_value, 0)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + check_complex ("clog10 (NaN + 5 i) == NaN + NaN i plus invalid exception allowed", FUNC(clog10) (BUILD_COMPLEX (nan_value, 5)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + check_complex ("clog10 (NaN - 0 i) == NaN + NaN i plus invalid exception allowed", FUNC(clog10) (BUILD_COMPLEX (nan_value, minus_zero)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + check_complex ("clog10 (NaN - 5 i) == NaN + NaN i plus invalid exception allowed", FUNC(clog10) (BUILD_COMPLEX (nan_value, -5)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + + check_complex ("clog10 (NaN + NaN i) == NaN + NaN i", FUNC(clog10) (BUILD_COMPLEX (nan_value, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, 0); + + check_complex ("clog10 (0.7 + 1.2 i) == 0.1427786545038868803 + 0.4528483579352493248 i", FUNC(clog10) (BUILD_COMPLEX (0.7L, 1.2L)), BUILD_COMPLEX (0.1427786545038868803L, 0.4528483579352493248L), DELTA552, 0, 0); + check_complex ("clog10 (-2 - 3 i) == 0.5569716761534183846 - 0.9375544629863747085 i", FUNC(clog10) (BUILD_COMPLEX (-2, -3)), BUILD_COMPLEX (0.5569716761534183846L, -0.9375544629863747085L), DELTA553, 0, 0); + + print_complex_max_error ("clog10", DELTAclog10, 0); +} + +static void +conj_test (void) +{ + init_max_error (); + check_complex ("conj (0.0 + 0.0 i) == 0.0 - 0 i", FUNC(conj) (BUILD_COMPLEX (0.0, 0.0)), BUILD_COMPLEX (0.0, minus_zero), 0, 0, 0); + check_complex ("conj (0.0 - 0 i) == 0.0 + 0.0 i", FUNC(conj) (BUILD_COMPLEX (0.0, minus_zero)), BUILD_COMPLEX (0.0, 0.0), 0, 0, 0); + check_complex ("conj (NaN + NaN i) == NaN + NaN i", FUNC(conj) (BUILD_COMPLEX (nan_value, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, 0); + check_complex ("conj (inf - inf i) == inf + inf i", FUNC(conj) (BUILD_COMPLEX (plus_infty, minus_infty)), BUILD_COMPLEX (plus_infty, plus_infty), 0, 0, 0); + check_complex ("conj (inf + inf i) == inf - inf i", FUNC(conj) (BUILD_COMPLEX (plus_infty, plus_infty)), BUILD_COMPLEX (plus_infty, minus_infty), 0, 0, 0); + check_complex ("conj (1.0 + 2.0 i) == 1.0 - 2.0 i", FUNC(conj) (BUILD_COMPLEX (1.0, 2.0)), BUILD_COMPLEX (1.0, -2.0), 0, 0, 0); + check_complex ("conj (3.0 - 4.0 i) == 3.0 + 4.0 i", FUNC(conj) (BUILD_COMPLEX (3.0, -4.0)), BUILD_COMPLEX (3.0, 4.0), 0, 0, 0); + + print_complex_max_error ("conj", 0, 0); +} +#endif + + +static void +copysign_test (void) +{ + init_max_error (); + + check_float ("copysign (0, 4) == 0", FUNC(copysign) (0, 4), 0, 0, 0, 0); + check_float ("copysign (0, -4) == -0", FUNC(copysign) (0, -4), minus_zero, 0, 0, 0); + check_float ("copysign (-0, 4) == 0", FUNC(copysign) (minus_zero, 4), 0, 0, 0, 0); + check_float ("copysign (-0, -4) == -0", FUNC(copysign) (minus_zero, -4), minus_zero, 0, 0, 0); + + check_float ("copysign (inf, 0) == inf", FUNC(copysign) (plus_infty, 0), plus_infty, 0, 0, 0); + check_float ("copysign (inf, -0) == -inf", FUNC(copysign) (plus_infty, minus_zero), minus_infty, 0, 0, 0); + check_float ("copysign (-inf, 0) == inf", FUNC(copysign) (minus_infty, 0), plus_infty, 0, 0, 0); + check_float ("copysign (-inf, -0) == -inf", FUNC(copysign) (minus_infty, minus_zero), minus_infty, 0, 0, 0); + + check_float ("copysign (0, inf) == 0", FUNC(copysign) (0, plus_infty), 0, 0, 0, 0); + check_float ("copysign (0, -0) == -0", FUNC(copysign) (0, minus_zero), minus_zero, 0, 0, 0); + check_float ("copysign (-0, inf) == 0", FUNC(copysign) (minus_zero, plus_infty), 0, 0, 0, 0); + check_float ("copysign (-0, -0) == -0", FUNC(copysign) (minus_zero, minus_zero), minus_zero, 0, 0, 0); + + /* XXX More correctly we would have to check the sign of the NaN. */ + check_float ("copysign (NaN, 0) == NaN", FUNC(copysign) (nan_value, 0), nan_value, 0, 0, 0); + check_float ("copysign (NaN, -0) == NaN", FUNC(copysign) (nan_value, minus_zero), nan_value, 0, 0, 0); + check_float ("copysign (-NaN, 0) == NaN", FUNC(copysign) (-nan_value, 0), nan_value, 0, 0, 0); + check_float ("copysign (-NaN, -0) == NaN", FUNC(copysign) (-nan_value, minus_zero), nan_value, 0, 0, 0); + + print_max_error ("copysign", 0, 0); +} + +static void +cos_test (void) +{ + errno = 0; + FUNC(cos) (0); + if (errno == ENOSYS) + /* Function not implemented. */ + return; + + init_max_error (); + + check_float ("cos (0) == 1", FUNC(cos) (0), 1, 0, 0, 0); + check_float ("cos (-0) == 1", FUNC(cos) (minus_zero), 1, 0, 0, 0); + check_float ("cos (inf) == NaN plus invalid exception", FUNC(cos) (plus_infty), nan_value, 0, 0, INVALID_EXCEPTION); + check_float ("cos (-inf) == NaN plus invalid exception", FUNC(cos) (minus_infty), nan_value, 0, 0, INVALID_EXCEPTION); + check_float ("cos (NaN) == NaN", FUNC(cos) (nan_value), nan_value, 0, 0, 0); + + check_float ("cos (M_PI_6l * 2.0) == 0.5", FUNC(cos) (M_PI_6l * 2.0), 0.5, DELTA582, 0, 0); + check_float ("cos (M_PI_6l * 4.0) == -0.5", FUNC(cos) (M_PI_6l * 4.0), -0.5, DELTA583, 0, 0); + check_float ("cos (pi/2) == 0", FUNC(cos) (M_PI_2l), 0, DELTA584, 0, 0); + + check_float ("cos (0.7) == 0.76484218728448842625585999019186495", FUNC(cos) (0.7L), 0.76484218728448842625585999019186495L, DELTA585, 0, 0); + + print_max_error ("cos", DELTAcos, 0); +} + +static void +cosh_test (void) +{ + errno = 0; + FUNC(cosh) (0.7L); + if (errno == ENOSYS) + /* Function not implemented. */ + return; + + init_max_error (); + check_float ("cosh (0) == 1", FUNC(cosh) (0), 1, 0, 0, 0); + check_float ("cosh (-0) == 1", FUNC(cosh) (minus_zero), 1, 0, 0, 0); + +#ifndef TEST_INLINE + check_float ("cosh (inf) == inf", FUNC(cosh) (plus_infty), plus_infty, 0, 0, 0); + check_float ("cosh (-inf) == inf", FUNC(cosh) (minus_infty), plus_infty, 0, 0, 0); +#endif + check_float ("cosh (NaN) == NaN", FUNC(cosh) (nan_value), nan_value, 0, 0, 0); + + check_float ("cosh (0.7) == 1.255169005630943018", FUNC(cosh) (0.7L), 1.255169005630943018L, DELTA591, 0, 0); + print_max_error ("cosh", DELTAcosh, 0); +} + + +#if 0 /* XXX scp XXX */ +static void +cpow_test (void) +{ + errno = 0; + FUNC(cpow) (BUILD_COMPLEX (1, 0), BUILD_COMPLEX (0, 0)); + if (errno == ENOSYS) + /* Function not implemented. */ + return; + + init_max_error (); + + check_complex ("cpow (1 + 0 i, 0 + 0 i) == 1.0 + 0.0 i", FUNC(cpow) (BUILD_COMPLEX (1, 0), BUILD_COMPLEX (0, 0)), BUILD_COMPLEX (1.0, 0.0), 0, 0, 0); + check_complex ("cpow (2 + 0 i, 10 + 0 i) == 1024.0 + 0.0 i", FUNC(cpow) (BUILD_COMPLEX (2, 0), BUILD_COMPLEX (10, 0)), BUILD_COMPLEX (1024.0, 0.0), 0, 0, 0); + + check_complex ("cpow (e + 0 i, 0 + 2 * M_PIl i) == 1.0 + 0.0 i", FUNC(cpow) (BUILD_COMPLEX (M_El, 0), BUILD_COMPLEX (0, 2 * M_PIl)), BUILD_COMPLEX (1.0, 0.0), DELTA594, 0, 0); + check_complex ("cpow (2 + 3 i, 4 + 0 i) == -119.0 - 120.0 i", FUNC(cpow) (BUILD_COMPLEX (2, 3), BUILD_COMPLEX (4, 0)), BUILD_COMPLEX (-119.0, -120.0), DELTA595, 0, 0); + + check_complex ("cpow (NaN + NaN i, NaN + NaN i) == NaN + NaN i", FUNC(cpow) (BUILD_COMPLEX (nan_value, nan_value), BUILD_COMPLEX (nan_value, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, 0); + + print_complex_max_error ("cpow", DELTAcpow, 0); +} + +static void +cproj_test (void) +{ + init_max_error (); + check_complex ("cproj (0.0 + 0.0 i) == 0.0 + 0.0 i", FUNC(cproj) (BUILD_COMPLEX (0.0, 0.0)), BUILD_COMPLEX (0.0, 0.0), 0, 0, 0); + check_complex ("cproj (-0 - 0 i) == -0 - 0 i", FUNC(cproj) (BUILD_COMPLEX (minus_zero, minus_zero)), BUILD_COMPLEX (minus_zero, minus_zero), 0, 0, 0); + check_complex ("cproj (0.0 - 0 i) == 0.0 - 0 i", FUNC(cproj) (BUILD_COMPLEX (0.0, minus_zero)), BUILD_COMPLEX (0.0, minus_zero), 0, 0, 0); + check_complex ("cproj (-0 + 0.0 i) == -0 + 0.0 i", FUNC(cproj) (BUILD_COMPLEX (minus_zero, 0.0)), BUILD_COMPLEX (minus_zero, 0.0), 0, 0, 0); + + check_complex ("cproj (NaN + NaN i) == NaN + NaN i", FUNC(cproj) (BUILD_COMPLEX (nan_value, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, 0); + + check_complex ("cproj (inf + inf i) == inf + 0.0 i", FUNC(cproj) (BUILD_COMPLEX (plus_infty, plus_infty)), BUILD_COMPLEX (plus_infty, 0.0), 0, 0, 0); + check_complex ("cproj (inf - inf i) == inf - 0 i", FUNC(cproj) (BUILD_COMPLEX (plus_infty, minus_infty)), BUILD_COMPLEX (plus_infty, minus_zero), 0, 0, 0); + check_complex ("cproj (-inf + inf i) == inf + 0.0 i", FUNC(cproj) (BUILD_COMPLEX (minus_infty, plus_infty)), BUILD_COMPLEX (plus_infty, 0.0), 0, 0, 0); + check_complex ("cproj (-inf - inf i) == inf - 0 i", FUNC(cproj) (BUILD_COMPLEX (minus_infty, minus_infty)), BUILD_COMPLEX (plus_infty, minus_zero), 0, 0, 0); + + check_complex ("cproj (1.0 + 0.0 i) == 1.0 + 0.0 i", FUNC(cproj) (BUILD_COMPLEX (1.0, 0.0)), BUILD_COMPLEX (1.0, 0.0), 0, 0, 0); + check_complex ("cproj (2.0 + 3.0 i) == 0.2857142857142857142857142857142857 + 0.42857142857142857142857142857142855 i", FUNC(cproj) (BUILD_COMPLEX (2.0, 3.0)), BUILD_COMPLEX (0.2857142857142857142857142857142857L, 0.42857142857142857142857142857142855L), 0, 0, 0); + + print_complex_max_error ("cproj", 0, 0); +} + +static void +creal_test (void) +{ + init_max_error (); + check_float ("creal (0.0 + 1.0 i) == 0.0", FUNC(creal) (BUILD_COMPLEX (0.0, 1.0)), 0.0, 0, 0, 0); + check_float ("creal (-0 + 1.0 i) == -0", FUNC(creal) (BUILD_COMPLEX (minus_zero, 1.0)), minus_zero, 0, 0, 0); + check_float ("creal (NaN + 1.0 i) == NaN", FUNC(creal) (BUILD_COMPLEX (nan_value, 1.0)), nan_value, 0, 0, 0); + check_float ("creal (NaN + NaN i) == NaN", FUNC(creal) (BUILD_COMPLEX (nan_value, nan_value)), nan_value, 0, 0, 0); + check_float ("creal (inf + 1.0 i) == inf", FUNC(creal) (BUILD_COMPLEX (plus_infty, 1.0)), plus_infty, 0, 0, 0); + check_float ("creal (-inf + 1.0 i) == -inf", FUNC(creal) (BUILD_COMPLEX (minus_infty, 1.0)), minus_infty, 0, 0, 0); + check_float ("creal (2.0 + 3.0 i) == 2.0", FUNC(creal) (BUILD_COMPLEX (2.0, 3.0)), 2.0, 0, 0, 0); + + print_max_error ("creal", 0, 0); +} + +static void +csin_test (void) +{ + errno = 0; + FUNC(csin) (BUILD_COMPLEX (0.7L, 1.2L)); + if (errno == ENOSYS) + /* Function not implemented. */ + return; + + init_max_error (); + + check_complex ("csin (0.0 + 0.0 i) == 0.0 + 0.0 i", FUNC(csin) (BUILD_COMPLEX (0.0, 0.0)), BUILD_COMPLEX (0.0, 0.0), 0, 0, 0); + check_complex ("csin (-0 + 0.0 i) == -0 + 0.0 i", FUNC(csin) (BUILD_COMPLEX (minus_zero, 0.0)), BUILD_COMPLEX (minus_zero, 0.0), 0, 0, 0); + check_complex ("csin (0.0 - 0 i) == 0 - 0 i", FUNC(csin) (BUILD_COMPLEX (0.0, minus_zero)), BUILD_COMPLEX (0, minus_zero), 0, 0, 0); + check_complex ("csin (-0 - 0 i) == -0 - 0 i", FUNC(csin) (BUILD_COMPLEX (minus_zero, minus_zero)), BUILD_COMPLEX (minus_zero, minus_zero), 0, 0, 0); + + check_complex ("csin (0.0 + inf i) == 0.0 + inf i", FUNC(csin) (BUILD_COMPLEX (0.0, plus_infty)), BUILD_COMPLEX (0.0, plus_infty), 0, 0, 0); + check_complex ("csin (-0 + inf i) == -0 + inf i", FUNC(csin) (BUILD_COMPLEX (minus_zero, plus_infty)), BUILD_COMPLEX (minus_zero, plus_infty), 0, 0, 0); + check_complex ("csin (0.0 - inf i) == 0.0 - inf i", FUNC(csin) (BUILD_COMPLEX (0.0, minus_infty)), BUILD_COMPLEX (0.0, minus_infty), 0, 0, 0); + check_complex ("csin (-0 - inf i) == -0 - inf i", FUNC(csin) (BUILD_COMPLEX (minus_zero, minus_infty)), BUILD_COMPLEX (minus_zero, minus_infty), 0, 0, 0); + + check_complex ("csin (inf + 0.0 i) == NaN + 0.0 i plus invalid exception and sign of zero/inf not specified", FUNC(csin) (BUILD_COMPLEX (plus_infty, 0.0)), BUILD_COMPLEX (nan_value, 0.0), 0, 0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN); + check_complex ("csin (-inf + 0.0 i) == NaN + 0.0 i plus invalid exception and sign of zero/inf not specified", FUNC(csin) (BUILD_COMPLEX (minus_infty, 0.0)), BUILD_COMPLEX (nan_value, 0.0), 0, 0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN); + check_complex ("csin (inf - 0 i) == NaN + 0.0 i plus invalid exception and sign of zero/inf not specified", FUNC(csin) (BUILD_COMPLEX (plus_infty, minus_zero)), BUILD_COMPLEX (nan_value, 0.0), 0, 0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN); + check_complex ("csin (-inf - 0 i) == NaN + 0.0 i plus invalid exception and sign of zero/inf not specified", FUNC(csin) (BUILD_COMPLEX (minus_infty, minus_zero)), BUILD_COMPLEX (nan_value, 0.0), 0, 0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN); + + check_complex ("csin (inf + inf i) == NaN + inf i plus invalid exception and sign of zero/inf not specified", FUNC(csin) (BUILD_COMPLEX (plus_infty, plus_infty)), BUILD_COMPLEX (nan_value, plus_infty), 0, 0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN); + check_complex ("csin (-inf + inf i) == NaN + inf i plus invalid exception and sign of zero/inf not specified", FUNC(csin) (BUILD_COMPLEX (minus_infty, plus_infty)), BUILD_COMPLEX (nan_value, plus_infty), 0, 0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN); + check_complex ("csin (inf - inf i) == NaN + inf i plus invalid exception and sign of zero/inf not specified", FUNC(csin) (BUILD_COMPLEX (plus_infty, minus_infty)), BUILD_COMPLEX (nan_value, plus_infty), 0, 0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN); + check_complex ("csin (-inf - inf i) == NaN + inf i plus invalid exception and sign of zero/inf not specified", FUNC(csin) (BUILD_COMPLEX (minus_infty, minus_infty)), BUILD_COMPLEX (nan_value, plus_infty), 0, 0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN); + + check_complex ("csin (inf + 6.75 i) == NaN + NaN i plus invalid exception", FUNC(csin) (BUILD_COMPLEX (plus_infty, 6.75)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); + check_complex ("csin (inf - 6.75 i) == NaN + NaN i plus invalid exception", FUNC(csin) (BUILD_COMPLEX (plus_infty, -6.75)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); + check_complex ("csin (-inf + 6.75 i) == NaN + NaN i plus invalid exception", FUNC(csin) (BUILD_COMPLEX (minus_infty, 6.75)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); + check_complex ("csin (-inf - 6.75 i) == NaN + NaN i plus invalid exception", FUNC(csin) (BUILD_COMPLEX (minus_infty, -6.75)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); + + check_complex ("csin (4.625 + inf i) == -inf - inf i", FUNC(csin) (BUILD_COMPLEX (4.625, plus_infty)), BUILD_COMPLEX (minus_infty, minus_infty), 0, 0, 0); + check_complex ("csin (4.625 - inf i) == -inf + inf i", FUNC(csin) (BUILD_COMPLEX (4.625, minus_infty)), BUILD_COMPLEX (minus_infty, plus_infty), 0, 0, 0); + check_complex ("csin (-4.625 + inf i) == inf - inf i", FUNC(csin) (BUILD_COMPLEX (-4.625, plus_infty)), BUILD_COMPLEX (plus_infty, minus_infty), 0, 0, 0); + check_complex ("csin (-4.625 - inf i) == inf + inf i", FUNC(csin) (BUILD_COMPLEX (-4.625, minus_infty)), BUILD_COMPLEX (plus_infty, plus_infty), 0, 0, 0); + + check_complex ("csin (NaN + 0.0 i) == NaN + 0.0 i plus sign of zero/inf not specified", FUNC(csin) (BUILD_COMPLEX (nan_value, 0.0)), BUILD_COMPLEX (nan_value, 0.0), 0, 0, IGNORE_ZERO_INF_SIGN); + check_complex ("csin (NaN - 0 i) == NaN + 0.0 i plus sign of zero/inf not specified", FUNC(csin) (BUILD_COMPLEX (nan_value, minus_zero)), BUILD_COMPLEX (nan_value, 0.0), 0, 0, IGNORE_ZERO_INF_SIGN); + + check_complex ("csin (NaN + inf i) == NaN + inf i plus sign of zero/inf not specified", FUNC(csin) (BUILD_COMPLEX (nan_value, plus_infty)), BUILD_COMPLEX (nan_value, plus_infty), 0, 0, IGNORE_ZERO_INF_SIGN); + check_complex ("csin (NaN - inf i) == NaN + inf i plus sign of zero/inf not specified", FUNC(csin) (BUILD_COMPLEX (nan_value, minus_infty)), BUILD_COMPLEX (nan_value, plus_infty), 0, 0, IGNORE_ZERO_INF_SIGN); + + check_complex ("csin (NaN + 9.0 i) == NaN + NaN i plus invalid exception allowed", FUNC(csin) (BUILD_COMPLEX (nan_value, 9.0)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + check_complex ("csin (NaN - 9.0 i) == NaN + NaN i plus invalid exception allowed", FUNC(csin) (BUILD_COMPLEX (nan_value, -9.0)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + + check_complex ("csin (0.0 + NaN i) == 0.0 + NaN i", FUNC(csin) (BUILD_COMPLEX (0.0, nan_value)), BUILD_COMPLEX (0.0, nan_value), 0, 0, 0); + check_complex ("csin (-0 + NaN i) == -0 + NaN i", FUNC(csin) (BUILD_COMPLEX (minus_zero, nan_value)), BUILD_COMPLEX (minus_zero, nan_value), 0, 0, 0); + + check_complex ("csin (10.0 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(csin) (BUILD_COMPLEX (10.0, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + check_complex ("csin (NaN - 10.0 i) == NaN + NaN i plus invalid exception allowed", FUNC(csin) (BUILD_COMPLEX (nan_value, -10.0)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + + check_complex ("csin (inf + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(csin) (BUILD_COMPLEX (plus_infty, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + check_complex ("csin (-inf + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(csin) (BUILD_COMPLEX (minus_infty, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + + check_complex ("csin (NaN + NaN i) == NaN + NaN i", FUNC(csin) (BUILD_COMPLEX (nan_value, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, 0); + + check_complex ("csin (0.7 + 1.2 i) == 1.1664563419657581376 + 1.1544997246948547371 i", FUNC(csin) (BUILD_COMPLEX (0.7L, 1.2L)), BUILD_COMPLEX (1.1664563419657581376L, 1.1544997246948547371L), DELTA652, 0, 0); + + check_complex ("csin (-2 - 3 i) == -9.1544991469114295734 + 4.1689069599665643507 i", FUNC(csin) (BUILD_COMPLEX (-2, -3)), BUILD_COMPLEX (-9.1544991469114295734L, 4.1689069599665643507L), 0, 0, 0); + + print_complex_max_error ("csin", DELTAcsin, 0); +} + + +static void +csinh_test (void) +{ + errno = 0; + FUNC(csinh) (BUILD_COMPLEX (0.7L, 1.2L)); + if (errno == ENOSYS) + /* Function not implemented. */ + return; + + init_max_error (); + + check_complex ("csinh (0.0 + 0.0 i) == 0.0 + 0.0 i", FUNC(csinh) (BUILD_COMPLEX (0.0, 0.0)), BUILD_COMPLEX (0.0, 0.0), 0, 0, 0); + check_complex ("csinh (-0 + 0.0 i) == -0 + 0.0 i", FUNC(csinh) (BUILD_COMPLEX (minus_zero, 0.0)), BUILD_COMPLEX (minus_zero, 0.0), 0, 0, 0); + check_complex ("csinh (0.0 - 0 i) == 0.0 - 0 i", FUNC(csinh) (BUILD_COMPLEX (0.0, minus_zero)), BUILD_COMPLEX (0.0, minus_zero), 0, 0, 0); + check_complex ("csinh (-0 - 0 i) == -0 - 0 i", FUNC(csinh) (BUILD_COMPLEX (minus_zero, minus_zero)), BUILD_COMPLEX (minus_zero, minus_zero), 0, 0, 0); + + check_complex ("csinh (0.0 + inf i) == 0.0 + NaN i plus invalid exception and sign of zero/inf not specified", FUNC(csinh) (BUILD_COMPLEX (0.0, plus_infty)), BUILD_COMPLEX (0.0, nan_value), 0, 0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN); + check_complex ("csinh (-0 + inf i) == 0.0 + NaN i plus invalid exception and sign of zero/inf not specified", FUNC(csinh) (BUILD_COMPLEX (minus_zero, plus_infty)), BUILD_COMPLEX (0.0, nan_value), 0, 0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN); + check_complex ("csinh (0.0 - inf i) == 0.0 + NaN i plus invalid exception and sign of zero/inf not specified", FUNC(csinh) (BUILD_COMPLEX (0.0, minus_infty)), BUILD_COMPLEX (0.0, nan_value), 0, 0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN); + check_complex ("csinh (-0 - inf i) == 0.0 + NaN i plus invalid exception and sign of zero/inf not specified", FUNC(csinh) (BUILD_COMPLEX (minus_zero, minus_infty)), BUILD_COMPLEX (0.0, nan_value), 0, 0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN); + + check_complex ("csinh (inf + 0.0 i) == inf + 0.0 i", FUNC(csinh) (BUILD_COMPLEX (plus_infty, 0.0)), BUILD_COMPLEX (plus_infty, 0.0), 0, 0, 0); + check_complex ("csinh (-inf + 0.0 i) == -inf + 0.0 i", FUNC(csinh) (BUILD_COMPLEX (minus_infty, 0.0)), BUILD_COMPLEX (minus_infty, 0.0), 0, 0, 0); + check_complex ("csinh (inf - 0 i) == inf - 0 i", FUNC(csinh) (BUILD_COMPLEX (plus_infty, minus_zero)), BUILD_COMPLEX (plus_infty, minus_zero), 0, 0, 0); + check_complex ("csinh (-inf - 0 i) == -inf - 0 i", FUNC(csinh) (BUILD_COMPLEX (minus_infty, minus_zero)), BUILD_COMPLEX (minus_infty, minus_zero), 0, 0, 0); + + check_complex ("csinh (inf + inf i) == inf + NaN i plus invalid exception and sign of zero/inf not specified", FUNC(csinh) (BUILD_COMPLEX (plus_infty, plus_infty)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN); + check_complex ("csinh (-inf + inf i) == inf + NaN i plus invalid exception and sign of zero/inf not specified", FUNC(csinh) (BUILD_COMPLEX (minus_infty, plus_infty)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN); + check_complex ("csinh (inf - inf i) == inf + NaN i plus invalid exception and sign of zero/inf not specified", FUNC(csinh) (BUILD_COMPLEX (plus_infty, minus_infty)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN); + check_complex ("csinh (-inf - inf i) == inf + NaN i plus invalid exception and sign of zero/inf not specified", FUNC(csinh) (BUILD_COMPLEX (minus_infty, minus_infty)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN); + + check_complex ("csinh (inf + 4.625 i) == -inf - inf i", FUNC(csinh) (BUILD_COMPLEX (plus_infty, 4.625)), BUILD_COMPLEX (minus_infty, minus_infty), 0, 0, 0); + check_complex ("csinh (-inf + 4.625 i) == inf - inf i", FUNC(csinh) (BUILD_COMPLEX (minus_infty, 4.625)), BUILD_COMPLEX (plus_infty, minus_infty), 0, 0, 0); + check_complex ("csinh (inf - 4.625 i) == -inf + inf i", FUNC(csinh) (BUILD_COMPLEX (plus_infty, -4.625)), BUILD_COMPLEX (minus_infty, plus_infty), 0, 0, 0); + check_complex ("csinh (-inf - 4.625 i) == inf + inf i", FUNC(csinh) (BUILD_COMPLEX (minus_infty, -4.625)), BUILD_COMPLEX (plus_infty, plus_infty), 0, 0, 0); + + check_complex ("csinh (6.75 + inf i) == NaN + NaN i plus invalid exception", FUNC(csinh) (BUILD_COMPLEX (6.75, plus_infty)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); + check_complex ("csinh (-6.75 + inf i) == NaN + NaN i plus invalid exception", FUNC(csinh) (BUILD_COMPLEX (-6.75, plus_infty)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); + check_complex ("csinh (6.75 - inf i) == NaN + NaN i plus invalid exception", FUNC(csinh) (BUILD_COMPLEX (6.75, minus_infty)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); + check_complex ("csinh (-6.75 - inf i) == NaN + NaN i plus invalid exception", FUNC(csinh) (BUILD_COMPLEX (-6.75, minus_infty)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); + + check_complex ("csinh (0.0 + NaN i) == 0.0 + NaN i plus sign of zero/inf not specified", FUNC(csinh) (BUILD_COMPLEX (0.0, nan_value)), BUILD_COMPLEX (0.0, nan_value), 0, 0, IGNORE_ZERO_INF_SIGN); + check_complex ("csinh (-0 + NaN i) == 0.0 + NaN i plus sign of zero/inf not specified", FUNC(csinh) (BUILD_COMPLEX (minus_zero, nan_value)), BUILD_COMPLEX (0.0, nan_value), 0, 0, IGNORE_ZERO_INF_SIGN); + + check_complex ("csinh (inf + NaN i) == inf + NaN i plus sign of zero/inf not specified", FUNC(csinh) (BUILD_COMPLEX (plus_infty, nan_value)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, IGNORE_ZERO_INF_SIGN); + check_complex ("csinh (-inf + NaN i) == inf + NaN i plus sign of zero/inf not specified", FUNC(csinh) (BUILD_COMPLEX (minus_infty, nan_value)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, IGNORE_ZERO_INF_SIGN); + + check_complex ("csinh (9.0 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(csinh) (BUILD_COMPLEX (9.0, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + check_complex ("csinh (-9.0 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(csinh) (BUILD_COMPLEX (-9.0, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + + check_complex ("csinh (NaN + 0.0 i) == NaN + 0.0 i", FUNC(csinh) (BUILD_COMPLEX (nan_value, 0.0)), BUILD_COMPLEX (nan_value, 0.0), 0, 0, 0); + check_complex ("csinh (NaN - 0 i) == NaN - 0 i", FUNC(csinh) (BUILD_COMPLEX (nan_value, minus_zero)), BUILD_COMPLEX (nan_value, minus_zero), 0, 0, 0); + + check_complex ("csinh (NaN + 10.0 i) == NaN + NaN i plus invalid exception allowed", FUNC(csinh) (BUILD_COMPLEX (nan_value, 10.0)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + check_complex ("csinh (NaN - 10.0 i) == NaN + NaN i plus invalid exception allowed", FUNC(csinh) (BUILD_COMPLEX (nan_value, -10.0)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + + check_complex ("csinh (NaN + inf i) == NaN + NaN i plus invalid exception allowed", FUNC(csinh) (BUILD_COMPLEX (nan_value, plus_infty)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + check_complex ("csinh (NaN - inf i) == NaN + NaN i plus invalid exception allowed", FUNC(csinh) (BUILD_COMPLEX (nan_value, minus_infty)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + + check_complex ("csinh (NaN + NaN i) == NaN + NaN i", FUNC(csinh) (BUILD_COMPLEX (nan_value, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, 0); + + check_complex ("csinh (0.7 + 1.2 i) == 0.27487868678117583582 + 1.1698665727426565139 i", FUNC(csinh) (BUILD_COMPLEX (0.7L, 1.2L)), BUILD_COMPLEX (0.27487868678117583582L, 1.1698665727426565139L), DELTA691, 0, 0); + check_complex ("csinh (-2 - 3 i) == 3.5905645899857799520 - 0.5309210862485198052 i", FUNC(csinh) (BUILD_COMPLEX (-2, -3)), BUILD_COMPLEX (3.5905645899857799520L, -0.5309210862485198052L), DELTA692, 0, 0); + + print_complex_max_error ("csinh", DELTAcsinh, 0); +} + +static void +csqrt_test (void) +{ + errno = 0; + FUNC(csqrt) (BUILD_COMPLEX (-1, 0)); + if (errno == ENOSYS) + /* Function not implemented. */ + return; + + init_max_error (); + + check_complex ("csqrt (0 + 0 i) == 0.0 + 0.0 i", FUNC(csqrt) (BUILD_COMPLEX (0, 0)), BUILD_COMPLEX (0.0, 0.0), 0, 0, 0); + check_complex ("csqrt (0 - 0 i) == 0 - 0 i", FUNC(csqrt) (BUILD_COMPLEX (0, minus_zero)), BUILD_COMPLEX (0, minus_zero), 0, 0, 0); + check_complex ("csqrt (-0 + 0 i) == 0.0 + 0.0 i", FUNC(csqrt) (BUILD_COMPLEX (minus_zero, 0)), BUILD_COMPLEX (0.0, 0.0), 0, 0, 0); + check_complex ("csqrt (-0 - 0 i) == 0.0 - 0 i", FUNC(csqrt) (BUILD_COMPLEX (minus_zero, minus_zero)), BUILD_COMPLEX (0.0, minus_zero), 0, 0, 0); + + check_complex ("csqrt (-inf + 0 i) == 0.0 + inf i", FUNC(csqrt) (BUILD_COMPLEX (minus_infty, 0)), BUILD_COMPLEX (0.0, plus_infty), 0, 0, 0); + check_complex ("csqrt (-inf + 6 i) == 0.0 + inf i", FUNC(csqrt) (BUILD_COMPLEX (minus_infty, 6)), BUILD_COMPLEX (0.0, plus_infty), 0, 0, 0); + check_complex ("csqrt (-inf - 0 i) == 0.0 - inf i", FUNC(csqrt) (BUILD_COMPLEX (minus_infty, minus_zero)), BUILD_COMPLEX (0.0, minus_infty), 0, 0, 0); + check_complex ("csqrt (-inf - 6 i) == 0.0 - inf i", FUNC(csqrt) (BUILD_COMPLEX (minus_infty, -6)), BUILD_COMPLEX (0.0, minus_infty), 0, 0, 0); + + check_complex ("csqrt (inf + 0 i) == inf + 0.0 i", FUNC(csqrt) (BUILD_COMPLEX (plus_infty, 0)), BUILD_COMPLEX (plus_infty, 0.0), 0, 0, 0); + check_complex ("csqrt (inf + 6 i) == inf + 0.0 i", FUNC(csqrt) (BUILD_COMPLEX (plus_infty, 6)), BUILD_COMPLEX (plus_infty, 0.0), 0, 0, 0); + check_complex ("csqrt (inf - 0 i) == inf - 0 i", FUNC(csqrt) (BUILD_COMPLEX (plus_infty, minus_zero)), BUILD_COMPLEX (plus_infty, minus_zero), 0, 0, 0); + check_complex ("csqrt (inf - 6 i) == inf - 0 i", FUNC(csqrt) (BUILD_COMPLEX (plus_infty, -6)), BUILD_COMPLEX (plus_infty, minus_zero), 0, 0, 0); + + check_complex ("csqrt (0 + inf i) == inf + inf i", FUNC(csqrt) (BUILD_COMPLEX (0, plus_infty)), BUILD_COMPLEX (plus_infty, plus_infty), 0, 0, 0); + check_complex ("csqrt (4 + inf i) == inf + inf i", FUNC(csqrt) (BUILD_COMPLEX (4, plus_infty)), BUILD_COMPLEX (plus_infty, plus_infty), 0, 0, 0); + check_complex ("csqrt (inf + inf i) == inf + inf i", FUNC(csqrt) (BUILD_COMPLEX (plus_infty, plus_infty)), BUILD_COMPLEX (plus_infty, plus_infty), 0, 0, 0); + check_complex ("csqrt (-0 + inf i) == inf + inf i", FUNC(csqrt) (BUILD_COMPLEX (minus_zero, plus_infty)), BUILD_COMPLEX (plus_infty, plus_infty), 0, 0, 0); + check_complex ("csqrt (-4 + inf i) == inf + inf i", FUNC(csqrt) (BUILD_COMPLEX (-4, plus_infty)), BUILD_COMPLEX (plus_infty, plus_infty), 0, 0, 0); + check_complex ("csqrt (-inf + inf i) == inf + inf i", FUNC(csqrt) (BUILD_COMPLEX (minus_infty, plus_infty)), BUILD_COMPLEX (plus_infty, plus_infty), 0, 0, 0); + check_complex ("csqrt (0 - inf i) == inf - inf i", FUNC(csqrt) (BUILD_COMPLEX (0, minus_infty)), BUILD_COMPLEX (plus_infty, minus_infty), 0, 0, 0); + check_complex ("csqrt (4 - inf i) == inf - inf i", FUNC(csqrt) (BUILD_COMPLEX (4, minus_infty)), BUILD_COMPLEX (plus_infty, minus_infty), 0, 0, 0); + check_complex ("csqrt (inf - inf i) == inf - inf i", FUNC(csqrt) (BUILD_COMPLEX (plus_infty, minus_infty)), BUILD_COMPLEX (plus_infty, minus_infty), 0, 0, 0); + check_complex ("csqrt (-0 - inf i) == inf - inf i", FUNC(csqrt) (BUILD_COMPLEX (minus_zero, minus_infty)), BUILD_COMPLEX (plus_infty, minus_infty), 0, 0, 0); + check_complex ("csqrt (-4 - inf i) == inf - inf i", FUNC(csqrt) (BUILD_COMPLEX (-4, minus_infty)), BUILD_COMPLEX (plus_infty, minus_infty), 0, 0, 0); + check_complex ("csqrt (-inf - inf i) == inf - inf i", FUNC(csqrt) (BUILD_COMPLEX (minus_infty, minus_infty)), BUILD_COMPLEX (plus_infty, minus_infty), 0, 0, 0); + + check_complex ("csqrt (-inf + NaN i) == NaN + inf i plus sign of zero/inf not specified", FUNC(csqrt) (BUILD_COMPLEX (minus_infty, nan_value)), BUILD_COMPLEX (nan_value, plus_infty), 0, 0, IGNORE_ZERO_INF_SIGN); + + check_complex ("csqrt (inf + NaN i) == inf + NaN i", FUNC(csqrt) (BUILD_COMPLEX (plus_infty, nan_value)), BUILD_COMPLEX (plus_infty, nan_value), 0, 0, 0); + + check_complex ("csqrt (0 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(csqrt) (BUILD_COMPLEX (0, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + check_complex ("csqrt (1 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(csqrt) (BUILD_COMPLEX (1, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + check_complex ("csqrt (-0 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(csqrt) (BUILD_COMPLEX (minus_zero, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + check_complex ("csqrt (-1 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(csqrt) (BUILD_COMPLEX (-1, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + + check_complex ("csqrt (NaN + 0 i) == NaN + NaN i plus invalid exception allowed", FUNC(csqrt) (BUILD_COMPLEX (nan_value, 0)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + check_complex ("csqrt (NaN + 8 i) == NaN + NaN i plus invalid exception allowed", FUNC(csqrt) (BUILD_COMPLEX (nan_value, 8)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + check_complex ("csqrt (NaN - 0 i) == NaN + NaN i plus invalid exception allowed", FUNC(csqrt) (BUILD_COMPLEX (nan_value, minus_zero)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + check_complex ("csqrt (NaN - 8 i) == NaN + NaN i plus invalid exception allowed", FUNC(csqrt) (BUILD_COMPLEX (nan_value, -8)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + + check_complex ("csqrt (NaN + NaN i) == NaN + NaN i", FUNC(csqrt) (BUILD_COMPLEX (nan_value, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, 0); + + check_complex ("csqrt (16.0 - 30.0 i) == 5.0 - 3.0 i", FUNC(csqrt) (BUILD_COMPLEX (16.0, -30.0)), BUILD_COMPLEX (5.0, -3.0), 0, 0, 0); + check_complex ("csqrt (-1 + 0 i) == 0.0 + 1.0 i", FUNC(csqrt) (BUILD_COMPLEX (-1, 0)), BUILD_COMPLEX (0.0, 1.0), 0, 0, 0); + check_complex ("csqrt (0 + 2 i) == 1.0 + 1.0 i", FUNC(csqrt) (BUILD_COMPLEX (0, 2)), BUILD_COMPLEX (1.0, 1.0), 0, 0, 0); + check_complex ("csqrt (119 + 120 i) == 12.0 + 5.0 i", FUNC(csqrt) (BUILD_COMPLEX (119, 120)), BUILD_COMPLEX (12.0, 5.0), 0, 0, 0); + check_complex ("csqrt (0.7 + 1.2 i) == 1.022067610030026450706487883081139 + 0.58704531296356521154977678719838035 i", FUNC(csqrt) (BUILD_COMPLEX (0.7L, 1.2L)), BUILD_COMPLEX (1.022067610030026450706487883081139L, 0.58704531296356521154977678719838035L), DELTA732, 0, 0); + check_complex ("csqrt (-2 - 3 i) == 0.89597747612983812471573375529004348 - 1.6741492280355400404480393008490519 i", FUNC(csqrt) (BUILD_COMPLEX (-2, -3)), BUILD_COMPLEX (0.89597747612983812471573375529004348L, -1.6741492280355400404480393008490519L), DELTA733, 0, 0); + check_complex ("csqrt (-2 + 3 i) == 0.89597747612983812471573375529004348 + 1.6741492280355400404480393008490519 i", FUNC(csqrt) (BUILD_COMPLEX (-2, 3)), BUILD_COMPLEX (0.89597747612983812471573375529004348L, 1.6741492280355400404480393008490519L), DELTA734, 0, 0); + + print_complex_max_error ("csqrt", DELTAcsqrt, 0); +} + +static void +ctan_test (void) +{ + errno = 0; + FUNC(ctan) (BUILD_COMPLEX (0.7L, 1.2L)); + if (errno == ENOSYS) + /* Function not implemented. */ + return; + + init_max_error (); + + check_complex ("ctan (0 + 0 i) == 0.0 + 0.0 i", FUNC(ctan) (BUILD_COMPLEX (0, 0)), BUILD_COMPLEX (0.0, 0.0), 0, 0, 0); + check_complex ("ctan (0 - 0 i) == 0.0 - 0 i", FUNC(ctan) (BUILD_COMPLEX (0, minus_zero)), BUILD_COMPLEX (0.0, minus_zero), 0, 0, 0); + check_complex ("ctan (-0 + 0 i) == -0 + 0.0 i", FUNC(ctan) (BUILD_COMPLEX (minus_zero, 0)), BUILD_COMPLEX (minus_zero, 0.0), 0, 0, 0); + check_complex ("ctan (-0 - 0 i) == -0 - 0 i", FUNC(ctan) (BUILD_COMPLEX (minus_zero, minus_zero)), BUILD_COMPLEX (minus_zero, minus_zero), 0, 0, 0); + + check_complex ("ctan (0 + inf i) == 0.0 + 1.0 i", FUNC(ctan) (BUILD_COMPLEX (0, plus_infty)), BUILD_COMPLEX (0.0, 1.0), 0, 0, 0); + check_complex ("ctan (1 + inf i) == 0.0 + 1.0 i", FUNC(ctan) (BUILD_COMPLEX (1, plus_infty)), BUILD_COMPLEX (0.0, 1.0), 0, 0, 0); + check_complex ("ctan (-0 + inf i) == -0 + 1.0 i", FUNC(ctan) (BUILD_COMPLEX (minus_zero, plus_infty)), BUILD_COMPLEX (minus_zero, 1.0), 0, 0, 0); + check_complex ("ctan (-1 + inf i) == -0 + 1.0 i", FUNC(ctan) (BUILD_COMPLEX (-1, plus_infty)), BUILD_COMPLEX (minus_zero, 1.0), 0, 0, 0); + + check_complex ("ctan (0 - inf i) == 0.0 - 1.0 i", FUNC(ctan) (BUILD_COMPLEX (0, minus_infty)), BUILD_COMPLEX (0.0, -1.0), 0, 0, 0); + check_complex ("ctan (1 - inf i) == 0.0 - 1.0 i", FUNC(ctan) (BUILD_COMPLEX (1, minus_infty)), BUILD_COMPLEX (0.0, -1.0), 0, 0, 0); + check_complex ("ctan (-0 - inf i) == -0 - 1.0 i", FUNC(ctan) (BUILD_COMPLEX (minus_zero, minus_infty)), BUILD_COMPLEX (minus_zero, -1.0), 0, 0, 0); + check_complex ("ctan (-1 - inf i) == -0 - 1.0 i", FUNC(ctan) (BUILD_COMPLEX (-1, minus_infty)), BUILD_COMPLEX (minus_zero, -1.0), 0, 0, 0); + + check_complex ("ctan (inf + 0 i) == NaN + NaN i plus invalid exception", FUNC(ctan) (BUILD_COMPLEX (plus_infty, 0)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); + check_complex ("ctan (inf + 2 i) == NaN + NaN i plus invalid exception", FUNC(ctan) (BUILD_COMPLEX (plus_infty, 2)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); + check_complex ("ctan (-inf + 0 i) == NaN + NaN i plus invalid exception", FUNC(ctan) (BUILD_COMPLEX (minus_infty, 0)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); + check_complex ("ctan (-inf + 2 i) == NaN + NaN i plus invalid exception", FUNC(ctan) (BUILD_COMPLEX (minus_infty, 2)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); + check_complex ("ctan (inf - 0 i) == NaN + NaN i plus invalid exception", FUNC(ctan) (BUILD_COMPLEX (plus_infty, minus_zero)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); + check_complex ("ctan (inf - 2 i) == NaN + NaN i plus invalid exception", FUNC(ctan) (BUILD_COMPLEX (plus_infty, -2)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); + check_complex ("ctan (-inf - 0 i) == NaN + NaN i plus invalid exception", FUNC(ctan) (BUILD_COMPLEX (minus_infty, minus_zero)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); + check_complex ("ctan (-inf - 2 i) == NaN + NaN i plus invalid exception", FUNC(ctan) (BUILD_COMPLEX (minus_infty, -2)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); + + check_complex ("ctan (NaN + inf i) == 0.0 + 1.0 i plus sign of zero/inf not specified", FUNC(ctan) (BUILD_COMPLEX (nan_value, plus_infty)), BUILD_COMPLEX (0.0, 1.0), 0, 0, IGNORE_ZERO_INF_SIGN); + check_complex ("ctan (NaN - inf i) == 0.0 - 1.0 i plus sign of zero/inf not specified", FUNC(ctan) (BUILD_COMPLEX (nan_value, minus_infty)), BUILD_COMPLEX (0.0, -1.0), 0, 0, IGNORE_ZERO_INF_SIGN); + + check_complex ("ctan (0 + NaN i) == 0.0 + NaN i", FUNC(ctan) (BUILD_COMPLEX (0, nan_value)), BUILD_COMPLEX (0.0, nan_value), 0, 0, 0); + check_complex ("ctan (-0 + NaN i) == -0 + NaN i", FUNC(ctan) (BUILD_COMPLEX (minus_zero, nan_value)), BUILD_COMPLEX (minus_zero, nan_value), 0, 0, 0); + + check_complex ("ctan (0.5 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(ctan) (BUILD_COMPLEX (0.5, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + check_complex ("ctan (-4.5 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(ctan) (BUILD_COMPLEX (-4.5, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + + check_complex ("ctan (NaN + 0 i) == NaN + NaN i plus invalid exception allowed", FUNC(ctan) (BUILD_COMPLEX (nan_value, 0)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + check_complex ("ctan (NaN + 5 i) == NaN + NaN i plus invalid exception allowed", FUNC(ctan) (BUILD_COMPLEX (nan_value, 5)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + check_complex ("ctan (NaN - 0 i) == NaN + NaN i plus invalid exception allowed", FUNC(ctan) (BUILD_COMPLEX (nan_value, minus_zero)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + check_complex ("ctan (NaN - 0.25 i) == NaN + NaN i plus invalid exception allowed", FUNC(ctan) (BUILD_COMPLEX (nan_value, -0.25)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + + check_complex ("ctan (NaN + NaN i) == NaN + NaN i", FUNC(ctan) (BUILD_COMPLEX (nan_value, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, 0); + + check_complex ("ctan (0.7 + 1.2 i) == 0.1720734197630349001 + 0.9544807059989405538 i", FUNC(ctan) (BUILD_COMPLEX (0.7L, 1.2L)), BUILD_COMPLEX (0.1720734197630349001L, 0.9544807059989405538L), DELTA766, 0, 0); + check_complex ("ctan (-2 - 3 i) == 0.0037640256415042482 - 1.0032386273536098014 i", FUNC(ctan) (BUILD_COMPLEX (-2, -3)), BUILD_COMPLEX (0.0037640256415042482L, -1.0032386273536098014L), DELTA767, 0, 0); + + print_complex_max_error ("ctan", DELTActan, 0); +} + + +static void +ctanh_test (void) +{ + errno = 0; + FUNC(ctanh) (BUILD_COMPLEX (0, 0)); + if (errno == ENOSYS) + /* Function not implemented. */ + return; + + init_max_error (); + + check_complex ("ctanh (0 + 0 i) == 0.0 + 0.0 i", FUNC(ctanh) (BUILD_COMPLEX (0, 0)), BUILD_COMPLEX (0.0, 0.0), 0, 0, 0); + check_complex ("ctanh (0 - 0 i) == 0.0 - 0 i", FUNC(ctanh) (BUILD_COMPLEX (0, minus_zero)), BUILD_COMPLEX (0.0, minus_zero), 0, 0, 0); + check_complex ("ctanh (-0 + 0 i) == -0 + 0.0 i", FUNC(ctanh) (BUILD_COMPLEX (minus_zero, 0)), BUILD_COMPLEX (minus_zero, 0.0), 0, 0, 0); + check_complex ("ctanh (-0 - 0 i) == -0 - 0 i", FUNC(ctanh) (BUILD_COMPLEX (minus_zero, minus_zero)), BUILD_COMPLEX (minus_zero, minus_zero), 0, 0, 0); + + check_complex ("ctanh (inf + 0 i) == 1.0 + 0.0 i", FUNC(ctanh) (BUILD_COMPLEX (plus_infty, 0)), BUILD_COMPLEX (1.0, 0.0), 0, 0, 0); + check_complex ("ctanh (inf + 1 i) == 1.0 + 0.0 i", FUNC(ctanh) (BUILD_COMPLEX (plus_infty, 1)), BUILD_COMPLEX (1.0, 0.0), 0, 0, 0); + check_complex ("ctanh (inf - 0 i) == 1.0 - 0 i", FUNC(ctanh) (BUILD_COMPLEX (plus_infty, minus_zero)), BUILD_COMPLEX (1.0, minus_zero), 0, 0, 0); + check_complex ("ctanh (inf - 1 i) == 1.0 - 0 i", FUNC(ctanh) (BUILD_COMPLEX (plus_infty, -1)), BUILD_COMPLEX (1.0, minus_zero), 0, 0, 0); + check_complex ("ctanh (-inf + 0 i) == -1.0 + 0.0 i", FUNC(ctanh) (BUILD_COMPLEX (minus_infty, 0)), BUILD_COMPLEX (-1.0, 0.0), 0, 0, 0); + check_complex ("ctanh (-inf + 1 i) == -1.0 + 0.0 i", FUNC(ctanh) (BUILD_COMPLEX (minus_infty, 1)), BUILD_COMPLEX (-1.0, 0.0), 0, 0, 0); + check_complex ("ctanh (-inf - 0 i) == -1.0 - 0 i", FUNC(ctanh) (BUILD_COMPLEX (minus_infty, minus_zero)), BUILD_COMPLEX (-1.0, minus_zero), 0, 0, 0); + check_complex ("ctanh (-inf - 1 i) == -1.0 - 0 i", FUNC(ctanh) (BUILD_COMPLEX (minus_infty, -1)), BUILD_COMPLEX (-1.0, minus_zero), 0, 0, 0); + + check_complex ("ctanh (0 + inf i) == NaN + NaN i plus invalid exception", FUNC(ctanh) (BUILD_COMPLEX (0, plus_infty)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); + check_complex ("ctanh (2 + inf i) == NaN + NaN i plus invalid exception", FUNC(ctanh) (BUILD_COMPLEX (2, plus_infty)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); + check_complex ("ctanh (0 - inf i) == NaN + NaN i plus invalid exception", FUNC(ctanh) (BUILD_COMPLEX (0, minus_infty)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); + check_complex ("ctanh (2 - inf i) == NaN + NaN i plus invalid exception", FUNC(ctanh) (BUILD_COMPLEX (2, minus_infty)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); + check_complex ("ctanh (-0 + inf i) == NaN + NaN i plus invalid exception", FUNC(ctanh) (BUILD_COMPLEX (minus_zero, plus_infty)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); + check_complex ("ctanh (-2 + inf i) == NaN + NaN i plus invalid exception", FUNC(ctanh) (BUILD_COMPLEX (-2, plus_infty)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); + check_complex ("ctanh (-0 - inf i) == NaN + NaN i plus invalid exception", FUNC(ctanh) (BUILD_COMPLEX (minus_zero, minus_infty)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); + check_complex ("ctanh (-2 - inf i) == NaN + NaN i plus invalid exception", FUNC(ctanh) (BUILD_COMPLEX (-2, minus_infty)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION); + + check_complex ("ctanh (inf + NaN i) == 1.0 + 0.0 i plus sign of zero/inf not specified", FUNC(ctanh) (BUILD_COMPLEX (plus_infty, nan_value)), BUILD_COMPLEX (1.0, 0.0), 0, 0, IGNORE_ZERO_INF_SIGN); + check_complex ("ctanh (-inf + NaN i) == -1.0 + 0.0 i plus sign of zero/inf not specified", FUNC(ctanh) (BUILD_COMPLEX (minus_infty, nan_value)), BUILD_COMPLEX (-1.0, 0.0), 0, 0, IGNORE_ZERO_INF_SIGN); + + check_complex ("ctanh (NaN + 0 i) == NaN + 0.0 i", FUNC(ctanh) (BUILD_COMPLEX (nan_value, 0)), BUILD_COMPLEX (nan_value, 0.0), 0, 0, 0); + check_complex ("ctanh (NaN - 0 i) == NaN - 0 i", FUNC(ctanh) (BUILD_COMPLEX (nan_value, minus_zero)), BUILD_COMPLEX (nan_value, minus_zero), 0, 0, 0); + + check_complex ("ctanh (NaN + 0.5 i) == NaN + NaN i plus invalid exception allowed", FUNC(ctanh) (BUILD_COMPLEX (nan_value, 0.5)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + check_complex ("ctanh (NaN - 4.5 i) == NaN + NaN i plus invalid exception allowed", FUNC(ctanh) (BUILD_COMPLEX (nan_value, -4.5)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + + check_complex ("ctanh (0 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(ctanh) (BUILD_COMPLEX (0, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + check_complex ("ctanh (5 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(ctanh) (BUILD_COMPLEX (5, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + check_complex ("ctanh (-0 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(ctanh) (BUILD_COMPLEX (minus_zero, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + check_complex ("ctanh (-0.25 + NaN i) == NaN + NaN i plus invalid exception allowed", FUNC(ctanh) (BUILD_COMPLEX (-0.25, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, INVALID_EXCEPTION_OK); + + check_complex ("ctanh (NaN + NaN i) == NaN + NaN i", FUNC(ctanh) (BUILD_COMPLEX (nan_value, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0, 0); + + check_complex ("ctanh (0 + pi/4 i) == 0.0 + 1.0 i", FUNC(ctanh) (BUILD_COMPLEX (0, M_PI_4l)), BUILD_COMPLEX (0.0, 1.0), DELTA799, 0, 0); + + check_complex ("ctanh (0.7 + 1.2 i) == 1.3472197399061191630 + 0.4778641038326365540 i", FUNC(ctanh) (BUILD_COMPLEX (0.7L, 1.2L)), BUILD_COMPLEX (1.3472197399061191630L, 0.4778641038326365540L), DELTA800, 0, 0); + check_complex ("ctanh (-2 - 3 i) == -0.9653858790221331242 + 0.0098843750383224937 i", FUNC(ctanh) (BUILD_COMPLEX (-2, -3)), BUILD_COMPLEX (-0.9653858790221331242L, 0.0098843750383224937L), DELTA801, 0, 0); + + print_complex_max_error ("ctanh", DELTActanh, 0); +} +#endif + +static void +erf_test (void) +{ + errno = 0; + FUNC(erf) (0); + if (errno == ENOSYS) + /* Function not implemented. */ + return; + + init_max_error (); + + check_float ("erf (0) == 0", FUNC(erf) (0), 0, 0, 0, 0); + check_float ("erf (-0) == -0", FUNC(erf) (minus_zero), minus_zero, 0, 0, 0); + check_float ("erf (inf) == 1", FUNC(erf) (plus_infty), 1, 0, 0, 0); + check_float ("erf (-inf) == -1", FUNC(erf) (minus_infty), -1, 0, 0, 0); + check_float ("erf (NaN) == NaN", FUNC(erf) (nan_value), nan_value, 0, 0, 0); + + check_float ("erf (0.7) == 0.67780119383741847297", FUNC(erf) (0.7L), 0.67780119383741847297L, 0, 0, 0); + + check_float ("erf (1.2) == 0.91031397822963538024", FUNC(erf) (1.2L), 0.91031397822963538024L, 0, 0, 0); + check_float ("erf (2.0) == 0.99532226501895273416", FUNC(erf) (2.0), 0.99532226501895273416L, 0, 0, 0); + check_float ("erf (4.1) == 0.99999999329997234592", FUNC(erf) (4.1L), 0.99999999329997234592L, 0, 0, 0); + check_float ("erf (27) == 1.0", FUNC(erf) (27), 1.0L, 0, 0, 0); + + print_max_error ("erf", 0, 0); +} + + +static void +erfc_test (void) +{ + errno = 0; + FUNC(erfc) (0); + if (errno == ENOSYS) + /* Function not implemented. */ + return; + + init_max_error (); + + check_float ("erfc (inf) == 0.0", FUNC(erfc) (plus_infty), 0.0, 0, 0, 0); + check_float ("erfc (-inf) == 2.0", FUNC(erfc) (minus_infty), 2.0, 0, 0, 0); + check_float ("erfc (0.0) == 1.0", FUNC(erfc) (0.0), 1.0, 0, 0, 0); + check_float ("erfc (-0) == 1.0", FUNC(erfc) (minus_zero), 1.0, 0, 0, 0); + check_float ("erfc (NaN) == NaN", FUNC(erfc) (nan_value), nan_value, 0, 0, 0); + + check_float ("erfc (0.7) == 0.32219880616258152702", FUNC(erfc) (0.7L), 0.32219880616258152702L, DELTA817, 0, 0); + + check_float ("erfc (1.2) == 0.089686021770364619762", FUNC(erfc) (1.2L), 0.089686021770364619762L, DELTA818, 0, 0); + check_float ("erfc (2.0) == 0.0046777349810472658379", FUNC(erfc) (2.0), 0.0046777349810472658379L, DELTA819, 0, 0); + check_float ("erfc (4.1) == 0.67000276540848983727e-8", FUNC(erfc) (4.1L), 0.67000276540848983727e-8L, DELTA820, 0, 0); + check_float ("erfc (9) == 0.41370317465138102381e-36", FUNC(erfc) (9), 0.41370317465138102381e-36L, DELTA821, 0, 0); + + print_max_error ("erfc", DELTAerfc, 0); +} + +static void +exp_test (void) +{ + errno = 0; + FUNC(exp) (0); + if (errno == ENOSYS) + /* Function not implemented. */ + return; + + init_max_error (); + + check_float ("exp (0) == 1", FUNC(exp) (0), 1, 0, 0, 0); + check_float ("exp (-0) == 1", FUNC(exp) (minus_zero), 1, 0, 0, 0); + +#ifndef TEST_INLINE + check_float ("exp (inf) == inf", FUNC(exp) (plus_infty), plus_infty, 0, 0, 0); + check_float ("exp (-inf) == 0", FUNC(exp) (minus_infty), 0, 0, 0, 0); +#endif + check_float ("exp (NaN) == NaN", FUNC(exp) (nan_value), nan_value, 0, 0, 0); + check_float ("exp (1) == e", FUNC(exp) (1), M_El, 0, 0, 0); + + check_float ("exp (2) == e^2", FUNC(exp) (2), M_E2l, 0, 0, 0); + check_float ("exp (3) == e^3", FUNC(exp) (3), M_E3l, 0, 0, 0); + check_float ("exp (0.7) == 2.0137527074704765216", FUNC(exp) (0.7L), 2.0137527074704765216L, DELTA830, 0, 0); + check_float ("exp (50.0) == 5184705528587072464087.45332293348538", FUNC(exp) (50.0L), 5184705528587072464087.45332293348538L, DELTA831, 0, 0); +#ifdef TEST_LDOUBLE + /* The result can only be represented in long double. */ + check_float ("exp (1000.0) == 0.197007111401704699388887935224332313e435", FUNC(exp) (1000.0L), 0.197007111401704699388887935224332313e435L, DELTA832, 0, 0); +#endif + print_max_error ("exp", DELTAexp, 0); +} + + +#if 0 /* XXX scp XXX */ +static void +exp10_test (void) +{ + errno = 0; + FUNC(exp10) (0); + if (errno == ENOSYS) + /* Function not implemented. */ + return; + + init_max_error (); + + check_float ("exp10 (0) == 1", FUNC(exp10) (0), 1, 0, 0, 0); + check_float ("exp10 (-0) == 1", FUNC(exp10) (minus_zero), 1, 0, 0, 0); + + check_float ("exp10 (inf) == inf", FUNC(exp10) (plus_infty), plus_infty, 0, 0, 0); + check_float ("exp10 (-inf) == 0", FUNC(exp10) (minus_infty), 0, 0, 0, 0); + check_float ("exp10 (NaN) == NaN", FUNC(exp10) (nan_value), nan_value, 0, 0, 0); + check_float ("exp10 (3) == 1000", FUNC(exp10) (3), 1000, DELTA838, 0, 0); + check_float ("exp10 (-1) == 0.1", FUNC(exp10) (-1), 0.1L, DELTA839, 0, 0); + check_float ("exp10 (1e6) == inf", FUNC(exp10) (1e6), plus_infty, 0, 0, 0); + check_float ("exp10 (-1e6) == 0", FUNC(exp10) (-1e6), 0, 0, 0, 0); + check_float ("exp10 (0.7) == 5.0118723362727228500155418688494574", FUNC(exp10) (0.7L), 5.0118723362727228500155418688494574L, DELTA842, 0, 0); + + print_max_error ("exp10", DELTAexp10, 0); +} +#endif + +static void +exp2_test (void) +{ + errno = 0; + FUNC(exp2) (0); + if (errno == ENOSYS) + /* Function not implemented. */ + return; + + init_max_error (); + + check_float ("exp2 (0) == 1", FUNC(exp2) (0), 1, 0, 0, 0); + check_float ("exp2 (-0) == 1", FUNC(exp2) (minus_zero), 1, 0, 0, 0); + check_float ("exp2 (inf) == inf", FUNC(exp2) (plus_infty), plus_infty, 0, 0, 0); + check_float ("exp2 (-inf) == 0", FUNC(exp2) (minus_infty), 0, 0, 0, 0); + check_float ("exp2 (NaN) == NaN", FUNC(exp2) (nan_value), nan_value, 0, 0, 0); + + check_float ("exp2 (10) == 1024", FUNC(exp2) (10), 1024, 0, 0, 0); + check_float ("exp2 (-1) == 0.5", FUNC(exp2) (-1), 0.5, 0, 0, 0); + check_float ("exp2 (1e6) == inf", FUNC(exp2) (1e6), plus_infty, 0, 0, 0); + check_float ("exp2 (-1e6) == 0", FUNC(exp2) (-1e6), 0, 0, 0, 0); + check_float ("exp2 (0.7) == 1.6245047927124710452", FUNC(exp2) (0.7L), 1.6245047927124710452L, DELTA852, 0, 0); + + print_max_error ("exp2", DELTAexp2, 0); +} + +static void +expm1_test (void) +{ + errno = 0; + FUNC(expm1) (0); + if (errno == ENOSYS) + /* Function not implemented. */ + return; + + init_max_error (); + + check_float ("expm1 (0) == 0", FUNC(expm1) (0), 0, 0, 0, 0); + check_float ("expm1 (-0) == -0", FUNC(expm1) (minus_zero), minus_zero, 0, 0, 0); + +#ifndef TEST_INLINE + check_float ("expm1 (inf) == inf", FUNC(expm1) (plus_infty), plus_infty, 0, 0, 0); + check_float ("expm1 (-inf) == -1", FUNC(expm1) (minus_infty), -1, 0, 0, 0); +#endif + check_float ("expm1 (NaN) == NaN", FUNC(expm1) (nan_value), nan_value, 0, 0, 0); + + check_float ("expm1 (1) == M_El - 1.0", FUNC(expm1) (1), M_El - 1.0, 1, 0, 0); + check_float ("expm1 (0.7) == 1.0137527074704765216", FUNC(expm1) (0.7L), 1.0137527074704765216L, DELTA859, 0, 0); + + print_max_error ("expm1", DELTAexpm1, 0); +} + +static void +fabs_test (void) +{ + init_max_error (); + + check_float ("fabs (0) == 0", FUNC(fabs) ((FLOAT)0.0), 0, 0, 0, 0); + check_float ("fabs (-0) == 0", FUNC(fabs) (minus_zero), 0, 0, 0, 0); + + check_float ("fabs (inf) == inf", FUNC(fabs) (plus_infty), plus_infty, 0, 0, 0); + check_float ("fabs (-inf) == inf", FUNC(fabs) (minus_infty), plus_infty, 0, 0, 0); + check_float ("fabs (NaN) == NaN", FUNC(fabs) (nan_value), nan_value, 0, 0, 0); + + check_float ("fabs (38.0) == 38.0", FUNC(fabs) ((FLOAT)38.0), 38.0, 0, 0, 0); + check_float ("fabs (-e) == e", FUNC(fabs) ((FLOAT)-M_El), M_El, 0, 0, 0); + + print_max_error ("fabs", 0, 0); +} + +static void +fdim_test (void) +{ + init_max_error (); + + check_float ("fdim (0, 0) == 0", FUNC(fdim) (0, 0), 0, 0, 0, 0); + check_float ("fdim (9, 0) == 9", FUNC(fdim) (9, 0), 9, 0, 0, 0); + check_float ("fdim (0, 9) == 0", FUNC(fdim) (0, 9), 0, 0, 0, 0); + check_float ("fdim (-9, 0) == 0", FUNC(fdim) (-9, 0), 0, 0, 0, 0); + check_float ("fdim (0, -9) == 9", FUNC(fdim) (0, -9), 9, 0, 0, 0); + + check_float ("fdim (inf, 9) == inf", FUNC(fdim) (plus_infty, 9), plus_infty, 0, 0, 0); + check_float ("fdim (inf, -9) == inf", FUNC(fdim) (plus_infty, -9), plus_infty, 0, 0, 0); + check_float ("fdim (-inf, 9) == 0", FUNC(fdim) (minus_infty, 9), 0, 0, 0, 0); + check_float ("fdim (-inf, -9) == 0", FUNC(fdim) (minus_infty, -9), 0, 0, 0, 0); + check_float ("fdim (9, -inf) == inf", FUNC(fdim) (9, minus_infty), plus_infty, 0, 0, 0); + check_float ("fdim (-9, -inf) == inf", FUNC(fdim) (-9, minus_infty), plus_infty, 0, 0, 0); + check_float ("fdim (9, inf) == 0", FUNC(fdim) (9, plus_infty), 0, 0, 0, 0); + check_float ("fdim (-9, inf) == 0", FUNC(fdim) (-9, plus_infty), 0, 0, 0, 0); + + check_float ("fdim (0, NaN) == NaN", FUNC(fdim) (0, nan_value), nan_value, 0, 0, 0); + check_float ("fdim (9, NaN) == NaN", FUNC(fdim) (9, nan_value), nan_value, 0, 0, 0); + check_float ("fdim (-9, NaN) == NaN", FUNC(fdim) (-9, nan_value), nan_value, 0, 0, 0); + check_float ("fdim (NaN, 9) == NaN", FUNC(fdim) (nan_value, 9), nan_value, 0, 0, 0); + check_float ("fdim (NaN, -9) == NaN", FUNC(fdim) (nan_value, -9), nan_value, 0, 0, 0); + check_float ("fdim (inf, NaN) == NaN", FUNC(fdim) (plus_infty, nan_value), nan_value, 0, 0, 0); + check_float ("fdim (-inf, NaN) == NaN", FUNC(fdim) (minus_infty, nan_value), nan_value, 0, 0, 0); + check_float ("fdim (NaN, inf) == NaN", FUNC(fdim) (nan_value, plus_infty), nan_value, 0, 0, 0); + check_float ("fdim (NaN, -inf) == NaN", FUNC(fdim) (nan_value, minus_infty), nan_value, 0, 0, 0); + check_float ("fdim (NaN, NaN) == NaN", FUNC(fdim) (nan_value, nan_value), nan_value, 0, 0, 0); + + print_max_error ("fdim", 0, 0); +} + +static void +floor_test (void) +{ + init_max_error (); + + check_float ("floor (0.0) == 0.0", FUNC(floor) (0.0), 0.0, 0, 0, 0); + check_float ("floor (-0) == -0", FUNC(floor) (minus_zero), minus_zero, 0, 0, 0); + check_float ("floor (inf) == inf", FUNC(floor) (plus_infty), plus_infty, 0, 0, 0); + check_float ("floor (-inf) == -inf", FUNC(floor) (minus_infty), minus_infty, 0, 0, 0); + check_float ("floor (NaN) == NaN", FUNC(floor) (nan_value), nan_value, 0, 0, 0); + + check_float ("floor (pi) == 3.0", FUNC(floor) (M_PIl), 3.0, 0, 0, 0); + check_float ("floor (-pi) == -4.0", FUNC(floor) (-M_PIl), -4.0, 0, 0, 0); + + print_max_error ("floor", 0, 0); +} + +static void +fma_test (void) +{ + init_max_error (); + + check_float ("fma (1.0, 2.0, 3.0) == 5.0", FUNC(fma) (1.0, 2.0, 3.0), 5.0, 0, 0, 0); + check_float ("fma (NaN, 2.0, 3.0) == NaN", FUNC(fma) (nan_value, 2.0, 3.0), nan_value, 0, 0, 0); + check_float ("fma (1.0, NaN, 3.0) == NaN", FUNC(fma) (1.0, nan_value, 3.0), nan_value, 0, 0, 0); + check_float ("fma (1.0, 2.0, NaN) == NaN plus invalid exception allowed", FUNC(fma) (1.0, 2.0, nan_value), nan_value, 0, 0, INVALID_EXCEPTION_OK); + check_float ("fma (inf, 0.0, NaN) == NaN plus invalid exception allowed", FUNC(fma) (plus_infty, 0.0, nan_value), nan_value, 0, 0, INVALID_EXCEPTION_OK); + check_float ("fma (-inf, 0.0, NaN) == NaN plus invalid exception allowed", FUNC(fma) (minus_infty, 0.0, nan_value), nan_value, 0, 0, INVALID_EXCEPTION_OK); + check_float ("fma (0.0, inf, NaN) == NaN plus invalid exception allowed", FUNC(fma) (0.0, plus_infty, nan_value), nan_value, 0, 0, INVALID_EXCEPTION_OK); + check_float ("fma (0.0, -inf, NaN) == NaN plus invalid exception allowed", FUNC(fma) (0.0, minus_infty, nan_value), nan_value, 0, 0, INVALID_EXCEPTION_OK); + check_float ("fma (inf, 0.0, 1.0) == NaN plus invalid exception", FUNC(fma) (plus_infty, 0.0, 1.0), nan_value, 0, 0, INVALID_EXCEPTION); + check_float ("fma (-inf, 0.0, 1.0) == NaN plus invalid exception", FUNC(fma) (minus_infty, 0.0, 1.0), nan_value, 0, 0, INVALID_EXCEPTION); + check_float ("fma (0.0, inf, 1.0) == NaN plus invalid exception", FUNC(fma) (0.0, plus_infty, 1.0), nan_value, 0, 0, INVALID_EXCEPTION); + check_float ("fma (0.0, -inf, 1.0) == NaN plus invalid exception", FUNC(fma) (0.0, minus_infty, 1.0), nan_value, 0, 0, INVALID_EXCEPTION); + + check_float ("fma (inf, inf, -inf) == NaN plus invalid exception", FUNC(fma) (plus_infty, plus_infty, minus_infty), nan_value, 0, 0, INVALID_EXCEPTION); + check_float ("fma (-inf, inf, inf) == NaN plus invalid exception", FUNC(fma) (minus_infty, plus_infty, plus_infty), nan_value, 0, 0, INVALID_EXCEPTION); + check_float ("fma (inf, -inf, inf) == NaN plus invalid exception", FUNC(fma) (plus_infty, minus_infty, plus_infty), nan_value, 0, 0, INVALID_EXCEPTION); + check_float ("fma (-inf, -inf, -inf) == NaN plus invalid exception", FUNC(fma) (minus_infty, minus_infty, minus_infty), nan_value, 0, 0, INVALID_EXCEPTION); + + print_max_error ("fma", 0, 0); +} + + +static void +fmax_test (void) +{ + init_max_error (); + + check_float ("fmax (0, 0) == 0", FUNC(fmax) (0, 0), 0, 0, 0, 0); + check_float ("fmax (-0, -0) == -0", FUNC(fmax) (minus_zero, minus_zero), minus_zero, 0, 0, 0); + check_float ("fmax (9, 0) == 9", FUNC(fmax) (9, 0), 9, 0, 0, 0); + check_float ("fmax (0, 9) == 9", FUNC(fmax) (0, 9), 9, 0, 0, 0); + check_float ("fmax (-9, 0) == 0", FUNC(fmax) (-9, 0), 0, 0, 0, 0); + check_float ("fmax (0, -9) == 0", FUNC(fmax) (0, -9), 0, 0, 0, 0); + + check_float ("fmax (inf, 9) == inf", FUNC(fmax) (plus_infty, 9), plus_infty, 0, 0, 0); + check_float ("fmax (0, inf) == inf", FUNC(fmax) (0, plus_infty), plus_infty, 0, 0, 0); + check_float ("fmax (-9, inf) == inf", FUNC(fmax) (-9, plus_infty), plus_infty, 0, 0, 0); + check_float ("fmax (inf, -9) == inf", FUNC(fmax) (plus_infty, -9), plus_infty, 0, 0, 0); + + check_float ("fmax (-inf, 9) == 9", FUNC(fmax) (minus_infty, 9), 9, 0, 0, 0); + check_float ("fmax (-inf, -9) == -9", FUNC(fmax) (minus_infty, -9), -9, 0, 0, 0); + check_float ("fmax (9, -inf) == 9", FUNC(fmax) (9, minus_infty), 9, 0, 0, 0); + check_float ("fmax (-9, -inf) == -9", FUNC(fmax) (-9, minus_infty), -9, 0, 0, 0); + + check_float ("fmax (0, NaN) == 0", FUNC(fmax) (0, nan_value), 0, 0, 0, 0); + check_float ("fmax (9, NaN) == 9", FUNC(fmax) (9, nan_value), 9, 0, 0, 0); + check_float ("fmax (-9, NaN) == -9", FUNC(fmax) (-9, nan_value), -9, 0, 0, 0); + check_float ("fmax (NaN, 0) == 0", FUNC(fmax) (nan_value, 0), 0, 0, 0, 0); + check_float ("fmax (NaN, 9) == 9", FUNC(fmax) (nan_value, 9), 9, 0, 0, 0); + check_float ("fmax (NaN, -9) == -9", FUNC(fmax) (nan_value, -9), -9, 0, 0, 0); + check_float ("fmax (inf, NaN) == inf", FUNC(fmax) (plus_infty, nan_value), plus_infty, 0, 0, 0); + check_float ("fmax (-inf, NaN) == -inf", FUNC(fmax) (minus_infty, nan_value), minus_infty, 0, 0, 0); + check_float ("fmax (NaN, inf) == inf", FUNC(fmax) (nan_value, plus_infty), plus_infty, 0, 0, 0); + check_float ("fmax (NaN, -inf) == -inf", FUNC(fmax) (nan_value, minus_infty), minus_infty, 0, 0, 0); + check_float ("fmax (NaN, NaN) == NaN", FUNC(fmax) (nan_value, nan_value), nan_value, 0, 0, 0); + + print_max_error ("fmax", 0, 0); +} + + +static void +fmin_test (void) +{ + init_max_error (); + + check_float ("fmin (0, 0) == 0", FUNC(fmin) (0, 0), 0, 0, 0, 0); + check_float ("fmin (-0, -0) == -0", FUNC(fmin) (minus_zero, minus_zero), minus_zero, 0, 0, 0); + check_float ("fmin (9, 0) == 0", FUNC(fmin) (9, 0), 0, 0, 0, 0); + check_float ("fmin (0, 9) == 0", FUNC(fmin) (0, 9), 0, 0, 0, 0); + check_float ("fmin (-9, 0) == -9", FUNC(fmin) (-9, 0), -9, 0, 0, 0); + check_float ("fmin (0, -9) == -9", FUNC(fmin) (0, -9), -9, 0, 0, 0); + + check_float ("fmin (inf, 9) == 9", FUNC(fmin) (plus_infty, 9), 9, 0, 0, 0); + check_float ("fmin (9, inf) == 9", FUNC(fmin) (9, plus_infty), 9, 0, 0, 0); + check_float ("fmin (inf, -9) == -9", FUNC(fmin) (plus_infty, -9), -9, 0, 0, 0); + check_float ("fmin (-9, inf) == -9", FUNC(fmin) (-9, plus_infty), -9, 0, 0, 0); + check_float ("fmin (-inf, 9) == -inf", FUNC(fmin) (minus_infty, 9), minus_infty, 0, 0, 0); + check_float ("fmin (-inf, -9) == -inf", FUNC(fmin) (minus_infty, -9), minus_infty, 0, 0, 0); + check_float ("fmin (9, -inf) == -inf", FUNC(fmin) (9, minus_infty), minus_infty, 0, 0, 0); + check_float ("fmin (-9, -inf) == -inf", FUNC(fmin) (-9, minus_infty), minus_infty, 0, 0, 0); + + check_float ("fmin (0, NaN) == 0", FUNC(fmin) (0, nan_value), 0, 0, 0, 0); + check_float ("fmin (9, NaN) == 9", FUNC(fmin) (9, nan_value), 9, 0, 0, 0); + check_float ("fmin (-9, NaN) == -9", FUNC(fmin) (-9, nan_value), -9, 0, 0, 0); + check_float ("fmin (NaN, 0) == 0", FUNC(fmin) (nan_value, 0), 0, 0, 0, 0); + check_float ("fmin (NaN, 9) == 9", FUNC(fmin) (nan_value, 9), 9, 0, 0, 0); + check_float ("fmin (NaN, -9) == -9", FUNC(fmin) (nan_value, -9), -9, 0, 0, 0); + check_float ("fmin (inf, NaN) == inf", FUNC(fmin) (plus_infty, nan_value), plus_infty, 0, 0, 0); + check_float ("fmin (-inf, NaN) == -inf", FUNC(fmin) (minus_infty, nan_value), minus_infty, 0, 0, 0); + check_float ("fmin (NaN, inf) == inf", FUNC(fmin) (nan_value, plus_infty), plus_infty, 0, 0, 0); + check_float ("fmin (NaN, -inf) == -inf", FUNC(fmin) (nan_value, minus_infty), minus_infty, 0, 0, 0); + check_float ("fmin (NaN, NaN) == NaN", FUNC(fmin) (nan_value, nan_value), nan_value, 0, 0, 0); + + print_max_error ("fmin", 0, 0); +} + + +static void +fmod_test (void) +{ + errno = 0; + FUNC(fmod) (6.5, 2.3L); + if (errno == ENOSYS) + /* Function not implemented. */ + return; + + init_max_error (); + + /* fmod (+0, y) == +0 for y != 0. */ + check_float ("fmod (0, 3) == 0", FUNC(fmod) (0, 3), 0, 0, 0, 0); + + /* fmod (-0, y) == -0 for y != 0. */ + check_float ("fmod (-0, 3) == -0", FUNC(fmod) (minus_zero, 3), minus_zero, 0, 0, 0); + + /* fmod (+inf, y) == NaN plus invalid exception. */ + check_float ("fmod (inf, 3) == NaN plus invalid exception", FUNC(fmod) (plus_infty, 3), nan_value, 0, 0, INVALID_EXCEPTION); + /* fmod (-inf, y) == NaN plus invalid exception. */ + check_float ("fmod (-inf, 3) == NaN plus invalid exception", FUNC(fmod) (minus_infty, 3), nan_value, 0, 0, INVALID_EXCEPTION); + /* fmod (x, +0) == NaN plus invalid exception. */ + check_float ("fmod (3, 0) == NaN plus invalid exception", FUNC(fmod) (3, 0), nan_value, 0, 0, INVALID_EXCEPTION); + /* fmod (x, -0) == NaN plus invalid exception. */ + check_float ("fmod (3, -0) == NaN plus invalid exception", FUNC(fmod) (3, minus_zero), nan_value, 0, 0, INVALID_EXCEPTION); + + /* fmod (x, +inf) == x for x not infinite. */ + check_float ("fmod (3.0, inf) == 3.0", FUNC(fmod) (3.0, plus_infty), 3.0, 0, 0, 0); + /* fmod (x, -inf) == x for x not infinite. */ + check_float ("fmod (3.0, -inf) == 3.0", FUNC(fmod) (3.0, minus_infty), 3.0, 0, 0, 0); + + check_float ("fmod (NaN, NaN) == NaN", FUNC(fmod) (nan_value, nan_value), nan_value, 0, 0, 0); + + check_float ("fmod (6.5, 2.3) == 1.9", FUNC(fmod) (6.5, 2.3L), 1.9L, DELTA972, 0, 0); + check_float ("fmod (-6.5, 2.3) == -1.9", FUNC(fmod) (-6.5, 2.3L), -1.9L, DELTA973, 0, 0); + check_float ("fmod (6.5, -2.3) == 1.9", FUNC(fmod) (6.5, -2.3L), 1.9L, DELTA974, 0, 0); + check_float ("fmod (-6.5, -2.3) == -1.9", FUNC(fmod) (-6.5, -2.3L), -1.9L, DELTA975, 0, 0); + + print_max_error ("fmod", DELTAfmod, 0); +} + +static void +fpclassify_test (void) +{ + init_max_error (); + + check_int ("fpclassify (NaN) == FP_NAN", fpclassify (nan_value), FP_NAN, 0, 0, 0); + check_int ("fpclassify (inf) == FP_INFINITE", fpclassify (plus_infty), FP_INFINITE, 0, 0, 0); + check_int ("fpclassify (-inf) == FP_INFINITE", fpclassify (minus_infty), FP_INFINITE, 0, 0, 0); + check_int ("fpclassify (+0) == FP_ZERO", fpclassify (plus_zero), FP_ZERO, 0, 0, 0); + check_int ("fpclassify (-0) == FP_ZERO", fpclassify (minus_zero), FP_ZERO, 0, 0, 0); + check_int ("fpclassify (1000) == FP_NORMAL", fpclassify (1000.0), FP_NORMAL, 0, 0, 0); + + print_max_error ("fpclassify", 0, 0); +} + + +static void +frexp_test (void) +{ + int x; + + init_max_error (); + + check_float ("frexp (inf, &x) == inf", FUNC(frexp) (plus_infty, &x), plus_infty, 0, 0, 0); + check_float ("frexp (-inf, &x) == -inf", FUNC(frexp) (minus_infty, &x), minus_infty, 0, 0, 0); + check_float ("frexp (NaN, &x) == NaN", FUNC(frexp) (nan_value, &x), nan_value, 0, 0, 0); + + check_float ("frexp (0.0, &x) == 0.0", FUNC(frexp) (0.0, &x), 0.0, 0, 0, 0); + check_int ("frexp (0.0, &x) sets x to 0.0", x, 0.0, 0, 0, 0); + check_float ("frexp (-0, &x) == -0", FUNC(frexp) (minus_zero, &x), minus_zero, 0, 0, 0); + check_int ("frexp (-0, &x) sets x to 0.0", x, 0.0, 0, 0, 0); + + check_float ("frexp (12.8, &x) == 0.8", FUNC(frexp) (12.8L, &x), 0.8L, 0, 0, 0); + check_int ("frexp (12.8, &x) sets x to 4", x, 4, 0, 0, 0); + check_float ("frexp (-27.34, &x) == -0.854375", FUNC(frexp) (-27.34L, &x), -0.854375L, 0, 0, 0); + check_int ("frexp (-27.34, &x) sets x to 5", x, 5, 0, 0, 0); + + print_max_error ("frexp", 0, 0); +} + +#define gamma lgamma /* XXX scp XXX */ +#define gammaf lgammaf /* XXX scp XXX */ +static void +gamma_test (void) +{ + errno = 0; + FUNC(gamma) (1); + + if (errno == ENOSYS) + /* Function not implemented. */ + return; + feclearexcept (FE_ALL_EXCEPT); + + init_max_error (); + + signgam = 0; + check_float ("gamma (inf) == inf", FUNC(gamma) (plus_infty), plus_infty, 0, 0, 0); + signgam = 0; + check_float ("gamma (0) == inf plus division by zero exception", FUNC(gamma) (0), plus_infty, 0, 0, DIVIDE_BY_ZERO_EXCEPTION); + signgam = 0; + check_float ("gamma (-3) == inf plus division by zero exception", FUNC(gamma) (-3), plus_infty, 0, 0, DIVIDE_BY_ZERO_EXCEPTION); + signgam = 0; + check_float ("gamma (-inf) == inf", FUNC(gamma) (minus_infty), plus_infty, 0, 0, 0); + signgam = 0; + check_float ("gamma (NaN) == NaN", FUNC(gamma) (nan_value), nan_value, 0, 0, 0); + + signgam = 0; + check_float ("gamma (1) == 0", FUNC(gamma) (1), 0, 0, 0, 0); + check_int ("gamma (1) sets signgam to 1", signgam, 1, 0, 0, 0); + signgam = 0; + check_float ("gamma (3) == M_LN2l", FUNC(gamma) (3), M_LN2l, 0, 0, 0); + check_int ("gamma (3) sets signgam to 1", signgam, 1, 0, 0, 0); + + signgam = 0; + check_float ("gamma (0.5) == log(sqrt(pi))", FUNC(gamma) (0.5), M_LOG_SQRT_PIl, 0, 0, 0); + check_int ("gamma (0.5) sets signgam to 1", signgam, 1, 0, 0, 0); + signgam = 0; + check_float ("gamma (-0.5) == log(2*sqrt(pi))", FUNC(gamma) (-0.5), M_LOG_2_SQRT_PIl, DELTA1004, 0, 0); + check_int ("gamma (-0.5) sets signgam to -1", signgam, -1, 0, 0, 0); + + print_max_error ("gamma", DELTAgamma, 0); +} +#undef gamma /* XXX scp XXX */ +#undef gammaf /* XXX scp XXX */ + +static void +hypot_test (void) +{ + errno = 0; + FUNC(hypot) (0.7L, 12.4L); + if (errno == ENOSYS) + /* Function not implemented. */ + return; + + init_max_error (); + + check_float ("hypot (inf, 1) == inf plus sign of zero/inf not specified", FUNC(hypot) (plus_infty, 1), plus_infty, 0, 0, IGNORE_ZERO_INF_SIGN); + check_float ("hypot (-inf, 1) == inf plus sign of zero/inf not specified", FUNC(hypot) (minus_infty, 1), plus_infty, 0, 0, IGNORE_ZERO_INF_SIGN); + +#ifndef TEST_INLINE + check_float ("hypot (inf, NaN) == inf", FUNC(hypot) (plus_infty, nan_value), plus_infty, 0, 0, 0); + check_float ("hypot (-inf, NaN) == inf", FUNC(hypot) (minus_infty, nan_value), plus_infty, 0, 0, 0); + check_float ("hypot (NaN, inf) == inf", FUNC(hypot) (nan_value, plus_infty), plus_infty, 0, 0, 0); + check_float ("hypot (NaN, -inf) == inf", FUNC(hypot) (nan_value, minus_infty), plus_infty, 0, 0, 0); +#endif + + check_float ("hypot (NaN, NaN) == NaN", FUNC(hypot) (nan_value, nan_value), nan_value, 0, 0, 0); + + /* hypot (x,y) == hypot (+-x, +-y) */ + check_float ("hypot (0.7, 12.4) == 12.419742348374220601176836866763271", FUNC(hypot) (0.7L, 12.4L), 12.419742348374220601176836866763271L, DELTA1013, 0, 0); + check_float ("hypot (-0.7, 12.4) == 12.419742348374220601176836866763271", FUNC(hypot) (-0.7L, 12.4L), 12.419742348374220601176836866763271L, DELTA1014, 0, 0); + check_float ("hypot (0.7, -12.4) == 12.419742348374220601176836866763271", FUNC(hypot) (0.7L, -12.4L), 12.419742348374220601176836866763271L, DELTA1015, 0, 0); + check_float ("hypot (-0.7, -12.4) == 12.419742348374220601176836866763271", FUNC(hypot) (-0.7L, -12.4L), 12.419742348374220601176836866763271L, DELTA1016, 0, 0); + check_float ("hypot (12.4, 0.7) == 12.419742348374220601176836866763271", FUNC(hypot) (12.4L, 0.7L), 12.419742348374220601176836866763271L, DELTA1017, 0, 0); + check_float ("hypot (-12.4, 0.7) == 12.419742348374220601176836866763271", FUNC(hypot) (-12.4L, 0.7L), 12.419742348374220601176836866763271L, DELTA1018, 0, 0); + check_float ("hypot (12.4, -0.7) == 12.419742348374220601176836866763271", FUNC(hypot) (12.4L, -0.7L), 12.419742348374220601176836866763271L, DELTA1019, 0, 0); + check_float ("hypot (-12.4, -0.7) == 12.419742348374220601176836866763271", FUNC(hypot) (-12.4L, -0.7L), 12.419742348374220601176836866763271L, DELTA1020, 0, 0); + + /* hypot (x,0) == fabs (x) */ + check_float ("hypot (0.7, 0) == 0.7", FUNC(hypot) (0.7L, 0), 0.7L, 0, 0, 0); + check_float ("hypot (-0.7, 0) == 0.7", FUNC(hypot) (-0.7L, 0), 0.7L, 0, 0, 0); + check_float ("hypot (-5.7e7, 0) == 5.7e7", FUNC(hypot) (-5.7e7, 0), 5.7e7L, 0, 0, 0); + + check_float ("hypot (0.7, 1.2) == 1.3892443989449804508432547041028554", FUNC(hypot) (0.7L, 1.2L), 1.3892443989449804508432547041028554L, DELTA1024, 0, 0); + + print_max_error ("hypot", DELTAhypot, 0); +} + + +static void +ilogb_test (void) +{ + init_max_error (); + + check_int ("ilogb (1) == 0", FUNC(ilogb) (1), 0, 0, 0, 0); + check_int ("ilogb (e) == 1", FUNC(ilogb) (M_El), 1, 0, 0, 0); + check_int ("ilogb (1024) == 10", FUNC(ilogb) (1024), 10, 0, 0, 0); + check_int ("ilogb (-2000) == 10", FUNC(ilogb) (-2000), 10, 0, 0, 0); + + /* XXX We have a problem here: the standard does not tell us whether + exceptions are allowed/required. ignore them for now. */ + + check_int ("ilogb (0.0) == FP_ILOGB0 plus exceptions allowed", FUNC(ilogb) (0.0), FP_ILOGB0, 0, 0, EXCEPTIONS_OK); + check_int ("ilogb (NaN) == FP_ILOGBNAN plus exceptions allowed", FUNC(ilogb) (nan_value), FP_ILOGBNAN, 0, 0, EXCEPTIONS_OK); + check_int ("ilogb (inf) == INT_MAX plus exceptions allowed", FUNC(ilogb) (plus_infty), INT_MAX, 0, 0, EXCEPTIONS_OK); + check_int ("ilogb (-inf) == INT_MAX plus exceptions allowed", FUNC(ilogb) (minus_infty), INT_MAX, 0, 0, EXCEPTIONS_OK); + + print_max_error ("ilogb", 0, 0); +} + +static void +isfinite_test (void) +{ + init_max_error (); + + check_bool ("isfinite (0) == true", isfinite (0.0), 1, 0, 0, 0); + check_bool ("isfinite (-0) == true", isfinite (minus_zero), 1, 0, 0, 0); + check_bool ("isfinite (10) == true", isfinite (10.0), 1, 0, 0, 0); + check_bool ("isfinite (inf) == false", isfinite (plus_infty), 0, 0, 0, 0); + check_bool ("isfinite (-inf) == false", isfinite (minus_infty), 0, 0, 0, 0); + check_bool ("isfinite (NaN) == false", isfinite (nan_value), 0, 0, 0, 0); + + print_max_error ("isfinite", 0, 0); +} + +static void +isnormal_test (void) +{ + init_max_error (); + + check_bool ("isnormal (0) == false", isnormal (0.0), 0, 0, 0, 0); + check_bool ("isnormal (-0) == false", isnormal (minus_zero), 0, 0, 0, 0); + check_bool ("isnormal (10) == true", isnormal (10.0), 1, 0, 0, 0); + check_bool ("isnormal (inf) == false", isnormal (plus_infty), 0, 0, 0, 0); + check_bool ("isnormal (-inf) == false", isnormal (minus_infty), 0, 0, 0, 0); + check_bool ("isnormal (NaN) == false", isnormal (nan_value), 0, 0, 0, 0); + + print_max_error ("isnormal", 0, 0); +} + +static void +j0_test (void) +{ + FLOAT s, c; + errno = 0; + FUNC (sincos) (0, &s, &c); + if (errno == ENOSYS) + /* Required function not implemented. */ + return; + FUNC(j0) (0); + if (errno == ENOSYS) + /* Function not implemented. */ + return; + + init_max_error (); + + /* j0 is the Bessel function of the first kind of order 0 */ + check_float ("j0 (NaN) == NaN", FUNC(j0) (nan_value), nan_value, 0, 0, 0); + check_float ("j0 (inf) == 0", FUNC(j0) (plus_infty), 0, 0, 0, 0); + check_float ("j0 (-1.0) == 0.76519768655796655145", FUNC(j0) (-1.0), 0.76519768655796655145L, 0, 0, 0); + check_float ("j0 (0.0) == 1.0", FUNC(j0) (0.0), 1.0, 0, 0, 0); + check_float ("j0 (0.1) == 0.99750156206604003228", FUNC(j0) (0.1L), 0.99750156206604003228L, 0, 0, 0); + check_float ("j0 (0.7) == 0.88120088860740528084", FUNC(j0) (0.7L), 0.88120088860740528084L, 0, 0, 0); + check_float ("j0 (1.0) == 0.76519768655796655145", FUNC(j0) (1.0), 0.76519768655796655145L, 0, 0, 0); + check_float ("j0 (1.5) == 0.51182767173591812875", FUNC(j0) (1.5), 0.51182767173591812875L, 0, 0, 0); + check_float ("j0 (2.0) == 0.22389077914123566805", FUNC(j0) (2.0), 0.22389077914123566805L, DELTA1053, 0, 0); + check_float ("j0 (8.0) == 0.17165080713755390609", FUNC(j0) (8.0), 0.17165080713755390609L, DELTA1054, 0, 0); + check_float ("j0 (10.0) == -0.24593576445134833520", FUNC(j0) (10.0), -0.24593576445134833520L, DELTA1055, 0, 0); + + print_max_error ("j0", DELTAj0, 0); +} + + +static void +j1_test (void) +{ + FLOAT s, c; + errno = 0; + FUNC (sincos) (0, &s, &c); + if (errno == ENOSYS) + /* Required function not implemented. */ + return; + FUNC(j1) (0); + if (errno == ENOSYS) + /* Function not implemented. */ + return; + + /* j1 is the Bessel function of the first kind of order 1 */ + + init_max_error (); + + check_float ("j1 (NaN) == NaN", FUNC(j1) (nan_value), nan_value, 0, 0, 0); + check_float ("j1 (inf) == 0", FUNC(j1) (plus_infty), 0, 0, 0, 0); + + check_float ("j1 (-1.0) == -0.44005058574493351596", FUNC(j1) (-1.0), -0.44005058574493351596L, 0, 0, 0); + check_float ("j1 (0.0) == 0.0", FUNC(j1) (0.0), 0.0, 0, 0, 0); + check_float ("j1 (0.1) == 0.049937526036241997556", FUNC(j1) (0.1L), 0.049937526036241997556L, 0, 0, 0); + check_float ("j1 (0.7) == 0.32899574154005894785", FUNC(j1) (0.7L), 0.32899574154005894785L, 0, 0, 0); + check_float ("j1 (1.0) == 0.44005058574493351596", FUNC(j1) (1.0), 0.44005058574493351596L, 0, 0, 0); + check_float ("j1 (1.5) == 0.55793650791009964199", FUNC(j1) (1.5), 0.55793650791009964199L, 0, 0, 0); + check_float ("j1 (2.0) == 0.57672480775687338720", FUNC(j1) (2.0), 0.57672480775687338720L, DELTA1064, 0, 0); + check_float ("j1 (8.0) == 0.23463634685391462438", FUNC(j1) (8.0), 0.23463634685391462438L, DELTA1065, 0, 0); + check_float ("j1 (10.0) == 0.043472746168861436670", FUNC(j1) (10.0), 0.043472746168861436670L, DELTA1066, 0, 0); + + print_max_error ("j1", DELTAj1, 0); +} + +static void +jn_test (void) +{ + FLOAT s, c; + errno = 0; + FUNC (sincos) (0, &s, &c); + if (errno == ENOSYS) + /* Required function not implemented. */ + return; + FUNC(jn) (1, 1); + if (errno == ENOSYS) + /* Function not implemented. */ + return; + + /* jn is the Bessel function of the first kind of order n. */ + init_max_error (); + + /* jn (0, x) == j0 (x) */ + check_float ("jn (0, NaN) == NaN", FUNC(jn) (0, nan_value), nan_value, 0, 0, 0); + check_float ("jn (0, inf) == 0", FUNC(jn) (0, plus_infty), 0, 0, 0, 0); + check_float ("jn (0, -1.0) == 0.76519768655796655145", FUNC(jn) (0, -1.0), 0.76519768655796655145L, 0, 0, 0); + check_float ("jn (0, 0.0) == 1.0", FUNC(jn) (0, 0.0), 1.0, 0, 0, 0); + check_float ("jn (0, 0.1) == 0.99750156206604003228", FUNC(jn) (0, 0.1L), 0.99750156206604003228L, 0, 0, 0); + check_float ("jn (0, 0.7) == 0.88120088860740528084", FUNC(jn) (0, 0.7L), 0.88120088860740528084L, 0, 0, 0); + check_float ("jn (0, 1.0) == 0.76519768655796655145", FUNC(jn) (0, 1.0), 0.76519768655796655145L, 0, 0, 0); + check_float ("jn (0, 1.5) == 0.51182767173591812875", FUNC(jn) (0, 1.5), 0.51182767173591812875L, 0, 0, 0); + check_float ("jn (0, 2.0) == 0.22389077914123566805", FUNC(jn) (0, 2.0), 0.22389077914123566805L, DELTA1075, 0, 0); + check_float ("jn (0, 8.0) == 0.17165080713755390609", FUNC(jn) (0, 8.0), 0.17165080713755390609L, DELTA1076, 0, 0); + check_float ("jn (0, 10.0) == -0.24593576445134833520", FUNC(jn) (0, 10.0), -0.24593576445134833520L, DELTA1077, 0, 0); + + /* jn (1, x) == j1 (x) */ + check_float ("jn (1, NaN) == NaN", FUNC(jn) (1, nan_value), nan_value, 0, 0, 0); + check_float ("jn (1, inf) == 0", FUNC(jn) (1, plus_infty), 0, 0, 0, 0); + + check_float ("jn (1, -1.0) == -0.44005058574493351596", FUNC(jn) (1, -1.0), -0.44005058574493351596L, 0, 0, 0); + check_float ("jn (1, 0.0) == 0.0", FUNC(jn) (1, 0.0), 0.0, 0, 0, 0); + check_float ("jn (1, 0.1) == 0.049937526036241997556", FUNC(jn) (1, 0.1L), 0.049937526036241997556L, 0, 0, 0); + check_float ("jn (1, 0.7) == 0.32899574154005894785", FUNC(jn) (1, 0.7L), 0.32899574154005894785L, 0, 0, 0); + check_float ("jn (1, 1.0) == 0.44005058574493351596", FUNC(jn) (1, 1.0), 0.44005058574493351596L, 0, 0, 0); + check_float ("jn (1, 1.5) == 0.55793650791009964199", FUNC(jn) (1, 1.5), 0.55793650791009964199L, 0, 0, 0); + check_float ("jn (1, 2.0) == 0.57672480775687338720", FUNC(jn) (1, 2.0), 0.57672480775687338720L, DELTA1086, 0, 0); + check_float ("jn (1, 8.0) == 0.23463634685391462438", FUNC(jn) (1, 8.0), 0.23463634685391462438L, DELTA1087, 0, 0); + check_float ("jn (1, 10.0) == 0.043472746168861436670", FUNC(jn) (1, 10.0), 0.043472746168861436670L, DELTA1088, 0, 0); + + /* jn (3, x) */ + check_float ("jn (3, NaN) == NaN", FUNC(jn) (3, nan_value), nan_value, 0, 0, 0); + check_float ("jn (3, inf) == 0", FUNC(jn) (3, plus_infty), 0, 0, 0, 0); + + check_float ("jn (3, -1.0) == -0.019563353982668405919", FUNC(jn) (3, -1.0), -0.019563353982668405919L, DELTA1091, 0, 0); + check_float ("jn (3, 0.0) == 0.0", FUNC(jn) (3, 0.0), 0.0, 0, 0, 0); + check_float ("jn (3, 0.1) == 0.000020820315754756261429", FUNC(jn) (3, 0.1L), 0.000020820315754756261429L, DELTA1093, 0, 0); + check_float ("jn (3, 0.7) == 0.0069296548267508408077", FUNC(jn) (3, 0.7L), 0.0069296548267508408077L, DELTA1094, 0, 0); + check_float ("jn (3, 1.0) == 0.019563353982668405919", FUNC(jn) (3, 1.0), 0.019563353982668405919L, DELTA1095, 0, 0); + check_float ("jn (3, 2.0) == 0.12894324947440205110", FUNC(jn) (3, 2.0), 0.12894324947440205110L, DELTA1096, 0, 0); + check_float ("jn (3, 10.0) == 0.058379379305186812343", FUNC(jn) (3, 10.0), 0.058379379305186812343L, DELTA1097, 0, 0); + + /* jn (10, x) */ + check_float ("jn (10, NaN) == NaN", FUNC(jn) (10, nan_value), nan_value, 0, 0, 0); + check_float ("jn (10, inf) == 0", FUNC(jn) (10, plus_infty), 0, 0, 0, 0); + + check_float ("jn (10, -1.0) == 0.26306151236874532070e-9", FUNC(jn) (10, -1.0), 0.26306151236874532070e-9L, DELTA1100, 0, 0); + check_float ("jn (10, 0.0) == 0.0", FUNC(jn) (10, 0.0), 0.0, 0, 0, 0); + check_float ("jn (10, 0.1) == 0.26905328954342155795e-19", FUNC(jn) (10, 0.1L), 0.26905328954342155795e-19L, DELTA1102, 0, 0); + check_float ("jn (10, 0.7) == 0.75175911502153953928e-11", FUNC(jn) (10, 0.7L), 0.75175911502153953928e-11L, DELTA1103, 0, 0); + check_float ("jn (10, 1.0) == 0.26306151236874532070e-9", FUNC(jn) (10, 1.0), 0.26306151236874532070e-9L, DELTA1104, 0, 0); + check_float ("jn (10, 2.0) == 0.25153862827167367096e-6", FUNC(jn) (10, 2.0), 0.25153862827167367096e-6L, DELTA1105, 0, 0); + check_float ("jn (10, 10.0) == 0.20748610663335885770", FUNC(jn) (10, 10.0), 0.20748610663335885770L, DELTA1106, 0, 0); + + print_max_error ("jn", DELTAjn, 0); +} + + +static void +ldexp_test (void) +{ + check_float ("ldexp (0, 0) == 0", FUNC(ldexp) (0, 0), 0, 0, 0, 0); + check_float ("ldexp (-0, 0) == -0", FUNC(ldexp) (minus_zero, 0), minus_zero, 0, 0, 0); + + check_float ("ldexp (inf, 1) == inf", FUNC(ldexp) (plus_infty, 1), plus_infty, 0, 0, 0); + check_float ("ldexp (-inf, 1) == -inf", FUNC(ldexp) (minus_infty, 1), minus_infty, 0, 0, 0); + check_float ("ldexp (NaN, 1) == NaN", FUNC(ldexp) (nan_value, 1), nan_value, 0, 0, 0); + + check_float ("ldexp (0.8, 4) == 12.8", FUNC(ldexp) (0.8L, 4), 12.8L, 0, 0, 0); + check_float ("ldexp (-0.854375, 5) == -27.34", FUNC(ldexp) (-0.854375L, 5), -27.34L, 0, 0, 0); + + /* ldexp (x, 0) == x. */ + check_float ("ldexp (1.0, 0) == 1.0", FUNC(ldexp) (1.0L, 0L), 1.0L, 0, 0, 0); +} + +static void +lgamma_test (void) +{ + errno = 0; + FUNC(lgamma) (0); + if (errno == ENOSYS) + /* Function not implemented. */ + return; + feclearexcept (FE_ALL_EXCEPT); + + init_max_error (); + + signgam = 0; + check_float ("lgamma (inf) == inf", FUNC(lgamma) (plus_infty), plus_infty, 0, 0, 0); + signgam = 0; + check_float ("lgamma (0) == inf plus division by zero exception", FUNC(lgamma) (0), plus_infty, 0, 0, DIVIDE_BY_ZERO_EXCEPTION); + signgam = 0; + check_float ("lgamma (NaN) == NaN", FUNC(lgamma) (nan_value), nan_value, 0, 0, 0); + + /* lgamma (x) == +inf plus divide by zero exception for integer x <= 0. */ + signgam = 0; + check_float ("lgamma (-3) == inf plus division by zero exception", FUNC(lgamma) (-3), plus_infty, 0, 0, DIVIDE_BY_ZERO_EXCEPTION); + signgam = 0; + check_float ("lgamma (-inf) == inf", FUNC(lgamma) (minus_infty), plus_infty, 0, 0, 0); + + signgam = 0; + check_float ("lgamma (1) == 0", FUNC(lgamma) (1), 0, 0, 0, 0); + check_int ("lgamma (1) sets signgam to 1", signgam, 1, 0, 0, 0); + + signgam = 0; + check_float ("lgamma (3) == M_LN2l", FUNC(lgamma) (3), M_LN2l, 0, 0, 0); + check_int ("lgamma (3) sets signgam to 1", signgam, 1, 0, 0, 0); + + signgam = 0; + check_float ("lgamma (0.5) == log(sqrt(pi))", FUNC(lgamma) (0.5), M_LOG_SQRT_PIl, 0, 0, 0); + check_int ("lgamma (0.5) sets signgam to 1", signgam, 1, 0, 0, 0); + signgam = 0; + check_float ("lgamma (-0.5) == log(2*sqrt(pi))", FUNC(lgamma) (-0.5), M_LOG_2_SQRT_PIl, DELTA1126, 0, 0); + check_int ("lgamma (-0.5) sets signgam to -1", signgam, -1, 0, 0, 0); + signgam = 0; + check_float ("lgamma (0.7) == 0.26086724653166651439", FUNC(lgamma) (0.7L), 0.26086724653166651439L, DELTA1128, 0, 0); + check_int ("lgamma (0.7) sets signgam to 1", signgam, 1, 0, 0, 0); + signgam = 0; + check_float ("lgamma (1.2) == -0.853740900033158497197e-1", FUNC(lgamma) (1.2L), -0.853740900033158497197e-1L, DELTA1130, 0, 0); + check_int ("lgamma (1.2) sets signgam to 1", signgam, 1, 0, 0, 0); + + print_max_error ("lgamma", DELTAlgamma, 0); +} + +static void +lrint_test (void) +{ + /* XXX this test is incomplete. We need to have a way to specifiy + the rounding method and test the critical cases. So far, only + unproblematic numbers are tested. */ + + init_max_error (); + + check_long ("lrint (0.0) == 0", FUNC(lrint) (0.0), 0, 0, 0, 0); + check_long ("lrint (-0) == 0", FUNC(lrint) (minus_zero), 0, 0, 0, 0); + check_long ("lrint (0.2) == 0", FUNC(lrint) (0.2L), 0, 0, 0, 0); + check_long ("lrint (-0.2) == 0", FUNC(lrint) (-0.2L), 0, 0, 0, 0); + + check_long ("lrint (1.4) == 1", FUNC(lrint) (1.4L), 1, 0, 0, 0); + check_long ("lrint (-1.4) == -1", FUNC(lrint) (-1.4L), -1, 0, 0, 0); + + check_long ("lrint (8388600.3) == 8388600", FUNC(lrint) (8388600.3L), 8388600, 0, 0, 0); + check_long ("lrint (-8388600.3) == -8388600", FUNC(lrint) (-8388600.3L), -8388600, 0, 0, 0); + + print_max_error ("lrint", 0, 0); +} + +static void +llrint_test (void) +{ + /* XXX this test is incomplete. We need to have a way to specifiy + the rounding method and test the critical cases. So far, only + unproblematic numbers are tested. */ + + init_max_error (); + + check_longlong ("llrint (0.0) == 0", FUNC(llrint) (0.0), 0, 0, 0, 0); + check_longlong ("llrint (-0) == 0", FUNC(llrint) (minus_zero), 0, 0, 0, 0); + check_longlong ("llrint (0.2) == 0", FUNC(llrint) (0.2L), 0, 0, 0, 0); + check_longlong ("llrint (-0.2) == 0", FUNC(llrint) (-0.2L), 0, 0, 0, 0); + + check_longlong ("llrint (1.4) == 1", FUNC(llrint) (1.4L), 1, 0, 0, 0); + check_longlong ("llrint (-1.4) == -1", FUNC(llrint) (-1.4L), -1, 0, 0, 0); + + check_longlong ("llrint (8388600.3) == 8388600", FUNC(llrint) (8388600.3L), 8388600, 0, 0, 0); + check_longlong ("llrint (-8388600.3) == -8388600", FUNC(llrint) (-8388600.3L), -8388600, 0, 0, 0); + + /* Test boundary conditions. */ + /* 0x1FFFFF */ + check_longlong ("llrint (2097151.0) == 2097151LL", FUNC(llrint) (2097151.0), 2097151LL, 0, 0, 0); + /* 0x800000 */ + check_longlong ("llrint (8388608.0) == 8388608LL", FUNC(llrint) (8388608.0), 8388608LL, 0, 0, 0); + /* 0x1000000 */ + check_longlong ("llrint (16777216.0) == 16777216LL", FUNC(llrint) (16777216.0), 16777216LL, 0, 0, 0); + /* 0x20000000000 */ + check_longlong ("llrint (2199023255552.0) == 2199023255552LL", FUNC(llrint) (2199023255552.0), 2199023255552LL, 0, 0, 0); + /* 0x40000000000 */ + check_longlong ("llrint (4398046511104.0) == 4398046511104LL", FUNC(llrint) (4398046511104.0), 4398046511104LL, 0, 0, 0); + /* 0x10000000000000 */ + check_longlong ("llrint (4503599627370496.0) == 4503599627370496LL", FUNC(llrint) (4503599627370496.0), 4503599627370496LL, 0, 0, 0); + /* 0x10000080000000 */ + check_longlong ("llrint (4503601774854144.0) == 4503601774854144LL", FUNC(llrint) (4503601774854144.0), 4503601774854144LL, 0, 0, 0); + /* 0x20000000000000 */ + check_longlong ("llrint (9007199254740992.0) == 9007199254740992LL", FUNC(llrint) (9007199254740992.0), 9007199254740992LL, 0, 0, 0); + /* 0x80000000000000 */ + check_longlong ("llrint (36028797018963968.0) == 36028797018963968LL", FUNC(llrint) (36028797018963968.0), 36028797018963968LL, 0, 0, 0); + /* 0x100000000000000 */ + check_longlong ("llrint (72057594037927936.0) == 72057594037927936LL", FUNC(llrint) (72057594037927936.0), 72057594037927936LL, 0, 0, 0); + + print_max_error ("llrint", 0, 0); +} + +static void +log_test (void) +{ + errno = 0; + FUNC(log) (1); + if (errno == ENOSYS) + /* Function not implemented. */ + return; + init_max_error (); + + check_float ("log (0) == -inf plus division by zero exception", FUNC(log) (0), minus_infty, 0, 0, DIVIDE_BY_ZERO_EXCEPTION); + check_float ("log (-0) == -inf plus division by zero exception", FUNC(log) (minus_zero), minus_infty, 0, 0, DIVIDE_BY_ZERO_EXCEPTION); + + check_float ("log (1) == 0", FUNC(log) (1), 0, 0, 0, 0); + + check_float ("log (-1) == NaN plus invalid exception", FUNC(log) (-1), nan_value, 0, 0, INVALID_EXCEPTION); + check_float ("log (inf) == inf", FUNC(log) (plus_infty), plus_infty, 0, 0, 0); + + check_float ("log (e) == 1", FUNC(log) (M_El), 1, DELTA1163, 0, 0); + check_float ("log (1.0 / M_El) == -1", FUNC(log) (1.0 / M_El), -1, DELTA1164, 0, 0); + check_float ("log (2) == M_LN2l", FUNC(log) (2), M_LN2l, 0, 0, 0); + check_float ("log (10) == M_LN10l", FUNC(log) (10), M_LN10l, 0, 0, 0); + check_float ("log (0.7) == -0.35667494393873237891263871124118447", FUNC(log) (0.7L), -0.35667494393873237891263871124118447L, DELTA1167, 0, 0); + + print_max_error ("log", DELTAlog, 0); +} + + +static void +log10_test (void) +{ + errno = 0; + FUNC(log10) (1); + if (errno == ENOSYS) + /* Function not implemented. */ + return; + + init_max_error (); + + check_float ("log10 (0) == -inf plus division by zero exception", FUNC(log10) (0), minus_infty, 0, 0, DIVIDE_BY_ZERO_EXCEPTION); + check_float ("log10 (-0) == -inf plus division by zero exception", FUNC(log10) (minus_zero), minus_infty, 0, 0, DIVIDE_BY_ZERO_EXCEPTION); + + check_float ("log10 (1) == 0", FUNC(log10) (1), 0, 0, 0, 0); + + /* log10 (x) == NaN plus invalid exception if x < 0. */ + check_float ("log10 (-1) == NaN plus invalid exception", FUNC(log10) (-1), nan_value, 0, 0, INVALID_EXCEPTION); + + check_float ("log10 (inf) == inf", FUNC(log10) (plus_infty), plus_infty, 0, 0, 0); + check_float ("log10 (NaN) == NaN", FUNC(log10) (nan_value), nan_value, 0, 0, 0); + + check_float ("log10 (0.1) == -1", FUNC(log10) (0.1L), -1, 0, 0, 0); + check_float ("log10 (10.0) == 1", FUNC(log10) (10.0), 1, 0, 0, 0); + check_float ("log10 (100.0) == 2", FUNC(log10) (100.0), 2, 0, 0, 0); + check_float ("log10 (10000.0) == 4", FUNC(log10) (10000.0), 4, 0, 0, 0); + check_float ("log10 (e) == log10(e)", FUNC(log10) (M_El), M_LOG10El, DELTA1178, 0, 0); + check_float ("log10 (0.7) == -0.15490195998574316929", FUNC(log10) (0.7L), -0.15490195998574316929L, DELTA1179, 0, 0); + + print_max_error ("log10", DELTAlog10, 0); +} + + +static void +log1p_test (void) +{ + errno = 0; + FUNC(log1p) (0); + if (errno == ENOSYS) + /* Function not implemented. */ + return; + + init_max_error (); + + check_float ("log1p (0) == 0", FUNC(log1p) (0), 0, 0, 0, 0); + check_float ("log1p (-0) == -0", FUNC(log1p) (minus_zero), minus_zero, 0, 0, 0); + + check_float ("log1p (-1) == -inf plus division by zero exception", FUNC(log1p) (-1), minus_infty, 0, 0, DIVIDE_BY_ZERO_EXCEPTION); + check_float ("log1p (-2) == NaN plus invalid exception", FUNC(log1p) (-2), nan_value, 0, 0, INVALID_EXCEPTION); + + check_float ("log1p (inf) == inf", FUNC(log1p) (plus_infty), plus_infty, 0, 0, 0); + check_float ("log1p (NaN) == NaN", FUNC(log1p) (nan_value), nan_value, 0, 0, 0); + + check_float ("log1p (M_El - 1.0) == 1", FUNC(log1p) (M_El - 1.0), 1, DELTA1186, 0, 0); + + check_float ("log1p (-0.3) == -0.35667494393873237891263871124118447", FUNC(log1p) (-0.3L), -0.35667494393873237891263871124118447L, DELTA1187, 0, 0); + + print_max_error ("log1p", DELTAlog1p, 0); +} + + +static void +log2_test (void) +{ + errno = 0; + FUNC(log2) (1); + if (errno == ENOSYS) + /* Function not implemented. */ + return; + + init_max_error (); + + check_float ("log2 (0) == -inf plus division by zero exception", FUNC(log2) (0), minus_infty, 0, 0, DIVIDE_BY_ZERO_EXCEPTION); + check_float ("log2 (-0) == -inf plus division by zero exception", FUNC(log2) (minus_zero), minus_infty, 0, 0, DIVIDE_BY_ZERO_EXCEPTION); + + check_float ("log2 (1) == 0", FUNC(log2) (1), 0, 0, 0, 0); + + check_float ("log2 (-1) == NaN plus invalid exception", FUNC(log2) (-1), nan_value, 0, 0, INVALID_EXCEPTION); + + check_float ("log2 (inf) == inf", FUNC(log2) (plus_infty), plus_infty, 0, 0, 0); + check_float ("log2 (NaN) == NaN", FUNC(log2) (nan_value), nan_value, 0, 0, 0); + + check_float ("log2 (e) == M_LOG2El", FUNC(log2) (M_El), M_LOG2El, 0, 0, 0); + check_float ("log2 (2.0) == 1", FUNC(log2) (2.0), 1, 0, 0, 0); + check_float ("log2 (16.0) == 4", FUNC(log2) (16.0), 4, 0, 0, 0); + check_float ("log2 (256.0) == 8", FUNC(log2) (256.0), 8, 0, 0, 0); + check_float ("log2 (0.7) == -0.51457317282975824043", FUNC(log2) (0.7L), -0.51457317282975824043L, DELTA1198, 0, 0); + + print_max_error ("log2", DELTAlog2, 0); +} + + +static void +logb_test (void) +{ + init_max_error (); + + check_float ("logb (inf) == inf", FUNC(logb) (plus_infty), plus_infty, 0, 0, 0); + check_float ("logb (-inf) == inf", FUNC(logb) (minus_infty), plus_infty, 0, 0, 0); + + check_float ("logb (0) == -inf plus division by zero exception", FUNC(logb) (0), minus_infty, 0, 0, DIVIDE_BY_ZERO_EXCEPTION); + + check_float ("logb (-0) == -inf plus division by zero exception", FUNC(logb) (minus_zero), minus_infty, 0, 0, DIVIDE_BY_ZERO_EXCEPTION); + check_float ("logb (NaN) == NaN", FUNC(logb) (nan_value), nan_value, 0, 0, 0); + + check_float ("logb (1) == 0", FUNC(logb) (1), 0, 0, 0, 0); + check_float ("logb (e) == 1", FUNC(logb) (M_El), 1, 0, 0, 0); + check_float ("logb (1024) == 10", FUNC(logb) (1024), 10, 0, 0, 0); + check_float ("logb (-2000) == 10", FUNC(logb) (-2000), 10, 0, 0, 0); + + print_max_error ("logb", 0, 0); +} + +static void +lround_test (void) +{ + init_max_error (); + + check_long ("lround (0) == 0", FUNC(lround) (0), 0, 0, 0, 0); + check_long ("lround (-0) == 0", FUNC(lround) (minus_zero), 0, 0, 0, 0); + check_long ("lround (0.2) == 0.0", FUNC(lround) (0.2L), 0.0, 0, 0, 0); + check_long ("lround (-0.2) == 0", FUNC(lround) (-0.2L), 0, 0, 0, 0); + check_long ("lround (0.5) == 1", FUNC(lround) (0.5), 1, 0, 0, 0); + check_long ("lround (-0.5) == -1", FUNC(lround) (-0.5), -1, 0, 0, 0); + check_long ("lround (0.8) == 1", FUNC(lround) (0.8L), 1, 0, 0, 0); + check_long ("lround (-0.8) == -1", FUNC(lround) (-0.8L), -1, 0, 0, 0); + check_long ("lround (1.5) == 2", FUNC(lround) (1.5), 2, 0, 0, 0); + check_long ("lround (-1.5) == -2", FUNC(lround) (-1.5), -2, 0, 0, 0); + check_long ("lround (22514.5) == 22515", FUNC(lround) (22514.5), 22515, 0, 0, 0); + check_long ("lround (-22514.5) == -22515", FUNC(lround) (-22514.5), -22515, 0, 0, 0); +#ifndef TEST_FLOAT + check_long ("lround (2097152.5) == 2097153", FUNC(lround) (2097152.5), 2097153, 0, 0, 0); + check_long ("lround (-2097152.5) == -2097153", FUNC(lround) (-2097152.5), -2097153, 0, 0, 0); +#endif + print_max_error ("lround", 0, 0); +} + + +static void +llround_test (void) +{ + init_max_error (); + + check_longlong ("llround (0) == 0", FUNC(llround) (0), 0, 0, 0, 0); + check_longlong ("llround (-0) == 0", FUNC(llround) (minus_zero), 0, 0, 0, 0); + check_longlong ("llround (0.2) == 0.0", FUNC(llround) (0.2L), 0.0, 0, 0, 0); + check_longlong ("llround (-0.2) == 0", FUNC(llround) (-0.2L), 0, 0, 0, 0); + check_longlong ("llround (0.5) == 1", FUNC(llround) (0.5), 1, 0, 0, 0); + check_longlong ("llround (-0.5) == -1", FUNC(llround) (-0.5), -1, 0, 0, 0); + check_longlong ("llround (0.8) == 1", FUNC(llround) (0.8L), 1, 0, 0, 0); + check_longlong ("llround (-0.8) == -1", FUNC(llround) (-0.8L), -1, 0, 0, 0); + check_longlong ("llround (1.5) == 2", FUNC(llround) (1.5), 2, 0, 0, 0); + check_longlong ("llround (-1.5) == -2", FUNC(llround) (-1.5), -2, 0, 0, 0); + check_longlong ("llround (22514.5) == 22515", FUNC(llround) (22514.5), 22515, 0, 0, 0); + check_longlong ("llround (-22514.5) == -22515", FUNC(llround) (-22514.5), -22515, 0, 0, 0); +#ifndef TEST_FLOAT + check_longlong ("llround (2097152.5) == 2097153", FUNC(llround) (2097152.5), 2097153, 0, 0, 0); + check_longlong ("llround (-2097152.5) == -2097153", FUNC(llround) (-2097152.5), -2097153, 0, 0, 0); + check_longlong ("llround (34359738368.5) == 34359738369ll", FUNC(llround) (34359738368.5), 34359738369ll, 0, 0, 0); + check_longlong ("llround (-34359738368.5) == -34359738369ll", FUNC(llround) (-34359738368.5), -34359738369ll, 0, 0, 0); +#endif + + /* Test boundary conditions. */ + /* 0x1FFFFF */ + check_longlong ("llround (2097151.0) == 2097151LL", FUNC(llround) (2097151.0), 2097151LL, 0, 0, 0); + /* 0x800000 */ + check_longlong ("llround (8388608.0) == 8388608LL", FUNC(llround) (8388608.0), 8388608LL, 0, 0, 0); + /* 0x1000000 */ + check_longlong ("llround (16777216.0) == 16777216LL", FUNC(llround) (16777216.0), 16777216LL, 0, 0, 0); + /* 0x20000000000 */ + check_longlong ("llround (2199023255552.0) == 2199023255552LL", FUNC(llround) (2199023255552.0), 2199023255552LL, 0, 0, 0); + /* 0x40000000000 */ + check_longlong ("llround (4398046511104.0) == 4398046511104LL", FUNC(llround) (4398046511104.0), 4398046511104LL, 0, 0, 0); + /* 0x10000000000000 */ + check_longlong ("llround (4503599627370496.0) == 4503599627370496LL", FUNC(llround) (4503599627370496.0), 4503599627370496LL, 0, 0, 0); + /* 0x10000080000000 */ + check_longlong ("llrint (4503601774854144.0) == 4503601774854144LL", FUNC(llrint) (4503601774854144.0), 4503601774854144LL, 0, 0, 0); + /* 0x20000000000000 */ + check_longlong ("llround (9007199254740992.0) == 9007199254740992LL", FUNC(llround) (9007199254740992.0), 9007199254740992LL, 0, 0, 0); + /* 0x80000000000000 */ + check_longlong ("llround (36028797018963968.0) == 36028797018963968LL", FUNC(llround) (36028797018963968.0), 36028797018963968LL, 0, 0, 0); + /* 0x100000000000000 */ + check_longlong ("llround (72057594037927936.0) == 72057594037927936LL", FUNC(llround) (72057594037927936.0), 72057594037927936LL, 0, 0, 0); + +#ifndef TEST_FLOAT + /* 0x100000000 */ + check_longlong ("llround (4294967295.5) == 4294967296LL", FUNC(llround) (4294967295.5), 4294967296LL, 0, 0, 0); + /* 0x200000000 */ + check_longlong ("llround (8589934591.5) == 8589934592LL", FUNC(llround) (8589934591.5), 8589934592LL, 0, 0, 0); +#endif + + print_max_error ("llround", 0, 0); +} + +static void +modf_test (void) +{ + FLOAT x; + + init_max_error (); + + check_float ("modf (inf, &x) == 0", FUNC(modf) (plus_infty, &x), 0, 0, 0, 0); + check_float ("modf (inf, &x) sets x to plus_infty", x, plus_infty, 0, 0, 0); + check_float ("modf (-inf, &x) == -0", FUNC(modf) (minus_infty, &x), minus_zero, 0, 0, 0); + check_float ("modf (-inf, &x) sets x to minus_infty", x, minus_infty, 0, 0, 0); + check_float ("modf (NaN, &x) == NaN", FUNC(modf) (nan_value, &x), nan_value, 0, 0, 0); + check_float ("modf (NaN, &x) sets x to nan_value", x, nan_value, 0, 0, 0); + check_float ("modf (0, &x) == 0", FUNC(modf) (0, &x), 0, 0, 0, 0); + check_float ("modf (0, &x) sets x to 0", x, 0, 0, 0, 0); + check_float ("modf (1.5, &x) == 0.5", FUNC(modf) (1.5, &x), 0.5, 0, 0, 0); + check_float ("modf (1.5, &x) sets x to 1", x, 1, 0, 0, 0); + check_float ("modf (2.5, &x) == 0.5", FUNC(modf) (2.5, &x), 0.5, 0, 0, 0); + check_float ("modf (2.5, &x) sets x to 2", x, 2, 0, 0, 0); + check_float ("modf (-2.5, &x) == -0.5", FUNC(modf) (-2.5, &x), -0.5, 0, 0, 0); + check_float ("modf (-2.5, &x) sets x to -2", x, -2, 0, 0, 0); + check_float ("modf (20, &x) == 0", FUNC(modf) (20, &x), 0, 0, 0, 0); + check_float ("modf (20, &x) sets x to 20", x, 20, 0, 0, 0); + check_float ("modf (21, &x) == 0", FUNC(modf) (21, &x), 0, 0, 0, 0); + check_float ("modf (21, &x) sets x to 21", x, 21, 0, 0, 0); + check_float ("modf (89.5, &x) == 0.5", FUNC(modf) (89.5, &x), 0.5, 0, 0, 0); + check_float ("modf (89.5, &x) sets x to 89", x, 89, 0, 0, 0); + + print_max_error ("modf", 0, 0); +} + +static void +nearbyint_test (void) +{ + init_max_error (); + + check_float ("nearbyint (0.0) == 0.0", FUNC(nearbyint) (0.0), 0.0, 0, 0, 0); + check_float ("nearbyint (-0) == -0", FUNC(nearbyint) (minus_zero), minus_zero, 0, 0, 0); + check_float ("nearbyint (inf) == inf", FUNC(nearbyint) (plus_infty), plus_infty, 0, 0, 0); + check_float ("nearbyint (-inf) == -inf", FUNC(nearbyint) (minus_infty), minus_infty, 0, 0, 0); + check_float ("nearbyint (NaN) == NaN", FUNC(nearbyint) (nan_value), nan_value, 0, 0, 0); + + /* Default rounding mode is round to nearest. */ + check_float ("nearbyint (0.5) == 0.0", FUNC(nearbyint) (0.5), 0.0, 0, 0, 0); + check_float ("nearbyint (1.5) == 2.0", FUNC(nearbyint) (1.5), 2.0, 0, 0, 0); + check_float ("nearbyint (-0.5) == -0", FUNC(nearbyint) (-0.5), minus_zero, 0, 0, 0); + check_float ("nearbyint (-1.5) == -2.0", FUNC(nearbyint) (-1.5), -2.0, 0, 0, 0); + + print_max_error ("nearbyint", 0, 0); +} + +static void +nextafter_test (void) +{ + + init_max_error (); + + check_float ("nextafter (0, 0) == 0", FUNC(nextafter) (0, 0), 0, 0, 0, 0); + check_float ("nextafter (-0, 0) == 0", FUNC(nextafter) (minus_zero, 0), 0, 0, 0, 0); + check_float ("nextafter (0, -0) == -0", FUNC(nextafter) (0, minus_zero), minus_zero, 0, 0, 0); + check_float ("nextafter (-0, -0) == -0", FUNC(nextafter) (minus_zero, minus_zero), minus_zero, 0, 0, 0); + + check_float ("nextafter (9, 9) == 9", FUNC(nextafter) (9, 9), 9, 0, 0, 0); + check_float ("nextafter (-9, -9) == -9", FUNC(nextafter) (-9, -9), -9, 0, 0, 0); + check_float ("nextafter (inf, inf) == inf", FUNC(nextafter) (plus_infty, plus_infty), plus_infty, 0, 0, 0); + check_float ("nextafter (-inf, -inf) == -inf", FUNC(nextafter) (minus_infty, minus_infty), minus_infty, 0, 0, 0); + + check_float ("nextafter (NaN, 1.1) == NaN", FUNC(nextafter) (nan_value, 1.1L), nan_value, 0, 0, 0); + check_float ("nextafter (1.1, NaN) == NaN", FUNC(nextafter) (1.1L, nan_value), nan_value, 0, 0, 0); + check_float ("nextafter (NaN, NaN) == NaN", FUNC(nextafter) (nan_value, nan_value), nan_value, 0, 0, 0); + + /* XXX We need the hexadecimal FP number representation here for further + tests. */ + + print_max_error ("nextafter", 0, 0); +} + + +#if 0 /* XXX scp XXX */ +static void +nexttoward_test (void) +{ + init_max_error (); + check_float ("nexttoward (0, 0) == 0", FUNC(nexttoward) (0, 0), 0, 0, 0, 0); + check_float ("nexttoward (-0, 0) == 0", FUNC(nexttoward) (minus_zero, 0), 0, 0, 0, 0); + check_float ("nexttoward (0, -0) == -0", FUNC(nexttoward) (0, minus_zero), minus_zero, 0, 0, 0); + check_float ("nexttoward (-0, -0) == -0", FUNC(nexttoward) (minus_zero, minus_zero), minus_zero, 0, 0, 0); + + check_float ("nexttoward (9, 9) == 9", FUNC(nexttoward) (9, 9), 9, 0, 0, 0); + check_float ("nexttoward (-9, -9) == -9", FUNC(nexttoward) (-9, -9), -9, 0, 0, 0); + check_float ("nexttoward (inf, inf) == inf", FUNC(nexttoward) (plus_infty, plus_infty), plus_infty, 0, 0, 0); + check_float ("nexttoward (-inf, -inf) == -inf", FUNC(nexttoward) (minus_infty, minus_infty), minus_infty, 0, 0, 0); + + check_float ("nexttoward (NaN, 1.1) == NaN", FUNC(nexttoward) (nan_value, 1.1L), nan_value, 0, 0, 0); + check_float ("nexttoward (1.1, NaN) == NaN", FUNC(nexttoward) (1.1L, nan_value), nan_value, 0, 0, 0); + check_float ("nexttoward (NaN, NaN) == NaN", FUNC(nexttoward) (nan_value, nan_value), nan_value, 0, 0, 0); + + /* XXX We need the hexadecimal FP number representation here for further + tests. */ + + print_max_error ("nexttoward", 0, 0); +} +#endif + + +static void +pow_test (void) +{ + + errno = 0; + FUNC(pow) (0, 0); + if (errno == ENOSYS) + /* Function not implemented. */ + return; + + init_max_error (); + + check_float ("pow (0, 0) == 1", FUNC(pow) (0, 0), 1, 0, 0, 0); + check_float ("pow (0, -0) == 1", FUNC(pow) (0, minus_zero), 1, 0, 0, 0); + check_float ("pow (-0, 0) == 1", FUNC(pow) (minus_zero, 0), 1, 0, 0, 0); + check_float ("pow (-0, -0) == 1", FUNC(pow) (minus_zero, minus_zero), 1, 0, 0, 0); + + check_float ("pow (10, 0) == 1", FUNC(pow) (10, 0), 1, 0, 0, 0); + check_float ("pow (10, -0) == 1", FUNC(pow) (10, minus_zero), 1, 0, 0, 0); + check_float ("pow (-10, 0) == 1", FUNC(pow) (-10, 0), 1, 0, 0, 0); + check_float ("pow (-10, -0) == 1", FUNC(pow) (-10, minus_zero), 1, 0, 0, 0); + + check_float ("pow (NaN, 0) == 1", FUNC(pow) (nan_value, 0), 1, 0, 0, 0); + check_float ("pow (NaN, -0) == 1", FUNC(pow) (nan_value, minus_zero), 1, 0, 0, 0); + + +#ifndef TEST_INLINE + check_float ("pow (1.1, inf) == inf", FUNC(pow) (1.1L, plus_infty), plus_infty, 0, 0, 0); + check_float ("pow (inf, inf) == inf", FUNC(pow) (plus_infty, plus_infty), plus_infty, 0, 0, 0); + check_float ("pow (-1.1, inf) == inf", FUNC(pow) (-1.1L, plus_infty), plus_infty, 0, 0, 0); + check_float ("pow (-inf, inf) == inf", FUNC(pow) (minus_infty, plus_infty), plus_infty, 0, 0, 0); + + check_float ("pow (0.9, inf) == 0", FUNC(pow) (0.9L, plus_infty), 0, 0, 0, 0); + check_float ("pow (1e-7, inf) == 0", FUNC(pow) (1e-7L, plus_infty), 0, 0, 0, 0); + check_float ("pow (-0.9, inf) == 0", FUNC(pow) (-0.9L, plus_infty), 0, 0, 0, 0); + check_float ("pow (-1e-7, inf) == 0", FUNC(pow) (-1e-7L, plus_infty), 0, 0, 0, 0); + + check_float ("pow (1.1, -inf) == 0", FUNC(pow) (1.1L, minus_infty), 0, 0, 0, 0); + check_float ("pow (inf, -inf) == 0", FUNC(pow) (plus_infty, minus_infty), 0, 0, 0, 0); + check_float ("pow (-1.1, -inf) == 0", FUNC(pow) (-1.1L, minus_infty), 0, 0, 0, 0); + check_float ("pow (-inf, -inf) == 0", FUNC(pow) (minus_infty, minus_infty), 0, 0, 0, 0); + + check_float ("pow (0.9, -inf) == inf", FUNC(pow) (0.9L, minus_infty), plus_infty, 0, 0, 0); + check_float ("pow (1e-7, -inf) == inf", FUNC(pow) (1e-7L, minus_infty), plus_infty, 0, 0, 0); + check_float ("pow (-0.9, -inf) == inf", FUNC(pow) (-0.9L, minus_infty), plus_infty, 0, 0, 0); + check_float ("pow (-1e-7, -inf) == inf", FUNC(pow) (-1e-7L, minus_infty), plus_infty, 0, 0, 0); + + check_float ("pow (inf, 1e-7) == inf", FUNC(pow) (plus_infty, 1e-7L), plus_infty, 0, 0, 0); + check_float ("pow (inf, 1) == inf", FUNC(pow) (plus_infty, 1), plus_infty, 0, 0, 0); + check_float ("pow (inf, 1e7) == inf", FUNC(pow) (plus_infty, 1e7L), plus_infty, 0, 0, 0); + + check_float ("pow (inf, -1e-7) == 0", FUNC(pow) (plus_infty, -1e-7L), 0, 0, 0, 0); + check_float ("pow (inf, -1) == 0", FUNC(pow) (plus_infty, -1), 0, 0, 0, 0); + check_float ("pow (inf, -1e7) == 0", FUNC(pow) (plus_infty, -1e7L), 0, 0, 0, 0); + + check_float ("pow (-inf, 1) == -inf", FUNC(pow) (minus_infty, 1), minus_infty, 0, 0, 0); + check_float ("pow (-inf, 11) == -inf", FUNC(pow) (minus_infty, 11), minus_infty, 0, 0, 0); + check_float ("pow (-inf, 1001) == -inf", FUNC(pow) (minus_infty, 1001), minus_infty, 0, 0, 0); + + check_float ("pow (-inf, 2) == inf", FUNC(pow) (minus_infty, 2), plus_infty, 0, 0, 0); + check_float ("pow (-inf, 12) == inf", FUNC(pow) (minus_infty, 12), plus_infty, 0, 0, 0); + check_float ("pow (-inf, 1002) == inf", FUNC(pow) (minus_infty, 1002), plus_infty, 0, 0, 0); + check_float ("pow (-inf, 0.1) == inf", FUNC(pow) (minus_infty, 0.1L), plus_infty, 0, 0, 0); + check_float ("pow (-inf, 1.1) == inf", FUNC(pow) (minus_infty, 1.1L), plus_infty, 0, 0, 0); + check_float ("pow (-inf, 11.1) == inf", FUNC(pow) (minus_infty, 11.1L), plus_infty, 0, 0, 0); + check_float ("pow (-inf, 1001.1) == inf", FUNC(pow) (minus_infty, 1001.1L), plus_infty, 0, 0, 0); + + check_float ("pow (-inf, -1) == -0", FUNC(pow) (minus_infty, -1), minus_zero, 0, 0, 0); + check_float ("pow (-inf, -11) == -0", FUNC(pow) (minus_infty, -11), minus_zero, 0, 0, 0); + check_float ("pow (-inf, -1001) == -0", FUNC(pow) (minus_infty, -1001), minus_zero, 0, 0, 0); + + check_float ("pow (-inf, -2) == 0", FUNC(pow) (minus_infty, -2), 0, 0, 0, 0); + check_float ("pow (-inf, -12) == 0", FUNC(pow) (minus_infty, -12), 0, 0, 0, 0); + check_float ("pow (-inf, -1002) == 0", FUNC(pow) (minus_infty, -1002), 0, 0, 0, 0); + check_float ("pow (-inf, -0.1) == 0", FUNC(pow) (minus_infty, -0.1L), 0, 0, 0, 0); + check_float ("pow (-inf, -1.1) == 0", FUNC(pow) (minus_infty, -1.1L), 0, 0, 0, 0); + check_float ("pow (-inf, -11.1) == 0", FUNC(pow) (minus_infty, -11.1L), 0, 0, 0, 0); + check_float ("pow (-inf, -1001.1) == 0", FUNC(pow) (minus_infty, -1001.1L), 0, 0, 0, 0); +#endif + + check_float ("pow (NaN, NaN) == NaN", FUNC(pow) (nan_value, nan_value), nan_value, 0, 0, 0); + check_float ("pow (0, NaN) == NaN", FUNC(pow) (0, nan_value), nan_value, 0, 0, 0); + check_float ("pow (1, NaN) == 1", FUNC(pow) (1, nan_value), 1, 0, 0, 0); + check_float ("pow (-1, NaN) == NaN", FUNC(pow) (-1, nan_value), nan_value, 0, 0, 0); + check_float ("pow (NaN, 1) == NaN", FUNC(pow) (nan_value, 1), nan_value, 0, 0, 0); + check_float ("pow (NaN, -1) == NaN", FUNC(pow) (nan_value, -1), nan_value, 0, 0, 0); + + /* pow (x, NaN) == NaN. */ + check_float ("pow (3.0, NaN) == NaN", FUNC(pow) (3.0, nan_value), nan_value, 0, 0, 0); + + check_float ("pow (1, inf) == 1", FUNC(pow) (1, plus_infty), 1, 0, 0, 0); + check_float ("pow (-1, inf) == 1", FUNC(pow) (-1, plus_infty), 1, 0, 0, 0); + check_float ("pow (1, -inf) == 1", FUNC(pow) (1, minus_infty), 1, 0, 0, 0); + check_float ("pow (-1, -inf) == 1", FUNC(pow) (-1, minus_infty), 1, 0, 0, 0); + + check_float ("pow (-0.1, 1.1) == NaN plus invalid exception", FUNC(pow) (-0.1L, 1.1L), nan_value, 0, 0, INVALID_EXCEPTION); + check_float ("pow (-0.1, -1.1) == NaN plus invalid exception", FUNC(pow) (-0.1L, -1.1L), nan_value, 0, 0, INVALID_EXCEPTION); + check_float ("pow (-10.1, 1.1) == NaN plus invalid exception", FUNC(pow) (-10.1L, 1.1L), nan_value, 0, 0, INVALID_EXCEPTION); + check_float ("pow (-10.1, -1.1) == NaN plus invalid exception", FUNC(pow) (-10.1L, -1.1L), nan_value, 0, 0, INVALID_EXCEPTION); + + check_float ("pow (0, -1) == inf plus division by zero exception", FUNC(pow) (0, -1), plus_infty, 0, 0, DIVIDE_BY_ZERO_EXCEPTION); + check_float ("pow (0, -11) == inf plus division by zero exception", FUNC(pow) (0, -11), plus_infty, 0, 0, DIVIDE_BY_ZERO_EXCEPTION); + check_float ("pow (-0, -1) == -inf plus division by zero exception", FUNC(pow) (minus_zero, -1), minus_infty, 0, 0, DIVIDE_BY_ZERO_EXCEPTION); + check_float ("pow (-0, -11) == -inf plus division by zero exception", FUNC(pow) (minus_zero, -11), minus_infty, 0, 0, DIVIDE_BY_ZERO_EXCEPTION); + + check_float ("pow (0, -2) == inf plus division by zero exception", FUNC(pow) (0, -2), plus_infty, 0, 0, DIVIDE_BY_ZERO_EXCEPTION); + check_float ("pow (0, -11.1) == inf plus division by zero exception", FUNC(pow) (0, -11.1L), plus_infty, 0, 0, DIVIDE_BY_ZERO_EXCEPTION); + check_float ("pow (-0, -2) == inf plus division by zero exception", FUNC(pow) (minus_zero, -2), plus_infty, 0, 0, DIVIDE_BY_ZERO_EXCEPTION); + check_float ("pow (-0, -11.1) == inf plus division by zero exception", FUNC(pow) (minus_zero, -11.1L), plus_infty, 0, 0, DIVIDE_BY_ZERO_EXCEPTION); + + + check_float ("pow (0, 1) == 0", FUNC(pow) (0, 1), 0, 0, 0, 0); + check_float ("pow (0, 11) == 0", FUNC(pow) (0, 11), 0, 0, 0, 0); + + check_float ("pow (-0, 1) == -0", FUNC(pow) (minus_zero, 1), minus_zero, 0, 0, 0); + check_float ("pow (-0, 11) == -0", FUNC(pow) (minus_zero, 11), minus_zero, 0, 0, 0); + + + check_float ("pow (0, 2) == 0", FUNC(pow) (0, 2), 0, 0, 0, 0); + check_float ("pow (0, 11.1) == 0", FUNC(pow) (0, 11.1L), 0, 0, 0, 0); + + + check_float ("pow (-0, 2) == 0", FUNC(pow) (minus_zero, 2), 0, 0, 0, 0); + check_float ("pow (-0, 11.1) == 0", FUNC(pow) (minus_zero, 11.1L), 0, 0, 0, 0); + +#ifndef TEST_INLINE + /* pow (x, +inf) == +inf for |x| > 1. */ + check_float ("pow (1.5, inf) == inf", FUNC(pow) (1.5, plus_infty), plus_infty, 0, 0, 0); + + /* pow (x, +inf) == +0 for |x| < 1. */ + check_float ("pow (0.5, inf) == 0.0", FUNC(pow) (0.5, plus_infty), 0.0, 0, 0, 0); + + /* pow (x, -inf) == +0 for |x| > 1. */ + check_float ("pow (1.5, -inf) == 0.0", FUNC(pow) (1.5, minus_infty), 0.0, 0, 0, 0); + + /* pow (x, -inf) == +inf for |x| < 1. */ + check_float ("pow (0.5, -inf) == inf", FUNC(pow) (0.5, minus_infty), plus_infty, 0, 0, 0); +#endif + + /* pow (+inf, y) == +inf for y > 0. */ + check_float ("pow (inf, 2) == inf", FUNC(pow) (plus_infty, 2), plus_infty, 0, 0, 0); + + /* pow (+inf, y) == +0 for y < 0. */ + check_float ("pow (inf, -1) == 0.0", FUNC(pow) (plus_infty, -1), 0.0, 0, 0, 0); + + /* pow (-inf, y) == -inf for y an odd integer > 0. */ + check_float ("pow (-inf, 27) == -inf", FUNC(pow) (minus_infty, 27), minus_infty, 0, 0, 0); + + /* pow (-inf, y) == +inf for y > 0 and not an odd integer. */ + check_float ("pow (-inf, 28) == inf", FUNC(pow) (minus_infty, 28), plus_infty, 0, 0, 0); + + /* pow (-inf, y) == -0 for y an odd integer < 0. */ + check_float ("pow (-inf, -3) == -0", FUNC(pow) (minus_infty, -3), minus_zero, 0, 0, 0); + /* pow (-inf, y) == +0 for y < 0 and not an odd integer. */ + check_float ("pow (-inf, -2.0) == 0.0", FUNC(pow) (minus_infty, -2.0), 0.0, 0, 0, 0); + + /* pow (+0, y) == +0 for y an odd integer > 0. */ + check_float ("pow (0.0, 27) == 0.0", FUNC(pow) (0.0, 27), 0.0, 0, 0, 0); + + /* pow (-0, y) == -0 for y an odd integer > 0. */ + check_float ("pow (-0, 27) == -0", FUNC(pow) (minus_zero, 27), minus_zero, 0, 0, 0); + + /* pow (+0, y) == +0 for y > 0 and not an odd integer. */ + check_float ("pow (0.0, 4) == 0.0", FUNC(pow) (0.0, 4), 0.0, 0, 0, 0); + + /* pow (-0, y) == +0 for y > 0 and not an odd integer. */ + check_float ("pow (-0, 4) == 0.0", FUNC(pow) (minus_zero, 4), 0.0, 0, 0, 0); + + check_float ("pow (0.7, 1.2) == 0.65180494056638638188", FUNC(pow) (0.7L, 1.2L), 0.65180494056638638188L, DELTA1398, 0, 0); + +#if defined TEST_DOUBLE || defined TEST_LDOUBLE + check_float ("pow (-7.49321e+133, -9.80818e+16) == 0", FUNC(pow) (-7.49321e+133, -9.80818e+16), 0, 0, 0, 0); +#endif + + print_max_error ("pow", DELTApow, 0); +} + +static void +remainder_test (void) +{ + errno = 0; + FUNC(remainder) (1.625, 1.0); + if (errno == ENOSYS) + /* Function not implemented. */ + return; + + init_max_error (); + + check_float ("remainder (1, 0) == NaN plus invalid exception", FUNC(remainder) (1, 0), nan_value, 0, 0, INVALID_EXCEPTION); + check_float ("remainder (1, -0) == NaN plus invalid exception", FUNC(remainder) (1, minus_zero), nan_value, 0, 0, INVALID_EXCEPTION); + check_float ("remainder (inf, 1) == NaN plus invalid exception", FUNC(remainder) (plus_infty, 1), nan_value, 0, 0, INVALID_EXCEPTION); + check_float ("remainder (-inf, 1) == NaN plus invalid exception", FUNC(remainder) (minus_infty, 1), nan_value, 0, 0, INVALID_EXCEPTION); + check_float ("remainder (NaN, NaN) == NaN", FUNC(remainder) (nan_value, nan_value), nan_value, 0, 0, 0); + + check_float ("remainder (1.625, 1.0) == -0.375", FUNC(remainder) (1.625, 1.0), -0.375, 0, 0, 0); + check_float ("remainder (-1.625, 1.0) == 0.375", FUNC(remainder) (-1.625, 1.0), 0.375, 0, 0, 0); + check_float ("remainder (1.625, -1.0) == -0.375", FUNC(remainder) (1.625, -1.0), -0.375, 0, 0, 0); + check_float ("remainder (-1.625, -1.0) == 0.375", FUNC(remainder) (-1.625, -1.0), 0.375, 0, 0, 0); + check_float ("remainder (5.0, 2.0) == 1.0", FUNC(remainder) (5.0, 2.0), 1.0, 0, 0, 0); + check_float ("remainder (3.0, 2.0) == -1.0", FUNC(remainder) (3.0, 2.0), -1.0, 0, 0, 0); + + print_max_error ("remainder", 0, 0); +} + +static void +remquo_test (void) +{ + /* x is needed. */ + int x; + + errno = 0; + FUNC(remquo) (1.625, 1.0, &x); + if (errno == ENOSYS) + /* Function not implemented. */ + return; + + init_max_error (); + + check_float ("remquo (1, 0, &x) == NaN plus invalid exception", FUNC(remquo) (1, 0, &x), nan_value, 0, 0, INVALID_EXCEPTION); + check_float ("remquo (1, -0, &x) == NaN plus invalid exception", FUNC(remquo) (1, minus_zero, &x), nan_value, 0, 0, INVALID_EXCEPTION); + check_float ("remquo (inf, 1, &x) == NaN plus invalid exception", FUNC(remquo) (plus_infty, 1, &x), nan_value, 0, 0, INVALID_EXCEPTION); + check_float ("remquo (-inf, 1, &x) == NaN plus invalid exception", FUNC(remquo) (minus_infty, 1, &x), nan_value, 0, 0, INVALID_EXCEPTION); + check_float ("remquo (NaN, NaN, &x) == NaN", FUNC(remquo) (nan_value, nan_value, &x), nan_value, 0, 0, 0); + + check_float ("remquo (1.625, 1.0, &x) == -0.375", FUNC(remquo) (1.625, 1.0, &x), -0.375, 0, 0, 0); + check_int ("remquo (1.625, 1.0, &x) sets x to 2", x, 2, 0, 0, 0); + check_float ("remquo (-1.625, 1.0, &x) == 0.375", FUNC(remquo) (-1.625, 1.0, &x), 0.375, 0, 0, 0); + check_int ("remquo (-1.625, 1.0, &x) sets x to -2", x, -2, 0, 0, 0); + check_float ("remquo (1.625, -1.0, &x) == -0.375", FUNC(remquo) (1.625, -1.0, &x), -0.375, 0, 0, 0); + check_int ("remquo (1.625, -1.0, &x) sets x to -2", x, -2, 0, 0, 0); + check_float ("remquo (-1.625, -1.0, &x) == 0.375", FUNC(remquo) (-1.625, -1.0, &x), 0.375, 0, 0, 0); + check_int ("remquo (-1.625, -1.0, &x) sets x to 2", x, 2, 0, 0, 0); + + check_float ("remquo (5, 2, &x) == 1", FUNC(remquo) (5, 2, &x), 1, 0, 0, 0); + check_int ("remquo (5, 2, &x) sets x to 2", x, 2, 0, 0, 0); + check_float ("remquo (3, 2, &x) == -1", FUNC(remquo) (3, 2, &x), -1, 0, 0, 0); + check_int ("remquo (3, 2, &x) sets x to 2", x, 2, 0, 0, 0); + + print_max_error ("remquo", 0, 0); +} + +static void +rint_test (void) +{ + init_max_error (); + + check_float ("rint (0.0) == 0.0", FUNC(rint) (0.0), 0.0, 0, 0, 0); + check_float ("rint (-0) == -0", FUNC(rint) (minus_zero), minus_zero, 0, 0, 0); + check_float ("rint (inf) == inf", FUNC(rint) (plus_infty), plus_infty, 0, 0, 0); + check_float ("rint (-inf) == -inf", FUNC(rint) (minus_infty), minus_infty, 0, 0, 0); + + /* Default rounding mode is round to even. */ + check_float ("rint (0.5) == 0.0", FUNC(rint) (0.5), 0.0, 0, 0, 0); + check_float ("rint (1.5) == 2.0", FUNC(rint) (1.5), 2.0, 0, 0, 0); + check_float ("rint (2.5) == 2.0", FUNC(rint) (2.5), 2.0, 0, 0, 0); + check_float ("rint (3.5) == 4.0", FUNC(rint) (3.5), 4.0, 0, 0, 0); + check_float ("rint (4.5) == 4.0", FUNC(rint) (4.5), 4.0, 0, 0, 0); + check_float ("rint (-0.5) == -0.0", FUNC(rint) (-0.5), -0.0, 0, 0, 0); + check_float ("rint (-1.5) == -2.0", FUNC(rint) (-1.5), -2.0, 0, 0, 0); + check_float ("rint (-2.5) == -2.0", FUNC(rint) (-2.5), -2.0, 0, 0, 0); + check_float ("rint (-3.5) == -4.0", FUNC(rint) (-3.5), -4.0, 0, 0, 0); + check_float ("rint (-4.5) == -4.0", FUNC(rint) (-4.5), -4.0, 0, 0, 0); + + print_max_error ("rint", 0, 0); +} + +static void +round_test (void) +{ + init_max_error (); + + check_float ("round (0) == 0", FUNC(round) (0), 0, 0, 0, 0); + check_float ("round (-0) == -0", FUNC(round) (minus_zero), minus_zero, 0, 0, 0); + check_float ("round (0.2) == 0.0", FUNC(round) (0.2L), 0.0, 0, 0, 0); + check_float ("round (-0.2) == -0", FUNC(round) (-0.2L), minus_zero, 0, 0, 0); + check_float ("round (0.5) == 1.0", FUNC(round) (0.5), 1.0, 0, 0, 0); + check_float ("round (-0.5) == -1.0", FUNC(round) (-0.5), -1.0, 0, 0, 0); + check_float ("round (0.8) == 1.0", FUNC(round) (0.8L), 1.0, 0, 0, 0); + check_float ("round (-0.8) == -1.0", FUNC(round) (-0.8L), -1.0, 0, 0, 0); + check_float ("round (1.5) == 2.0", FUNC(round) (1.5), 2.0, 0, 0, 0); + check_float ("round (-1.5) == -2.0", FUNC(round) (-1.5), -2.0, 0, 0, 0); + check_float ("round (2097152.5) == 2097153", FUNC(round) (2097152.5), 2097153, 0, 0, 0); + check_float ("round (-2097152.5) == -2097153", FUNC(round) (-2097152.5), -2097153, 0, 0, 0); + + print_max_error ("round", 0, 0); +} + + +static void +scalbn_test (void) +{ + + init_max_error (); + + check_float ("scalbn (0, 0) == 0", FUNC(scalbn) (0, 0), 0, 0, 0, 0); + check_float ("scalbn (-0, 0) == -0", FUNC(scalbn) (minus_zero, 0), minus_zero, 0, 0, 0); + + check_float ("scalbn (inf, 1) == inf", FUNC(scalbn) (plus_infty, 1), plus_infty, 0, 0, 0); + check_float ("scalbn (-inf, 1) == -inf", FUNC(scalbn) (minus_infty, 1), minus_infty, 0, 0, 0); + check_float ("scalbn (NaN, 1) == NaN", FUNC(scalbn) (nan_value, 1), nan_value, 0, 0, 0); + + check_float ("scalbn (0.8, 4) == 12.8", FUNC(scalbn) (0.8L, 4), 12.8L, 0, 0, 0); + check_float ("scalbn (-0.854375, 5) == -27.34", FUNC(scalbn) (-0.854375L, 5), -27.34L, 0, 0, 0); + + check_float ("scalbn (1, 0) == 1", FUNC(scalbn) (1, 0L), 1, 0, 0, 0); + + print_max_error ("scalbn", 0, 0); +} + +static void +scalbln_test (void) +{ + + init_max_error (); + + check_float ("scalbln (0, 0) == 0", FUNC(scalbln) (0, 0), 0, 0, 0, 0); + check_float ("scalbln (-0, 0) == -0", FUNC(scalbln) (minus_zero, 0), minus_zero, 0, 0, 0); + + check_float ("scalbln (inf, 1) == inf", FUNC(scalbln) (plus_infty, 1), plus_infty, 0, 0, 0); + check_float ("scalbln (-inf, 1) == -inf", FUNC(scalbln) (minus_infty, 1), minus_infty, 0, 0, 0); + check_float ("scalbln (NaN, 1) == NaN", FUNC(scalbln) (nan_value, 1), nan_value, 0, 0, 0); + + check_float ("scalbln (0.8, 4) == 12.8", FUNC(scalbln) (0.8L, 4), 12.8L, 0, 0, 0); + check_float ("scalbln (-0.854375, 5) == -27.34", FUNC(scalbln) (-0.854375L, 5), -27.34L, 0, 0, 0); + + check_float ("scalbln (1, 0) == 1", FUNC(scalbln) (1, 0L), 1, 0, 0, 0); + + print_max_error ("scalbn", 0, 0); +} + +static void +signbit_test (void) +{ + + init_max_error (); + + check_bool ("signbit (0) == false", signbit (0.0), 0, 0, 0, 0); + check_bool ("signbit (-0) == true", signbit (minus_zero), 1, 0, 0, 0); + check_bool ("signbit (inf) == false", signbit (plus_infty), 0, 0, 0, 0); + check_bool ("signbit (-inf) == true", signbit (minus_infty), 1, 0, 0, 0); + + /* signbit (x) != 0 for x < 0. */ + check_bool ("signbit (-1) == true", signbit (-1.0), 1, 0, 0, 0); + /* signbit (x) == 0 for x >= 0. */ + check_bool ("signbit (1) == false", signbit (1.0), 0, 0, 0, 0); + + print_max_error ("signbit", 0, 0); +} + +static void +sin_test (void) +{ + errno = 0; + FUNC(sin) (0); + if (errno == ENOSYS) + /* Function not implemented. */ + return; + + init_max_error (); + + check_float ("sin (0) == 0", FUNC(sin) (0), 0, 0, 0, 0); + check_float ("sin (-0) == -0", FUNC(sin) (minus_zero), minus_zero, 0, 0, 0); + check_float ("sin (inf) == NaN plus invalid exception", FUNC(sin) (plus_infty), nan_value, 0, 0, INVALID_EXCEPTION); + check_float ("sin (-inf) == NaN plus invalid exception", FUNC(sin) (minus_infty), nan_value, 0, 0, INVALID_EXCEPTION); + check_float ("sin (NaN) == NaN", FUNC(sin) (nan_value), nan_value, 0, 0, 0); + + check_float ("sin (pi/6) == 0.5", FUNC(sin) (M_PI_6l), 0.5, 0, 0, 0); + check_float ("sin (-pi/6) == -0.5", FUNC(sin) (-M_PI_6l), -0.5, 0, 0, 0); + check_float ("sin (pi/2) == 1", FUNC(sin) (M_PI_2l), 1, 0, 0, 0); + check_float ("sin (-pi/2) == -1", FUNC(sin) (-M_PI_2l), -1, 0, 0, 0); + check_float ("sin (0.7) == 0.64421768723769105367261435139872014", FUNC(sin) (0.7L), 0.64421768723769105367261435139872014L, DELTA1524, 0, 0); + + print_max_error ("sin", DELTAsin, 0); + +} + + +static void +sincos_test (void) +{ + FLOAT sin_res, cos_res; + + errno = 0; + FUNC(sincos) (0, &sin_res, &cos_res); + if (errno == ENOSYS) + /* Function not implemented. */ + return; + + init_max_error (); + + /* sincos is treated differently because it returns void. */ + FUNC (sincos) (0, &sin_res, &cos_res); + check_float ("sincos (0, &sin_res, &cos_res) puts 0 in sin_res", sin_res, 0, 0, 0, 0); + check_float ("sincos (0, &sin_res, &cos_res) puts 1 in cos_res", cos_res, 1, 0, 0, 0); + + FUNC (sincos) (minus_zero, &sin_res, &cos_res); + check_float ("sincos (-0, &sin_res, &cos_res) puts -0 in sin_res", sin_res, minus_zero, 0, 0, 0); + check_float ("sincos (-0, &sin_res, &cos_res) puts 1 in cos_res", cos_res, 1, 0, 0, 0); + FUNC (sincos) (plus_infty, &sin_res, &cos_res); + check_float ("sincos (inf, &sin_res, &cos_res) puts NaN in sin_res plus invalid exception", sin_res, nan_value, 0, 0, INVALID_EXCEPTION); + check_float ("sincos (inf, &sin_res, &cos_res) puts NaN in cos_res", cos_res, nan_value, 0, 0, 0); + FUNC (sincos) (minus_infty, &sin_res, &cos_res); + check_float ("sincos (-inf, &sin_res, &cos_res) puts NaN in sin_res plus invalid exception", sin_res, nan_value, 0, 0, INVALID_EXCEPTION); + check_float ("sincos (-inf, &sin_res, &cos_res) puts NaN in cos_res", cos_res, nan_value, 0, 0, 0); + FUNC (sincos) (nan_value, &sin_res, &cos_res); + check_float ("sincos (NaN, &sin_res, &cos_res) puts NaN in sin_res", sin_res, nan_value, 0, 0, 0); + check_float ("sincos (NaN, &sin_res, &cos_res) puts NaN in cos_res", cos_res, nan_value, 0, 0, 0); + + FUNC (sincos) (M_PI_2l, &sin_res, &cos_res); + check_float ("sincos (pi/2, &sin_res, &cos_res) puts 1 in sin_res", sin_res, 1, 0, 0, 0); + check_float ("sincos (pi/2, &sin_res, &cos_res) puts 0 in cos_res", cos_res, 0, DELTA1536, 0, 0); + FUNC (sincos) (M_PI_6l, &sin_res, &cos_res); + check_float ("sincos (pi/6, &sin_res, &cos_res) puts 0.5 in sin_res", sin_res, 0.5, 0, 0, 0); + check_float ("sincos (pi/6, &sin_res, &cos_res) puts 0.86602540378443864676372317075293616 in cos_res", cos_res, 0.86602540378443864676372317075293616L, 0, 0, 0); + FUNC (sincos) (M_PI_6l*2.0, &sin_res, &cos_res); + check_float ("sincos (M_PI_6l*2.0, &sin_res, &cos_res) puts 0.86602540378443864676372317075293616 in sin_res", sin_res, 0.86602540378443864676372317075293616L, DELTA1539, 0, 0); + check_float ("sincos (M_PI_6l*2.0, &sin_res, &cos_res) puts 0.5 in cos_res", cos_res, 0.5, DELTA1540, 0, 0); + FUNC (sincos) (0.7L, &sin_res, &cos_res); + check_float ("sincos (0.7, &sin_res, &cos_res) puts 0.64421768723769105367261435139872014 in sin_res", sin_res, 0.64421768723769105367261435139872014L, DELTA1541, 0, 0); + check_float ("sincos (0.7, &sin_res, &cos_res) puts 0.76484218728448842625585999019186495 in cos_res", cos_res, 0.76484218728448842625585999019186495L, DELTA1542, 0, 0); + + print_max_error ("sincos", DELTAsincos, 0); +} + +static void +sinh_test (void) +{ + errno = 0; + FUNC(sinh) (0.7L); + if (errno == ENOSYS) + /* Function not implemented. */ + return; + + init_max_error (); + check_float ("sinh (0) == 0", FUNC(sinh) (0), 0, 0, 0, 0); + check_float ("sinh (-0) == -0", FUNC(sinh) (minus_zero), minus_zero, 0, 0, 0); + +#ifndef TEST_INLINE + check_float ("sinh (inf) == inf", FUNC(sinh) (plus_infty), plus_infty, 0, 0, 0); + check_float ("sinh (-inf) == -inf", FUNC(sinh) (minus_infty), minus_infty, 0, 0, 0); +#endif + check_float ("sinh (NaN) == NaN", FUNC(sinh) (nan_value), nan_value, 0, 0, 0); + + check_float ("sinh (0.7) == 0.75858370183953350346", FUNC(sinh) (0.7L), 0.75858370183953350346L, DELTA1548, 0, 0); +#if 0 /* XXX scp XXX */ + check_float ("sinh (0x8p-32) == 1.86264514923095703232705808926175479e-9", FUNC(sinh) (0x8p-32L), 1.86264514923095703232705808926175479e-9L, 0, 0, 0); +#endif + + print_max_error ("sinh", DELTAsinh, 0); +} + +static void +sqrt_test (void) +{ + errno = 0; + FUNC(sqrt) (1); + if (errno == ENOSYS) + /* Function not implemented. */ + return; + + init_max_error (); + + check_float ("sqrt (0) == 0", FUNC(sqrt) (0), 0, 0, 0, 0); + check_float ("sqrt (NaN) == NaN", FUNC(sqrt) (nan_value), nan_value, 0, 0, 0); + check_float ("sqrt (inf) == inf", FUNC(sqrt) (plus_infty), plus_infty, 0, 0, 0); + + check_float ("sqrt (-0) == -0", FUNC(sqrt) (minus_zero), minus_zero, 0, 0, 0); + + /* sqrt (x) == NaN plus invalid exception for x < 0. */ + check_float ("sqrt (-1) == NaN plus invalid exception", FUNC(sqrt) (-1), nan_value, 0, 0, INVALID_EXCEPTION); + check_float ("sqrt (-inf) == NaN plus invalid exception", FUNC(sqrt) (minus_infty), nan_value, 0, 0, INVALID_EXCEPTION); + check_float ("sqrt (NaN) == NaN", FUNC(sqrt) (nan_value), nan_value, 0, 0, 0); + + check_float ("sqrt (2209) == 47", FUNC(sqrt) (2209), 47, 0, 0, 0); + check_float ("sqrt (4) == 2", FUNC(sqrt) (4), 2, 0, 0, 0); + check_float ("sqrt (2) == M_SQRT2l", FUNC(sqrt) (2), M_SQRT2l, 0, 0, 0); + check_float ("sqrt (0.25) == 0.5", FUNC(sqrt) (0.25), 0.5, 0, 0, 0); + check_float ("sqrt (6642.25) == 81.5", FUNC(sqrt) (6642.25), 81.5, 0, 0, 0); + check_float ("sqrt (15239.9025) == 123.45", FUNC(sqrt) (15239.9025L), 123.45L, DELTA1562, 0, 0); + check_float ("sqrt (0.7) == 0.83666002653407554797817202578518747", FUNC(sqrt) (0.7L), 0.83666002653407554797817202578518747L, 0, 0, 0); + + print_max_error ("sqrt", DELTAsqrt, 0); +} + +static void +tan_test (void) +{ + errno = 0; + FUNC(tan) (0); + if (errno == ENOSYS) + /* Function not implemented. */ + return; + + init_max_error (); + + check_float ("tan (0) == 0", FUNC(tan) (0), 0, 0, 0, 0); + check_float ("tan (-0) == -0", FUNC(tan) (minus_zero), minus_zero, 0, 0, 0); + check_float ("tan (inf) == NaN plus invalid exception", FUNC(tan) (plus_infty), nan_value, 0, 0, INVALID_EXCEPTION); + check_float ("tan (-inf) == NaN plus invalid exception", FUNC(tan) (minus_infty), nan_value, 0, 0, INVALID_EXCEPTION); + check_float ("tan (NaN) == NaN", FUNC(tan) (nan_value), nan_value, 0, 0, 0); + + check_float ("tan (pi/4) == 1", FUNC(tan) (M_PI_4l), 1, DELTA1569, 0, 0); + check_float ("tan (0.7) == 0.84228838046307944812813500221293775", FUNC(tan) (0.7L), 0.84228838046307944812813500221293775L, DELTA1570, 0, 0); + + print_max_error ("tan", DELTAtan, 0); +} + +static void +tanh_test (void) +{ + errno = 0; + FUNC(tanh) (0.7L); + if (errno == ENOSYS) + /* Function not implemented. */ + return; + + init_max_error (); + + check_float ("tanh (0) == 0", FUNC(tanh) (0), 0, 0, 0, 0); + check_float ("tanh (-0) == -0", FUNC(tanh) (minus_zero), minus_zero, 0, 0, 0); + +#ifndef TEST_INLINE + check_float ("tanh (inf) == 1", FUNC(tanh) (plus_infty), 1, 0, 0, 0); + check_float ("tanh (-inf) == -1", FUNC(tanh) (minus_infty), -1, 0, 0, 0); +#endif + check_float ("tanh (NaN) == NaN", FUNC(tanh) (nan_value), nan_value, 0, 0, 0); + + check_float ("tanh (0.7) == 0.60436777711716349631", FUNC(tanh) (0.7L), 0.60436777711716349631L, DELTA1576, 0, 0); + check_float ("tanh (-0.7) == -0.60436777711716349631", FUNC(tanh) (-0.7L), -0.60436777711716349631L, DELTA1577, 0, 0); + + check_float ("tanh (1.0) == 0.7615941559557648881194582826047935904", FUNC(tanh) (1.0L), 0.7615941559557648881194582826047935904L, 0, 0, 0); + check_float ("tanh (-1.0) == -0.7615941559557648881194582826047935904", FUNC(tanh) (-1.0L), -0.7615941559557648881194582826047935904L, 0, 0, 0); + + /* 2^-57 */ + check_float ("tanh (6.938893903907228377647697925567626953125e-18) == 6.938893903907228377647697925567626953125e-18", FUNC(tanh) (6.938893903907228377647697925567626953125e-18L), 6.938893903907228377647697925567626953125e-18L, 0, 0, 0); + + print_max_error ("tanh", DELTAtanh, 0); +} + +static void +tgamma_test (void) +{ + errno = 0; + FUNC(tgamma) (1); + if (errno == ENOSYS) + /* Function not implemented. */ + return; + feclearexcept (FE_ALL_EXCEPT); + + init_max_error (); + + check_float ("tgamma (inf) == inf", FUNC(tgamma) (plus_infty), plus_infty, 0, 0, 0); + check_float ("tgamma (0) == inf plus divide-by-zero", FUNC(tgamma) (0), plus_infty, 0, 0, DIVIDE_BY_ZERO_EXCEPTION); + check_float ("tgamma (-0) == inf plus divide-by-zero", FUNC(tgamma) (minus_zero), minus_infty, 0, 0, DIVIDE_BY_ZERO_EXCEPTION); + /* tgamma (x) == NaN plus invalid exception for integer x <= 0. */ + check_float ("tgamma (-2) == NaN plus invalid exception", FUNC(tgamma) (-2), nan_value, 0, 0, INVALID_EXCEPTION); + check_float ("tgamma (-inf) == NaN plus invalid exception", FUNC(tgamma) (minus_infty), nan_value, 0, 0, INVALID_EXCEPTION); + check_float ("tgamma (NaN) == NaN", FUNC(tgamma) (nan_value), nan_value, 0, 0, 0); + + check_float ("tgamma (0.5) == sqrt (pi)", FUNC(tgamma) (0.5), M_SQRT_PIl, DELTA1587, 0, 0); + check_float ("tgamma (-0.5) == -2 sqrt (pi)", FUNC(tgamma) (-0.5), -M_2_SQRT_PIl, DELTA1588, 0, 0); + + check_float ("tgamma (1) == 1", FUNC(tgamma) (1), 1, 0, 0, 0); + check_float ("tgamma (4) == 6", FUNC(tgamma) (4), 6, DELTA1590, 0, 0); + + check_float ("tgamma (0.7) == 1.29805533264755778568", FUNC(tgamma) (0.7L), 1.29805533264755778568L, DELTA1591, 0, 0); + check_float ("tgamma (1.2) == 0.91816874239976061064", FUNC(tgamma) (1.2L), 0.91816874239976061064L, 0, 0, 0); + + print_max_error ("tgamma", DELTAtgamma, 0); +} + +static void +trunc_test (void) +{ + init_max_error (); + + check_float ("trunc (inf) == inf", FUNC(trunc) (plus_infty), plus_infty, 0, 0, 0); + check_float ("trunc (-inf) == -inf", FUNC(trunc) (minus_infty), minus_infty, 0, 0, 0); + check_float ("trunc (NaN) == NaN", FUNC(trunc) (nan_value), nan_value, 0, 0, 0); + + check_float ("trunc (0) == 0", FUNC(trunc) (0), 0, 0, 0, 0); + check_float ("trunc (-0) == -0", FUNC(trunc) (minus_zero), minus_zero, 0, 0, 0); + check_float ("trunc (0.625) == 0", FUNC(trunc) (0.625), 0, 0, 0, 0); + check_float ("trunc (-0.625) == -0", FUNC(trunc) (-0.625), minus_zero, 0, 0, 0); + check_float ("trunc (1) == 1", FUNC(trunc) (1), 1, 0, 0, 0); + check_float ("trunc (-1) == -1", FUNC(trunc) (-1), -1, 0, 0, 0); + check_float ("trunc (1.625) == 1", FUNC(trunc) (1.625), 1, 0, 0, 0); + check_float ("trunc (-1.625) == -1", FUNC(trunc) (-1.625), -1, 0, 0, 0); + + check_float ("trunc (1048580.625) == 1048580", FUNC(trunc) (1048580.625L), 1048580L, 0, 0, 0); + check_float ("trunc (-1048580.625) == -1048580", FUNC(trunc) (-1048580.625L), -1048580L, 0, 0, 0); + + check_float ("trunc (8388610.125) == 8388610.0", FUNC(trunc) (8388610.125L), 8388610.0L, 0, 0, 0); + check_float ("trunc (-8388610.125) == -8388610.0", FUNC(trunc) (-8388610.125L), -8388610.0L, 0, 0, 0); + + check_float ("trunc (4294967296.625) == 4294967296.0", FUNC(trunc) (4294967296.625L), 4294967296.0L, 0, 0, 0); + check_float ("trunc (-4294967296.625) == -4294967296.0", FUNC(trunc) (-4294967296.625L), -4294967296.0L, 0, 0, 0); + + + print_max_error ("trunc", 0, 0); +} + +static void +y0_test (void) +{ + FLOAT s, c; + errno = 0; + FUNC (sincos) (0, &s, &c); + if (errno == ENOSYS) + /* Required function not implemented. */ + return; + FUNC(y0) (1); + if (errno == ENOSYS) + /* Function not implemented. */ + return; + + /* y0 is the Bessel function of the second kind of order 0 */ + init_max_error (); + + check_float ("y0 (-1.0) == NaN", FUNC(y0) (-1.0), nan_value, 0, 0, INVALID_EXCEPTION); + check_float ("y0 (0.0) == -inf", FUNC(y0) (0.0), minus_infty, 0, 0, DIVIDE_BY_ZERO_EXCEPTION); + check_float ("y0 (NaN) == NaN", FUNC(y0) (nan_value), nan_value, 0, 0, 0); + check_float ("y0 (inf) == 0", FUNC(y0) (plus_infty), 0, 0, 0, 0); + + check_float ("y0 (0.1) == -1.5342386513503668441", FUNC(y0) (0.1L), -1.5342386513503668441L, DELTA1614, 0, 0); + check_float ("y0 (0.7) == -0.19066492933739506743", FUNC(y0) (0.7L), -0.19066492933739506743L, DELTA1615, 0, 0); + check_float ("y0 (1.0) == 0.088256964215676957983", FUNC(y0) (1.0), 0.088256964215676957983L, DELTA1616, 0, 0); + check_float ("y0 (1.5) == 0.38244892379775884396", FUNC(y0) (1.5), 0.38244892379775884396L, DELTA1617, 0, 0); + check_float ("y0 (2.0) == 0.51037567264974511960", FUNC(y0) (2.0), 0.51037567264974511960L, DELTA1618, 0, 0); + check_float ("y0 (8.0) == 0.22352148938756622053", FUNC(y0) (8.0), 0.22352148938756622053L, DELTA1619, 0, 0); + check_float ("y0 (10.0) == 0.055671167283599391424", FUNC(y0) (10.0), 0.055671167283599391424L, DELTA1620, 0, 0); + + print_max_error ("y0", DELTAy0, 0); +} + + +static void +y1_test (void) +{ + FLOAT s, c; + errno = 0; + FUNC (sincos) (0, &s, &c); + if (errno == ENOSYS) + /* Required function not implemented. */ + return; + FUNC(y1) (1); + if (errno == ENOSYS) + /* Function not implemented. */ + return; + + /* y1 is the Bessel function of the second kind of order 1 */ + init_max_error (); + + check_float ("y1 (-1.0) == NaN", FUNC(y1) (-1.0), nan_value, 0, 0, INVALID_EXCEPTION); + check_float ("y1 (0.0) == -inf", FUNC(y1) (0.0), minus_infty, 0, 0, DIVIDE_BY_ZERO_EXCEPTION); + check_float ("y1 (inf) == 0", FUNC(y1) (plus_infty), 0, 0, 0, 0); + check_float ("y1 (NaN) == NaN", FUNC(y1) (nan_value), nan_value, 0, 0, 0); + + check_float ("y1 (0.1) == -6.4589510947020269877", FUNC(y1) (0.1L), -6.4589510947020269877L, DELTA1625, 0, 0); + check_float ("y1 (0.7) == -1.1032498719076333697", FUNC(y1) (0.7L), -1.1032498719076333697L, DELTA1626, 0, 0); + check_float ("y1 (1.0) == -0.78121282130028871655", FUNC(y1) (1.0), -0.78121282130028871655L, DELTA1627, 0, 0); + check_float ("y1 (1.5) == -0.41230862697391129595", FUNC(y1) (1.5), -0.41230862697391129595L, DELTA1628, 0, 0); + check_float ("y1 (2.0) == -0.10703243154093754689", FUNC(y1) (2.0), -0.10703243154093754689L, DELTA1629, 0, 0); + check_float ("y1 (8.0) == -0.15806046173124749426", FUNC(y1) (8.0), -0.15806046173124749426L, DELTA1630, 0, 0); + check_float ("y1 (10.0) == 0.24901542420695388392", FUNC(y1) (10.0), 0.24901542420695388392L, DELTA1631, 0, 0); + + print_max_error ("y1", DELTAy1, 0); +} + +static void +yn_test (void) +{ + FLOAT s, c; + errno = 0; + FUNC (sincos) (0, &s, &c); + if (errno == ENOSYS) + /* Required function not implemented. */ + return; + FUNC(yn) (1, 1); + if (errno == ENOSYS) + /* Function not implemented. */ + return; + + /* yn is the Bessel function of the second kind of order n */ + init_max_error (); + + /* yn (0, x) == y0 (x) */ + check_float ("yn (0, -1.0) == NaN", FUNC(yn) (0, -1.0), nan_value, 0, 0, INVALID_EXCEPTION); + check_float ("yn (0, 0.0) == -inf", FUNC(yn) (0, 0.0), minus_infty, 0, 0, DIVIDE_BY_ZERO_EXCEPTION); + check_float ("yn (0, NaN) == NaN", FUNC(yn) (0, nan_value), nan_value, 0, 0, 0); + check_float ("yn (0, inf) == 0", FUNC(yn) (0, plus_infty), 0, 0, 0, 0); + + check_float ("yn (0, 0.1) == -1.5342386513503668441", FUNC(yn) (0, 0.1L), -1.5342386513503668441L, DELTA1636, 0, 0); + check_float ("yn (0, 0.7) == -0.19066492933739506743", FUNC(yn) (0, 0.7L), -0.19066492933739506743L, DELTA1637, 0, 0); + check_float ("yn (0, 1.0) == 0.088256964215676957983", FUNC(yn) (0, 1.0), 0.088256964215676957983L, DELTA1638, 0, 0); + check_float ("yn (0, 1.5) == 0.38244892379775884396", FUNC(yn) (0, 1.5), 0.38244892379775884396L, DELTA1639, 0, 0); + check_float ("yn (0, 2.0) == 0.51037567264974511960", FUNC(yn) (0, 2.0), 0.51037567264974511960L, DELTA1640, 0, 0); + check_float ("yn (0, 8.0) == 0.22352148938756622053", FUNC(yn) (0, 8.0), 0.22352148938756622053L, DELTA1641, 0, 0); + check_float ("yn (0, 10.0) == 0.055671167283599391424", FUNC(yn) (0, 10.0), 0.055671167283599391424L, DELTA1642, 0, 0); + + /* yn (1, x) == y1 (x) */ + check_float ("yn (1, -1.0) == NaN", FUNC(yn) (1, -1.0), nan_value, 0, 0, INVALID_EXCEPTION); + check_float ("yn (1, 0.0) == -inf", FUNC(yn) (1, 0.0), minus_infty, 0, 0, DIVIDE_BY_ZERO_EXCEPTION); + check_float ("yn (1, inf) == 0", FUNC(yn) (1, plus_infty), 0, 0, 0, 0); + check_float ("yn (1, NaN) == NaN", FUNC(yn) (1, nan_value), nan_value, 0, 0, 0); + + check_float ("yn (1, 0.1) == -6.4589510947020269877", FUNC(yn) (1, 0.1L), -6.4589510947020269877L, DELTA1647, 0, 0); + check_float ("yn (1, 0.7) == -1.1032498719076333697", FUNC(yn) (1, 0.7L), -1.1032498719076333697L, DELTA1648, 0, 0); + check_float ("yn (1, 1.0) == -0.78121282130028871655", FUNC(yn) (1, 1.0), -0.78121282130028871655L, DELTA1649, 0, 0); + check_float ("yn (1, 1.5) == -0.41230862697391129595", FUNC(yn) (1, 1.5), -0.41230862697391129595L, DELTA1650, 0, 0); + check_float ("yn (1, 2.0) == -0.10703243154093754689", FUNC(yn) (1, 2.0), -0.10703243154093754689L, DELTA1651, 0, 0); + check_float ("yn (1, 8.0) == -0.15806046173124749426", FUNC(yn) (1, 8.0), -0.15806046173124749426L, DELTA1652, 0, 0); + check_float ("yn (1, 10.0) == 0.24901542420695388392", FUNC(yn) (1, 10.0), 0.24901542420695388392L, DELTA1653, 0, 0); + + /* yn (3, x) */ + check_float ("yn (3, inf) == 0", FUNC(yn) (3, plus_infty), 0, 0, 0, 0); + check_float ("yn (3, NaN) == NaN", FUNC(yn) (3, nan_value), nan_value, 0, 0, 0); + + check_float ("yn (3, 0.1) == -5099.3323786129048894", FUNC(yn) (3, 0.1L), -5099.3323786129048894L, DELTA1656, 0, 0); + check_float ("yn (3, 0.7) == -15.819479052819633505", FUNC(yn) (3, 0.7L), -15.819479052819633505L, DELTA1657, 0, 0); + check_float ("yn (3, 1.0) == -5.8215176059647288478", FUNC(yn) (3, 1.0), -5.8215176059647288478L, 0, 0, 0); + check_float ("yn (3, 2.0) == -1.1277837768404277861", FUNC(yn) (3, 2.0), -1.1277837768404277861L, DELTA1659, 0, 0); + check_float ("yn (3, 10.0) == -0.25136265718383732978", FUNC(yn) (3, 10.0), -0.25136265718383732978L, DELTA1660, 0, 0); + + /* yn (10, x) */ + check_float ("yn (10, inf) == 0", FUNC(yn) (10, plus_infty), 0, 0, 0, 0); + check_float ("yn (10, NaN) == NaN", FUNC(yn) (10, nan_value), nan_value, 0, 0, 0); + + check_float ("yn (10, 0.1) == -0.11831335132045197885e19", FUNC(yn) (10, 0.1L), -0.11831335132045197885e19L, DELTA1663, 0, 0); + check_float ("yn (10, 0.7) == -0.42447194260703866924e10", FUNC(yn) (10, 0.7L), -0.42447194260703866924e10L, DELTA1664, 0, 0); + check_float ("yn (10, 1.0) == -0.12161801427868918929e9", FUNC(yn) (10, 1.0), -0.12161801427868918929e9L, DELTA1665, 0, 0); + check_float ("yn (10, 2.0) == -129184.54220803928264", FUNC(yn) (10, 2.0), -129184.54220803928264L, DELTA1666, 0, 0); + check_float ("yn (10, 10.0) == -0.35981415218340272205", FUNC(yn) (10, 10.0), -0.35981415218340272205L, DELTA1667, 0, 0); + + print_max_error ("yn", DELTAyn, 0); + +} + + + +static void +initialize (void) +{ + plus_zero = 0.0; + nan_value = plus_zero / plus_zero; /* Suppress GCC warning */ + + minus_zero = FUNC(copysign) (0.0, -1.0); + plus_infty = CHOOSE (HUGE_VALL, HUGE_VAL, HUGE_VALF, + HUGE_VALL, HUGE_VAL, HUGE_VALF); + minus_infty = CHOOSE (-HUGE_VALL, -HUGE_VAL, -HUGE_VALF, + -HUGE_VALL, -HUGE_VAL, -HUGE_VALF); + + (void) &plus_zero; + (void) &nan_value; + (void) &minus_zero; + (void) &plus_infty; + (void) &minus_infty; + + /* Clear all exceptions. From now on we must not get random exceptions. */ + feclearexcept (FE_ALL_EXCEPT); +} + +#if 0 /* XXX scp XXX */ +/* Definitions of arguments for argp functions. */ +static const struct argp_option options[] = +{ + { "verbose", 'v', "NUMBER", 0, "Level of verbosity (0..3)"}, + { "ulps-file", 'u', NULL, 0, "Output ulps to file ULPs"}, + { "no-max-error", 'f', NULL, 0, + "Don't output maximal errors of functions"}, + { "no-points", 'p', NULL, 0, + "Don't output results of functions invocations"}, + { "ignore-max-ulp", 'i', "yes/no", 0, + "Ignore given maximal errors"}, + { NULL, 0, NULL, 0, NULL } +}; + +/* Short description of program. */ +static const char doc[] = "Math test suite: " TEST_MSG ; + +/* Prototype for option handler. */ +static error_t parse_opt (int key, char *arg, struct argp_state *state); + +/* Data structure to communicate with argp functions. */ +static struct argp argp = +{ + options, parse_opt, NULL, doc, +}; + + +/* Handle program arguments. */ +static error_t +parse_opt (int key, char *arg, struct argp_state *state) +{ + switch (key) + { + case 'f': + output_max_error = 0; + break; + case 'i': + if (strcmp (arg, "yes") == 0) + ignore_max_ulp = 1; + else if (strcmp (arg, "no") == 0) + ignore_max_ulp = 0; + break; + case 'p': + output_points = 0; + break; + case 'u': + output_ulps = 1; + break; + case 'v': + if (optarg) + verbose = (unsigned int) strtoul (optarg, NULL, 0); + else + verbose = 3; + break; + default: + return ARGP_ERR_UNKNOWN; + } + return 0; +} +#endif + +#if 0 +/* function to check our ulp calculation. */ +void +check_ulp (void) +{ + int i; + + FLOAT u, diff, ulp; + /* This gives one ulp. */ + u = FUNC(nextafter) (10, 20); + check_equal (10.0, u, 1, &diff, &ulp); + printf ("One ulp: % .4" PRINTF_NEXPR "\n", ulp); + + /* This gives one more ulp. */ + u = FUNC(nextafter) (u, 20); + check_equal (10.0, u, 2, &diff, &ulp); + printf ("two ulp: % .4" PRINTF_NEXPR "\n", ulp); + + /* And now calculate 100 ulp. */ + for (i = 2; i < 100; i++) + u = FUNC(nextafter) (u, 20); + check_equal (10.0, u, 100, &diff, &ulp); + printf ("100 ulp: % .4" PRINTF_NEXPR "\n", ulp); +} +#endif + +int +main (int argc, char **argv) +{ +#if 0 /* XXX scp XXX */ + int remaining; +#endif + + verbose = 1; + output_ulps = 0; + output_max_error = 1; + output_points = 1; + /* XXX set to 0 for releases. */ + ignore_max_ulp = 0; + +#if 0 /* XXX scp XXX */ + /* Parse and process arguments. */ + argp_parse (&argp, argc, argv, 0, &remaining, NULL); + + if (remaining != argc) + { + fprintf (stderr, "wrong number of arguments"); + argp_help (&argp, stdout, ARGP_HELP_SEE, program_invocation_short_name); + exit (EXIT_FAILURE); + } +#endif + + if (output_ulps) + { + ulps_file = fopen ("ULPs", "a"); + if (ulps_file == NULL) + { + perror ("can't open file `ULPs' for writing: "); + exit (1); + } + } + + + initialize (); + printf (TEST_MSG); + +#if 0 + check_ulp (); +#endif + + /* Keep the tests a wee bit ordered (according to ISO C99). */ + /* Classification macros: */ + fpclassify_test (); + isfinite_test (); + isnormal_test (); + signbit_test (); + + /* Trigonometric functions: */ + acos_test (); + asin_test (); + atan_test (); + atan2_test (); + cos_test (); + sin_test (); + sincos_test (); + tan_test (); + + /* Hyperbolic functions: */ + acosh_test (); + asinh_test (); + atanh_test (); + cosh_test (); + sinh_test (); + tanh_test (); + + /* Exponential and logarithmic functions: */ + exp_test (); +#if 0 /* XXX scp XXX */ + exp10_test (); +#endif + exp2_test (); + expm1_test (); + frexp_test (); + ldexp_test (); + log_test (); + log10_test (); + log1p_test (); + log2_test (); + logb_test (); + modf_test (); + ilogb_test (); + scalbn_test (); + scalbln_test (); + + /* Power and absolute value functions: */ + cbrt_test (); + fabs_test (); + hypot_test (); + pow_test (); + sqrt_test (); + + /* Error and gamma functions: */ + erf_test (); + erfc_test (); + gamma_test (); + lgamma_test (); + tgamma_test (); + + /* Nearest integer functions: */ + ceil_test (); + floor_test (); + nearbyint_test (); + rint_test (); + lrint_test (); + llrint_test (); + round_test (); + lround_test (); + llround_test (); + trunc_test (); + + /* Remainder functions: */ + fmod_test (); + remainder_test (); + remquo_test (); + + /* Manipulation functions: */ + copysign_test (); + nextafter_test (); +#if 0 /* XXX scp XXX */ + nexttoward_test (); +#endif + + /* maximum, minimum and positive difference functions */ + fdim_test (); + fmax_test (); + fmin_test (); + + /* Multiply and add: */ + fma_test (); + +#if 0 /* XXX scp XXX */ + /* Complex functions: */ + cabs_test (); + cacos_test (); + cacosh_test (); + carg_test (); + casin_test (); + casinh_test (); + catan_test (); + catanh_test (); + ccos_test (); + ccosh_test (); + cexp_test (); + cimag_test (); + clog10_test (); + clog_test (); + conj_test (); + cpow_test (); + cproj_test (); + creal_test (); + csin_test (); + csinh_test (); + csqrt_test (); + ctan_test (); + ctanh_test (); +#endif + + /* Bessel functions: */ + j0_test (); + j1_test (); + jn_test (); + y0_test (); + y1_test (); + yn_test (); + + if (output_ulps) + fclose (ulps_file); + + printf ("\nTest suite completed:\n"); + printf (" %d test cases plus %d tests for exception flags executed.\n", + noTests, noExcTests); + if (noXFails) + printf (" %d expected failures occurred.\n", noXFails); + if (noXPasses) + printf (" %d unexpected passes occurred.\n", noXPasses); + if (noErrors) + { + printf (" %d errors occurred.\n", noErrors); + return 1; + } + printf (" All tests passed successfully.\n"); + + return 0; +} + +/* + * Local Variables: + * mode:c + * End: + */ diff --git a/src/openlibm/test/test-211.c b/src/openlibm/test/test-211.c new file mode 100644 index 0000000..8bec4e9 --- /dev/null +++ b/src/openlibm/test/test-211.c @@ -0,0 +1,12 @@ +#include +#include +#include + +int +main() +{ + float x = 0xd.65874p-4f; + float y = 4.0f; + float z = powf (x, y); + assert(z==0x1.f74424p-2); +} diff --git a/src/openlibm/test/test-double.c b/src/openlibm/test/test-double.c new file mode 100644 index 0000000..4d239a7 --- /dev/null +++ b/src/openlibm/test/test-double.c @@ -0,0 +1,34 @@ +/* Copyright (C) 1997, 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Jaeger , 1997. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#define FUNC(function) function +#define FLOAT double +#define TEST_MSG "testing double (without inline functions)\n" +#define MATHCONST(x) x +#define CHOOSE(Clongdouble,Cdouble,Cfloat,Cinlinelongdouble,Cinlinedouble,Cinlinefloat) Cdouble +#define PRINTF_EXPR "e" +#define PRINTF_XEXPR "a" +#define PRINTF_NEXPR "f" +#define TEST_DOUBLE 1 + +#ifndef __NO_MATH_INLINES +# define __NO_MATH_INLINES +#endif + +#include "libm-test.c" diff --git a/src/openlibm/test/test-float.c b/src/openlibm/test/test-float.c new file mode 100644 index 0000000..26a4213 --- /dev/null +++ b/src/openlibm/test/test-float.c @@ -0,0 +1,34 @@ +/* Copyright (C) 1997, 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Jaeger , 1997. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#define FUNC(function) function ## f +#define FLOAT float +#define TEST_MSG "testing float (without inline functions)\n" +#define MATHCONST(x) x +#define CHOOSE(Clongdouble,Cdouble,Cfloat,Cinlinelongdouble,Cinlinedouble,Cinlinefloat) Cfloat +#define PRINTF_EXPR "e" +#define PRINTF_XEXPR "a" +#define PRINTF_NEXPR "f" +#define TEST_FLOAT 1 + +#ifndef __NO_MATH_INLINES +# define __NO_MATH_INLINES +#endif + +#include "libm-test.c" diff --git a/src/openlibm/wasm32/Make.files b/src/openlibm/wasm32/Make.files new file mode 100644 index 0000000..e69de29 diff --git a/src/openlibm/wasm32/assert.h b/src/openlibm/wasm32/assert.h new file mode 100644 index 0000000..5c6205b --- /dev/null +++ b/src/openlibm/wasm32/assert.h @@ -0,0 +1 @@ +#define assert(x) ((void)0) diff --git a/src/openlibm/wasm32/float.h b/src/openlibm/wasm32/float.h new file mode 100644 index 0000000..c82ecbd --- /dev/null +++ b/src/openlibm/wasm32/float.h @@ -0,0 +1,33 @@ +#pragma once + +#define FLT_RADIX 2 + +#define FLT_TRUE_MIN 1.40129846432481707092e-45F +#define FLT_MIN 1.17549435082228750797e-38F +#define FLT_MAX 3.40282346638528859812e+38F +#define FLT_EPSILON 1.1920928955078125e-07F + +#define FLT_MANT_DIG 24 +#define FLT_MIN_EXP (-125) +#define FLT_MAX_EXP 128 +#define FLT_HAS_SUBNORM 1 + +#define FLT_DIG 6 +#define FLT_DECIMAL_DIG 9 +#define FLT_MIN_10_EXP (-37) +#define FLT_MAX_10_EXP 38 + +#define DBL_TRUE_MIN 4.94065645841246544177e-324 +#define DBL_MIN 2.22507385850720138309e-308 +#define DBL_MAX 1.79769313486231570815e+308 +#define DBL_EPSILON 2.22044604925031308085e-16 + +#define DBL_MANT_DIG 53 +#define DBL_MIN_EXP (-1021) +#define DBL_MAX_EXP 1024 +#define DBL_HAS_SUBNORM 1 + +#define DBL_DIG 15 +#define DBL_DECIMAL_DIG 17 +#define DBL_MIN_10_EXP (-307) +#define DBL_MAX_10_EXP 308 diff --git a/src/openlibm/wasm32/limits.h b/src/openlibm/wasm32/limits.h new file mode 100644 index 0000000..1f8d124 --- /dev/null +++ b/src/openlibm/wasm32/limits.h @@ -0,0 +1,9 @@ +#include + +#define INT_MIN INT32_MIN +#define INT_MAX INT32_MAX +#define LONG_MIN INT32_MIN +#define LONG_MAX INT32_MAX +#define LLONG_MIN INT64_MIN +#define LLONG_MAX INT64_MAX + diff --git a/src/openlibm/wasm32/stdint.h b/src/openlibm/wasm32/stdint.h new file mode 100644 index 0000000..3996e5b --- /dev/null +++ b/src/openlibm/wasm32/stdint.h @@ -0,0 +1,43 @@ +#pragma once + +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; +typedef unsigned long long uint64_t; + +typedef char int8_t; +typedef short int16_t; +typedef int int32_t; +typedef long long int64_t; + +typedef unsigned int uintptr_t; +typedef int intptr_t; + +_Static_assert(sizeof (uint8_t) == 1, "invalid size"); +_Static_assert(sizeof (uint16_t) == 2, "invalid size"); +_Static_assert(sizeof (uint32_t) == 4, "invalid size"); +_Static_assert(sizeof (uint64_t) == 8, "invalid size"); + +_Static_assert(sizeof (int8_t) == 1, "invalid size"); +_Static_assert(sizeof (int16_t) == 2, "invalid size"); +_Static_assert(sizeof (int32_t) == 4, "invalid size"); +_Static_assert(sizeof (int64_t) == 8, "invalid size"); + +_Static_assert(sizeof (uintptr_t) == sizeof (intptr_t), "invalid size"); +_Static_assert(sizeof (uintptr_t) == sizeof (void*), "invalid size"); +_Static_assert(sizeof (uintptr_t) == 4, "invalid size"); + +#define UINT8_MAX 0xFF +#define UINT16_MAX 0xFFFF +#define UINT32_MAX 0xFFFFFFFFUL +#define UINT64_MAX 0xFFFFFFFFFFFFFFFFULL + +#define INT8_MAX 0x7F +#define INT16_MAX 0x7FFF +#define INT32_MAX 0x7FFFFFFF +#define INT64_MAX 0x7FFFFFFFFFFFFFFF + +#define INT8_MIN (-0x80) +#define INT16_MIN (-0x8000) +#define INT32_MIN (-0x80000000L) +#define INT64_MIN (-0x8000000000000000LL)