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 zcmbu7!AiqG5QhK6s_m(bC&7zCKo7e303tm^dnxtQo0rt43fd-Qw_r~`h!?NEh2RVH zBzg$?2vQJolxb&7SQJD*2(vpo|IF-UZ;sl>uH!&(aEM}8uv2n2=k6wIsA5+40zaSC zy|(|J1@kX|$!}lZ2KT6pKeAIgYy^IuJwKAH0$>xsGJsa63m47<`6Ru=`&v=@TPS|* zO9kvo)L. + * 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 zcmbu7F-yZx5Xb+CRokhJli;Ed&_N%50Fe&SE~QT0TvD4TXq%9{f}Q*zF0OtH!7tEF zGl+hNB6P?g*WQ`%s37`-@b2#2|L)$AyOZ{*ZCMa39Ha0G_DaF#JlsSLRZQ!S=jPM8 z({^W>H~;c%cK`knKB6-E%+Beu;ko(S>odtJ0JZ_F0%&!*uwgw>Ov+pA*NWClq5O?+ z6|gT^;UMaVfJ(;$?f0Nkoh;5Pv2<{&q58h|p?YZwHH>tiTAl7es{M;=_AiGc6(>;~ zBzi2h|G^f&am}c)*kx&crXdEi!}=8oFgIct$UcQ#09D}6dfKm9llX1_BLM3FY#E4& x`8<>WL$j8l-lmp#;3Uyg56Tt&Cg0QlWbTfb@IC3um~VA{(7&+gtSnx#t1s5fKcWBt 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 zcmbu5ze)o^5Qo1zqh7jbApskOfQ>FbfJhomBe9CuUd%G zLJ)lk!BRGv<&Nb9(XZM0_nVoW`;)U%-}A6|9Fu!FwL-AD2sfz`FpnGcdE5wQUytt} z{U<8p&$rnWD!>k~3bfiCe7si^vv}ec+LmJSn}w<^Th$*Vy%*)G zJB{jvIz)A|3^h!2q+0FHL8im2Tk)@lV>L>XQIzV5?fnn7VX^I+(_?uv^8JOHHH2N! zuh@WaVGRfOetSRwf7b8Ie3#$OKLXYP-)V3u{-F~$yB0D3akYjADYAMq!_-=RUGmkE YzZ;$ + +//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 zcmbu7y-LGS6vzLGRa+d|I2BwJ0xo*#1Bi5pb}4o0=91d@fi?}vE!fEiadGu61Yf{W zDM24W3Wbbv+H*{}R1p0^xc7Yg&&MTqN9|+VvLIMEL~i9Y3eM)--9!atOskIPX49(E zc0W^Z{$+2o`}dFYN0dgh^pt`%&&|@;XOfiwYy(&Y(CTzy!+Ij0l(*R4$XhRk@;AR# z1>#`fUxoc322?U0Xuk)Q=y-8n%1sBi8mjMWAF7umP~lJqs@3W4C)z)|X8R%>sVE*s zL9EAx7XM+3cU?1zEZ!8@GyFBf-eLWU;lD9#LEcr^1yBb5tf%?Rn#6DW9{^YfV9P*E v#Aibs49!}EdYf9}fs;f}Jt$Z7b&gk->`uIJ-2Cs%U7a8F6V{*bDVX{%=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 zcmbu5y-LGS6vzLGRa+F=I0-Ha0T;dW0Yo}PyOcV0b4hKgqD@0`3wH8BTwHw%!545e zpy)f4fN!(I^g0hNpg+V4UoI-c7L`P0FThU)p+hw3H?R5;XuYPLK3iT2N~*gp?PDvF0u z5bJSa#y{BNTUU%8^EUuEo;C-K|)2LM(9*s>54 wv8_vhpm%QUs-S>LdMj80UUWjm;e9( literal 0 HcmV?d00001 diff --git a/src/openlibm/amd64/e_remainderl.S b/src/openlibm/amd64/e_remainderl.S new file mode 100644 index 0000000..5f21b93 --- /dev/null +++ b/src/openlibm/amd64/e_remainderl.S @@ -0,0 +1,35 @@ +/* + * Based on the i387 version written by: + * J.T. Conklin (jtc@netbsd.org) + * Public domain. + */ + +#include + +//__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 zcmbu6JxT*X6o9{3qi(=LEo8w)Az-6}2M|f4X(Uz=+l^U&aI*=!6EKynckl$>z%rnh z2to7`>1E7}I}8y-zh?HmdEdO5xA#XU$AJ)71c#JSN#rE!U+FqkLMCY~nxwUGJbirs zxO}2An7)l)paN_Gi$J5_b)wjA=L8{cG|Bu_yW!>)?k$U^0_ z_1b=^c3wO6S4;?~4h*+BO5UO&mz(CP6HHqBd?yfbFAgAFgg z>c!i}_vdrw)miLZEjvI6fA)8sf93Mq{s+J^5V$gMZsL6}ukY%j-{ZTQ2UBEy-9y(} eKQjB(Id9iIoBb8DTKxH~{oubE;na!--~R+_(lv?z 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 zcmbV~J5B>J5I~=oUsCa@kZ7Qy0gD45lqQ4%1ySSx8(4vaNW$7kNyT-jI71|E#0k)3 zXTY+81iZ$cv7bLp!^-OGPl$>ALvW{|~{)#1(u5~i3p2i{2f`9u*$s48ocK=gg z11M4%xX}0{%gb3)O BDOCUf 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 zcmbV~J5B>J5J2B9zog<*A<;lZ0~QBBC`||jN<@(ZY+wNik%YC8l8WolafL`6i3=cS zXJBM467U*(#(wsAc3--e=XsW)WSsFG8BDUXOm}G0;$!n_@eZs4`@kB|>krAv7BQz< zCUM&w*+ksG^JUfNE%8rPxCQ6ukD(ahe5mU2UT2}41>8*$3f#zh+;|d7*Xs|DeJHLU zB)%IzyJVI1qnD6GB%f3EEHP5NN@_{Uh^@EWf?~ z6xaZAD+3o2pCtKMt0lfCbt5y`q<*|3?p1$R*5m(__Ac@&>(R5M{oDS*e-mk7<%V8; E0-k~?z5oCK 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 zcmbV|O-chn5QV=U|0X+iCAd)#+-TzgM6%IwA#s%hOmt8%CULriWaV|-c?H2!h&OR1 zomAscjG(?v_j^^ZyXrliUYuplk>EJtn>El7yK}iqhn$b$UjF|1#xk%2tN=x?PlkJq zT7pyFc%~JxzS-6l9%>na53_qI2lycM;=D~asiuOzE~Uf|Lcov4Qu(6SKMYb{-6_8r zJ^D#Ko>aBWS||7$wqZW)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. + * + * $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 zcmbtWO=weD6h5!jX@fPX;-X-suX-6;&}UPW`iB*blYpg+r9~G)d~NP))iepoQ>p|k z#D$M4bU(A`(p8zAJ4vY^xJoxp!w42Pbs<=#Pz=GydGDO$dHosC55m3oyXWVgza)3h z5B<@kX~59nG&D{PENpM=&$!z&5QLrJd??#ub#6$!bT&ed2ewMxOWiM==YbE-sCZdU zh}F>I6|s3BA~pjXPDE^m7DvTqxVRkZy60Mn72b9@pDZUYg0Y8r5qyK}U*Te`@U&w& z)CJ{%&|QdEmd-a}iN>qMe1c;?CJF04E}fYo&X|a)v~uoD`L% z^_H!FyPr9Ea=G-TB~aQb71joq=fBc--?Q`gOhio4CV8bHm(mv^-q#tqSP z=T7K7(c!UPJ$%IIH^O>fCFw4(kM+6!9I zSBCbzxJH6{g7ohbKj@SFoAxJZ{Sh#}ZSY>np@-&r^bNEEz-}MUF?JB|%>a0D0>JOY zUnLV9=V9VGE{^pS@e3sH#tY!)3H_Fc=XfuXd^;72W1a+nU2Zi!U~OGkGIh(C088ei zEoUZV#+QUdu_30ZUFwTc&P-C8yHKM4i2vNtm|uE@a9aPc{@1*K)pdJZ{N& z!b-+b7ID$@?)F(T093u!tv&Ja*l*19dz%2<590`JnCE;CDLm(!SC;2|+loBr`+>r9 zzWJW*aK6FF-JZ71aWHar)?24|mz7D=u;q*mM#8jBFvfE^FtTayFp-{~mMI&IRN9tC zba?Dg&Ne4*(0MX-)5v7g8JV?jgJ(%j#jUJ4E$M~72Fx$E%x{Vr&gTUld;-p;AA8-o zfx0~7Pb?xpecrL((G<=N0_OyQbAdeef**5=UxrE_B%430A141;Pd^sO5%(WMJs&51 z{$67gNgwCi4}L$dXGvehI~Gu&(jx%SqRa+jg9O!gasCM Dt9Cc4 literal 0 HcmV?d00001 diff --git a/src/openlibm/amd64/s_llrint.S b/src/openlibm/amd64/s_llrint.S new file mode 100644 index 0000000..d7a0f74 --- /dev/null +++ b/src/openlibm/amd64/s_llrint.S @@ -0,0 +1,12 @@ +#include +//__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 zcmbV~OHKko5I|p#A7JHYW#R@_ZlvP@jA0|NFu39X15DJ21DS3USa}_n9)ZLgc>>c? zg`JKjgtzIg>U#aDnYY`!Ze|RM;fCKRB1(3C(j6Mq`RX6FSD&yCG=T%4HyDy(Rw1XF zk+>0U`4^%7bYsDx7EPzsQ|ZCF<%`cpSm&$t_^2~qEIf9S`y4xR4qMKAVS9sN+xdL_ zEb&A6YUkB#UQ~XmoA1uKym50+VcnzX{=%_NgqHYwnh?4=Nzi^O7eF0$_AjGv6tnI5 z*FX)(Vj1X5e3j(GU1P#~Qa7-WBK5-=p;rAfSr7kH+PlEJtZTiJ_V45$|3id(6@}FQ E2KUn{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 zcmbV~J5B>J5QaZ5ucYEpA<;lZLo5z}P#TgHC{#JX29}2in`mvMq~bcX+#nK1;sVHI zCX7}=LirlcjOVw<|L)t>btiKU#c|1RW-!I}Pq|H#24B71*8CGTfn#6`==KL>xOu9n z%t_ufN3J6EA1qa{txcm*^;E`t@L~26^C3ROYOy|Q6pLxZ-{mpK4@1D0<5>7^f6xjs zzkQbcp?vj|YCI{bIMdVD=1AVSoKskMWabz4G!RZizo7-8qd^VzQ#l11u(tlpd?U+$ z@4o;@#|9>i+Hjq5lxkjTNu( F>Ko>qDz*Rs 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 zcmbV|y-EW?6otQ8|0ac?R)UQ}z(xljAV?aGg+`lz?M4?B*GQJx-J&pg3fvX6VRlPwX}gG@p4>pS*tSuU7N&16TyM zfhC~R?UA6~oflAEN7vQj>Kk>Z^1Qq&Y!0RxJ=nC5scbp@-iAM$Jz30kYEw+VsxZaC zW~S5a?N>Ivy7&5~cr?RuFw9Cjs-594Y{6vOWf7Y03RZ=`CiITaF9`ok=z!ecE}-Gx z`90rXGH?GDumU9Ff(x$?gzsjJaqp2?$BRD{@~($F8}ggJ-l%!I<1MPk$o;MVk{|of Jc^t0U)ermQErS36 literal 0 HcmV?d00001 diff --git a/src/openlibm/amd64/s_logbl.S b/src/openlibm/amd64/s_logbl.S new file mode 100644 index 0000000..d22afeb --- /dev/null +++ b/src/openlibm/amd64/s_logbl.S @@ -0,0 +1,29 @@ +/* + * Written by: + * J.T. Conklin (jtc@netbsd.org) + * Public domain. + */ + +#include +//__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 zcmbV|O-chn5QV=U|0X+iCAd)#+-TzgM6%H!NOY3}%;*roF%xE5Fe^QhJGX+DP{dn! z0I8&#G{p$&+jPHI^}4Fx!|~ZkVhjO>Bj#+5G!na0xl4zXk8&q{|N4A;^{tD*7O({L z`U4Woi)aDH^XR!&NPWGntE`533AUNsx-7>wuAZIO;pU2ahrP;NhRvG>JE~k^d;P(F zA%dRoxKiVsJ^i9DpGo&~8H+)_4)!7N2d|iAobbf0;_@BM$JT|vv F^$j^fEUEwi 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 zcmbu7J5B>J5I~=oPm+pHg+v1t4Y4=?LTN}+pit!i8(0AXHqow;l8WolafL|Sh!db8 zGr_Wg6v1ok8PD@)c3&^Ax|wqrjthRGh$z|lPIqY0rio`1k5a0F}ty}^(SH + * 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 zcmbV~OHKko5I|p#sIc<0GI66TH`4I{#IO-q7+i6HK}RL%K&IOSR$j-YM3=KbcjlNp0zxaK#Ch?4D}bejfszIq4E#S&`38L$g<`vWq}BIHyv z5;vkPHxcTO*B0z)(MvTd{Uca6fA#qg>wL8upLOPona4ilKF1E7! + * 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 zcmbV|y-EW?6otQ8|0ac?R)UQ}z(xljAV?aGg+`lz?M4?B*Guoq0YwJx-J&qBvxxX6TC9p4e>~Xg>3%K6(AtU#;fl2e1fi z14}@s+ap1}doQAbt{hj3uW!_K<>g)BaxixE;L<+Ex^nuxjejnCa+vGXrI^08m}1~E z)9Lp1txK=&gT5&q&9EE{v(k-fSNIcKFxhrlq^55LtHNIsdMD%;gnuS + * 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 zcmbW0ze~eV5XZl-)~3;+sgvNM5OL9Kv$4sTNN z`B{@^OvOq}b|0BvqLCrlkopA*NIGQ1pnVcs0MfwR`t8U+it^w72LKcRiKrOBlk|6E uaWQKYah|wV@G6r?FM5bv(yz+z>Ws68$VE{;5#L|-552etf)f%-;`$%IbyX7p literal 0 HcmV?d00001 diff --git a/src/openlibm/amd64/s_remquof.S b/src/openlibm/amd64/s_remquof.S new file mode 100644 index 0000000..129a807 --- /dev/null +++ b/src/openlibm/amd64/s_remquof.S @@ -0,0 +1,76 @@ +/*- + * 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/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 zcmbV}ze~eF6vw|;Yt!h^)Jbqrh`4A_TtzxmyM#Iw1YJ^%3eq1YSFn>qr{bT`#lOR; zhf7A+3}W5ftI$FQx%AE+p@Q@SN8Wq)zVE$zc{s9}py`bD(|XVuXpgoz+PBS!jSV(7 z_JYm_AwgFQ&v`YYXhtt_mo$KN0E+-h^2 z6=3=88g;6$eCkcUH`1c+J%x4YPzP4k_hHo=)U`_G%8pN+i(BDe*IQQ8YcyStwq^CX zSrc!}Bq~gHugotnq#@W4`UM#f^rVqM?o+Y_APdZ`-&X#S%76PG0MG!WR55@j;qNBm td{!0yo}`xZDw3q0_u#owzbfwa8E=mfi{kex$^GU3(CZ@cL>152)eiz2Rh9q% 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 zcmbV}ze)o^5Ql#oWA4r-r&Yiv!ikM8imgZ*jYWu69^j&RRAjU4OphY@avzshS1j*Oz&Fp;4&fMKm;W$AE6ap*IS>DQXRf&6M)B-!+9_1#Ogsi1CSd4W!W6IDcI|fdSylcc8(l_^V zZ`3K&J{4O4Y+zx3Tl+^k|LuPOzygraWnk*>8hP^eB^#g0>O9=n~ literal 0 HcmV?d00001 diff --git a/src/openlibm/amd64/s_rintl.S b/src/openlibm/amd64/s_rintl.S new file mode 100644 index 0000000..479e836 --- /dev/null +++ b/src/openlibm/amd64/s_rintl.S @@ -0,0 +1,26 @@ +/* + * Written by: + * J.T. Conklin (jtc@netbsd.org) + * Public domain. + */ + +#include + +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 zcmbVIL23d)5Ug2~xZaYS0=Xy%Ud)gOhly71X-SRCU)(cl~{}o1Ri|P^ja~Qb>u7quf9NK6cZxzuo`i0YDMJBY>dOg9o*- znuB7VdL|RL{+iX5Ok$b>+AM!4>_Zz$PUqO&C|VHoFr*N=Zwz!iqeusx-iM)Z@XdS_ z|LS=%n@0&PGbgwW@4#`|Ct*8f1muPOEO?3iIiUxFJIMSh0DRzXf0h52xc2`V@92pK wTFgI%Zf8xy?jyYx3vP0Lo1^V@{x_}{GIqCEab4yw^Lx4AU$eiT<^TWy 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 zcmbV~&q~8U5XQgMf9=J#o&+xn3tn{b0Yq|$)`QejZ(cTSuwYF?c7+xM&%S|=Blr|W z0zQF<(nBtSY&&DZ(t`TC?9P|@c6Mg-bbfVF@jNgd&QL@Jeo6G_vX2_7nAV$t$e$m@ z>^%^(ED-tRE1P6DBA?b9fym$Jh;;z_05$-$+8tEjy;_Zr^(d|tC6{9JcYa*J0cBNJ z=+Ip?2xAO-(I^3=9^V@kLTZyP);{k{G%}DqWfWwnHDo+Ak!-a)$J(gw9mTitgG|z4 z5~XIm^n!n6k7lsx_!cuR`ePcrA#DG4CTlDZiZ>2CZ{`q~&+fneqtY9e`EC7E09ybm zWix<2#V3w#-?@zK$MsrXDCv?`Tf^qEf0uOozq!3zKIr>4t&BUr<_iBO8Lrt#xc+a= Cw>>@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 zcmbu7%}T>S6opUfU%P7SN^qkv;6?`@KqQN3T}WMZ=VsET7OZK=jL?GM+BfiV1fL>^ z;3Ej#WKlt`y<@@h&=mv&9Y08&zr44. + * 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 zcmbV~&q@O^5XQf(|F$>vBzRF+@S>p)Aku?c4^r_^@S1HG1><(vL})?qs&6Iu0$xiI ze2@wv!RFX8*iXf=b-a}&vd)fJ#gOiZaKfs?{!fQimddb+9&>rZD7{Ts&LI`itqjc z>mguv*}oJ7<}w5VIo~}1G4OByKHo3-?fr)U)&NA}fGf_MLZ`P@p?;*7c;ccnUg-|1 f4gM|G>EFoN5pTRN=Pl<)|F6#f!Tt+g1JeHm*4Z_1 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 zcmbuBK}=jl7{|Xyi(R4J*=?mEsfJCnwyzc*yGtpwsk>OvT@!+og0jhr%kK8QvITa@ z?!!Pmw4tKLQxm;K%_dQQu!(;- z=(9<3)h7PQpojXg$!K5DW0LjnZQ`TdK0VlMlh#ew!An2dBzfB=$$gGveZ}q5@0vvY z#U}cFlc*1DlElAdo9J{4PJ2{nKbBV{OEFTeRu$m zgY^U0Yu_{-AA7%N_`&KQo0mT*Kbb#n#GC$#;oJa~7(nI8S?y8moilTt>!(&I1{jra4+&nmW+l)m=P5{oV@y0JKgML0xDY7?eL;SNZlvs9`N zQmI_Y%;j^I0olUzTq$=k52b8+GLvWfJILxfdS3wk-g3mx2|3T%vG8k1?wGG;B%E~KqAXqi$8v|<52v~0=h1}$5dnlkbhX!(L=Xz_uOwvv_3 zPO$Hb`5A4xSeQ17)*LwQjPaCNOivlr`TwVIU$|wwYod6*;O~}8&TEI*edpu323gA7 zWbwqigH4_8z^!Z=yF+ZYDd{d$xvx&wbmrYLmeV+c4%BynC`e`jpQebq^B<02H07Dmi|blb>ck#@0VqwR9xg F{|l;`(X{{o 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 zcmbtYc~}(35-;!oJQxIhprB$zMT8ZQ%cJQP5f&wg2)e7tim)IGg0SKp2T^>O5WJ#5 zJU{Pvpb46Q436MIFc=OwR1i5lqX~|;5chq(JENO@CV#wF-?vp=zpkpOuCDH#-L;eb zef0J8Kp;Kvgpb-sl9+rPi`7FhP+$x*B&kmvIjWDhjp0KAbCij{jUh+b*GEyd7t@u$$%C;4YaAsNaGf!k|2Rjj zS7{b9kk6%>qxuBfSa6hynuqG>CZRSKk}OF^KVmM)CtRgcsW?jZSd*HpgrkIDp*0*O zt>UQAiYV$2vbYkClHK4alSuLaSv^Ndt%~_r93|~r%u&(?j*^yfl!^KQ93`vZs6L_U ze7p&lR&tcISiJ|<9A)CI=KeO;Q4;ElV!}#OS^(gUWJsyRs6vu17+6F}sKqQtg_df( zB&nAi=a5I0P=i5I^l=^9izkaEF)InXmC~#U%t?&OBK>T`V{jldIc#-b#w0m4duxRgTDair5i!^U znfgRoM&`LNQFeJJURsYwyX>lZDk5A_w<5W8RY=#N-@0TakAz!w8L)4!xWFX%$mN9{sr%5qMytvXSytvGx5n8 z=eVg-ba|+vcVOKZChYOv%>%ZH(b2l!ozBnjWU51Mujzj|0HsemlPT*6L?_$_roCP@ z2W`mn^#AJnAVyQa+34`Xquq=~N|?Sb?nCz21v6%I51z`s7|1BM=45rOb4H5_61-Y( z&S1F0j8_?hJ<?Y6t9fcJL*{NbuXZ@d zkjMRo_a`RJV|E-ElX>is0_}@8zH(t-3~E2MDnF|+2RTZW;4ZZuiIW+4@H`OSd8W+R~~;*G#zc;&~ts`G#lpn zXJ$JCu7op_XJ(z=b$StcdGNAJ-u7r_R^ew&`Nw^b_m^J%j_r&@+bYLjT~jV)^3vV% z&}~1a{m^$KJM808-R0I-UqwcvD!EZ@!qO=8uRPPY+s{l#F2jv2?IuZ>f4&_6fHqlV zcXurY=sbOt&BVag7+B`-#2{X7{O!8E7})pu8}}T*z&gK@Dvw~G`!8wqI*x(v!#eiJ z#XukU-A!=@18cdXZsHFZpgT6OJd1(8x2dZA90uB{c5=y27}zP};m6k&h{r!7w|V4y2je^JL`phwr({df@rSicGSrWgY~$hvb$2?qLF?5NK#VPN;S z-Wz@y1AQdHQFR#u+y4Podj$h)qMv^JDhAeCv2SfD2Jwqsvx9!dz_tu799o8fr2~F` zUWS2oP^J}M!$9X;eVzFW26oz_A))1bKG!jb8?K#fCo(L~BL7zmY~J=^;tC9OQj5)j z3Jl^?Z@=tTiGe+SJT$rz108cQtCYxJJ0^~-!a(0Ko1I>T0h$Y19uhq(r_r|>gE%I{ z|8O-1HZ9Gu>kSNItKu)iZ(yL8eIqZrfdNDtPY$TTAf9Z#EV%{)NG~vzH5k}@Zk>HC z2KaVRX<97?cGP!Y-zD<=tGcmu7{rb8LtE=Gu8b*s{=9)tK|+L)Yr47A(E zLC@+jz!0nLzBe&|Mann3Z(^V?JQ@1@CIlZ5@up!9QX4U_7rQRJ(TIUw zJ>cIqcQDYk;a*B2eX6oc?qGmid8TO-264i>q2Wy!U`3`hmq@9h=+7n$?4d(J!|q}b zAKTqD^)3e1D%3NP=(DE9XAwE9EwPB;l^gupi0-iGxluC)*#6Cu(ajjx7gZ&}%^2wV z^N&{$Jv#6Ho@NZBE@q72( zEf{F;r;k`N-{z)lBXZi9I)hdWU^>=p6p_1k+Xl2^5c{4rUqa-}>bu(r4pY{jBl?ns z`ZrrK(3R`wbP(zDFmqrV2KH^sUfjm_LmLMAapjCuqMx4o=3pBJD9>GSh3G%_seeG` z^?orkx<}5@a0k1480hS1o2mCOKwiz;MMN(@d-5wHUH!!;2_D;UrkqHdWBR`n-1mjE z@qG;9ckjJK_ep*L(9X+wnpae~%j-05SIsSTp(o%y)1Mg(^_!2YuM}iwXQ$))!66|b zA!jvqhO}6S_u=00oiu5jwXJVJ$Vh7^7m>5b$=cb`+11g>$ zC)7o~%D;fIq^8Du{OD>mF{4x4FbS; z9(UBiH4V}oJaq8MyglDQA7~1XOFkePn#SXSI(P^Gm}=Eoy@vo02Jl~NB^2>DILw#F z#z%`HAT~bQN4`K29;q2A!((DWyM$)B8MEB-v# zY2lQXy;KV)_CowPEu8eYfDa~t)o1jtbsndMYu8!mcQVbJXh@W_B2F1TA4EyYM2%b^ zj1m>G;UcACxe`Q?;mU9j%}+`KQDVGC(MVB5lF|c25%F-Y=n7bLj{g|RkG`cb;zV5Zb5y%L+ia9|h8_ABp)Xf0oZbMR4Rv*Z)5p!;Uxr 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 zcmbtZdvH|M89xg|g5sWCi5i~-dn*f-&F&^3T4fVhV8s+247#hgSwpfnAbFWA5UHg| zG@`AQ>DZUHqqWo8m(}T0$Ery-*fiK_D5x=lMly90Y6XsE3;ykf-^mrH1Ji6tU8%TfPDx#u!`EE7_=g_54jU}{NUfAmFo%49Mb zB|X=}vy$FQV?@dLfRZuf``^!=JXXKve;3KtGugvT))tG(#=|Ni z%{P?vnucu=#*{Gt#=ye1qxT)MP4-4-^n=9F=tB`>08G9HCU;xq($}eE?9WPiBUvR8 z>8a3Kqz|06UrDpas*u}yxke>pT~>u`>_x4rT$(48jCWho_cv88W4$nRD;ZBKX}+su z{GgJt0VPcenFlS#_N1*{80Yp6eM)-HwPO|U#3<)0S=Fnu5sY`S$aS&EeFnU$TS@OU z1HN>`w(Y3|yXN^Y%VnP>eIrVm3v3>5rQyLSdo1ZwN_tF~$M;&&_YZKr9R%(z@c#gK z%A=(Dv6As&mgTQ08Q-mBtY6zzGFD(j+k1QzfwYpb9wp5oOZr|{GPXy_SYKMsz8{t& zZXpMjS<;Wm+;W*Ei}7jmEtWj;7bUB@qU}9pcckU)2vm@+FMqoAE-fSKpv z`udbKUzhDCr&3)9(5o<38UaiCj^!etqzAp9&F_9o`ns|{h8%@FuOL4MAiLkOWbtk# z%>&?cNc<1BxJMUF69WB!&MlYm*DdMWhg{_{z7I;{T}(e%#=S-WDk5S8AfNX@6<|4^ z%o?6x6v|+qk}=4HUNCqFVnZMN#+FBP(n3^53dS>#S9>w?nZw^|r82iX(C_`!*<{nG>-p9Qnk3%R2umo%WbrGnnOyO&|;u-K@pKleD7QGwqa~NgyUDV zk7u;3eBj?FaQW%cf1b!>pvHu#U)>pT{jnx&w658D<8!x$-5t$ye*E0#aP8BJzcPQy z-te)<=d7zgG#tL^isM74UwC`TRq1nw_wFbRf8Tg~$*F5ji{V=?9>9n5uzkcI7 zdlg5+k@5TeFF*artB)Og^U0lSwuDm^TVH(k!bJGzPvysvR553gVTMDV_4;U!n@ z^*-fV6%O3cc|m=b6|P(h^m|*s7z)4hoA2yc)O278>g^vSys*rCwEMU(l`JcJ<<^=3 z_p$KlvD+W1{`$f2*zm@M9shbh{N4R4RvdTNU3Xvmnrm*l_I>^SRl@&dud_c~xFAwF zK4%6US(BZJch+^rKOXCz-S`uI)ZK3L3n5l6TXt=cZ{_N>^NNC{{*XUd6bghE27a}8uaCHKv6}xCYgA5eVU)R<(!qw(+T{3fe z{w|jg9wEe~^bR@>P@xbaK-glyqVB-dSuS_J5CQ^GLGP|TO9)Z!_Owrlx^KSoY`3S} zoxkFo7W?5#=iH!?#My4oa(8~@9FjW|fthLI7-ic;nwtHp9L*F0zBvo%wO>g1QF?{z z7edTIPAsnpbS2@<6HpM_2nXMB`XWy9gpY$l&|M}EW5{VaPV%z; z*R+c8#Tp>GiEum7a#TrpGzTHY3BTEaCkT%@@Fd}PI`EBzuXo^g6W->)w-BC7c$>aT z_)eN@YA1Y`28bRa{CgT8dX(^|G(hxi!hfa#q9+J{UIRowBK!pn5IsY$YQMqWCWM$b34dr3{Q61orIX+*Cc(wJM5?a3p`qGeBU-9c)~3cp zU3G(~uWqSJ;*-B(SpbG$DUL9NU?_oMAq@Cp5jQrR=CMDiL?jaRO?8PxMA+^TiA1uk8Rm(^hE{7spU!aIe?brI4Vpi~^uV60aouNu|7?cqJ_|VPi<-Zd z>47~?<9dGrez?nM{9eZIX1MOBz%Lp87~_Y%U+d9*6ZpLh{}tmukKwvM0{<+AzejZl zIGj1O{!}n14i=m1q{EO;jpJ`{`m}ty;kFk7!E%fYJ4ffA=VmS&G1VYemleA zT%`FehQkS4<86dPe!-bZ;~k9ua)$qa;oJ|089tlwpJq6m_q6`&sZYUcINNA^CBv^^ zcrC*}$M6=08w}shaJcPh{SPyoum2B(gC9y5|A9&PFQ$To^}`uV>wk~oa~WPhM>i+` zT86_JOY8YE!?~WbXiESyrHp?r;h>+#E68yEz2yw&{E12QKg{^&F}qJQd_Kc}$Mh^@ z_-l;+3k)A%IP@;aMQq}8(zctlj|6Q-2T9WnE{#3Fp zCH%G3scPY0*V-!lEln`-*R-Y<^9gMGHBAi-$;OoMH#Vh`{*|lOE@(|v*KDMDUE?Ny zb4ycmvL$tou$3p*C#;t02K$omnF#y=TLh(Rmh`>mF7mG?*tZTd*!O%++JE{l-04AH-}^Or=+X`~z)3Gh|6NP+P6|(Q>DO|aAcdgy@LB*WBYEe# z^ml85dnD*|$~Tj|J`ZVf%ENv2O!!KYh?vlO?D8e*iUj6+Qp} 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 zcmV;}04M*6P);S^YjvfAt zt^p(llLxC+R8*|Ax3~Kb!e`H%{Ew~yBnFcQsbv5P7N9G_gA2fJ0y5?kp?E%uN4|gi zdmX@ZIgU=3D~#E|_uU`DGt*!YlC@Am|DD>an&JK*_ z<>mi__UCKux;y>4Pqor7j|)IU*M9Gw z-IGbu2m_ZdUGO1GBT$h55cdP|c_4ld#Or}LA6*>)0_L))J+G2e00000NkvXXu0mjf DP-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 { /* 1+`P4ET*7S_G{D(d^SbxC^5QP~N#6S2=lkRHecx}__1pK-Z43hh z4BUX`sR_HixtIN|45y$Ql*)eG)dk71+;KtKNC|8%`TOR2%&}^__JLB_j&Jq!rvSd$ zACi4C!1DQ|w+^sWbO!}wwXKF-*%%StyfO(L=7XTI}(%&~0C zT@!f6s(o?lwLN!SsH0k3U5M4HPQ7;M>H=Teb=L%0scet#A!E+h_e_CB%lDsoDJX`3ZL&%dR?Ad&k*v*O0(*xnm-bnV1;kxMI*0^S!is) zcu_WW(2EQHPokuwM2^kyaqmpc+`8sAB6a@|Hlv?_HW07LB1zLdC*J|+VBb> z8mk3UodeM@%Z+EA?8=(1il(+=f;g|5Du{E20b;gTC}@i&h>Jy26El<3Lx!nlpX2kw z;*wY@7fV{%T!lskEkBzps|78P{2!oupev%gh0*x$LoinYdbYi|@5GrvcLd9sjt+{O;q1k~yLIp;!`6cqBt>Be0m<#JW)ce@1kC b7v^bv!ts|W1Kq#VE#mXIe*Ys80v-PcWi=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 zcmbVN-D?wB6#q@E_CuXS5fM~655bLKuSs=R5ZAP{nkc1$QrPNZ9qYt``6$V_8y7T& z79{v0;-BDyPd@02Z#GsR+QvLxu2aV;J@(?{(J!6&ay0wrfE`Nz$PF3ga=e1?htsDy0X)o4Bdj4|S|F}~8Ncn&3vR^K) z^LO{5YQ?9X2F}d-yQkeBgyV=vi%{qwFm|GQPSCBemZfA=6zwd@&^vi`K| zwSQ}GYh@ui>ZzVxERhanbd{`^*6Y~>6MFViW2N?H7AW66F#1E=?fZ8M?sf=K#0CZq zYN6Qh$ZjpNpY^hc)*J5qF&v46wa`i9f)>|JzR+`Ew--m{&;YCj5E~wW56TR2qIL?O zui-LVxK;i*2_+v;wr^4_v82OApLM~?_R3dzjH$Yj#>D{^;wr?i_-j)xnZ_W|y^75sx1o?-<5 z{u_BdxA;?ygg@1kK>6v{0LxuTnfiIKoSF6PgcxOwq|QtuZ-QOWO&#ofE(ey)(1eZW z%*aozv;AP>nN-S1n_%gTX|UMvNKekx$1m~u#q?!1naxZZS@R0K|A^WwV@NR#s_km)@<=l8}( zxc+8IYmy7e=M{5dqu+?X&f}@~S|R4b4)OSKs}q1}9=})O#rcID;qfva3I_=?O)b+)>__sGq=9uD{~j08r=g=Y%7N98dj0??UvOz%5=-(I?bDU90pD$;jG-I4AG% ng!GR@x0TQrc{};NA>%cV4@wL2`=fhM?mfaiPKx_UK#u + +#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 zcmbVNPly|36n~T5+B8`wX|1@l!pyYm=5 z1SX~d_BQFZ8b+=6Q>=P*yPeq#OvGU;9|~q#w=llni9Z&vM52~e+*o~cPiL)X?dTMD zYs!|;lbwfALr3?cKX02GA3hhYZ<`yHExTsX2lboU>YX9q&Q7pgo#s%%>KVsz=XR&L z2>>ySf@pky>fFntU){V>CBnhg|5ziLNW7s;CesVY6z!xMQ8gtJj=UPyw6HQcuU}MB zS(6r~P8|an1poyAu%yZK0(d~GBgc?P<{mms3(`mPAgu+ZqhtHMUrGR<0Kkj1b_12q z$iZu#kLB@cS(%l?b8>LrCwpi8=LBZfCwtHOrv)bMlf5(k8K3M;3~45PvN!3+_pD#H z_1}@hX*rmXy`1PSz*I)zv9;6kNPkxY`0c6PU_%Jnl5lAV&lB&g4{!tk4hjD4nozCX zx`>wmcI2_WcG3s^Lata|%Bwk0=MoyeBKUd*Y#NO0VmS}`+DbvQhdiZrhDJQ&{Q&U9 za&T7Qv8K#l7kE+sTY*0y=>I^x2LMI{z9Hy~ets2rF|JGv=g#wpz>9H1#Jl501Rj0y zzCIBAi21At`eOc91bs2?x}c9;!~XG3Auu0&`cTW43ubl^)UsJ}#wDJW^n6w|^)(aJ zi&--Z>SDPJYN?2Vnk$_H;rvUW-|q}}4>2L*9o)tKJIeoaHYB+1{|5wu Bp)~*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 zcmbtUZ)jUp6hCR!t=r;DoPxssJ;qZvSf5ExQj%urixpq~EP0bw zBMsD1MU;IMgnbjl3F2Tl{Ln`1mkfvcEstj-)i0e^u?qfy(#m=7oaF76eDVkH-gkfZ z{JZC#b7xOS&$M|w!0q03h=2Gq!%E zcAvekD{_6sv01xq-nL50V131`)T(CHDk(At611(L^n$l(rEbfNy@)(}vUDYY-WKuP z-`}mT^M+Yc;^u1oOG{S<{hx=Gc=>Bz`t7hXZtBXoHLl2}uEgIdDY8{k@{zfvsk<0p z+J86e{W&&7uFvh8hTnjIvg84CWlU_U1~_~ z3U+k|L!qF2^t?7HN0J6@boL$t*Z}}C0AMnPW24Xpo(ghYV;)-L9U&g1+4I_Y@Jt6h z`+d7Qu6h9a0N?=aJ%!3)Y2tZl?4&euNt$>;%C}vRrcOG4r=*T&rIF|!sUy5MY>yGC zgH*QxP3?g7t!*0s;B7>CFT9Oto7iKY$;;OQLE7>W&!9AeWD~BYB0NBRfC<9G_S|mg z(~X0~iw8Vn^E>U_yYU#wi--WgKG%8e90R~{fNilLx?AvgPh#wdGc9<~654cLS5q(o z=Rl1Pb>Z*?4&6BP;LwXh5E6-(i`isWhqRu{6?8}>@;P05Ro6kEL?h^DpY6@5JA5xT zsQw=z9$ys9I`h3QewT|s>*6uDEI;b9k9Wwt=90%+#ylW0G^5|$F8LW3kF~>gJ|G@@ z#P8y-yX4V6%P+Q&ueo@<50*bbjfe5bwKc z=u@Yk0Ujm){Qfb@q?c!c!1uwx{>1te^?xUQ5h5KT|J*kW*2lQrpkp=W{ucUNEc^~K zIDb4xNnex;Qn5YGiUf|IXY5D*cO!96u{I&fVhLg2i{cYRh;fPU>>K1?)W1r^Sktu) zQGdEc{m4|1Tqk%B_)f4s^LQT7H)55@_vyg+7NQMNAKxUgb`WK{XnqG7V*c)Lq5mYs KKhKH;QU5 +//#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 zcmbuF4|r2mmcVb)LR(srQ00$;OLg8NAjJMJVx=h*2&HrZWror!DYT{5(8jhqpi^xy zrL|Otj^p5bt}|2@7Pq4_DCms%hXinF0GWcWleeLuel*1%h(I;b6aI7$JbF0u=l>Jc3 z)iVaoV-{o6ll;EyZ&$O7jh~GGzOzfoGB(~Zf-&Bne}+cLz5bbS^&L^K0nhim3kf~n zLEq7^?f-cfxFjF(jfUC+2LhfRQXm*X$d~SRfSo%T+}&PIiJev{vmS zx!a#9Sz98dmItKhQug+d6cZb@pDoU3R-u+6Jv2nRhwX!zXNr_h1SyOYKG)wN5 z-Tq9;UneDSL)q=GlT6u#EB$uK)RHGnwYJnriT+TRY}~Ref-&Rf#Sx6DPO~h=rnCsP zbLUt#jOHE4I}RJ<>ee+!O8!X6)2(;)>y29vM>5u<@AAn#0WUPegv~JdGbPdPmN*IO zG|Am^uk3}IA0KIK7^_zs-<+o!f%Pn(SN1}4g*AASdjfq!+ACU zG!|S>Rr_ryUN&A)cu9?yiYtl&uOfH*>m*yqa|QaGb@_Tms&Om#4#lj6$vxp0@!KT_ zv@hTl4OqEKyiMqC1>9J8BYBK&YN1Ee27FX7sBW22N*)C=JCrPqh zn&Xd@S|TM^Fd`7bko00$g?{jzM_Bm25@9+Nu;2eKa7p%HzK!nnbB!BuFAZiCocoxL*Pfg9Ny>c6Zga6$Odrolz;Ud`g)k#7GC z$=J9WW+6lYyoFaj5{ekme01bsAOz#Na#g^qj$p+AWK}sB?zO;a(r=;EL3sTCbnMDi zJjb=fNpg4S=0Qbq_3P`~H@l4upA9IAE2wkz>o&X-I32Eo)WBmRbaDXZgxYe*Q*v*Q zUdC7idP>CQfggPLm9X#)#rgNX3k-#)y->&fP zTfA))mOs01@V9wE(X>H=UEh=?douR(* zL+l^NqL>#O8fB;GkM=vC>D)1W;sw$Ey|+bn#?CDNqp<(v^OlnBi;JA2u|1DI|H6NE zRUY3Z%70kCcIF>Sx9$}6cZ^DZeZd#G{fDr=>T%_c@yX7u;{AFb`H6qo(=}&A{XJ6* zW&1N`?i2OLUHR#=8PhNJiuawqf76P%mN`l#<9nUT|e!GQk1cymtcQ}G$E$7A_}?;>_I zW<7u8W-QOX_~y?_buV>{#qvjck5+FzF}YVf-}}qB4HJ`}f8!>6K6=y37gn|0a$2;1 zM&&beE8p01R`h@C*PdOu$NsBH)YtTD#{IV^sxiKh;O@y+qWtudS0moG#lHO=>L1(Q&SenG59jtQZk$yAshH0w&a3!* z?v{h^y>rX{EVgjoyx9p;7v`^+mXMTcPBtecBqt`PB_<^$CQMykT9RNbuEhs4Go~>X z$rwvujKLyhVg3rHXF4}9v3Js8IRY!Z8Lzs>mowc)lWt;MRCKG3vCE9HN%*We8rDDt z(=+;P!vt4Ej=`p1ZYa+&I2IVnvkkVKQHBZg45qn;==rgEqYM+W`Te3;RcE20e6GQ^ zAgr?>Ho~L>JFuQ>u&psTintqng~73eqcVe|z~Iy^HQ4kk!~W*SE;cys=b90>>p%mn zA2v90IV<4}(yuX;FEZHH8yxy2hVuCao8918rh5O7E2tIN_HgLeM~oD zDdKlg;j)loW=Gzt;nm37G<+lS-5UNRa<_)7tMq8rso`5tzgxrA z{)%SjHGCWDhbJt`OUO-PBBQ*5JVC=>MV_ePzejG-@V&^FYWP0Rqr$mCh&oPDJpWMn zkQbt^i`%2fCs1X^*a=>aW;RW|e?{)l@Gj&|4gVZ@tA>Y=w`us-$aib_x5(WZK8UD-DtNav>M z>OFUm&K;z42N~Q!26vFb9b|9^8C*X@wS`uzP3L;aTrZjHC3C%GUR^R*Oy+eY^E#5b zRf_t;+%|>Vrf}O7ZkxhwQ@Cvkw@u-;Dcm-d+op2cRBoHfZBw~zs`{GTHkI3^a@$mH zJBx(}klCx&*;!ffni@MRvsYDB+gZ)Sm3Fqasz&|J4^1-&V^|Mg=Ev}gQo^G|W&c9> zF2Z4rBJ@SR1V6CG7JLGad$pdCgo`{1`mkyd`qPO%tXTw4B^f;SRAhVYZfq3>xw$AV+*|7Apf z8FIM96TXG$FDJZ%a5`Q-!fCw)_&nW)a0d?NNk*)9(PdMz&1fN9sorF&zd@A9Igij-UHsR9=&msIS!t)7-J)vk% zA>nkqp1J|wjvTs!&R;jtr{nc0;c(P0>g7oj`^`-FEs#txKip6FY~(Oc?4ZN+cn0Cy2#3A5XippA_YmGr_-w-W z5`Hh?9}u2Ncn9J45q^?z*z=3_gpk9y)A*l+TXQWhKn~*tAt3xz6MdS8_Yh9Uy_5KX zqcY*=6yb2@A^6`2&nEml;d2QeAbcL-k$A8G?T0fC;om^`e8MLXzJTyM2wzC}48pC1 zrxU)2a0}sZwj$b-OZZ~KA0RxB@G8QW5U$QTHIKnN?Bd@SE-9`pX67|DHB6<|RVq=h z=Cw7osf-k05kK^37BjD{TED)uvX+@Et7=Ql3-edZtf?(t`v{iTRsO5lQC;OIt*(6x zD<~~rT~=MZzBJs&cl zaSj9DCg8Y?2#Z%JY6O>cVS#T6sQ$h7kR!n-#08aOSid;07J^|D7Rc?xy}uI{6O7?G zp1PKWJS1LAyg%ePs2|pxRJu_SzQt5T{o)F9Za8}r_WOBF$B6M0*Mb|^^Tj%8uMp9G zafS0vs9$>?9L@hPj{2>n0=gjLT1D=uWT3rPgq;xhgC(R;?fA_?`|H{z3{hUd`nC4u zXfO6zLbUeJ-C+Ftas0(NL;QnFVJ|qmkG5_QCv1usW8L_Dfbq&7#vX=QGsIkMunAy{ aeWmFzO_8s;hO;-}|8sj;brTk?{r>_Uc#0eV literal 0 HcmV?d00001 diff --git a/src/openlibm/ld80/e_log10l.c b/src/openlibm/ld80/e_log10l.c new file mode 100644 index 0000000..bb6cd7d --- /dev/null +++ b/src/openlibm/ld80/e_log10l.c @@ -0,0 +1,205 @@ +/* $OpenBSD: e_log10l.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. + */ + +/* 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 zcmbtWYitx%6h5#y08D#} z1pu`lMe6m~;5k!f8wwpAtx|y_IACTI9k5GfMeB;HJ1Pvpf0Iq^lLUZh4oa^Ln%Xas zAhEa_LZ7p#01yc~I$p%_XscAAhN1;hv{f>bq@#*dL3C+kCZdXkqpgxPsz?^5wJ@!< zE0IVfVuLt%Rg<+!7F_n)YL;G9k<9Bh#%^efM@vgiJr_Zb!l)t@s^Lg)teaSNsQ?*G zGt8pqr^toadG*4GPmK9!5hmc0XcR>%q{W5E9rDykiyu;ZA~$Jy?wQ&TYGoiNMJ=6{%8$ne*fLkpOZowb2r^Q!L#jncdFLJuxn+NDRo2n{mu4S1(D7=)r=HIZG+yrh-@iK9A3K;#<1L;$tLxI?%V(14 z_>YsOCGE`F*2CsMW*BXpE+!t+{9C@s6SrlT4(EH|)~X-wA6auWh5DZwGQ9C{ z%d|EYuX=0cUx`(Q-lNDsMXWQFh~7#OooM){0`pCV!BM@-kTkrS(MTFz)dZ1 zz)Ocj%9FzsV3;>kp0y9VPh@c@7_Zfjoam!4l~{Prj>dDuOd9F1oF03M z%{!UCpqS4jj?bbz=8wM|OrOp186021@mLe4f0yI&6Uq2bIG&GxlH>V0T<3VKLjhgS zBg$j`d>zb~H~`6?)Q#>-7UfaT*I^IG^L1eTkHb`=LH6%x3^+G|><{>~djos&xfQ1z zaJK|Nb~yu1kT?1LAp1OM$o2j}9&gwdfL!lsY;-pTKyLB`+;VAoRgOR4tlvuQEltg` z*XQxNeSsaI1$Q^pZuU7F-87f~0bC!JP=8{ubB4Xg4A`?grqkYMdWO^Z3kLvf-?Z~k zdlwK>$Q57~ou7Rd7_QS|d+Gi%u>D}jrZM&Y6}Z7qfi4`_==|6VJeWUwzZqCqcE^t^ z#?<@QQGt~?Qn325dl~iD>pH3bT;@o@@@Mxd>aRx^OHc>q$AB$_TQ#b;0f2nG0iMW9 zf9~(1^XvWZ(D~VSjzRC=GDiP=fG + * + * 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 zcmbtXTWl0%6h6D#8!gOM5anh%k_kf64!fm5fE8L=X#-_#iw&iK?b0q(*><Iy|F%Eyul7j7po?=q|wx>0fmk^Gv{=tV|ns>n3?mP z%YV-K&;M_G;*rWNR*MA~7T5?WDTRx(Qs2eeXEE48fQqiMx`a<^Ot_>Gq)T?!Cwx-X zv(ZD#lyoGNSYmWYIcg2xr~H~253W>V*GGrqNAEv0U)NW3eOmF!e%YRPQj2OJ?RjMY zL-C5fh?HN^HI~au^p;7kl3gYBeO1=3ztim9qX3X7K=140_U=;_0A(aOszlM};|u_Z z$13_BMtve86)Vw%OG-qfTrJ&%Pb${zG68_BlCeZYawL3`$hIQeI{H;rRg>eWyr!E) zBoPa)tLO9*J}GzCuD*2aSrKFV(~AN1GIo6IjBr&Qf#73%1=ppgQoXK8Hf*4 z$rJYOPQ5ft*%2Sc*w_CP-gm8R&tvzF}`*J4f&G@5j>8+-xjy?0&CS7x9 z{;fsNC%1ht*{{o|d;1=Bo%g?KrFexsKfU|bNbdk>0!8z0=a={dN|~dtdoxLuoXAhvf%1+))2q^3GY7_dJ$$W#7|l zUd|+YGlG*#FMW9Bl6r^o?|8pRXwNU7%D4AM^%pl!?>v)E{%=oOpZw>*qE3!if3W6v zwc7d}%a_(2ekrYc>l-YuTbvV?cT8Mne}GOEAbJ9z^8^5FI@z4OwQ3^my-8aCx50+M z`LS1j~g~oso@CjAzLSv19wiI<{ zV4i6(KI5#~rmC0@+f+3vO+#6Vyj=GchxyYSU_ z;p^|hgSWxwKTznCo1hA+p$2w&L`?&^tfetd}gEPo+MB*`j>}fhk@`1KPavTzEAkPGR$XlG4+h? z8IAad6#!hMe&gQbC*Mo@eFU(Kc)s@;=cw5M@@MdVF!0{Nm}dW69EcfU3a8yq$l)v) z!T#oYIV`_7QvPOtkqpfFay))llE1^aINpQgztY5W{`{^be>41?pb6~9z!Ac&nl{_` z`$PWbymH^I;0G!g l?-*eQe_X~qJBXWfAUv9sg1LWq=gj0^O!;@GTs4^e{{@RMahL!A 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 zcmbtXZEO>D7=Lc>47gSVL@}(&g+PF_oeUB(VPl0g+ZbgsQ^;T|TgQyuTH6i>j4<5H zTyUsgOhiJA@hy??!DvJxtYh$@1QCfbEoBEpqFW@mIbs-*oq6t_XS*HSCx1!rf6woE z|G!;&Xk*!?6hQ!n0PA2vn!tk@6YmAuYXMk51XufAPtq^dB=e;Kqzktf?nwG2_gm5C zC5d!o60zi9e`0@1WPajaayTR>VmAl->Lk}J{q=CGyHF90M4l)*$4UCw0yKs@H^ehKx- zR>_)(CiA6at7OxvP5LG4xE)z3v1F@Mkn~G-wzacuL654csxpkq8@icOs?w7yF{L-z zD%oA_7i?-o%EBM}*_7MpqVy)6Qkf?{8;jY2eJj0vmYg;eX|8(Xx2cyAOXu5I{O!c0 zcueV4MzuOq0l3aYG#*P}5jL*Vs^v4=CH<1^23hhHA~)WKQ>wzE^}O+z(wB%S=k+3$ z-oc$?s%puB{_BZYBHBJ6#4mL@rF`XlA~x8ds%rayfC+nW&vZGZGS0Al7p}r!^O&k) zd(+}hYb@vD*^hosjp`;N+1A;C*H83j=$i}@5E^lk{fXZ+d>T_KgFF|5>kV z9?ctl=3S-q^jMEBe{iIGOa5nplPMH0x9hiWP7NqW()ho>ig;GUxqR-7O0O%-tghIFV;NlxF(Q&f5{bJ)$!85Qc2#}am?G-e0hZ9eRcS1 z{+W~EJ1qBZ{L9kN(Kc#3#4 z^tnve*2jqFGy$*0$ylO^8CrfLmTN-#W4xVs?9Yfi0GMN#H*GBeU@gF7F%U)5@Fmmm z+os`nPQ!z*+8@~CmutZdTcHA82Dz*#7aw+fIPj5&kJb2CgO62!9#CEVYPiYU7(GGAffaZfQH zARgmCVc_u_fx!4P4g8k|9?#wllF!hHad1y@{3|B=R+4`=*gt8oPp1Qpd9innvxs<% zk7u3vJcB)c|Clc^@OUPe-)7*AeeE^y*jGN)ca(T@UnflV9RF*By|J&$276;)*A2X} z{<$~-+8r{vU%V3$s3sE~a(G{3#Jd~ha3rLU4g41J`Mq+)*AfA_&KvQ9ygM8QITS!a zt_??483o5`kZS{tjlQM`$W4KWPcAO6Tp5mdYhNRIPgAoT3(Y^&xMg zk81fJ!2WPb%r^<&SA6ancqWWkNOQ*a3|FT9W~E8PHNZT4?=2uhyswbw?+T-h{M@u& z3| + * + * 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 zcmbVS4SZBZlJA#H5(M_WK>_7fCAyCjSsasq3LYX8LKxUAiUi3AAqGeg3}h}DAz(bl zBohc2FZi{%uCDm8hl;wmDjy0YuqcUoe%vYZ7-k5FYlc7|224mu-u|jz*QD~8+4Zh| zzs$V)cXd^Db#-;Wo~)ggmKr5V3`t^>Ss&L&QxeECf1JXsOkwu9TI+7$?dfypI4Vv% zeA`qvW9(Sa?^T|!Q>N{&tb2Hs*X3N#oaGc1oB1eQk(V$kXoEii=g zm@D}3j5&o7&Kd;c_j_B07bqiB;JIZm@P2QL1wJ+IW$=bxUFYrCmB-Q0*$~?oLSLJ* z?r1F7&>BE}PF!CASN$c-tUb5MH$jV~+WS?fV>58Ru~AxM^?Y>#%;Vl@#+diGqlV8> z;6&h}R_ARnW=yN|O;UYjs@0e@9==c??9l+T4ik#f@i@f^`*dB`18vZFl#7LeR;I=q z>M|E#y7&rJ>&6t-0S5MU>$=|I4IDRwsv*1T(JKQB?AL^s2Jb6W6OJ}&je&ZR)!f?< zXXK}m?;<}_steWleGqnN<=NVAJ!4;y%%`o`G1s2K9Ymgc40=Mt!v*^iV=Qn&xYFp` zW&jO=`jDjX1@Zx(Ljgd*o}C>=z4tgBsIU=6HK+?|%K2HIW85$IGb6H>nG3==8K_6o zx%N=OF_tH+HNU2;J7{47fl_9PVN5GiZOV=m)#mQS-=1N3~bzQ)YBKI=*z&H{b23 z*JGql0u9xj)n%%qzA47B*>SVi2sJJxRBv=PJ8LxUMvh6c|W#WOJmS9WmiMP2Wo zbUfMG6)Ru8Xs2BnlCD~{6cws&nHq1O9cZx6M&19U&f2r=*;r}CUKFcTZjUzVtk%lw zVa3-mjI|6TCA17*6)QfJI!-asoVxd6gKzPV{I!3ReY*zO};YK3GFG>-`n>< zDV^pyxjMGPZ?E`Vhr&FmpYt2j)wBh5SBINgxnM+oQlu2i&UdxsyK4_pMF ztD7sDB&G6<#TZdFALLg(o-;~ioxr?@coI0L{B%%qod`6vG}ZEe^R03@ET2}~llTGP zY^Scb{DRMH9DMq{wOVU1rbE~LUcaU_8>bGw^R3&_sq45doffgl@+~z?mS!#pO?cmN z3vz3Jhpyv%!2W%%)8M^L-gCjne+p-Kk&cE}Zo-qx?VVxM#-1H^?~PR|-@T;k{pK|z zE7;bd>$QIGv9^+;8b{xL`BiAY3>vekH7HZ-`Gl44g&;I*t--_KH!tP8VL9%)4mRfz zusIJgZO*|3oiHj<4-N(Y>w>P=B=?y+gu%6UDy?*2|vDrfaT zAFU}k`+O)ND!#zF$qObXqJ55i4wl92oPDtHu?gWYXScqpnBRpnt~D72J9yteDqi*s zd!|vnzJP&2&HOplOKa8YFxtw7q;3dSLbtB-YIZb=vDE`Gnb7@UdOMx}OemHO$AZd+ zSRQH%3AJ(Xud0GK6FP2eLzstPOs}qc>ReG;lfB}gq@BM@iA5x{Sn)AgLt5n_<8c}L^i~Y7j z!%qmwnpoE)W7C2l85SVuTB}kHl}m`i%gBWGP$;Snbm@BVH(k0uJG9}qD^_?<2<1k* zG9-;25AF{%+>h!0PYwsU_KeF%SoWilYJEN`<&W`2NPPSd0Fi2qFw>cr`bwbDGtdx( zU|}kI4+U+U)tZB&_(Qb?c2C$cgNHhG9me#J$bI&j@XgQvNuG0E>zJO_yN&kLPyXYH z2QtgI{3!Sj79DwOSvY^!8kO0fOChZkP^T0vEm;FFFNe|h+|f+}n`lV#_Q zt>-^pcI3R!AAB_Gi@J>CT|I)&nsVbE4NF*)F8Jp@pZZYax^aI&-c0L8CipH~b7#jM zAwO(e>g1%GXYTuGpCOsDx?uOFm#+MDmuN55-<$F`+wcGOk>H;>wDjJJ@8-0ADC7fW zE1w!Q_03LfAH1b$)KhgmZ|@Q9lOKKNRKZo<@1nixobfH2W=l^YuemFBTDx1m|4``9 zu{=KdbiIEs_CIsRGe03Us|MxEU)c8jz$cdX>=yDp%QISrzEe`MOW2!maod_NHXUik z@%&73W4!K+9#ialx1tN@bL?kT>aa&gT|oZR3rCJVzw6{#M@#r5r{+>*ScWP1kMx8u^p%%8|n! zSN|LNS8lp>Mb(~N4aobC#LgWuX30V1?|<4^(3m#19{GK@56<}GD+Bf*AAGTU;q-U9 zcOqZ8IB;=XyXAf4Ye#MS`mqbY3gz?1Gq)t4nw;?#ws*>9r{2rj@;dUTCd}Uc`nSEW zAwS~58H1yzI$uWq?IBw>J&<(aMdT;Wo%PMGi8aq7U-bIUn%U>>*o=JM6&<}>&z^r8 z`P&Z+d9&ny4s1fcZqDb^Hcou?3FLqHcH^n<>Yv$&{7s%CPrBvJ>yaP!h~u**2j1`? ze|XEUw{5Qayc~H!Zsg%w0;qSb(PExYb9~M7WgfrTAM^NxIlWhuxN)ZW$V)tX>ABVA zyP2pL+eEz?EO_)^Sz^wtwtUr;~B zhcWkB#@yg7tib7vu^G(G8W>}DvFTH%-Wfl7`mDJ($0v@rCD{_=lM<3{OGr#ih#!4l z{^EE?o=Y^`a>vbvW(#91o-qb@B-3ZjWl>Cmx0%o#uO#?E!jYlkTUv7;lS-}9F9*jB zsFfHijAHCs(e{bL7)zF|HBmFd=$Zl!6T$(I9(@f3N22Gbsr^{|Bl{Y^SV(hXr>Y)&qEISJfX0}`_70Aw1xin37 zOEYCI_?FRTm{?}myN@f3s*>H3ORklo(&Y7$U3N?9z^sy;!Y=5WA+MK`WjBA0vI{0n zu9fZ)eb&mg(oFFT9ae~EkeMZ(7Z~K zq!~@6Mw2nTXjKXY0>ZL1G+Mjt%rzuaxy9%a5@qKb%q$~F8KI_R*_kJo&XnDJfXN~P z5S)43{3^r1Zw+5wGWtz7w4{Z&WZ4;&MI93}lq#>6?%{#KSuzwY3AqhD(?OkES}L!X zruGZYOm0z^tNqu)vWJhovB~ z7#0tXF~+P>#y7mC0*+)A?N@O;nl*_AEHm(yD=`bZSKz4sY9SBTnLzk647>}2Jn|_2 zOM%0h2SWUMfg_LKHwgVGkCFeCz>!cMD4L85iJ#gT-1qgTB+kaM0sUb%f%CB;dq|V{ zLmaXpn#!MILvcfzA#my+&@6%DxRB-u9OH(RA#igFE#P?EW%?Hj9P1_0GJ%_q%SK$| zcpgz&$(dLN*Ity$I1|fiDaaTr7dYkv68snj@fX`th@KGmmm$QUrv-k_g#TXPn3qU@ z6gcK5(yIc000BX-3;fRr2zrNq$6dDa-sgC1Xq_N^$QZklObXw77~|tK&p8lml;QAi zBH%|O;3p#B!3cPJ1RQ=J4Cha@6dq^!xz3_hg|@1nx%hs^jY#y7J$L1|$ z_c7P1qUDJR2?+_zmNqq!e~jm!$%=(bU4@LXOpyq1W*N&EgL_7xbrJ9n2o5y~ z<&O&-%JY>3zg5&_&~GF7odO4WXqzPZFDCN068Sca`mJ%HFApRuLL+$>-B%dPe zzHGu#&sGzTe!fNYQ$P8I5M!Znp`LGu9;j)EUn%x8_<}tO@tX-w<>8zNWR7Pkk*D!| zg~&rqM*Xi7`QZewBRK4hD1U_DPd`k5D&& z(g_aZN)z}(fdiIE^gI|rzLenb_y?ha0q31bzM(%>P#Ojw9s$2T0zSrsWBw-z9KPsyvm(gnMv#Aq;B=inLU5}8 zag%e;b`}w35WAA zkZ!`!{}^%fMg16uAtoI4j}SPhqkfJeI33q*1gG+;CjB_BG!u??(@i*zYk>(z`2vBP z{d5wX`uP~ash_nb{b=`D6OR7B6hY6MCV7nic7nq@0mlCT!9h3TX9x~s!|`^QaP;#E zany(Tg&*fo&oF|69+V$Na3~cxu3H2Svb0X#MdYcT#U>ork;{Z*9M+g{lrN8fuaAJ& zM!=tqfWIhk@SV>4pCZV=7Xkl_=%M@g{}Oq6-hh9m0y3|=E~1C#r$xMKp*)^92AXi3 zU#khnI1dvzjFA1}I^KtgJY8Rh2~OX$ju9NjhWUIW|2fq-gV4B56gb2OuCj4{(+N)X ztRZ^nJXS@JKN&&3HG=##a^E_lakxR?IFIP(O$4X)If>|@eoi9tFfOda$tE22J4`sn z^S4Al^>Yr9A4B4qOK`A@`Zo|g)X!&4@@V&cg46fG7NUpx(@x}Re7Xrv{ka-0TEo=I z8w8H=$GF{O!f{-;m~iwziRh<(+D-DPCzIfGyfp-;b?K=H_{#*R^$_nZVO;PRB3sGo z<*vMi%vRzmHohOkr{es=Jew=O)WvLz^IUn%wy>mx*@}w{#`v}^DsjP8Paij)*%lQo zU!K3h#cV5zT=}-?v*zAX;>ug}kl>fBc-ZDFE^_7 +#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 zcmbtVUuauZ82@g%x!Try<2L``2D!2z8MN2jFcqa)Gn&~{LN~ewEE8(l-D}09Ey=CR z1kJK;t|F+QFFtL8zR94E17T@e!O#cAryFCgpf9QML75CSvMb-scaoE9E22M0&ON_; z-|su;cfNCzKN)}4BM87Cz;WozI#|7@^Bi#=BOrkYXJRWqd1G%!{eibO^uiBzUN1E5 zyma|90MM@#b2F8_7_AqYp2!#|;G_C%yBcK{#^0AEN~8vsxp_S=R(fS)>M zp>}oHPtTijb~bZh=izcH>$zGy4eEH*qf)2X*1`7S%V{>Sy{h34In>Y!hGH(}d$WgSz^ z(%DMM+^W>AP3yMxy;a_D^z}lsKO(*JNz0po$g&>3^H63@dh`7@^FsJm%~*T&K)6^l z)|Mw7@4`P8Z>Z;=a~oye=e7&C9$VRz&9YVAe%iKe$#)TBYG&iGw$RCQSLAJEwXE{?mv?O&%ZvcPEqwU+x2*>sEgku^na3FbjE#;yBL~JN z5=UkAm=aP{ITQ>%5meQn9GKM3$+4tCKMXx}6krbk$N+#{G&Yd{4+ur%SdR)c?;-hv zGzzaxf{^nHhX(fbz9#^r0N^nFcEAGwCq(axCo0OGQ(_=02FJxnT$IQAMDGc)cf5aD z48|R1nlVu>Y^qQ6j*7ig{hpH!drFL)=9Ny1xa1vy>)r#uI3~H#)817F{m!Fvhq~Y; z9=+i4fHUDPE8!6U*w5)Z9+0;!t!_L9up^K6YNvS6X0k6Y%%_w&P~xLO{8I5N1P%>) zayFX+Ew_|bodM4SafC)Z5s+Lykum8Gn=0;q^b~ zcwYZ^j_2d|QX^tbKK>HN^YN?1yZ8G67k@9e&ab(6e*M34@w~nx?DQCP>9B^xy7*~B z$zDhs$yrdcMy55+v!{%fN-BnyGe9|)G?JjqX0xDV7IC7?WsPI}M12yJxy5u^TQERb zSTrH~wqgrYRG+Pv zfwt8ikMENIBIUdNVskdeDL=>x5SA$aaYhi>{@IwId^fKBOaHKi@E*9suM^>3m)nom zslGe^DdStA&aKDcWmo~MTR*_i?0A3gRstIzWBo#E~s aM2rqPMEMNNcZU0S$!8bpDhnjI^Zx>_Q`27n 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 zcmbtYYfuzd7CtkAL2$c?*~DkoNo+0L=w!ebVF`i|#YefL==zHCP)1ybM=^szGDb>V zDU+ydTvL{s6tQAbaZ?q|ql_kTLEP0LnvE47)3!61#ndv3Q3iY@5$vtgeeTSqm0$U) z=feFJ@K^95Uy}Yfjn%zXaHrUS*t=U2`%a;B9hzAw2DpKXP?3$D5fzYz1NPl}Q&DZDmVec}UziwG)#F6P*hSR@%PNyzb?6Hlo#M76W2u(Hs(36P zar043n@{$(_mjPKvPVi2k7P+{)n^7ewq{AGpQ|{_2H7d4DkCJ>DW$zOLaJ#siCI3m z(f2){f^~!ZKCDAuQ1*uNiglbSX>PO!@UvIpUeSs?%z7ltk`>zYQ>C_yZdFAOb2ApR zbGIqI>eg|UE=SXy2K?~w!6efqa-;>3LfcERsUt#8%|``y0x;meE`KzZuWJ` z&AukNu_g3Ur(eN|>!K|oR{<%t$zQj}=yhq7m%Vax@NQ2eAF|?+>{^`$>+Y$l-xnFY zrBmEg-=nI%>I>IH$S;ep)&PKex>&mjR|$qe%T=$nezkYzFc<+ZhG+58Kqz>&TUG1) zvR`gD`(?Qy@V&1ic(fZm!~Mg@DkXTJTU8z5_1M03gcJxVQBuGge61UuYmdgdez*s0 z69~Sns;ai24LG+vV7_~F+uv?a)jRg?F7k)|x$pX2YQHnCV@PT8fwz95_S8y$#<|){ zAO7+WU4B_r@uldYTMu?qd)3B?gEriX4fl^(acXSQJn^3Ki zz7g%mzPtFt=vVgLrv5$mKmBIzsXbx;M!#{hC3xt-TR&0%q4>equWS4vL;m{S^ZQwROU54d^eo@; zE%SG9)YkQ1UP^BLndEmR?VenH;p|r||2Hd+qb~MP zEA#28m!J9gPzT8$y!~w3vI*83UDS3SUo>U#so`5#J!WovbDraHQ4{lL=C04Sr@Vfv zmCe6m+ef3Woj!k*jsNelpA0?yMAgLy>MiVFbrt|j1*lE~XxIo)jejbDJp&*euOeRo z0G{32wWPDj^i78O58?b>v%L9!=DkS%4mVHhNh*K4gT=S=`S&iY!~D^B+c9}u{{F6~ zFPy(m#w8zCcRTCp5(GO=+)j9LM~N~(zZAjn{7>WO{aCvyT!%9A0BOTzrZRhI00H+77kG8P~T04xB2o9>Lc3&9Mg2ISbC%tY-t8sN9| zHdW0BQ)Rqq_`pYE>P!IR0AK|5jYs7y!R8Rs&C`WEr(ny86=G(_%@NWI1iLw1umQXd z0CPxw1P+)X#MhX!guEPKafVFN056YbPF{-<0N^#(1pOeL0$xX&Lx`_7>x6b$0Dxh{Up2^M?9mPb zvon(Tdg@^OQ(9X)YI|Xf*6QDjLp(!#yrIWNJk}78Nm`>n^+%9GJe6-4`f}(G_AsLZ z7b8|DmI#lTS|b|pD$QfA*60t$tS->_=m-2?N<6D;23MUI6bOJdDxw&gxCHW;zaO4-boZxVlmX$j?^ zPg9AS zJpQD@RMmy&MyF~%U!O&i`Z9rp)=p= zF06EebydDQAFKr~7g)(lp*c*nMG+;mTq>joO%sNX>PJ~j}+sE_xuht*F4{T|K6$NItZoawXr!TA`+M(jpmoCg&K np5b_Y8THXkW9=XksD4jrtq6?q!#(z4`isf`+K8$KqyGN^dDy2b 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 zcmbuBT}YE*6vxlZGLujtBeP_Jq%(WlmYOWof%s9WWM)wp+MG*Qx~=W?tD@`!GPDx& zLN6j&1m;b<5GtEBtVBUjFU%A}!;FG7jgb7xczw^=#)DDR|K>T*?>ztKywBIzrKGfE z4~Yaw5{L&^&!vX7u2{Vis=)^~z_Xg$i~S`ZzdV28%Dd}ci>Rdpk=pZmRPNb%9nLE%C{$1RZ(6x5}xHd z^=Wz@{Rbx6Lerb$2j|hR3K<%?eE+tC@~Vhj@9#SfJfQp=)z{;FZ>>{v=+Cs(KZ%fC z>G^?vR$g06%7?1EM(voV{jj6|YR8?jz#QM1b|&AB`K0s18+XQPCux78I|@Ur!@k`= zsoqelZ+%X~0`)1sjQL}eH5US{FDq$1kNa#-M;+c>G+$&|Z@2%4g2831Crdl}zTa}L z9}f|lVm3LBhqTziA+9V_|9HvvT0b?3<7*D(2dYcoO?<=tw&i^)?}Gt#b69`l)wzJU zmh;tgp1u0n&krxm+Nu70b!+3Pps;}@^f%*up!0^5#6*=eJS8JrCRIdnN=_kF%9YV_ zg+eY3Kdj4_rfPUh?Aj{>@B{!U00`GHB_kU=K;jS>NrL^=?y$RryeG^oyE8#P0N}q; zMU)@5n~@8(1@&PYOyjYj_%;9{kgFLUgS-+s%`a@HP`8%hsmPlco{8MX@Ds=#4A&y> zV|WqrF@~2QpJw<);u z37{&`x0?Wp)=zC5`dK|<>XOJuN(TTha6S{KZ0KjdOV}%S3G=O1Y78O0dv6>^{w+9( cz}d4CREs~BR`+77tkwTFekJ}7IQa+vFV*=$L;wH) 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 zcmbVNPe>GD6o2ENw6ff!!ZKnr3yu8T-PX*|RakX9h=sA8f^}V|3}<&`cLeQ_m(CI$ zgP==L5Z$6KftvV#WeskInKB$LvrKMJ1)ZTxpM$#JfH`+eb^l$p2wyD3}Ftv?S$Z2aE zrlq!4PS;nBWxZ%D=_^{%D6T6ljmE0}!T73uF*fxTqhJ)4%=oz2Ku_Gn<30euA4Haa zJb3u*OmEwv*A3zBr@dRn=PTOx6OrbQv6q+c+>bObNJk$@KO;V+a9Al^>w{P{dePq+ z8;Q61gJBU8L4PO^>I?*f0e|bLJmJ5TROv%|R~rD9!4CkqiP%USDnMFvl?EizxrPTR zSLyaBNV7hvsjjB>o&+X;jK0l~{1xgOj%)8dS0%hNA%-LO7hmA&f&O4(D;`f<$6U&Shl9bjB!HPecWsJ)b%6hxuRI z7I;6%WA&In?OF$`$NX6rkF{ey?BaL3_#PLJxv~9#i{I=x8C$)3nKJgBDJK1{6!08tPpDUxuynkTZ zGg>RHnMMRYbr^^HpZfsM9eFah@xq>!0&U&E{=hYN>K~-|C1(r(uPBIjznnj#oBSJ? zAiN{V_kqDW%b_y`37HvAj=;xjEe XXlf2-LzzsGx0y+^#2?Y1Mu-b#Kq|0td}TS#$eSl<8w+Y1 zL7SjOZCVCxS_DOn5#i_`Fc0++6o$3QRhz&#_nq_Jn@bk>fw}kH?>*<9d(Ztbb3OgN z0Zju&gD&t|9_M%XzUAk6sDWx&PBm66ryBQJxkBEWFDzKOmEG9AatzBtent8f^8aq% z-<)n*UA7ji{HnBfN;_vQ*o*eOy#qE6Jo?rFqT#LhdaLtQEb#h5-CF01)W%rP+U2fa*W%B=9Q@RE z_o-I@OgqtCE4kYZ0Nv0Ri?s(seFO31!AOgUibyaTj<$v)k#I0HsE-9NCQRyRZaeOT zE(L%f0N}Fv2I3F^?LBIYMs3ddUh2?p4}vyRqcv2OS3J}}>IbOr2|ND-9Iq5MHveW) z;zsk>1ppfCfC`eht|pyf9VwBkD#n?AS+NKJ`=wG=cAaAo^orEFxG$u{e!I z3l^ywo&Lyv(fg{$d{R=OVJRlV)NR zMAkH%dYr!uJ(UoqK4XFyOPC1|quDG7BjYrjS|qdPSr)O;0wS52oYd1Mh;+u(Mc+WY zIcp}86V$$uo)%L^W=c2AS#Vj#(87GJAZ_FPa0@X*q)gw zalV4|uwZWSlkYFzt0vOP+-2GQDu#x0IZ0z~*FQq>i}n}*K2rpBy*z*B9QoI=K>Vco zEDHqtbKSdze~1>!=a=C&*F)s5zAq=q{}ekCoIkFwlE2CoHc(Jyd{6M5Q1f?<4Apt@ zx|w?vU-ifT9OQrgb6cFh$CMyGXL$bbz2W$*V;D6y@}A<4Q@sa3{#1W_^VGA4gh;$3 VTOKr=OYIi^FKPY{TuTSl{}1Uj9u@!q 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 zcmbuCdu&rx9LIlm<56C1HxUODsiA?9Kxy}2!_0NK%8JgRu<_PWMn_@Yx^zWe;(!u? zKQI`C#7CmYKO|^kLQDuIWNnGDE%Jv6$vt$vj91(Q5eg5)=XcKe-LB`=hWUAt1SAP+AlJ(2*67@Gt@>CCW-!5GN6H<(VF_oYl;3JM9g6K= zRh&)vt+nhXOQbUC3#MHj2_P-I!#B*SYU=>nE`KLI9BVef5*Kf$Wi&+_Q+T@s;OJ!$ zIl+46xYjFUGON8aCi6J7%9za0YIT9jYG7wFrh*2mSx#n51x?l>7VT4e^{F;;@}Jf$ z(dV)nl<2>+SCVO$)!gT@7AY~7kdsP8j>|D6!Qx6(^Ij{Jh!R&KEFwq3_axKq9{?bo zVsVxTKafIYOp8WDj>wnT0P9!ou&5kWF85t!N#$x^vM<2~lo(4YQ5@y^NYfNZvov#u z&sbK*+Dubi0IBz^wHRX7o2s^ALk;w@6+F;!G0efO?B>Oc>4WXK1##A|{td8xmS8;O zn$<}>2ueh`tXs(?CBkkFE`6BIwjJ2F%4$fttOnH=b>9+lMER4&mCG!y{L12TuQI5_ zW2Py)anEqe)p-UdJj`aPaebfq4oWsuWj=DAI`{cc->cx*&g!CBuBHbs4m#Dg`Hkx7 zCyx}LI&xfV7j;$_7N8^r+- zT*H}~ug{$rwPN}(=jrdJS*%NDJKOIceXZicQfJ}2k>)GYb~yodEQI>Hx|b{^^^MIl zERJ$psm)<2wU<`d9S*ytWRZ8R#qA047qcp7XiFXj02Tni6HwpS40#~+BBMJf@%9+4 zJB;VGv~>|ko6S=3*pY?<5m2iC#~k3;zROsPVppd;GE)53UE&QMcT+Y#gnv+bBaG{C+BYx;M&9a zG6G!tIoH;a(?QOCIi%_nwH&FV0ABz=p>Ph>vkw5@06Y;(RqZVyPp9A33QZNh_0Uw| z4?t5TK2_pV89tTy1JJcTP~PHOuhqQm4-oMOkl7mQ%CIQMq5_LKSX5$Bg~ePf9Co#I zsAZ{Is#Xrw%%R#jR6|E4w6wH)gPmT#>Lj#z)^z(dw;fug<_o+7e`PhzH1TSIV5nr+vLw@0>`sV{HVYS1b$rLg#tez@Mi?B zeHb)9F?Z1TF`+;HIv{>t;1dL%68LihzantFb2QF%fn#nWen;Sw1pYwa#R8wq6Fcq~ z#@WUDP1SMC=csytW9(_(PdUeLg?Jvm68ekh;b(#4y!0KBb$l$J_ZJ<5k0b6${sMS7t3VQt>TgbaP1h%!FkOypQy1T&^3}_9lwzYPLst97E z9Bi$Djt*~U2yC5!kk?k<*gUH{mn9 zU+pmu;h6gA_Hv-l|KvXj^A+0TT^A*D`z{d*>!)$%KgHh77ewcjL~W`Ub9?=Fuz}mp zCPOZYAJwb4y*KeB+w1+Jb(8Q{^ic8tmfP#UvwHiUr<^}G|NoB8 z8J<7Z*^73$U8{|~7nm)`zw DOyQ{- literal 0 HcmV?d00001 diff --git a/src/openlibm/ld80/s_asinhl.c b/src/openlibm/ld80/s_asinhl.c new file mode 100644 index 0000000..0453a9c --- /dev/null +++ b/src/openlibm/ld80/s_asinhl.c @@ -0,0 +1,54 @@ +/* @(#)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.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 zcmbtUTTj$L6h2*0P;{u52NR7pv0g}I?BZ>sqFqs`h9E&m0F6*^E5^dE+ZsWMn4k|v zV~p`9`0S&Px*K^wf5A2t z38i(VCgnF1>5q@gPzOn{f$U-T0Ufiou6ZKj(wn zALk3mV2~hJmRsqLRar9%tZpMrom)iStTe&dTKS3WPfttvsx;Z zqWbbLkM!@Ueg5jjbaVu0Z)-cM?QQSuZPMZgX$y^OEk?^BBOW)jz1^v+nq~X!Me~s+ z0Bnl}0ISfovln8ZiCOY-8_^p>vX`GqKae zxK0wMiFuB6br9piTB0UN{keuAV)l@(UScJQ*-sKlV)T?>wKtsS_BOFj5p#efP7#9z z{tHm57JigJhJ>0*6;-T@wpi_QYyg0bf_+p20BivOb-8JT?JMv*SKymg;K3WTz3bzn zE*$~d(PlvT1dcuIx!|U+x!~Q*`q4I?ap3^V1$%^5{3?}kQs7q${4nEV08tOQ{S(1n zjPp|9>x4LO1ioJ2zX`k;XA>JB%u|d*1zyY(XApsT;!^?jCdYhx7^vrG%j+oLWmB$A z{nUgH^s4RKK!-gKXf}-pI^y~9!$3#UV`HgtALw}6Pto?y-e%9YM{cn5weedtlTBw* zS$`7B@lvCMPSzevRTB6=U|m=;)+(ZW2SR1eIOJK|8qGIU>^U;*hb%Cnf$3mx5IDDp z-Hhk|FUMWh2N^QG4<`A={|2HF3{3jMe6#}fLC{a?d+CGsdEYa>P( n$>#^}MGVRH`TSr^x%UW@k#ha=_rrVjZ~j9p|2t8%DrEoP4=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 zcmdU!3sjX=7RS#;AOpM?HLa#0uXQz_H!g2Ac?=}vgV4~)NCOpyF%$wuF&TvL0fQEm zuEw-UEgh#UO|6;f31X9!)3Va(-XX7mIRk~JHDeEyJ8PeBpL_qFsBtxG)~wlU@$sGC zxA#8JZ}0P+yW-ZVll)93p~NKOg|Fn3@R7dzM0uMiEW#{i-jP<_m7i9(%T^%UK+|BMr1E*CV%+H$BWEqkoZJ+ccSXO6BKbgl&iA(Nwb>yu& zy=<7P_0ysCji=3jp#D^!@*CMv>u+oEx4Al$$FJRu>?_YQWTouYB~=;^KWcV2HmT>H z{j#I{uY+t{4K3xi&^zyPHMpBy9qw~g-G6;aBwAKK?5BF*Y&P7wJO7irmU3IT;m6tN z^>f*GZqJiCf_-eknlr}O*c&POU%d^@&v_QHIT zqPM5YSCjJ{Z=}4;JGatna(_;7XT)(QcW?bgkLS44`+gd$t+PVCzpiE@Lb)3|7hd#u z>ikWxAgLmF|(c__5FOq~1@xin1ObDKJ=Nm$V zCI}(7XbDGudwqOCO3RMWqra&35EVkG@&zt;+&*~I#&c`72R0bbuifzJ($qm=JA#Z& zo>;s-Y-3nK(<%#>Z6Ck+%bNbjw)W@p*VEhMqi5dx>{VP2d8hJE?|##-b|9Bsuh=I| z`Q&6xAeZO(H8e@j8- z)}Se?)|=RVL*e2#dv;IRq5O}jdVgo`UHP9Ye}Ne%`XpIT)G2>sg4Rv`>5J1Iyn^lb z?%KU6bpDd3RXH)>#fmwPo1!>8xn^0M;3Hof&s(Bqxk z{P?*wJnhC6S8c6R>*x6a&%ThEJ#MYiA60wmN3U($xlgs{xj*mkp5?c*UDf~Pg@@iu z&kbnn$NnA+Z}xxi*T;^i^8PvZ&Y#kL=z!9{FFb$ReV*xmQ2yS!@BUG<#va+6II3@5%)@7Tcs)ga^QY*L`q)Obz9v==8Zf!ZvhquQ{$6&|=C|I7KYW(UpN#aM z7CB<*Ys!Dp`109(ezpFTS`U+6dFIuvbv19Ra{WK=pBua4!`~?VpjX}d*7j}hQtNBx z-r%zn77W{_#ykJ{^RwSeZ`i8p-`=<9`RIzKYSrJzm-MaL(f@p#vcG=#x@*5^t!q&I zdFj-Mz)vO~=~Vr({iWpR4~*G(Soyp5iS~gjCYYZ;$NdSs`@D7e!ckk)_?RN<{(gA$ zH&3YYik`Kfr?wq_Pt|wy!on4MUs?KrYHyuublB|uAJ%@w{zPhW@_6fr)byDnt&S*r zgxz6{2#<&kcR0eWBWC0-u%_jd@`JIlBZcr6LRf_mv}s9ApDFx=sezah6PMLD>s9=~ zbpH%tDhoAT7ji}4dXo_4LWm#pv!&!9$sD@cFUfpOb)OV-rOB^2$b3zbIW)=KcT%ul zinlO1c)Is~T5zhl#*}KVH%&Fyn3BlqMRUEW+`Pq9MukmY&D*`2lUP%%6+&$0`g?k* z|AQd&HOaF6DZx43`{dv`UZ+XHcX;oocq{NWr>c(dSY=ig~EU z!Y9bu`M=du1CjTbO) z(0DQPBN{K0Jm6d7U%~qH4x&`cLLiT;Pv{hg+R5SFE9;nNc!?p8FgN<=lV3A0@*yd| zVNPd7C{N2mpr}VEgm{Me7LD&=Zv6MjOU!vY*oF@h;{W8vmSmw#L6=UZn9J=9L=vm*qe~u@)tW`4){E z{R|X)G(MR18#Ml7Sq>0=(YX-f2Ie6eAHjZ(XnyR>TQwfV{H(^uGZ$L?F~&Dgglc>e z>svKGm3g?vXE0CH_?^r%G(MMkw#FAQFVgrz=9L;Z<~2~%YkUdoZ_#);^F11WfO&() zYnUI=_=C(_HNIZ*0C9~rkB>7~d0mOIo&vl%UC9pRUyEV= zc#YoBK3~|UCP&aEk}gqniIx{xjy8ZnVkD21*Eo3{N7tBe zd3DIEbQL3QW29}2w2hIrG14|h+DahHvM4<{q$h{; zZKI@Zl(dbKwo%eHO4>$A+bC%pC2gamZIrZ)mbTH-Hd@-oO50dTVx@;z=^<8nh?O2< zrH5GQAx?UTllpPeL!9&wCvD@R1x>QZ%b8bFAacu!3aC7v_7=0{A~3=ty;2uEhTH?3 zmZah;kJD>UyG6y{2YuQtDy}x5n+&^wFG#`gb+x=K`mgui8@xoW2PZUk3a~z^j2@2YelH`tDPH zHUJL;{v>ev=1}^-13m=!KH#)BR{F029}4^};5PvOjJdwfyFvd((C@?fiyqTAkgB&I zaQdN6@vDIk2R;<|O~6M39|1fXIQ|T`0G<2yx#_a@i>K^9bU_R2JeqsI{2psco7;wzLHvz}| z>i~}VcLH$CzqbO%{Chia%)eQ{G5_WQ$NXCe9P{ro;Fy1_fn)w%2ORV7W56;0I)P*U zZDmgLg8A1>lOfOUF6CpH(|o1E{QeB|aehlcAM?&~;Fxz-0mr=a5OB;p8-Ziqc?vk@ zo#%jK-uXRn%sX!Y$Gp=F9P`cxz%lO}2ab8?@4zwdoCA(|ryDrtoe)0Apn0LQLlyUK z0FLt&1swC#Pk>`SnhYHCQ6_NAM{|K=KFSA<`KTB;=A&}pn2%Ni$9z-|9P`m;;Fyng z0LOf^2RP=Vmw{tGItU!|(YwGgA31?zK57S!`KSvx=A&Q=f}Ce>gLxkad@}Gb;8TF# z1bixR2k>dYCjh52X|>)`f!_{%I&eC(Rr*=LrvuLgJ_C3m@H>F3^JH58^ru9f(<-jc z9fZAP*`m^%dBR>&T5SB!S9is^1v&Q8+_F+(UyxIpBkc1^N`$?*kP7zsC8beVpzr_r zg^L#DE-n@J#f7E0_SE#5V@pbN=HJWZpDq4{y{NdbD7UzDnJ}E^=HHW7oU9 z68_xt3dK(H`9tj~29i(8nJ5ihzgibcczfmjPw#wh_N{DRuMAk!_^JQ&u8_U)dyr3x zc-$zaqp1F?|CB4$J<5}8uZylrONdeeu6dFzY_GRV&7YEAa{apf5wkWHPV|;bo+k+;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 zcmbtYd011&7C#YG+!~8QwQg9k7F%M12xvzSMTJy(xPnro2pU}21cD->Ty|N4pga{p zT+!NUwX|4kuL4q~;D+K7wzyUHEd=o4(!B46dofL)@BQ(9-^a{7zd2{lnVB=^n-DSI z(Y_y#2OM}X2i{6=QNVxuZL9gTh4*1NRP<+r-d3En+;n(CnfGLMg!k;Bw){9X0C>+< zNAP22@HnL^UsHoe${IO8I*I6`W-d;S1O9ChcQ&OW*zby|GlrcBEO=zskosiQe27b(JN4^`N;=ZSCKu;#_(gl z1pq}!5q|>3%lsL)J)IdD5Fr>eC?A_31%w+O{BK`zhVDzfY8NJ?C6Tv(Hj;$zFlqgDy zQs3&ye=p)sfEu~HK+6IuT8mg`e*x7t>MwF1Zhju&oqf0#skONyENhbJ{K_FAh6S|< zL)GhC61?bXA4*8>qgsTWWc{qmZgfoglAi7AS_FRFWIhR{r5?@oArtBlw(X2_@DHS= zkvZZ6Sch<5;#=_zMVG9zb7}IZL+}@^a5bf9bXP3eK-D1__Zxh{dnbwKH3g46QiqVC z-@3&}N?Q~Pc`b!?2u{X#91V97FQ?m9s;6}bVMZ7GxvwUMAI@1mMZX?lpPyG;coaS2 zmSaZ3)gcd6^aK>yhfdm-(-2yXXw>#ERm? zdW5`i)s^%FQgwK$-SgA+2n*v}lnrqtd0w8e#qD~8KN>8)zQ3Bb+G3RPy^`_w?C6La zA>^7mZHU{*2878g1zR7;=;v2&p0l=YK%nv>i#=A*{H4ENpZ8S*LVM2M@P*#=VkgC+ zsO=31abv>WM#<=l14}n44>usx-b%X^97(6PAB#%+tpTAU@SJ_PFPSvy+2}R(4G504 zp{1tliR8KaHt(U02=~Xjf9V=cPd8uCoGENX%Bp(%Dq$RPpFAg5&$$u7PFCeVO-8T$ zQ8*%dYa_zitED@xCz1R&Tb+Hf8xh{Tc(3FoMZ#3&`94LB2!3^?mb)Y9Gv!}p9I9_b z>V~`J%_H%|`@GC-;CoF7e^8EHiX{4#(V`1Sr#B(UV}xH*OX*pz&t*ZbO$h!Me|;2~ zOgnu2s$+9R6T<1`I~J{!&RQJl2i9mz-?j~9e?~)^{ACC2-a>7`?Um-{m~`H&!`rJ z$1O>P<0I)a^Q!NO2ej8v?GFkl-Pc^Z;1z~i1=!(iH;*q&+`o7mKNG%+-=w?nN zZFZz|he@So~^9SSv!x(9)0YN0G|Z<44aP zZ$;{ptPdt-rO?WCDdytatw^1D|0mU+WO~Y1o~>hEwjy=@cwA?(jO@GUWBuvmHl$L9 z<>wrUCbska-8L_7L+Xg!{7HEN8F@MD%$sd(2r~wh8U8Ax<*C_`g(uq(_T;FRiMJ4C z;I2=vl(!*-O7=>dmXh8=(2iU|m@)m;soBQuNZq_}z|1p~cv4&D9Qdpq!N6@;;3*mvDo!K(gdX3Od5m1WKyYF|dEpTB>FyitNG*D5Ts=OO z9KBO+(fq6(fx0^7gITs@O!=Q@y&`!U#Wctuc+ziWjBa{f4^JWgex|hBo@-4VD zRf+J8?~fz%me7yQPkn#DPKlJ2@<9HyJ@k^4oZt66AfY4n3+ubrO{=s<{F5E)V|BYUg2r+qo0 z1K~t^`i@gk#KtScKg^~Bss6?1cbv;0cp`VvttA}@U7eSm3lm9A_*2PzpALjZ+l=X# zqDbVLt|yOTI*=NM$+H{}&`%T-x(;S{AQ+xGTW=UgQY$LUA}(|wnAkk19{dG8MDLFi zv3ENV?5dVK^h+f!)8?Ey+uVU*dVfB@G>{nmEE@dh02M;C=Gb%c_$qgl^9VR)2)h&%YT_WL~5~nCfo*FLgHkk)@&I355#b zQ2YCXDig_A>a_m+mnwvpEa z+C0H?wSiM70@bD;mMJDHU|h==8#|FoTzh9>dKM`og?UHgIuX25&mSucCW`Wh?Ng6+ zB6azW%IkUtnKISter0|qf?f03eRH>yVKr|ua;rNLLO0S?&HKs8&kk3Vn2 zkLk3X_wA#V#$5>Mmo~(1-bF_(I_UDLWf#KiAI4n{qiFta_tN7_x)5qx+OpQm=*lU1 zRt^DONbMQN`|Q^Y@}_v-JwsU+!uSJjPyQK2%$AF527cFtl!JYLM~l7WXM5Mgk4w4` zs11>077`+!c*ZE8t_!JJO4xHElMJff{L7R6-AE~1GVPx3p<|tAo!epBjnq%JI|`%s z&?ZGUEbZrZBP1LQA>w3u@<+~5HeTHbV_oA1ozJ9$PdVOmj_gLTeKGHQo7Dt>vWIZ$ z8bE;?KtTjs2Po!EqXp_uc4YRm89UR2rf7ANa-ihSnDdW|0pI0DPz{zux;kcKkWpy2o7`S&NBJL!O7XoL}V$j5Qt1HgcdV|B9YMKlckciCSp%1J78{Y z2A~fBCIG-Z=Nz1zp&#%H7>;|>@>p4q4Q?dc^TL(_FLXF>%+P@bsXWl|W7)BC&iKE8 zQPBq_^Wyy*^!mL26?%P9yu}brteVGYFARD+=K0Oj(jWfT1oX7^S&Y{717Ijeu$aK| zx-eyVX0NnirV$2kVe~UbMlgU+v`GMP z(#QjKSb$|Luj|(p01UOxrSFV`JtU!RxdBrORuc^w4X^=y3Y;wdNV5 z#d~P+gSGe{wDt>{CO?@eXV(}Y4L_yJeOyTU*@k5g5a%wQco`s1WSW@`}N#c zki^$hAeDqlL9o_S>Inj`;9w901@sENyM0I5Xa z;N)x`EcIOD!^-RYLj;?G0yas4q+6laqh!5@caW!_q%Xw(2h6&eEn#v(8@<2r;qAR( zp?i2uhm`Be?DpWSaJCzwwz&$;{lG0SuHn1cy>2)h1s<)V9(TU-P~m` coV`C>J?Egie@t!rPxdBk{8^kK3tjtv14f9(DF6Tf literal 0 HcmV?d00001 diff --git a/src/openlibm/ld80/s_expm1l.c b/src/openlibm/ld80/s_expm1l.c new file mode 100644 index 0000000..6ad23fa --- /dev/null +++ b/src/openlibm/ld80/s_expm1l.c @@ -0,0 +1,138 @@ +/* $OpenBSD: s_expm1l.c,v 1.2 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. + */ + +/* 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 zcmbW3e@t6d6vxj4Iv8LJb3+r1^pEG#8F=ffY^a%o2uiaMMz*0ujkAL?;$CTOp9yR% zVpzmwi8lUaG)wRgqKn3D$;`5UTq{eYsKLdU^rfMKGYWwj@gH0=H*@Yg_w{md|LmJ^ z-#MRm&bvQ)?!CPAT*vc8iUM2;?1h3?P*+*OZeeB%c)$(8u@zsg0YT1C{khdS%QNm% z0IWZ)Om1n;I$mz2Jf}7(0CQP8?w3{1cnwC}434c-Wp7!T+=$v@x$qnLbZ(Ejh?X^? zYM#q&sy6z4W&i0mwcbiuhFYI{MXj<7Rm0RXBdXU*Wgno1CIv z4(6=j*frl&zo+gLj@wxkq}l1IIQ2b)0z35z{o};$;!R4BZ zFU~hzDoNS?qx)a|;lz7iUtMmt{mf6lo$T9L`_7%Kwtr*f_kWWsRmo!d-k0z8yz$lF zzRyd^51l^SQ`1vFSx$b@H?uDsG=5&={r{m>zaE>~I#ELJGr!iww8`z4%E&*rxp(wX z?Va5_yn3S+ z&~$IWAK2yBb-&klAl&B-hD>_V(6j@f1OU7MfMwL)*$qXYq>%AiR>&`=4!6=%Ieq|? zp(>@eva~Fz0MrA(BlPZNOm1`gN8BwZ++9VVx%~&r-DUeKI?CN;Z52Vcuq8GKQ%hj= z?uHitQ0$DVph{-4O|VYY#Bpw-YM8T0L`=2Baqgn*d>8md2mp^U-$i@6pvQ@K6%do1 z?}FDPzMJ_jh)H}8@llCCOFSv@An^%_cM`uK@k7L^{2jeS{6~k_vd8U$d5QNk-vw0? zKL!9>gx`zR1OUVVHpHTa@4+E)I6M@K=!Vt{T1TsnO(QnDv1!8QNo=0NM)$Lp1?d51 zKfzj-q3>cgOVnAW&Qb#`J^*$<&~HSeaRZFL@KDTfDy4|kAHeOqwltbAa;zE7_X!-U zl5=~#?bvMs9~0uSDtY|-0xuQ#S%Kp|;_;IL-z@O+0xuW%6@ga>+&(>l%?tMy|Ng8H zk2eSBmcZQtzaemsz;6m1YleSkP2jk9Ip{T$#{JZywCGdyI1))z8EpdCphK#NDw(RvdmmQulM1g$q3iG&AD z&<3MsSZnX>Zb+D+-ecq+9eh)Z#iOxs+#Ck`Wplb--&BL*@J=6$_s)7r!U?vxD;Gd*VaN-^mk6eE$5|P5H9EU019H@jNapAv`DK z@M!|_xa9eqr2ggne+bz3OF?q}&^_ws0uBnmsS~UpJcoEbuOFO`+&8L)3c^P(@$A9> iLF9Zq^W@q=4N(2c_o%#nc;@_H{xpq$oPDhzIsZRHBLCe0 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 zcmbtXeQZ-z6hE)s7hi2bNkD`(@M0j2XFGurGq=KqYuFgw%n~%pRz?TLZmn&n14bBj zxS$T<9}K#fwZC|Fx;6u0Faa3-se%9>J%MHB2_A;Iz^vePbw%n#_Y&S z#f)63pxDH0o0zRj%_4s-nW_|PQbExv&%(Ig_<5(1nmnMMSBI1VwNFVJI<+t3&@_$m zGm6iQjv`YD5FZrwSBgdU?rKfb(z2YuYBC;8(^_q>_ja z3i1F(P|vAZy$~zrW0b2T5z21$bpNEcHC|>dY-@ZOEs2<3nc;BAP z?!9+h$TGeA`_HBwdU@U#xnzI)#MR$>iu%(mANA>V-aDVZe8qk* z@shW94Cj#kRNaZAbE|Kh9;W<$p8v~m{soWrkmR)=Uiq@*LH8Ab?9=Oi3cPZ(`VT9~ z>$;El``a&$uy|kXy;S<$@#rlkpRJj9F(}l1!t4RMG=Rh&fUZ3NP!16{tz@8kt9t+0 zk(_TviCwgD^N+g@oH;whtg0$1o^vj(s%=>2bgz(#CAYKKRlL&WcDtNQ>jPVzUVn@f z%S)C47K>?r?0G=dWxdi|! zZN3dQ?^>J3vVOX)pkhXyF0Zk9ENg7O?Y1Ths(SQk%to6v2{4Zw$ZC_Qz&e)YL|DhN z9mh<)CM(<^Domq|c>Qq!fF|M{#IwxUIEQ!!#vA*R3k6I;n6Hoei#P#`bO|4?iCChG zxq7}lmg+*Do)-`Oy@cFH_+s5CS3h4KB>*so+c*8J0H6%ukr;@oDfrqc_)Syr5N!;G zwz5 z$78*C{}GpoH`ja9WY5<9le6dRwPT?GdcAyI3pt*z3*RtiPbLPW=#JKye+x*_Si~5& zvsok%^h>coM+~H`{+J)6Ezu}Qkq`<}b2PSs7u>5rY7Vuw2HIjEwS{5*F2b!Tj0p5(D-h zf{pmTVNA3CFs*OSm+c=LYslY4aTy%6z%z^>u>9GG?+lysC}#KzS%!a{`hY5F#C5*(LV+Bzk>A%_7A=j%%AaCk9lpx548RbDj4syeG-3M cX0lc}Mi;`*CqKzv;~PGizmxLs`49hp0kSNF{{R30 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 zcmbu8&ubGw6vw}tRvWd}Ry+jjVGluCY{zVNjDanY|8Eksh3iE z>dm8g@=x$Dkb)jOdiM{|gBPzNMBeUuyX%C4=m)~geBZCx_a;Y=n@>uP1Hr*Vg31GTG- zhU&&KRBtpK2BCopMR(m}*y0_2g=iv)=5RDFk$Q&Zg5bSmOksbzoga3oRgL-_? zN|U}VWc?GQAHp*CMf`=={17TE&|FB8NsE4)b$Yi&_KSxCoHk>PbN*|*$MtJj#uTZ4 z*V3iFteYHf^Trk!i4&dzn6uvyfVb>m-%I)@bh-W?ZxF!ezl?u&&ivl-MP*JjKdLSD qMJG4Ab^^zb`5sr2|Lb)8CDv`m9Dma?u$-}UPW&f!9Aus;cKmN6EM+4A literal 0 HcmV?d00001 diff --git a/src/openlibm/ld80/s_nextafterl.c b/src/openlibm/ld80/s_nextafterl.c new file mode 100644 index 0000000..1e0764b --- /dev/null +++ b/src/openlibm/ld80/s_nextafterl.c @@ -0,0 +1,90 @@ +/* @(#)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) +{ + 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 zcmbtUO-K}B7=C88Tz{IGtUxH(3ARwkX;+LOT-(sv4HpSZDlBBw8Krhz*_}WOvM`D0 z(yh*&I@&4d(u&fL*DkwQi=L9~kVhlhcxT_w9S6PC1H1Em&%Dp`e&74P%=G!h1)n5A zKtd-fy9z?pm37ovMj>M#F2|qV2sS;*TgOV%R-`noJX!(}f0_uY@h401`R|$)@kQ^C zS&^!!GW#CD!(XLR>5cOEEr50PYu>VSCGg0xR01g3!6y2x5fPvHq2_bT9YJST*i+^f zwJ-Che{xd;_AQx;FKhX zSXb8>tvS})-=c-v^)@}MwT0SFg~H*G*4$@~XmP{l7p24pSNmV-BP~(3l0UZF2@VjaXJ}0X)KHp`zsaw`A%AqT=dZ|wK_tf8% zwLUqNkX5rz_Q&gcWIwBR23b{OqqNi8s;yI1Q12|A8g7Hiy!&p1LjW3GKF-+z90pjk z9Y=TJksY*+@v)>n3_Z~mroT2g3@l?Pn}j(zkqReqo$crxdjb3|l`-n#Yg~Mac^`l( z7ysH7@Ai4)il-dHpN51$oZJ61^Im_N2?Fu-+k&2*O4-H`^sJpJKgYx>V$J4f{$9nr)v$ipOoA;yRcl3!&dcw@uQz+Y+ zV}n-4NSRyt{}XgCnklN88|7~bw)!tno|_72E~thgUf?Ge=@k<+hm=Q5cN6o+nWtX5 z(M`cSz)PQC&wtg2Ie()km&h;9D?oQ8h-WA3L(B^#_@E~R!4T&c&lu~yxF-TU@X}X# zez(mefCn7tJ(u@BY0mG}&$0fRC%;#JYnT4N;D(4kQ~zss=s%_L<|g==%yIq({w9n3 e!k0X~y(fHReKYF?y!G3^i++wxr-YE<)&B*b1Ob8o literal 0 HcmV?d00001 diff --git a/src/openlibm/ld80/s_truncl.c b/src/openlibm/ld80/s_truncl.c new file mode 100644 index 0000000..8a261d8 --- /dev/null +++ b/src/openlibm/ld80/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 + 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 zcmbW0%}T>S6ot>!`tL$TL8yzkQbEV2D2fXaN*fnaL@2lsP3vfjCMn4X)s3&Iq)?ttZ%OxdlrBLU>JZ`sUidMVl+n3oMY!` zLEIlhw5LUGYIN*TprbF++6bHf!0eaB$LCKaLup!%2>`QwdYVy>f*=ZI9nBs2_PNYm`#Gh2^ZxYnM3evgC-iM` zznCLB=mH7jbWYA^-IUqchIjIv(`dd6(_`Cj_O*L&*rEJ+@-z1TH}i|XL4{XrBy9f| DB3?+k literal 0 HcmV?d00001 diff --git a/src/openlibm/src/e_acos.c b/src/openlibm/src/e_acos.c new file mode 100644 index 0000000..7295ad6 --- /dev/null +++ b/src/openlibm/src/e_acos.c @@ -0,0 +1,111 @@ + +/* @(#)e_acos.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_acos.c,v 1.13 2008/07/31 22:41:26 das Exp $"); + +/* __ieee754_acos(x) + * Method : + * acos(x) = pi/2 - asin(x) + * acos(-x) = pi/2 + asin(x) + * For |x|<=0.5 + * acos(x) = pi/2 - (x + x*x^2*R(x^2)) (see asin.c) + * For x>0.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 zcmbuCUu;uV9LImRV{FsWvki=kpp-bU7h!*GId*LTXYx| z0uq5l1z+@mM`CKJ3s@FxgL0~@!oB714)fUoL0AImsCu&)J$^A-yb(G+x!QHzgYB+6 z>%8(%Gr%pUrlgK;wgA#(5kKy8`dgj z-V zJdJ@C%6-HyM^{a16)$R)Fs0K`H9Et6YZbrjWyVaVRtbuYxmW29$``pz^vL-}ug(5* zX%(K*Dn6xE;-XgZ39Vw+wCca4RSe6Y*D6-<#;;YPpjAJn4$%nNr2@A+p;n>~(^|1V zo&j3Lk*)UX#j$nrFMgGWtqo5I&Lh67@|U#g$B~t^N?cE?aH;Hk;#;i}MKPWSXTI^-`Y@QgWYOJLai;W8(SigmQZ+S zYHui-%u`15rnLZz03ZYaXn1#T9|XWEAmg*ZqI8Yd0W71p_1aFb#_O!*wN=$8Er2Ef zSV4KA3IGV~4Tb_2gVhxcRxlL!K3Gkew-NTY2!3-H%C4A;X1*!_JDRV1OzdUO-8PtF zm2+v<{lo_tkj#ujB@8hjJ#5~UbQYEsCSF%YM$N>dKE9rKqmQ={-{Irih~r#Ib(%ya z#3TfO?Zmyf%IYQFQbtD45cm2o%WKzc$9Z}l02;)+m^lZ4Jpljnz$mplIhe`WgE00& zrgisl2JD{BR(wR(o9706ZpMd~Zoy9jBN6=Eh>wV=@i=~N!bh8dfGtDr^Be?W)m*CRR0m0=u9~NBtIWD;L^DV)ppC<*Eex4Rw`uVZo z($CKYmwuiXT>5s6xPPC{it=*(ETt<0v*r5a^A*u zollMD!QPw9C&Av6%YmKEV8R~E<=em>%#4hrM)P2gX7VY!ySJ}7mroA9MCpB_`|Yu8 zW-OJ>9{{hp)X?s9HaU`_-tSsCE?lCxcBJSB#oT$$^51LA&3z4X32yl6pKfR9H^w%Hq0}^e=IYp>{?{`62T%Yd+7WdC@ypOR>|2;ZQ z{XfPPN!&lbyQ#ikRpgsrT#xk}fZ4C})+BmD_5E>i+^h`s@2}rR^?4nz{PkbF&HRVy z|02&bCh;8N`pj`W{=QM;)IXn}cxEhJpgy*_&{U7n`rF5Wll=bSS+P+44vPN(SG-OA F{{X(u9cKUl 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 zcmbtWO=w(I6h3d#*in-?lQv?YYNnFtRP0M;nzmxek3>5Wh7=0HH}FW9PG=l#l8G~~ znus*P8dN9}Ty>{NS1w$2Wd$dhE@EvZw40ihC5SErD|ahAIq#kO-pR8C!EbSYzB%{& zeCNK)EWegN88ZyfFkl42U5K7|xE}MCV~~JOsNjW-Pq+GA*IgcV-R04DpBV;N8O7Bd z0I1-f&DGoZ*>46wtAf3+0t~yZJM!K^GRoq|KLLQkWIH)jXnAwXvzxg1N6+eQ{G{9P zEING)dsAV-TVr}%VOPE{{=5H6GT#?hnCzz=rnf41p&2?Z-0O$?uB))HuF&#qDmZ^v zq0Ny!-dj&xyx!y6O<%|Kj>5u@Li?t|!iGZYj>7313N3QeQfM_>3hk!C>1GRiS2(sp zoo@1JKe@t|!om%OHkUzbORNh|_;wc06r-@I(Eb_In_(IDj|%N|Umt}@HjW0fHWU_g zUF1Xuy6ZdDfvs(S-({0>UHQI_P|6O4)4rfy1(@FQ^d=2#s(ZuB%L;PyRkPPyYhkul zGw3J)R1bc2WE)=}+r}S8&)w<#?%VwX!{@(#VdR@%hrXu^0|29t8y|l;mCj909ZF?} z%&eJ7We2lI2Q!($RQh!JY-*zD@DGQNA0o*B_5eT%0I1;Hh~cK*!$rngP%U08jC6{V@QD*@;waF%gelNu*+*C&cxCASm7*_{)9Jk8MFV zyU_-1y9oez+{-=WsTRV1Z)^|t8a>SWa|o|*&>qyJ@vOIK4|LFYp8050V?K%#0I*N!;Asp1uK@hZhllb^u~chR%n~fTRm;xI*1*hFFIhJEjmRo&omlf)@!seOATiT z%u;P`t~~F6IbUJ@90KxaK5q(Dv@Y}BKHGbg-@kB5~d_9lw`9W>KxWw@XG{MmE^_=7LQC$0v`M&|+eNR#I zCKJ)TNGpjN$B&-B&qTDZ(erOVr2i}Qkpl#MrvB4Aq0j67lMd0?gh6g-m4%{jk^Ue> e&y&w+?+KT=L8PyQ)?K6PVdpvjC2h!vp8p3LISqsW literal 0 HcmV?d00001 diff --git a/src/openlibm/src/e_acosh.c b/src/openlibm/src/e_acosh.c new file mode 100644 index 0000000..1e783a6 --- /dev/null +++ b/src/openlibm/src/e_acosh.c @@ -0,0 +1,68 @@ + +/* @(#)e_acosh.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_acosh.c,v 1.9 2008/02/22 02:30:34 das Exp $"); + +/* __ieee754_acosh(x) + * Method : + * Based on + * acosh(x) = log [ x + sqrt(x*x-1) ] + * we have + * acosh(x) := log(x)+ln2, if x is large; else + * acosh(x) := log(2x-1/(sqrt(x*x-1)+x)) if x>2; 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 { /* 19GlCQ>Ek-FVX*$!OO;eK*tcxn> zLP1M+y4646A8^rB7jb2~6MukIC{$-DV&u-;m!z*|qX&}r-g)<&d*|IZ^YHSuDOl&wJzV?ks(F;#ZR6Q~I(N7z!{dh;j zDXzllZf*o-nYBiez%ogHdSrquSxFefo+9oB(iy_j*V?6)|pgM)Y(zG#1fkB1W+@qF)VLoe|v%UytY< zx(g)TgCDhB8vxqsRW%Uyr|nP;qs*%~2%x9Q$FCK@VSqI|L1z_^^N5=chZZ>y^*R%8Y%!N{M!7jOr2<+_q zlvBzU?0WwH1U(lW5%r`Q!M6(a`y`>>9lB?9t}ymX#6gj`Dud?2ffecko@B82S|D78m`%L|(Z?4o!p3 + +#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 { /* 1_r3RK-rL!mntm8i6bL97 zM{Cu>erIc*bf-y#(Fcp|R+v^BYc%#I*wGPy^uhNSEg$U;(6GmjY5*LTsWGjZKKK~> zzy^~T1NJA_;U|EmNbXupJ8@WadMN0y%!$JmD-O$cQ6z^&=Z8Y4-ZbJGMCOM=4$D*> z7U?6N+&XNj=CEv?X~$>8S#0nDiL*6_Eq!KM)s5@0tgB#JooQ7OaIx-r%N+Z{cuq4_ z*Bcu=B&XotGj3+?ZoD`a`%yW&(P%UP#7f2lZ4ar*$@{97npqfDjZr|J2L^0#GW%iJB;Uec3a|6+SAj=Adjxlz~up@T~&e z25^mki<0w3=E6ZMtQLF1!P(x~o^UYL%k3@#Njq^)+xiO~&8%7oxzjFp zAAUqRFXJkJexDyVR{+-mL}X(CH{0-98y@CzE?+FKTY4V)^kjlw20RMo7bV-mMsdx3 z8Cw>x%wq-sbO89(@bHZDREtYK{&gGs_igxk8$ahhzT4;jr_T??7WuquWB<*^2YvR` zQv}). + */ + +#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 zcmbuCZ%kWN6u{5xrekz#asG+PH1xxpVT*gVj5%Y*C@^SED&QCs7h~74R+xpB_H7vp z30u(U!eU5t@q=d059&VfVKLE9s4ZyZ&zy^i$$RO18Q*{{2I2=HA=aGx?(I7~e8yzw z%Q^S=?m73KbMCvZ9cqd+yCeyONN@LwN-NF5OP- zDh?%T|E@dxbfUIcr-lk+@)7`OceSPP#UF6)q_;8%>ap<1;~1xK+HYBj+HdQ;?@mbo zMqbQLcq! z*=Nx~xxyM8lr4Ku_FIFEK{gOQR~VE}SbR_p7ODz^avN^!z3(J|-?i}Y{fff4d>gYJ zmvg4NVXAAU8U+A-zAz?Z@r?y-J0_v$aBJi81pvUpAsCnM0>DpiGsQ9;V`gEDO)HGC zh}v{vjIChgnTcz16L-PPq@3oujq4M93T{T5DI{gTk!RY+bp_YK&f~m02=sX)Z>(yw z`h+%XEb6n`gt2N&7nHc5m=iShA+El4l+H}ce3ya!5@IafPvHp8t9!Vo_U>Xy~ zvNmlj8gs_Nq_+~w4*ERnp4k{JZ#L%6E&Z19qkdES*_hO4w3|j=o8_g!T4L$2mNR$` z^ciiMml8FW5;c|*br7{Np-;0Tc~EA37H2mpx8c;+-Y{0R=|Z>PSiq|4_l&uP8*9ZP zzDHtex1T-8FMPCCEV6?Ebr5Q7e9>1GYU$YR3)CppO2Aj`uiozu1pL0LBk@zda7^V7 z_8!=6I&B639{}K66l&=J7f3l|LL@#Gcf@1-fpq=|Nare~o!hpQjYkj-Ba!<3%Ol6&jpw37te}R?^%*U<({&b+x11cr|h`98J`UCCt_g-!RMP{ znWwy7HkEd1iJO`1j#wuZ0I-A1XL|;KCji(pyFBZ_UvS`u9r()*{FnoeI`D1>-tWNA zJMdu#e%XOvao|@S_?HeGuS4v?28l;wU8!tR=>jFvxDVI>qM=A@LwzLL+T7gUbToRj zz9G^Sh3HFaBpOp=ece5lolKc_fBSx6)CgmrFsg+SFpYHk^TOa>Y2lR?UTNW#w!Hk1 z?a!!50I21O>;Zs>0bs3YN{H|+gnvMI8R4H0zLoIL3CB;fi2oJgc-95~p73pi&k~Lw z9Wh@c+(Y;r;a?9~zHDl^-VP)dUn4-qd zsi2&SsWDJaX0xDVQaDh$vT6+|U8&yQc%KSNUrLQDp_Y!lSvA)679YRacScEPQt5a` z9RM?2ygQo6#Cqd=^#>Nr3y&PW(^Smg#8CQf2(jO3J9%xzd?B4!R1{uM>>;j$X9DF( zuAkwYPb1{EFHwIXDZaklKgj*@J50syf7+@4{Qs5cGxi_f zd*LrQ=3`$Q{J-_WI#n_iz4bzW)Ksm5JT|A3vr; Ar2qf` 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 zcmbuCU2GIp6vxlD6iR`;OGUE^rc2V`KW%Ruh-1#3duNVUOo*O`nYq6? z=bm%_b3bW{Yy<{ja1w0q>7>Jq;l$CiPb7-hV@I#` zUvgb{U*h18M*mIMy07)38Estir<|?+>zcF;LDT!qH*I zC}-&r&Qh{GHN@0;&Zf6jM>w;ECugZaGNALEr3v>3bpFo#sh>T>y=+a@6 z9TnyF->h43!{RK`QXSu+Ufu1wE+&Z9G_~EF{kt_OJ!8R~H(p$Fsuzwdxx8pEz7uox z*IUyrK3ZZOc`wvEc4L+G$cfGmjRUV+$)+RWWbvG}r{`K}d{MJ#F2Do;hyeh~+1#3h5(u3}rq*yswkOL3GvqzA zdmV)OBB7a6CzYQJ0W<-?Ecxz(5&&2kjvOvYgrf&b*M=LNig0vUII=8UzIsZ@I~C#R z3ejkrV*4*zr}#s-onbu_;3uKIZl!*;fqC0a8AJmljEQR*L^SS=t4wG??Oy4>mO=oi zlHAaEwdA(O=Sg0x@%fTJt?_!v7i+vh@=lF=6QoSu16v{e69E#oT5{diNM5eJXp?-q z#-9@Hi5dkto-*ju-Z%hINxqkuD*&(+;2+-v4fE;WN?3MdCcmZI>;SW6`2xJu;bkFS z;o0PIVq4oa#JEIMsPva@6e}GT!@8c<|;M z)qf7*RR0FTD@i{Cgj4@l2)~Q?;~ApzN*B+}{I0G-W)qnCLe9H)s;69bTgEJ8`wC!g z&J;3WZp!Du%=KWy?8p}u(*~}|j-IZrY-F*A`Z(;`~r-yG3%0B;Vd|c+oIYR9>nLqde;+d*n-IxAL{C-)Gu9s@7dy9R_?GhGmADoz1c)xlhY@y)HFwWqV|PJ$_uqt8+z}9*^fJ zu62F>l*|8BYM$Vpf=I literal 0 HcmV?d00001 diff --git a/src/openlibm/src/e_asinf.c b/src/openlibm/src/e_asinf.c new file mode 100644 index 0000000..1c1ab2c --- /dev/null +++ b/src/openlibm/src/e_asinf.c @@ -0,0 +1,66 @@ +/* e_asinf.c -- float version of e_asin.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_asinf.c,v 1.13 2008/08/08 00:21:27 das Exp $"); + +#include + +#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 zcmbtV&2Jk;6n}P#Ym(G&Q;Mi4C`K}{L1bg6ZX1vir-~t|Vx_1w!gj4xPHGcW@=<$3 zQx2q3T2*iXB#^k2I~@1}Dx^9I2RA26xkPZ{fJ7yvs@@Xv6Rl2Llk^E#oIUpYFfxy6(o*<{!qW>u#hz8W;t* znZjG&0)T^s8k%(n=jv0NKN)ClUD_#I*ndk|8FgKE4DWocHX1JyM<(95e#}ARSrV0Q zwt+)?*YBg*aL_nHw1c^ZgSlM?3nK42nAO%frA|ICIhfsZaBkPZT;0KJ9nGzsGWMs* zOup8{+*4$-jE^3u?M=+9E!Ypgd%nC-9F7ppI-1)K7PcH#)uO6v5$&@>jw<`JC+BMp z_7!4b2m3OyUU89$^*T70iG|B(Hp=*@=3suSiMj12r`*Ksb`!I;CKl>V%s;sO3x59H z6W7J}l>LWypSbSv!SuzyUive&+dOxT&fx0akst3pGc>yP{cB@C{Fb~A04YjI!%b}s zFgY>tX4IUVnH`8GlGd=5hz`exPsJ07c+|X5x)Pl#+WcYg%mBb40Ehwr6>xH97J?9{ z5hpzqVEJiwa*XG|#}^>5ZUj#B9u9vI07wGB3;c~_I2$oGgXbgBVt2$yN5a!R!BTg` zI2#G)doFs5>7I_jJ3%H6!DF|R_0ZLdt_{ytNadr$P=eO{4Aol@g0K*b=hYm7ULhF$ z%zO6Qh%qm95e%q>YRe8-N(#a84i?~~k`Mb>fDr&Vs^zO{3jkvP|B8i>K7fbPQ6eWvE`O*b?A*UIYQ43jqFhJv`SLcKQ#V%Qs zGqZzLySQ+b<@cA@tkufOYN=x10MAot@p8FRTq?Cf`#+$3sTBSj?)}F>>%Iv5_xFT) zXP~uTuuca70N-$(sds28?}gmoSD2?B($Qc&Km7FTZ1cbBC)oc{pCj=v@d`wincfkK z$*;f9fy$dM;Ig#l=>zno`TX@3S>_z;$Hf7|;N~3?f+6*jd7kzCNOd%S8=@zu0H}ND z-#*TSKQ5`8;4}8`*I#Ag9ofk6>(l#3HI;r97~Ig(XViam&qZH&%E#}UP-9Zw4|-GR hKh3XCZ;HS72qqu&IVH8>uV3Fm`W*jPZB+%o{y&t6o5=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 zcmcJRT}&KR6vxkQtEHvxuCfPq0e0Ey0{bx( zFhq=ivEiXL@v-`7Vtnz%kHnWx%ci&TeRKjZ~&JBPC>a<)@yspcF;6~;070TM`mvYBMZ+9eHWC(A!8=d zbg%h*O`^$YcF)}b04*hSDXYqz$n2Hib4!U!?ztKVK%z-+o~XgT8~0%_wA6LA^xaP@ z>crP83brE)W|x{*u4#3wp%gbwz3^W)loAd6*A1MBUeHVGy1uC2Rf>9HDIvNK&Y4+> zEc6Inkqg%&g>~;C!!TxcUw6;{a?dc>478+=TR8h7w#|ST#(fYBS?I&Rb&SSFMrLn$ z)b$%{YEgN>%+~*wj%gwIPlDrG=!J{ax{-s(_O8RYeSt;ln>avp8f6&*|l9E?$qV?l@=CZ-%ad`9O z_s3rafM)0jg-&?uIy!p~d;N`KK=gY9zQ9qR-|zF*orw>5Ba+NIjvPO1`R@b(F92Z8 zc69cF6C8PDd@ngzdxtd~_Oqwsl{4U&^f+qw?y9=v00;xXqpWYy2>>lF&#W`->KfkT z^0c_BLe+!ttG~;Yb}Fte=4>PUo}F;l*sgoW=GT^0ZJOpz+#-+J zx_=8pJq!T*NE~wx08k6Se74GO!%x`okPVO8@Ln7Kq75Im;b|K_Wy4>$;R`nWZ5#fM z4S(N;e`Lcyv*8erNx5^QDRB_QXvl~E0$>t|bwp3MwnSs6+uOU_dSX2-txRNO zc$o9?9~15(e2H*3;a?Gsdy&V{2!D`p^E77f-A8ymJD~7;9wPi0;doZ@_-7f%vkmt; z=lx_n&2yS@To?4=rf=B7quX#m8WoVA`w zZe`;sNtEN0GKfQxEP*(X%Ym33!-hDRlb@oEMi2+bMn>YJGKiyNa$M}_>^+i`rNNh3 zdw6tQOlQZ^@vJ-rR_u5(mdHvYarPyP&*#>ASUs$v28_j2(zf1a}O z_b`9V4Ha+m=QGUT{M|*gpZPyY7>duIKYIwH3RNbAiTiO4v2%S(ZR1a8=3n_;eBNBs z?ERJglgz)L4`izJpRlQ)RXn^%onZaoxyAi?{os5m-;Gk(`|DUIo>llOtkNG}vu&za a{T9q 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 zcmbtWUrbw782@fNq;(qyCz_cVTcTM?9CsAPhR#6=WptA;Hir&Hu|PYPK}*_81fv7e z;#Q*>Z__7T;uhnBd-QQFXu^Dv@nB{&kz`S6Og8KiK{~nSJNKOS>xDk~dpLi7=lg%o z{o0Av_M;X>0SN^fA-~Jxl0Con@TCVBltIwPE`0Ax{FqqqrS3Ub?<7|33sZmSx;~Lw zcG%aB0IW=~iyr`R$<(pLt;GDXRNA?Er!_HepKqR860%-mY7YgR~*sx zAFS;1*8t#4-E**br-F{}FUHotWgoXF0I{sX;x_;n7B>C65ynmt#%&CPhLs-Bb)7jp zkVXmSfY#|-V|96nGdzKGqps^g=J3*-#L=_d0Oqh}~5(tXq`DFu~%# zZlL+s3}1`5nUT4lh-EF>hq0`c#jkDXx{Qox`6XAoznK1PL)WK&X7MYAgb1W(A;WqM zn-{nw#*gL(V_BKRR+g;;yoeB&%eSS?GR3EAW*aiSj z0Ki(db##FRlq7QUn^eSJevTEwrSk46P{zuYJv&NmGYY^y0C-xQePsavOQ5VgX0dq6 zY%kAs^5tZiZO(@)A+{yZ?>6{LRId=$TvUayg0+wUfbBd7E7-(|oXZ6-A^9gc@ra~z z*i(eBiMQb^u9a}3m)%`!swAD;G!e|wDNrkG?@6~ zf;arP54KN{1D-(yheCxKTdcm{}JKw4a<1GAUw)T{s!T95dIs&(>T8)d?}It zlkoTzNc%g**J`fYQ-r5^9VR@@tA+6RD<$op6g=MFNNMOjXYJo8g z)B(Td2emI61vL`JjoKg88tBG-5Y+zg@Ngicff@>H0ky58t2(Or`_GI0+0dvu5($q4 zBHB0@#sh=B!H9o2AY%C+!2B?EbH_CL5ajxXgt@Ls0$0hTYcwhK8>nDYNvHD4j z6?s3)!jXI@_k3)iVE63eYP96)@KiZEmH{ M4FkYMsaQn+KWQ^Z00000 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 zcmbtWT}+!*7=FJN9NVC$PTXc@MrVwcL_TSSp+*PFG9%-}FXvGiwK1_j%X1k5%d zEm<&&F0f2L z2{1J&E`A9B(;LqC699M-V5(W9e*=J5XP0KLE#wa_+^I?3aP7>`TptUh@-C6S0sz9l zn##M!s&m3yj^=X0`>@mZuL}R-$t6)Uh4Y!etq9pl&lPN0J+*(%t}Wc#H@#uolU3rq zpO}i&4I?LBCvAPQw>}joT*2^DPWkhF7Ms&_+#PZdQSZ>aUPW)ZHxw5zA=E~lA0BDvD1IT+)KznQJ z^FDujcWV5v>(TJ}jWYI!hQ!PLl0Qdj^gKF>Y1s53e$f-AC z&|E!_YBFTJa~zCuuW_JqN5%UFz*7M5D6NgU0N|X*n{u7o<*De{?dtPXEcM|0ZBIq} zQU{I-{%SzGW$=fs(Gu>0S6kr*_f`S`DrF3A86N^;LOe*kg5vi{;sHe$;Ka0@e@yNu zFUTuANj&D1qfSoBrC%ID;&n6;U!g6$K)hGuUm{+ek3t*q>TDE_5x-v%gdPCc!}2W8 z5&%vBY_o}YqXZApfshr72V-U!tTXWm7(FvEGy-Nxy4w{4U0?Fn$N) z?=qhI^AF>>o=SRXy8qRT-_7*5F&=NF@-xDCZg+_B_$Ji;4;jz%@EPN|-JcoH_5Z?n ztj0?JU&Q14dWi8GjNilfYN`k-4@!@Z@!X#}#&drf8Si2G+ZfOHcQanF{R52W`%f_* z-=OmIP>Hxy9Y8S>bzmkZhON*bm`N+)^rzJ*5giJdR&?9~GZL~wU=AjeU?xUzVuq7e z1D^yAgBczf9*)K>FykXu)NJqWtxH;=@L8IlijSG2iILH0!kPd_dGz!^ED;)xk}v-Q z7$1hNS4ihS6cp-*f?l@{P;FNG71rff7T_aFnp4lAP!CnzdV=ipGeTS;IlX?Wdar=r zE!?Baf3@YXilAdIAVBuR@k@{zpmmwq1S$-XY%L-HNU5J8t8FL8gSXrsC(cz>|&DtX0Y uJi2Yf9NAx|fU&mWe+OM2zZLgO)i~YXuyUNB=MQz>PkxRJT~vZ4. + */ + +#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 zcmbtXTWl0n82)FsNDH`UC0+`cFzRBsuG?}cF(}=#+YV&72MbpF=QJ;ME4Wmtrkq(!XO5z0*VcED)jDewA#0NEJ*+U2lzN!EUlw4aq=@+R$9g2~^_>jTfg13Z0}+0)VWQ`LN=UCi^OL?LM!hg?wJE(VFBZbK88kaf4`68lM+a zQvyjJ6aZ3FE|O_=0Z0Q2&@i_;Z)C^wW8*4W39>dK>37BCEle4z80oDyx7GWEq@9)Y zJ7V&tS<6|HuCqmm2XY%Ql#=eS%s`nhe>8Po=u9nNV>%uxk*NJ z0a#^P*ZkP{JA>G4+}s68|4U5%VQ%gMNk2y^4U?fGwmbxY6 z;sM^kcp$HnbTy?kd&5{qDOLPrW!hAkv!5jMPk~ZJpY$+i+)--Gm5T=|?kTBB7fCM@ zc%4dW(oNE@nmd>jNV-M<$c|op6eH(#<5Ypt>}d8ze$4o~K&jbhNB>CrQve8QKPviN zLWYl@xW8^bqbKMFq7vJ7H`y zGqaXv$Md?e7MJ<{GdYr8R-lx(%F>!)EHK?_LDoXP02Z*73&t>o#Qn1q*&D{yY24j$ zT(FML)`V}(HBd66L>qfZX)rbQ9r@tOLrSv~MtQM*cI4mZ4dZ=_w9cm(Y0T)E#;%kV zWoksHDTRxlj67B7{$lwy^EhGi+4wV`Un8S1Y|R;t7tZh@YzG*|zcbLVW5V`c{ zYs9Ke{%U`fSRJU|9H^=ah^zOMjU&V$Wh;%pAbF%HSTIV+q{Fs%OFt?wJGtECB$)#(SB? zW9Hp_Zq2}x=IoIf9AX9I?L9okzeg@7Rc!O?cUimm0im0m}@OXmg_7oU}uv zLEc*zlp}lV>kot*BaOj2IUIq=PF0R{w?*2!tRXta+e+j1E&%wI^$Gio`glk!+_dp{ zrkv*j!M=KIe2@tnd1B*tG2R8Jqf(rE^YHg=JgSA~-G~7IX2q|y@u&%If6T_)>p8`E zyxHsd%EqG_d7NEL;!gX+jCc0o^gQ<8*!YFE_;+kPYM19NW5UP0_zA@MkC;6!+t0=N zU4UuNwqn7bIMSg;o57z@d#rn$k9uP5QNJ4NQ^DUFRiof&KqC-5);;3CtV_56b3bEJ|PKF{*A_80L6J11v8=X^bj z>Gbbr{!XxRiooX;a!ZSh1@6z!pM&S;_wDoe53>BYZ##Hd{4O*9fZYfHK4S(iICx$^ zzc(>|Cob^>4sbsXln@@(3~d9zPt4z0m-9VvjOBOw^H)+IPsHH#$8}8Q)XzTl{|VO# z_Hof1`oaCo$_)U0?3IY$s0jQ=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 zcmbVMOKTKa6#lAxq&v~RJwZWyklHwOaIAF4C!&cElN1;NW+vETNT!lhB`~HtbeEb4 zK7xw&&V@@C{sa99>GVd0fwXQ6vzUaLg&;DqHX;nvaH`JjuG~pB`Jn3D^WA&ScW<3@ z>wfP*Urf^=p`i;6uYqSf8{>F4sYS^i*FKI`8;mRAzX3v0gb->-aX zOT4)NtapnizXMqK9*iH=g0b&+bltjQmfw`$dm?p&Qks=j-ApVwB3*S%k$>libj=eZ z6;I@93*UYJ&+c2lcw%(f5$UB*6yS+#yU0HNWA4}MRnc~dsMLO<9P!UvPvn*z(NVko zmswfUBRYw9k^H$D<@3bIiYKmBJTY4JL{7~=|I!gx1FgEw$l`TRj4oE4K$rB$uT)7L zcySX?&;NbqUg)iNhjx`M9)v!C{+^z5db)pbxLwblG&+r}-kIqS0S zaCdJc0ki>Vjpznv18@}hU+w_*nB`jeX=4J$Ku;&VPS7h$uagMoaHBAloeh_pp+OA5 z4gml9A?BH(Va(_+@2nDiq?!>-_5o`=cArfJ0tvOq23P?YQG%{ z`Wf~05*aE6fJG+uu#W8G1I+)(JTI?fNM29{Doyv2a&9+1%lfT~PL74-J|*P-rR~}x zewO3a?1sD%FzC#iWd46e!IbOvpxj=zRQwuezy$#?sFI4v>&n + +#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 zcmbVM&rcIU6#lk=)PkK#(3qg17j;Qw=~mRl2%-gx5ivmRSNp#d`ofmbI)dUNTwe1i7SG<_nX{ zOfH#hv~048^&ZQzdKY6Ro7`gZ#ts>oY^;Ig%O8bXOo zuRo+x0MNHW`5nY#v5R3jKAh+XtKCXeQNz(l^jt($BVl<&p9v3Y2A}A>&;ii4g#l3J z_;3O~NJZkr9!p$5$P=`3DLom1R0v6J&5iyw2{;4bIG_7Q@=7rD+~>O&2>P!!`R)XQ z{{E(cK+u1qX&~t5cC|ox>+#E~HCN}Xs*2{yu%S|i8;3dX&2^OXUbIz+175naH!ZHb zmD&KD1`zts8h}2f8Cqs8r6i#Y#iH~(OFxx<-LNMypPf|~QUGKg!v~-az#q%TP0rI< zPz{1lxa?_8@G~x+&QkDCUA#N~>pkMXbJ@G&e{k`%OCmn?4uRHBp93Yols2?!D0w4i z%Q-R1>GPUm=mi7HjAm$1rt^6yxhyG4GH-Od74oLxs;yj(58!h63df=t$UQ*2c`l~#DiziPjPh{V}DyUY1kiC2Ohq=FZzl1L2 z5ciMpxB?OG-z5kRQNNIMU&Pprsaj+WTWX<3Z*K#*&;7mY66YsC_m52fxf=lJ%_I!k z!hzSnut)#A;Rh=Egw7#Qqkn4UCT#Qk+dT6jUZ=<};?leC?H$5LUXa551$bBo^bXhZ N|IEo%$I^z^|1TLX_#OZN 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 zcmbtU&ubGw6#h1~Ha41xML|(CAV>;!Osb_KrHw{Sz*77{v?b7(rke(BnvkqD^P(_jdNpE}kAe`XDSoLMa_eW8VYGeu}8Eeay?(iG#*$!T$D{(~td zUYTNiIb(`Rdhog+A}gz6KRI)#ir+>|rXV73O);@zipkfe7$X#2tdC{=PS4Ii{+;?!Piyxzh|ckrm)ya25p()Mia@-Jz?Q2=}S*&2-}f}z_! z-)MKxp9oy*4*Ju9i_ZOY;B3&(;x?fCoAAT>+v5(Wx)!?aX(vK0%7$Rxi{^WD!du2} z06i{$`&|I+1OD(P9B9MG+VH(?c<9-DxmJ{U$k9YU-J*1hfmjrBQ#I)IN-2hHc6M5? zSF(D&LitbGRRBH!9RPk(i&&O*o_YF~T`vBTi>G&2`bn1$#VG#1OYio1;Nqz_l>V{H zhk8o!Ph5Jp&r=ug_Ic69=bcOM_W9`IsTWjU>TLq;4_yvqZJ}i3rXXuZwK*2mtg6rE zq@mXh$myJsgPf|>Agg6s$b8K>2AMCHO8T4uIafAxnH)>^)r?&J8n0*OuFFcbT+yq> z0-APuFXVU?D)dJf&*xn}o3fI5jD4X!c{{o&tAx!`P literal 0 HcmV?d00001 diff --git a/src/openlibm/src/e_coshf.c b/src/openlibm/src/e_coshf.c new file mode 100644 index 0000000..e129659 --- /dev/null +++ b/src/openlibm/src/e_coshf.c @@ -0,0 +1,60 @@ +/* e_coshf.c -- float version of e_cosh.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_coshf.c,v 1.9 2011/10/21 06:28:47 das Exp $"); + +#include + +#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 zcmbtU&rcIU6nGZ9crn3)SHWJ8cqoYnPhPy}QTGVRnzwz^4ikFOFX_(AH{bi-{CLyi9_GV6h#II=&?f5>NT$2c7mJUs}^x0%9 z*#A^c?$+Z>=50rlW#+G#EOubBl_Qfa9h6zm1X>mtPw z3*Z1{A31)e3XLyT<#3r=<@p>a1+UW8*6Q3<00sb{o8~Imj(NPV9FDNd2;| z&f*5Zx%^-QKG1*%J)TJC){|-i)R}NUeuDT3flWhFTg@dwFJw}oB*fzzYkDCQ*9(~> zE$1$^4ghEZfKx0H%d)13$9=X6d{p4^%(y-#_+Sj@OM+hX*%5fG5w3qD_+V{u{;i-F zeclPY=<}h0&w-#9eZC01OUR2gj==N5Ukz$*D`jY_pyrHhwO!}EtiGYChF&m0UDFH= z)YV)L)NC3DY9eP0fSO3BQu?L=>So%|)kt(9kTbNzV;Vo)e5z)$>5QH=wxDXKug8;F zEv47;|0i%?_*O1RKGpv`sMRlrT*F=VJA;~@qZ5k=>z@7y@O@#IzpqXbV*Mje@*2Dp zCqt(D$n#(0LzKTmO2qTGNj!h=yd9?aprq@jh2E5SzJA_DC|<@i7f6ulMS7QKY7ziu zNhq(2pFc;M^2_nt6hF&_1UddugZsZt2gL6g?;qbKkLNt5k#i#|l;24$-UHUC9FLyz c-6Ot{>5x6DgY0U!)F6JA*1uI#Rw2j#1*=ROi2wiq 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 zcmbtWU2IfE6h7P1}y0hl4gr!0w8Hk>LXj-RFHh8n>$QA6gcktRw4dF?>}j zPfZmv^c2&c1pwX0N#AunHRYvPJ#fa7VfZq`@TE~x!=io?%0_Gyi%!_{(3olGkeG`k zz|e$=CF3~w^CQb*7@{nz&&e|kCn@iwp2Xa_FEc?LIyG-uddm;`NgiNK?VDt1aE}>3n>{q2U}&V(yk{s= zH7xE!h!UHh@~E=KOzk7f;*lV9yAE$XS~gpGr%Lqa0jB1+X@3Ppf6-n#6%_r&1Md}n zzT#p*&1~h|{5EZ{=FB1ZbnBnx$KUoBPkMF?CGB;Y;QYt0MjO}OmwJM7pYgL7Vh762 z>bnQ8U8+6*UG=70FMa*tyQ_nz&tF*Ao-%{g&4f#0KT$ehst+3L>R$Ky8h18t^ai$Q zrCPvS>Mt$x2LgVtZ+EoSt4HGELvi^=pi2Z^J4>K(XEWr1D@mNJRW31KZW|1RqIVtJ z4X$2~YyHZl%TBp$euMZnkS_-R0@A+(?&dOmKsqqc}G6)(vkt_)5X=bMW?o zyCLM@w~O^{4*pHSOaCS8{oL@JBm|my?-qXK@V?;vIf`Si;42(_tKgkDAb2&tgigVC z^FD_-0IX5+A)8y#z0uxotp(a5?F|q=($x|0`~A?~S*q`#wrLk=O?73|R8kZ0^ESZS z&Act;?G|eJkdI!YX*o3&{4+K7@-m3_c7q{I%LCxK_t3KOg~G1@$nql!PfxvEe@@|7 zD*QJJPj9MRpH_IvZOJbe7nSTmg|An5inUz7Tj5tLe5=CKos#Q&6@HDvf2Q!1Tk`Io zR(RFlGYYTzJEHKazvmQQ^*62X&nWg>Q+TRT(*9ctub#^r6fl6t;?|(>R6V4geubwe zOY&zGex1U9{{;Sy!c*KR7KAwmFZEZ55=NiZ^L{!t3J9hzi)&ejtF zXI)y)->K{ao5hW#_HbMTjn0wwk#$zq)t3b?!k@*MAmn-p=X{gU>69OL5&|OKvj~X& z7o06XR^D09o&M81L^|p2F97`{06^~oGUvbaqd~|!_vsb#B@TIMzwCDjc_+RS@=i!O z33{LCsGR +#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 zcmbtXTTC2P82*<_OYP;yDpI9}O|)hpFzg~ot8%d@(1g%P#4tJmw{%w$xh|tn9|QzM z5<%=+UyTo@Ph!%9#H8${sa0$Wm6%r3L>eEcFKs=2Kx4Y*pE>`|VN#5V-^00l^WV>Z z&cf&`%?%koA257S1Mbd6(=K;iXD{mjVIM^BgBWU;W)g=|snlrv_rmJ@=)zI_=pF!6 z1B{L0^y3)-I9X3)SvINS^kW$S0&|^RSsbS;6{2a@<|BCf7u0SE%*`Vufw`5=Y{Uh& zXUz*NiLniV#n%KHNrA?bj*z*5+GT;}GHUCn{VC8`N9}?@BO$Q;qCn$Xt;sVWUu3z(pK$HBE%|vp(`apD{W_XYV zs#B@d;o&FPn85Z`EL(YRm%#RT5)119wd?#5wRM5Ub%Dl@0^4QMv^H;|wkFV66=)uE z((70gXwp8Bj9}r*0M(!6P1WM`;{8;rsVmVmYo~$Q1{)V>mW)fpAsSo)fLZ`p8XH_V`u!ir2G8BSl6c|lB7LhR z*}T@uZ$3R+Ttn#t*eyQ_jrH}<`?bcFwjzJ9LNC{Y{_;S1Wgr*~__fyXNq#V5&-a!9cwn^$}c%`Mw@r#DJMd{lxI1f>00{iDmY-Ckg4#D zr|iWJ-lm~RUeza*N`8+$yC|3Z0hh8-C3&tX<3-7HzKoY7&*#Hvko?n3NHj~H&R)f< z_GU-AUX0fz@8svg1c3d@d8N-j+!-Dji0EC=9qMTSYq-BR7zjX5UwP9p8k>)U-drD~ z;aM6gXsDv$Fb$P7JV!$?K;sb_%I$p+$S_9`kPB)#>e0Vb4r&yhdW8Ao3cp+7o&3PI zLube56jtPkV>`VHPnVzh4;6l&!k<=n>P?ovs_=BC%->LW>SE^qQuv1zzCd1Bs)NcG zEBt;%zER=TyxvfFHLpR1SK~aR@KiUxXJ071YX2*RCwb0mQQ=j;yX9L#lj^rX;njR! zQ+PGsZiRnD@jI#TYMnpXhCie5s$afG^jV5H(1%X-TA>r54_Q%X?&eiA+!NBR@Q4Na z$&eKS{lw4^=+S;>GNWav|F>jiB`J6=!{plfm&bj!1p#$t{opQG6;mexB(a zr4@u3{X_3P`)8hV_nsXgCjD>9;?UbezoA}z`fYhosTS@31pq=^C<$+^>8*H>eoQ(V JXT@#w{{i#iK^p)7 literal 0 HcmV?d00001 diff --git a/src/openlibm/src/e_fmod.c b/src/openlibm/src/e_fmod.c new file mode 100644 index 0000000..285da8d --- /dev/null +++ b/src/openlibm/src/e_fmod.c @@ -0,0 +1,133 @@ + +/* @(#)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_fmod.c,v 1.10 2008/02/22 02:30:34 das Exp $"); + +/* + * __ieee754_fmod(x,y) + * Return x mod y in exact arithmetic + * Method: shift and subtract + */ + +#include + +#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 zcmbtW-%A`<6h5<>#7)vYV=y43ka^gIktU-nNt+a!YSlQxA|+MgCR^;PI~7t_yE_3b zG`g6i45TQue?(tO`&dGuZdFLNrHiq2BTX@B5;WFoZ(d3hGv(a5H*Tg1g?`}PIp5s# z^M2#Za8vYjKv6(Kfm5()ZQ{$Fo7Z*xvJMbJV3~MnqQ1>SeX-rlEopBNG3!j5xfLyY z-*w&L>~HjIj{dHlyp7k6DF9BvYQan2J1fpK!}4gjl3{sISY4v949gqCWmXHOrnv1a zFjU*ZWenAxuv+zyp&AWWTBsMYe*;XE;Mh3@Ap01grW42h0D$X(C$9U|XB)2D6uFn( zaNRGo;ghr?;MnI1@RAF`CA|D8&!_I7y!FmJ!&re~EN@u`9=yzZw8kye8N>J^3#%XD z)t%&y`mE^`EIj)H?J;wU8pGJEWnya4LVbZ@$1e=y^A_q;3}f_nlVN;@VLZoMvQW=A zUAbphHad&B#flvO>#tK3itrc1*w5zZlxCs+?fJLsPe4INeIsq*4io`HN%b{s9<@IJE-w+ z86R(O^5S7;nUZq8j8MQ`4tF5U$UK5GbX!@CCk7g!papUMKRRE;`paB4hxVg0*0-#I~C!b+O z*g-EkRESmi;0!2(s&ZiOuCj3jpb-FG6!%^#pYxI57m_%QFe#4 zrch;lNPQzzX6^}$><(%5(vI#C?puQDDTP1Xt!|b)t9BD!F#c#h2bEhz|BM9o1Hitb zIJ^e{H~^&4e}iVW6%WbI-l2hh+vo-(+7O|iTHp*=iLMM}-cQ>UEh<9Ntf`tOu7~(G z{FLAW06^oF`!|YsiY57Kae&0_D&qH30017Rcz;yz{{7QMd~uz3w&7_mGQQa2!N?5t z*@-SNGIrWqd*xL+`Ch`XlY=%GJqbGjMpq^SM!KI2qdQ}tC^jN5gVEjJ*OyG$V5Iu( zq|w~kel%kzx-SU(-PA>6Al*NZOxr`?1yA;NTIobzQq=N4K>g8Z{R;BlY4A)p5`K-4 zo@mB$zr+b4)q)`Qiace)t`zHG!IK7xaluar$mdw%2mp`i-~M0yBO?Dk8BkzA1eEnk zNL#L_w(%bk{{DGMTdwrnP){{7fxx)%ua<;>>|d_!!rzZ?`~&g%OOS-H9_(;2Y+tDn + +#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 zcmbtVU1%It6h5;_+HIQ7*~Gs*~HyZ z62WfPnCe0`J_^40;6opMl2ZDRf1+)*S_=^?q@GxuhvV*;Yz!<>80 zJ^$y-Od%FO=u;GsP~ZTRxiSJ<%IAoEi~xcP#tTNmH1On%@jQ`>iD+r{aI~~oT;iM; zii`AYANeWpMY65 z-9l|*Wo?afJD=ih&I<(`o2FcD0>G}~Dm~B5a?Zo!CT1^~m|Zo_M*(1E2j|?WgJI_! zMR7u)Heno{!iEURKPyfF3!ZKOeI%oXnd3>R?p3`Ni`t$eh`IaM)y(rze~ z>PA~@>;9nD){$rmhWF{sdN|k|YJMyf4u^u;q0I4Md)g8gd!A?ls04r@0MNFybtJ$C z$~ej7JD>=Dn}~6*pvvoqKp6}uJ8QQ3-&X)q0Pvu=d(8&`Eo$IBUyEA*Zbh3KJY9KE z)lOAK)zHY6!)nC$TeTXBs+yq&Th#g%HPE8^pWW_zu38NlE@@2l$F{p`+W?ejCH!i4 z#EXjcD$1y_kM_H97iw+J^^yzR4*+#8KXz>ZK#LTRN-jLSi5xP=dWQ!3EmQ9SJ>D9o zM>9AgFw@<66Y{U*EK|DLFAg*d%IYuf;F(S29|}3OzQUz{#U&?S($60*KU-b$PsHHK zk6V91$Vukbe}oi;t~*a-6FKb~fv$y$13f>~XQjJA&s#Z%_R3Q(b0V!&s*<(6jwkMsMp#?8#f{o|gsxQubASAlE;T$yr0- zIM4JRGjr*_jL7AGfa;@Gc{j=VXTbXYNO*T>r|6~Bm-v7h4*>H*KzmGa{DQ9+bhnVx z4!H5@UCk~-jCCE43ZMVgJ}lzbt$TEE*0m3Ah_cq{flchkg}t|5l9x0t>_hG#0B~8@ z@Ab%K{gNhxy%+pn_K#MG-j9E%i-vmhlJk>zL&W#mhlKs0R21;q(>?XnyFUZslPC9t z_NRJ-{h>a1V-wDZ_~Rn(4)M>B@ugq-Pk48S&?^SrB +#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 zcmbtWUrbw782@fT#|GY87avGww)=3RTUM?uQRfUw3x!@2LK=_+*&kA%mB64AY4Af0q6>e>eopU0MhyNX8M+%AWnJqp;K=n8)(qlCy1yk#Lal={HYBs zqbG=4o?Q`V9|wdh-5fw6pL+6lKY(y$3jl69GN$>>wO>uM&9k1`J|Y6lG|z7dpWQ&W zE|OaA6#-JW@as#j=n3MDq|XysSBO_{BDzAHC7wcg3F6dU7XNNh%V?|mqk<+}`U}vp z?jjhd6;$whKM7*!xIqxcxqT{;&F8cgZO!-*HSVr! zck-*+ZR0mBXWZ6u2G-`DQLL;=Z(s5Lj%lJldBIPda(YQ#DvF1H5a#~eF-^Szi|kAP zjIGM&Xn(9y6}zdP_D8ubZdx-dpUTk+>etB^rFMBM4j24H#PO2TS$XM!nED3*k`wLo znTeJ{p2kygB3#YRXN0SnxvVhPh0!U*ncBv#=q~b0uAu2nq1KrUt70^ zBDp<7cY)T{x5blz&Yn}E=XI%3@`#P@#y8v^k6S$16&@1hkV+34&YS|M1^^KNo&$hD zXAd}l%OH>4S&q_G)ci|y<)*uUn{;x=>JHT`asUbdyiCtdqi_rFyzKDt^_QxAyf|C! z=cChnlI!3Xxr=<%vA`#}DSpz&M?X5ki$1>I$2(j28egsBlS;a+_B}qyIWAa|jsTzJ z&hd-f03W5Eo(9HU4Uf#HPXMaQS?!|E+G6&5@ge{mt&q2J0)Tn|aPAegaQpy1g!_l5 zqT{L}4T99s>VXmkk*eiTWnfyDBl7gKd zp?qAhJxu<~3i(RE-yOimSwY}26)8cAPmQXf0g&Qqth5fZT`a7GBsDy#f;1FTLm&;r z;~>Sxk&p)Cs^?9R2FFK7!(%E)W8-RA3Uu}~#MRK?2&F$9n~ + +#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 zcmcJWd3aPsw!kZiBUivw2ct$s60pT)210lC2ua^SfCwQ(2$GhN5Rx=&AS4k2q7b8i zC_`YLih~Q!1#um=anw=L5H=Mtf*^`w1jMi?cwIoYp6^th>OK@?{_s7|_tE#(ug*EO zom;o6ZkXLKyMJg%2vZWm(pfMSl+itd_olctSqB!uyjlEyU)F|}m|OjR|LleJj4@yB z8OE5w=k*R{EY0taHu>D|8Dmx^wNT zCb#`b>Uw+@x23_ompe{byzr#OJwI4H|CpCMzO}gLu*LHac)8;{%I(c6hmCgExaac0dAhHo?z_DkXG)ysyYMal`XJws_$Ni|21`^z!IT z#?ltVb}*+;O`EjuN|VpsL7V^o+wx3qyA_&!MDN8Q+{XE(X4(1ted2MLC-rIV-4j%>)+nBZCSj@v;)qV?;W>(#CN9}pP z|HSNRoh><$VFe4Dv+6cEyxg&A-=}?6Q6|}RitcCohj-D;RLG!gq}}+n-iP@Yvtxt#uu_4!TIz{>P^8ayumCxEAA39C-^)+`iT65>5zV^{HBa8bMqd(S~H?|Gchdrq`AzauN zlv&nvct8U#BML;QXWNaIoxg~%zNm`nD*SC0w~0D3_YWL7O-?8c*^S+Xn8}1E_sPN5rX~?>!ZZW>N^M1eIzq;Yhu`joY z?=s3PZE3gl=Izg!DQBjgd29PdbM(#Y7oEQQUuLP}{({i*dh@eKo_CyBagVQLd!Mmu z*H-)LuD|c@p2u>14HMh{R`I;ex8>~L4}-t`o0qn)9i3xtf9%kJ)lo0MS6iQa?(sEc z=KaeW-#Yi~VslTit$gx|C1&`nf&EjLPBZ!5B`aU6bo=_<*tSoXwu60Vb^_a9$fN$hB^0@Z>EHObL;x6qEa*0=JqiCXWqO$tapjI ztj*CrbHA%F7tL!4f9A?!lYh79AGQ0h@`aVyHy<9;)%Vj&|M>o=1)Y3-SK1e(CY@^N z)2Z-|G5*yJ9?v87WhqH!dFX9NuG=+zy?A)oN%v;wW8KToM{Y=Kx8E^wMYoK;e|fR) zi#kV!`_Wx_L%ksxC4ZWjlmA?U>Aki-{L>Bx%<`Y3(w`i>!Mrufd2LB~t+^**?Z}}I z-)45d;P?9**0|qI9htPdrqsM@%f9s^j;`}9&zl(?wfGye@|NZ&4*v6)S>DNW@6NG1 z%^kkZUo7vn++1;R%djKYKWo-*+V=Es?d#1W^XIi)a&WY{EA6qjSB<#d%wARb3Ha@M zZQzGkk? z$(vi(W3JiU`AqGs&q~ec^MwcYdCJVM-sti8(jooKU!ICAKIdy|_AwTQ|Io0;y`t~I zhAzcf<^vz@pAhy@T)L~<+S3!#ul1E(!@`F>Ho=VCSn$-WCmu1oG_38?&%3}h2YqsA z@$L$9-Jsg3t4*gl@XNE^{`!jB{C3K3uQZ(RZay{rw(p)e?RO`n&rjdHevSM4nZ8qx zk4iW9O+1y?%k^No?0=uTd|98|&#pe;e(D}JzxSc!`z3F3?{M#_`fhjp`WsSn+kdip zefp6tH@^AeVTW6Uvwx9$(WvU5-!&rBU*7%Tj=Wy~oBs2@5nt_G(aHV7#%&L@oLl6U zewy)mvY~F<`{mA}L+#K@^oh&X z#0=h?h7@mX*e26<1?MkK}HQ zUBMWOVT{3~J|Jf}3uPfbU}}#Xg6XTUfJnTC%pA%>YHT4lwQpn8hcLlAV&1G!##q>> z&~TgN3CLd)e4*g5$IeFnI`E8e+uYEM@Tj`5;o)XM+wiD<;kJx$V?evmFWZJkWr)Pk zcG-c9!gj(3Y{)@&fsg*-wz|+e!<}K_A#H`hz;=1^W>D~ET-$J4zi^{(JG8vKK>M#? zKf)XT5(x|RPEZWSpzi`e^Z{cmT=Zodb|vPhs~z>{K)o50eZv_0GwLf*`XFJfjluzu zXBANT#nMkCjZ1O{B8M@jGDIW{=Ae)}nx3$XCi_K;#2%Fj%uvk#A3fZKIGewm_r}25V(1GR_RPmqNza<05Ua zW{p3E{4I^cssj4Kr*T=%R052^}*9XPaiv`hx%khn8&{DX27xq7aZ$o3m-sRAg!imSnvD}Zti zIe8?7go?N^n4!gwOdBjlY++d?MKhm$k#%cU6)Ss{M0_5;+pfU#eQjJT$23x7| z$*5nU@oMBX8lQ=Lj>cu$V5>Af7xkBG{88k4aeh{^1bLLkWqS-3qw!}@-_-aE$g?#5 z3i4cy%X%AZw8q~=eTT;1Mefx2M&v0P--bM2<2#U#)A*;zD>VKE^0&k_D9y-y8b6F& z<_G0C@)k|sLVi-?r;#(QJ{OS7_66k%p=Yor%}-n8do^xDF3SnZb;u2I4N6Dk(k>`n zkk@GXa{P?IdO%4m>Mz&y6Ogae`0dD7Xx8~qbqD1g^wTV^L6PHXu=$#wt*D=`@g2xVYkW8IdX0aH ze4NG)B44WUqsS{X{v-0`8kgf_uo{i~QGbrcuM}y6;3y*j%m*-@$*?q;23+@u&ClP*<;3pY=;@~G9ep28k6@C&#cAUtH z6M1oxNDHADCp6=P%Q)dPUKA8BN{Sb@E^+UY_d>@d{J4Z4m+<2f{$0Y4OZpUk;-nvu z8!vL>g;l(;ikJ12CCbu;=LFeKQDTCyO%S#TLMK6ZNDv+pg-)W-NfbJX(u44vC_E<$ zZ;8SxQFurdn#m$JS>z@Qo-AyWg=VtwkSzQs3;)T|N|c)-Y*VCXSreh3Bs7zRW|Huk zB)laF{Uo8EBzz``vXX>tlCVt?JVkg&5mqU(ERmZkY*U2i6yZ5Vct{nVQ-y7+uuT=V zslwLflt{R6Ifb>$DNI~W;lhCU4;;=2l%HZ!pBo6DK=_S>R}p>_;j;*bb1LQkA;RH9oZ^oW-idIz zo|oelP526;4`(aN&l`kyCS0!DrJpW@uP6Gq5WbagI6G4Q)%q3s4L+AC{yEX_O85c7 zZzKE|;cy0|{G2De8{t<%fmnYyvr_uug#U$bxlWet?M`?nq7Q#vp!{?tJeKgDgu|cg zD1Eh`foyn|70)30F2V;A9!K~v!s7{7`!2|aS2L4{*+@%B>GVBekb8~5k8dgLc)g;K9+DeTUP!n2p>-P48q|Zs`MWqd<5YO z2#2#yrT;g=;p|%R7YVX9WIgmr~bl#JH zYa;#A=Y1;Chc%2U_hI6n>OV=im*}r09M)9IPZQzr4MOp~gpVh@h42Z4|4jHq!qw3# z^yehP+vAZdaQMcd%8ep?GU0Z@rx2b=IBi!c;jmUz{+~b&{a;7;tAxWh5vBiiEBsgD ze=5uUracy|2*P{#^*A^X?%X%3O`Kz)A%fd zO&ZQKG(M|a;SV6!<5qn)h5mtmO4N5y#npFR^&L)eb)NJ;XsEb4?_sf3Gs>%r$FSI{ z>PmSXr|v4tCKbn4m(^6W*wW(aVir55s*1%{PJsldyJB4zCsR~XU1LkCssj)buy-z* zQeIv*xthgJo>E;FJ0NFxkE-h8l8KleJNcg2ipnV!WtG)4n5;tCxFT<5aXGvu{?7va z30n-DRsy2F2d~9(P@;cVhCLpPkYEQ7r|zfp1$?a6=Z5Tfd@t}qv? zdn(azxN;fMbsy38gGyr1UayyGx02_ve7*m3(Y{G3qUiR|v=aZhuxVy2@ZBBU!TFN1 zSAT~A?a|8yiNOx`VE{l9)@`~yOt;z)3u(qb2I{9}>iq|2Qksg8RapPmWilYT{eJ+t C7vuE+ literal 0 HcmV?d00001 diff --git a/src/openlibm/src/e_j0f.c b/src/openlibm/src/e_j0f.c new file mode 100644 index 0000000..62258b1 --- /dev/null +++ b/src/openlibm/src/e_j0f.c @@ -0,0 +1,337 @@ +/* e_j0f.c -- float version of e_j0.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 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 zcmcJVeRNgDwZJDKc|?Ml8;TeNA?U5WP)KgR6C{w38xm^dDIbzsLNGusK>~p!1`sr% z7=o=naY2+GW&0~g|bYwy|n-ra%p58rdI zm2>9&&fa_G%-Lt|%$_tBmQ0C^h)^sMYN85X3Hg4woQK6crB$2?=zH3}8w>^;bA!QP z-pb{<|EPN?Pj4uUP|ERXR|cp;;aV(c*El-!^;L9zB`X@>(_vyveA*SwI^Tst?>s#+ zFI-8WP=9p#|F=Bk9qs?C_Pplk z(pMerf5XYwrN_1BkfZ%awWmE_dyYa8a3>u8#8;>Rm=<;4i z`ysO4!>IDV9ge8uBBG8sx|Boeh@<^oCZaI5wEqYcAgr(eVTA<V8&PPpnm6=}2 z*X1vF@bjB^TM_C8DDb!XjeCHfTy_OI>pA!JzlytWp~6Nh{$>UAJzX>I>s@yW2C?Gx zXA;(32nHJ)8%EIQPXSZjUA(?CL3_I9%kgWhu*e&cBWNk{vsYs-3jw+Hb1)1KZ-Bij$Laoo|RG+N@zG$ZCE zysQr{_0j%yN0%SM=1f{S${{;=$T@QFCmKquc~t7LMCpF0M9v>e3ow!_i!)$W1N zcWjdG4!{_%T_x@qJ=+8?`qrK|9PL7F|EoIrJ>BvY`Z(t3^5g3+D5XkQHeh>=%lMg4 zSA3Z}s(Zqh!C>rNyQ)tAGb#n_rue`hG)r%0-)DK3@ z)P9NP4%CEkSC@UPJ>8BjKdU`&^c3-UJOc(u?KyB?M<_yF_|h76OJaml%_sG}=ao{; zZF=J^5la0MBeHo`gi`q6IeNp;2>AUv5e}>P5_o(+5b8ufyh<*^4;cqqhr^?Uw)r>K z7e34PQ&_Zf4`S0GbaaUMeGolDMTx=j*V$_%e*?5_eR0)#n(% zvT?2FDa>OW?ZWE)gCV9(B_|wR`kJHt^w#4CyL$(R<2Ovh@5BYx<;S#Vf6tF$L>2uF z?lIiT-|U$g3ew(XqFt#?`?kjS zOg?-2kir9%L#A~8d2iu&s@D5fXFb*N=+B?%SmSTmzj0V|TQKa_N4vp;P+y!-i=23>e?-?)z5`M=-#;-54(yERS%dlbV;ml^A9HEEA?>hul{&_!Hd&(bhU3BSaj{v zbBnf2+&rcK+YyB~y>#ApWKolE)A0TU8}{wZ3kF+rw?FX2R{o#A1x{zUY+7Q{lX0e?;IUd(6x5VN2l>bs^aMGC1TXXlE`6U13eWTKqQWIZT=9+Zq zlc_6|YMMCV>Bn|&{EyEvk}`^NlxmvLUAW!*i#M;xcqH?)Y~SA-Cn%*RDb@7S`Y*4W z^xGRA$?YAL{Oi4uJ5wio)|k0?%vgY8Qzo>Z=z><<-)|`ih8;+E^D+>QA(*qr4)SK zMbl=fNEOirjMpF$bbSR?FqqB}cTHCjt6UMo2KJBH6rq$$DK(t#rAL|qFfXxsVz74c z5qlI^ew=GVWMN#w`hF#G-m(F43BEX2eq2mpY~;xSaS8c&F(bBQKwLs0mdj(&$42t8 zpM0#3oDrAUFDhaHDiy`fG=-bOg{lE@uEMyOf>^S=yufousgHw~yW20+D`A0ti485;-iVnKmbW5Zq|rl!NrS;4)s0DjaY~d zy(gA@;tM%li8jsOxxy64=yv*V+5Wn5x?ZoRX{xb1Z7C%DV^lMmNBmU2WnNoit zZkDTId58F>FhYS90X**(a~YCeEJdrWA!6iX;y<(a7sPp-VYx{Beg-7{aKMaK+Zm8t zLHuzBB%1h61|(Mze~SUhFyikrAQ?sc90QW?5&x6{$vEOLXO)shTnuF>ImAy(W%$t| zj`KGmka&XrKO-2(O~k*l_^rgF@En%e#A7Tzm-sVbRg?w9pR@R4;++<+A%4K(cM?Br z@ioL>xA;2Zdo12U{0|m?fOwn5HxoZ$@&6=#%;MXKSK~P>PY{Rou#_i>yDYw&IILx) z{GPbm;`@kuEZ#xfYw?4`2V49V;t3W%PJFnSUvBHtJ-fhis#Rw%J%qHrA4j9&*q&2W@lEHV17}yau6* z6faumphb$;JOa8+@uII3FS<$b8V^Rn+@Ub@8ub*TM^Q)NNYO`ONl{2)NO9<;s;N1d z>JD!}1uEv(1ytSQWdXII21+Yx>jP@FH=wF(76nYM0KXH;8GIEqV%DRu7FIZFGEXs| z7jpR2nCA!%YcA$y-D&h;ZOweD&>tZ9birX|&-!x&hqW7XUN=EIAyd!XtQSqaae_Ap zKU(l+!6DDVel`mpFZiQ^4-(w0+f2RR5&TJ^4{KZY|E%DU7-Y`#On9y#f_Djh$UU(B zQNdx2%>2)S4;B2B;MWMw^G~REnBZm}ZJrC(+U);s8vj8bavsc^1s@@}nJ*hZBL#02 z`mhFPKaUAMO7I*dAkU=B=ikHwgY$q5nO>KM)*p zLG0(O;P6c`|6K4ff`2VI{EGnV_lF0f_CQXFxl3@^KVd#p@Fc;n6C83&tp9z%A;-sj zq2TcCGhZrrs^E7Do+h}Nf0_P-92EO$7W$CWV*Y^OnSwtoc$VPX1c%%j``IZtj8V*Y z3qD@(=LLsc8taGV6G~x@j`?w+4}0LuPYFIz@Ls_u2@dlee!r0GV?P%Jhq07-zkXr; z$$}3Qyg=})1c!Vr`xzm4q2M;6D)j zL&0wn{4>EJSIK@Z3J$qU=Fyahgl?TCc%0z>F8I}gL(Y@^Bnp13;G+eH-!j%u5gc-; z%*P83IYZ_*3qDKm+XTN&@N&Ut3my<0a*ynPnc$GSW!@n84+U=&9Da*gf1}`#V`To2 z;By84so;3J$qS)_+fM8E;<_hZE!^S>Nndn(;^KC*n4!;T1wZPw@GI zn{9HV4>@f1KTqhxoP>Fe;FW@}5j-Gxi{Og{-z+%fgxUW#!50huq~Lc5{wKlZbDa@< ziO?TOOJ?ZLy9G}b{2sw8``~Mc!*>U{Yi|EV!C}tEyg#kupx#Eo-NeC<)KBR{|JOo) znefvlc#YtP1&3TZx95c5D+E6+IP68R{yD+x1pi8K$g#723~f}vbKNQUV8LPT%KC|d z%Xl6uIP8J2ezxF{!)HE~IP~)x!RHDNdn2sBMEF@P_`QPPCHOAEWjovZ@PAO~OaHG5 zF5CZw@FU}M0Bvx>bIJJ3?Ss!CZpY_Q!DYOi?t_0U{L8rIeI@V@e=NKo$DH>Uc|VRh z=Tmr}f;s0qR8rmQrS%o_RZ?AjtvOe5skXAZBB{P|RlQ1DSW#c0lIGXdsifK(xJX)1 zSD!8~VA;8#X6e$(W%Vj)SxtRqQqiTuE$Q2q73E + +#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 zcmcJW4Omshy2l4J+xfw4jEd5dZfF~?ZTIGzuEHWgw`t@D3Of)&V2cWZK!RrC_gBY{ zPUngeHt0Rc=|083>4l;7Iz{(VF28mu=9W*!%x=XEu-g!T9Nd^M}q zGRC|MeqxMS__85^j1Beq`Wbxbw~R3}gNpe0Q=1##MqN@2NDsL5I>)r>M|sA_vapN`_AM!=S=QCOTzFo5{5@<7=C2( z%#JYp$mH(#WE6^c~B;{Eq^PIhnp0zSAXJcHR>?|(- z<;GBrpzcNhGCt3C9-qHMX;uF$PJf5;uBY)jtMhoBFdibd(baG+Y{h2_&O)c@T6EsF z;EK<8p=Q>d{`kvjaxL0z^Kjd{S(6$)cHVC>ggi5OaMy4V{g)aUV}{ACJ;V8u_hd(^ zI!^3J-G{($Qesu_jyQ(E;)5HjUhr_+7k=vg!sPDVCeK#g>28x_;9SGq`$#@bNAp~} z4>ih~Bt2#}nmlJ8biz=_MpD0&aEqv*$*tMp7Exgjw>2sj5)PI6yr$!DO1RbJ*-d;| zlkEK)O&**c9%}N;jy%!f9(d$%>uAtQx7PIVP|EjT;e((+@w&!-#*ca`Ux_p@L^1cjO09TKiY?o-lJ z_7Ri2@v;Sn$SZ4dD+qI%&V{X2N3mR8vE&3_apa26=iwQ`N$cJ#vVZn)+bNUhoNgWF z^Z7jf_!0f(cn`PjbFFyS)$mQ&io>o&=ff6!36Z$qXNbb8tQ(puBrxF_j%}y&>`wUqMxO%_&|q@+A(LJkaZV7Wa8yO5eCA?+xlKseteITS(A(b&NOFCup%&X)5TnO(sU-oO{E}#u7?*!;0TI;Te0>j~WlgYEcgd4MU zqR;26D9;~Um^;mB&ljB}V{B@5;!sC*v_o3hfB|7stA_xImxRqMol(fj;78a!J?2ae zzUid#)-7wc4?1$msCnzXrI z|7HYC>DDLq=hem=J?Fi(W66ADYF!a8DHL%Kcj1GA7dD6I1T=W z=Kt5GZ(e-Bcx?X{$ES4LI&}QE_PHgd+h}##UwrJ?plE#Tf#G%^tt~JTV%B?vqZ_nb!qlfOy`qB4J(zD&7|1z>L+4$_a ztuNpCOGM%y$EN-8*PUU;=Eb4M=S-hud~)K2qs^8QNE;A&#Z}?Ycsst)?9wW3^W$?npJ2~j^ z*trM0jyhpHeQ4(^B^fP7#DRid{rDjxq5aXXo&BCS*1vpZ`Ikj6c^|BBPTf=aXK&q` zFBg~m=<$x)+GYP&eZ#yLYTO@y-|fK<`L>TuH`Z20Jn7w; z=SO>ep9Ds|Th`l~{_VE0=aP2rIy2?)hj$$vVLZ5R&Ed@lW9p~3^!a+}u^YWdniGfQ z%*!_-yhmL9`z$jqZ5Vmrx-H9$oqZRcD0;rs7&qf!LTqk~_m%stCtr+6_13H{YB;?) z%6mNRt*MKM$>b#+P2^WHpoaNw&$2l*a* zfBBY}#C404qS|-;cVfZCkKUY^YfBnGFTZz>^-rR{ZP%iG@0U1o&+OW9-4hepmg@S| zJ8IW-d9^)}|Cr)BJ0Ume(4dG}dk=3;TKV>n5Krj)Ndv3)A5R#wedy9>YO`+Nb#G$r zAJSGls5?)9DDajVmk&bLCayfqUX280*Ry3uBBypFARM0t;jTUSMj@8-VE>q<0pA+kiRa zSU|Nkpij^1Eo%cL?~BLg1~SIFObQILN*;}Ti{PsS2R0h{Bfyh`tV;uvgF+W|nGj@T zb`J_o4YDQ&Sw{5;Z0H^onk*8NdaxA6n0&G_b`0_j53()_92?}A(_Ki?dZf#pQU0C4 z(-NijaCHx|rh-!}`C5Z|cV*xEu06t7myTBPn}soGvkoBY&KQGk<0V-TN(09e^U#ag?y7tcGz6x@a(6yP$Vo2#vYk+8643K?U6LVil)&miBS@eRnm8m~nz#!bYwAa5fKY&-IHjmz>ZY>dWb zhi74#8sCk6WV`xpKk{ln5+>WlLOL30$Hc~h?dP{okw5H5!cHSE(zvX@g~5UuweLj2 z!q!p982bUaY*)X*QX7Nl*WyH`EzF|vZX#`AVH)p=+@|r~$Q>FFMINv5JCIv79*$h* z^V>k=hNhS0S(r=Xv8W%T@gX8jdl6~(3Es_LAe!`RVGnD5(nQ+AiZq^%e7VLSLJrRa zYSOQTt<$&%^_w(ajJ!^UL@vws+Zp7iH2pWoTQuH=TyFh#5joS&=NIJrG(UktXJJhmw;-4G@LLe_c1<6G zT;}uJZOE-+>o*x67FMnC0jO8w0cC@bZ_xCS$Tw+RURMjN(|984y&6wJzFgz?BVVg= z8J8BePU90%zeD5M$oFY{GV&&k%Q&;J7LCt9eVfKBk+*An4szB-wWPEK$SoR|^|vsq z#@C=eRO3$}57YR1$9QRv2`f+J~-a~F^{6pkp zG=3O)wZ@MlpRe&RkY{RKUOx+4uJH?~e^}!ek+0SG734)4?<&$3wocT!cNfNbvjFD6N2i#ZFvbRUq95D|kLrZSb;5^Wxpg?y7jqlNSW+i?hRZu* z#U?j*%(&F_ba(FX32DR9M?RRAn`?K<6`kKYQBag9DN5vZihZZt7aFJV;}m|J!jDt< zcM3mF=~MWLlzzm~C~-7Osh0j<~R;GSz;p-ynt=NpG!EbPbvRP z2#2?WivOALI|zS{@P35X5)NxC%8wkk%XYq#@Yjj{-w3ZK9M*`GpS^^K6RyUu&~EVh zR_Q+>`T>NWCj4%~&k+u5P|D90!XpUp1_ffh1`;mE$+EuxPWa74KZx)<2#2o(RJn3I zEd9VIHi{1>`oV;&`3xL}wJN1gCVD5~a(pZOM-o1s=%WZ%^Da0Hk7jHZ2H#Ssc7U}^ zRc;00@D5CIHSUMCRamT5{57JFCA^XFIKn?59M<5JA31)L^-3W81kvA1_?LwL2jS-l zA42$#gu@pns@z`*hdxvBZaCh8!>~xLI42y|{uJ*^IPI5SB0QPs_Y!^|;Z20YTB!2h zOgO9|D}IXbRKi;bhdy8F+Xx>)_+`Rj?NaFj;ez9J8A*5#!tW_az+G&6WTD zgu_~{;xUB7vq|wp!XG4jIN`8{sPt)sk0pE};jmV$^f`o&CwvOw>4cXNK7sJrgu^pb z`CmvltVJunl5kk-RQyT8-Gpx>{2{`(5uQc(>x9EvxAI?4_$0#j5Dw3Jr9VJ;F5!PC z9M(*g{uJS`macd!;gbnB35S=zO8*n#1%!9Oc@EsC@ak9T<@W`$KY@Nv@xDY)`@Ope zr~RG{ITTO(z41g(@Ap|m4`Ucr?i!+pcL$0;O*r-QD&a7uQu+qMVGUaGLxfKy{4>I* z5#CBTyt7b#E)!l%_;tAC3hi7%crf8J2)~{1Qo7e^CH5h6Atgql>Yfn z_z~iNCeaVac`2NKIpJfFL%B-`FX%*H-iiKkqNn9vCcJ|955ZSoa6XlU45^##jqxysZy zUKz|yz~{f3ALba~6Xq1uRQdWB2daFvg?j&1{$@OXm_t%i^;h{}EC>5EmccG#e!Uq~ zK4mbL0tWXuH4C2jCaqyq`DzPeir>m#2a6c&+O<}7{nZxkWyr68Z{WrJFz2JD&R=bz z4^{irE?|D$bnW9fzth{V4fE^grRuHhMJ!*>9|nsxj9v4+fu8@lPU62sd_vDU-lKy% zxD`}>^<4$jM=u+!1DWkp}W;Cv9L|}QO_{#px%D4#-vGvx$ysFw#sCO H>G}TwN~W^z 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 zcmcKA3v^V~xd7mukQ53rd!h(9qF2RLP-^Rg`nZB5BnWDOV1t$VL?WL()iez7@=E?7%QTmqHWEv=yEPD<_akiMM$n_9uf|RSLTGn z;oSO#IsdM`Cs(d6h!Mi_Nm~Yl!otsRLE1*ryZ(GReZE8oD)7mus4hNfi`OwjV4-WK zOwNt2Bvc?ze*FKtCK+h9q%8+lCLP~cGI+|8fzPDls3rYJEEzZ^9q(Gw|1V1h-j|Ml zSkiyMl7Y7@uk;_3j@K<2*e4w=Ug_8ei@dN zThgcZ*k07wHb6Rdmd}-|E!jefodmL_6oPR<8$F~2(O#c@u4MyA9WUl&%eGw zc{NMNp0%wFN2tPV4QHXk>WiD+sdF_o%Qe@>2=N3IlWdw1BSgblAw*hzi9XInjcvA4 zIAhguQrEJOJoy?Je%TtmpsGJwaK@{+XlMO9-;UO45+0ZUh_1X=R#EU5jdqslW!?Dy zCO+6M9W9m&9I*JYz@G%QC><@j_S9cKs-u7piZl4RCCgs5WPpCSKhCapg-l)rXJ<&B zYzDAou=)J`!|Qxfq|PJj>T9Qi3r7jdT?IwT{YfnMmPolrdXCWLUWVn4-2z=$<$qF_ z2dsUp6FkQL`f}U@Nfl77NyS**lk9PyZu%Nang6Dq3-uuteuDspj=jQ+6zHjp;|MIb1@49u~ZHM!{ z&G+}u?f31;oa4*4csEb^Bu$7_OtSU7lB+Ml+x-Ll2g zn)!)n`96GL`vdD9%e&&u7oKWJ>)G0Vm9x~GD=(jIJTnoH?!yL zyma-w&86W3+pl_JY~Ix6e|g5U_2K3(zPK`f*r6<+b5@S8@a(euXU{y@l013n&VExL zY8h;IH81}1!1iL_ac}C{aa)CG9{chF+c+V_xYxg!u;|U{C25(?)t+#W)dHA{td1;Q2;n0u2Jyi12Q>D$KGEgxojAakX!9oa z^7e_{(K~T~7e7qzgMF4!zg^U?F?L#FN^NfpDe6@`&_qda(#SsQ$-bz$BDNB{17jSI0_*ql20=H7v$F)KAqfbW#mwM zyp`jJc&sJfLgcz0b-RUpfCg#{$#sqDwwSz^25PsFCupFyk{r$%-qdg?Uf4MbA=cvO zc=2b$*OM0;em}Y2@CV5&41bh-uHl===NtYMx!NDm_8hr74$<}!`K%~m+d*Du_%8A# zhQC3s&tcsTke`1M6XKubYQIL?d*pXV3EL6!`wZ_Sf57mQ% z{AF^7;VtAY!*`SSHGD7m0K@-5KG5((lFu?+lKTw5oV>{JE6FDrel>ZS;n$K^7(SAGuHk9qb%tk?FEM-^ z`7*-`$X6LYk^EPN|AKst;ePU88$Od9?m2l2k>6){75M{(tNXHevBB`$G5#k!HMR!I zv(SjYll*bRe?$I=;rEkoHhcs5Hp4fPHyi#W`JWAchP=)27s;PCd2`{-WXUkhdHDQLGS`iWq@|4I$K6KnQUxR*fahcDx(^yc_?z8~={ho6=LQ0ml;1 zdR% zF5(gfU=B=y889*S$5hxm9RpMGt5p0h6+5J=9vGOa)}taZXBw_34cC;W(qi88~bKs-)!ugjeWCK3}$e7~irOI_@iFxjj z2$kPd8xplQF9?a*)v&avrYG2Mn&M;T-U0AiDbfSX8Ra3j0Ih<hI48gHriE10WsmGb{!uJ1o#y)cKN^DL(8JUEQCwJ&E5Pgk_7`(>5?D(350d@}R< znL|zLJP$L6xfAW1m=9vE{|>_M9L)SB77t^2oo6R=c&w%UAoFXOzt0@zY;^oF<}eqe z{WIopPHF#|IXuGG{yp>I%zMHH(f))vB^_^L4s%7?uVC(EK8X1!=EIr8+>y>x!5q$g z?dtwZ9p6;ui&;F(QR(>Q%weujdlPeboS=Oj^GxQyWA0)8pUh!yP3PIn9IjE?)%}$E z{iB(`#NvO>d?$05qtkf~GKXi^+K(_F%e;#@%*p9^i#hy14((@|!?jdx_$YY+s zJfHdH%wf(@=edeG%mr${hWU8rqnH;m|2cDhJ$Z#W%rWZx?=pwK1=^1?zmE9{<}f#@ z)*{Q|C`%4s)W~hcbu1W!l}$r!gPR9Oevl z{AA`O%x`3VBl940n2XhULd;?AQTqbs0p_g#JryQ&zQp; zzK$Qtd@1t`=6pX~M-IpRb`~FG-oQN6O`bcL!!sHEdtP99cpbjZoY&i1EDt~Kar9u* ztk3o2u-|wcKHiN#!}9R@+*wz-q)s?1%InI7^QPKb;jF2K56;=Ob?N*Aj1p&8S5;Lms1wcw z)peE5!YL&qYwOBq-$I|~ELiMZSW~^QvZijSP{}Lj&J5L*SHT7A|JYzZ!7VMFo{^^h zuc{D7Y5(d5V=vxd3EMv){`xud#nuhYMRn(*-vJ-tdT92C@-}M++AJ81!<>uprMdrL&cO&# PjsD;Fo%B&Rv;ThsVf!2s literal 0 HcmV?d00001 diff --git a/src/openlibm/src/e_jn.c b/src/openlibm/src/e_jn.c new file mode 100644 index 0000000..1a53965 --- /dev/null +++ b/src/openlibm/src/e_jn.c @@ -0,0 +1,271 @@ + +/* @(#)e_jn.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. + * ==================================================== + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/e_jn.c,v 1.11 2010/11/13 10:54:10 uqs Exp $"); + +/* + * __ieee754_jn(n, x), __ieee754_yn(n, x) + * floating point Bessel's function of the 1st and 2nd kind + * of order n + * + * Special cases: + * y0(0)=y1(0)=yn(n,0) = -inf with division by zero signal; + * y0(-ve)=y1(-ve)=yn(n,-ve) are NaN with invalid signal. + * Note 2. About jn(n,x), yn(n,x) + * For n=0, j0(x) is called, + * for n=1, j1(x) is called, + * for nx, 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 zcmbVQZ){W76+h2OhC}E(4((X9BE^;5>5(laVNl4VLL44o+6)*Z0{Q2E;UpTg|alJ>=K#B&dA@`P(lM8dt_586O5OfGNhnlR7c=T+u zIWV!Uap04idS+*+CA2ez zm2mSTiT9-d;AMMS>-|GcB~2DsSD}~O#vSVycQZm5^M~3VyRp)rh%)=l=N8MY?V{WFeZp6aLu3o{Nw zU$t1`aefbB)t$GAD$EqCGHm_ILSvX=>yU-UO$&|740l{-82OlC%O%UirK1PS)5nXb zC!+pnTqGSkp;>7Bjn-$_^1g+}6scc0_^~#rB`nNbP=Z$Vwa;=3I%(PvWQGB+6d8UsE`@C)9!3Wg$Q zlRNWq9?F8ayyax8-oB>wUd|H5&#?Rm z#Zul9FnC7yq#eC^LN+E3S-wbhCc4m*BJ0yxO5VaS8JR^CZ{Z4Cz52? zno7TT$8l&Mx%AeqN!B)zCatA1zJ)K{6!5wvEKq=#-F=X`V4*R=uxi9kP!Hc>7#U&M zGHRi5iFQNXWbeiF?J2RoDavo5af@rr>HTX_rT!^~k#h`r?S~k)oaf}DX<(r-eqe#1 z^(BU_Bh-?2(|cwp7#_b{Qs$QFe0tjyZN@CKIDO_Q5YdaKg_mK=NP6-?jNZC$BMZ0l zp`fgIV9Ieqr_6vS{p&l9qZDh9ctV?ZEIja!fw6G%fBu`}1D}_U_5F*+cyh9`bc7Fa zeC0L(l)i)U4*=lA4LrF}18CkBwyzo|96Wgy0RBSL0pq1KeE0s!p)6cLMT$Aj?&9x^Jz_$X&&c~ihkK2E%*f!MF2e)-&MBr4`7d|y-7 zp3-KWGR8AIQ-dr^x6B0^im7bhcZ^Z6^8Myzp6#jPHTHyONh)3DxO}C28MY>*Uf3qT z;#e}>b70^|U@_m&*|Xs8T}6E%K8}QwlYZ)egYl;wBAcsBdyY@zpB)J-zS5wybneG2 z|Eb^MqKrsOL0f3H}4V#+516qPG z`Aw#Y_foOYBjT>TxD~WRKJC#3^Spx^zV{pi zQ-99$^nBe2>Hd&j(V+Vpbgx+!$wM}lne%mHouczpndi+srS)Y1VE`BuYcl%$IHvph zJt4iqE;99c&xl?T(tRP_+mJf9N3XYw`aL^zZ|d9@_t~7USAtCSNjfBZ%c5W*)Sl!)JR;(q3qfG-De`4+$OgMXH|H73vO zfNv>))5f9r$3#gvUjSfx0sS8rz@hWmy!i(~2L}{|yDF*(UwZD7YHuQ7XEq4eeQ}{|g1z z75q&FSL6Is0sNMNtNwLLRIID|?-e+OJ6~D%+k)Tpv)bRK3a;{Da{;_V!BszT1y}w2 zQo&XI-w2%Iq!eY{dc}y$kMmUpSN)$6c)p+CDmeL){{O7_QF;4!MPH5QQw68PK>FEC zBoOtdKY1nIq2P-YTyqbAyYgD3;A&ng6Qcl8GM z_jK>??1>!)*LmljXRV&LeVsDO2N%klN+oEM75D$D0ER@}rAS=Lqk>cUxZnLyfZtOC z0APVwN4k^eKAr2dz8D)>@yHLgJP~cp%J%@c&j+=q!-{;m-!D1wiuLpJlJU#?>H_v# zggtRs75Ogjjlw?v`{g-dzf?6Ay6U}I!BjbYpY%~m0l*MH5*^7$zCDGR&mEEkDFeVx W_m-7>{!y57*-JvblC^Xt-~Ru4GCoZJ 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 zcmbtX|8G=P7C&z&%Sgv}UbUDexaqJvx{pStQv{`MkUn^9C)wI1(ncl@qXp(ksv<=r3h-XS!0#DxCC8hTT{(-7f8Wp&VBdJT%Y!r z-A~eY=YH-z=bmr(yw~G9JAM<=G?38Xaj4F!7>`tcxAC8CfS`lb)$QQ$x!u;-f_37W z=XuAI?n2Z$aT{RdIG*|f0LGR^J$&^q0Dy&K8i2c`Vd1X;aGmr_eAT$_Gc;#*j$XsU z6aYxs!rK7g?8L<)v$3gUVRI4Pcl-^WcRYco+B5(M7mM!FI(+?g0AQF}Lpm86chl&W zv@;<(*PL{mI5rlz;p)$EhN(#h7cVnxnstjB!_>vr*}*cy%*6aQY=j$^@u`(0cH$fW zjF9c4w&!_C_iXg(y;izRYuE@3_Y@^p!bWb_=vVm#AzfKwSZBu~+GXxLL!&De;go^q zq~y{u!(ZXXtL9dns5pa*7ts8iVbio*3^B~S$1pX`FntltIW#9)X9wrXInVR3afD2j zhDf{Z)3LPRkUOt2tm}vw%;s_C5%t4rqhZG)4le$e zp+P$=Z2FdmxxV7N&6OEE-!c%q?oPeWtLPS*a{>F%EHO+?F--r50>dzU9-FxWG?&nv zeYw^T+Z@Bpv^%d2et_mAx3Pg?-BCKcE*-m{yI{xy=%NCkI;j>#oz08Fj`==0I9y`n zkuT$5-#kNut1~)c4cL5r;0eASVQ6susR@ReQu*K=Dup&ca{|rV^DDTOS40-c1q$&j zn&-*ZtL5ME%CUJ}a0|Ga^W}ASJkL69$3o?;-+7)A69}afpZnv+aK=&KX2_Cwz3{*!f zECV&cIR}S}XwHy~m*34Z9p({;@LGQDXsl))6?4bYoH>HB0fCpRL!KKB<>r-J=18?)NejFu5e#Z*Kc#L zhSq;nzMBV_*Ljg)rYPl-?pb3mzofo?2N$n#_nW?8Sa%>+BSMg}V>SGK)1`%xZ2&-j zZRYcRog**(dHb!j~qOK&*2Vy7N;YdZC|(3h+AsHHbpy0KjkCu@`H)UMsFPOaKdL7gXS z0bmP7M4T~12KMU4$&jr_LzB8;>EZUNgL?F2XpbJA+C@L?)w*F#>EYj!@G>AZHSmoe z?f_O)qELk&hm|~TDs(>KCG!K^%V$6P0Y_-y&y^4kto&T?%Ilfq7lJqZX$8L$yv&Ql zLxT6usiFk{?os^WxdMRA06)@A`1LY86=l#C!j5J5q&U~0+5qtL2LK(*?BBHv57}pW z`<(cGhvmwY^28~dTgf0BlLKb9$TQd&jF`rU(SKv76*D04!qF+oC8CB4h$t6 z7;162JzM$HzYi4q+n$d%1W%tGD-`}sg(sKfe)>Qn(0-~0$^TMZs36}ec+x>NB=Kj!AwS{opA;UI{nLV{K|S{)g{NAU_I#%Bsy+8n z5Ji0GF3J6!f)B=FpTetg$SJ&o*A)I9g}*6yazo8yL|k#=S1bEp z5j=^hdgP}#@v8lAEBRIPo>BCuc2bWf(77VC9R6FV%FFu&@!Zg%e9u0J=kf#ocu@Wt z$iC1M&u5S1A%37I-vjY|xg5j?`e_p1pUZDjCoPXae1HF;L)pGO#QXa5*?43iHvT^#zbRC~4(k8U0x%}xB_Vler-`YD&c=alU-#N{F(p zjE^rP|Fw`0_Ha3uBlTxGKOqm05D96Pa{=kU9J_^l5Y54a2IM8Egs5++HBU$g`Ji1g ze-g*U`9b+-h5Q-0Q6MOPWSRPz72g!{e5xPn2U1?v55*yPHlcx>0)S}|DC!NQGAK`F h8mt|{=VD_QpH(5_E + +#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 zcmbu7&ubGw6vw}tR$DbftR94V*pswk$84|&1*Jbow#bq~ZH}@`(rqecld?NPs|R}& zy!dB$^iS~UpW)S`HxEMP?Y_6W4vC08|WYhwiR6e6jXuHTO3Uzy)v# zfZy$*2In(rg2QLY=@wr&ulM1cHk{@9!r})9nSO`w>SFu{$lpA^Urc*4S41lzpGy^8 zV%!AKD4!M3_onII3>{H88tORKYJhx$&=2;uw}No5(|OiD2oJWlgLa7Y#c({-F+U0u zjyT8bJ+9@?i=0K)siv2KLZ_M&)YeLC0hOM`M)#poljQ5M?2>4tm5ELb)S)&Ss-LD% zgGn4mV*@pwm`M5E-dbw(;3c1j<5%h=nVdw4IYaItIu4H#9Y>tO|3UwtUee#H6}A9=k7WIeL&udr_Oj^k5(tJw9sF~h#WNsX$;Q+o9aXFX~4 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 zcmcJVX>?RY7J#e6(qXZyBPbCa6E#93&}2`L8D3Th5Fi7IbW5{zLOP&< zslFOKIcde!rI);3@8Xo=7RzBHI9%H9^2!r~RpNj;j}wv-jOfUF(y!qDW>tF(Nh zfskhK>!Ox=7oBns+@};Dv`n4mqL%7-NBp!}8Wcy8ORvtK3YNnXY1vu>AugAd29>ZH z!F!dOnW>9jt5WIodT;>_rcPrn)`5FqDz(>h25)O!(#M)oLd;bzdhG~Qvl<>r72HF zV(~m|^m@Hs7oGB@i&|<}Psvv z?X@ZmaDyC3cXapGB&)T4=(yx7hkSr*Zf zTvpN)*4Z+nN_Mq-y^zyEanC>KnFNvZYs<^p} zN*yP(oU@-+sr|f4ZNkJR`rTfmcK)t2n_tNtqHM6YT~g`vGmvk^ZC&Z|TB%>&###rg2C*U7XLN$z=Aq}19( zy8I`YCV6)A*raRYPh^8Row-9{hB&#XQ>rhEI^|FYG1_1nx1oDpSG7}aYfzbA8Fa^aKK07F+ZsJZH+>UP z$F5r1o;c^S!cq<53A0 z4Oy<<_r$Uq@ajU2sMLXSL`H*6bub0WA%~~H{~?$C$jTFgg-v&mlP6SaJMG!j zrp0$@`^>k$P-xjW_F>hM-E%LWnT~ptR<9QZeW!9=2^^Y~e(RAQd`U){6s~F(&!LI@ zxlM2qcf0NBHO^JvD9UF~Wi@8DDwA%mPH^Yn96A1y`D%+gM46`K1#Db7S!uquwsKj8mRn|M9WL_i~gM z)7Ss?(LR4v-lK0HOnvK=(z?%-JNNxa<@^3a54`-#Q%cf>{0mLDi+bu#)MTBO6=;| zmXO7f2Ru8R*Lt5zRle%$+3mH?Q(AuR`RZlYdZovqx-|nY)+j-*uH5$d;k5k;D{J?E z^1uP5$IihAR^_ZxLV6f(?3(a}l2&ph>G?6&l)O(L_|h@DRq;+Es~(QKs5pGw^`0iq07XBSou zn65bgv|-UhDX%H5>ZQ*%@2gSlZ}geC_MfMeBLDNzt4fY4aZ7h^Z{2%#D88R4QYSZ+gQpR&iJ>?$51uDI+pKK2qi^JhJY>@zXL7miSU? zbYkL@!IsezG6n^QMOwqHVZq^{;ZdPsVWGj6N!hc4Q=D$`Vra}DLb?({f(aooltxd; zAb!M91x)T44C1+mD4?&n8Wv0} zF6)|XvJ`h4Z%SL#(`1P^1;?8LN14nCCjaDK?w%$~G9w9$B=kzrkqNzgt-C{@o?XfJ zcO6z;e68pxU07>7iith?cZ7tHK8zUe;DLgN>fW%G5iyb!9e+&d7wPyQ!P9hnnBZE+ za$$=GVk9=5{s^I8uH*57&(!hJg0Iu@@q*9R@yUX3(s8@s`8qyB@U1$YEx1|7pAj5# z5lbF>Fy7HKZo$iCq6%3c_#PeSaWoRhRV-yfze>kf3%*Im*9%^+<2)`#vQ@{o2>lZ} zzD@8QI{vQUjXGW-c!iEv3f`pS`vt$Q<28cw{MF>J;B7knF9dJa@somEG#5-71t)$T zUz`=(U&k*BZr1TDf(PpOb-{ym{D$DL(!_FGaM*8Q@nh{Vin9+*`~}~kAtollc|T~< zSMWU=V$xsmDjg3Nyk5r#2!2AxhX~H&s!6!uO&VenD>&OfAQ>q*kDn$I_?(SrsE3)=kd^FiQqGJ`elO0 z>G*2FdA&4QFL;VhpU)RYlCR@igg%d-Cffur(&@h|IIpiJeEb_ptcI9;WFX{T)LHBs zObGeRK<=1pL25eTFt6$7W{`$X_~}kK$)1s$>SirX-^QOs>L zw_8?;V=0wbHMyYb3J~~yhk&?G0bBO^A*FJ#7HST2aONR` z=|?aR5zIpbvyEW35zID%HUd4M8shkD)~6Xdm=s+aad+b z{Vc?LBVLF&9OOv-7ZHcGq~xm*r-*Mr9LAf}e+%&d#CIZoFXH$w~82M|Aucz?u?BmN-b=MaZ| zm-K%baoCGU-ir9chX!5lA1m zYZl@IPh{KtI^wS^l-y%K$ zaX1i``q7AwM0^zDa5yFPX9*7D0_W#4qz~_;{yM~Q-tOwePhBVaUvn9+N$IDp6v3`!=&{jNt=OcX_hcd)*99}^j4iRNNw;&E@Ka%f4JOS}a z#NlvR>enHjg!tbOPe%MK;-e7%7vgZ{B>mq&9L~xl{{`_eh?~R#B=igZzVt_YEYgob z9LH@U;^UA$pWXO;4rP=>Cx|rz2r&4o5nNQ$$MXe;wIbG^DY)EINk69qm*-uQ`@~u} zf3Dk^NvwtL0)Cw>?+UVWomO{tk(*d&Io(cT%`7Y=oEGG9!mrk>LU$}d53qB}%9}ek zd!CzE=jFMxt)nMo3@vm!vz`^tIrE;g<`?AUXBW8V3!mAuXSfQSbNR{Le=E>lSZa!C z%O~O>+_!I)BI70n)<6(CsV^lT7IB1-dRW{O!q(tWj_fCS-UZ)S;9}Y1lRt~R(2H0W z`vksC;Pcno!(0zOp}(=EV1>MADf + +#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 zcmbu9&ui2`6vw}_t+whG)}kQPLr&7F9XDG=C@B5GZi<90)b3Hj>~^{pH@hVnq1A&u z3SRs(Jo+bi^w03>(VGXMGRb>M99$9oTxRB*dGnpT_mVg5uu~HPjKE`*tCF)?Ip4^p z8(2UcJMSLZ)z?f4wzt>4<)GVJ@%;O;C4H~eY&~fDe$!jt(+A#;GW1~e;YxnqEC3I{ z1pq;}hZ@8ut1*Jse5Y&lK)l+6IBAHb`rQ0`flR+i&*~if2kd#X_;&ugEi;8%$pV1I ziq0O_0W`{O1$UG(!}GyIY%KwA<-CZSP0>n_FQ!Li&6-9;%pk zMTs??A?Mqa%OB@C^Q7CHUIYr==G|fK4fZ=d_3Y=qDM*^ePSRFlu?lV zG=&^Y;#iLjYqeu6%V4ign?y21Zp-^13@zFU>N zM^V&?aci}d^#O|g%x7x2CJC3xhx2)Z^joBJ{+W;`4&2AgT_8L2U*mo9=X)~je~$%% z{drucc$e3%KyV!M1i+lzLjcZbgL^N|AJZrQUwRP0$G?n!Hl=>w>7raGTR-c~{;b<= quD9h2`G27C3Vma4{H4mbSLH4FXMe{EZvL)LiEq%QMwM8L8~+ni?Q1ar literal 0 HcmV?d00001 diff --git a/src/openlibm/src/e_lgammaf_r.c b/src/openlibm/src/e_lgammaf_r.c new file mode 100644 index 0000000..7446dfc --- /dev/null +++ b/src/openlibm/src/e_lgammaf_r.c @@ -0,0 +1,231 @@ +/* e_lgammaf_r.c -- float version of e_lgamma_r.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_lgammaf_r.c,v 1.12 2011/10/15 07:00:28 das Exp $"); + +#include + +#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 zcmc(k3viUx6@c%Cz($C<8x^F8P1Go>!kWkCK_0ss9wtIWr69Yo1_NY+5)w=nL1cg! z62OW&)fu5f>!V^Vw&P>0D6M4^VxcWgm#2>S0BePa7Ufq7O87hH-gEXp{3O$vcATD> zWdHx$bI!f@+;gA1a$?nuNe+h~aR{HV-Yf}TVLb=bV?d+}mngqox_3?gNkp#LvF?MG zf10MbvaE0vVojYX41R>V939%{`ktg>4#xz%&(VeGu2q6NpZO8zqXCxBw%l3~3!tA&{U-!jH5VS&h77%9$n@nXBpX-ap80roCKhISY-J)D&a%^FTAXGqrsa9N#j8HTc4Raq|SjzjVC zh8_0~f%Xj7ansqOGDogn2Sv=dP!(J*R~*DlTK!tDX{wYB$o6kka_ed&BBko8%1M## z!<0eNecX`Ye;Bg5+mK=97LrQ34;V58f1NC!It>}7-0F|Vtvm$#L{9F}<4UgEb;dL! z<+9;hLxxXE_rdP1XA=Fd8*p!tN`bI!FEmY4b$p@~RZx4#GtBkSp5t309&3D#?$8~m z$0-dVLtYnaJvP9Q;a$}5|KqU1VQDqNkijmPPFUSwILBLilI5CRXHBzmy`HA#CO=T= zh?|F{yUS`?@Q5Kpi4HYnu)~m{KE4lP@51oWeViDJiUi}`VHk?;uH&6nO@bZAACFk^ zrFlmWkaU&FP}!NWJ_bnl5!JN;(bAjo+%NpH{XGYaHl1cLt*Nm>T@~t3c^QJ{>}Nd; zGYa)~f1HP|i)CpS%ijKYhap{w#5WRQf|=DC5Pfq9b;1_>?=oa~k5%{JzU~WpO*0Wc znj3UFxAbOAD)G~hr0GPq*QzM#$sZ>E?xgQv7=&~Vz!a$_nEx~x8Zykn65Oi?^XM34 z)x*y?glIiBu(ih_*G$&Ef-z=up)N+xfokRr?d-3oPpK-NvtaeLTK&)~QXfMrgndgx zEC|DGU-v!VLrisrTY8;&3w^SEvYKvmr+44kYbhAgH72n_P*lPn8#28f=A$k{hTek6 zbRRqoMu||KZ=?-6$v_PnwRGuK%vx2tH=j05wL~p3O|vZ~S5F6U%+cE8ShC3)pM8`O zhBdNY4RTehK1L=kUEP7xrU?z}Q&#y8$(vxia5RwJBIzi|4i$? z!n!Bw#y&l5Q}K$VlO>KX*OmFN`eoVT(WONbSASgOeQjXzpBu_bhHiYmG%{kdZ^8YW z$KLz()?(+;oh21F4=SsE_gLSM$Fr{v_~T>8I}x^)1`|oNs1U*!Si;-xM7D*W}`9+c%Up z$ZX$R@gjf8m{bq?`8@WDP zSWc65C;GFb61o1gWD0Vxg_KM~4*kkyrh0LTA`XQRcOt*l#v{n> zkzRn@Wz%1T9CDD$V)f#*5)* zQlFM=M*hBql)Qj^myN%S{IHF0MZVj{-$ee2jl(HV2&ahK_+OB#nVHGok?&^=Tb1Q+#dXXHg&KG%h+noS4^^3|9T;6hR9q z(Rtt$VH+QY`a0h&8Hs$Jg_K;0e7=plk=NU}2e}>xmUxjzEu^Fv`BEDXAYX3dHzGfG z(Ga2vxxQtvWGeEt7E%&K{*aAVBY)J!=OKUG#_vW>>k3ID@(lz~79;;H0hIfZZz6!w zg8U@{C~J^EMF3?z@>dCJ54vlrAhHPqJ6ZoaEwUPMG{<}@=nx3PI%L=eeg_7ucv-3AWZ zPvW#b10T$|o_}?@u-PR2Y&G6AhqZ{fo=-K0;~eoyrk}>Ro*%V7>@`XMPNolgAL5G` zPiK57;}BAnA{A_2O=izt#__=z3uBSZ?V~~Rx&rcuY!&teuG0x*ZpYcnX zew1-ILs0!!F%D-8;tw%Cg7FQEU&i>ejKf+%evTuzxAzRw=j|N{ir9~EUrTZ{0YXdVf@#O zk7E2q#^DS{ezr5t$L~JId7d0+9J+%1n2cY`xP+i%zrY!i^fMU0p79$P=ksbgawvw6 zmphm~oHfaRlyN?O*E2tS{Jzfg;qHn2>}1@-_=k+&!1!m3!`Ybpe9L$a<4Mp+j887( zX^iJF4!^pPKAe5Y|22%~GoH&hoXJVw$9N&*lNg7yGU?yW_*lm0Fb-=g={GQ5!uT@A z;Vyvm+Zl(Sl!*VFakxApz74rOAL2|Oz9an)8HcVQeu8nH=P7uV0zUY9aW!(7Z+SjX zVH_^{$p7t(^E_O_{NKj(f5!BAJ)dD5?pnzI7RJjN-^MuHt&n~vZH!(hfaXv3y!}uhoKb~gFpQXxZb03elhCPJqPJ0Bd7Z?;&&mZ`wZd<@igDJFj_N5c$%Y4`g1-# zHPzPFc%rpSqrx+w|D+!_dQ9AFEP~1ph zZv_2D`Xoir`9g>uI1C7(_Uup&rcL607xn_cahsHoHp~mV;I=p+u!e%q|JEMX81M=G z&1Ef?Z@({rwsL{Bv9I=LV!<&o$Nr<=A)xnl)ARDm!mvDW7vnky1+wGy7?YRq536rW2 X;!9h=Y_Dpq>B~Nb^|#*x+U@@h03e+= 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 zcmbu9&ui2`6vw}_t+whG)}kQPLr&7Foo=>@P*D1V-4qF1sNJK4+3mO$H@hVnq1A&u z3SRs(Jo+bi^w03>(VGXMGRb>M99$9oTxRB*dGnpT_mVg5uu~HPjKCw5tCF)?Ip55t zn^-^{yYC*_)z?f4c6K(r<)GVJ@%($TC4H~eY~64Ae$!jt*N5J&GW1~e!AgGKEC3I{ z1pq;}hZ@8ut1*Jse5Y&lK)l+AIBAHb`rQ0`flR+i&*~if2kd#X_;&ugEi;8%$pV1I ziq0O_0W`{O1$Ur-^-Xf#xDtVVJGnjs3pz3r_q+Usj^4^_;& zqQsickn?TI<&X26dD3l8F9L;bb8fL^t&|p!>1k|KA2KybJ|6Kb(IX{|J~5Do$|%Tw znnDgHajeG%ay&6w2HoCjYSiEbt%u{6@;I3s>%^QQKS3Ww&k_}Dy21Zp-^13@zFU>N zM^V&?aci}d^#O|g%x7x2CJC3xhx2)Z^joBJ{+W;`4&2AgT_8L2U*mo9=X)~jzs3T= z{yc6_yvu7>AUKYB3}DXfApmEz!MzvfkLi>DFFgq0<6p) +#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 zcmbtWYiv|S6h60fp{s?nVogYpupvH{My|VsS}@YBw$L?_hKG%N&8B5(_tFUM)^^p_ zAJztHtVuxw(Ns2o{1J!fX*gZ)<>XSNUbe*yr5li9hlx}m)# z#x=(ooRl*CKa$~6+4Cw_mbwGD@A=xHqIWg(ahp&VFLgM$_)S;L)n2#xc6hZo;@NkAhiURe=X3;3bYnd zxB}zZFZ7eLt75bhoLuK`EAZwId0?ZAN~n}<$nr{ zj|*&?)nh|Kx-!Xx4c6iHmPGI0JHz@0r!1%4!IU7S0xbGbqzNMrl1jcg$ zt)l~%aNxN7mY5Wn7#*|a`BVldTLPQt)GxcvlvDSd0?AZDI&s%lZs1a;&Boai0t3rj zo$_x4T4zMweIh3?F)lDMZDVL`43~qD?qw24KcpS*v_NZ>YbWs)>rL7i8f86-jr2#f zSSfz?ZGBhJkN+w#aav%4Vm>2%li@rz^LBHsOI?TpoW1^-c`o|=BfXWg>&~xllsFxA zzn|q9YU;LD|FHPtX!QGeN8fDS_+`{Ou;So7kDrJhkn%r8-#gqh;eUH9`f1O;WnVmd zELwc^t>NL}=_u6K);=5z)i*S*3`W+N6=oz@5w55VMX#40L1_h z1OO_}`i4d*0%L?Y^;Qku`}s^|JR2`=1*0cmEG=D7^11<%zni~(Uc`%k0NF2wi_XnN z=HBEn_i=A3;C|*~1xi8| z7WiPZhhHuCK8Snxbbu>i6a*W7PibkYtL<&cwbd~%_!$Yt;y%T`* z13;xS4*;$?F5cz%h^M+#{0WVx(}=C`sy)RwYy52* zzf0q9*Z3DSzEtD)XgqahWq-fMQ*A4re(VSoKWh9bji)!DH0zQ*hF)RR;^EaJlK?rqN`cYxWQ>2l{bwdzXkPMVoi zPX^4^WF`sbj_z(SyVA5VTe>rA!E8ylx2HNXV0NT4DYL$zaaDIF*|LlGJ3F2;JG;`I zsjf^fxaLxA&30F^J;mPtH|Sh+1$0&&?*BeecyA1EUt7xWK*=kF*-XA;|@Bx#aNx+x)Nk5%#}0Z;`wEiL59>du6d5XhHP^Gg z7aw>J +#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 zcmbuB?@t^>7{{OGhwW9`=Spc}S_!8q=1{xd($Z2BI1IF$u@WR9-WmiBxGmAbQSO?6 zMk%IE$_v^iZ8U9S`WG1AnMRG_KwCJlxnPWI-0OOlX>pd3I-R#|>?aev_M> z`RqK;JkR{v8##RRNS>yFlm@lnwp?X5x%E1`S_j);D_9YHHys(vMAE+p#}SPHK*SzD2vo`S{tM4xb&(MbC{t1R{b|{f+!zjg^rS}#FGYq41 z45PCm@${5+!I*az<6QDS=N1O1-FH~lK%wSVVS-^hxlT`E88B>{uyAGGF=@~IF-wC> zHBULU=6dJ38g`yb;t6#PEwziqYm?!h@@L=gIdUUxUVQS>o)_oC7h6fo;j7n&vc4-* z;g5&Tm40<%E?jW;gUgpMFN6UCJKvuDF$|qon|CyP6aMz2E1Bv`pVb_AW^MbQ_stq; ztgnAQ5NvE}tq2(V^-A3cRE8?6LWU6v1Y6=gfk-SRUhF+s0Z;${0RW)6Y;0M+l9i;Rhi&H7unh)c*w&m1h4jRU2x~laJ5hHh>L6;61>^N zosCimQ4c>X`uBSHOM(x1_$z{Udibk?4|w?Nf_v2k0L99>Q6$+=bA$gU;wy1sVdy}bH z_nV@9tpB7wFqjyK52l8}aTo9Hum)p&@!a_TQmJwXge^_HR63{j0_Q zN4d_l{&Y{s@g=8xyknCF#P~}hVY(Z3Y+z45H=3$uvH!f^3Ge*T+27D!#6K)2O2}*f EH#b}Kod5s; 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 zcmbuAU1%It6vzLQX6^GlrTbvoZ7|cFxUsd+?LxF$Bm`Ov&cc$qO?MNt*)6*x zBqH4eDwv1b`W6Iz);{_qKJ6wJG=yRWXWu$`67EViQyWjfzH;`Jo0}KC zEi)G{cm4JvX0NwacFlYTOvCzlW{n3B)Uz_XxOu)zm3cu08Bvh?IVJB?a#>LRuAq@M zJ!;S|+%D7kPc~zDL6&3^)KBMHip!_-|ZwSisvna@wlL^}SM|n1aTvfA;yC^8G z`(F!kmjvZ|1H1gSU?K~G+?L)ALGHZavM4BjD|qj+-PHx!GtKVKSG>CodguDO?+bF9 z3uW5#Jcp0VHI`}h3qd0-Z7-~s@i(vB&^A}wR_vfO_!~JKcU{eubuxvY|@D} z|3M}j+R;O8lg*f%uc?O>kDCy{V~PiUp>`|2DMV7d2fPb2I)I4(bJ+4ZRjuXq}E-Kz!lxNg--XN$I1n)G0wDSAcNr|WgtwJLY)(Ylw0 zJzAZZC{;Yzm8w^=b3?~IZwkS1rSVhcT5+P(j{iT!>*6IF zzagn0zY*r6QuH44edT=7_F8ic0UT2M$!En)eXsR><$Pq$xoGN+@{1~p`JVBZ|JC17 z@pnW5-Bp2t??NcGtahDI{?YHlPL(9V_a>B{zpiu2KdOPhBv~l!r}Z)*?^)FRxB}66 z>HXKLs`yd=$$#np>ffCIm+~))_Br$U^ZnNG_4)I9qOn;YDmbSW%y*h|FY3=@M$ev= bRR`tDUa08)@&D;T{y(VsPlc{hQU5;yfXRa2 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 zcmbuAe@q-j6vy8JXM0HdPC^q+t(-qFi;?yAS}dBtVZh$nRB|C9-WdYD!flBb4)3-J zm?$CAr2NsMsnOs+CjQ~S_D?m&+(9gG(3W8TsU}*DzoJPG<_`@Gy5`N!+$|egjeZkm zWRCWhKXm79jQ8 z%!dja~ovh8zc2mAdzi#dh?9((dTfB;Ni$#2$8 z{!ZbPP5&i^k6oW$HS#|N4gb1n;K(Y&-hC9$_?TMTwrz&-ITKZ8qFP{>_?}_ky3_Zr zP_9=Q2KI252Nx*B0>fSkbInBcCd0%{6V*Q%Cg|@f!#KCS!}v18KoiAdm?$!g-)?-F zVSL3z^#;Sl6^8Kw!vIg+NiLpem?)U2ekpgCVf-57y!R^;)n)Q$7+)k`6V?2@sbT#T z%?$dQv-#)W_=|5q&O~+5vBCOIO3hiaiNzelKIbQ_2Zp^l6N_tP&akiW+cFO)6q|Pj zu@0wSk2w7e(L;M@ciXqM8*`CwDwp3GJhBi;TzKg1N1j`YT<9VF7)}qGKE5`$?i2O_Hw1tO1Xn%$ zVZlQl?%4UD#lv~cf=|2&Wrg|B2SyojIsQI~d3YQD_CegkI|V=P;YS4@@^B|Ee+Ray z2LNha`&>G+RR5{;$*?v6+Odu>HHWBarsg0uPf~N3niguFqDBw#R_85u(z&h9eRZIS zV)lcgrxK|IfGv7xY}+1jajHMbXIz|CA^GPnewT}HxHvu0(*A%bXquO5Nb*J(ry7^M z*~O{$B!9-m?{@L$UA)G{6E05gpNuo^;(J~EEf=TSmi9lmIMuG?bazR#u5H&&%Z?9Q z$rGSut&GzT$x$YCDydniF$=W8q?H8iL^carCQTpOK-OvjZ6G~7oEot}8%bL!E!x%7 zl(murFN^P!Bd4{|OnNkxvBtp(mm2CfGs)qUNaufx)Kj{oxXw{3D+B3wz2ikfd zqM+nC)A`fAm-9=AxkUZF=zNtV_g#u&?&QBH@*kIm ILSFyB0Reo_oB#j- 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 zcmbtVUuauZ82{aNaot?^WmB10p?R<+8}6E$b*>YZ7CMcLQe;q;K-kQ>n-yJ?kzAn_ zTw0jm9=6q2AAHt5`KW@B5Fd1Of+A9ep!nj3;;e@~OvkQ#=g+-omrX=}knf!H%lZC) zCuzSp{ZgOfz`#KP@hQf7D&9}Z?IgBi5H&j2ITVI%&}Gj7J`BUKP3H>^@OFpZnQ;I? zWvTn=&tVvv>utJB4p5_8okPI#1fAaiaG^WGrUa!2*@d9=2(R5cyDkP>S1zs&{&fT^ zKLN|Q@OAgkT`L=`>in^#TcdhcP(}I?RQiIlHz>O}^5i+m!uIP?5E~wO1 zW>o%suFGaBZMw8^FAN2hI=vbVAC|exY?Q|FZjXkSRREPv#4!P^ z0hs1W0N~H$==+O>$G%!C{C4x*!j&s~Ccb@d{1bfi@dS!fQ!iw)#hKaN8E?$ZyIv-r z%kR&5UM`b8>YvKITn+RWdk^eZ#y0`T0N`MXGqdP}(_zlch@;P2)O9?rSLe;6a2C_f z(6-G3tB&HI*5AEll>Y&IWfL~S2VLopyvKM{Zc{Q|8)?m}HHPdOQrH$#5>H8)!a#x_ z*1XBj;2F(7X$TEfzEqU6fh#vDSyLPPG@rFe00%X%{KVi!tFGLS!vJ<#^@(cjpE%Pv zov*obaHps8EcUY)W3i9L^DGXq7-w;ih383`lM>Q^b~mcmJ^=jy?uH5_i|08p{Hqqv zvt;;77XOIFe_-*OE&d0K=N=h5zgRraqTz+bZ?*V-J%b!S&yKl2YVkZ9hObyW|0)=s z-v)#2@F#-XT3QIIC*ih&rdsFCuIZntx`DqKz&%wBs&G%XT5y{UKDcwOU<~eDV`0Is z2XO0+z;}x?vwK@Xb?$Y2K3#vqJ=<)Y^_#&GlsSL?M6Fp}@FV~K6Py>P%ssK8e)|#6 zl}7S?4axV5=)S=?4+Ve$T~Dq(Z_Rr%?}+D%d7dpBpJ}}$lJv9M=6}`qwEvw6M;+~m z?c304MQcIp=j=-We%1QVC3q9RS&LdfiJ|+3EQZlDI0ndflf0hML^3W@e}jhhpVWWl zU+Ta1kp54~e>FsX=Kk}0HU3TiIiI9&# + +#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 zcmbtWTWDNG82(N!CaG=ywO&%Gngz9Nf;sNS#KfXWAknCVAcf!_IJRul-9~M)b@vn! zL3aaLNQJcVNgqUCe9(yCb3x4RKA6O)Nwuh@g7!rNYG~&{yx@`loSEI}p%Kv!GBf9! z|NhU+Cim#bV>N~W1p|GkepT^$Lv=miEeFtyJxI~Z%a6Ej4s^B%;9b{sb2OJSfWk7( zH`f4yta?^B_k-)YN<2qr-vV&DcrWV~e`{HAcFiu#hyQpIr`L*GEwh(_Jd7)|SAl$g zQz=DLrG-W0*_`c}o4w4Mv%k9^0l7qqwpYn4(kpcaK!v{mP^4H`rMZ_3fOiFjJUv0} ztAebeAZrhYB`97jr%Y;{^RkMa=WKFxCgHlSp!jk*MXf_D7V^X?^4+=lQa2Vph}xgK zZKV`#|J-y{Q2Umk_==#z-&Z9s39>FxRQ?z|v zQ0PuyrF~P7b+HKlBYYh4FU0yce{Jb`Z)vFyKtF(i18+|E z-Tc{l-!EIQ_AM>7_hWc)@L)JHJUZ4Ej&+%xW-Qzp?d*=mV$pEqQ1V##@q{BcI(piG zIsjn+d`5;x$4~=fnK^YA4Ef!}83MRP&c=&}U`&UM{kt0)7Y(1kL+(w~$i+W^?bqRo zdp(ibiuWpZdCPh)UL7R)MxCt0S&!WT{&p!J3h;MHUge;0x8%7-IwIajJ?_y-0H);q z{VKX7e_xgIa8UC50z5a@@5;3plDz7J!V>`YYIUphAbI3O`gqD5hdDCX$-@IYbn(#5 zLoW{x@eqr8W6T>p(H?Kf!-HTe01ilp+~QgQf4V+SX*{1F#lNrde8v?2p~l~!@jq!i zKfOx+HhCb~FZWvUQH|#_s`!UBp3jcrhcy01jekbt`OGN!IgRH>O!04Me6z;Ct?{~@ zk2PMe!&e%w*P&M4A)a)3(s*5dNaJ<+r!-!dSLd0xrHBtRJ2UAdj>6138GoKot4#7l z!gP|;4$NZ-Cjs+lHVZS8<_~i`>vX{!Pft!JryQ75X(wq8kB)U@oy7R_^85JIDf46| zeKMJGX5gDkP8>;P5|c^k{eOe=;*xT%I{e>mRPTjE@EzFiy-TRbEA(} zdUw?Q<@>=r-whq_TvOyKq`3aUQN{)76x|5E?C9s2JD1yuUX{pa^a z`B(kte1g6i6ViWPCd_XG|8@oS+2-|1^`mUis7h2KSihTg(BCKjkDXD9JLvxnJ1O^_ 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 zcmbuDeQ;FO6~NCXh9pAwED{m5Hj9GY__44F7O=wRB^%i|k+w)QJFI~Kd8K?Lm}~^v ziZ00p-c&+n)T*tuI<*};wzd7ER%yZAg%CbQ&4&mCh4@j(qJj7vNeEtF`~jc#Y4}sd*yGv>f8!Uf?0umP)Ui!PS4XMVUmELomWD?F2D}XubaZ5p z!AO6os6;!fgin#85>5gPJiZ|ppN>WP@tJs2XTzlMMb5@Ilt!YV63q1hsCX`_V?~FK z6)_zv;{L|Ht|bpELFHkkQdzpE)wFKmD&{uvS(IplC6WG(g`TcR6eBe@0Amnrnv^D< zy$x$rbj3>|pKW?sN5{8FPshrGD!O8y@4(zA2!t;(<}Jppd$|S1&UqibUF(Sr=Y-F& zbb!X;9Bes}3Gmh|0Lbgq;@xMoBi*Oxwqw)ZvjAxD!f^neE+u>k01B~5%LL$!tU_!m z$`TDnAvUea1Sq9$z21iGl1M*lOS$)RB{(@u2;%Qkr zI?AR^!KO9<@M(RqzTCz>o7SFv1e+Gw02+-8hdSdaaDDji;ubgjn|<` zqaG(7V2ttj`?S94j4|&#N~TbDN#s06Zefg3v>Z~j_EWU@TJ?-Dri9N@eM++n_l9UjEOg&&fp=4(d4y9M;J>a zlZ>_M80^xqvWudVSjw&QeDOq;!8Xd~hRHex_y&0M5MxX&#m()dv2#wJHmrnCGlmcw z&hcp%wm3lpOA_!K9A#uy9!p&NIhic zq>hf8Xz51Hk-86E9b~QB3^tkR(lKzYxwX1N z8X^P3ItG(E1~2LuJfdTulX_96AM@`tqvxO6L9-grF?fPp(J`=(`$|(l*C9TlA2)aT zwGMx*&pD5=9fjC3Aq`;rHh}eSXLn-cbQaYhereJ2fIC!_(`;=2I` zC|NoctwTGa#D;Q={8hreEE6F79;K!d?xT9>(_-Dpw{ier>Ic5Om_K&P+0Dq$^BPTR z-(XK9ivD48P8*JWl0zO+Mi?vmR%&wlNvT7}K#z(pUB}>nls9~Fbqv0%V}PFyG-M&A$PDMo{g-t#8F5x#zjAyoXG_TXs)jg!Ocb}en5+knk~ohjKrMe7lKjI!G-2oNnd@Y%+irlXcvhI}%fAzh`%BqDW_$AxV|+%5 z;z7pfmPLg%bpuOK2m#=Q2H1AbXR|jOtpTrSCq?^hy7Q#J`H6R2$9u(}kCe?f_>dO> zmMyq;(Ca(-@X+|bEEc@OTh8S$y$4#q{ug5u)4ovsB7%k!L`S?+wd$C*Df|E`%H&rGLl zQT0lvzbYhN+&MdsLJi;q0E*s%h2@Y2wkR?44sR3fY%vyKBXnS$nM;JRgvBGWQN~9vw56ipVOH61N*YH+NdU$U`Yr;pAuCB{6*rGOAS z|NbVQ#CZl--IyY{Rd`v43|M7(af|5xl7;69zTU!T2)@z6dC7weDIpB`zUaTr(q9q0 z)xsAD{+xy1FZin#{(#`T3`-Ia{I3!tSt@wc!m9<}Z{ceM@38Pk1V3uw8wBsQ@W%w_ zzicFF6nsEpB%0tu7QRDpYYIIhc$T?=g#21?BQH{7#5)5VDa7UX{4)dm7XF&xKeX__ z2|mZd{~@^Xn>!`D1g}UTE_(!DX5n6Ipi$8O%e6E$xwF%~z->qcjgY3G*`r?cARFG`%Q!X|%L;*%xbBXRoIo!S4C#Hp5HC} z28rK5!4~Utqr@8|PAOp8e@x>67?( zr2Y>|JXhkC5~o^e+Fvd4sS@8J@tY<7qQvQLVA?q>aavlF+r$Np{HHmayg}k}|7M9# zllr$voc?WR+Id0Zw@UmKiOcJGNaC_TCj}=)cN^3GRN9=v_uC|Ho;Nfv`WqE@{ib!H zs^#FW57imptIVgm>a|twQ1!+TxK~z%s=&Rxz8>6lwbXF0s1MDN8+0J7s9m?Nx+Vnf zn%Ypcd%?o;JL^MLE7pkik82v->+5RQSJ#C$fnmIQ)l#*tYMpUe`M-qbN2OG3lTk6x zYx8_G#d_w^-l4TL`pi7a=o|O!l$h?A-{nHz zDsKyYtC)JGPzq5=x-7Q=AS(2&ewp(&h3>Ot)2crp^sV=It3LgH7%P94(P03oJfX9Y zLSpKh_t>$ + +#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 zcmbW5e{j^r6~Nym1frz(f~|tpnpi{oMdi$05{XrE`6hP)nu1lLcjFf{U`}TW0h1HK zu}N-n0j~nmnU1ZU@h{q$7N@_)u|;dkT?mMDlt`4Kf{FahX^@x|62ispy#4N8mT$vM z$2XJv?tZ?zZ{O~|_jbQ&3)bD8<8px#7gWJSZ9?{4JyEU}#cDusgZYs8V8q1Mcg=cp zX?-AZ?tuul?v9=0oVP9P7@QTm2+;12uJ1e(jhcz0X!Mx&OEWeO(BAfRt9-5tCeC(# zjL*FS05-z-0af;6yfzoWjC~CN)fj&<7a-_8Vb}fGc?bX&c685rc$sOL%gp8GBWbb` zi-2Ka9u+TryE}qKaWRVso=q~Gv9u)r!$3(s!_Yp4GXf>~hed5hon89SqIZRXl6;4r zZLx9A+wR4U-8lf}n>othwx{k^Bij@8V|)YWe4DCmI-Uc74}D9RX{3Uk=kd7^=bY?G zFX5bHQM>)Fi;)=xwvhwG5{GAV&i(UgWidXM0}$*y!?19vFtVDsAIqt zxS}89sT_M*;m5c!Uo7SLIo{^SjX0Iob$lA>+Vsp+pcVTbjl!^SHa#OjJo`4o!nqPw z*iUOW!$RQ{EFjmIVYr`Rc!*)RhoLp7G%ySgFbpRdS|?>2p_!reJ{qSOhK`}p6~Wg2 z*)T*)(A1B{`wXo^46QCSdKrdOX6zKbL?azBvFSWR>kEeAL55*cFo4E83`2tvY#o>n z0JZqS@Du=y-;)QBNSSD)VxN*v#x4L{Q;VAh$2p%5aLsOv|2_}Ed(g}275H&eUmn10 zXy;r_I)Y6!r!Uah%h2j(7*=brk6~DD;Yo&}cNvC0MWdUcwFeEdZIB@~vVD+Ycn?EM z_@iA8Y30eeP-6`UrJ}dohUIdAG{ew446T%HnRPgVt%qGb5o}7%=e!MY>tCkOUWU8U z7c!i0L!*m)Eisr8^ApB1T)rQTRQhm+bK%eab&n}Ou=D%|WSE`EJ~UFDA7i2*!?_tdLm?8p z;v{xvF4BChB*W#&^x2D9JCwKEUamYDjb3jucAOH_Q&%wzi*4FDK=El}>sx`um>D}w z%bOaTxg}5-3na#3`)MpQ#-HrI9&qbM$_Fui=+$L_TOk)H(VXc>x?-OJw1f9;G|mOk z_&kD5U1%JCZ!CaD4;rJfV=%<~SP(-WFcYnD(h9{}-kbqY4Uqsg^)VBd9}A%I9~Qvy z`;h>)9M3!9HPVjhbk5 z5$$3a&SY+Qt?JqMMT1Ipc%yQY_nD?75e z#>8+kJ@tY(QOANO&V$|)A_p9~GzU=Vr1xbw7cW~bh>=x-N~Yf!)d6Mq zPzrC`^Yj)qkTu6+ij?H8k%0#erH2tSB(e;uOX zl;wA8=be4DrRUipJczfYvE$ZJ&UaCUQlpRbecmxyGUyn0VdvK)oZ~}cF6rSB&Qlj= zzCm%=k#6lB+ftrG6>cVm%+%=2ApR|Bb_}!y5~<#?*JlF2jl;216zqXHsl*6HZ0rDa z?&Y0HOibsTkMyOdaL)G+FM5)a!2aPyUjnr6g5=fyBM08A07&}jsG)NScI@=8{oUa0 z0PR(;?ATF7N6wu)cKQL@@2&arfvS4ns;a#0&sY6@^~Y7edFfg|Ky@`#uk$adT<70= z)A^lu?Win+X0Lx%v)8}*U%M*m{^2cie|EH@{?(sXHcY?$&R2HaOgil=nl0iUk(C9t zwLdC07A&rxQ|vAG_&nZXU#YL6)axxRHtuhHtaxEVRKA!yZw|l|%0B==Yqwx=J>-BZ zNle`lU9x_K9N;_h>3ZgVaIG(NT~{zIf13;7Spc|RzAK={HSWR}a%$YOw&pHy7jKzT z<2E+uneNh!Qv>eGj%kbC_vJKQ>8>>0rKa1caTnLPXVth1Yuxz@r`Ju&@0lK*l-Eqp zPJJ?=c}#&X`DE{Mv$LF#D@AeY1dxK4;r6vTPpqRZ-xZZSxK)R8t!cGO9sCEfeTjqH z{qw+ZaGz}NlzEbuJ6?!n3VBfJ;I*>-6Ar#e^0f}WMDkS*UN3pn!5@}gXDKPc$?%)9lTR=J+MfgmpmYz6Y>km7fv7{zmmMp z!C#jAJ_p|}dC0;4Ao-&X{%6T82Y*fS0tbIX@_Yy1CHZ3xzDIJ(3A+4SRPvxuhXBwc zxylPlK9GEt0#ZJbT;&QSeE@Kk7LOu_0Kf@={~43yv&-W?*N(`v^?1yjXI~kLh%8OU#s!2G)`x%YOjuLvS0VB0(q1ZzfNm^y~ZgQ zDLv0>oc>Ls_;!uopz+r^;3yk>11p*p7Rttw2rEMR%Am% z#wF!e8b>aF_WY+kCN9%bR_fG;g+pZ8&kEgxN#{51@0H_IuGK}2zgdTJuKJTcy2vJH z|9)w|bG=kuJ?TD3{hjyzA=&>n$M|ag>Ph!&Ro115f_4&dwj~#$kiNvXDF?~^PP^3p zDfyWk-`W2@+5gw7p%iC-y8ln+KZgAQmGu+yA5y9MtNSC($2m61fE>S=lmmz}oW7Nu k{b`wOV 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 zcmbtXT})I*6h3zs3W)A36kDtsmIm!&^mdnG!RqSbB3xTa3>AgAc3tt_`Uh;5Z4_%j zvi|g%)X=m~?V}HUZqkR^_`nJ^NZJNXniSIqG^P=wwcePPig24VcV>6EZi#8Xhxz&L zIcH|hIdf*We_K<7Ly~|)g3XYbWiVKn83*Yw2rgIxnnL=nv?}_~?l6v6L@2)aU zvtLQxuMM0yOoGQ${ocTB(vcg^WEzTAFx4Y;Ijd*h^^ebl` zkdMDdr6T9lk8`F;%IYm|k4ag)?RYL%31Z3o zy%guE=@R{_LE1+R(l%z0@EHGKkoM~aS<5oP5=KrV-d_w7zKMxAp`@m&2X2{p0F^%_ z=iGgLTw5dFNy|d`wn4%p8u9*WxjSRYAYn{}k!;pRlhgh_AGc;%YNu&xSqV?FeW3Lp z3=*Euh!-sm8>DEt&O;lbdAn!tu$DQ0c*uW4BPBzmC~s=@tZ8aAPM0t>r&iAKInS5B zZfd0Dnnre~Fsy$*HBE!G&A&HuCMw~*X%p^En{{udhO?=d3#treQ<+^*Wp6f>rwgjA zd1{)N0l}R!<$rJSckF*9`ptO2nimAE`D6gV*MD-NI5_tCXJ38lnquFVvG0EblB3r; zeUUp`XmUYq2w)$z(-U*b=a*gF2mrKCZTGDDBKgq7LrL!q}k-p1zEN{_!< zu9E$pDqq!lpWpBEcw5v19wnM!AJ)}W0${#-002YK*xU*ZkcN=sHB@5r0=7U2>!lMd zARTv0%NOV64@v-G09e7kHKTzBm;0=v-c_1(wzzgU_APRihFtDCSH4o{XkX+it)r7| zh0Yu)J=ZVIq-;j-VSH_6dAbakS5$byvX?cc`QIFctsKbUS)jD##?f^;I{GWn7p-4233srWhjao#@E{TO^mnRwhXMq$OR=sQ8dst z7k1eACdRkf_!h?Rv+gB8OB}tyy24UJ4?S zBWk=$J(^({npuy}4VE~p35Z<+kLl0(uLT~nj`NoU{sn>G#4aA%&l7mOV+gd3caYn; zEXZT-a(+bM@$PcoiG~5F{Y3&_DDZgMxO~09FBbSFfyZ}*%c}w}`lnamMgLqBc)Xk3 z&al7}fqx|Mc$c{RtiTru{88KlJ8!YTpA~q~Zx;k!^c#K8m>uz4DM4O5*L{H(cwOW5g2P@)g}%gfc)jQKcQxZ#n9{hw;$R26 zW@)TtHvg->pRJF%Dq@hWPyZ|k;QQzOW~Og{H{9&WdtJ~)@cr|?QQ$;udG^Vq;CdXp zS>2kKllZHM>D%|k_s!AG*0<}&n7;izvFjiHm-tU(u}i<_K;w`1o9pxV<9Y0BBkr>G sr`dtA7UFLPyFS{q#~v|>#T@@zSX~-+|6%RQrtfCIfO^xK7VP@}02Hz<*8l(j literal 0 HcmV?d00001 diff --git a/src/openlibm/src/e_rem_pio2f.c b/src/openlibm/src/e_rem_pio2f.c new file mode 100644 index 0000000..9861bb9 --- /dev/null +++ b/src/openlibm/src/e_rem_pio2f.c @@ -0,0 +1,81 @@ +/* e_rem_pio2f.c -- float version of e_rem_pio2.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/e_rem_pio2f.c,v 1.32 2009/06/03 08:16:34 ed Exp $"); + +/* __ieee754_rem_pio2f(x,y) + * + * return the remainder of x rem pi/2 in *y + * use double precision for everything except passing x + * use __kernel_rem_pio2() for large x + */ + +#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 + */ + +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 zcmbVNOK1~O6g`txt-rif6r&Z5SfvFWGqHXUKP|O3NDZ|T{8eHaCn}nxB%`!~MyVgN z5V{a?C9Yk$aN{oZ1J#x8imn8~;se=nn zG)QRJftpprV0~@f?kw9O;72?yEC#J;V$F^v!Z=NKfEdslm8?JsDzLypUW)Smj;=`Tvs4W8X$#UZb7P-EM z#%*!%xh?vi+coZ`E!K|N;*jHSi~dKp=pXasNK%Z9Kg)y@Z+AKdwsZpM{kih{&eXut z)>X5sK{(5qHG<*h>lA1jmN?c7s7WkmJ}}K2 zSjBu$;adPK@Z{s19l$o=k3AfiiM*Lf44%qG(s~MdPiGqqVHyk?A~bA3B5}$z&CMIz zYVJrRPMi6xd8SGMus9#88P(`l#lDsEa=CRRucL^p#VLfBSTLWtSw%{*aSV5 z%Vf-~1wEUyOuai6Uste_sncwq$ez^)^SMDYZw*IF9U3*>`K0XZI?ahH6@S2{9O{m?)9=LHv3_6haR9IiD%@)Smm?SRQIt_Av2qS!LN)YCUc a?H$4w*2h>cq26EPKlGEl>2)b&sQTYGpabRr 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 zcmbtV&u<$=6#mw2s7X@KrV0X7AeJzdD>V~4ZXkjxbrl+0q6(-bkSHjwldK7)jxBo; z4xpw{L;|;*ICA8a1OGu%nnRT$jwpv7D)o{|sFXcbDq^a)`^KJZWeK&PEq?e3fG6yuWatU|C7MZRC@a=!kK}<7vHoYU|2pfv70f*!C!!^hyyc0>Jx}x` z5+yNk=j)+;+Vuxd*olNE>_BfX(4E@z#3b45cw%PH6QAAo#MEwnb;mA=HSLM1TjY@aQEcKV_O!u!qNg{}%GhtvSx?x# zl(%1JNhB%bJ7R5EDb?~bb9*`{WNNp)Ki?DAy?g&D?W+!?da$D+BeNVYR(pNmC5?8*n!2VIRoxYWg#PlH??#y!0Y6SBTkc8jx+b+;DG z3tFl-_bcWBV`)|Fiy20soza)h{y<&P(U5QQ`Pu`wb>0wIU;If2Ga&-{nucK4&_AdS}{R v^VElMY{EX1!`vu(i)0(NC!gW7C&c;w@gHy#y6+l2ZR{U${!3bs5w?E<;USts literal 0 HcmV?d00001 diff --git a/src/openlibm/src/e_sinhf.c b/src/openlibm/src/e_sinhf.c new file mode 100644 index 0000000..6e5e06d --- /dev/null +++ b/src/openlibm/src/e_sinhf.c @@ -0,0 +1,57 @@ +/* e_sinhf.c -- float version of e_sinh.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_sinhf.c,v 1.10 2011/10/21 06:28:47 das Exp $"); + +#include + +#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 zcmbtVOKclO82;96=r&1rHWdX#LGdAgQ?*+=7!@kiBu$EQuu}Snh?T0wiPud_9b5K7 z9jHj6KmxZ)T#+~OrP08ZcB*fwtO~8Dw{sLyyde?_kEVTH@3WKv&5aLjS}k}Z5z@`nRCAM zecp@`C(H~ExodG8mA4m?olT4+O@x*zz7#}Nm z^5EEseqb+vIDifSnehq4V5}3TddQIb{h}Jci*hzTKM$i}8;861nYRq!eE_e?v)iOR zY}w1P53P9Y`%cRqwaiRcY^c++hb{ALSEkdl&sb)*s}U?NbV<$KAX9tsFW-Fv>00*^rL=6BO0e0CYB-`+Gp+T%W zaiR?mH($RxH(PRM;ABUVG^A)q(=b58+YkaM6{hPYxQ%K#RYE?0z34WodACt52}k|X zT};#!*rulAoToIN`a<#NG@h!h_?*V?(fH3KPd2ERl>8SO->LDpH9Pd_Qu3P`zfa>I zYrG!MTe6X(evfLr?l&#@XdP~7@_PI?HJ*A;#rcEA>+(NpJoS*0r#DC-zw`^?)aT1y zVH!@|s|E9{TGia^1;=w69-LyqE5Mnq*WuJEv~gzYUK-9!rCfIBJUDX|&vi266UXXa zVdfLLzcTl!Q>|61Zq1uVV9uS*muiKw8~T4vP+pX>_V*(Y{0AX?CkoNtKP=uqLV1NT zx=;X%vYu3XTB`T@iWGcP^3;nuwxwPaQTnK~`G584{gBOr5l70u`kpGtw8Ht6)Ti%- z4qGMa73C5sgdLU!fxXNA;_cm{fuiQT=Oe?!PHN z@#>!G{^^}5eZ^BgQQw57B;S<@(_19ns6N?@-o1dlsL@~-B3i$mHu}HI_~%2-08#yC D-dmND literal 0 HcmV?d00001 diff --git a/src/openlibm/src/e_sqrt.c b/src/openlibm/src/e_sqrt.c new file mode 100644 index 0000000..2eb4a1a --- /dev/null +++ b/src/openlibm/src/e_sqrt.c @@ -0,0 +1,451 @@ + +/* @(#)e_sqrt.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_sqrt.c,v 1.11 2008/03/02 01:47:58 das Exp $"); + +/* __ieee754_sqrt(x) + * Return correctly rounded sqrt. + * ------------------------------------------ + * | Use the hardware sqrt if you have one | + * ------------------------------------------ + * Method: + * Bit by bit method using integer arithmetic. (Slow, but portable) + * 1. Normalization + * Scale x to y in [1,4) with even powers of 2: + * find an integer k such that 1 <= (y=x*2^(2k)) < 4, then + * sqrt(x) = 2^k * sqrt(y) + * 2. Bit by bit computation + * Let q = sqrt(y) truncated to i bit after binary point (q = 1), + * i 0 + * i+1 2 + * s = 2*q , and y = 2 * ( y - q ). (1) + * i i i i + * + * To compute q from q , one checks whether + * i+1 i + * + * -(i+1) 2 + * (q + 2 ) <= y. (2) + * i + * -(i+1) + * If (2) is false, then q = q ; otherwise q = q + 2 . + * i+1 i i+1 i + * + * With some algebric manipulation, it is not difficult to see + * that (2) is equivalent to + * -(i+1) + * s + 2 <= y (3) + * i i + * + * The advantage of (3) is that s and y can be computed by + * i i + * the following recurrence formula: + * if (3) is false + * + * s = s , y = y ; (4) + * i+1 i i+1 i + * + * otherwise, + * -i -(i+1) + * s = s + 2 , y = y - s - 2 (5) + * i+1 i i+1 i i + * + * One may easily use induction to prove (4) and (5). + * Note. Since the left hand side of (3) contain only i+2 bits, + * it does not necessary to do a full (53-bit) comparison + * in (3). + * 3. Final rounding + * After generating the 53 bits result, we compute one more bit. + * Together with the remainder, we can decide whether the + * result is exact, bigger than 1/2ulp, or less than 1/2ulp + * (it will never equal to 1/2ulp). + * The rounding mode can be detected by checking whether + * huge + tiny is equal to huge, and whether huge - tiny is + * equal to huge for some floating point number "huge" and "tiny". + * + * Special cases: + * sqrt(+-0) = +-0 ... exact + * sqrt(inf) = inf + * sqrt(-ve) = NaN ... with invalid signal + * sqrt(NaN) = NaN ... with invalid signal for signaling NaN + * + * Other methods : see the appended file at the end of the program below. + *--------------- + */ + +#include +#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 zcmbtUO=uHA6n@(_wrcIH^#`R2s|QWNj!A575lsq3;~}(Kh$avSX}Yo4CMn5^tq1MV zWAUuwMerghc&)UydhwEjr;1Q-dZ{`fLJ=x&_swQ9SP}gW^X7d!?`Ph7vvx>m)Ve+vmSmujh8AVU2`(^U8B3SCRV5v9DXy{@s z=E<+IcLR4{e%^Spu=4!H!o&3=(Wj&L=SFVdi_Y(Rd+?F55xseNY5&yHl~^K)cpQWH z(9jtx7#~h{Tj5?F;bAKhiu8rT;gA&^wa2ZCIfp*<^mhYbnJfUn%fyG1&;-UJaDwu@y(EoWqhQRKMpt`l+q?lTe~7+4Ao(Yt{}%YR`MWdCe)KxL_-@G?(BWzUXlq~r z_7HDs`~l)US%=#g2)MOSanw};5L8J3I8J;><4+Jjpz&b<=v40I*Jv`EFIRaUcw#7o zOBk03E~jwm#ib9I)423QHalroO7;|*0YE#&X##*|0QkA-LG}rG?5E_h*9hdXnvy@O z@Y@tVq42E=Kd$gtd+Enfc)>fLEQ0Cnw~tVo&9`W6wCi z$8$~&_*k_Hyi!Jm=c~>D@O-&gv`Y@~QrWS2d^p)tb#nPh(yx_n@aal<+O9aW;JLFW zvV}^nX#4U16L>G2ajc~Z?_UJ<{uA^$?V`TP^AaXD82}cE*hz8Z{L8sMMm!z&@xk9U zLcVtioMZI)ul6|a=(AHgB&?Ct?GD`OP`?4s}lhPqU<}YQO>~)OD0~&PtDu6rh z4KoP_5IU8DH`kMvsknM)74G@&AE7bbIuv b_a0Frr`R7Azd2i^V`fjsoc 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 zcmbtUL2DCH5dOApY}M9{MM0^Q1w~V^&m>lq9@^5X@lZmk#5N+vZMw0VCMmlsv|hxM zS3v~-fWO0NFXBn?lAC(-q;+qC5}E8wc70d{{b1j`_w9T$^WMDO2bbnA_ZS8Q2Br|L zB5d?V^O??c1_v;Nz$`WcGkKV(z)TK>w)nbYrdoknYz5}BaPIfd>?ZCXj z+TyFgTz(mt*PGh_9^M@M(Qdzg5oX<)o}Em5yjplZeP`kGhuJ6JrcRBTpB^=@O(Qoq zH)*AE`NEi$nNV4kv9jsxxpXFzwo;4Es&&Qo`NjD8F`y5C1t0++moK0PMw2+%v%%}V zVPYI&YusOiv6(bR2Kxsd8zFy;-xb*Y2^7B%U)#U)>Fs8Zu&*;sAQ@2|n9S=4>r7xk zdvTQgk7)cT^K=$*90xEQtEaoSYN_1tDyj@MKbNH;O+$u;vouVgRH`~|-B~Bc)d~ld zdU^oR75d%|A^Rep&R_TwtRtR!B>Y5--xK36#`yjiFZ-f6^mL)Tt(tGIKzY6!+BKQE z&bqC9XVZsTwS60E#q*%t1}#+C^DjV^8?~BK_o3-W@#+t_ei ze+ywaXRTCm?V8ig|DT|J(Osf5h$H+a5%r59=PVfE^A>->Ek2}8CiZh4>7U%6lg!6{ z2OT_>KpNz`5}XD)G5=Mc;rzoAknxOdN(hG3FLsLcX>njQ*`5)CA@z&Rv0ld)onVMg zump7O=`VK@zz#d;bxGZV2ItrH7AN|f{_ZaQZ*f5BGxeYTfs$W%N~7l{EO7o77dpsV dT~9If-V;(BG|PH{etrjc(eJQ+ON0zv{}V~TvP=K~ 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 zcmbtUO>Y}j6g^|R)S<~dr?QZtNS%cNMWtgc_(S#} zB_K6asZcEugn$KGP#3UciCAUgriv;7;Rhh1BuF&Cf)OiPWOT>(*`pEOz>)0t?wR{> z-rRR*<>gbaL=*)Q3QnSD^)P;@x1aF06HqaPGoHBMKWg6ph3JwguC1F*x4CY*_cXJ4 z*S(j#zT0jKnAh(DJ1eHUtC<7aYo8p6M}hP1Zn9*G$`;YI+3-ZcZIyI!{Dxn}IA@$S znh)mAn5(~~JTW|&_QddXI_?+qMB;2Z?uo=;n(DSnBD2v^F(a!=NuPbh|G$Sf^ z%;rJ!chf!4%;vUxkbJ@yIMmU%qnQJn#@dbKK)c;;Zny`>m5m?%8rhy+`@9_m);^_w z!`)BHoRuGE+Xu0R~F+Hb^WyhY+ z=5kprbJ||eOv~X1qbEjy7yu0b^(a3(hX|B);$)8%wgTY%CW)2@edUs z1>kXhc8*ph_|gJNA+TeZg`p=ocFe==CZYda>b*LoZg#WxL`) zuT&jd&(F?{HXN&XmF-KFxAa=QTC?lUGCJw(%k!nWRko$B{|h=Vy^4oIi8|j_z>)*X z2;bFX{(PY8FR?|<2e8h>5w1hMB+wiao@AcgyZ9_rS0YS54fr|#YkZFDAC(0dUvMF* zS3=ryJ<0J|>A?7k + * 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 zcmbtU(Tf{J9R4?$w1iV~PR^1(z`%jggxk_pk8o6{t9g>polIQ~gJWL_4gr)4%)t(NPzJKhq}x zbhnpIZ#vA~yD|7J?J)PQ&nkl)S!c&wDi03z<^F%y%e@D={(SbF&rsh%e?bDx$WOK@9dM^!Qpx3{?8A$*Sj-AnaSNB{E_YryFRPzIn4cKaFFI% z9OfSQtn!o3D*HZ5B?E&r^}u27KMr#r`K;E*u_X7KDEIE=ZoFr% znC}nq{lRlZl#0dI^jv9ic}6c>GG>i}KAWF?IbSH`_1rakO)p!Xn7HuDOi-6N0386; zqO`b-7?d62WGxjjemaojjA)gQu0d&Q%GuR5YVkI^6>C{zK|0G^ibG_+#_3fCi=1f&L)y$l#&GFEQpfqv(eRP~)YUF;5XLvVs z83h=CQz5<7S$6ZC}%JgswF{x>G@*jTmO4aca$SSaSPy1Kb$ zw;P-r4XUI-wP{!KrhSsxg!t(s@ugwgVv zLAx${O?%TaJiG0|ShG9}#?4j>Mzc->quTN=!Kl`2HQV)IxOLAqN{h=ETAo$i5aV0! zheo4WZ`e(53qd-2ebs4NHCy_6QqX?sD4vQWlKXp0oRdWKPMziN1S7q~cT{`;JA!yt ztV6XV(0eAlAb24k;q%D45>fgkfaiSNczQpS^ORgbfWA2dx*uW4v1~7k_QC=a#>@I2w>Dv27)l5q^!=ce(Rj)ktv#V3$T>b5L!=uaH6i{R;eTtS3=oa~AC&Je A6#xJL literal 0 HcmV?d00001 diff --git a/src/openlibm/src/k_log.h b/src/openlibm/src/k_log.h new file mode 100644 index 0000000..a0943c4 --- /dev/null +++ b/src/openlibm/src/k_log.h @@ -0,0 +1,100 @@ + +/* @(#)e_log.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_log.h,v 1.2 2011/10/15 05:23:28 das Exp $"); + +/* + * k_log1p(f): + * Return log(1+f) - f for 1+f in ~[sqrt(2)/2, sqrt(2)]. + * + * The following describes the overall strategy for computing + * logarithms in base e. The argument reduction and adding the final + * term of the polynomial are done by the caller for increased accuracy + * when different bases are used. + * + * Method : + * 1. Argument Reduction: find k and f such that + * x = 2^k * (1+f), + * where sqrt(2)/2 < 1+f < sqrt(2) . + * + * 2. Approximation of log(1+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) ~ Lg1*s +Lg2*s +Lg3*s +Lg4*s +Lg5*s +Lg6*s +Lg7*s + * (the values of Lg1 to Lg7 are listed in the program) + * and + * | 2 14 | -58.45 + * | Lg1*s +...+Lg7*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 + * log(1+f) = f - s*(f - R) (if f is not too large) + * log(1+f) = f - (hfsq - s*(hfsq+R)). (better accuracy) + * + * 3. Finally, log(x) = k*ln2 + log(1+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: + * log(x) is NaN with signal if x < 0 (including -INF) ; + * log(+INF) is +INF; log(0) is -INF with signal; + * log(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. + */ + +static const double +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 */ + +/* + * We always inline k_log1p(), since doing so produces a + * substantial performance improvement (~40% on amd64). + */ +static inline double +k_log1p(double f) +{ + double hfsq,s,z,R,w,t1,t2; + + s = f/(2.0+f); + z = s*s; + w = z*z; + t1= w*(Lg2+w*(Lg4+w*Lg6)); + t2= z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7))); + R = t2+t1; + hfsq=0.5*f*f; + return s*(hfsq+R); +} diff --git a/src/openlibm/src/k_logf.h b/src/openlibm/src/k_logf.h new file mode 100644 index 0000000..1b665ae --- /dev/null +++ b/src/openlibm/src/k_logf.h @@ -0,0 +1,39 @@ +/* + * ==================================================== + * 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/k_logf.h,v 1.3 2011/10/15 05:23:28 das Exp $"); + +/* + * Float version of k_log.h. See the latter for most comments. + */ + +static const float +/* |(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 inline float +k_log1pf(float f) +{ + float hfsq,s,z,R,w,t1,t2; + + s = f/((float)2.0+f); + z = s*s; + w = z*z; + t1= w*(Lg2+w*Lg4); + t2= z*(Lg1+w*Lg3); + R = t2+t1; + hfsq=(float)0.5*f*f; + return s*(hfsq+R); +} diff --git a/src/openlibm/src/k_rem_pio2.c b/src/openlibm/src/k_rem_pio2.c new file mode 100644 index 0000000..9555d3a --- /dev/null +++ b/src/openlibm/src/k_rem_pio2.c @@ -0,0 +1,444 @@ + +/* @(#)k_rem_pio2.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_rem_pio2.c,v 1.11 2008/02/25 11:43:20 bde Exp $"); + +/* + * __kernel_rem_pio2(x,y,e0,nx,prec) + * double x[],y[]; int e0,nx,prec; + * + * __kernel_rem_pio2 return the last three digits of N with + * y = x - N*pi/2 + * so that |y| < pi/2. + * + * The method is to compute the integer (mod 8) and fraction parts of + * (2/pi)*x without doing the full multiplication. In general we + * skip the part of the product that are known to be a huge integer ( + * more accurately, = 0 mod 8 ). Thus the number of operations are + * independent of the exponent of the input. + * + * (2/pi) is represented by an array of 24-bit integers in ipio2[]. + * + * Input parameters: + * x[] The input value (must be positive) is broken into nx + * pieces of 24-bit integers in double precision format. + * x[i] will be the i-th 24 bit of x. The scaled exponent + * of x[0] is given in input parameter e0 (i.e., x[0]*2^e0 + * match x's up to 24 bits. + * + * Example of breaking a double positive z into x[0]+x[1]+x[2]: + * e0 = ilogb(z)-23 + * z = scalbn(z,-e0) + * for i = 0,1,2 + * x[i] = floor(z) + * z = (z-x[i])*2**24 + * + * + * y[] ouput result in an array of double precision numbers. + * The dimension of y[] is: + * 24-bit precision 1 + * 53-bit precision 2 + * 64-bit precision 2 + * 113-bit precision 3 + * The actual value is the sum of them. Thus for 113-bit + * precison, one may have to do something like: + * + * long double t,w,r_head, r_tail; + * t = (long double)y[2] + (long double)y[1]; + * w = (long double)y[0]; + * r_head = t+w; + * r_tail = w - (r_head - t); + * + * e0 The exponent of x[0]. Must be <= 16360 or you need to + * expand the ipio2 table. + * + * nx dimension of x[] + * + * prec an integer indicating the precision: + * 0 24 bits (single) + * 1 53 bits (double) + * 2 64 bits (extended) + * 3 113 bits (quad) + * + * External function: + * double scalbn(), floor(); + * + * + * Here is the description of some local variables: + * + * jk jk+1 is the initial number of terms of ipio2[] needed + * in the computation. The minimum and recommended value + * for jk is 3,4,4,6 for single, double, extended, and quad. + * jk+1 must be 2 larger than you might expect so that our + * recomputation test works. (Up to 24 bits in the integer + * part (the 24 bits of it that we compute) and 23 bits in + * the fraction part may be lost to cancelation before we + * recompute.) + * + * jz local integer variable indicating the number of + * terms of ipio2[] used. + * + * jx nx - 1 + * + * jv index for pointing to the suitable ipio2[] for the + * computation. In general, we want + * ( 2^e0*x[0] * ipio2[jv-1]*2^(-24jv) )/8 + * is an integer. Thus + * e0-3-24*jv >= 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 zcmbVS30M$7<8bZXhlV|h>^GhVo+OgsgqEr5Vh7; zt?g$QTesR3>r$%;Ae%c{cNDc%qE#@sfGqPrcQV1q*Z%+W{O5Vd%z5X%=Pq;3xo2ir z5fMGoNhX6`WEh6$+H(o(E=+) zWYe5=Q>b>@rpa}qsa9drTy$YntF~#bx)7?-6=b+tH=T-VN}Hz8b)cHJO>@^Ns1_sx zo|t92cHE67R#U5tO^Q8BVYM6fAL|AZmxV&nK$GTU_2=FlRNGfN5Zb%*H$ea)do zY9k|KNK7@u*N~jIl>k@gM6%+Pbg~awO(|>aPfbP}cilnhrVBYHgm+9XWrz=`yhNI?u&=cLn!1d7>> zM21O(Sca=})`g3NAVSE$}O8$Kp`lTL(bRU*c{w$Vz3!40p>} z_ja@${eOPhRbY(63*llqcOFhg%)ML!fJ|*;Z7oJ zll287F`9x1gRo=>o2^!P$7l-Fyk(TJOK;YgtE!LzQAW8b!f>DP6|Mkhma#>ybg5a+ zq+q#11rvHKqk=W+RI!noqG*1+YLJ?L#v0{WEZI-OJhBC5dH8q~yPh|`jqKr8O7i9oz%*>Lre6>~^NV?IR1pJ?;%|zl; z%yK3<%UKjw5`WA}{2yvbRf(1OozxPa8&(p3(@LfkSc!kNl_(j7l}s}8X$@>>ZAQMD ze;UoJRh{_pDrKeEE%7O~5~Y|Bti&@~MQxhJOI8vu!V!iiR-zQI*d}kEa`t$YGCEtW z>SQHT!~nIbiGPWeA%13xkTqAG0b{ywpc7pI%@ein!)$eKEMIh1U}SY??;PkzgP~UK z`;g)Dd3A0qbGAOhaD}XOcLC^))snzs@>auwfXe&7^kRIjYAA*tY+WV%5$By~x(mfS1inw)fgRI9LQ&blr&B$Yj_ zCHJV~nmcn%a-ByFNewe;$vra-sm@xGTFmgz_>)?)@REYzZZ^>v4h^B1HS+02R%6zZsz0NQ{lugj zX|8aNHhw00xU7`bltml8K4FcbZ$`?>7~}Z1U^Qhi#x|$f?C~n^2)=^hDw-l?XVm=7 zGj}b2$YAS_;TmK_-@%FA0;T$BwU#JbYe}I=rX}&kTH<5YlJ+H5GO2+2757X=^s{6l zH~MIWmME7hwWP3wl21{BL^gBJoQQt7op@SHlncG>#FH-)or%7KooJ%OpnoCCiT*x~ z9HNXq`XlW+%ua04wF}V~*oj|Ii?McMi>_UXev6&Bj#`{%C$_NYrduR-yONU9{)ME_ zjnxum&e1eM5VS=33r&i4YKxBDb-hIDG>J-+=08#+HPsQJ1-dSbG1>*b4_Qr#l_+z> zEyzmZ+tkpdv@*m~p3ib7S!hva5Dg?6lj>Cs^n%)4D<;48O>|J=rDpQ7v!omNXO_@< zK`2tI{Aq&NUnvNJC9qZyNH;nGF))LlSe6QcK=hqtKt%8rE$P#iUL&g_8U%si%rfRT zC)mynaRF$2%%WyZE9JU(LO^Wx^wulS+*Kp5k4);VGm8H?1&>Zc@UJPO{ zZ!rw~*SRah}i|=Pfu2-54!Vu9m`li({C#V7lviQl=E;TO6bO1*V!m z5fOS^*OfmNt!ebFqV+_ZdR8M?NqkNNEjPuRVU}5mr>jHVLJWPH1VNoWRAm|R)E3^s z_wOBKHRkB-@v1?z2#Mg!>1M<7M;Y!xCqqd_hbW^wD?8S<$K02RXqoPTy(SQYX1q$F z=G&-PUME!zhWqO5HY#dVK??}7I)!e(nnruPu-Q75GTNvYcO#asb?~@#V$!kIYw>0) zi7yq?m5JplWd_qbH&|nrMjFM&7}ww@k+O?)PYa`2#vqW@{!Vo2%~eQGDIb+ti88U4 zdRk^GbHuXFO5%^xTflIFjOa6Epp^#EFBFLlFA`5kL?@zuOC&lGeUwOSe32+_2@EGV z6TP2EbSC=lBC+X3qPQ0^oFFH9`W(nL$%(#}E*T@Rn$vWU=V&i8`>N*+6%2*9u&gUjdDMh?THN2VS3T2U8rGl$MtYeV0LEcvqQN-`Z&YGV7bi-Bjp2tPGjt9Le2N zM26<;yzH8io{XSa#@}?8G902eoFSf0?0W^`6DePuz*V?SWu`DwnYWq5eCka`MzAE< z6RvGvSOLqeIziwpvdAKN4RsAVYC3wZ&V?9$XcPnsBZygYrd1GVWQZZ6=AY6M=jnA` zERo8^ZGt`oD5>)+qItPW+$y58|42S6aN9 z1c7>vZKgTmOszzz7aOp?bu3>`C@zkcOf02KWvOat4!jjp4WFN`GX@ekG&Nc`F zYqY&3p--vamiyHdvAsi(UMq;N4=jtS1tGY^GN4KjdJ4h{v5>G;BrB|fV43~2*$0<5 z*me_3Sd&<1*=`42h>mQwI6?c|B6%kZt!yHT=-R?k(Ig1;qbB`wh6yo+l_rmM=>}>g|e7%M7mbM{ca$-tUrT$U7O(hQx{YY z+m6TmS3&(-AU?C`k=rW`%<@E>|1cD9aiRF^Q7Ez#_3)|t9ktzt;F_=zWRnX#`&6OT z8%rPJX{a04kNW`ibMKfTRXer?W7N(=zJT7&B^$}D-p)9Sy*{dK<|YyaCHqv z>4f$u*|88yZ%)J991~tH7=;rv^Wk2374e)OvKJNL+b*9#{X;oko_Ge|40C~tn}EK{ zha)ef5}U?c!*9z%(CdwSygIiETWjA&|89e^!di-l?{`J!y6%{x%ETWj&kz)_8109Q zz+SIHPKPuii_xxybmFjJZ>MEhN^-Sm^Z*3Q-_~JhiexwX~;EP+p->I zJ$&GkRf(IEVo+Eb0>!Nks91Ik9Zj*Q>AD@ADiRR*Qa^C*rh{W;c)TV7dwyJjS1nes zQ6r$7c^13MFXH>eaLh?MiB>+_aCUPpT)(wq%HkFHI*&ur(AD^0;S&6iGa0EDen-H! z8az634954W(91j%aitL`y)*zmJIaukWJJ4?#gO;%Lc5V$P!L~$;-hNB{QM!%u?FWx z?169OUugV82^?;~s~e6Z?c@WzH0&|{ez+39+{s5#tq(qO*#Pr`VF+~p1+61$u)5u6 z*zLU(fqS=N)cQOu4e5h6ar2SBeI4fB>4xBApWvMiQDEM=iAUFYRBqUao457Y9J~>$ z@6SbI;sE^C=mGZAT+G}y4-3-6VVoL*t?l>Y&|mH_2KU5MT_}QFx}a?v8QxUPg8zd_ z7`1C1ba$Na`*{_fF8dZKY&y1fsKS~J-y-+JCph!gSe$BQh4-euc>Lya{H&RU@?nVx zo9YY$zXEaNd@*o_3G**15yFNbAvy!27o0=H_!P8uH^cAoY?!#_P1@@%X=O|ChLC1Y}ptwE+?FYV&DJ#FgA4=H@*?J~`~g>lH!)}(L42o0nEp+BBpv$=Mf?FM!+uAZRgTDv-njSc6I|)>8(Mko z0^h3-W^jw(KBO-^HoStdgLk3p*LnEi{`Z*Ds~zU&#US9_&tRIc5zfOoxK}^H>tQ*V zAG{f%xo&9V-5wY76YzL_0SfoLiP5FsVEe!mxV>`#cCX)n^6*)BS#u4Ga;h*ZdmI|B z48-?e?#A`@!NB)lqD}o}%!twAzRN!NCI?~Sgd-Rw491+g1IRdB1D}tsWB1A+Xmg%G zeyly7^>D?dKfB_MU$$Xl=d~Dc!X2Z-EqLkhHuQaMFRFLFf-%WEP-gxHt%nmNEIEPK z>K0*Xwj6xNbQFI37E)7gqUs*7C2A51F7LxG?LjO$bqZ&ky5gsY0m#{GM*g0~$YL+! z>C`V!xbhLctL}sHzdyzBDTi?S+I*}l>IT0nzvAnjgMlAD#h$l5!mktM@D0etn=6;& zvfFkn+U0?z@n51tJ3n0A7l3DfHG;p=1paU%{#-NU z3=7J$P;%{89GUhQG0C2gxy?n+kKf^E(`k&2WASRe2R=^E$JeeyU<&IG*Q-lW5pf)& zeV^fcX)!8m7-Y`4hAlHL;?m(@Y}=TR#gooq_N}9+zWfpn4jzh;okk)qBN1i4KSs*> zLVOoE6&~vQ=rSxENd@o2x6y(-=WEa-vlOWx_J^Y4D1-|}q|CXA9~%qtk;073sXENv z^D|DQe2!u1OHt@K2TxD!gzv)Z*jsWC`!E(ae{KuiK^6X5HVwLqAE0e}f4tYJ4VG&+ zK<3*4Ti;!T#>T^#5K)Co%Lm}^OD`e&-~kkDY(Vgi-guajj}1o$;Np%6$lb9Qr;dA| z9Up+yiT&U|fyd^Pw{YJ30Or2E3&Z?AgJQ(s4hMCT+ou ziH9(jE5yZNN|Y~P5zwU^KXm#M-Tg-*zUBfhy}Jqj8E?XvtY?_u+JL{_`5t_a0T{HW z2WEbB6>*iju&UP}l-}8bv2C|ubKjq^^MVIvyRb<9xf&~0Z^!EBji@^_0NvOBf~BjX zu<2BHgl)ZwtE1v@LpK;R?}el3^Xqu~Tq2gv+=heSy^FXfU*YxDuYoxjhxil)y8C4z zbQA~v)@}UtpL2+;4}&nlf-a;KN8>-hhG(zitobO&(NnlG`Fo5yngzp%>FAy{1pe=A zfHLWQ_(d>K6ybi>Qo;rlUWo%DhG{amQGdSmpaQlzcYV0q?iAO}LQ{qY)j zO}K;Z4;9$^xgS!O$Kacn$6{~YZmha~9-ovap~CR7iR? zJ%-hHuM_nEwT`x1xoKqWPyo}$9$zwq>RjjQP|EY}`R*X9_gHmn0JYb(X14gggJL%O z07i`%G1%K@)aW>0@8EucA%Vf(AwePigMx#DynV(c&+ulGbkc=@fxfn}djp_l{HW1! zaDvQ4=VSk-ER%G1sRJ+RD0_DtWJ{E?&TZTj>*zaP09~YO>Fof7dnngBMSFBw;=JCYmB%2pN08dXC)~q3+@n*thcetl!L*j_{FBge z$?>qoQ-w{On@9azJjA)U;B+e+rj#yqkZ`*cOV_D5i>vXX*yiT;A_$;|i2OJ1BjV3J z!Y<;AD!4*n2P6p*kFL$*v&%pUrytQAg*pheL+_oV*c{GP>i@Zn6i;0d^c)i9O$n!t z7XoPKaDPP~qu&^S z|5`IDIsbxVZen`!{KT}`sUd+H%uboDOPn(ov#E~2=n=sK#ozwoFZ~hGzVxgg{Shw= zpl2d+5IqZ}Kfyubuh=HoW=d=o+z*L~bCc6klIJydjD?z{dDBy%otK)LF3nSXj0QlT zo9X#+$sc!0foR7Y1e-84@ko5?OLqJ%2b{*N9dAX0TFO)O!>b+dAmP+L?b43-bl_9p zv*Q5{d>W^Ae3%37IG&LXxZ`-LqzSj2*CZ)0DBi}wez^lq-|5=>ef%$Y2Pt9E?j7gr zBjMD(<2ZvHaK~|e>VP};>qiGCt-m84CgCmno#w!I?6<%Hr@6{Luj39lalkJ+;53)n z`4tYhrvqN;fYY>W=Rb77Uvj{oIp8$c+xgDoi*%cR(pO)0oS}pJ2frF8;dGrH*E8J# zcU*@kI%vs0&8Bwy3;qRP{xA482b^YKyPfYGa7X*%qDcKxm$dW8(Z!N*M>~@pa7R1# zJWS_H|C%Lm;XCtnNz)OyP?v5y&a$7SC(la?)Fm&`A#g^LE(w9t7cN9#da6ya9RoEB zb%X36Re}c~P?I`;esYQqfhnoF9bkrS8ZzZ|Jy!T>i>m%48SDyU*S+kP_g@kU1%Xk$JBDTUx@!$1f_TzY|eakw)TWa6O-cSgljMToR*xT8K z?(Z~iTCQKL)V}4o?DMt@-S4T*mhD$c?OWCjE!)#Vndat}{0XN 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 zcmbtU-Afcv6#tDMX=UDBD=1W2qK~n1+TFBFXjib>0+A3FcSTr6oz2qSmE93EjOrnf zp85lN=&83Jdh2mbA_yWv1$(Q+2qdU^>LD`D&bhO*gGSU3_MUrw_k7Jg=kA?LeV3~g z1riD(C~IXTYRdbb(zXYU*n_lCS1sW?N>o~?Uo4SawM23)Ez~7TB$q5PTspHva>Le> z%hI0gT<2?+NU&{U`Tpi~3;XY<*p^7HSR(OaQ5?E!>vm3?PqwqoM@tNUN(*(Fecz>p z`q~nSHF_3tZ7nK4?GJ2GDf{0Mr7A z^~X^KrAVB-TZQ$Vb^`2UsoWZXGUHR48|vyGDmLH3XHQxF2^7Bu-#53isdloLVdtkR zE74d|Yf)cGV=wbQ4}XApTb9wvJl%yGhf7K=R5uCWIP*ade+od8tA6J$CQ^kPS#15G`R^&d}09OD8R7kxES%`K&QX9x}ZAzA6CK0Df-TIKl?RQ{N=t<>KkqB!AJx z?{M+gTzs92A9L|kgN!rh;;A>1pLg+YdwH)^C;c2~h1ra$k3cJ!d0URlUEY|~HPe_e zp^fRL4sE1RfR@jZqKy{JE@-2}Z_JXO8POyGGJFQLSb5lm%oP{0E z7*D11dd6__|0n3XXqM?N-LU_AQ0_m&JCDuWH)-#Hnhc=G#BR=-;v6No|cXbS-+Gq_V;2?8hGHP2Z7SO zSIi`U1RHwml66buIKS6_{xAJ+ZqxrFH$?WC`cLmn=9fIB@#ZEx=lu078vyLu!k=P# cdrv5G(DNm&3=ZeOzm5MY2c2~+ZFv2E1BJ2n*#H0l literal 0 HcmV?d00001 diff --git a/src/openlibm/src/k_sinf.c b/src/openlibm/src/k_sinf.c new file mode 100644 index 0000000..15c8e03 --- /dev/null +++ b/src/openlibm/src/k_sinf.c @@ -0,0 +1,48 @@ +/* k_sinf.c -- float version of k_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. + * ==================================================== + */ + +#ifndef INLINE_KERNEL_SINDF +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/k_sinf.c,v 1.16 2009/06/03 08:16:34 ed Exp $"); +#endif + +#include + +#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 zcmbu9J!lj`6vzLY4-++UF2O>H%2jd^Gv1wwhe8qv<}5;x;9*t*=jO6&G`YL5yJF5p ztVFP|wM%DXWn~!@CHPSUZS2&>GP<28B)q-%Za0fj&>!s1%zx*-H#6_e-Z?)p-ewpO z3=AV0MHJej{%F`8#Xj`HQJFPIWj+Neb(rKpnQMVEKRYV39w?KZkAX6Ko8M-5&J2&u z4}mh@2FiRNsOdFFZL9`rdOc8Ap1bY-mmfGb^7LozeyZ>8$gL-D zE|p3zM^GFaJDbiFCrg9r+$o*cxpY38Kb_6xvgyo}J(s><`TSw%%plMKAPt}sKyk8! zHW;g<$({`!@8ZvORLwQD|ft?t{pI9VF5>ddaOX*{{^FB z5=RN-eh9~b(C5F}=Qw`9IAm71mAnhGerboa ev?rg*+!HBwIuwo~lIPdAgZ(qMZ$zdcN&792GOH&5 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 zcmchZT}&KR6vxj%g{rk@L7I@F?cxUxDB~`rLXGLvfU+?JO%>UVo6;@plmvDmyHg7! zr6L&VgV9vuOJC|s`{0X7Um6}PUz%-rp~er|YJ#oCt`Aagn^arFm~-deo!d#HrVsv; zoqO(Y&beQ6?#Uj0q5Z`oO#>+nc7oUQq_6kvUEJIS2phqQ;Mk0X`qGh`k=ZN3BeUZ_ zI*xOA{Ld#o`q_L_e`f}#Vj2L$z&#YjFh0jHuu0hGEL=UyFuG)+e#!F*)YE$l^$QGR zml(#rw@|;%Fh;*G8AioevELX*x$pnL7Z^srU>KWc7<<@Ve{_~1=Q#`YIfl{m45Rbz z-VYv{xT)DuhJnZVX6T$E(_}i1<3y^L817lIBABMwJj3{}4C6nL+e)N*iC)Ywj4d;a z_HQe}PXYqzTNW@)@)Tg{2_ z=e{02V-MBc+L=FjwE<6;n|*=zHs7cTnVTk7)^ZoS%nv8i`O7tLn`_UXs+#`fQ#1SO z-iwO|u6=&uXw&hju?ka5GPc~>V(P`OpM4~iGMm0FnY`Znu{pXHC@U+QHG4Wq-)?0iPA;lJ0%UlP38$6pq_&&N9jAM)`x1RwVCgy4mQ7uwHTe${T%005LL z-?5Mr{oQsVZS;WA-qJviZS-iQM>s^!?c5C0^BHb(uO@DC-)3&|h#lN?BV1?K&vk+B z?*3#ZogAPU<>HM5shQiAf z{+Or%bk5}p?^8J4Q8~_}!l}kcF7FqOL%)KI>`2N^>;offXWX_=TAAcP!myLWHW;X&a36pq(_@Iy&pKcA}?W^!KL^7(P>q>_cz+_h+bv~_=Fll7@^Z-o5ytcurBDELb)i!1q=I9JLEGG(2Vb*@Hm zx(li{-*(uZ#Bc>YCC0ql_^_Ctazs^7%Y&R0Ne zE#jZ{#moK6mg=aqRsHfG&yP}w>V)6@iU9s~$#qK|67&1xE5!%-w|J`aRPSWINlnqB z=zom>ls{C5 + +#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 zcmbtU&r1|>6n~>`T4~=&3Jfy_qF5on?XH?jgeyp`2it?Rv@6s$uCp!a?#k>08bk*n zIz)IYPj(EVKcJIt667H9fEz(1_cp*Q4ry`wonfuZ4337E3?Rdv_~mXWUfTliYRKg?=#TuWEi%vMw-igYg-TABF;UGH<14EGFFWrq zKb@FQq`rOHd~&InSns{N@U?3(@nigU*V={033F*N{=L1HSX%4oJD+}&!1w^4mmxVk zd|C@9Q|WFk+9zW&s>LF){zx<$(ZXZKq&A{k^q^;;8vxs(0RR@5Or@a#lojN-cM9pd z-2`xeq;g{nlv!2jY;A5?P+a~nJ-bKpPr&$1@MY_FHjQ5PI`%kMr;Xbnh*!6aKYmkTlva&$O?M+}cB9=&+< z;n9!BDahrf46|%ZqswH$$c^I!d=l)s$= z5;jQ2nILfeEC + * 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 zcmbW0&rcIU6vw|)s#GDN7)eMlvL+@%B15-Aj2;XL;_kupKvKfRG)vi~iQ6C99Z2!w z0S{i9@W1#EP(69`CZ^E?Cy({!NzAnGbvFZC_*`b@JMa76%)Z(88?Rqwga9M(0?8`j zVF-*u zr)Xp8=^`CF3%~+!1AtR1BLi`wHAc{y?|zpy#Jf$1c3#X)j^~aAkOy#&_MXtFwSu8t zh0dSFpYzN1$41o?CIH+?>0EP$^kFYB($Q*${y`YZDk>G4>zS=Z`UV=^&QwdWLM2(} zypZu>U3oi@v5JOcjc3YlE680>d5}AC3|Vc~>wZH)Hk!(pPN}>UE3f*N)_aY8*@~Ji zKT?N~kso@}uT_G`tNY1)uge@T_)0g81bmO!&~?w!JRtvAS_JUPSTp=im`4C|z_tC4 zsXo6WhU+i0KyZB?SIKX3W(oxRm<<5q#+%UmrU3I?`mSl-Q2q3q(#%pJ?gL}`w+H_P zF2wc8&-HK7IoUr;33ZrRTeD66HpShh9+`ff*X+IK8~N{(pCNg~^c8-K4z)Lm9Af(a E1LQ`5f&c&j literal 0 HcmV?d00001 diff --git a/src/openlibm/src/powerpc_fpmath.h b/src/openlibm/src/powerpc_fpmath.h new file mode 100644 index 0000000..6d80eb4 --- /dev/null +++ b/src/openlibm/src/powerpc_fpmath.h @@ -0,0 +1,49 @@ +/*- + * Copyright (c) 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 { + 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 zcmbVN-)kII6#i!0*frL@lcEr;(s@W_BX+WzT5Hu!6H~hjE}>L|TP&8{WTz|nv2kar zsbHf7O?|8Hf-gP@zT^+^!I)CwL!nR#1z#+RL@Kl$e3IhGnK@_n_UgX$gPnWNch9-! zJ9p09U3tBFJY!i9SQtas>f&x+cRn6Z$DxqJn_fj-*z{C>tFm$1`QqmOD2i4ptA9GB zD7v$v*1iW&ilUJ*we}@|P}xsXbg1lSlCgHpQzO?uoby!vmZ$O?p&B?nG#IK=w?Z{A zJCxmK_n5S2hq9p>I5uR5s`jg=@|Pc6uF`UCGgR+xh00FcHe#30eqPCX>g~9S%Ian3 zolQ^eI|h`1^@$ILV;|nD7CYU(8n1_{wiWx6woUJn2rmH`SDzn`q9_(LC_<_v-abUC zJ(b@UwWodxRgJ9qSmHfT<*!J{TU3tyIG@Llsd}mKM*H9VX^%vCwPKK>!XvfmThbA?p@hS7VtcPr+ICTf+uqJYNnPe zWWMgt*%P^J`LUKvQmy|33f+l&N%01Dq^i0|Hq)AwVaH=1vO+N8Zp0&Erg$oz^>JJm z`vC0G^2W6R*bn^2m+)KC4Ilpd zodEOgv&AKP$}R_ak^!&-!2Kw}D;iJlS@;I?#L<}v|Eb1P4+#H_#`kOdy0$;P74hHF z{Pq2>YCOG5@xP(%LvKs?zcgOg-_H$e>K|mD&O!GtY5sa$Z}jkQX#ToR`gRDkKmAg; z{`rNV-hk@|on&mutkayYyFqg~fIC|c>Tnyr54Y1M!=3Simvp1}BHWqw!a{Q~fVa>@do!~r@&6}+=UZ=j$Ow~Lzs6Hy){9=;-1f<`C!0hF{ zeD2~e*ruig(BgC5&3WW|9c0I6nP>MD-*KD?lcsx#_I%j*BIn;@BwFW0qEjIHWgP1f ze~shK^AcOeD#sTj0pk~rr+Y<*)Gy;S$D2?OG;0?UC!iMEW%f4RSsZWblDY*SbAB`3 zI1?3dWSH^GJ^JSaU-@$W)IW3&Nxbk>kC~frkx7ROrhj9q(~PIP!R#Hvw@e<1tuD;- Q8|V?=V*P8~&=_X?zZ6wx-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 zcmbVOO>7fK6#mwP#z63FP>Yag6(2&`h-UGIpQ=cKKmfavNm1GeN3DuBi5*uYaqun> zDuE+KC2-3X#FabZ#07~ofI?4^xFGd}+5=T90o_|wX{$H;#u=vg!Y6rW=9~B4d~f#6 ztQ#kaCsURM1q+9<&O6gRd*%>WXkyZ#>@>$8n>u@R!{m$Bl+qya#}~ zo>*K25DEJu@{5H1Nz#_q#NKC@CWZ4tILndf{I0tr5~D97(K*rG_L6NSX-{;wMWXX~ zcRCWK--Pq%?b#yDmR2J1{c0ra#A;cZ{Pb(1U7V593k#3zZ&#N3f%#Jxd*m!fDarXi zpNX#HB(Jn8O@*_(BD$J#`vDAyYhT52ER}R92}M$EA0WBHd8t&6K8-|)MpIJT8{s@r z4&P7~_Ez45pPQ;FheY)sC*n8;@XOy{o(JZS?5KN3$eb~+IuiN8!9!UmKQz*l_4d1c zu9xl0^&QB0UM}klmnX6XKjewt&wGG209gQ(bAD(9DOeAQQ}5j3@g`p6LvF1fhhfdx z*3ORh^pXX92H<0!8ztwX8G9i$oXMtcZO+(7GwEYns!1omh0Wdxa&5yKO80-*&{VaK z4%yX;kL3pUXTAkCx@?Fi)JG*B349PiywNPO1+A#iw5rZg6=z^vB=^VLfT9s#h;h`EFRA3*k=q zp$~T~2;kOhG;qg*aKAqA4#FL;O;49+Lbx-vufS31YkRp)O98-B_> zn>TTj{Y;oN-Afenef>RNf19z;ZB4fh%9Wtn!!7*pvcI`sYOLBK`{y{W!bA4os|be5 zU$rCbZ{n3QFksSDLhWX419;7brY`mV6t3|4Z=DVL<}guEh78kxu0{Ri_{vvxLiI!U ykn&eN$u!p{RGG|j9`yaCJWYSP8_e1vTxU}M5EIP(qwmnW{0pp~{tD?Z{r>~xl3j!V literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_atan.c b/src/openlibm/src/s_atan.c new file mode 100644 index 0000000..23a2949 --- /dev/null +++ b/src/openlibm/src/s_atan.c @@ -0,0 +1,124 @@ +/* @(#)s_atan.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_atan.c,v 1.13 2011/02/10 07:37:50 das Exp $"); + +/* atan(x) + * Method + * 1. Reduce x to positive by atan(x) = -atan(-x). + * 2. According to the integer k=4t+0.25 chopped, t=x, the argument + * is further reduced to one of the following intervals and the + * arctangent of t is evaluated by the corresponding formula: + * + * [0,7/16] atan(x) = t-t^3*(a1+t^2*(a2+...(a10+t^2*a11)...) + * [7/16,11/16] atan(x) = atan(1/2) + atan( (t-0.5)/(1+t/2) ) + * [11/16.19/16] atan(x) = atan( 1 ) + atan( (t-1)/(1+t) ) + * [19/16,39/16] atan(x) = atan(3/2) + atan( (t-1.5)/(1+1.5t) ) + * [39/16,INF] atan(x) = atan(INF) + atan( -1/t ) + * + * 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 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 zcmbuBYiv|S6vxlD&{o>+EQnY|WCcPNrQ7ZT@({VLly;335!$#7%VTMGAxIx|msgF{ zrj&;tw3wJsG!cj~kceP3p+*g@r3OI~AE1d9Vo;KFk zZ|0mcGk509ZC+Gfn&xl-%K-}@RZD3}PU?S={96Pr5D*QB?Ol~o;ptx%*wYi}zUtm{ zvE_@F38DiHIhyCAJAa-5{fT+0E*J)Xn6&0SIsPJ4cg)0}wVT!5?QQ^64iYoklZi*oD z+x>sW6t26-=Xq0vZu5Wej47(lwO+Txj&J0^LT618I%kSdcUzy>GfocvnUNSEIb&$+ z6EE$SyMGPWtIx=j&Eq@pWPXAI#B#rJLs7Y)ib>r9tEl)jnRH@O}%4sKMQ zqbY(EN3r>O(6VsUx7OuI!KCJgn&xMQ#?F}fR?Ga4&ki*0&TOFi-XzbB zul?EbRd(!}VcYGc_8SKKd+NjR$hB`@G;F&YCtu$LyXXHjd%Hc70fR^?{S4 zznk>qyrb>L)!fZfo_Owv@${o#9Ej$=Yt*^Rd(SO8VOXv3%9O`HF>)(W7mR`p>!+8z zf9T}?!Anc?FC8^%_s5T!$KNwHj+;F6>Bf(YQ&;zObaZ^i@mTU*N|h~KIM3}VTUFH=%3XZKV$M~Ggtab-LIRM;8ZHI8blsa8I(-t}NTGN*~-Rnm=^NO9WVrN!qcG}O$ zN=bGo`Tw!(w0+4+X*RjKNjR<%@cXd4AU!$ilt#(9$TJ~@b7iF~oHbhh$$$n1q`Qf4 zWk8Z=0y2~rU~95`WB}#@Rnuf81KL#x00qSNX?zy(0~&vX_+gC~6F;u;GUA;Yf0B5Y z#+S)@rbYp(sJ};RSxG#g@fzYwG`^mAp~mZp2Q|Kl_#BNl5vPNfR5S6_Nn)#wxJ%3Dr(EHfcR9aSC>(PV z_ped-7=qW=VjRw|oX4k9eCn3e<$o=DO0+$b znod6dtG$on-xQ7<@;+ec^|@q^XI+(>>`$vunLn>X=`HLB$X;J>uJf~k?DczEzLey5 zOG>)dI+SKwrN?ve(DO^Jd|Fk3Mz#)nu>V>$*LDSP!@V4$~JZ z?=!p`5V1Y;;bNmsQ+(dPc!x|J#vbo9eea=upii@RWGy9q{V;b8XWvERx4&;v((V5N DD6;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 zcmbuCUu@G=6vt1yS>^`4WujEkPzXv%;K#ZR1_aj;7#-M*1zBvfZdgX^jO-6;kVEmbL?>YS)evB9WCcA$= z_nv$1J->TTv(eV%PQT9wEFUz3+jI3rwcBpd%@zoOg3i2p>+2WK+&=NM<2a*jW4~3M zxaT;d$s-$2+yf|$s?%Qrz{xx6y;>iDtwN8Zv8__NZX3H%rJ~onx+m50xAm%M{bRE_ z{Skm}k8VC1wpC~m4yx#ktx{8Jz3v^ouKQ-lR_PfPowHRM|8ChTrRR9s)2{#Y_qNKE z_t4dCYm%DQYo@1cmHAFZuTPGv=nQVsR;ih;ZX{}X3HR~~7P#5><43!&ULRMdSNm|2 zv$hJY!(rE3YSvb%M-0n6W9pvS+q?7Qwh9q9kwIs;o6HP4%a7yI%UaZ_b7noV^{(GD ztD=(}CR?Q^RrDuYrSb0@5ewO#ay_SS*eXN2z;{$J=G3nEoVs~+`uAOj0ZMTIyt)%{fYQ}xFTMHv zqCXZle|qs^bE00st7!M0+Rr!8d`7-;|H~kCKBWRQul83%-$%Z`r~HRpUN@3;;Y$ zV+Z{Juq_xmO^1$vI z{|DtxYfbrZ4+{5L33u;{Ijf?43Rk$6PoLH(31R%2i}U^&B%r_jPH8 z^cwY=HtJHhbyKgV7i-c^^N`OTD42-V(?Rgb;kV>?oBIHoo6Y^^KotF9}14Sf%yf&@h6!1Wx??cGQT1?zA@&15yvw. + */ + +#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 zcmbVOQD|FL82)csyR@D6)~QgO&?{t`4R@E+X;ti+v}tpvp_8r=aT_sh6CQ-0N9`8yid5Fv>d;0?K zzm)7H^U~5Y0)V>u5Kb?qd^In5XU=_-l)9E^R(18PN0z?a((kxc z{cex+MX~k!g}tx;?E~opSpZ1(ntjspp8#;TMd}K`c0v92Iw6D<(;k^sF!F`(jC^6U zxSj_9v}=I1(7VjN)Z3Iu1uP>|<27~jW^w&97Iw8ddD@!wx@CNp=`eM36WzsoL|VE9 z0NVyzf~wzXR)sCK>2ccp5wnczGs{JW9dDAGF*Uep;DN`XNDRqSajM7FE&biH=L|Gq3X#-`(VtHIo zg%BzO`1Cw{_{uLmmjF<1`925_47@CR!^6?Tvj4c!t@!0`U-$DqzuzZ&M-mgV8rRr^ zqdkWKngKut09D`Sc#=IE!ES?M z$FeIZb}lxBMEO#i*clW%f};D?cGn-(L8#po5xpVNHzaz4qCD3ob`H>4q4rSKSKC?I z`vTY547+SM>d{o~q6RA&J(N0h(2?!O%RqGrEp(skcmehS`=efj|-d4f495FdnsvXUciqHXomH{+^A;)8{;DAA$MtQ-zY7o7CcCpyafyWmDYCCem?5 zOU!DZOvJS~C}X)CDA^1Sl<}PQqJ3~2l<~~uWMWDKWh$d3l<;u$XikfdzsJV!Or2Mz zvzh5cR+|GWcOn%_X5*8I>S7)o*dMm;RJQeQf~sygoZ3A|e_!-+sR#QB6&Smp)j@3_ zI+=Z%@%;YaxK_8>HLzo<;#sD*2aWf$`Uk2REqu)C^YwD@F}Eig#IH4oN6jI)eT~KY z7|*fJ;*W8Hf%nhtD2sRE$N#y169BN!scn31vv}vac;6fsS$$_YH#?A7K9Rv0Khr=z z)(f?!6Vwmh6Fi>l2lv5Q8*!P{$NxHrhndEm@pzXwwS!n=2ZZk}JNUkHJklWkcc%Yk JK9Rv0{~xMP@4^58 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 zcmbVM&ubG=5dJo;HfqhLMI}%VTL`)Z^Gt%j@K6hhCWla@G*q!rw%bixY?89OLMn(t z4_^HOp(*=%3JoP|ZygD)TavA6tXa50ZKFz4y(`o1NX)4=ayih5>57c?58rt#oyDv9_ZA-8@52HP`Gc|rTOZNmAj?#Dre=h z`P)j5t)wwEJ{Esx zK=W65Z-ZqB@1E3V@<1LZtv+k_J^*v{cGD+psTdMZYaR*np4C2T7 z_*@@PO_cKm=3}}~J$|W=r&w~Ho-KjS)2|B^?9@YN6)Fh*j@^)z?`=6M^jaa*niD!u zt3d$eH_1_M5Z>!|a(AHIX1(q;La0VF^i*lSnh8S3ea`-Rd>Qf+yUp78B!~M+Q2@{59tLJ_j1_c|Qty zuLL&$9rLt$niGmSDFGRhU+NWzFLri_{sRl5{Ssenh4ooUz}RDZQwWCKUu>22Q5;1H zhUf$|LiFAY%r<}@d>~qv+*|O9^GEd-C;FeB=Hp-U^OXb2oY4H7=Vwh2p3+2f6CQK^ mZ`uPc@;5~47d?HKqq9S>IcSFUf@uFHhUgDj|5k*IsQxc5R;_FR 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 zcmbVMPiqrF6n~pW8zpu&rAnby_OM8b?U;nB#X}otY$AjnN`nZ6vfb{s#U?4cE2M%| z=s|iD`~n_5il3lG53Qd-@C)=Hh^|MW@@C&`w$lcrKSwJqZ#oD5ndMyXJ` zS11+>Mt;FrHELEs8xs%40MYi)SP?8~%+KUCyI=VKJ?a#c` zK=7lq_X*|WfpY4@K!&I@!1!tSb#i6{0Q%zWU1Y^lwCfadLc4s5L)-v>!9*NU69C)< z0R4eYSvqC5R}nEq|lsg1ynS)?BbX$J%r$=Pi=hW32k` zNrbrs-=E;y2_Bm%?d74TM8CTHJF-U}b4YtUV+8W}i^2WvW?-!V_X97I>vH8en-&k8 zP5^w>3M}9&z7O1Mqrz=Jm`p0g`@rpXv+1+~;H`Gx@alYH!VfI_8R=`S=X}d+Z#iDD z4N-7secAP_rW03lVc_@SOsSI)-F1l1UqYRM5$cz;m-tA{>JWi*hP z2KlR)kp>D>8b=84&8gW2fHE1Xb;S@$N9iss`Hbl1C?`v^K + * + * 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 zcmbu9&ubG=5XZlpwl-?b#^OP!%ARx!_L+@}#Y3%BO@tDm5VRnq+s&>)n{3(LLeqaU;fzDAMSd(`L3%!c<Q@XsjRQ3a40VTT9S3^V-zJcy>nv&LI8~_vr6dF7F@9 zWp5tmfFV$wQT*CJ?D5D!7kwsrOX_xzlK>_Y{=FUmoCc5|bnS6&h#g_gu^m5bC~!`7`6sRlpu%=DvR9$P zD2Qc4R)M=_tH|Aqpz3yHL#>7(RN#}MoG_Y&a{Ok~ZADNmKXO&6Qk@AS+j+wJqt=F6 z5BzmEh}wwLxs93^*iDz)`EO`nG+WwhlK36qJCYzhqbWXH@jrkMsmuntUQ{Q`I?bCn z&vu$Yl4nUJf!ufDBIo?qc#G>#NFLOefGtHmAO%gA5+E2PRQQ(cf m;KKAhp?5MJPdU@GCq8rh1&$Ze=SSb8!{S%CskQ_%>G;2icajYN 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 zcmbu9&ubG=5XZlpMjJKlOG|}fRaOX+ihU-vqIjs4MiZg*PzYKO!gjlB(573mTWEWz zLNE5_pWx9yqs3Sd6oTm8V?d?Kf+wLen|aA*NiX_=&3iL%e(jstJij-0Kc;C=XqZMv z>Y(>^_A|kD27?%YT@>4U#hve?#r>x4i=livv71jPeX*TSCz@nv3+JmXoTe=f_eAEi zIQUWW#bU!3i|>5#_=_(d)rD+qo%O}gNIHlR_r-QRUEHaUzV$`w0tFG7x-AYr*~0m# zg8sCH(+~&0OSW(hzU>D!y|{zI?CfnlQ$xd8DRcT{cJf9xm&@vz1#4L^8Xg}^ z+#Cnu0CWH+02Jm+h(X&Uow@^!ao)4 z!NlD&?9m&_6UVQkUZ;KSDmn}VTdKC3VF1G+`=AB@=K!R-O#?0+qla5I4byQewlpE< zW^-V%wc03`tLrPSd7Wcks`_)(!eo660F92)yCM6NAwBhgAbWb+NO!a98B36^ zS8J^mwX0bxhV-lr4|3V?49F$dg{(OwNYnMEAWf%QwN^dIRmZbrVZJosdWQLo0QILz9F8K5Yb+Z1@nQny<&zhsmKbNGRl)+ zd6d`7tPg#@0q^-dikf@HRgU?u{yEN1^BLv?3p6)jl&sci_Rofm05n*>7SXHv)mmWx zC_O*89<~nw^hakhWEibW-M_-&m|ZgsAj<{bQie>_|LHOPf5`z=pQ-=!AEo@2p3+2f o6BW+?hVv#lPt>1cMte`BIOrAjSEzee3?1YDn*BGGArtlg3%10m82|tP 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 zcmbu9O=}ZT6o%hvtBq|lL{SLT#Vn$vV8 zf1tm`mCIt|BJ~f<5VH_BibZheLWta%bCNiwoBF_T?tSk)A367s*AJgQnvozH02Bb{02GR4%s@I68vj;__Os-0nXI(8 z0jV96mY3!u2NJLb;3}P2!sg{zUXJHwB`+uQa_X@hd$Ax#a*Jg-{y>POXL5}0PebIN z!_VQgv)NH~W1;{qP3V3N0ImR-mPgb&O^01Ebfab0>Z$=+1-6b#rLj|Q8@D*FK=ev{ zzlQ-^z8Ywvr>u(}3&glgj0~XKyA4OLLbV+$ur*#;W?feuv+Y3L)Eyma)wZD;twzIa zI#8P}$5ac&@~Z9V#w*&tZ0@MrR%_d|oLvMF%vxp3(iQVEC`>T>811%EiXdw95XinKjvBe)0Cge~pT&k8TEp{r>>%Zll`( 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 zcmbu9-)qxQ6vw~mrkglp9SXt(BLvyNUen=JWN4w)R+wcB27OzzEN*jYJCX?7DEP2{ zz`wyqpY|sd^}+fd#K>@OK8Qcwh000pY16p9%nyWn&$;*f$UW!YSC1E-WE2IAf`=GL z11ckfc_Eq>pyC25``_>Pe7%26{`Fye4dlbtk7mE+H>2h^> zM$6w3vm&p}8nbgoK5uB#OZJ*pF@3p^yEg-j0?+`Q0Z^_kBLk&FI!2K)pTT9hpzJL{ z*~uzX6Jz7A6+j1YO|HG5v7{DCYNezumeg8Ft!JL9+h5lt!U zVJ-ofOze+x0dN&Sc6e*V^%L|rPte0#u}rJwIl_WiC>n?*Sf;nxbYN{Z%ykErYnzTk z0j|iHbf%Q;pI*%Eg#K(oUry-968dLSp8-Iv$9|}G1nKGPBfQ;)Z>~akz8jAlJacWw z6u!OVL#&y;39;&V5N?YEVR?T3E`-%;H0-7i(QNs)C|8$ro^M)PQeJPq6x(iV+jjk3 z#QyA!mFKS6u=@%8AM{_;6LdC7;=6`^U72)kr=osBe?PM*52-E{=VcsjPU;ha>QC_# z*F55FJp2RS59SsS`8=(CUdEqfhmr$1rvH~^9_cxtoD4RUbmYkW$8i2UR-}EJpJ|1J z?U))6_3uzm0{A62r1RqQXSQYhw7n(+aUU>g`>hk|e;^%lovHrkWUUC+Q + * 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 zcmbu9L2DC16vzLYRvR^DH=-8Gy=0gt@l4`*bT3gwYq+9>CbXl!IVkIVUy?G(x#&wl;6V^=;U1K#k9)A8*7 z*C*eTH5%*dt8S&yY%ROB>!L1dZoOK+QLWXgZe=UjaXqPcVCCj=;+O~E0yqJn(QF|H z>yR|PXN%uYC9{F^+*&WUVC_5BQeh$g)&edfeTX~sbFb(Oa~nlBEIOOTJiDf$IP>^< zJUs%;jdwBOG=Os%J&6Ut2H;Gljkz#GUz(vK-u7kG6+Wne9|f`p|5+%zkV^LJdf^gx z=&tDbb)0e~qtl&g{dPt_nbGO)2`Yz7NdO`~2$gI@#41YLUEPaO*4EhS9KTv^aG+QgNlKyjk@AhAay=br(MCt(P3c>DnCz4^nJNQ579F$8sTb8u8 zxh680xuSf~J?iS-fm`hNo{_I%C& literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_cargf.c b/src/openlibm/src/s_cargf.c new file mode 100644 index 0000000..41e320b --- /dev/null +++ b/src/openlibm/src/s_cargf.c @@ -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 "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 zcmbu9&uSA<6vn?vqm3Fn6X~MRg0mPT1$#|`qI4mJRx?ToS{hfCI+@HQV*Zqw5n2~@ z(Um(N!iA4f!8dTzrOOI#BwL|!X3j~*sX@>mgnREd=iKkkJty<_!REu9ra{nfACuLD zliXy!7Ejl36-D^Aet2vjeJ|UePR)^C+OQVhZCFe3tT@sSlXc;gQbxM5L!z;572<&W zNH6VJ#z-%1Tk~PCZ?>TA8`@%Vw(wp{^d)}Qrt#5S zCHHKuz|uKr|2%%2oqGUaX6!!U3V>@VJ@x=l0$@zS#w<+HuTRkt?z&FU@s*2sgd2EH z&xiZ6?{s`Pku#|I0Ltt@cSOIRX9-VJI^Ct{FH-u&luma}P`jjB22kNaKXO`7VH6}| zS7w3Nb5!K*M^J4ia-dpa2;~m@eQyv!4Th1Y>W$_~7&-1MUUvqs)m|{%^MdFA$qrt3 z*AJY&$0ztd=sl>G^loXA-p9C3Lbg_me2)?@6!=nX7A~`oG!)gBxWW1iuZ0gX$sm0# z+yvr1|24nL{uSAf5&v5vFyb%cD(7eUk`)-q6CMMY&Grz06As9pOYTo-vHx#9NO!_U zf6IS9rG8I%L#Y$hkG#cSbh62M6ZhEvBOjFh|5T%FK7E(6wIjZAKJ`Z$mdDWd<4^fr MK2&cUnUKx@1vD~=KL7v# literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_cargl.c b/src/openlibm/src/s_cargl.c new file mode 100644 index 0000000..5052133 --- /dev/null +++ b/src/openlibm/src/s_cargl.c @@ -0,0 +1,40 @@ +/*- + * 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/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 zcmbu9-)a*<6vn?ztF2l~6fcAd?!_Q2*y$!HmQo~8H9<6JAtPpEL80*RKwFzma1}=s@mx&+g4esyl-?gOO>02s+RAD%FDLZSPzw( zrD~X^s@*vGviCjrTi@B)a#!ok)|y+nr>nZ+R=w(duTt^c)!pF0ZJ2~N)*q~49)Jtr z0)Tq6g%X?*X@bLRdD9KvaNh62IVw9VOACu19pw5g-g`;oqvdv~vAigLY{=g{exBPp zF*k`ePEcDES_9DWaW63)=s1bS* 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 zcmbtW-)mb{9RJ?6+v1%4CbNU$ltl<~1NJUSJFNcuuW$Y<5Q^tiE*Z5 z0^Kz}Dy!|bz?~I=-uChVeE*ySAaLhaz#q?8= z{nC#Dy-mC}?&hkasThmrDaXRM47HRQ6&i~EUPG* z$|5mdRoA`o;H`gKt&Rm9jX?MIgV$TF78R8+FgP~#_tSs99PM^_{VLkG@m~9Fe0221 zq&q%2ola(ly_}a#<}$gHnQS(bbkA1G$q7Hy2ZPV20eS%-2>?{V@yTh}2hIv{-1Cm! zKcXG<>(yC43(iv9Id=G9?79Q+Bt##=#6AER>&x_f>Ky8ejX$bY_5}Iqh2Puxn&@dq z@i2N+)DMH4IMAzdA;k4Dt;Cyq0^Kt43_gEC5eJxV<9HW7rTG0|j01(V=52VIXMc<# z061dgt7-@UFBrL)phmE55YBYrU+u!b)`cJL!cTYMp)nKqjrj#HfWY^LAPBu2EH8Um z@baU>^cbQ?jvg6$oCGBgLA~NvA(*fEa}YEx){oKMO??Qd?LZu#Ffyj8}{EVpkwTh1Ae}M9%6510m`j4Y$ zy8(L!9n&>tdB!K|CmP^GT{P-9^22j;Knp&jdFmMxtY<@CcN;Vh$fm7-UHi?nB_r7J zXSILoDHE*EaWXi5UQcz=|3dq>{qdgHyw + * + * 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 zcmbtW-D@0G6hE76+gQ__oo1ClD=sq1RFcVVKD215#ca(MmJmy#yRZ-^o1LVXWaI7> zlYp_>YrR(F^Lf3S1s{`P$Q z&bc4EAD>OXRTl~YBLt^mceab|hTZow^7RZLG=ZDKx%t%PN2ye0GbYeTnkPR?ny2Jj zqrf?T-mpn70wZa&L11KnzA}<#SfG(My962oW?UM_*>J=RqqXef);!wFvj_3Y=OF+& zweAYcuA%k2z|13o*;@iLKcV#tM%S_VIX_RXg7yMly&j^Z#xq2sb~BkYfqbDN`=;% zz=-@tV0Infm3{(q3$koeVD6^0F_LCXhL2(NE;dWKD%PCz@ta)PjJY_ujnO56bMsQ$ zHa4sHM$&A-rN4d?Xn5vv8Lfr&$bc>uAEUK_OVvS)-gdFLy5pN&LFzJR5-TqA9U*)~mUo~bYYdq9&Ed+2J{14&FIsiD=)L;KF zbhxP@`LuG`7nCOqe{gwwP`{&MFY2Z0y=au0!w^w4A8$kPJm>LQ#WR>cCW(Vg?|^y) z`|vMH{=k0}y{z~k+7-|F7+nBxRI69^5CC2W*r`d!n>F}zHTeD-{5v)H?izfq1`p+- zyi>j~>Dqb7J9a1JJ-Y*DXYB;o>7Finbkd`P9&vhfgYN+OQo$K_A%9`Q8Fe9F{-ET! zkRLCOy5Ks)Wfz8qCN7Sb^PN<`rJ6u{lR3pdXynid6?DV`1>Hr1pk0?H<{{_vS&Kk#W(|FRz{D8(&UCd{-_^9ztz@F>+ zB*1f=ue3OHrkKB>*&ovQZ#7=m^F)h7XOZJXs4)PtKYG0_8h==`w-ishk81oW&0dc) zpxHNT_A{D2T}-U!N)3De-1|C}i4VIxGvPVIV3)m;KaTNRsW9%?USZk;d&Kb^u!qZK zuuDan*!i;8rB4#CfSoT+OcW+PuqTUN!S3xFY%6@WR-T zTXH4}O3VKM)kjMdyz%`1MCvZr!1pVI?n_z|wr6a}-*JE`)inQphMjZPq6}YB`DxGS zSl`p^U8wD}gH{zY=)a--IS+%+IU}L+)1K17{-j$6pBo-e*YMv~`Gfu9Ige@OAJ>x* zR6+jl#V)vh9tV|w5beQ+D6k)cwh*1;V7ueWKd39%zmHV@p#OWy|0E|;2>MUg*gyTs zkk^maf$jtLXP)W_<|cfh@^7eu>9>Mn1pVpG*soR7YX1h0Sg?O|r|suIrV@S1g)0R8 F{{ + * + * 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 zcmbu9&ubGw6vw}twl-?*#Nv-a6&4SYq8*b|v3RJJqKQz76pAer!#3TuYLk@g7TR7c z6g+w8KO=b4YA==w>dB)=MM2%OPnRzphZ%*7wSr!BfqiBs< zJnv}r$D-~SdT|V%`u@RF*-xIzekpB!ONVOqRj6j)hiY!yQ`y~6&FpzfZ?ES*lUJxR zC#e;e*nDO?RI|IGnu|^C(&kS3b*M6DW78S^7)*dopKlKk`wU6(A7bp6Mzk%3qWyl8Yx&WNt3;? zczl=>o#575pMtfTu?Bj&(_0pB2Jw%0N}oHunbhqgz3CfA*`qy_rxQQ-+s$?~SJ9#; z>UJUBk|K_?ZgPtCj4?3)pf3?WS~Gxiz+bjR_5dAzx#IW_YKyu8JuzOOPo6%*i1oNZ zxm;aYTBr=mGA?k3_PQIuul*P?NCBWy6#X9ClTJRO*AsDQPefl!*wfjH{^S6AssV!H z)31s4*Q$Xt5A6qyxLuT9!(DQ8;I0PH3r^rb&-*@fqfP@|@q-cQO1)ZjYXNkv9=N(V zIX&bDPUR7g@7GrJa-+WNHi9+8;oQZt*Kn$CGyi`=|BGtukP#=o+gz&&+SLi|x7Z6? zyh&RuP?b|2smp%W&$FI*RwDLz-bC)5aFJvFtAC#J_entJ9k;ShLDnzrDEsHcfQeox z0GC8yWc|_>+27=}7#NuHUA`ZG)Fgm@HZ<2I>lWyKkg4fkV*e2_WK92ueBaFTxA{P1 z|LFYbjTC>;+vO%UIR8h^OYa)hsOe8J&9f(F_z%(fCgHG6=v{2*Kf + * + * 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 zcmbtU&ubG=5S~p_8@25uMX}flIRr`3K9jVfc&OD@(?cmz3~iwhx9P4`n{3H$q0ONd zdhuqD9t8gp!J;vqlpqSB2k}@@sj?tF2$9*Hm#j;3(GT|h_}e2dsS0*f>|UaqhK^^B--TEu*NG zvNlF;$3iwn#$%l}Zj8r5d!%Gz_$2i@8b3%5<29`OB8gp$S9CPq**N#o#@SCc&X-Zt zO4n_S^v4{bpp6^B*u+-3_mz#|Go*v@vX1-jbu`{O`Z^j1IvQ21)H6C7Z@yUddfj8} zHL6LYuTM#8^C~p}n=c?eHg+W%PfukAqRC;A63J*Pk-C^jCKJ*4w6++XP%T~XTLI_?_ap35bE`WVC>`q# zT|3SmhlAn-;b;A@)waein&@(d?ascv=waTEQ_P2a3$))JkG`{K0EhuV*k?;P*MbK# zn^Vnug(Y3&KunIMs7X>Y1iaw(I%Ko?)nzj`ax7t9AgeV#S{ z)j!Gc-TTo*KL_e;QVyt&2(lkx{{-_AarVC;35MLi?5UpR*o&FN$U|&r_aj$h-rln1I&zdvdE bb5D4}qQmSj!LkiRTKKQA=z7D_h2Q@V{fg-t literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_casinhl.c b/src/openlibm/src/s_casinhl.c new file mode 100644 index 0000000..33ae217 --- /dev/null +++ b/src/openlibm/src/s_casinhl.c @@ -0,0 +1,56 @@ +/* $OpenBSD: s_casinhl.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. + */ + +/* 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 zcmbtUU279T6g}Hk8~d@WqEM(0`w*oCyKZ7dDSkv+%_34lrP>!sx9Qf1o3v!N(3XNq z{y<-R@L%*r5MQh$4<`KsJFW|&FMgDQ??PpgJDYUdBIto-?wpx(&&{2gJiC4GPKP8x zK*9~QW-VOpY{jWYm_k4LV3c=az8zP5JFc=_w#6!5-TTVw-nLiuf2>^({J;x78s#0; zUym#PwfHwKHp*3%ZLwYU`BRKVJo2;IW$VrloiXWQ2m%+DjnKOQgrg$JC+pv> zFbd!-t-a^tgsd#cdPY`ed*s-7?|pgTmaI<5nFq4+P{cE`LXrdE{$2RBcVGcPXINbe z{Qyq2@r@b)oB?o{39t1q9!@rAI!}suTg!o>=4d0EEiBtBxl256lB{{J`1gCSi5G1= z@2TKlAHnn9b9B%bLUUFNt~m$IaZAlHFQSrVo0@B_xX|WJ*Mv6bIM8y7g@RRdp%oWh zOG{5qk2tQGdrI@i#bs@&w76uI+*LF)So!Qi$t+l*<^O>H4t{3GBT1TX3*mVPM0-C- zeH8lz^1Lzpg%Qz1J~5gP(0HDBaZd%>{tEU%+;4#kKqKeB>J#Lzi-ZK>e^C&EkBnoa zk3tt4BZ$&>0dz<25D@C4b&387%#lB}JH#v*WkRNjsQ%Fr=eJ1-#X0fw<65B?JhzE@ kb8M3T2Kn|j-v2@U3F4zjQPOjfg=qgy9-;q0diyW>Kf`_2KL7v# 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 zcmbtWZ){Ul6hE&+7=OGiXp{tTHK___JiD<$A`@Cyw?ZZi%mOI5meNt6`{P=)EF&x# z0U|L$6C)pqe$m7aelkWs*lxqvb{Z4Eyt}s+7Gtu(vPeRRi9pSH@1FMVvVQWHwD;cM zJLlYU&OP_McmBC(fMF0=}F1IS(Gq`J>KBx zgj;@qbL$~bo5LPAKIRKNdvmT}m~oG5Xu0#kl*3YWEv>e|(`MY`=4m5u#ywu1HpXZl zo;ET@o{t;1dCr(9=B9t;+2RfU1p0FGexcyJSf>FLi~{Fbo;F`cp67xeZ^23MwegfzWj?Q~ANS>8#(=CWcJ93Ia1E8f`+J-eNYOiVllK}9Xc;-X{e&)L9 z@U!)!H31e1uvmZ%1XwD-Mzpt-^*$ClB0mqakmD;hqB%k=)W3?Y_cK>3tKGBuLpGwt zS*VT0+SouFOSPfQc@}c`S)Jak z6t^_|Eahh-T06U}1=v+Bz^-X%WH$?mK$ZaJWf|NpE%69y%2`{C8Y|0-fo)!cWk6fu z86egQ-tPVO*&v<~Jjv0xLGT3P?QuELWxQz3mOtjvD;95cv_*Io0M4B>qdmI{=_o;(wHQyrW0NdP3n_#5%9=bZ7ri__$c# zR(P`ix5AVBeTAoeA1Hi>SZ^1N2IE5ii9fCI^+NuN;4ztvf$Bw`P`codFrz}6rSw(6&~#&+7+Js=@7hH zho`E@Cl#Ld9g*xfr959&1%-mWc)WH@qKtWWfv(FX?m2cmd z-aiDj=i~bj&z$55|E#cQo#LY4`Qkp$m7`peiS^i+s;Q3lp4+En#v-;uJU z4b}e!u|L+74ANKSX-y-34x&%0en|LF@e(L38nF+eKE5|)#DoBT56GbSY3vgEDn6$T z6p$VPO9+o@QEdajHKDKirN(nk?62zoBJ{0~Y6+@-s!II?MMI!E!6n{r(kC9{QTIlC sD?Y7miGZ>9uU + * + * 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 zcmbtVUuauZ82@gzby>URyBSl86PiJkTUl?DY;|==JJxmySSpMb6S!>NruVj+O)`>O zT>IdLo9{mQ=%e71PvTp<%n@adGBzma#`Ypgg>FX}fBJ`drK~K*E4Ah*lBa?}@(8@Xs@lfJ0EY@tegkIh{5cCMVPVztA2-b2i=2(3EuC zN9&f{a?){z=4&MAqqXVd&bp8G)>?d}$H(CZA6hwM$?yUO~R_ZgapL~y)93{5hErIyT=Vd-avr8^8u zJPpd8p|jhR#n6i_InuOwy4!_kKOwZnw!e0DRus{^a+&Pp^fmXXD}g zWW0Z9a`w+-2f`zU&GG8`RJJ^S`E3A@ym_wg*cjv|CQhfU{LI{7Dtpq-+1XSslN-ro zvze52-dji&+(2v$of-t#3jiqqpql1q<{$>fI&res46!~C1_DRKY^~r6!Dlqy7W}Bjp8$ZvN?yEX0Pq&TKVl?M zBj~Xcrn>O&bm5_KvFrwJ)h>fQJ&~g!L&FIgPSP+!!<#gmqG1%cJe2F6yA0(^6?YNH zKn|8`ivUR;Mc79N0pPE8h~o-R7f14^1s?-|Jqmwa;i>Q^5=6}`C3jc>SM}G)MdR{VqIgbf_{k<3!O){+6mGR3t zFZ6XR?rO3KQcvPN(eJwWk|6ZBWZV)p;a}JPOc34jm$=;J{9EGbmgh|8PxnmvmptX8 t`zCA&^14Wv-XyZ2>yu6W> + * + * 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 zcmbVN|7%-S6hG>xZH@Uv9Ap1b>efRUu z=bUrTJNM?w$+1%{fdD83U;vt{CRW;-&q?{11cXj-QnOL>JBWL^`IAew735eK(71seU0?1N~o3pAvmAw`*=kpfJ&%2>T?Xl~#~-^$&l zAEQ}yaQjbz*;@iLs{+&Cq4oVz8(y2P*XtsM-D?8V54JM(h^t}d6|yGY!R>oB%-%thf>Z@& z9@TK_w!rkAC-?uU*Bv}EOy4T|_{rP#dL00+fB5+_z{(&13~u6R5@2P3yg_)M*9zaf zH+cPvQ(Zm7*9Kr@Xz0zbIWj(ZEF9~z;#MpikH-6>u~;;0p3TpOQ?|=5dQKbz*h_8z zfYKispM(|&tP-bsFu?15G9bV~o&!r~A#l+M9NOO={44-)7`z|hR}znQCR@Jl=nS5G zffdgNneK%@Xq!8*r;$Yy`{iS+%v(o@c|TreKInUKh**<2y9o>nD);P)-e4l}iQJJ_lCCEqn94dMf7^Y|G7GbitanT^p=(l?qtp5-qG; z#qHA<39xddLLpyt!77&AyfrdD*;8@t+y}g#D=u2+%cb-AvU>?U-}(6&r)(GUjbxr5 zv_IOq|HOC~6W;|I{O5trA$=2NuOKfWx|_JJ)LZnZ&T$tT9%Y_-Nyn@IDRvX=u7Pg$ z`MmlV$3M{U=pn-K)qSZzdnKruE^^AruTQXE?NdSRU(N5bKB^2Dr&;gaLrtjtt9gR; zeq8yV^_vBd=f-co!h}CBmAArWj_=oh#Y93GGW_}ryY$a5^8Xkb^`riwbE)*Iu2ctq vY{C|kD_khL!|0#Pucte}-#dhP{=k!R)r6|M0{w42OaB+=|FJS;`1St+(<+Jh literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_catanh.c b/src/openlibm/src/s_catanh.c new file mode 100644 index 0000000..3e3eeaf --- /dev/null +++ b/src/openlibm/src/s_catanh.c @@ -0,0 +1,62 @@ +/* $OpenBSD: s_catanh.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. + */ + +/* 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 zcmbu9&ubGw6vw}twl-?*#Nv-a6&4S&MLQ;`V)0NbMH8VEDHK~M4cm0rqD@k=TWEW+ zQ1IlT|BT>GtG!q%s3(se6$N$ALgnqgm&7r>=m)Yh^PTr&GV^90-=4UWvMdM|M$sHK zdEU|NkHy_F^x_13_5FjdoKL=Tz7)5|0qDM9OLV==2WZvCSF#|kDJ`z z#>a2iPGNF-(9T`ed7ZQK+5EL^E|;~PDR0p(x*<;tT^|HG0oVY#02C&tk%IM-G}#-A z$45EQDQ>NeDOhV6YoMn)y=?*Kko<_J^tsoYN!>lxo4$3NJ=#NgI`Q+M-E2o=6-|2L zZWq!`Ddr^WCTCdB7!v~k`dZ@0YX)!u_{)}X4$%>m%5LaZmvk9=Vmwcu9DRn7=t+Z8 zsj|AfSRR&TT;dMxbvJ-t2MJ=30zjoG`aIi{PCla7TH?^2h`!!pPiHIolSAyO1_+8z zzXm#3uY~RbbP(2)c1e15Z`swMw-!P#x}gib5CqWm8Vz(g2uGmHwMxaShS1eo=;^}b z^iUAG={Y}n_fq^OC=lk(TO#L#`J&4_su+in-4_x zkItXoNbwiFU2bBN^MB;L^sZ5jn*J2iJbPk>{}7#TD;%}~y^HPqM_811LNNV*1HV?q AcK`qY 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 zcmbtU&ubG=5S~p_8@25uMX}flIRr`3K9jVfc&OD@(?cmz3~iwhx9P4$n{3H$q0ONd zdhuqD9t8gp!J;vqlpqSB2k}@@QCW~4gvjj9OV%a1=m-0Ld~fEPw{PaX2REi~1{4J( z6c~f%tck;p=6Kv0jzcf>fR4r|9gPDWzwb@$eC@~hd#rrR*tk%&ap9GXiyv&9FQcfI zvNlF;$3iwnCS%<;ZcWBQ2c%?U_$2i@8b3%5<29`OB8h#BS9CPq+PLt-#`%vnE|yW$ zO4n_S48|Oxpp9F>*wjwB|D}!LGo*v@vX0;1>1e!h^mQ~2bu_A2sb_RFUVpag^}5H{ zYgCg)U!IWE_El;Cwx2_KV&Y0Po}S4JMU$f=7r=R^j!1T0by?DEp-WmX%*dmMUINvswymP!ve9aS}KSo z(*#j8Xd-f^H3}kUS!`|(#z0>C`` z`}ZZ!U&3HbzyCw_zbp+Ie*b%I@_&aDBJ)i7r#DjiOP<2`V-xl`evRW&9;inB{-o*8 aJ>fBnj + * + * 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 zcmbtUU279T6g`_(8~d@WqEM(0`w*oCyKZ7dDSkv+%_34lrRs~Mn{;cyO;VCAw56bu zKhPH+{1<%@#1|{cgGv9uj_ZQxiyx)nyHJ_r&L-Wq2zp?dJ7?zHb8}}V&u-tl6Okkc zNVtK{tb?mPojBPFlNiDvjOtF*vtx>9$5ghoLW<7W>AO(TVpkM+x_BwZ|(Pd*QnN`tWon_pBZn-_<4TsCNOJM zcXV$(wl5uP7}a|6=PTd!UDhz(bQJG^v{0}{cL}6zEuN&GXM@V;k6#dqms#)j#}ML`HYG)|H} z3|(vtAxz%|&=X6wL&j=ZWH$A k*d+fA@*QZs|AYDy#D|fjq~}5l;r^XGLjQsE_FwdW0BkDODgXcg 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 zcmbVNL2nyH6n=J_HcidiR1_h#QWms8f|A8HNo%31brrWZB8{S=h|mM+#@!?p>$tKv zA}xVN7zq#@a)c8S;>Hi)!ok=P>RLI#ZKsa6M7=n26g3{s zd-L9#+51<Hxvx{o5Hpma zM;8=kC~Bs(6M1AP5x%PFRG4KyaDH?4gcJ62JYxI+Xm!(a$F@~B6nXlFv(-JEQ**Z1 zF00xWt2vLE%$CfYpnT9vgdG9!O724a%_*HLk|wcr-p5jm4t!z;*qW zoY7307(PD;a1;P!0Ko93C#E0>fiiNUwgMy{AwOTBK5*|k1ePO#GojPwKsL@;&M1hf*>)BTarHWiCs}@jj_{<|OU( zG;r&quqVQ{4@Wv)cM;-4UOfBoJeNF|h43Qr7y~cPaG?hxUXo&m(Zd*e@hTU3AnGLn z;0*vcPO$Caam+qM>F%9UqHg^AY+c|CC091_|VC3fwZU#=f9gkBV0Q^h!8~5;-MZtedd=P-wlHh;!tjAml zzT#Prxe)wiDoo_?HVQsXJnoO#7W_32kJ%Rd2Oj>ohrjLNdp*3!FYb^34%Fh^oT<%% zS~Lr8zaT~h-OyB1Up7I#rI{M2v&AB)g**yswrIxAd8H9hv-w<3Uo=5o%$vHJo|qag znp*ZFlIItf)H{Xz9lc=Q1$T3OVP>wN<@Am>&kQ^t9^HQ<+;0eU>QumAdw4%ECt|(8 z8eOC(L|~554#pPo67{bUFWwmeM)~l=PY=e_ye7A@l{Xgzz5tmroPn_sf5tPszSt z|0^OEgdu`ofBBI5S*532)CtxPzBfW&@OU1-ZNw8IC+WcWW}G-cA31;RAd-}*ce&Js UKYsW + +#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 zcmbtVT}V@57=Dks)Uv)MT^N?0evD(}X;`%Qn~pyFr%7%~_cUi&An^Qa|y@xrSUWmpGTpZ6wIuIu0N? zfBQWE-1?>hWD{c@m05D9gagosy$KyXdo(>gtr33)U1cOS!|NU-@>rGB%pu#o@kC?g zqNJ|!vP2@O&xc8UJGC-t9vnAmWFpMTL|A@`aW!IZz&IKinAeDZStI@xjriAOA}nac zzo3zRdX8)V%Yxp&W;%PP5#PbQA0O)GFx^)Y_d-g3m(W29)5EZ;OazReYQ(pqk%2{- z2x*P@UTdUZ)yP1ao~bjW9yH?9&u8>IW$5v|{qo@rJW0D(E`EHz(4KLpmpU(8-u&U_ zk7lPb9pCmpai%Sa;)YY-B;37_R*QU(F@$TovW=XubAXO=MT`cPGq3WsJKS^!1prPDSRfoS;{PY` zxv=N(Zp_GkyP!}%3Txlg>ir6ao?#S=1^| + +#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 zcmbtU&r1|>6#tArQptKI5ru)@}G9&c5&NI%q_FVEBIDoA-I2_kHg>le;=_txD6N zprHq4tBm^U^1e6N_Tn%O!J@g9#kJGE@8>T2elACkHUTWYS@;TIe&Gu+pQHN^0lav& zw6xSu&sX|azMZP|PTV-tkhduF!=mkv7Hz*S(8y~HXr3xyEg=Frb%mQtgC;b zA@HB%cLiSm1ew1EKmEO8s!Qr+91OOy%H3!J&|DE;(sssDS&5clPAJ7IB)Cb(*&*j6b?Vtx{xgKK#ebpDjfe H5$68}`gqKX literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_cbrtl.c b/src/openlibm/src/s_cbrtl.c new file mode 100644 index 0000000..2fe0360 --- /dev/null +++ b/src/openlibm/src/s_cbrtl.c @@ -0,0 +1,161 @@ +/*- + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * Copyright (c) 2009-2011, Bruce D. Evans, Steven G. Kargl, David Schultz. + * + * 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. + * ==================================================== + * + * The argument reduction and testing for exceptional cases was + * written by Steven G. Kargl with input from Bruce D. Evans + * and David A. Schultz. + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_cbrtl.c,v 1.1 2011/03/12 19:37:35 kargl Exp $"); + +#include +#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 zcmbVN-D@LN6hD*Q?xwnW(?vmDArYpMEOtz4tBYv2ZlfKsR9zZLMRrZoj9pAWNM^As zg+v-ZLJ|BQ1Rv^ykClCzNfEaTLRNj4F>R$uph>epIzO5Rnob<+*2S8l$RN~Ibra;uS-E!EtM#11}w z=EbTRJ6JuCSmmk&uzC<+l_@S9vPzZ|5yn!iLGmbPQHwItfs-1EIozw5dsjYYr1y!NkuzP`S$vM*|?*?OeM zdGOV<8e3@n&R+jYW6@oQP1BS9-eJ=UD=r)06(eVdc`@2!`f>8Wt-NIwrSOxn@wkXt7$g! za;v$u$--r{QP+}k5br~+*09Xpn*P)FJ@^JMhHWI}-F~+OFd$t3*jqYuU5$m40IRKl z#m&@geQ)E?b?Lm-mSh>oeabnoji$NDJBdT{?@`( zWvQ^Zlq=}hpnZ03?y^?M%;!4E+&Qp5EZu)|?QbP??~CA{lQVn{p<^$wkCy}h%S4=_ zIAZ=DApTL}$-IN%e>J-cx~2{u1K?-gsegjvpYEL4#yN^F@)QvHi+$t>|5wOg*a_f_ zBE>vyx&yv4@=(|AQ5&mV${{vx2 H@caJ*FoSJu literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_ccos.c b/src/openlibm/src/s_ccos.c new file mode 100644 index 0000000..faafdb0 --- /dev/null +++ b/src/openlibm/src/s_ccos.c @@ -0,0 +1,91 @@ +/* $OpenBSD: s_ccos.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. + */ + +/* 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 zcmbtX|7%-S6hFy2mws7pGA0yPXuvml!|s{XZH|F6qnV9bs*Y3}3Dz{pTZe5ElDE+c zTOI2<3L^cfKlu-+zlcl__QTe8ZngVmZh~X}QYXSH!n*g9!t9fC-nlQg&*m3B(A;}J z_ndRjm(RUPr;hi%8Vm$LN&t>ReN~sQTI=&9O_LxX4CxDh=(dRVX(3xgQ(EL9?%5)e z(;~KrxNwtZ3VliL?AFY*ICsMo`aPW7NzbmQ7k-bW7aqoDf7t6d&eZu|=<_efc{G(2 z^EY3{iMX@?0Lf`bOn(ai&Ff>t=7`@j~tpKURC2W@PT{nZxPyLc}8 zUlN_rd_!Es{7vENyHz@~eExys2uL+Aii>Xt-Ed6t=$b8}MQTllCZnTuqyr)8cG4siW<0v&dyFo-)!9d-v%p4)+pm%-27TNpAleGl7p*nGWe59g^Fyn0z z&DC!N6^v*@1w*@{7LwV~eevCt;$|LQ$IK;<>h)1bEuHQ6E+Mw(A-BgpqRVSi7Zx<5 zwVOg;wMF(fEWauA@07sShU>f-yu*aTM5tk2oi!p85h?PwTW3BqgUoTSRj!^aUMS`c zb%#`B@MIF9n{$urzCgAA=85CXdG8JSP1P@R4(}sU&MS=f;AF6j?-Hw-k9g?f8WxFV z^%Zxr&g1Ho++iV3lJxfU9Es_@{R8`Ai33Krk%)E2yAQ?_iFiyuQ7XpLd5bspzqAja z2>@aMfR99P{{RFba1Al}#s+xZ%m?k}G4Rm|2uwr*d)jt{<^lkR0ic8T%IF{!j&IWf zE#XkQb+jcM%CrW*ZV89_TQjtHza<=cy*0Q_`|SWQ$hL3dmZb)j}pRW{2rw0vqa2mqY`uuD0YY5)Lx0siG1<@pA9q5*!W z0p8O9f2RT7*8oQjxV6|UZ#BS?h+F9oa2+bh0RXq3D7B$Npi)lz;G3a7^MC&A1Q*I;O9v{;&`3>8Wf6)2P|leJSP$DwwL{zk}(oC8F8#AC6? zPw=bLaU85O3gXCNiCc5FEP!IsNDSmb`j`6f9_?Hdv z9~D1nBjd3Z{hbOf@IcNttl$L&7YaVF;A%Y07&QA)^`BL6_1t3$j=Yd@4k)-9&#Z#0 z_5W1Cv8U3{JmVNHzEu*xtmv!p+*fcluZ;${fyL!~RX=YixElX?1y}q2nS!f4`GRqb zA72j{{}n}lhl1mML_vLS5lPM+JY3#0Flv)yR(=?anpJhj5jm@tM)QVMny|nq=B+#! z!?hY1)iN%OLd`m?E)s{pD3r&>O5+w7<7KO4^!5+zuUYxRhrB*He%h#1%au~qngrK* zX=KQ(=Eq7L-2V{F8>#JoVcp;K09UzQQv7ew9`2#km!k8-f18VmoWOG!2K){}d5&?W zi6@TlTq%4FJ?Ubf|J5GffAqP_^TMpddYKc(HwN?c+v8i}=MKs;Dg(fK?%;{Pe)wi?Wv}!9$Co@y ISN!(>0NC{@dH?_b literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_ccoshf.c b/src/openlibm/src/s_ccoshf.c new file mode 100644 index 0000000..53c8e7a --- /dev/null +++ b/src/openlibm/src/s_ccoshf.c @@ -0,0 +1,104 @@ +/*- + * 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. See s_ccosh.c for details. + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_ccoshf.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 +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 zcmbtWU2Icj7=Bv{6qtQmf;a0YU(dnteDq-*@45xNrJytPu$WS&3`@+oWS-Fim7Isri|J&&E(%i`W=SY8^~CA_Wtg&&0_~CQe?id|jzd-EthK z{0Kd|9H(54;d`G?{Xr`{vkU;Sncr~cDgex0$C;}hfG)?uZk)5c09_9i&p(HAOSJs) ze5?o0?DPPje!<32LTh0bD`{=_XO81I%rBk!qO%9f-H8Fq5##BP{-5JKV)3n87jN!R2X6H|? zi_JJVdx1weyN*X$F5}!ipm>(1zH^*1*qB;kW_>vOiU+{NpXYfbn76rqs8?-FT|xaK zb0o+Tv59#Z?3-SQy?hDVW>}SN3~uA4OMQj<_be#CjVW3UH6l+^FsW-ifKbx4L5ble z7g4`>=WT2Q6Z1E0OkcM#^(A+D<6+i_NZYfEg# zu{Lub((^W^s{GC0iB+NjD0TW^I?yT2Q}cW9kO#)Tz?;oi|0_3B?4vsP1|;FLZ)D zU6x6D|8K`JO+)q))sc^j>ARivyQEj*+HRI0J}&6nH7>Xp?81c78ePGJynZs`q~^ny z9^{=Giqnk?CF%A}#4nZ3>t=@i0H^l@Kv_^Mk9G9+^gJEbdk^*R3P(GPb|V^Y zkF@WNM5B?gek3;(?#ozWW6zVj0DJ%t1^~Lpy@&e23!Zu6TdrntsR#+)ZEUmP-Ppp2HEx>aYNKM8#R>qA0zmLz(f~#ies2^0 znI`2EQF!(IZozv2V3l&t0Y#pA zQ=b1p6aEL~9I`Ft*})>-2NeEcGAQ_f!XH+6)$XXmqawe9oEGP(d{p68yN4B?`d<2Z zT;WxJ-cooq|L-b1-BEeYIl+^=G@B&81L4OySk~PARw zu4tVCet2$Vz$|9Qa>BX)0g9Vi+dWa`@4?3+UlQ(FO7oaRq`buMlw1J#R3wvXPj=*- zr{5gHPQiT?ugw>)0*M{IB{^VSi)&M2=sCeezp{bW6VXHPL66V}%(l^C#a4 zp&wC=kRJO35Ae8)m+{MYztDGMztDF>>Pb)wQK{6PC&Yxl+b>x^3HrZ4XS(&rg+Bd$ zsc`F0H0hsDXcz(1?Nc3ylKQfLR)2&al#N9iDv!Z{8*jEGY{LyS& PN&j2n|Cxp=gIoU}lf(}; literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_ccoshl.c b/src/openlibm/src/s_ccoshl.c new file mode 100644 index 0000000..0233d19 --- /dev/null +++ b/src/openlibm/src/s_ccoshl.c @@ -0,0 +1,59 @@ +/* $OpenBSD: s_ccoshl.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. + */ + +/* 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 zcmbu9&ubG=5XZmURvR^4;x7>EVTGVA*fj}?(t`vVO^~)oC6J4>o9)^ZH%ZApp_PJ% z_y_dp&8vTgVlVaNwN&c02NAssk;%?%9uN1TA9&gKzBBXY<<0EAez^E(%(5U@c!1Gr z#L4(*ULH=%m_in{{`dO>m2c?dgzQJVd8gLjcXR{I#aLitW}xz!L>#F642@U_^X21% zquqS@Z@xLx*Ev2o{6R6b{(j@@!QtoQkDpLoSeSQas>}6Rr+CLLxkaZ`DBUd-iv?$9 zC0KWAo?^q?y;%Sg02~0P092Rj7=!hJG{NGv+|eaASg%%KZRf1%>||!o0u}*WW7|7= zR_t=cu2t+O6}wTf*OpS2OGE2ZvBt}~oss+|bdCx98kjmUo}6+-7Qh8fAD#`sMF6>x zTf)^8{d$UiGew_D(Ql>bh*o{S8?{2$M?8Vw3%oFdzuERSLPVRL*6=rk-;F{!@MWG* z&1n1{#FR9hYAbqG(@$%9L(?ZUJ<@b4itO`7)6Zx+^%610Bf*V!+RAIfjZ`mwwq(`| zLeEvfwt~CvDGzQlis1U)c01@OxSg&F-0E_DE>fQVg4Y|Jm+n@tyA|}*4&ohx*6Q<~ z*A9}D{{#IG>NUC}o%maTq>lu%m!`QM;xBxmivh65!dcEE4S$988?0-ep&{ScZX)le zKz&Ag{%d@Z^A}`8M)Kblfsy?3oacBGTO15b`7to;L%yzr96OrllKT^yoZpNub9_r2 z88iM_O8wUOLZwbrKZ=!j(J76Yn|ROpe{$Y)Tq84{-YK(o#9Q8!>Z8NkCY(=+-{wt| J4+vw%{{c2G+u8sC 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 zcmbVNPiqrF6o1=4Hfo*5q9RmqkwsEy*G;V&wA7?cn+UbmVkGUscDvm)#Z6MOE2L7f z*n{B3-uw`L0Iv~yNk2hCG!_q{AVNKP5F>9hlS~Hp(jRPQ-f!NYnK$oEo=?q8cSsU2 zNH7j9sfF$C);#P^!_Wr=;yXVAbw`Qw-#1)eiXX=g9Qv5DaaXmy9B8#67Kb5OP zO5ck&0O-Ka6lGTtnd+7zS1m=WjwzJelhG3&2IuZ#a*?T34yu+S*Ggz!ca$Xmwfs<@ zRZH>LN|m2z65rVieJoY>Ywtg#`YuKr+iEHf;GaIyWDNwLYvn{psFn;4XXqw0tnlt;9YYg#a<$$@!uRgUWpT^PPG2+#!pG5}z* zVzUY80I7%^yAz4Zoix}PI!aIHK`QvAf!-e9t^}|O02k<5HyTHY7A2u52}emhO6I0X ze1e1@lF$Uv?vwC5nR`IAc)LP`gp;mvlq92M`3{P{yXYrukWhqZ)c^m0A-mv^rluX8 z&C|4S(w%ZeM&WnIV@zz~ECBR#e%vzxzyJWXX~!iGKH$Nt9{i{Wf6IeE=fPtSHO?l$ zUNVfFZK(#RGm{$rTm_c_V?CpowmSU&!#Of@}_RNf(2$_!$Oak9|YD8 zX75kEfy*4obwJJL98-$mcf9yt4@n=Vp2-mDe+7b2mo@ zo)3FX?2yJA4b8q_5Ni(m1@p!98Orp5@zI9|?*OM*1Bml<#Ck%Wy+;gF)J}v*W8I<8 zquK{){C*)&oCd|uj5c7B1!~Qqj|I3!C3(@``)mlfO literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_ceil.c b/src/openlibm/src/s_ceil.c new file mode 100644 index 0000000..9c70a97 --- /dev/null +++ b/src/openlibm/src/s_ceil.c @@ -0,0 +1,77 @@ +/* @(#)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. + * ==================================================== + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_ceil.c,v 1.11 2008/02/15 07:01:40 bde Exp $"); + +/* + * ceil(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 + +#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(jZ{C~CNUZyK zouWWO!C_Q)Roq=wwU2t{QEb9Sm5!3 z_{!E1v+#*se+j@@(jRfoV6xD(KL0i9JZmWi=IkTOtZ%hQY_bo}Ot!mtWoN<7Z_*zF zje;}(O;;xM&vUVe8+B%)Eelb{O%&g$iNKVZU;{HI3l*Q5H^*1@e!O>j9yF^Rj}HUYN6szg53eaPvFISAw?jXfFW$q3FuEtF$fY^RIMe zmL2;d)U-^OEH4%1_vc~PPIAr*Zm!i?h(+AM6r1ScoIe3R9w{B*oU`UpA?!v@S-i)Z z5sSD_0F0J)aLxhT8p8EMZ};aB@9H|JhT=WFZE9q%)}ckzj&R4ma3m5|Lnn;0Y9eXV zhxYw#5NC%9K(sX8(~CMNuJFm(Dzp!HT>*l$DpyZH$u%lX8yeQ$RLcJC^zF1H{{bST z9!o;{Z&+2SUd1}k^alS67=SH5#aC)uXHv$6%UTLrcUKs~_IN$St^**h>US|<&iV5i z{ve&jA1`_)ApGK2fo2V-?PNbR%g&b9^U}&1my?=prXUuFeZB*+2C&anLk=OY0 zl>f`9_LtBo4MLMQS5)F9rm0B@a;&F1YiYlY)>iWW^o)48UE@yq-MauU=fCnJRDTQU zk+?&Jq+SWRm+N8Thh+faF7bCu2SMtWYn=FgEXV*K{O(f#8vJ(>zzYiW>yo-9GF1PU zJ1u%jj=%9Q)|h`I4Mfga%wN1IvcB{Snf}@Wo#f1s&<#|_&lfrUvlqBeeEEJ!`1`lH O20uhehb58V=l=lTjs(~M 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 zcmbu9-%Aux6vw}_YARW?Nx#UT>7^9%y1OYsgb8A6AQFP)n~m#CR_?CtOtIU8yCDnp z=0DK8e?bpD#HcUXljTECLC{kW^uvcRqKz|i&dxSyM15f9-uu1xoO9=%bEiBqb|t21 z5Ht)T9EA)uHT3=N5Dwx1Y<TS1FY=Qi;?+ zBAHAW-4oWVF>1Oz(R-mMFm4850H6Tr@kzv>d8El1X*_NZmg6wD+Jgyb#kkhh(b~4G z1^P*zd&2FXApgzyQrm4!Q$2dfe!ts-wovkkvmV9I2wME_Yvcrg&IbSWy*kqw>(;!j zGEif~=joN8R|>w2v+N`WfJ)^@Ens#Jz0{!7dCK}n4LY5<=#&G3{L@oMIi;*?&OkYC zA!z5MSFq+yy8JppeZ4TshjfDlst<}I z^>Li_GpsjUZ=bh3A4Te3ILAK!)jrAbJH;XMj@u3q7^)RQ+CjEYur7S$PM-*j>|fe6 z+ehh=1reh1bpWl=nxuaQFO2R>&R@uL{NHLCz_q`$zr9EPSJH%fV+8jaeM&uH$6Zgwj7R$#Yv4((y@vAz5!gsA;5;_A1^ literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_ceill.c b/src/openlibm/src/s_ceill.c new file mode 100644 index 0000000..f525411 --- /dev/null +++ b/src/openlibm/src/s_ceill.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_ceil.c 5.1 93/09/24 + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_ceill.c,v 1.9 2008/02/14 15:10:33 bde Exp $"); + +/* + * ceill(x) + * Return x rounded toward -inf to integral value + * Method: + * Bit twiddling. + * Exception: + * Inexact flag raised if x not equal to ceill(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 { \ + 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 zcmbtV-)mcS6hF7yT%vO~8zO@Z@2$Ja3hpi`%0z6}(5v|lLXpwp-bR|;Y`V0Wxwo3i zunEaVFJ-L0`v)lKgD=kYK@tm&_CZz)v!N?)We>@WrS+v-8Ghy5d%j6~U1jL!<@-J7 zo*$pjIbV{ocjE81NfHQ1&r*-`18EKHj%}`=+7Q&}X#&?ATgkF|F06Q?g

{RbPoVd-k|a2ow<|q z^|&)D{ps{;HRo5Wi&a+C;!hGbw!+K{%yS;S`kurN$F)Xb8OO;g%PNzn9w;n0%TTb# z@1J_)D_xxP^;_)^9Yd?t!<=(jfogfH>QDB1%BE!{kJQ+Np@qJ}Mk9yt9$?Ootnxq& z-m>p3E&Tqhtdv{@xHv-#mG0+uRcq6!$?8h=?zF7HCJ}P+9L{CRjn8w=4)<#fS65!? z0TBG_QO-GhF#_Xn-#`8t#Cm(*Qjf&?20GNp>w2diQ9Hw(Z-gU}uzKW_c~)f!n?4*p z-T{EmQ3U{8Wvp)i+CVC!PrO};>>V`s7wD8eJq1!OBpuwdJ1{AM>pw)_PPEbGUx4*@ z!Ww^4$c|?B7M^pj?t|Nc5CH7o6yNM^ok^M>q|CgZ zlJ{E$t@#pg{+n^o-77TX1-_&Q#K?jB#6AJC577B4`New^7~3-B7HB<9yhb(uYkq|K z?{8N0kf;8FuYj<{*-iOj5kMHH{A0pF5d6g%qkKQEKc)Wn0bsZPO#;C8l<(&ycnf5x zzrS7WDf2(vX8)_S5V2?6fA9(W$2s_WBMwl0j)?A|K7zlfi#7ebM@*9QMamZta~IgR PO@4s>w?{=F!Jq#(!O3pd literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_cexp.c b/src/openlibm/src/s_cexp.c new file mode 100644 index 0000000..1510721 --- /dev/null +++ b/src/openlibm/src/s_cexp.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_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 zcmbtU-%C?b9RJ>FIo;ZsA~Dc%(5gv!+oULjV)N%!%m>X#G{<$`tCE{zyVi_w4K=Wb z@E_=_j_-ut-IYK z2*4r0Ehy{?xN)Me4$x%)PJtbQchycZ`=L*o+jC_}rQNfQhgssZdsKoG2Y{QpzMp#NO&qZnO9-kpA`Rxf32W;|a~cuMY-?cQ7?l_cWJb zWhrJD&G6)^JX<=Zf$bi|~*Lg_UGX3`01s$deGBh{$6Q3QdkG$rwF? z@Kgd46VY6%RV-ud9X`MH94;7m>@nvv2ENR|?-k+sm7#B|!Tt;z6y$M6xPR5a8|`Nd zywU!RA?`_oADm5ug*|zQiJ6EdkARra;<@)YU&WP4S=5xI2I8o!$smp-5+H`BA`vC3 zff$|A6tSbHzagQ?;RkF#7M&Jj@u`>+*JdE+K^YIJaXF&oL;er24lEsOGa~nIh5Q_H zm}jnr^_AOmY?kC!n~cCY#yEKA2p4EB!Ya14FI{-KuZ wdH=8;b8N&rMjp@|0RAhnM`k^KYv$e|UNiC%({q^bud;}KjpaYdg$!o>9|EdE>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 zcmbtU?@JS59RJ?5T&8<&(u;*gR~&VLUYitwP&m7El}Ooq5l!rzcPedDwzF1{ORR8E z(Vx(p-q$}6g$iN>5(Uw_fu{ zdDq+zfE%Tm>$g6Ug>L{rlogZYUfU$KvYF_JvIx2U1x$N^8sdH|3B0A=kP z7=i!@PmyEV3-r9rbB7&t6|N0}P!xsMriS2s0YC$QHfpV9ttCAqd0A0vh|qN(<*9oGOH>a({4~xh=KR7@tr#Q`(n?JVU*VQ$19Y$$Q&vB@xwLrTfi5M(+Ty%SQgLp!#4f35et<3 l;-0+k8EWK@$9K)I9im7{)Q5-v`Gsr5KcM|*_~5^2^&7$OIqv`f literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_cexpl.c b/src/openlibm/src/s_cexpl.c new file mode 100644 index 0000000..f143d88 --- /dev/null +++ b/src/openlibm/src/s_cexpl.c @@ -0,0 +1,69 @@ +/* $OpenBSD: s_cexpl.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. + */ + +/* 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 zcmbu9-)qxQ6vw~Wrkh$r6$N2}c?i;hi)m3TL!`2}Mv*cGl_JQNW^o;+KWHL!GVq~q zKJC#z!#_cBFWX<>sO;GX5quPc%1O^jV@hB21DAX5_nvdl%{@2w?W3n_Gl~L1!2^s( zV?NA|?NVfxa1j~U{qMP9sN2c*jpl352lw^J8tm)YVW`)VEt;_Vhg$69>)F$z!M?5~ z-N>Hedh%o7>zds^EPg#YIX?aL8Rga06)jh;RF|~;9iw36wSrl=Yv%K&mfP^QHQNb! zV)@>Ze9asH4Zs-ytEFdu4{Pdzq@95B&*A5AVgkTyyt^?M09;P!(VhTY z0+1cM#bl=F*QV$e`qUrecAjt^AoMD?Rsi5H#Hq;nJW1`=OJUG)CYlIi$!(R(#XgBOh-W`>uIq4z6Y Nd!oc*{D3g&_&@r`%nJYj literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_cimag.c b/src/openlibm/src/s_cimag.c new file mode 100644 index 0000000..456ae99 --- /dev/null +++ b/src/openlibm/src/s_cimag.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_cimag.c,v 1.3 2009/03/14 18:24:15 das Exp $ + */ + +#include + +#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 zcmbW0-%0{O6vn?%E6boibP?Fac9lX-Dn-#n2x4{-5`xf8*rr=Xt;+5M+D)&}WAqqB zFVJPL(GwK2p0f@^5cC5%d(O;vzFE)gQ|iuw|CU5 z)k7y&Z?y7GX;+qI$tf4hd&N?z=;WGS*Ew+&Efn_ikvavy0Wbrg-e@5K@v3WVBPgGz zBdk#rk4=ctvdAvZrJn_&`Ub7(UVowcr||Xt+rDJ%J|zQS)u_iFVY_qdyEn3fD6&Go zlO{pG7#WUzeGY77~8_pbDM?d!nxz1Z#FWN8MoR)@*VC-X8{HWL7wq)%G)nw2v=Z)OWX8u+(< zoBWI1kYN8EE)eX`anHDeCdy02tC_*Y!5rTk}b}ONt9LBU`Wg+OyXjkpBwl8T%ZxHv@!nB2wVRH DdHhFr 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 zcmbW0-%0{O6vn?X`!DqOBB+b)DutX>lA?0->9*RacE#jok^fn_i*E=rMwz z>n?kZo}d`_oOKwAz#l9#=j?pvo7pq_R609J2mwam5Tj_shmkxQrjL-qJQm(xt8XYD zA0IgBa;2Ja^1HGi^G+dGDCY9{oRhxrn$D@K=tXufGgK!5H~=OAlq*#vAYOHjZ3M-$ zw1rg~#p4A;e^IQbre~f7hWQP8r)&L(uAju$_iyVaV)qd#0Lw-`_6Tc@8{ciWWCPJ8 z(&#g3672+$Y!1cY@ZEV)52UAvssOM3?Ocu=mz$WP@tbECe8SXc;1z-jk zTfa^IIW9=B{|+Yz_UEx^+(8p%1_rESw9mBNdjNe}VDC$x)#Qr&_5Cq{;%{t*`M=zneDClB;7TQbJQbSuj|^q*X)!33h5d9`z`&U@6f_F3kh5Q E1I=tm(f|Me literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_cimagl.c b/src/openlibm/src/s_cimagl.c new file mode 100644 index 0000000..588c6a3 --- /dev/null +++ b/src/openlibm/src/s_cimagl.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_cimagl.c,v 1.3 2009/03/14 18:24:15 das Exp $ + */ + +#include + +#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 zcmbV~-%0{O6vn?XODiwz&qZJt8w45Dq>>a}gb-yHAt4Cegl)QMR^UXK2XCIHxP7*?Z5je!8n(!7AD}h`=2J`snt*^YI zdUSMP<*T*Erd8aPC0Vpeg;KdtEEcSM-Dz8=wxWscz0JU#1YiM}22iavkbrp68Y8IY z*kzg!4|Rx9R^&3N^pilKuhN{}>o4?vNqm0&v~DU&n~(vp7}KK+zuCHV?M_d&5Wa*S zeJ4$Vo(SoWU1eWG`pOH(F25;fq#)b2vLUa1AF?%YU8k=g`vc|3YOS&DE4y_^b*FzX zhu&c5cxnvkIXzoC-R6yFyH1q$Z*o9z+Zkhru;*dF;$-6mfHm?@8TzqNGu&Th13()1 zw||TB3%nu0`8zBSoX=yK{3gm22=*~LCuQ~?z=#%@=hAnLb4mI7|B3TV#b5r5;QvO{ zFXo&Mx + * + * 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 zcmbu9QE$>v6vzJsbf}Yp`aqlyeIRB_qywTc*@GD@N->0o8H|h3rF1P@gtE|@Fdyav z@5Zm;x4>YGPd@J>_+Vn>*<|LFbD-(qMSn?q+yA})d+t5ww(lR;pTraef`Uhwzs)h? z^XKj0aU0jMit_Vkj-j58jp5JiM9tK5$sg1k+$L(eo=Z;DOd{tPsyhyePE9@iIv1Uq z>V6Np9d-Siqy8FA)Vl?Y8cbedun_xAkhHnfH9tdc*H+_pN^1?;YEH{{+(+?8AMhZ+7ij$p3-%L1%?> z5oY?WVRjCLXsy;b?=oI6C@}yAEYSI)IC5a6K6hCUedYn5*cU~qiu&n47_A+l@uYMiuqe + * + * 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 zcmbu9-)qxQ6vw~mrmI?;RQ6EVz&u3hV2f>0ls(AC>RMz>oEuD>j5JF+u|GxXCH~zg03E;u z0QKcHWS|_8#G6=V8)oxp0s^aC#%w|V9{ZOaUt-2mp66<9Evz7NyxbvjNrfZ6Q@j#*z`oACq7 zekt!;-B;$0*V}QtU=Ps>&i1D3Ssf=%`9IMApglviND_Uka_=Qb?}-UnclI-fR2Tre zQn)Ph@W!QmM9}`A{E1^i@FN<|z~2!w4Tv?*8()$6%e6rPz+05$X89hL^OJ 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 zcmbu9QEL-H5Xb+QR$Db5Q4|Xmy@x0**z*z;OA(3mY!1;-3V|RSKEUhQDYt~$I>+#QF5k>bTZisIergQt}43h z8SBf6ep1n^iaw+0p`y#e^FHz}NHR1=*zsOd_;uK^=%n)wTb(fSZ4q__>}_B8uJDm21RLvh;It{g^uC*W)cpw8aYvJ^ty0{&7LMPqKe9 wmg8BMY4qHZH + +#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 zcmbu9y>8P`6vzKg3k{IQPQ`#IgNF#Eh+g6dO2q(0X&Vn!hC&1qL+iSB3vE7R8>#64 zND+GuXwuIStPo4&7?KF1rrUi#|m&t}QV z?tL+QTW|GW^hc>B@1%fQwfev;)#{A})4D4v!ZIu6%Du8>mCe$ow`$9bcdSys@6o za?~VLXBxlGCU=0TVHYDV$0Bt*jt*c>@sE1|;(m>B*O=?TxpstGZoBnLxDXrFGDwCS zc+Mf*mrZ961tmLS}Av+1=Wh*mrDM6KRf3?s)qV12LkT6BVT#|xq^ zl6>C&mLE7xkNf#w=(*@l=?qkocYtR@A$>RV@jPJYKZFm-X2TV(BPZ(`+i$X+&RXTY zswl`gm)r*8oc|hcas4@&kU8Ns{k&3_>m!aY%RuG>uXm(@k^Re+&PU2B-&92*?fV?S zOnN2(eCL>SU-JAV9j-q%(*ze!jl;XZr4mQ;wJKt%S`(==*S9{5CgrJoHRR$NvG|v4hS4 literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_conjf.c b/src/openlibm/src/s_conjf.c new file mode 100644 index 0000000..d2ff743 --- /dev/null +++ b/src/openlibm/src/s_conjf.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_conjf.c,v 1.2 2008/08/07 14:39:56 das Exp $ + */ + +#include + +#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 zcmbtU&1w@-6#gcyHeyUBrAVL^W-&+#?R6&jQ(R~u)kFvZON%aw?Q}Y6wapJRBP3l^ zp(}TN3}3-rL?6J%=)#R;D^$+SxtZy-LC_DvIp@3QZ_c?lAD-2pr!)-;8lE7sBIr|* zUY2SZS=>UimOCEQPJXV`zMdJwTz=Ioep)q`q&7Fq9gl4Nj6#MveUnJNZtBt@GtA{T zO$w`AxU-3bm8(E8n7aK1M2lYNhhnC{`OAi-vt)l!R@R ztkMI^wk@N$=It6aC**_WM~lET00RJ(sx~%|f;J#d%|K)O1{axQsU59B>*?BjW+r{A zLGlZH)+hNQTTXSdX{IiL@=xQ}`K1E@Q{(CpZc0@S-*XO|aNo9^y{1f6gM zh@jsJogIiE^ha`EX})*ph|ueW5W7z3KpX$EnO-VDb3QK0?BF)!~0#{LQx z52?lk-3O|pE?9y2yUfR)tHc*RPeR>ug(c4Uukkk5pH&GN1D46}Rko5(Io?u%j2|rT zDT1N;SCZzV^f<13Xjk~Y1~8MnlQG9+UuymeUCw#oP6M#GslUY^OxS;q6RJJa{^>tS t)mJ=~N!BK8bN$cUXol+~<0)ry_k=VjH91}(IqUp{_*0HQQh|(Q{2$Y{lkNZj 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 zcmbu9L2DCH5Xb+UR$H|$X;COta1TXNu+QC4G4vpjt|o{^DdZ?+v)#7pZc=ui(25|^ zFVLeO!;etVFCo3;=)sG3Au^kp?Do+j=ns}RZ|2RLc{7uIeEjT5#j+q+c!*+G@VQdR z&0K8aI_A(m`nfpL%Z>8)gY2gtmYw#|H>YeMIX8YEp2oSk@fEF&jdiEi>U38eZ%x&e z=hWT$eb@6`r?wewJMBQTVfDcZrU5trE&*tDx~RZ9A)R3HUfytn4c7ZjSO-;WX>Mlr z*aFr7++y1!T7BE`?V4}9zTNQc=JT`L7xt_~I3J2PjbEeltW%S03a$ZIDCzSY0L%lZ z7RM$mUZ6*|6%P7uVih7^5vEZP#|U31!EOxPL4|`PiTWCTJO 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 zcmbW0Jx?1!5Qg711lxdugCc$L< zmpg@Gc~|E4RbJ&}KAS(t=5krNQ*zFwWovq|_iUG|&I6DD9snp5%Sb?sjE{R2v`>@Z zF|FdN1kuTejpbzOy};DJN$>KU{2!S7^Y}ISQ^;IUJ>(&P)rdc+;a94ycGthCyQ&H{ zXJ;~)&l~x~fbzRdZJ$B;+MBHnwzSjHQ0KO`q0W3Cs@iHc9alrSE$yg6vApMNyZVOq zb@x)Wy;j@tbQj8V-rCA(RBE2xbi%&x%LdJ0A(mivM-ZN$$gn|dk$#RHgvUk*O&1mFbh~v)_cpYa3Fee@*&Dno(SD^2TRxXpnx5^bENJ9{ojs MO@Z|waz + +#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 zcmbW0%SyvQ6o&t4z0?a-#f7&;T!Ohe5J9vqq=--uK{TyN6>VCQ5v+?=ce?YD z3hrF_3_gKAL1pSWX&AhKAB356GXME!awg5~y`7j4U<5YMjk>%?lAE3MCWbKtH`!>p z$;QiEyWMWyzX7-#cy*Ir>lwMNt#xZ5moKEO%!rSBi9f%R05VNF@bAmYHi2?VWnFo*n{;gjm|1=jQ*ngQ51pD*28o7&69-~17)-l@v z`pw=0c%lX7zVun69FxDkKT%o~{G~ta+;fEeVrsO}2}yWuGxFdKKW0Qo-x1Q=nwh_T3BWwVd_5tC2>}Y literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_copysignl.c b/src/openlibm/src/s_copysignl.c new file mode 100644 index 0000000..6cae5d3 --- /dev/null +++ b/src/openlibm/src/s_copysignl.c @@ -0,0 +1,43 @@ +/*- + * 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_copysignl.c,v 1.2 2007/01/07 07:54:21 das Exp $ + */ + +#include + +#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 zcmbu7&r2IY6vw}l*cz)4D;^X*Y+<2F>of^Up@$MM8V@Ch&_FLm*SJk2n;-0skQ6~7 z7mq!bp88jKF7zMpDD0*2)NB5N%52`-q(iIFelGLo&HK)GX5O6byxC0%0Y>08#4WJ{Pm}jWb8I34Pap+AA1D*)pn;B9M@W&tRjwC zsqd!I&pYwNfDC#~5}<>umVK4erW75`Xd;>12NA5@r3kAP7n^*?5RA8P<-*uAr0dPe{ z_vzn7{~U3@m~%Sl5+!Enob1neU1oYmkp6)5kElncUhix6UUNYDWzsX0j(PkS{bwqy J#g!vW{Vl?wUZMa1 literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_cos.c b/src/openlibm/src/s_cos.c new file mode 100644 index 0000000..9896bd8 --- /dev/null +++ b/src/openlibm/src/s_cos.c @@ -0,0 +1,89 @@ +/* @(#)s_cos.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_cos.c,v 1.13 2011/02/10 07:37:50 das Exp $"); + +/* cos(x) + * Return cosine function of x. + * + * kernel function: + * __kernel_sin ... sine function on [-pi/4,pi/4] + * __kernel_cos ... cosine 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 +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 zcmbVNO-vI}5dOBH6ocK09!N0hnxKIM*0zEW6Mhnq?x8_LY`Bm#rEH~vwq$n^Fi}Vv zV!Rkm-b_3hPbS{CK}zA()^&k!Vsg+j;GF?Oynj?R)d>%s2Dio44J%8=v+` z5(FfSp>EZowbtho_H+U=0?26c(~`D-s9dj9DqEv}t{si9caOe$Jw3KQUzYnzJEgS; zWjT0`LJs5*Mk|$*tw-%;dA@WYhbEvEe|Blle;m^LvK)-}_{(yzwWs*KrFbe?eZ^Cs z72heXjo1!a@l)49Mh;B@8TsV%5e3PiZ5sBdXxk|x&)M0Izmk5PKi((1(d8Y50{At~ z69HS(Mr?BOj?x>ON%Sd^K{cvIlxR3Q6plo~O7E<`sAwsRUknWQ0klmD04gCilYkFW zi8!&R65H*Z=?ah1<5@@>L8-f=&A%%FS5bWkd-UU*3MjdNe=b1k-k?0K_+4q{(Ne3T zj%pqDhBY8yTjv`%!c7334jsET0G9y-|MLcJc<{G8c$mp_!Bo>wbgEW zG?+B>TyiyAAZl4R^7;z-)(tb8M=#gl1JDBCZ>0*2c{&SPmEf}uzRkhEaPWQy|I(pP zT0-ZIhyQyA@6`Y3q4UJUUz|Fvi=G-(b2De97NDAzQ5~1W%+Oa-s-5{X(@Le6*?yQ`Q&)|`s%}`DsEX@L$&8W8 z>9uOk3|b%cuDj!^-x|IH4!C=*+wObR`~|-7W_@F#gY(dt61sS#KBfHBGfp(UNRIm~ z&=1&}XN`}rW~UGo;17qWS3uZe9P@||a=d%Lge}H6$A?7%hQjf5@10<}HYS?v3E`e_ zbiqwi3(@^(=xqS^+0k8>ShoP(8*+8WZ*%;JaAdgSH$3|1Egz`p6Y8G}eAWcPH_J`< q!1+c0UF81;kzd5qci7!Kgk4^cxCa6(Tf-%f_!5ggt9e%8j{gTCTJ@^{ literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_cosf.c b/src/openlibm/src/s_cosf.c new file mode 100644 index 0000000..57ec7c7 --- /dev/null +++ b/src/openlibm/src/s_cosf.c @@ -0,0 +1,85 @@ +/* s_cosf.c -- float version of s_cos.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_cosf.c,v 1.18 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 +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 zcmbtWL2MgU5FI-)b)DAhMhH173a)5TA~lQcCXI`5vM7cakw#TWN~j_k$62?bwHAubJwfCfeF(pPWYKH@k|E&aXr{P0qD+Hq

z4qm8x3Vr5s01knFRQF|-{kgfk3P2YL(4P$9wS3A>4|Mc}EhPHkM0M<6O_dWxF z9WAmS1=;$|=#DmXtElyCY$GA`>F*Lh8n5+YlA3nqLjc&-W*X>wL)^!prQp zt{K|;T}tw?NHQa;LLs?dM)zj+warUGu4G4>-uPKm@RAVyaYD`_lR;{Nuq<2c1uJkO^Waf?)gD{XhB8SlEK2NZf& z_sxBgG6SwnF}JVZcO20LfM{Q4@~=aC8?+nl-bHp7*?$gi9y(TAx!Y;b-T+t~rVtE~ zS3!##9T|Bl)-yUj)f-Fn>q$KkOU9D}@kAmX>zOd;V%fY+H~I#90onl|1_0Rf(eWwp zgRg-c&#aH^y_E1_+I_E2fbU|&cW~dH;8h>M(*W=&-MfQgI~;p86b?>woCya{hhv3M zIC!#SB@_;hb@(%(aB#B27KZX5Dlk+#{K0K}0By}GTL_8Ehgt+d6MH~Bs|@#f0?;Fq z0MI4u07##yKsWI!9v8$Om8Q4>h%0yc$Uma+Nnr;ds_=uvtNz&cPN@%~_Wf^Oa;#lnF=N4g3Jm1^|CME>254&MEU>N<7Xo^WRE5P6hK@ z5|3|OR=<4iE$P9F-^Dc93YJaYKX*nddkaVD9cl;YsG#=I@@INQuG zOL4*y|BmF3-xm9SB=P$s{tJ&d8xk+qc}t2T_u(w{2cK82=L3nCZ*?+&3SLRI* z{!@vU^7c4s^ z8~w78I1YNDQYx8c8}xF;Hucf*sXoij7tWJ?w!Ek>R4WT+)m{cSlX)&ztmaE*v$X#M zd|qsYdh)sdTR`(%V5sNFL7HFoXJo~%F@Ql$#D66)51)&CPCY?9eycJLJkb0W=(RO* zlw$r@eS-3LHY2)-QvQ^}bN##zdFW4(9_LyH+q}Qvp?`(+JdX_SKkqM-Uj3a|CH<2u zByj(DpC!GDYou4fIz|;hoP()+~$NarXKdC%tIDdGq xv7UK+9yK>2MFYj>AD$@~L)GJ%tIi(cHoag=SS_giJK&-JgzA64B^6Nh{{Z`r@1Otx 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 zcmbuCU2GIp6vxkO3$0LQ7F29PEo*W$t%0#$P$Ua%=}K2(!%y5yQ_j} z=;9V=sc7FM#s~3%NMa%nCW7%}TX5C}RHD~6Y?eyA46aPu) z-us(-&b@QanLFFQ7aF%&Bne0oY=+shSd`~&mD1KqyZq4f9UJe{`yXuYiT(n<$_SGgPUDtDuN7ssa%#(PWEJFE2rPK04OJVEdXIVlP+UW!&=sLCdeGFGreqQ-6abEOkyCC zPUc8DnM)gqjcAd$oh2r;XllZHBCZVV(1R9E=Y{WEl>SBN?tY%q|D%K*NjY&r0&s=z zSii*u;&zq|vSR$x9lOF;ZCd)a>{XT3{d(4tF>TTnzS^_*idR|f1ULkTbo02K&&+)CkW8MLiKUqMH~^O$kvQ%4b?6 zu?)ADnlk%Jjl`nbXly)gXRe_}R(O0ItD^iycxL6XHQ?Hi_FZf& zH9n7nF>N&b=cZ%!q^6A+>n1XSgIlQybdVauJZO>FMBL7_=;1od1%_%vK}xeBOMXv~=c4 zbAB%80YK*DLp^0qfZtJaz#?Pt`9=!ak|7(4G@#I(GYthaM_b*$D*E(N*@Kk0CII#U=3pn^Z2iZH^0HGbw zP+z~%R@Tt8yWCb;qgJVvwyKJ%brqGB6}GZwPn*rv66815)|Lb01Aq+x@Re+6+6@+v zBFN}$lK6Nje}u<)E4|eW(h;k)s;HoFSORzl08041Z!i{hvNddR${{JQUy_HVM)|Dd zls}SQlta=hOJr-ET-dO5t2`iWm522kjdDnG(v7_J(h}KPk8_&kVX47n+$1=ANx0AV zu#oV6KHQ^>%u!zMsb_`9u>^}?14o6t#W*0Z5O^u)Wdg@B&c|4z$WImL#R9i;ZWZ`8 z&dHwIot%@1qw@6Z&ed!BaPeFS0B)TW=yhRM8|R`rbg+2NdZ;eWY5$}E=k&a!a{#cy z6o0*j0N@C~KYXB0FTl?(z#-sn?GE_VR_N$@qo)zuj#cGY zb&gddQyc3m@luPIYP{6oWgTADgWG-BKM0)G z-Hc}%pJ$Gn$HdKX9x!q9e0u+J8NQSuHE^^u*m3~WK+tcr?bP#od@X9wb0i3ATT8G7 z)B}M4sQzwaV6}b4r)Mc?e6UKbOk}}>JEC;hNj(X1HqQo!+dvgrq-`(T! z2akfWhNs=_^|y3-_?G^U@Hw&6#1qE&O$)jAnB9T3{#&-hG z)VbQv?P(r~>Yv(Oe0}=9k=pr$=Lm37{HWc>?M1y$3kV`R5}t(x;yVHWXSuz&FY$Ts zS2+3<krQlvL`;@+Nd7=e;)uV-x!{qm?P2tk$Gwl e6~dqZz + * + * 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 zcmbtUOK%fN5Uz0ym|&*Ih=T=4%wb^73VQ8`_W|-EHYgh&n=G-22$RW7K*SGuCL-hj zND)^a{{VghH;#yaKw60noH(qs96>@N%o!=Dda6CMz4iq@$?C4J>#M5ns`2epqa!Iz z0|^aIKy1Z$x*^{8i)}yXuoVU_4*cnzX1CsWtnk+#UWMIS@mS$`W%;uivfM5!WVvxG z^AQyxGsdk<$c(IoidX0-4!qN>{w8F(wB=P;eI?>pVbx<_o_UO~F6~&zSC(IxXkYSJ z;q}1ff$0^G?H-0mD`fx6gkk>S@rEDEI4G7&sQFV%t%`v zyC|MBiYp4shphTS#t1})aY3$8?Lqq$t7$7_QU1yIpQhH=*W=bm+>sk74-FkR3+1ti zeP-z(@8c!2uh@5}SSl6G!UcEMtk?k^95}KMAPoQ}0APLPu?a|l_6#{W6B^l@DZzGH zwWSN7EgIU+?54~E4PY1mcG1~g6c6gg{nVhIzt?j{H<#1D>;0+oy}Efy&yVQFpq?pj zNj;A2L1B+3QM@XsdrT7uu2;IXd=jDx>6xPP-2*fYTWpcSoG<*wz<+dOa= z1K_iEU<04=ec-JI8r<=N(qZ6EqgHe40q}YwaCv!b;(#C6&ULcq>I=NtYBb$ea1)|< z?$v3pW!Kzx0Y3-47hV~Am4xi0{0=14S=~v!mi`h&Yy<$T5rI9yJlJDIp4Pp@_mC~| zlKP-RrT0_JAJvyA|28GjDkW0yD{Z-+Bz;lQe<1yD3NP!IYlZYG*nfsBhSW(+0*LQP zbvKAm>yqy;(WLyUzMqII(vhI*uXpLcNq@1j&)9$bj-_7mcpo)4;t`SO=)(Ao;z+4_ cjH&h>u}0)^VZ~72FV{tXl + * + * 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 zcmbtV&u<$=6n^WZ)GhALx{4}GE$SXd;6OXrQCg~kAWpW}2P;%<(%K?w*lc!_s__qb zHzJ8bs1z=iP~i{Zj|feHoFH)O0f}oXfm*be9*~UQ?2LD^>Pm=yl07ruy!X8~^XA!K zUaNnc(KL|I;6sR4F`gfb=Tm$-1v;F9%5ASkcJ?Z_Zua+U-#;-c{U4Dyz>6-lhq9huRpEd@AL0nqI{Ugij%*<7@Se>08H_MZ3f|bpQ z(!`}wxm+@fH{4~jW(Q*9;(Ox&qX1w60OnVnorer)d&tQ*rHS;WGr|_i|{!$8mHHH5ug$IAp z>2^N%m;ta$uN-WL~x zZvk)hpFspi;a^kuFBJZ`!vC!BS%v>g;qh%r{kO!!!?-6E{+hyLt)=~@;4=U)qVNwC z`<%jmr|_o~9(w?RI`|oa`J1i4UIOL^y=YvOv!1(Vv%uX5fGyjB4Q$Exf%Q7LV2&S@ zF9UNrt(MykfVDe;%c`^U7yZC??uqqEd!2QAovzypHX+h;R~NmW-ExNsyc+Oacx0@V zis(N9hW#Lc{i5P5??V{cORQpn0N}YGuqGG>Ym6v}@lC;FZB!gPa>+47d4{+kH2<%E zS;Rj*RE%JV_{sCiwH&d}FemI=6{hfiS0#n5I@T0U#V7yq{0#u!Pf7FZf=K2i?_Z)T z;wSy@3*x#o6iE8tOR0ZD{M5=iWBsv@rN89y?vk+)hcdn>IQA$$siZ$@CTou{#rw1P WDn|1C;P3Fu{JSFmt=N?#>Hjasq)~_f 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 zcmbuA&rcIU6vy8JN(CJ2kAn#&EXish%Gwf%gb>A0-HJj85kd?~w`D2BDQ&t-EQG`+ zcs23p(VPAO{s9oUl!U}%*QM2?C?WAqQuDSm?YMR?`c1a8^O^VN&CGkVeRcowgC#h-!2b6pXDQW1lRzWB~3kFm)E6-x;?6oVZF z?JZ|maW<4mZZ+aiMRsV_`k-JRJ5&jNJuDT`V|{$}QK?ueik@=Slg(Ey;1aOs3@dzO zq+FfHJqKL#LBZZDZ|^u8O2{tYWX^^X#K88qazSu(m*`H3%bFBN$_2E?EtR(qX{AyD zZFF= zRTJR0kjNT3rI1)o=}8I+J#OM}Hc7!;UZIdkn-q*(h5}6|DL^+n39KD_PAXN62^?#T z^Q6E}3;ct?TLr!^@PNQuS)pRgGXn1xc$>hV3LJCH*JBABbHF*?4OA0*YEsR$l%>Z( zHLYy5UE*(9gX*ef$zJ@JC|lPjxgCY#O} zS!)fdGZ;(ri&;Ho)I$D`a38ouJZn+aZ#mTJo6B3{oh+~1o-2w64**35@T@To<_LxN z0(FgX{vF}kXXoyf7vErW{;PkO#mD<1ipRexLS`$rcyGLGLY*{%4Q%lqU_E0U{UHXt z>*D9f6=!pL{X-1A=Y~vP|7Sk=liB||&lBbkeYrp9xJ_?t)Mo|<**V~y!W?=1@osu^ chYGOzx$E}o@*XRGcN_T+vh~xtt1GYnZv?V-(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 zcmbu9L2DCH5Xb+URvT^I-4+p{LKi8Lf_)~%qIf7NvCS4j50&bnhq~Qv+SDc+cDK+d zSRr`#WB47s1md9|!H?iUP{qhIe`khSna#fM9L-d1qtP8^j^<-?>{2yy zr&Z&7r@uHe%qw)D-TrKDb&Z)~Jc}K+x`Tx9;{@eW>4}vquW!y-g@>97Hag>`pYOgn-9h=(p#8~!&2HXd5 zhiz|YT-MEYW=*#;FR$z7vYuTTf2y0SdY1PLgW`_j=lNy!k$zSK#^Y&xITtViOeOZm zIRUr@#I`h)JNcx!J4DY7(GhOD&A>lUE>xvdK)iq(c+MeeVXaYxTdO;JaQ$X0tnD=< z-Xu@x?&)d%ocEx73DU17^n5}eOX!OUJ-L4^p(po0Pv}$|iMzvk1^~6Z=+r9&>GbQP z!d5+UcA&y2=#Bd_3%o-|Mc#1)wd+I<)J_;e1wJj58%B?zT)$rT8WB{(k33ag-<%I4 z$9=`?y~dGh27c2Eq856`dHdVdz^Qxv`2Pt#7xf<9S(4s6j(-0L>0X)U8p(d)9beK% z7N}n-j=TrAS-;16;`0*oiS23R{S@f^qci{2zrgXQzm%bEEdGbI6 zM)H@j%>HS9r3FU(gcm^E*B5#cz;E7=&P(zZe2$;?&v77IHZp1dgCX_LaY3ZcRDb%G uiofU-CLNn-a{MnGcY@=j{prkf?FpL?rTQjG-yeN{F7q$4*h)HIQmel#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 zcmbtUL2DC16#h1?Hfro9rDCB4_pnF`?U>Yx(L<@Unh2pnY4MnDx4Ug>lMTCDXgst+ zQSjzZ5WINvsNN!a=uhw`6cj{q@gP**>`XGaT#t&-*1%;zZXiMj*YgSSv0dR7tJX?OSSd=$W9)UgumK)x@;!f zdV0l7J#XzkYU`O5bF8gr%H{<3r}+wLGv&YNu5zz5_ZsE8bm{O*;WMWxk+NxW+Tc<3 z?2)VgXvqw&P&#_{=-Wr&*#U|R3wModacOnZ$j`DFmN#Z{Gq-a2e9p)&I~zvH3dM)% z+mlfp1_2lV&H*Scts()fMVzdiChQB5J4VH*Jza*jm)6EpL&;YfFoEbHwCMG4cs}vs z;&AfbC86jIiZh6xC%wK7bh79o#ix|*X=DJ5DE>SL0Am2sr(HR&_2IL9_#1tA1QomC zd)qFv!O9DHL>6q{v36WkD%GG`cU{=knziY|_8QHgx>;m<4l zn!*n$yrb}{{~Lu@{og5kQd#G{;1dAosK|V%M+n5z(*X;bwa{7z3qn5{x8%%sb}SY; zdm-3{6+4^WH37jXTfZ*R&(khSltU9R$N-04noU*BJ9ojE^GK+!|}r=qUD^e zitAf7`MduO`Y-B1s+o%DZVYB~M}Eu?eq5{I4P|-FsB? hxSrNLv-be@#G-eEUP3I}0o|KD^@416JR`*Qe*l|h)rbH9 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 zcmbtU-A)rh6#f=as^D0OCQUG5O{yu0j4ii3iOb8ETv_DnL6->e_CcJHe;B>Q`-q1D>kqn0<_)u@zP zZOE&nO}%J%Vq;=@Jh&fSQwKm93d<|#gVs{64o&E?Mz;euXdhoe+lyroUi`9E%qfevzeeOn=^upJVz0d8J>n zc>X$zEetKOm`HI6biM)nKEJd9pg%l)2gAPT*YyH!0T@y2{ks520El0(3^3M%Pxas* z_2A)_%!X61*xUqPn$IB6U^gZ5w92(R9n(HCrC(ju5DKbgMt- z0q!aMRfT`1@Pi6pPtOSPO$Ds z$+2vMd)A%@zG-*{_=f9(J9SdH>3UP(X1!XqY94s4?peIByfWc>hWSqD+qGTZaOw@q z@tO$2Sv#dI$EaFi{{IBsi)N5&rXu)vAeAXs+t+|U*B54z-m37Ao=etWqAp@a{j + +#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 zcmbV~%}T>S6ot>!ziPWsaUs-2T&bXAQY?ZCQKY5|>7r0@BQ}krf~GCW2rsZOCF`^Ba~6X2mF(h18383 zwznK_PgbSpRNZRL^*q~CQjfCFF#fZuGR0P${ejG&n9R;VDJTM&I3UmP3O%lkkA4RICA$xtTq~C1sBsvK1D8A`E$U)p6s8~Ni#_B$h z>h|(F4kDGgO-uzy?>KAiFr4+UmS-^^09dDf`hsYP?|~Ve5YZZVN@o 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 zcmbV~%Sr<=6o&uQYO8ipFAG5z<4Oe^r^O<;5JhUckS+=ZH=<*kwqS3}L}=ak3O<65 zBDitstM~*;I_FG>;05}@kerkA=TGM3sdRaf5CV+A38vAM_gM0Dl0HQS%XmZi{QTJ2 zEm!M%PX169WZo&bg`%6!yUuP+HJys5X(4yCha><8z&wC*wT=YDtI08fVzyhS1@Tye z7-hv~CY62`nB=#3jm3XpYLfW;`l)0ta+{I?uo}xp9>Gn+S6;Uz8we+%#@xw}pf5rO z#4|XW;TJz9T%(}!d{1KakB9Mz&6#)S@|<7W}^Q|>;OmuGwb)s-{lPn z_CMeR!TvlJf4HMz$N~%2F(m*gyZ14@eJ*p?IM?KF-cOtt3jWhyP2M-6elZm~=msSg u>74A(c~fS48$L*POXCvt$kv;E?cN()@?Rr8WB%Rd*I!2cO 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 zcmbV~%}N6?6opUfPpfuOe-?r+Mi8uEV_PhW3lT)?LW&d$ZbYYTY{C996QOnEEBF{b zhTsdh6nqMwK*`L#(;+BAKNvFiBqt}CJ5Q$wo}-XMOko)`C=(wDCC`NRW+S+SJOmpe>-qb18@M$04P^#NI<+AjS*CH z>p#qX)A;)SZQWFqHYN>VDW*pm{!PPEZl@y~2wy^v zxsxG5PlWVGUG3H(eeH!~o8Pn=YRIOmUC6rcLpJ)|uIg#XUSBI&uGDhAb{qFpw|Wn9 z;PnT}(<4YvbzG_1H+P=fRZ-f+tO3DoXRRH=o`?O4lZh7qHpo9^>8DoBaDSOC04ZQ% z{|@Enc|(HpcUd4fpT`pUZL}>A>|;z$((XNgAuX`aW$qg1n)1#66X%7B|NK|M|Ba|$ z%q1Okm4rDuC+D+nmf6{c5Axm8I8QyY{bpag_l5(?UnW0ef4{{){B2s;Vk2Sue*oZ3 BNNNB8 literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_csin.c b/src/openlibm/src/s_csin.c new file mode 100644 index 0000000..a905991 --- /dev/null +++ b/src/openlibm/src/s_csin.c @@ -0,0 +1,93 @@ +/* $OpenBSD: s_csin.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. + */ + +/* 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 zcmbVPUu;uV9R9Uz(skH#OJ=gj%@1T-XKk>NTsiNP&Una&NTSy^+ zfg1xJOlC|lF($tFfNwq+HSs~VPDF+Y;0uw&Oni_j33yG67}+)7x#zTpOZ&nv**)ie z_xJyN=bUb0d(TV3K!BtKXbV-}s-mr`&J%o^AVv{NPTn*f7VR-Y4vTgg+6{bjnAUG- z4%0li!LXTGmS0*7JIRimvzd7nlPk$nx0AEK>&e+0`l-unUDusB_6vXBaot-J33mFs z=P_X?-Xo&Kl*^`05>eA_HgzUI1g(t;Hf;nk-)c=K*mQ}{KmGc2f=yrK>7*X<(n5v~ zi?$d_GR$0bSn9gNQdb-n&GJH846g(=@2nBBnR(t}sa2?FJ~=sWmS^m4cI495Q{QiI zn%)15NHi88vY9#Ou>NZfOU*fK_Z5ewesox>Y%}u$w`A={kyFz-cKj>y>bNy=;QX=c zuFI&iX^tI#FX*|knYr-Cg3x!E*UmYIMSG1_Sx1}kjqAEDR0VYZlJpv_+}dGUBSIsU zs=dRsVZLU(1F5SvGrzT&dC_6fwo1F&4CIbBpfhFGPQ2s;Ly0N3m_@z#j#}{@0c4$( zysHs~tA#RaPY`TvcI&Lyr)V2mtYnA6mgbjT*JA~n{s{AGuijmDU9bDo;Q$B-Z)g&_ zpZbZLA76Ie8O~BHq_2VfeBC{!IxN~>WwL?R@ZO~sg8*Usgp0V zr_YO$Y4a4knrpfg&K?#tnOo|<>$*(%TkzINR_DN*pv2sgj>xtp+cEQ6a`L9m4+w0$ z&MIU3!A7k|z*rIQg!qdcc}(=F*V}P6+XXsF=F}p#IBRg8fOVd#^pu>O*Li+PHd@|e zvt0{i1b{5Q;ElJ%xHuu+#aI!(SGja;+qPLZyLR-g)8iYg4lAyA#5y*{;_;Yn?#yNN zWV$FmtbcYLQ3Da_M1&pJwWE)M6gUe^p0NS(-Xub`h%sNj8hW3r(^B}h(it->H&%xpUa1FVx`=o-075t3AgG97K!EpydkUqF1{rsxn z_z5EMqhbR=AIFr$-&gR6f`6jmYMx&T9QnYP^mA6xXA1tCf~$3Pz=80A^^|_zRB+YL ztb(ih*A!gs!yN@j&!vAIO%!p}KCD&n)r$Ulfx{inBtOID$n_r^gv%jbsERxwv9l9f#t(`4-}6v)bt z;l;`niqEMp@l9l9#zsbRqeZet$BH?tYe(PuLNT3rTfFZZ-EWQO$HsH{;z9D9=LQGt ze0n4&vwUzt-Pj`jliK^Af#?g-FDd@BZ;jxx)R&SF7f7q%1vrE_@?Mem#p41OY8Cn0 z7gvhd&J}q|_VRsJmf85@6SutE# +#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 zcmbtXUu;uV82>s76qx&Z$(&1=p(Yn{N!YcWn-apG;)*NDvMjg(O=_0X_OiwOvn^&L zaos{UGM{)-@zoc7QXWivFmX&2f_<2P2_Z`uY7A8pLT)5#bjN(>o^yM+u4?p4=(*>2 zzJKTYcSiAW_e*s?A4u}S0jTb()LUQuj`GhaAT)p#$Ek(*+57SMrF$V8wV1wVKBn*E zUjZAZoW1`ZiP#wI)BQFElXRr{bsM!lz1>DFsfRglSn}z*g;R@YELk{pcjjBhSaJU9 z4qEmzRxC#GtuJSOqc1%7CICcBkFYcY0JGPz^nnjxKVx_Z=gc~Q{ZHjCzKC=0(dQ2r zqn$YSKKCWD!|_Rrac^|JY8#DPHYS#BOnlFs^V_KDI(I*S#-e0wBq&LziKU+oTDUz1 z;CL0qx3A1DoZb{IF`Rwq_%$1G{3;f4Zl@1m<}PDJKw}wa@AxPi~? z;TaiAEL9@>&Lsl>c0SbeBBFWW-k_T*Etuq08RLD|z4m}`2FcToVJ)Wb#^X1*&&EGA zLj7Zn;2P#Bbj%CG8D8GqRPa+Vy;%lSF^tElJ^Ogq#vbche)WR@(+2^d2rymbh(kQj zE_HQw?hP4TJ^i~vk#@7qjD*_4Z5`oABpfo1W;3C9svr(pU)TlU2Y?U&P`7sV^g|u^ z76_9w+b8y$gn>q}`pz5$-$c;2t$t(Rybqum09wRZGbuRI(7W!KZ*xQ7&=xw|BhDVt zdZeMZ?tVi+Kx-1&_rpWB*5NwWyDB-)$$IcA)i}#~eovK}1n#A60#}|VP81`64bDa( z8v0umfB4-2U^f5+6+TJN)xh`Gz%w;)DulK4AFhGFTm#=(1AnCk-ctili#UWR_W(|w ziSh&K{Ltv2Wv0RG?rfu<2>pcVr=5N}z~O*&E}I&*AU!maI%Pq6EN_98I+?d%U|=|t zofscTXD7z#V0 zg8!`GR3lRVm}nTX`-Fm1Zx9jQpx~b zQ~gN&D>d+665YRnapna57J`N$Q_d_*MNE6kPT5 zV+B|9bw|Nf{#6B6`8QB90JuLi1*AW5fzzVK|1||y^IKH(Y*h4IQ21$vN&S};T-E=h zf~)#}siEJQUylDGrJVLT3&#kT{R?J(a-@(t31+^KbJjummCFvN%tCge0A?mtNP&4W zp9eEHMjJDoFSM(h$n#*P$3{l7qXjTW#|l}qtEay;Ur42275h`8r_J%)*myQqm;^_8 zc5uMTrAD&Cx&J|QZ)zRy`D@C?h?Htr1QVZM}&RqEtO6P``-JC@^RM#HRQ)@$V+{4?H2N3)i?l5 z3;Aa~xV*ny`-QxhKKz&QqY|P%Q)`~+BO&kgOXg3~8^XRy@Y3;H@2^pkN&0yDG`JOQPAnmi$%W|2fGh H$SeORIR;W= 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 zcmbu9&ubG=5XZmURvR^4;x7>EVTGVA*fj}?(t`vVO^~)oC6J4>o9)^ZH%ZApA(euM z`Umvr&8vTgVlVaNwN&c02NAssk;%?%9uN1TA9(D0-+43h_RZ|Rez^E(%(5U@c!1Gr z#L4(*ULH=%m_in{-S77YD&Nq@3E7W!@=k4c-_Z>;7h{2qnSsh@5^lE*}CAa953Z=V+VzJ=N ztOV;$%~NccyEhA90)PYH6oBe-9b>RQkS18XmOHw{2J6)dtbWd#&Q50bEMO79HMYH@ zXT>g8>{`WsQn4Eqdu=IYxiqvs6>Ge#+ZoAkLg$#kuYsu(H!|Df+Dx9nq>EZFX9r>m#1P?*(2M!ryFr8zKB|)Cv)8c81eX4t$v> zR5KdC2Qej0r`n2M)%4Sv-q7?(O^-C4iXw5|X!;pVr(Pn)cqF*dc3XK(xRL6`&z8)3 zLFlv#jO4#90wek5InVwkwrnsk<;TFV5Ba(ha=g(zm)xJw6 + * + * 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 zcmbVNPfrs;6n_gSRdJ|9jR_t$W@Bms>lRTPMchK6H6e&ZOyM9b%R-6UmUP#o7>q;? zCSKrc_yN4v$fbOOHmlWm(!`kH$%9(+wlnQ?;$HYA+c)!@_h;tKd(#&aQye%c{6II_sd_KPL>F{I48&G;* z?gF5LFjJI$MP$4!MfPk(^F|cP?aSzi4})WWF}=XlJX?`#Wi+n4N}B&#UZ_XUR>HM% z^#_`ycJ^Z*%GHC~yZ3%@rZR{Jsg^1~s|U4mwN&|nD!7gL$KP`GdcBd7yA9EX?Z1po zj*s7xBgyHxD{^#L9a5w6kT!H(i$*m$GHb2KDZ`};gEy}LbOC@20GO=g^c-}6R6>s3 ziA3j}G~8J#rDwAs6~j`0Pj_ff0$2fni*)S|$^_98B$gn0f}|2;W|E}Fi2jJg#)$TS z=(A+zA<;zXnV{|DS}7aY!g0(dom9}eJe2k_?uc2RTI>y zaSea2fzN=so;B8NST&X%8_c|uvB6o-Wo$4DmSOvp4OVf(Mvs^u1lA5_?{~d{%N*a$ z@dK3a0Pt&z>EGw{L!7?J@h3Qbo8wP%{A-TKyJr61a6GU7mg9Rk{R+pQ=J*=rasPN` z<{x_rfjoXqsLp2AHI_kj+(JWU*r;IHhU!{H7t|HQH9%c<98e2+oT#Sb4)c@f4N%Q| zHf!ZvP;+_LQj^njgN|#MPw0Ft_f*{|y9o{FR%UUvU}UZ4ZjKB*ANHEqA&oa0 zntj0_)*SW==8NewROkZ}q7M(=0S>VS5ErP#dP1JPM+|qUod}V}xVxlNS8cPWKxUIGU0RICJ z;=b7ZF+8X7Mf(!9XZ_3|+7|=r=QB+(s}rmr>~Chzcnl-PM(C7e_kg{Q{|=%(zCB{? aAoeIZ;m=wS^LHk|{ukZ + * 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 zcmbtWOK%%h6h2N{YLdohTtJOTQM_>JRHYN!P1OpCK9r<3QWT+*h(vJ{P3)P(P}`|z zkZO=fmB)fbC6+~OSg}F;03Hjgj%Zb}h`OO_H`yS?0?{(dD$1a9ANKWN3nadU@7(X6 z_c`~wm;Nj84SEyL9HEHW3ed z7#)jib_Ppz#?sgCKhU|2`nHYFYBn0X_*D(Z?`_oF6I{zi<3W>)+NeLwtZ&8U>Ns>; zsNVB1I@R(t6%TLL++!YUhe&{=NsBbbSSVw0t&_$Z9%dhTNXN{Bhx3m}@n7^lue)T6q)GrTbcRZZk_Ar{Kd^I<&@e&U|$F*;G(I48V|J+uK8Rl%3SyKZ> z{jrBLH4o>vZPe=&_2yIDxVi899?m@VaE5ACZ)EpsKI~^_1`X zjY*%3@chY6Gs*!GQnq8118l&k_Ix6m4aw8&X;V}H{jrVu78&($X3N8Qw)ZfaZ4FSC z*`PehbG`A3@B6G50MA!b&-T8ou02`h#P%h=?p%WO=;+%qJv}*nDwZ5EQbsbCN~F#u zlF39&zh>oQ8PgR9XU?AjI0yhS0H8{zC#RtYLN(&#T?>i*%fj=kVhw$A4MMlH(BP57 z;V(h}BLHw*oc-DZ09PW~de6I&M9=l!h;}6s&h%Nm5p6sYzS>vd%w(UC?*#IH5dM-0 zx8XoDx)!)CHZN_^*zOQ0&jiD3g6HQgye{~G7R4|G07n(SEJpx10q_qSgwtL4WEcK? z7yg|te7Xxi(S@Jx!c*^qHDGWSa?Z_)YvjO~7){boihj=0&j_$H$W<)!2ILAwa|sGg zp=3kBDVZf$Sa1qUrNx2^wz=p)uDntu0+y>QWtW?e@`cSG^=8lKIH~Y7bCUm5;d>SS zj^JtJ4k-M0iagDRwDX(7t9JGj{)i$!C@uosiGGDYr|=Plzpn7Ayd`*wlWfU&stQlj zEBWsgJE-vY75SGG{uf1_`YG-7lSAQCjq|j^t8tzcd@#-hMP7}ksK~4FR1|qNo;wP! z`u$1a)i`NB33Mz(I1Hy+bj?LD9Jj*PW%*UHZkUE^-EzUmo307QqT_&3DbvQtIqn58 za^+&tD!E{k%C2RkC#TOiu9^Et?3YR(8!MIaidAu|z|C393wFgUTEhGP2IWO9qnfGU z|6!o{zDNY`=%DDSl$Y2MPoOS}MYB(SetBJRS&7k;y)u(rm zY#wb|GYtTDh5ma|P#~!PVVC}gg`n&+^`G8RsV{lTJ?NXTEBxOT#i6&5@(k*e d%}%AdE#_}d1}+e+HNF3x^kc$NRVsGT{~O8gB6I)% 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 zcmbtWPiP!f82>h@?O5x6vq8#2D_P1=C(ur_vDGM8n`GOp8e?fUnr_#`$!1>?YLthd++!C zecycZ&0am-ccv*40f`8lgvP0X%{`6%DZV`gIv{kt&C)niJ-@J&zPX-A&;8c9kTQ;V z7)u$ZhchX|Tu2$(I$3zAj~d!S&PcE>oVn#;Y}7EgPJ+uB79V|2ifFDd+^C|pj$c*r z^y0Ou)9D+dc@M3%I(x{&Sk8!h7|R$3xug69;7Zxd%Ohbc9oc$i=R!RE6!=cqjUtsGjS%&H3d`rZaZc*+GH}2rEO@| zR$a{g{IIrFt6k^$;5*!q;YN*LMfWhfDWZK;k29E}I7$o;^$gD?WoT$FHsWf&#KUZr zp?TlM!TT-_Em1a<30;s^UUM;f6U}A$cyr`u>2ndl}5eLYF~>7bwI!RH}gF4&hCQWF$TlK6P1Y~ z^EXAi$Y6YWs^kFq0A`O=801S+)0K&_BI(dNGT|_IPSlKgimLv&=A&2PHHH61;i>1O z{UYAI`#-y z6{qa4<8oInT(T{vaK!;@)OKvJMk*Ds$|X8j`HFK~J#?yvOGPRVX{t;72Nq53{m8SrCc+KhS;Y5dzx3yRbi|l0sKqM-)y)Yp|dK!TOiQ zyc6N-NC^92Uh>`&pNjZF`?JEHz7Hyb_VXeAmlmHs*=N*$G^eD!Ksw`5kIa-|wC5-xK+N{x9}_1KctM)&Kwi 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 zcmbtWUrbw782`#PhXYT$%@~rIP?H;F2CgjwO|-#Q3hfqPmBCUVLQ7W$*`>wynt&NX zR*3OQ;**KS__X+Fe4H=0Y%k0i6XV0ZxoN>C*NiN(M|E8DoqJAudPfrzf62Y~oZtEW zo$ve3Y1amZ2Af|scPs9%H21*vhNgC!iWJ+el=Ld|`lD8N`v&z|GD}9ZaL+e&ch21& z1}Nzz{ZZ?jTwT|rg?*2qnE?p{pw2>*p(#_5Je!*8F;1Wv+k(42h*5ehRcgk^7LJD| znDAMB&+L?_tWhjKIa+>t#+Lr* zSWkV&3`pf2_iLuUPHqy&?s0`6Vqs?T-0BnJ{fChI@ZcN6N;A) zjG|H8G~F9F4lN6dVC?9cQ7ms)rVlNvRu9_)wa=`e1uTE1_t3Joo~>4OLldFN>W&Js zWm%QJS{@vAwp6JNADXxLB#pjOA3b`)?3;?@(%=8Kw<9t#e%|Zvk-KHTx7*j< z>+}14-j31qHE%SjvW2d<&I23=051Sw@ggJR&;%|GIesQxY<`THf02D%ACH1-+2cCb zda`-T1@Hg>US?~5HvvG1cnVEn5)6}Qn8d;)9wv$5`sqayTs=iRA<`Uaxk_R&5`B*Z zM{Q=HB}x?|lziVNFEVnFL_;JPqXL)c_$rAFk;G*(A0|t~BsfNwF4LuDlDIi<uGYk2J%$z;QBr`b3FI>;e zE~pC3C1>*rq_RsZNGUMCvXoU7o;tf8_Bp}a|6|#>zy$ED;7=9jzZLjX0{;W!@o3;# z;_^QW@+|`YRNzHBZR}v8U+gVzCm`^6iE=(J@I>HO1zwadFdpMXAKcE@0*~Fy`CkP) zZh_wuqW>G_$tTyinZV)-Ay{bA{x zHx|Du`Mty8yfg6r!hYiN9N#m89V}_s)98oab8SrURmSt*A&z&P1OsccDms}>r}%%> z_cQ-zsupbom_hrVuL1Xp;9tB)F(#*ejOjb`#pnDx#Pog4E=PjtzrhIxzJLB5XZlWj z?o5b7p95Ryq_ejHV2kNHSY`g}&ISNzOrQQS65!NdZqPqE6Xbn@b-??Q>vJCS x;Pj37juq%jmMA>yxKF1(-tkAJD#-eGL5Ll}^Ui_4_ebgf$sB#k1sR + * + * 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 zcmbtW-D@0G6hE`6?IvmG&Q^uRDA|WqreMb1)K*c@4OyF|E}_&c$DneR?>Ign*N6!7&y*tf7!Sk^9-rqgv zcRud9cXsia{IQ6lfDi?qg4U`fJDsh0hE6j;K!w6{xyJ9hM`HP8)FZKMQrp2@k7y%F z%_CYq8MSld{JKr_Pw7r>`TN}3jf73~t>vprzxuwvxb&~@-&}m@<>fDzuK7NJ&hK2^ zCO21YVr-p@xSe*6RDbhG@hVP`>9bs8LqBzTo%F)e4FJe2|3H05b89~*a-G|)5Tb9a zlGn=$09qj@i=nZh+eE)Y`4|tg4;W4>02thn47uqJyKltNNgOdGjya~`d*sa5 zHqqBGopsWi0h)qGVk1cwyiG=1UT||$#HqD#dOEFhq2}V;id0RUUo4x9Hjj=Sr$@B$ zw!CSqo7c;?eBWL{I@dDc>uVd@12SOz<{c~85vOHjgG9EiMU;Ad_dI( z)M&PQp-YV)=kv%X&5c5LWJ@S9t{KkvA&vv8)`(=)ROB^PJFZ6g)@_1u?}0!4+cp58 zqnTApy6JRp3*e&Bk@jYr+)Gz`AsE1Y0B}&^r#0ZUWnAs@5WueZ!y$No2>xUUJ{5u= z3&Eca!B2$Xg%G?Lf}ak-O=^)d)+o+I$u+BGqXb5NupfWY_;VO245hkd&OoU$ zYfeMOsZ?z!)#etQ%5)VbCMu3ysa9MIoJzF}&I@%HY;(#1Ykm$PDAgQF0|0kZXY3yA z1Au>gCVdi)XDx8ri(DV?gupLJ`dt$Kg@j|T34Kq(_e=Nze(|sz9TFbrINnWs_XUp; zqJLP@S0#NjME`9`pGf-eOZw^Q0tP)~`#re7^5UxZDpPa2yA@4i_bTd__c@mnB^0|3<=P{vSDxgUpX_ zGYaBdg~}Wonz*<>U^ol2t~mvU?j8U(oTwrmQ% +#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 zcmbtWU1%It6h6C&?Y3R_&Xyp7Rf(7|Yu|D`~aE zVez!8@n6MZ3u#qbNvqL&Xyh;@t41BBWK_ju3u_LGXH|9Odxym{YJ!Usmwt9#cah7P zwt49v*Iitkom;u{vFk2^ebi*X)|kF|F>FUnR=)4B+_xqxqo=gm%KaVWep-#?TRmr9 zSz~QWUgUUMjlOdY0BTYyZ`9c3TnK<^pQB?D_5LTU?J{2__bVrl7Gog*OzcP>yYe=m z^-Z!|=lT|h<<`BdMjoZ;8C4<89f##=4vUXsB}N{>_adVVR!re9l&spqv>(xv!*V}4 zEVto}BTsl9&wk;sv)?dnbqieA75P#vvXnC$uKPDxc|)Y9)M;-|a5tEClNZoS)L}U; z;_nr&4q~Bv2XP-q<+bt*H<w5oDVLJmAZZ64ur3_QWxGb7rwL0~rQ9SE=3E!?SM zEZ;KLFs&W%`qZ&>0$`~Z2KxJtCA5LTq4q?oTkq0SiLPYV)5%mSnb1xbClW^9rWc(@ z+X0#ZAOQfl#RG#w5Qb0%t_i%v2R5?5PWfLEh5`2f0?i1E+yDRo literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_ctanhl.c b/src/openlibm/src/s_ctanhl.c new file mode 100644 index 0000000..6d996d4 --- /dev/null +++ b/src/openlibm/src/s_ctanhl.c @@ -0,0 +1,60 @@ +/* $OpenBSD: s_ctanhl.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. + */ + +/* 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 zcmbu9&ui3B5XUENwN=-!{sOTcA_Q&0#_Xb0N|BYW?jm(5#f9}}H=D+8@$C;b5n3rI z?8Rfx{ssO6g2xtn(Z9eFSv-0uq6fi(P?=;V`;5&+Kak|T@4T6Lc{9oL8?!eD6a^Rs zu0em+=jUL5oC}6II0`8!c6YAsd3r^@zM$P-)3suEOOp*aW~1o~U8~&txUs$APwW1g zZn7nfmST4&{g+MXT5l5r-+hE*e_9WHgr3Iry*M z+yk|GKN#Fmt2K3mbM6P`AA;|D``HGg-StTUz;Q_r_5=VY03h987I7v)KbN3iNYF1P z=$Ql^+y&dSnss5=5DviZIF=A#FE^|u0d~u+2X_JPax=Kq1;8oVIo1lVUwa{0NynP9 zJ}c=5CA}``!;=0&(y=fc=ar-%l634LWPq*+!(DB7Rt*f->x9obk2;R949{8dz*w|A z3yhlUf?>BB4X5dW(QJ8+Q7DxsT+gzf(0r-+)M$5FZKva{LKwlRFFfv84JS(ZKj3>{ zui+WVg#QMJ`iP15(kRt~*E65-U;tp9gu|4FoBlNE=Si1-O94N~9*4h62Kx_V{;NOs zDaJH8Ai?=Bu|RNseom2p9Gw@$h|9MCf + * + * 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 zcmbtWU1(HC6h0IGqQ<+aZ9!DXwv0tVZ+Fx9(>7?Lwi`u*S^`N5#?87h;>}NYS5Vp3 zSOxp@B7N|wSP&ly^&t-d^Wei>jU~IrlD^&XZdO4Grb+=C;O49y1uW^@$WGeS7mpvnTxA( z?cRFs<;uwxe)o?G*}|+d={9p`5>q4Qge@KlTV%uyap%#p3nD9W;-q#Se*xf%8_eSe$XxZ+7;dVlmLLQ|4t2*2Cj3IN*x zMj9ZpW5)-Q}9TzepXIM^0V(ZYt!>pXk&0U!tfcxaLK z4yXZUBd6{xqxn4Y_YLaVsRO`H)U#D}i)t@0fH44AO>4i^pfO{VMT~J4F>DqwCRxOo zW_v4eUB)EaZrH5Hm}c!X?li_(t1-&@ml(CXmhL7i-DIT$tt>HWcQ4&(*la(s5yN2- z<38JE*sP-hx1Vg*d}r9Kri*6e@yo!K`S3(PsuJdvvQx%VIb2vK2=%g;SKn*gv}^Ix7705k!-v?t=jD*W~;e54A$ zw+jDB6~3zq56PZbDmrMHF);V+cn_OKY&K%E37gH>Y{BMzkfIPv#G{r4v7-agBNoJl zlCtTypfB2+v>iBfkMZjJUee_8uZEJ(YrO7{x>vYNA|A}- z$$?a~7tCZT;r0D$l!#kVGZjCP0`qV*6$P_5nFKR2gcCECOocb;vnDWOLjwcx!4#N- zL#enKY46yOOhseIXnthyxH+5{8jdGYC&4ow@9*hLLL3#H;U!!Wut8pzi3Yo|D8^g{<|cvpyF432kHCqlRqH@rKf-;g!k!% z+6I78()atN&QIZU+TX8#pY*4dAi=MHqDuXYlc1^-%;S;@^@H*F_eP9Tf=4M}e1j|L f;~P*ZRfnj44=TqA{`}!vT1kJJ{6DW0tLXm=MWefz 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 zcmchd4RBP|702%;M8a3@@}ULfdQCq|^TCo;K%TRQtKrLhw=%gSvAQmLr0;WO?8hlPirhIJY+;{KpKM$}i+MXHS zyYH8K&iy*~ocrFgJTv>j2%C*5v9Yl%{1ldpgTiH96m`Z~49oLzN8_VDH-DCPaIFs)8jpeH|A{hI&fwAi4ymmcf%;5P^WYOUH zJV*g<%6ICEW*git4AeF+Nm1ptp*|irfsER3 zC&fTp+-@3|kGI#^nhjofbjV4A53Mt}r(QN9>zkc1nZZ2)lb3r4U2pox5j)>~tTA8Nyh{5e($nyi2duAubQZr2k?>RNm?%qpd4F-cj zcS4iT%@;Jf*G@=`_HjqR$ET^K3K-lg%3@{=ZqH7PHn@FiqTS#0q-fZ zV4GP6o5rqP6aX#LDOoY@% zgAb+6ca*G?-RT7lsw1HW>uH}D+}k7??zmsfy`Nv_;|}We$(pN=iI}=Lf-(2nlkULz zIDdD_0C(zqb#8~?&|#}*tU4&0F(4M6^7bfin_nwh~ww?m*M+PsPO7YiIuhjccpv|VLG>uJzk&N+~?`N3ly)@%;!4o?K@bnzkG3NUrVWP&~vXX)~575(VR1MtJZr@|GCSK z9M?*PUY!+;E|BTE;5tZAKp z)-`>9(f+m!UB8*qE-w5jXXX#GFUnP30qIxQ}>_}t9Fb=t36U-{Tuyh}?iZ`*Wn(iv^gXJ5to z#{QnhH#5++P2Kl<>$m)|{nbHr#<7-ZCAm}eU2nbL=IuR4_YHKc{B8DZef_q>EnP=U z(FdQ~nbGO)d-R!Adt2^E`CLn#-D762l$F}7E&i{J_8t45pXA=qp4CskcZd6{ZI0=B zpU8@72~AJvrH%^;eTS{oAMf|mk9rJwQcpNHFSmPYk-mCS#UJ*(k*sU!pS(Od{i(W5 z`ObMooi^$YV`1+#7gp$-zdSg;pwDdmCoj#&>r(I1|5{sLvG@5_ZBqI9QKH@9kB>WB zkyclH?v-=??aTDfNB`}EzQ#6vUg9&QzYA{HV{^8~wnc2#yS{SQz#U${zA7$g77nw-ZXn5~YOdZ)0-=Psso)<@oLPvkP&61(lL?wzAI z+8BF;G1g!H?PD^K5o2E!kr@-aA~G*Vk8pR5iOq2ZeVlzbp8DKNFTjbleP_^7{(%21z#@mT~-En(K zi44s~Sj_o|V)if+5+klrEY`w%OHOl*V%Cdd(Fhr1;%VH@4@th=!gD0wY2ni(7cYGv1(MfU>K9Ai zXyJ1uZ?f=m$xmANLdj2C_>+R)Cax$o;vtHix71%Pxd$sV#^{Ba)^UV|Z<2hbg>RNT z-NLs@UTWdnB$t6AB-q60VC-vxitjENggfkVYx?gyM+&vJl4Wp zlE+*4NXZ=*K1T8p7Cv6`bPJy-xo+W8BzIeQp5%{M_;krV7G5OzObeeQd8vh$NnT;$ zRgzx}PomszIjE&+s&OIQ?&E@4(^yM%3*u;CIaNupko*>RznWY!U? zNv2t$n`Hh~=q8ze6)h);Mw3LHWI>VzNfwrqh2>;nGg(+m7Iu<_g=C?XB5bAz-4vml zB6L%PZi>)NF?G$+3z8=4q@}TvN+0tT&8lK0ODgC=q^c~jNTypvGRCgZ_qt#(I0ZN@ zsp8Xt)7eaM6(`BPC_5?s0@Uve{PmmgdG4NBd@cGRH+{B4sB* z?hEQ?SKz~e({W7I9|gQS@J!(J0YlZ#0ZwNw#S4IQ;PZgfnN8JS1iUBkr-AnZz5zI$ z>6D!-=V0sKy=e+@XDC6)b18Gp#9$oCWao}{uR(4JUPXK-aIGw3g z{Y$`c9(vNIy}`cdD>0jGBa#mj&X z0lpOYP~f$|hXH>M_`Sfl0;hKl)$W_Xoxt}1zYq9P;B;nIc3ObDfL{Qf1pE?kde>2Q zI?23A>y-lB4m=fjf8c4r9l%EdPXSJ6c-3wOaC*m5{9)kt1J4IO8h8ot2Y^2gd<^hq zz{dh#3!L8VRDWIsPVW?o{}MR*`Mba~p#J;7vHl?Oq07t{7*B=)$9OUtIL4DK;22LH z1&;A#25^ig^MPYLSqvQG$qL{YPo4#i@#JOTI1g8D!V~2yC;8_%n9mH!X<9KaPlWnt z|7qZump1^%yu1ZC=H)klV_x0`9P{!%;Fy;W0mr<20yyU7&wyiIZU>He`7&_K%bjUb zq`zTa?hPFCavX5X%hQ2l{+$CH^Y3Gl(|Te4ed{Lt1F$n5*1ZKd71e&U$qz^xm103^F0dUMmbAe+%S_mBTQ4Mg+N9%!OK6(i_ z=A$=(V?GK1p8)fJ9C(NI0*-m=B5=%8SAb)lik2T-t$C^saLiNjz%ftV3mo%QI&jQW znZPkmj(O@`;COye-(6`w>7Nq6EGVwt ztC_QEX_>!h7IRklE6sbUDpi&|R^;@TEb%kv>>_^=bIz)&V$RBPdTjuV4<_3vb>_C(!Z3M#!E_P_$rIaN>ndzU1;3& ziXg*dNYwYjfSfNS*6-Prb1BBC`bu_-9}pR<7QZSpksGKT>CU0=-xMQ=%i~x`Y?OR% zAo6u4B($f==B?_}9weKTD^Q|k`_bqO(0?@!^2HnJ+bJ2c>%ZNo`BV37sc-%M8!z=K z)}W~It9zc*x5^Z$ZxyAdgj|U7hGm%S5vgzOmm0T{WwL#%eznxMe$Tb))A!^X`A@q1 z|7ogyGDl0I^wsYtG#+c)B)aswlhU#2k$#J?>XUn0eTO7g{*blRGGUfSarU^8eyQxg L`Q1M(R{ehg%6j3? literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_erff.c b/src/openlibm/src/s_erff.c new file mode 100644 index 0000000..ed6030f --- /dev/null +++ b/src/openlibm/src/s_erff.c @@ -0,0 +1,184 @@ +/* s_erff.c -- float version of s_erf.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_erff.c,v 1.8 2008/02/22 02:30:35 das Exp $"); + +#include + +#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 zcmbuEeQXrR6~Nz}?}CHP%^7Iok`J5YLe?Z4zO(r(+y}TZ30I21E_d?fz&5_377Vfv zV%ikj0^2x6#cffWMo7?#s{9c}iG&0Vt>A2@a!e|j0+p$0m5^4#rC;gNDp4?7z1cUn zk9AC=qL~IU*k;Aix8)8`EOnK<^(r z|6&+M` zf4=P)(?x2eY*ZKXhjbAi7Fw3Hr~A|pOrVQ+c0lU6fl7onBD5i0Bt}#>x=8g4ZKQKz z$JpYC==M0};AM}xNYWjv-}^Z&_FYjUHPy#i+yD1mRO2h`9o0oq%$NTJylWU~(LB;y z<#P$GUu+^vCi-=el+SW1y71QcT)ObaeEGU4a`}XIT^I3-Qj1F$$@hddsEb5@S~OqL zMXJVEsEc?%wN1EuvZ+gGBf3ak>>3jXUvWrlQ+LV!@soE9qfcm~*2KJObw_oPxTISX zyP%7tdS~PDNn9;WYFHNuT)^x=+Am5D;0om?_Xrkr>QRm|H?m7OEnUQwVTM`fHlFMJ zUVK0osUfsLhwRd9Bed-JFD48_7oW}>KEDTye>7njeU@V;v*Yt73`3OQuyWogwEl4+ zv1zZV;#Ks#31)Pw|`<``)sa4BO`1@?Osax+tphxn$7S_zG3f5A|00@`aYQf<8AGH7^zm$Dd&?bk_?33e_7Qsx`X3|iZj(pMoCAR9 z<=y+k01&#oJ1=zjv0HC0D10?EYoqh*a>pAhKD==(^!StSul$FvEVQcka;WG=X7NW= z>6J^4JsomY+#fzPcTO12ZoX)UHxey~Jo?KS;l$awD-LvQ|8;EP>F~AM-$(v^ z`n5>;E5+Hax~}MVtKW(&D<}>B;P~7XKfmsY4wkH3mHJiXDvxVz6u^sP!Q(&}X3q`D zp#sSKlauPztCyE*)$3}@N&}Vtpg&L=EDtU!4+P3fwGB;MOV`wA=*5C1WdJS!C`ePxq`gIj$CO|0l*pn*hM=viQs=6I zZ%_9Wua(cw7UXTW)NClA_EQPY(*+-x%WjjroE0pYE+5^HZy_myc%hA(_Hu*Q#?9lM zTiTz?qp~1F;VyZcxU#@ed0#aW6ztViJ0GvLg>l<3r(A2gojpfEPM5S>6oB)6(yKR{AEaSL; zDPGGsW>v*iUPL{ZWfWI=4*4|3RerMbL8c$~1f}OHaU9D+#&5FvT>pKv;i7)rYn2`k zDfOIPN)0 z&ql_%pKNBFkF%4w-G6$gsQ-P&@ob^`J<9kT#$RRpA;!-zj(eceGsrl8yD2`xIG$Y; zzs7h8<2M+`y;{|GQU1f%a~Yq__+yMe%s8Hnlpc+7+}jneWc&%nBaF{uJjVEwjK>+r zvw+gSmGLshcQMY__WI{=@U+EXH}BEMc7I$)_0Sd2$Kk zJWsA>oaf1}GS2g49pgMt9%P*7!y}CIeE1XMXbzqauS~%|WP0$ds{D2~9kJ1F+|B{w z_H|h{Mg1t_JpaTP=lLheIL|-Z80YyX!#K}B9gOq*bBJ-Ce_m#s=buxIFJSh0hjDJV zYmD=}bc1o8mu@l6^O7_=#VOBAg}4~Rd0r}JoaZGU<2)~wGtTo;4dXoDs_!TC2mDi_ zzAqJ5=T-2x?%k28ZvcO5rp3H(Q%@~T+w1+ArnU_Dx7KIs!Qar@3jUUzSnxNtW-56B zPnV55ckF0t&VavpXQs(ty{>jaYo@;On^gXK^KSpHmYutrS~7dVRNl00bGoH|N0S=m zXBV6|9wlg*a$^4P1)!enrNsU{k3NjCqUtM&m_H1_7Wx4Na}D;Rem_v(rMSk(DV^u! zr?!5T(6J{c=$okXv$hXV|CoEYoS^>A?@CK34d?FoV-$|b-hMqz)NU_TR(JgV#P;^@ z-!0T0_XaL%{_2kBeD%!burjnw>~+zFaH`zrQTnL8eOz|6-=Y5P?ax!iGq(Qi?eTl$ zll$G6Fr{Qly_V!rK?mH+NZgv1rY%`dxDEG2Y PYCl2)>@n5k#NPgYaSF_( literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_exp2.c b/src/openlibm/src/s_exp2.c new file mode 100644 index 0000000..d643dbb --- /dev/null +++ b/src/openlibm/src/s_exp2.c @@ -0,0 +1,396 @@ +/*- + * 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_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 zcmbu@dt6NE{{Zl3x+j|MZJ|c@i>B!!#d$QMnx##wc1u#B(O1%xB5XBsE4zqg*JYQs zT$d$%*9!A6iIv=D$tt9AFXhq&YuM)ZI&(fJqwjCOuixwS`}}dvd4Hb!Gv}N*h2c>V zIvfsSgM-GP5Bd;hwjZvAnoA+#B2y$5aSLihCH113r@Rt{t6Hrt#A@|=;ld!SR=+6Z zu4+dJX$rW=xGr~~nET?w%4^)>s|cYkZk$}q^{5kbJ!)#Xj#9c?x-rFFWzC_B&8+DZ zT}8BZ5PjLjjjN|etn1=VuV3COEjh!HyY_18POqtXYShIw)6^^ZeYu=dbKk0qJ6*4) zi)&`p*~N{o>*B^iFaPa2{!G7m^~+QU3FP^+mz_aKQqaXU)2HVms=3b-i@5V|b#db_ z(%oy8A?EsOO1aC6H1lQVBj)$rmM6s;{n=w+y=M#-Z` zMZz36dJJV3H~x~Q|1NHvrvLu?*2Rsx(8Z0{tgkIwtyaT+ei$$QLfbU8TCEv{4GAX^ z7m9b3Jr31mibL>t+g#O@N-%1qdYepgE#%-l4{~~8L-U=hV7UYKv`?j~TKekC9*m0L zvhf9LnQYa!li%j6!HvG8!ly@^!+iqd4JWlp9j&>JV7VpMzxs4lkuO*fOr|W`E!q~! zmLu~1(#;WM65HMvcg_j>qCE+$)WxEV14mpWV1+vgPP{wmUs5n?mZ6~sgO8W8en91M z+80>;#QK>mS+US~=@GDyhXZN^oM$y`c^MV7N_CQ z4UTgm(SyfKb=PZU){6qLz2P6fT(e@$#RZq6wwAbp<->>~?6^Zz5Ln@fkJdX!*hhlR zBC#xCr)|%d;AAI!c*FSZO=;k>{$z87UsL^JFmfiw)eoM!#xze zI&I8)D~FKp)Ei6^tiVcr^49m~&ud-5!dKLU-!E5=90}&x;zL`KysJfEWK1qjsk=CS z8aT}r56fJ*tvMa62qIq5cXt-$v-LTo!gu%1D^q_YgXE0~n1KmY7x6?pmx zoX}ZOwBanc+6|wpo@kfzC)>V5w$Ay1-KMXO9w>iU&T0-}ja5 zb@jSuOB}#TW9-hK(6L$#&NisJafF3U-NnI*I>B;zV?1`Z2AsxwI`|095L)sC0OE(mvvu1on8w@O_bD~8l}F$ z`XNDt(WKOr!KW778Zh~cd4pR-MhZo2$t&+ zU4x$lmAk=`K}4Ln?U=F}TsjD=YbKUDTmqNr;LM-8YyZ^(&T}NyLvJRW>0-;xNL$s| z6c2+AW<5f4qMWj_dAl80X@Z~6Ry7UrVatt)uR@)4KnPZt66?QJd684W;t+gM@g=`= z4%p0|{8m$3vTrG4X?Pq7cw(?AV?C6M>`BYn$zKX9z~~~isr1Di-Z8L{gG+2O_}q(N z-b>2jY+|fQ3plx(8hs!k!MYn?+2HvDc9wr{`~3`SlUK~|H|neb{))nB|EJ@WcH0GV98L@v2AI<_wT`0He^P= zUHTmJ=gfLUCiqFkE2{`M@D(AR{@iACz-VyVK>Tay*H8E{V1Y47%b4R5k_twTWaFdG zzni=S{FfndJ9c@|;`Lxjx2&~vSNY*xV8tWqVf|ODdX9tbZSbJ9bv~l2;FwpG)yhxG ze|`uS{!Up=OL;z61(rUS8I1jH$Pe5X%>0X0vRTK|M|!)0ONW!(>}Ju0QDF2lSu% z1gwR=f1YR=pMF^deO;g#MfQA2-=?1*pk8QxV z7NkgLv{l+Lw)_M&Pr7K#w&CC{FR1#H=KO|{Z25UvN#Xof>v3Q~BQ+GaxaHu_* zw$l1~WjuI=4%zHTnGQ$=CwEfzZ<;;RC14k8?6WW1yJ0D~tWBoap8HAoYOwGzRc9!E zO*Vq_5Lw>+d;ORlV6;Uh2yxtgem~n@O}#IEJ1_1ixK1ToGw)$|ryMMAqHILj-WxB0 zdHT39F~oUvBUqu5b^meQzvBV;;9$IGe@oKt7vNSs^72~mVevb#U=W$;eA7c<*vag7 zOed9)V4>hxf>8(c)@#Or+YVrv4Zh(wPfonR!d5C@ughv*5LjVK+I;pO+7<>@wo<`< zlfK;?&DL+Hvexac+cFI-(8n#cSyOk3!NI!Nd`do5oeggAz&lTFUe!Bl%Md|8Bdg8`BN&m>Ah3TGjJ&fzquT|qUJ3)Z!lTEc4qNtgDz%2 zH~C5kmKyU19xwyR98~m3Yev*(#xM6=1m)5uDtR zdtw8)(UKUqIKKLE2e{G*Z#VrzyygJ-DWdSqAmWA-2J0B><2PQ_%xwYOk_4RQU=Z$Pg>H?x01{={VW^Jo56 zjHN9SQhhV(y<`}ai=0S#+rH7&eDD@mBDS4fWki7$4%l7wKs@tPFuEh-?%bGk?hA0E zfE+KrTkba-T<3&CejYV)Zx%S2hkJ7zoZSjp+mPT!{ftB3fRzJC?U<~=!foK}@q}0Q zDDd`PFwY2Yp5Jl0@F-Y126yeVto5m7{ep73_iX$l1-Q(XoD8&x+H)5yaKo3PhqOpK zzO<>+YoPGV~ORoxWj053RXFSb60+t%$d!9izZk=XrN&IVUtH)kp zjqvT}zqeN10ZWGC?+!FB^JxbwhY%f~9~V}=1@r81jbC`-Sff|W{>Y7pm-uS=EgLXW z$(~LQZOwND8%@BsqJR9tI}qIHM(hv1?ztZZ9`8?XZ%VA+H5p8aaJqS0vm_Z@>4NWi z9u11j1Wy}_P0!xH?Op&@dXmiZ-#1vS1sge&C=<22(GTE`&#?PcQM2IzFgh#iS+eh) z`3bhZ0GmX_uW`Eou5%-y>$aALH-fiC;CsAZtTUg0g@Z|b`yF1zYp}!?SKnE9{GR@6 zWs{n*&%|5X;(2ff3`t(x)=jI$7`WDd1!e z@_j&TQSeM~Zx&wXZ*;yU3(Oly3id}e#4cmoKc=!a?Ksj?3eNK+%-{b~=93PR6li>@ zRQ~b53#!9%rmxnOHpYe`y*I@Ns+NcDDbu@YlzuQY_gs;hoW2tJB1F|2#%KTEuPj87 zJ0C{L95kkW>Hb8=Y zc{j)h_se@j9)9q?VA>lXQD26MAkE33UlyU!kcVaV1=Ftq`lK(zM7ZW;fMWXPCqiC( zU+AFgS!nHl-*34fDK$^x&!2^IX3j%7i!w9(1Ofr#M~xdnAA;z^Ncs>=A42GZpQhN4 zz6_ubftsYo{)q039xq8VDndF4Awz`Fdo>etwes{Xu=$Nzd3x?_zEUes->Yn1rj@7f z6*ga|l{eAKH)`bvYUN*R<>|YM?Z*o4b$b5vM?g03q?M=dMK&L(mDlcv`iFduR-UWX z5B<#1L61w{3vB(g!eg1=yKMo!91#9xq;&79NNtL)TyDg2z&yd1=z zosyG+_%jzQK>X}X2F#g1Ye7yh;?K&=$Vi=^gZT3^b5i+{(Xl=Ya#CicgXhf8ZF+~68XRzjdg!<~UVWjyKj!+ux zD}7JUm+W)HK5z7MPv<|pahUiE+OhT7=5EE=WHt6>V{r+H= z%SJJ@?>{eg-fS%ThyAPmKeo^Qhx + * 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 zcmbVOeN0B`DF9*y&3Vwu1mgsbbm^e}VVDD*+@#C3u-#P8$Wi`fM(tGax zz4LYNJNLY1@9W%C=5hhU1-qfRD&n-eIB%8HR`7s;gg87qzHpmqn%Nf9G~1p~T1+#W z6(<$};I~=R%)&@@Li{{;{8MrAZ2%Cyydffa;hQ-x>RO=%0Gh;!ivVB<&qnkteEE)3 zH{i?=k@mvG*E_&xM(}W`G zj>%n%2C0~7HiSp!C>rwO$i1d%GGPdhR53&}zcO27tvwgl(Yci=beWTGO5x+Xvxyfc zuc%|Ll}zo+->P3sZfpDI%(6PM`s$HqKlo04bFufimzKX*U+6x5`T3iEP{*eJ_;PdP zNA=Rg)GKdI{iIrcS5-0o`(WhVRrRTdpT6g8`l=f0A4wew>FUP!0_*>F8|tmWn$Fk1 zGSoY^?YwyD+%IbVqaBwk-}n{n+W~Tq18h1EkW&F#@8?|KKlh3B->zIiIX(BzQIxsh zfio(E+uQH*`odj3_1-{GX;cEZGjXWdU1>uPQJW>WO#yQHbA6dWus3tu|o1D1U>=O|NfEwF*7T!%}Z+vvPF`*2Alp1JH4kZJAKPa8; zJ8;;ELo*H`9CqOlz@Z6;AP$X|Eyj6JMgu4Vkf-&hX(4LkahJ>|Z9MLg`PXbb)*SP* zHh#U0pSST?3#@P0cswiS|FZGe0GQuEHH-OU)iA%Q1i#hBZ?NeHZM?AYc*hXvAAbcX znS)6!)(=WXOIvb3&(iV1n4-l;HBk1&v=}J;nG7iDA!}htWgw#knZ!j1l!2jSGM>^v zNeyXnCEV4sJ)^}24$%6s)QB>i9vY6PwS!>Ai0|KMQ2aIT z7yu?ok^2*a>w>Y1?6H5@;U$OMe;J%V%RMFRLuBua$LGiL5wiDl078W98<-&Q{#o{s zy%S^3198|h2C08I)lU-P%!~78;J*dT#c6-`KiX$Y)ZZ$7Vz|z*{;=P0eCDqe8?j9B pPt!qR&%oMu+GEdi)*d29FZcnuDuU0QabpSlD!P!*up+@}{|_;$kUIbX literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_expm1.c b/src/openlibm/src/s_expm1.c new file mode 100644 index 0000000..5798714 --- /dev/null +++ b/src/openlibm/src/s_expm1.c @@ -0,0 +1,221 @@ +/* @(#)s_expm1.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_expm1.c,v 1.12 2011/10/21 06:26:38 das Exp $"); + +/* expm1(x) + * Returns exp(x)-1, the exponential of x minus 1. + * + * Method + * 1. Argument reduction: + * Given x, find r and integer k such that + * + * x = k*ln2 + r, |r| <= 0.5*ln2 ~ 0.34658 + * + * Here a correction term c will be computed to compensate + * the error in r when rounded to a floating-point number. + * + * 2. Approximating expm1(r) by a special rational function on + * the interval [0,0.34658]: + * Since + * r*(exp(r)+1)/(exp(r)-1) = 2+ r^2/6 - r^4/360 + ... + * we define R1(r*r) by + * r*(exp(r)+1)/(exp(r)-1) = 2+ r^2/6 * R1(r*r) + * That is, + * R1(r**2) = 6/r *((exp(r)+1)/(exp(r)-1) - 2/r) + * = 6/r * ( 1 + 2.0*(1/(exp(r)-1) - 1/r)) + * = 1 - r^2/60 + r^4/2520 - r^6/100800 + ... + * We use a special Reme algorithm on [0,0.347] to generate + * a polynomial of degree 5 in r*r to approximate R1. The + * maximum error of this polynomial approximation is bounded + * by 2**-61. In other words, + * R1(z) ~ 1.0 + Q1*z + Q2*z**2 + Q3*z**3 + Q4*z**4 + Q5*z**5 + * where Q1 = -1.6666666666666567384E-2, + * Q2 = 3.9682539681370365873E-4, + * Q3 = -9.9206344733435987357E-6, + * Q4 = 2.5051361420808517002E-7, + * Q5 = -6.2843505682382617102E-9; + * z = r*r, + * with error bounded by + * | 5 | -61 + * | 1.0+Q1*z+...+Q5*z - R1(z) | <= 2 + * | | + * + * expm1(r) = exp(r)-1 is then computed by the following + * specific way which minimize the accumulation rounding error: + * 2 3 + * r r [ 3 - (R1 + R1*r/2) ] + * expm1(r) = r + --- + --- * [--------------------] + * 2 2 [ 6 - r*(3 - R1*r/2) ] + * + * To compensate the error in the argument reduction, we use + * expm1(r+c) = expm1(r) + c + expm1(r)*c + * ~ expm1(r) + c + r*c + * Thus c+r*c will be added in as the correction terms for + * expm1(r+c). Now rearrange the term to avoid optimization + * screw up: + * ( 2 2 ) + * ({ ( r [ R1 - (3 - R1*r/2) ] ) } r ) + * expm1(r+c)~r - ({r*(--- * [--------------------]-c)-c} - --- ) + * ({ ( 2 [ 6 - r*(3 - R1*r/2) ] ) } 2 ) + * ( ) + * + * = r - E + * 3. Scale back to obtain expm1(x): + * From step 1, we have + * expm1(x) = either 2^k*[expm1(r)+1] - 1 + * = or 2^k*[expm1(r) + (1-2^-k)] + * 4. Implementation notes: + * (A). To save one multiplication, we scale the coefficient Qi + * to Qi*2^i, and replace z by (x^2)/2. + * (B). To achieve maximum accuracy, we compute expm1(x) by + * (i) if x < -56*ln2, return -1.0, (raise inexact if x!=inf) + * (ii) if k=0, return r-E + * (iii) if k=-1, return 0.5*(r-E)-0.5 + * (iv) if k=1 if r < -0.25, return 2*((r+0.5)- E) + * else return 1.0+2.0*(r-E); + * (v) if (k<-2||k>56) 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 zcmbuCYiv|S6oAjAEEE*Z77Bu(-5+AMLT|g3+LlnZQnYJA5Yfh6vJpzzYkl;Qc8e`P zC`ccaNZ^l&F^xeIBQY`2gajo)S_-CJ5sD@R@z16qNRgyFk&YtG!6?&%FaqUXom zneWbd+%sp+WLuxx`1}mR04)ZrgVZb~qYtIVrE*vb^I;xXA>7j&>Pm!qZ~3|gyRNLT zZM${f4FK3%(o$VkiX9&UK*_UaN9nFWiEWRx?pnTY$hHyYB(QB(8i2rXPoITZZPKcR zxgHu|=bAKt_Hk@KXwVw(BBBDlE1ciRpoRVm0>cUY&O-lHfvW~A92pS!)PTUqWr2}- z&id#z3;lfpqrC#7R|Q6Y`t=FSDut5u=9M6JzHb1O*!JPI*m2hJC;bElEcB0B=pPj5 zRhGOtDuOYAkt-JZCk1*76iWyUt93MvvhiQ??*&FC1V--&^p>b-FA9u|3XDz)eC?9J zNTPip9v2w>uB*Q{ndt!-4GN6(hkBDfq5`9d{S!8}H5mZ=Ck$-MGyo30WbD6NjGYI7 z;6gn7sR3{bzy|`O{Z+&hGmYoRo4*7_kb&?dhX`%moA9*3`1p6?Hc0hiU zg(E)*4EI}@dl@^|Pv0Y*sj0mhetFWiF>3?uV6>kMlf8WtFcSdVwi`foRGSnSNm}SX zCop=RN@4>*$(P4QgV^~wfZX8r@pz5E@MBJz97kWv5~>{acn!} zs7=evaLIkj%3k`I_VIYSj)L@0*=YdTiQb`1y)Q!o!xvPVsEWhqb-EmXlJyW*{?!*n zdYn1Ei%2%yJ()@v9i!nB_iUS@(2@)~qvV-gYg-CNif^4(zp_37M$e2C-<@1rC02LP0S@=X;m1B@PGy4M+MK1VsqRKLdV zEnqZzjb#tdPCsIRjgbAB@Y}TPYDt^&o)V|cdcdDTQoQo%fg%@|MJB&$ zx;(1Zho)nh16set#pO{24{UbvmC8=Diw6{!#ml5n@i1c~PT_c9yNj2}xd*CU`~}79 zUHnDGsi$$NkQ0x(n^Lk>@$?juvQ2R(uPNE7cwP!gc|-9dE?%ej2QJ>EIMp1N-E!iA zqa4z02>=UNJxtYBP(>+N-oX(zJ?_>O7##b>;&0Mc9VthX1 zn;A#O#~7y?)OO}mASxc7&&7;qu=S5K&hzsQ<2=u;j4xnz-ea8G>1KQ(TYrLa>XkbF z1mo13G{4R`kLNbyeBUP+=kY98J(phd{Nypt^Han)x3ih?#VpQl#`*Vt!T2L={b|Oz zeSPjJPW35{n2jwp@yZ=wHpUyA-)cQ-h`n8D#$(NKFn3nQE5Y2+*a&7r9Zk%t#&{8! zRdqErvD!G8wRQ2BS-zY`5dEhX;$x=ihxUa!Tk8noU=I*a5-_icS&J*l`#`;^S3Vt9b4V>TtLl+FLD zPrZe-~@)+d|p gy(c+J%?AMV{iH?bT?_S=2kF 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 zcmbuCU2GIp6oAjPRH{P$5kuV3NnvSstv_vHcOk{U zE@4aMfmnki#z&$L_{NhpCbG3PwzNnK#z6F;!VBwzp!b2+n2tGj?%h3|pdor5X7Byx zo_l`onRDCT?Ynmr83t%EU<(vx1?hRXFm8~;23QPb5XbkjC%;+ix^C~W8vu|FH4UEG zdZZ&%o;crlzs zft{6pL^g2$zjR&K)#lOsmRT4=^Nw`axh2pR0-YRl{YNzC1O_&#;QelsOS1xqK=%xstTolC-V{}P38eAdOxN(12dtbv)Y0N~{4&~*8!0f2P) z)K=s8%(K|PNWNc&AG~4!3<7{5&>4+m*Nv+)Cx-@UX(dgwln{aTG@2un7lHW`%%2>Z z;{qcW^(!=Q30yxG$J=89*Nq9Zrv%#SB%EJ!Kg_vq99Ly1E)W>Ws(sap2%W>2K8O6K zRg-w)wx@7SU_e%#@D6flIBpg8bLO8A6~8{Aob8$3Mo5M=EYKPD>^q}qju1XJo2H7+ zoRbyY^`}642F>pTIwQja+8=@TBvr+kdsK7ow>j6vRkRBX_5wg9h8X5qy4FKt{0U!$i zz0lm$w7J4;ZrNK|5v;XptYAe=bC0o9C$cd?37GRJz|(SG0<}IKRD8XU*C}4@ zf6< z%6rO{G@MA^AW}$VtkTu`qM$LpJtqDLi5$?!>0YIv1`7L@x_eSG0x*^WSraG z&p3~(n{gi3+l=$LPBYH^UqgpDLlF-|>4^K*Fh)1)I~B8L_^I#X9!I6Vc9?vi`q?;-XTd9COkA zG2hpe`1>Q>H`G`3dM#;69sulD`J``%?C8F(`}I?bt7Un4+<$>7QJ+m-=pLdy|EoUT zXS65PHkXyk{!R{6to(P2()Ztc?MlDOr?36jzs*YDFQ@M_{+9q`ozAOC0Qgwx`~A}S z*FyIg`Qq0fy-$6*FKDU%{HLke0p!n_&Y$|Cwy)3sUbabQl>LBmjCv&f3+LCTJ^g1- dQmX3jh@2Hf=Uof+x_jx*DF2V@g-ZPTe*+dl3+(^^ 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 zcmbW0-AV#M6vzLgmVJR0T?BTqU1d;{N)mKYLYQ8JNFa0*w(6=-ey}@%c9A_okJ5El zLNCxG^a%9?#ppTfGV}rcU^#ov&VT+hb7qIRv(u0eU<8gZ&8EBtirH~FizO_gQHb4- z3bE(+<3=IY8NDEXa&l-T^2PGDmD-nSnX=N!bS9ZfC9TA{Q@0AXq7S1z-k1 zzF0;GVx((qCn%q%rL0jDcjplOWf5PB&OHi@>l^fKnc{Eg`6KxF{BBIxcb~EVU^P(p zJ-kZ8u6nWt9VUCxgy`{+-k`1QDx{~}No?_(a{3CgZYvwI>Uog0ZoBPt6lABX9GNec zcRgj-t|@PJZe`Ey_8eCYAYJFimQJhEaP79^yZxIuo&Bsa!=&e!?wjz>f!HK{mzSr>k#gu5F>r~MHlU^tLb6pQJy)|#7yP~N72i;>+uje&;ugQ{sjP#6o Qek(udTQsoALc-L40cG|}-v9sr literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_fabsf.c b/src/openlibm/src/s_fabsf.c new file mode 100644 index 0000000..eeceee4 --- /dev/null +++ b/src/openlibm/src/s_fabsf.c @@ -0,0 +1,34 @@ +/* s_fabsf.c -- float version of s_fabs.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_fabsf.c,v 1.8 2008/02/22 02:30:35 das Exp $"); + +/* + * fabsf(x) returns the absolute value of x. + */ + +#include + +#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 zcmbW0%SyvQ6o&t4y(_kg3qcogAu8ChEf&Fr6pF@$WFZu~k($<|1?`1o1S@!X1Rupm zDEJaCeFdK&GWDD^45Hu%;mn+w|NJvK$yZRoItBS+I)vVkuuJ0hTHZh8<(09_L=!ucxprhOdWT=Ag*yfS)?iA#et6a!N7(zCCosQR4klmj0r0rC5 zp>mtoG;eipWk2Zky+92h1MkL_Uc2rGZpVw={>>WoV9KcQ-FuAhPh@#OY>+<93Buul z0r#8P0x$#oTfa;Gc`it>{~jj@_UBkie1l0Il9L3iV~zn#o4p6{OdHH|>ANPmAbPQ-fPO_zeIY*e1CfV NCw-qbwpd7*`Y#z_O^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 zcmbV~PfJ2U6vfYIe=J*6vefb{(^8PFwsK@P zUp(-XUA?3FwskK%ZoA{S>H*Sq8n$%mr5o37IzigZYytjl7mOW#-+=xWldMjb*dc$| z&cte8o4_P2MpT}eJo4l9;!9FGfVA1S7fLB^zo=e|#oNLP0 z?`NEMD*p3d`R^M+znC%|bd!W7Iw$9|u9unFngRLBG%iz*OuydO?7b#O`D^57%Hh)3;!lbI 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 zcmbtUQEL-f6#k}G9g{dSS-TKW=sXOPF6-D-rO*dyX|@ful%;GR6g5oSjFnB&l1!x) z*$Or9-G8zFVD&9ne}L#qr6}&352Bd7E>zB)b0)L1#s~di=HC0=@7(X+b1rx1m-(3i zO@lzgRrE$Zk)45DMKlhvAzaU&O~9)B4TPBW92M zyX2qgnps)7t3<7Kkc~DV{$29VME+g!&xCsA-(~;Melqfxv65!UpBSI~^`pSa(Wh3u zU2e65Q-@W@D(ybg_m2W6PoJ8*alO^vymDA|Y??p(bT9knpTh@^6{-Eb*9Wf;UVZov zX$}_w6%?0Zc6xfk&d)9^jo5|D?wDJ!$41Alj1~%`c7Cz4YL~o#CoYVSU=V-}fXX<# zu!I3w2lZim{UVS6b0g!K z*FfhS#HXV#X^ur%=phB*hZwKU3cv(l^<)u#Wc@>C)Oi7%?W1>OeJ+4HGk~A^=+P|u zt9NVe3aG)|X5Fi+u8(qAjeIq%%CH)4MD|LxrtjaQ5aYbhB>!iOKM~Xa-G@KT`=@oN z=Cb}sAD-?YVSqouJa>ebJZ>d;$rs$_b}jIh;WmRt*se*hQK@=vP}vILu6lt7ce&Yw zyRu%ZRq6rU`g%}tXBU<(Gy`wtcOKuVZ@L?e^^Hm+*haWQWv%Qtyjn%J_+6lLQ%WeO zafELvu+8}rNZkZddrM1EEeJVo&oj^R2u~8ef+YPjulcR<1@<2m z1BUot6oMiC(oS%E67NKiK$4yVa58b{2oj&%m*h{d%>Hyg +#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(j=tOty5SrI z4;?%7C)7UpacWsLHxzS2P3}l$(p*u@<>Wzi>^&(4=AH|Ogv8TT z(|Y2oIQtTSxu+}=B0?AISCy>;kGWQtEZsD2?27{@XkcCZw5E$q$$RG$Rz#h$BZCmq?Y7(`VTtA_ zAw)5)B>)eV*gHbVv{Jeu&fLm4EdigGQk{el9xtA*HZCr<08kca-{Y3hu%~RjQ-lq% z^Ly%n?dk#MB0?%a2zfGz+3O!$r{L}Cx+c|od;1$CcZ=LCyQOAV^HrDI?UL&Iv=K@5 z8SFu0YXfL6AOWB)_V)Ip0D?t1K5K#5rEJXA>=f?zL5NfcwPnR6^8#%C9D6pw#eV>G zDZ(E4ol9Xhdk&}UtGx)vPywLwh<`SBcu*e?21D{NGC~EDwBJ0obmNiLb1f3_%Q^M>Tc3xuqk + +#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 zcmbu9&r1|x7{|Zkk5sZ|ld{0TsY9)hue+NPM96~F8id9!hyNy^=^nK9fB?S|~3 zQ~m?p>(;45hg#iB27%?ZAm|hX{n$eo(Zn{k&0Ar#IDs*SEBCrO@#VC}HcD^5y%R6YHj$U$2_0cehIb+;mm#r3H3#{-DO! z%9X;~ni^{*n@67K6_;MgZB^|}qoz(*s(zg)0j1|Jzg@nG%*e=jEuI;l>eG^gA|;Yq zDv=sWB$Ej(K55Kpqq@rn{pb1u=N14O07{e@pF$Iq3hCq>DZK9p%yF2da(fcWa!l#z zY-?Xt0{wA5d%*HfQ2Z8r^>(vqu4fPF^p~w@4^=*gSWh)K((P~j>)SyOfUbu4^;(@7 zbHTD~Q)D5=M$XbBMUNx`Jx4jsvIzi<%ug?1ZV$cRWWcwl8m0aH279Vf>Zun5#iw5# z;S_SNJ`3Tvb|B~F$~G2s;Tp>>#GLNx5VMX0VOz8jS;rlO$XdCak#`~TmTQR2_*B2+ z>e(B-zm{JTi?+3B*lqzqIAeaswDp`(&;Os$|DvAni^K`uHH3X&VsgPy-{}6Ny<~zf z=_)Jsa~?S-$5?-g^$oAN&pSSkBIjRn2JmD4tACR7cgcXvdzQg`hsb%Ba+v)Sp^48Y z-Va3dvVJKu>>s5^8bpYyuK;L^&Ln+1*f3g`ynl(s`FG4TfQi5KzrIKRA9Fz2XX-zF zt7Lwur!>*rM2Yi1(F; +#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 zcmbtVQD|FL82)ZoU4nBr8xw?yxn);b!Cjl8Ohjr!@5~v*BBRB}k!6WPlV&8h+R88q zX(5*~sBeNk_^MAn2(mtCVqv2NrCrfAbj4aGBwH+vFWt(>k^knL##}lX`n{a<|Mz_V z_n-g&IX8PI{8pEuKtjO)+EyF0-R=FLvmL}?JdL%4?x~d4uIN?uJ5%4b%R#%8|D9)n zcrd@gvsXV=N}LyVpU;j@-&Bh~0a#yUGgov^zSevb_?~mlDF|EHV)g@@vvN%f+6%0w z!MqRDsc!`#tox?^REvKAj^ynpD2K{cW#PBR`s#;Ac7DBK>Q(ZYJwMx)USCV-)p^yA z^;HU9*d53w*^DJs*^LtEvX!dcuy=aOY{==GqztQH)jx>BuHTBDz2@W!eKT{{^X9_`fvuNeJCK;s|#$Hc09d=AQlPdR?*pl4Qr<9|+kJJTgL{{o8NjRxQE z$bmieHV!#kXKFie1i;aMoZr*VoR23`sdU1K!Uzxbqh(=Iuqj2l(?gnL&iTe8{N17u z?(OldV<{_UgoZ~?Wvoc_17W{6Hf~%_r!L3R)+ActVwcXx(~)FMr1QT)_o6F5>59~P zv(T=ufKP4&jyrwD-g${{!~ikjcuMGag#D~oUle{hZxYiTMQ%gRsl-cw6Z60F1493( z3@A_(`Z8Y$Y0Gs$@cZNefmy+SSvmw{{&Ecoz8gP0=KbFVaL_%I07`=I&P(PkkrMiD zx$Vc~zyFB--xm#$eWw06Ewk}a4b0Q0liZ)f61qq?%oqVbLmUSx=YY| QvLD|k{@?QbkZ|+=22W;v?f?J) 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 zcmbtWU2GIp6h5=%r)b$Ti##*}q3YF4qYSiSY#Jm*7CR=D5NzW%j=`nf3)TK*cNz;; zp=nEOkjRVS0TX=i!3U#8A4q(myXB{%kwqf5Q53Wi5`y^a+R3<=chncj7;@*yymvHA|jo_uN;m-c&E1*e8_Ddm?I7_mK{B{`oZsaM)NfSBT-f+ z)2U;{YPz14(tOmLH)Iwv{#XyQc1Kyw?j9B`in3LB&}P!GCeb+w1 zm-P@p-?eA(l^-;K@?%~Ej>g%s9#+kJn_0Dcd90OHL_ax}gc zXio@iJSnj8guuol0vpc=jFJ6ufw2+a#uFgDE5_)=hubnz2ME5W>p9){o`t@Jj*R?AE9&o8!c+%9F0=~V<#U9O}p+3TR9r% zI2u0+w9m`P9}Be4_oX zuB)V!3o+3!?Yg8xJQ!uwJHNd=Z57r63=U+c{1eL8;W3Z7N!*VsHiwGhp63UGh4QU!-w0Z_t}QB=TfA2TSP1}&+KN$?f|&KH{reld}RT?ssO*b0AE{xZz#Y&U4Vzw zCf*h|o4~AFyOJLF)1#6e6~No#uxV3Einp}4I0@j%M0Y2&Hq*1EwPVX>XzJ+PmTKA3 z4m^>Jx15-aZ!EyS7T|9Q_&FhYl4((ZAD6nNxb#;@#eI$zd76dm{JbQ2G9w$ceotV1Nq~PZ zz|*g=T0a!vNz;nIot*lY-&3vP?~**dFtENmzz6qxqyYb2fDh(#ue>5N{cn^!?RQQf z?vn-9Q}0pv%hLKVQ`_2{_+~IuPSSsGRik90HEueIZU@ZfxDy9+b1DU9vV%U%rj%0! zW>ZI7TcX_ov%SMfn6>L0mZh9{)3fq>OM92une6CHB%N*GyGv}{#FO#1gpB^bLHi;J zQ4NCd|1(3be<*kzJb*<~FKWHQR@t!VKOTWJNO4pjQ~mEA$xGSf@Wzd;&4ZMC4%ENM z=YO@YkntDfJoF5>U)&a3bjCDMA|P`goMgpy{SK{aS*@%%l$tA0CVNN z3gW7?pP84+TcJb7zfRKtU`Ro1Pzxny+CNj^{JZJW=6 + * 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 zcmbVL&ubGw6#llY{h@(L#e+~KTUap#J0`)P2uh*W>>(5>7HX)p+h(T)o1`RLXhX3C z(?dOZ)RSiq_N=!wz0_OOi}??{shg?vir2Pt+PVhsKZxX zGwNi2-e?r!Mgxlg*}rczTrwQzUw`vE_rAJqxU7&gT(4GLGh9xn7m`NZd+B+cP-lde z^MQ?v{GOF3WzBrci}F0rGe?iip$aoey28kpl1mchLq|V;y(G-n%ECDqk(h6 zYWW#xn|^J?H!%22YxysTv+u(G3p{@xzIlI&>20fba2mkbE`M7ix4=>sqs!o?RSO3n zi>}cCXl^UzSWBQeC)={Ca^={Y4rtPHEYPJ~4sGC+aqo&qqS_8!2h2vqOIYwgBEq5s?L0C@hN z{JG{_qunow8zSL(;o$!hzo*ofelDYGa~ui%MZxF)1MjiQ=XurMa|A_FBKQ&_Z5zXX O;olSdm3CwcD*qS?46w5R literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_fmal.c b/src/openlibm/src/s_fmal.c new file mode 100644 index 0000000..2fe30c6 --- /dev/null +++ b/src/openlibm/src/s_fmal.c @@ -0,0 +1,269 @@ +/*- + * 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_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 zcmbtXZERE58Gf&wmH_F!rm7~UcEgHJ5lq2zBDPsm+Q!9T^HEA6tl=ZXCb3Djo5Zs( zn_-r4WCtxuxAAA95~{jiQ-4&IDs{@V{lGTqhtp0%lQ!M6o9i?!n`#_TY5(zcr}x}* zoQuKzu|1M~&V9~#zu$ANeQxKzT`oxi0STUm)u&bXJ67j?Y}yA3$Z+^C_;4taUx^qh ziPD=!O}SK5c9sjp(}xU|B$sN+rLq#j=e@?;BnJRXHB&$PtK?THz|IC0o%IQ@1pd!4DG- z9y?}BYgbL(dXM}X0Qg|99|;Qe&zgFDgQ?e_F!e;jr)(;)D7pUnAB2Cu$rAFglSl`Q zEb%qck?qQyO8REXCxQc8Zzrby4ITO0Mdh_$ zNdQx~F-OYp!jhe+tsfe_gvD`efM!W&VrqnRT3=I@bSm#0C;q7s;A18zs^#xkem#d}4nxPWU;>Wb8U#rgRpVN~530=@D^b`H#>O3v!^NZK% zLUq2nKr7WUE$by()IUR6y-q9ojcSSBqzlG%^IvB@N@1T1z+5ybt7HfLo3yfY3;UN= zl#Au1Tc)mDEC$L-;kUSI*Qu9S8fj;r_sHvZ+v2e5+q!#}Wg4bVD_DDFE<`$W*S=o+ zMPepIIvYJO+fV$;-20_Z-MRm~x%TQzi1=AMV7N0&)so1`P;j93=ew504wgq>#-!@Y z)$2wVsV=huSB#oT&$_fQF0m~8(P-dV>l}cjM`lCBqx`;{|5OT;wav7mKY^)@U7~7W5l55{!#kOoxA3Y z5p5YNo<0_9nN}X~L?s?P|J73M@*NEPvPa|>i&^{O{ckAM^yha(scHxATNb}3=uP7m zc0MbssBjTEH<_V{~#;P3ACd$$~nk9Z?7jW2Bb z(N=&q0Kf*v<_qsX3@(t0$ccA>#GlvmRCn&e?Ss#*x zEk|8D;3rz}kRD2m$5h`i`1bACj$b|a)eXqP(9l>qF*Y%##Z^e8;+doh>IfUg)X7sP zRT!R3o=K0LnouDTPsPU4@pxu9p46D&#AIqbrm8Rz&uFoP7Ef_umckP}k$6Vd0Ki?# z#-$d#c+E8Lck=^=e7i%>rWX7QE%>~HU+d8GHs@Uc;CApiBv_9E>pkKByAIx|=bsK9 z?*Os?O9ziX5e4r?V_ZMJ2L#{Gc@)E#1)p;4mmU234&Ld{cTgDMAwAnTkAqXsK?jd# zO4yxq@J{`Icks@*EY7308%J^U!*veWJ$=bPjGd5isc2aC9PYHj$^XU4VIN${n$ zls%4$St_o^d|EuCfo~+H#lUwmod#cO5+8iSX>GgnAppMN$?@^{ga*EeNiFUR??1dP zt;L3a#-C43oc1MClgW5WI|H`v_~=j~6&sIpSN + * 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 zcmbW0PiqrF7{;GXt7)||Q3?tby26SZuwxP|iU$caHG7Zyo;=9*3rLSa1+@tE7Mbij*>q8n{w_1~%=^qcGw;mC{QY|gO@l(i zT|}dZ#YEK4_q%ya;4EB=J>PSg8CaWv%O>}&-EM}Z%SQJoaNmC45D#R)2WvBs6Qn(4 zI|bt#+bJ7Ioo=%8Ie9x+yLiZ|yK)_unS1YC&Zb}Xv%EOa4q2-Fz8mV>TLt5*%gp_& zy&l7OAl`iW$fgUxR>Alw?Mi>uk4JHC?v8F2OO>>qy~%SttLHMg*-SQ@(ai;CS+{IK z6EnBcGT|ry9l$97#Zmt@dmIT05mpO(e&*HT3n%H20d?e<9Z& z#gE>fVnznpBhCQ0Fr*K1_*J)Vw|Nb+3C|*tItVUz?W@d zgD?3$c&%BlI}HKeXbOiHOO+X4*tI7#UTLiHme*`Ko>&L>oToN-R;#XO*PUp;CuNH6 z{&Z}C@C_n5H<3~u;tKgklt6q^ofxXlifaJIfD`+#Q~r!vkWl$=D1lJu|H?E$1HFupH&)?pq~{$pk1dkLXXSdMOUbe~AS7pX5GOex=K>cy39H m{EOt5|3TI`?w9MvYcC1N&&aPJdBFL<_ + * 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 zcmbu8!D|yy5XQevtEsl|qU}Mb;0gh^V4q2_C?2Fx+jx*1N&>w|x=nXm&`rwj3#1+z z!QS;R@LurTbE+3_ZZ6`{WALQ((1Kv(ZDx|~QbhE3nK$$1o7uPXUVHh;O3E<67}zq&v8M5``_UJ!Ts4T#O`36UvVb}>zHK#>E!G+l$iW3ebzWn zDfP_V0g(Gk{TjV3o)`0l^w%h$-YdR;d;drgP*S4huL Sc!=IVPyd|~w}zPmlKS7YAc_hA literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_fmaxl.c b/src/openlibm/src/s_fmaxl.c new file mode 100644 index 0000000..48de991 --- /dev/null +++ b/src/openlibm/src/s_fmaxl.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_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 zcmbu8&ubG=5XZlpR+HL7qId{KafKCIu&+t5C?2HH)Z`#RO9Nh{ZqwZsnjaf(9v)9dcEpYqx^lWOZlzJaYf^K@>Lzl<>mYOY%-mh(_?o;T*UNvG`<*(#iIJ` zsQAEEJ1u8o(0#}>fJ-CsK@Vr$&YP8-$ilU(PCC(%&Fl{OTZOXNEfsgIlH7wRSvgZ!+v|48 z%v;p_KZwu_&UyJALW7s_g~-u!Ts4T zj=aH9u5p3~Z+HcO-#dHt)+y0@E_K&Yo>Bj?w*%nuU+SOIzs2)nev>{-fhjsC_vg4u r^Y&J}B>i*JU!WOz^{TFS_KGj0zesw9!UNR)Y5EWyYHN_$$E*JX%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 zcmbW0PiqrF7{;GTt7)||Q3?tbxtuMkoa`L=&fD*s@_`EYU~c(pg0zQx zw~##IyXEA!Rwv&29KYROyLiaw_tZKLPqp7Uf=|BeWqEPH4tb*dzSGxtwhPIx4o~f0 z?RGgvefj3gM?P5qwhPIh%C7ZSy?7L7X6_iNVyTigvNuIeWQ|-VH=W65Ge&C8UN%fi z(!|uQv`RP(zyNRxK(SOo46LOzeJ6~@qjVkP)Us!DVCxAsF%}=$Vd&|XY3?<(|3a-l zj33=U#S9Iy2b=+LA*2s-cnePLaa~lQn*Lc7s(hgm0>ayh)Em+k#ZqO;lUDT!jaTYxqUko8wktOvT>Ggd?9~OwwQ6>--;**y zcYivvK>rOQI5&~d9pVc4hqOR^(wzvp&YEigMt~FhuT%bvUXalFZ)kzg`E@%TdV68c z>3|4Pc@{uCT6+Kq3XJYcoi)rn + * 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 zcmbu8!D|yy5XQevtEsl|qU}Mb;0gh^V4q2_C?2Fx+jx*1N&>xE5-oCKj;76(tVJ#kRZ z{%UvA?eFP_ht2V0vD^_>AgsfW;?`bR_02cqSY*n3r~M$+Kicp0T4;VbQ?vO&yTS^> zP4!+YP@J24WLm{iWy;Lomj#(O3%SBfE}zet)}pg+KD8BXOh1?cFbu#1a0x)MR6z5+E^!uU**h<1XwW@k6u|XZe9*&R zalPj?S5^^PR_HTn^w?sf1Ejy>DSHjlSB<{i%C5d3f1}ovTaEgb(@;B*4d@n;J@{Eseg_O65RhD2MF%Zb|!WQdn zS*Fx8cLzZ3AN5Q0ws>C5SJL00fPPo{JGno{by~8wW|j1-q`yitO6qmp|2+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. + */ + +#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 zcmbu8&ubG=5XZlpR+HL7qId{KafKCIu&+t5C?2HH)Z`#RO9Nh{ZqrR$%#V_Nfm8|+ z^di0VFYxZgW6#n21M!x!1Qa|(1tF(;i@eQDek`Skel9a_-h5}?+j(1CdGyeyX<#%w zz;HFB>Kpn?uDgU8OvA|=fz(052%R*YeWT^%jqq{Z**7}5_r02Y(r&3u{iNwGb3c9U zR`6)e_!>M)7~T30f4$?s_eoxHla%(&w`!!VsstLj;PnLD`f9`JI-lFejl`vld8cy1?!m_L zRcljEnUXf<@6M@fP6E&YoCA4QY`Xf8bDq8^20> zAIP4Csy~Tt@3fqWLH8lk04|Nh2R-cdTw$k}7g@NL73xk3HP(^Q0>a)aNOJ?imgT

<;@Ox*k-Z~|E&!z4<$}{Re_I3a~{!9H+`nPyq%x}_%DKJIn + * 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 zcmbVM&r2Io5T5l%-L}F;X`y1ND@~}Dx=lnW2o^zY7AhXZKrh9vai5kNmFxzz6jxb= zE?#o!y?;WFHm9t)XiuT19<`@XO0l=r%a&Q^CF`T@!4JZl_r3XM=H<<-GdcC7Ns@p= zg2&LPX+MD(`&Pm%_81Fbh*QeeaY1EylLLZaHlGY|F9l?w^PM zTQD5>%9)2>^X>HZJc?#ba2rHyf|% zeoghJ;-`rq2pn%B{$2MDSt4-QXyDkrC4P}k-F*|UK}iOHLTf38DXJA#B)SRdA0*h!Hl01A6}cqYPiaN{1lcC7{{z<10zZSl z`83z7Yyfk1MtEM!9pYb*E3fAP@gIn<*JRDHwd}HCSufd!mW8>@*wCrjwXRg?wt*qLn zmY&WGShkUUMf=5-g0_}lT{H9c255P6+0e|TIhHqa^-EtK-PAKzgb?R53viP+6an8U zieA!3#yvzv&~b?LJpjNNxvU=h0Auog<>2`ra)Q9~^L02fGg0ht2LU2I2>@+EuOQx% zqgWT-HHznyKiX@E@GAsRp92n2k8^@^&)FBVt4r$?qDy fk*LSG;@ctKlYWHs9OD1i@eh3;1zqGqf~fxkYmCxk 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 zcmbu9&ubG=5XZlpR+C^gwG=5-a8HtgeJ1fIJ=8+b?4blH1oc$5$;P7Q2fI&9JeUT& zaB=jKx1GT zBX7j3$mqN>Jg(prPNHljo^8L6QpD;EtlqBK>9s#8rCRMhrM|YFEXDis>TBRzOJ3@1 zr@Otq+4hc7iLDpUW08HO+I`^TjZTyrb*TCGMPn}wKYo^+5+n+ShiO>r*;``M~y~4lsItZF5{7=4Uv- z=sL|E0Q6Tm@J#~v#R=iL^xT>n>xb);EcCbf2S@B*H`IHk{nI}}>+3klgtdvgtl!{4 ir&uRkPd&rCCk9-9hU+yP4mf>8{TvU~3^IMf^}hkqlbk;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 zcmbu9&ubGw6vw}tR$H+(X%Q+^=w6f->@*uHf`=MNH7X&8Vh~Sdn{HaF`N8gpi3c|o zFFh3eFI4ak&|9>Kc=PT>yeN1QPl`D5cHbo1p(^O-u=C!V_ha_G*$pq2E~P9B8VgGp zXal;bft-)TJdR-;we-E-&dco&N~v)7s@necQ-$H3E6$rIKsS{3i|<^0!phwD%3gv?`J z>8>Zyx?Yz!KAUs`@Raoh!>-S-*CNN8yfY1qj?-KRK%e-&I|<-DJDBIv{ns?Pz8Rn4 zLVt_j`px`5alD>0&7b}ey1urPn^~L4b9|c*O5Zp2+>EE3=In`QMtu#N`_TX4pm=?# KPTw=ejQ<5Zg^8O0 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 zcmbu9&ubGw6vw}tR-0mDVi6Q7xQ8gM*f9x;KMrj%(d1BaC+8p#)JPGmSsl-dXiZn92?`5}3RM5|5-h1k3|UFIchT zRjZpz4*QklQO}BB&H;s2xn#7^Jt({%=(C4=i4QX>xysse_m%V|=Gy!!stC{-;6Cu} zt=||DTgYd#_w>blv9zS8Z;Fga>zP#MRw|uN>5CiYj$SY%Z7knj0;U1z08RnO7fXmh zd#7xSMmnF#dD_sPZ9r=#w1v5u=xYtG{SxiHn=;SSuun( zn-XHjkOsuI<3QMTrHHa4??9C6)v8&O5Vg8AMZQ>CcBD~$O8Vp4o@m(hhH1+dymaR7 zrezydliK-j)OV?~J{`*B-C_9WMI=}t7Th^u?9UA8LR=)n8LAT{o$Xi2uFg70FQ^3I zd&XP`+?@X!pQifroRIiPEBDK=&g%-rr`Ulwr1b_H2=1TPJjI8Zc=0FrJ_4YggcEl% z;27?U`)2BtGaR3y2LBfS +#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 zcmbu8!D|yi6vn?vs%=eStMnjL$a=B`Gj2kQ&_fBtnjn%xA<&DYn{<@^dJyWVqQc5--t4AJ5z*h}y?OJ#_h$CZb~YYAj4%cT!#aXh zz*Z#i)1I5g9Ac>Cw8MVR8RQ0Ebm!gisq4C(^8s+yX|FgRXWxoichr8=?K>yEuRmS) zuvn>ZE&kH0pvBW*qZgl9chor_R^Z#IxW^grBWBm3I+@F|N z4so0GQ57IQC?|xPx8e?f8Q`Dwcd5Uj3KFXSJry8Se`QxE-rxmPLWpp91Hg26_7X}A zpG)3#k|&gU;q3r0{!+i?y>IyQQhXx)O$x~WN}f~oS8 +#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 zcmbu8&r2IY6vw|4ZH+b%Z3_xox;>OC=rkKD1;G*sHa(OSgg`IFZsI1EnnZR-&>p%` z@sLwJ_Rr{1Jjkm5K+Zjt9_^()6?)k+?t9to(jQPimwEH{edjx~Z^m1C`Zy&77=cHK zW)TyqC@x%t1!Qmy_3YczZtrdo1m4bPpyO@c+V_=t@+p0^8wA0D@b}KezVChS_Rg}m z3+SGn{21Rm_ZD^Sp_XNfy>9R9NC2HLA5kh67mVprxiVvz4`g1NMn0FH&zWYv0o2Jce|;qDx|BNa9ra^ z*;@*7)lwE@)pa3j?Pk+%Dack^*|Jow%(=>{y{37iwJA58_J-}KZAiynx1_zcQg^JT zP3D(il6r78u|{}z5S^bG<$$I=n{bud~NCW?^pC$hsFG#TeeNGVU&*OaT z4#qi-Phzl+SpqPW>^%UV3X=QMXN~iM{C~MS0KQVuzx2=PZE?St_q5RoO6Yf`_sRa8 r*JVj>jY0aCq#vOkCG~pUWbZW{(%&FGL+L(af6#xR!bZO`B&q)i6XkMe literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_ilogbl.c b/src/openlibm/src/s_ilogbl.c new file mode 100644 index 0000000..d67eea8 --- /dev/null +++ b/src/openlibm/src/s_ilogbl.c @@ -0,0 +1,54 @@ +/* + * 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 "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_ilogbl.c,v 1.2 2008/02/22 02:30:35 das Exp $"); + +#include +#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 zcmbu8&ubGw6vw}tR-0;|@fQ>-xJrr%m@x?!K|~8p&4Q9cZJ-xvH|Zu7^P^-Zka|gq z1YCOQU!$QH69Zx|V*dm^#alfncp90_nU? z!viU818CN3Ggp#;anyhDRx?`f`M0*OBShq5&&{`m5RLrq57FS4W?m;l$Md2AM8$oe z*Vce$FYnel-Bzc5?Lb#;Pwe;kjS#*3zH8D$YH8_?9!{k*5j}p3C0JZf#1ad!cs!rCjm&4Qvg!w41CZ!GN;gJt=`>5+R&b_K&uC}xxkcvUxS;!Ona}C z_z%c_llUrrS28hl8xa6-ek?!qu-Bg!D}`*4zd`;n)sRsBH&udA z{_43vdN1>;z=Jov3}DJTdjMf7^qx!Jb(|;U|I4=nVC^sUYxHlac@3e4vy_;ob1Hw8 smo{E+$xHIzApIGdkykJKdS@@`ll}tf6_g%w?gafT9jY*_9N^Xe1W&x0Y5)KL 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 zcmbW0&ubGw6vw}tR$H~Wv4~VExPoE}cH9juf(I$IH91I-K){Q{Z93Zqo22ZH(0XV+ z_y+{RKf-@NuN%Dd=%3)RM?LAS^3wOR!=N7exy-yD-d2M(S{`!`D`f=oc%>B>#*F^cZ-;c5q|1ck(lqvdd94*2F|I7N_ zQS?-zsIIL&4i>8Q=3)>ntBQ((N?2J5qbLj(8hR_J#fAe*j~1n>NdN(W3jnJ1CQ9&f z@<}fq+m~2yomcN|1Kxhwo1dAQ9(X_*z%7p5;FWx#qa*z~`(}ClA5_OAexCj#?cN); zm-hE`Y7U@My&EgN(@N5~tEKAmGtaYf(K$l;XgGeF37b2tpRk<(J~*}@b1B>hFb$kr z|A6n8IThsohvH!5epy$nf5m2K8y2DyHULaHvqBtmf?F5$YV(rsw`Yy`%}FopWd2q* z6sP}P-b=iKOk^Dgrnxq3R+eS6|N>m$|+?)SU)5B)1H KYFmVitN#OP%X-)V 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 zcmbu9L2DC16vzLYRvS%aqbP_KU3JA4?3jcWQK%N$nmL3VN&{XbY}4Jg*d!&pg;cZ= z^b&f>p&vrOfQNz*?Zsp0r^um)c+y*BcHeWCrFzicWoG^}Z~kv)-fnBD@GPNeU^F~I zI12fh2>bJXcOK(NK^_MBpyfz?uPgP#!BhFDryq3nPu(M@6jO>iaiL8;!-Jn)!8R}o5R>dz;e~#L}q4F5T_u*-4 zMt)}*asj|?X#SZL?3)5`=@eb%qjZLIzealSwg_`|%bV_I%@GxpgPsFl;Ne!Vle$xd zDw9a5U?!&XIvLa17sB1Gde$n0>otOQgL|Ic^dQzO&w^NWU5HA(TD5B)M6K@GB3~>` zyPj2fN#pg}j@WM0x9x_v3(>H*EMaeyorYDl$^1WAV=|BI%|{{ zTY-Y6cg_Km;2 Y!k|s>P&^aAzl(o}?@;_Y2NLo4UtI-=u>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 zcmbu9KWGzi6vw~URvT^PVsR)|$f*%qv_EsDMG%xgTXRFmP#SQNcunsbu}Mnq00O7>g0Ix?%pps&g!5a2*3AxzxUqv<@e{>ONIMGiUNs( zdl<|HObid~Twvyq#29QteZHq38eZ4v^s+y@_Q&IPYuxzk2dK~wjW=C&x8oh`tLa6+ z4#K@|r~*|t#AuLA`&orAHnl1c0oGAUB`Q8)w4_w>h7M`-A8_5;f^+yFP5e?eNM~@U7O9$&S!N!t4%Fi zYnoxYyfAZnI?x;epaD1qAYUwD2+9}o$vshceulT>0*}hmWhh%IWimOMc&h*@0GD{} z29M;+vVECH%3oyrE{}hM`WV3v|D>4VewPEz0k{I?H{CG+<0ts3AM#6N?-$wsh!^_3 zI_1Ys-K>iW%AsW=aLDOKm_U0<4DnAg$AjWThhTueL2oY z-b|FF42ThTF98^h-4!Cmf$_fRzeah;`gE_N{xuCqC^c|o+ xrTzp5l1yBic*pu5IPNT;Q9PgO#?PL}anY-sFX6I%&i^6*6X&n@BSYf(zW~3Cobdnv 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 zcmbVL%}x_h6#k~5fD)$?78o=RiH(rJb*6!sm}p2SwhPl3k|w$^btp4n?6hR&nt%)N z5!kTsMRYsphNX|-lBMq4K@L5qb919E_%`SN@1AoH*Izs@ISvF4o}rKmoR$iH^^#r1 zByJ*ZxCeRT5cuBwMzrNMLd}My#|sz*-~qS>px$hu1Scn* z%;K;-!DCD_bv|yu*(*Df$lFny-mMO*8n7_mHf1o}_@%#L5J|n{} z3)})QW$2|BszrL5l_338SU=beik`CeyR6qwld!8gXb%O0jSarbX@~h~?Z)b{%nqWL zJ{p!@`hd#z6CG|sWjY`*3Yp`zrKg)PF~{*ErV_wsOBTpo3LXL& z2d*5y$o1t;1ycW!C>T;-=!)@IOq`m60f`f=0~oVzg&^^EUo@+UH(cMmHNqcudSyEE zTbUp`{dd`yV1^UQebWD@KBfK)JJLLMZNf_)^oad#@Q&Mju+VPcl#gl MZ@H;$31ryu7sNV#WB>pF 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 zcmbu9&r2IY6vw|4ew>`ox@QmB_6 z`)Bk|=uv3@m>#^;vtW6f_p<2(q0|p7GxO%X_nmn&v!4!6juJ{iPw>$8+qz!mYYKh3aS3+F~;GRUxvk^V~~n-)6G!GAXu9 zLiwlh`*Csxm>Q|aqyfAbvqu^LmH=d9x0vv}*$g_pc0<>}J({F_60}G99v+8K4G1dt zSjhn$4qC>mL5C(7wwKZi{HCXk-#5?=&v?+aFodpmS}nhApxYhe>r$nf4~%3`MiSXLHnTE&RS`PcL$@o33lz)xGv%^^!Y-pvSFTe1EC2ui literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_llroundf.c b/src/openlibm/src/s_llroundf.c new file mode 100644 index 0000000..9b8b8b8 --- /dev/null +++ b/src/openlibm/src/s_llroundf.c @@ -0,0 +1,11 @@ +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_llroundf.c,v 1.2 2005/04/08 00:52:27 das Exp $"); + +#define type float +#define roundit roundf +#define dtype long long +#define DTYPE_MIN LLONG_MIN +#define DTYPE_MAX LLONG_MAX +#define fn llroundf + +#include "s_lround.c" diff --git a/src/openlibm/src/s_llroundf.c.o b/src/openlibm/src/s_llroundf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..7b619c3738d68d870a1822373313d3511e6db270 GIT binary patch literal 1368 zcmbu9O-my|5Qg85U-2s&S78M`%t;iq&4d-fg9y5tD3XJcqv#|V70idsv=F^4=*6Qy z!=K<$&>!Q$i+Ej7YNpD>4ua?dLw8qK)!SX&J^%h}{!J(aL17uKQH$|JtG^O;S1^nr zZnS+$W#&KW1<5kXv0{a;9^I;*8_|)>-X3*-UmJ}b}f}&PbJyX3FYs` z(@W>k()5dQa=!$1N=u#L$mm9U3UpLV8hVgZ-P@D^mS3ctLLH$G@2aRJt zFsFz!_=mgufmic+1>b}ALAC9*(!_TMZ*>!>e(g+fUBq8#@`V^@!vO2Z35$J-?OhVc zY)i*N?wK$PL^;12@3MYI5;CGcF9t^RrCs89n{(U1NSv?%pwGTT04~|VUYFEQD6#&# zI|$(BlkqzroFBbWLe7cKkF-T!?Br%^6Vbm0Kr;K|-!LHxP O2l3bJSd~D=j(-JVrd$00 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 zcmbu7L2DC16vzLQR$Db)R}m~Uggq>>1v~BrMd?8bT}=?lp^&4LO|rGnO;UEJkV-+J z7sZPo!JB>qJqmjC;L)7Cdhp_1h)njqWF6a!{$O@y-n{?3+4tVldk^oIga9LO7qi`r zjZ$GfS#DqnWi*a|ERU7z>G56LM@Me;;=9nTKKoqWc@esmQQ}s<9l7=>ajT7&p=&pe zKY1Tf-`rexyn3^>>I64sO$JWQuif&4z<0c@xa%|`MF(rQSAlr|4uCTN>dh8P5FfOS z5wz#GU!eo>WD89Jw24`r0b`(tY^D+Gh=IP(sLd!0FxS-`g3GAc~1JP#sQh9TslSng&dQqXO5}= E4Sg+Zh5!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 zcmbuBYitx%6oAk40aPBR)@mBTbVJZ=i5+$dl~QS^QlM)j4U$xMlM&pO9U7$%y9>7b zuvXb>`OzBjRTHB>{NWFc#@|MFw}9o5h7wFDCeosi7A0G5VgzD3=G?irdpiL`!b#@N zop0_r_nya`-QI0Gw&!RXNYS7cvQJt0t{^+F@zl*?hJ_E42^%xN_DwksLb;O*(0A*zFBSm~{Y~q}=sfAZF@RZf;9M|u z)fX&ab`aZ7F)VzXv>95b7>1|lN}R+*RO1$tHtM5z)6bOG)zE{nDrwrH936C=jmy7iO$uM+{p>>6!HO0_6CgW;j z<_|@WB5;ghSd?JscZSw^hSoSkD@}FJ(7H&8o++Ah99~Hzvp>1hog?C2@7^a(_daVL z+}u-{*>tT2U~+DYe${N^az(s{x~;ovFBRQLo1dTPK3nkVi1}OY>5ukq|JnSud+@R2 zubnZ&M^}Ha=Gk**-tCWvhleN3qf)=2zP{S$Z)j{P^BEiT3f=Hk1S%>6h7s`jcSZO5 zf|0m*QNFPZAP)e1RPzAP(AWeype2dPUZRO-*+z<82S7Wt3$*S+ZRN7XOWxCf^Ht(q zQ?8i&kC6R5xRDK+BDwRsXJsj$^0u=;3I$)XfCBJRgnaIsDvyfwB`O4fQo;QmzDDqX zhnETN?w=K1aJScHWxe3REaI|B@SPs+7D7IRJbas2|FVZaCwQxeKQDNvhrcLzw}-zZ zc$J4Y13;0Im-!sW_U!N2XLRZka?!tA2KcLvzqHy{qr2Q8ZzD(iG3a8&bxxQWDD-?c6 z;i&L_g;UK-JMSy}L52UI@FImzD_o7|O@*uR_laIYuhsPdg)dmINMdbPA zy;kUZ`*;a84FFiD=#t3u%X@>uRA~_UUXglIsNYhZE~rTW2nv1gx#YQ}P(LG^Uj6QS z)PLnJ`7aSa>@v@ke?oG9$?vo`$yZ|kN#QW{o`>$BPd2@|CwW)YpZ9mm8$aqTchV1t M^Y?ITS@G)s2YNA@5&!@I 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 zcmbtVT}&KR6h1>)TeR)L`U9~THc`w#WXkX(Eh)!ed*tGSf#cEoNY0OQOG{!OK&b{nqENap(**kZ> zx#$1fv&nt!`wKJ;Bs2&>{w)uGQGOrf+aPR*Z4kv%Q>f20FFdvsNWL_Y8C`Z9Cpmi0 zagr@~`U(J`;iL0-c0vQd)R+dqu$XgEygSRVJ3SpWuzZ|rZFZbw63UUuUIz46EiCT4{#XHdj+$X?Ty*Tk zW?Jx_d2Z1S5A{Wcp==aSWl_IAk#Sv4<#6%}PlA07^%;itCDgBp_`0vV5ltG7<9rS< z0u$eiWwgrl=mG$=Ow2^Fe<8hEaOWwxTO)=0~`6Xpv!ehOJSz8CvxF zo?%ERdf@#MLo1ug4ee!UFEg~~J@HCAiwx}y>RE=?QYtsJkD(g_mcPvF`m4+h!>SdA z)>jOzYEjo;7=~6D+CMS0Z!)wm$~;B!?kz=bnW1%&p(Q#i^dm!iiJ{GHQ(rK&uTn|x z=zlp5DTk3S0f5?~ohnEjy7)&)Xlre4^6PCKU6p>b-l#Q9e{D@|Lyc+H`1Q_6um6>BLVT!htmMX^5CHttlK{}x z(FFydO%W&Wv?ku=b$;9x1MTfj&`uU>JGXA$a$W<@mx*srZxWk-0qHM<-`tQr*tBLn zkF9*mr@%TqDtPi)#gqKS2gNE006PWm>dS+2Kv|ISN$|pf4@xB=P{p4<*dhsmU4nP@ zKcVo{9g_b@;U7}?s|vqa;cqKE)l}*!6&Hc*s`}qoc)A<% z{C5hk+P$>_|GUCJtmr8sgCY-)D14d1Qx8kKy28_+kL2qWe!Id46&@A7UE%5ONIfBi zr#mP4@eTOT6kg5el)|sezrw5MR~248FYgz97Drqd@!`Hi_%ImpM9h62mAhEvc-Tlp zPA0(U4JX229FE7qhz-z-(GyS9gV8h4*B9wefYCpYh!|}hUDfeKxaSS=ex!fM7>o@J zMq-I!aMeYQ9*oAqeGy^(fkAOmOHl8qaOVN!@1wx|<{RA)d0yg>P$>I^dW!7G`6cJu zbAtDd@B>~#K(y}~XkL*{@A3aDZwmW6)-<{}BoyxT@N(|UXF$k%=i`S$-kr~RNdM)t zO~`w3$s3S>l#_TJfcNRTo&D8-FwGvSkyoB{-Y-?F;;*|`1}fmqAI+Bg$$u;i4NJid +#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 zcmbtUK~EDw6#lk=6h)>I4j7E=1p|#8TLO`oNJy%7V+b)Mjo~8MmMugnCEX!{2aDmv z#d!25_%Ce111F>Zz@sK6U@vkoS@X7Uwsi=J(JyJ=%=g~=-rISzTf0C1AZA(6urQ1E zu8rZY_IfT{&S3zTQF6q~184uU)A(lZAB_b;Q0qHTOLv3dxc2rUfzYAomlQq$c)QzYw$B{6yrXq*m_KNWN_Ek<`KvniJ9hhh}Y-uL*|P)dv+ zHANznb@o2Qo8n31Fl-FK$@|voQ5Lyu_KrQCTgXq?nJGCbGxlV9ayp&Kr0wxVZ^d?8 z#g5eN37{K*4S;lW3wgv~)rr$*V)4F@OAWELUM#}ePFN%Tz412|LjD^2UXzWffkb{F z&eR!@em8yuXB+^!qUvp243|AH1qJgasL#O;ov3BIJBFLw{)y zfs$MB0VFvm7WN1H3R>7=p3dw-2mh)go_so<&YD0v^ot<(YA zZ(BjGxXOhr_&#K{LK|81)eK~@QZ9QN3UZ^OJega_r+noWpYeWmV@qyUE1O + +#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 zcmbu9&ubGw6vw}twl-qz#-dcH;EEt^v11Y{LJy@-G(kdA8 zdh*tze}eu2iZ_$igMWu75uwUnN)cAx?t960OA+(~$;^D`{g|0Iv#q;@dkIa0pkWrh zQG~u;e=g|GVHoF8(Odko&6yH z)+Yc3v`HI+IBoQ{KKL2cskaO&Z3lBE++{C@oMPfP&l>t^q9 zF6a&f>y46PJ=VOTUb9zA6;*~R%xCB?jX*)gEIAdizQ&zIuukB& zAM%8CI=eFwy&AEnIkBfRCnyg6x+tevbIlTz@Qt8b2O+Fq52_EHlh_LeA5xwLx(}2`F4$$(Z?GPDo&oQ9K91aT;U>rYSN{y> zACZ8}M{Z@k0_~NMc9#9qtP5@K+!BG2^-G&$|2PM6fe}C95rDz?odocc4dUyH@5ko+ z$L=(JV>r>@{GXjt|0)NRI#d1Wn +#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 zcmbu9&r2IY6vw|4ZIiaqrauk=J?yC%&@mfY3ON+P))|!6Lse6Ve zHr|#v?IHjNzykoaMhh9JDcNK#ipP)G|0TETTN7$rP%HUt?w3MrU*)+M)V^OX>@Mfn zG7sfn#Krae46tyco{|Ufe8wJY09XQ0NZnGR_8=S`1wGwG(n+Rhp9JlZzN_m5ssTae zo+&w?qsh>C9q7n}N!yoR=np(?{IP-VdB%h8L=kj%G#vVYfeuE-*R@7#BQjq1D~}I? zBYhZ-4*k$fkYw=t?JuD>^mzsU2knDu`_M|0+#TH1O|WaX!gUdUVaykz$cD$PBPT5O zS8QL9K<1-#EaaXE>p-0IzVR;Wmn9)1`kP{4L|@t}$J_j{4UEJIdjPWb9Rl!^9qe^U z{e%wd|8oZcoZd11(=F#mZuK_TQN5GT#ozBP8f5JXH;xp^Z UyA|yEJ-a3TgdGPG$k_3J0pdzpPXGV_ literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_lroundf.c b/src/openlibm/src/s_lroundf.c new file mode 100644 index 0000000..f526eef --- /dev/null +++ b/src/openlibm/src/s_lroundf.c @@ -0,0 +1,11 @@ +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_lroundf.c,v 1.2 2005/04/08 00:52:27 das Exp $"); + +#define type float +#define roundit roundf +#define dtype long +#define DTYPE_MIN LONG_MIN +#define DTYPE_MAX LONG_MAX +#define fn lroundf + +#include "s_lround.c" diff --git a/src/openlibm/src/s_lroundf.c.o b/src/openlibm/src/s_lroundf.c.o new file mode 100644 index 0000000000000000000000000000000000000000..086235f9a4d14e4f9827f123e06eea0f40eda788 GIT binary patch literal 1368 zcmbu9O-my|5Qg85UvbrJTonX8%t;iqHxrZv4*F76N7!pONGcj$#WyruBOr(sU%xEq5R!= zeD0h9x?a^|h5-C}V~;cdqyVI2x0rCR7Bo*9m8vd-do)S=BxsNH{eNylH6Won@r(yu3Pb2}vtIWb2D;HSzRnejbD{CdM?5}goap1A zdF%(~6zvTD;a)ZH>OQaFd(b|pw!K!G_T9m2-2}UK6I>VZ7g~HF#@XxJ_KE?Jf z31oJpVqciI_G{|Wo-h<(-{<9NZY Q-|z?VSL|4mK*o-L0Snw)AOHXW literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_lroundl.c b/src/openlibm/src/s_lroundl.c new file mode 100644 index 0000000..eb8997c --- /dev/null +++ b/src/openlibm/src/s_lroundl.c @@ -0,0 +1,11 @@ +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_lroundl.c,v 1.1 2005/04/08 01:24:08 das Exp $"); + +#define type long double +#define roundit roundl +#define dtype long +#define DTYPE_MIN LONG_MIN +#define DTYPE_MAX LONG_MAX +#define fn lroundl + +#include "s_lround.c" diff --git a/src/openlibm/src/s_lroundl.c.o b/src/openlibm/src/s_lroundl.c.o new file mode 100644 index 0000000000000000000000000000000000000000..16c9c3c5e1484f76f585f5e0b1dac74fa3cdedf3 GIT binary patch literal 1408 zcmbu8L2J}d5Xb-7R$Fx&qbL-*EI9;8!9J74qVynzMt2d}Lt&3nvb$*u&F+@u6}F|I z(2L^5kKj$efgS}tdhqC;yn68BU08X^OcNjNMSt)%FZ1R<^D;C0?BSC~6~h2y-~o!a zg7r#ipKaH%fGS!iKNqLcan<^v?2}`se)WCe)SrK;Zodqi+9Y;r-;W(@51DlS+@PVq9J^{;Wbu0-}h{HGwR!|P}0H5y=7n)fDPaRfM&ac3XG4+ z#u)U@cfUag#?dB>v1Ke(=jLATN{X^yIeLbavT8bG9n0~vN9Qkmq> zUEU>8910nYB}6}zAw)M#A$p_1AR0=D;YdcJ+3u{QGVJZq`_Aw{>?foBD3OQABSgDf z+etWx=m!6X`VLjwi&~g`#;8Xn^x7>^UD%&_LxZqLhRc+Pd(8G*WS?OnG3Jd1&lhtW z$YTDh-lzN?2P8QE9X1f0pPy@_*LkZO2-Y!=0nF($1mGPx==b9KFBD(%;k$$b8DRbM#-yG5Zsj H(Di=+Cv|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 zcmbW0&ubGw6vw}tM%!p%TJ<1Q$o5c7!H!965ps}1t(k-5PzZRiw%c~M1x-@2TWA&f zgIeew1pf~4;IYRp1x-B#dg#?#1=0SvBvD~yl9}u}_yhX6yqUM}z3;m3Jg7s)~If`yvhQ-M0d**&;?g?{i%&QMG?^qx3JAqf*+E3r#Y+PN-Z0(cn zHvo2gpWvYGdi{;q>C%fc(i>rJeE`5Z^FHYoBgKkE65gIg;xC&jn~giGeLQZXfhe$4 zwaD@Q8F^Cqa!BI$xyaWazQ5!9zJKs}>%@6mt1|CMw@9MWf5KuPc*#TNX3ogtkIl*? zzRnBRs?CtPl&vy15{kjb5kC}<5#>DQX7-RB8_Vd4Y%V{jr-o^oru1|&J(5hNl6qpo zoYR@%hz~<|2f0oZfDYgSfNU<02((@9lmA!~`&jd~z%^mD=M&JDd$hjp&aT&5%YQ?B z`zGwa;Ps<8_5T#p(N+(*1mH@@-`23F3Z*%V&VrlPT{wIkLL&iCd!^tQGoZFpZrKI7 za?E81bk1-L&>7nXoh=m#X3+sHmK>92bNM0LF=n5N{d{qWE|yD+X4zQ*Et}5_YA#G! zWussQ=RGfd;@@9X3bbY#!Mz1Nav|s!`5n?Bpt7L~s{1B@F5ukxw}gID(UJPM6~EM% zb|f@=VJ2mOg6bXz(5dzwz_bWd&&BT=W>V + +#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 zcmbu8!D|yi6vn?ztEsjyt%wR0x&_58m@x?!!Gi>9jRy%*2;`vDZL-^f?xyT+AyqI! z?ZKOWjfkftda0+Ve}Wf1N)B2tk=cE3cU_8t{w_1~&HLWl$D8f0-no_2G%y-&AUP%6 z%_aLvxUFCY)3C+U-ivo z3S;nAEL0$5PZ+}|pOqeI&%>j?x zT-S|it-hp}uFA43>E&X1xmYR{bz{wH>9@^*E(+I{qCO@8=m3rZsMhMpLF*}vd)MfE zg4#Y!tM+&eT4z?9pUF?X)DY_D=`QNv&9_%=Q&Y9g+lFb&{TN{?&!>rT66+p>vp zWrylXp~jUO86f>#Conf4{lJUXE#3uICxC33feE?c`;g7H<5+G0>9zw)R%`WwADGRD zbl!A#vHN1rWvIVDcHxX0?21)58wv{WWP)Gn&v*$|LyGn zFsRVq{EhH^Bc2yCB>y=Q)PJSElk2mt!m_m$4e~!A|4Eur*01trXRmlo{yFk9B*&=x Pqx@eea5IjK$ohW)ekgm- 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 zcmbtU&r4KM6#m|5Ig&LN{Q`q|!7CK>HX}vU!jZI`MYxa=m-f^*NzFL&<_T(%f(c0k z?%VVq)T$I(jJRmgX24Yp)YR%>Ev$_$f*1F_b7rQSBT*j=_nvdlcg}aux$_oo-o6#m zG%z&uplVey+fd#2`rBR{!%>tnM!59Qa3gQ}jhzeL0?_3pfTg|YLTb4XdGZ!O@~LBl z*P{SBHr71P^R~*#l^@BCZGE?RzSz7oWBXYWk=Omk_vEuvGJU~qS}JSFjdEkDGqjl& zk?3Q;>e61%qc$1-p-@VEav!{x`Wa7a=IhY^BSkUpN7MmCS@B#F@GhoH^2YHck| z;Z+U3{~Vp2Ve$cxA&vO%?HAHesb0kqUz1cBKx$?*)c6^#08Z58sc6cNW^)tij2Oqf zW#`}<08&H@`MQ9g@?CkJ=Z_Tl!_W0)y!=%l@^e|o9D~R^cCb$J&bBh9aI9GeV#0Jx zh_QSg!p;T8crKf@rW}Z=oMVZB!QrmFV~*b^`|i|?n6`7%mhH?T$Yf29rfoB8RZ9O4 zNqK*2-@r*TUPK+GE9Dy*|XKB4i_4%DKM(VsJ)!j)s|CJx7 z`oGN*z#S^Y^Jb{_HRAI<8H>cf#0~=M=k*5hRlMW?1*&@pK$H3w0lcC>RTuZ4aj(w( z%YVt2uTXwB)cL#AP@c1#fAc=`mu1x6OSF=6m4vp?w~F<1UYS#!y~GRRpC&#-?ceb_ Md`{{xk)ZN_0gWQsi~s-t literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_nan.c b/src/openlibm/src/s_nan.c new file mode 100644 index 0000000..dd1c5af --- /dev/null +++ b/src/openlibm/src/s_nan.c @@ -0,0 +1,124 @@ +/*- + * 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/src/s_nan.c,v 1.2 2007/12/18 23:46:32 das Exp $ + */ + +//VBS +//#include +#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 zcmbtUQEMDk6#izDZ8mi?vn_%P6?PvMNx+UfF(NG@*<`l4$`Yh@Yf;N~vY9ntb~5Zv zG?CU+rV2w{=wsjf2R@1q5;u)l)2FsUUu}w%Y6_xA2)1P9OwP@Qk-X>!%f0i>_nmXk zId^BNSUMF`6i6s|72T&U7J9q;(QrG80VGj4QwaVli{M95{mIyRQ>@&NiQw@=Qe3`- z{QME^tD+)W<(Pl(=U2`N&HOEVC$8p&wp_%Pc}huXSH1-BHKnc9bS-lwj9=3-CLpxs zGjWJuMfh!H%RH;3<{uSS^n_f;^?hEet8=01S z+u!N`@SF7qn|E67+WLddTQzyAcg`2yUDYx$)_$GubUN3B|0pejzn5bGMC)QM5tjE! zDVGGcm;TgJW-cN8@6xMU<}#Hf^;9hBlcD~qnM;yt0BA4OG^f3aiShB1*};j)@=(?o z(T8;-JDeYWDQ_70?BHp8Ix8%XUmSmV2%zy~0mK1JOqLOY(k4#MQsL+Ru(!a|yec1^ zhO&@SjwSmN*A(D+0MGKf4y|Kq>hqYXra$X>P0jkfvHOSBbU{sxsR{Ebj#Fa&5Ur+~ zomLZJ{AuO~nSWbNF!OKFIeYO(m@Fb+2=tN{pD z;`7XhH4vH=$8z*4DwSr{a_9kdyWX@tR4P?((X}g6mD#x}9LuQzc!p0vv!LIT&Mscu z$J5Ltf0Xl)wr3wdb^uQ^C(!+)pTrxy+2h$i6X9ij(3^{O&zgeX^cuVCjNCQsSxfiq z1rPePO7ys=m+9?>Y0j+n96hhPQ~_2=+{+*0Acf zJmUWX)lDTGibUD{HUa0jUJ2PJ3Azu|W2u+8Kurg5fr-PMN8a2t^UpEQ@;zLSq+)UaZ?H+h|;eE=!@Jr!VfHro=f&mVv6(czq5pG z_Af{wBkDhY!2H_WP{BT$A9H8C%9U;%8&VGq#|Bf8s OPtc_VFe{CWsQ(|aTLp;# 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 zcmbtUL2DC16#h1?Hfrpq;z6n4B0*bd#w1h>JxHL{EGjt^bCkMCCQWIxDZ8UIB6#Ro z@DB+70)In6j~;sUA9(O$dlf3P``+$4CKvr+nK$2j@4cD#X7=sFr;l=$1%`zONM|V; zGZ{NF8@P-D+`}Jr_uZRP@x)%(DCNKFr4zfz=C@v{Xn%TET5%7*)IZxdQ~jyd7b5+s z*2m_bdNkM9*PNwhtG(=0S4B-!om!=KuTrg6oTW|Kb6ii+Lizr3w5wSF4uEq2nyof+ zu#PmxXR>I1fsS*PM(gz^tb?MpSeVPdw-E6+XsxWrjrqo4J|FR`6ZmP+d1vwSY|{En zva1v}fGZh3$_?N;fMP03aBB*GhvHO7$#H5^^a!_n=>?tfj;}-)iH*M8mP-1s5bXFW z<@?dRpX^E3Sbx9HVk}Z#&FNk+AK#r=o7F$b=;tze-Aj!eeT+I8%=0-R!tqdf9f(i` z@i<^Bkb9m`@<2iKJmo=j!Vsc68V;qeApDV%qS +#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 zcmbVL(MwZN82{aA>Pk2oLYjg%P@0gpO_Eqp7;3x0un>g#5H|H*h1!(uj;0Trx-HsE z`O<3-Jw?#};0$8*5G#n@Lf=v=bq{U&(2aBNId|it5&q!b^PTTIzwdXx^PQ6%_TO>{ z0yqTRKxJ0JQccAkFw6lo;tW)oB-Yj2B$1c1U;Wv4a&A|YbHBuFIlJGj>w0o|lm4&k z`fiduegU8t*h@MKB=ZBn@_`xnN$o8f8FJ=G<`V#wNV&y2l70_>X3Oa0Nu20+Y1}&8rEMAd}=Zd6x$jCd?RW?W+vGb;i zk=ZIrds8FEnAJJ7U9+-yz*|b3OMMr%Bwg2OJm$RVEs&K?UDs3VLh4XR6|mJ} z1efSWGrvjp@Q<#0OXOLRj(P3l&KGsHNCIoLRIJd?p-|<|A|SN<>?L6j2@qC1rL(jRZrArFLSpvtHEMGMH}^m2+Td;s(P7#; + +#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 zcmbtTL2DC16#h1?ZPdV|q99aggor8FF$or_s3bHoJ%k8_Kzoq7O?O++BsG~}(nFJ= zIph%VA9$_5!GlQziMgeqKfr^Ro@8$&xH8FXb{$kizr(zF-@f<0-S^&BfeD{^?CB%$ixZl9JpAh(Jm$G zUjWoz^c9`t`XtaX$Y#eNb20zWAl{gN$V1(w8H0F}{vio;-s@x`29Q9{AR9eSjQqyO z^4-=mvlUfV2IS#~W|!BkRqLnxWCNY#di7J&tfKnXAe(Kc!pR%5fW~pfvodH!74o|K z@|eAAMNO;5Nf(LL)jPgGB9&hBg>KO>4f(>s@NzH|3i<-;+Kz8cW#Ylo?Zr_yrUCc> zoB@zXrQw3o=A6|_Mfhh$8!rm09IQhrdzE?5toxOM5r0KI`y}k2!0S)roB6AlsfoG` zFMtaUexgy_%4ub$>P#!>Gy~fi=kjmk;A`Mm1%MVSS*C7-7Fl6z_pBS!$_#WzWh&@) zu?U*UXR}(4f#&i|qlr{{smRpK6XEaXN_4-F-`5JP0$R|Xs#M$C(hF)<6XO4Yc`=I_ zsm6GhVfR6R_sNN?B7e$B0=Q%iSb|Jn2jB+&Isb;x4@x?g{!NLu^ewyW*hME|R)7SV zjsuvLXAfXa1j_HlztxFHLjR}T0Z{(S{Eg9`V=^xb0a5U>Ao%~q-_z2!crGJra~ui% m$0Glnn30^%>&mm|aEqdRznl +#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) ^ (xyAHsZ^WnEJrA`2p)?8zH<=3aLlGsN#@&N=sd=R5bDyPLe<@t{hQ zARyr`%3c|Nj+E_I$81FnPNEnlK5Z&UYRv|kERGSo7$$+@82N7Ap-DM?N&>X09-?e5 znOh%Nq+S9e1sL(`#^^EYdCC6iFWGY4I4fKDN%bU}w5Lu>_CcUX8J1^G- znI3D;=ZJ1PEM^B<<<}pXFTc*U-uf)3Ujdk0ieJ<+U$oqYvXx^s<@5@G>@%8L12FF2 z%yf|Di62s?huH4*-vTfvXXSL9Qp#G$Yf~M>r)3tj+z%zS&Z_tqonH?`RTmiQj0_|GP}w-li07_wLIP*|3cu%L!?ONZJYi$NV29vU(t z7SzbFWvFePy;ozFKJb+LPa<)3Bsx4|M6DN4qefU)jln)Mst+0E`yCeS{%n@VJO$kU z2JFm9fX%TI7dT(+S0K1+7-fieA#e$R4>&ac3fFHE1v!NNH4)$t`r><|;;mL9cEJAc z132#8J%9w~d;4N{t;A!l@0ELVK>j1=cYvLJ2_*PJ0zBa7eF}XMXLImsGuS+s;QSMO gM_xXw>)ky=7Z0-iRzl2O;PgKHY0iHl5;?s5zlf|$tN;K2 literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_nexttoward.c b/src/openlibm/src/s_nexttoward.c new file mode 100644 index 0000000..8729c8f --- /dev/null +++ b/src/openlibm/src/s_nexttoward.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. + * ==================================================== + */ + +#include "cdefs-compat.h" +//__FBSDID("$FreeBSD: src/lib/msun/src/s_nexttoward.c,v 1.3 2011/02/10 07:38:13 das Exp $"); + +/* + * We assume that a long double has a 15-bit exponent. On systems + * where long double is the same as double, nexttoward() is an alias + * for nextafter(), so we don't use this routine. + */ + +#include +#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 zcmbVLPe>F|9R5a4chh)lcnA!3f{9khX;+dWC>9*sIf#KEZBW>%GYYx8vOASZw8^@M z)r*H9=+e1k5D}erlxn?go)lZ!Zkh+zB`{ADZ}!dZFld1v%)Ix$dEfhff8M0}2W~fT z94v6Sh5D+FaASQQG^atdp%q(Gf=iXj^A$P!P1bk#Y<}yRuzk@mjMPoT*h@V*(+!kU z?gGht0w6C*g6E*1zBN*0VHrS$v`a#Po>HXa&RnxLRovWl6*pDll>n9Ot*J!R$>M7O zB=ZtLaf5u2g#Fxhi(c}|dWo0Qc}|r{ET7OKq#q1%#%fGPBQOJ zM~@_wR*CloO{2I`ye||glq;+fFXSanaLL)StZ(yX7Va`xxN8_jJ<#uxP_T)rancMj zYuS8|y!rZLzqk=3uf7DYA82>dJ6vX+NP7Agm(}Ng(qhaX(zhnf9~uThs^h4rv+HJJ z?t+;YHCZsLp4Pea3P&V;_nldv3JK>{5$fx^!TUmk!(Dvfs@Nk2_#S^xuRjp*^S&Wv zoR=dS`_O%@%RHwE01x04fY9JD8o=c!XZ4sE6&(7{G-ZV23rhwE%>aV>LI{yh7Z zvBduX-O_}8tTsA_3$6bEzaHp_`^0j +#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 zcmbVLUq}=|9R5~K&p$A0LE;zQY!?t|pZ#+);E+hP%Zusbu~{J!~qGryU1|G@1! zNrHfcTd0j{kn3yxK&2Z%8(LwJ_MmF61XXi$TJ-$I@}1yC;iY%G_EH-M#evb4aMBKZ_l_p;xca$DZTf)pk3 zEa@y*WVB$B_5pRrBJzN`L$m^U^$q}8dJDiJa!}pL6EDImRP}_H_rtkeC9}M znR79ynx(s{S&23C#LMhZF8;xxvYWNnVf$bsx9k17S1ty~o6n0`DRBJ@>CY{%WwzP& zGKcI>yI6XeL)%UxeYTRBX_3)&XQufm@dkN@rbR}wd4&4d7I{yd+%Da8K(3u(ZfeOyR=)xCyx0H+;%)gv_)H)bhKJkpbqs5Sw|h^g7$80z>} zg_fF&QGFa*iYAZRDbb_GEQJ=)sSa&Cm4Y^rh{cRJg%(dxLkkTKcc-X6@qmvf;}5l& zWMalh(m7~JV_MgYsj+BMj~P|B6QhIIqS3X&(VIc-95`gr;kd~4j^|dv8{LAr9exMGzdqU$niByXeFR5#WNG?g!B1u04Q{JkXsN+p81zxIeo;PHg?B zex!2GQLUH2Dqrv%Cz^Sl!e8*r#_i1@bMijdx9}Rd^=w^t?HOjc{sPwvxX+KhyW{ll LxqeazIo$f+h4$9q literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_remquo.c b/src/openlibm/src/s_remquo.c new file mode 100644 index 0000000..afc325d --- /dev/null +++ b/src/openlibm/src/s_remquo.c @@ -0,0 +1,159 @@ +/* @(#)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_remquo.c,v 1.2 2008/03/30 20:47:26 das Exp $"); + +#include +#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 zcmbtUO=}ZD7=AXbwyV*Jt%9JC?V+WDu1Tzj9wckESwt#Si#-%-Y&U);Dai`z!M3!5 zixm6?{s}L7GHaklJ-9Uo^=7@8C_>Do28$!JnMvYerQid}%=^wf@8|40bLz~HPm&-Y z;W(O76Ytxa`>4B(Vmr1Wp_98yx>ePz@4Ed(u^i2EtatX0otj+=_R3pqw z=G?uP_4#TXiot|dn#J7 zrpdN$e^&IxP0UjD1PS5N=4AGuosxnkL?A7tBd z<~{+Kwaflq;1``+0XiYuRz_Et(&kDL79z>$4mb%X+dl_WMi3Lm5#(}_1Baarb` zcJfuaGXm*WK-%N)=zJ)_)$iqJ4+QxiU{~7ly)}sj+8W-Q*y6_IHqJ$$d4#qWy#PD! zYO&LZDLaw5nljZ%oWF4Pa0E?Ki3`*<#1J*yc5)3aX#YW8;0j9-G9 zH8b_~ir8h08*$Y%ZkbT0;$|G`rEC^zCS4aM)5)ZfGNGo@rlH1$M-ODp_~dmiUryar zr!(nkBV*o1-I8%-B9VzFjfU(00n3M_y4ho-{_Ue#KaSS=Gwk7Y6ZZvn^EndYimlvF zCzp5gwU6st#*T~E>%1kedOz4#$lk)A*eE~D{r}NR01kKL&DSd*<$RH+z(>wMC=?tb zezBh5d@qPMAP-+)1VD%PEdmH|zBevWe}QZ3S^wEA5&ngq s)!}ccPIKi$9;lzsDlebe^!DBbSMCyta)`PM>{y3?k@MXl(E>03H@d75umAu6 literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_rintf.c b/src/openlibm/src/s_rintf.c new file mode 100644 index 0000000..60cdb46 --- /dev/null +++ b/src/openlibm/src/s_rintf.c @@ -0,0 +1,53 @@ +/* s_rintf.c -- float version of s_rint.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_rintf.c,v 1.12 2008/02/22 02:30:35 das Exp $"); + +#include +#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 zcmbtU&ubG=5dOBQHpS>h5i7Ki1yNeC&m>j+0ZK4v3QCkBjmaN!fjY#zRxB zf;|ZRYdmj~OTkP07d+`jlpO3qh`il-yXhlA(C@M{^X8kGH#7U1x9;8^(==T>Z?<>3t^Fzeqr3gJxxIg?IkWS*^)2zvZJhbl?)Ur6`a-A7^u$|_ zb$ts!{d-Seayxn=gT)VrguSQ7WAA(VQmdywZgup8w7>oWVC%qXS>JTeinx>AvR-vN zL0xwMd_pdpy=Khj^2IqLb&;i6%19^Emy)Se(wHq+tHz?q>0tiy954>R03fQ!<%<}D z<_eqafkyfyr8!Ao?NtHVMqHbYO+>QikR_rRv$+57zK=&E?4oA^!hc{j0Om9* z+*|>3xb1(}q-0w!O~$Pa4z_A?6KutC!0ei@lxmfVRpnsS8n;+3Uz~TiS$aYG(`ucq z+qHGe<_-9fthME`ZB{I*-n}DicCBD3;M3;mM(m;^)%kNF%s~Gx& z4Dl@hm{50dz)`JBt^fIm`zNWuzwyNuivLEP{}pPeoU@p}cuQn{X%}hK-U~dT{JWk8 j#OSS3`68w|dx0OspCY~lnFEOTVi^BE6~zNjA1eP3OG=mn literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_rintl.c b/src/openlibm/src/s_rintl.c new file mode 100644 index 0000000..d20768e --- /dev/null +++ b/src/openlibm/src/s_rintl.c @@ -0,0 +1,116 @@ +/*- + * 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_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 zcmbVN&rcIU6nnMh_-f+FePcU9!8xVj@2R z#&FWR7yk@BS-=DFq(^VY69*5to-`&kZ}+`+*w71K(w&)a-uK@8_;$N?CqEt2G+<~j z4y}=bj#hsn=uUuu1Xww-TDL@MKeuzBZ|`pWXfzsY8-D=~*TmLq0LX3r?0;FWjryW@ zYA}9)QePzVgK?$dI zk-UtPt)PedmKgcgN`nGQwS|%32O+7Qy<9XCON{c}q`aX9`2Qab0Gl zp=Z*W8)?Hx>#13@tmldzO$?6?L2yhu0N^IFGX;o&R>z~`Gu3E(mI|DwR(n1RS}my! z^mNAGXaJWW{2@Nz!%XPUx)SlJ?pQVvC($v$IvwzHmU zh-u@0;<0>PPkKq#xrzLR4RC + +#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 zcmbVNO-~a+7=E^(RH&Uo)R3UDF^wrkrXPYP9uNas4h=CRjT}g7DZ4_XE!ka?qA`-7 z(W3`{07sAh0|7k{PkPgT;K4-AUQICX?mOFIQ!YG7cjkTO{g`>@+3kya<@+(ifP#TZ zbgT}ty`A}#Kb?X=60_UChCMMjlS%v}))T36Ch=-lyxaz0iQl^-cVHJqc28Rt*{_~h z{N{<&S&9+4FLvA$3#Z7K-TplMNnEBx=l#X(o+k#&nS^+_uch!r>Jr!U-8`{yAaXxC zdBns0AXRqH9|3#>w(bDfqQDTP>FL|)Y-z4Cnl6mXqAa9~`Qk*rP{^mV^X77Tw&wD} z*sW23+K>i7n=Q>%5QDKxoa&ju_8Bg4jz{C^JdAeA7)kWS-x@#$z(rnrPvcB79edE9 zjL!_jO8v?B-GNdv&gr5ezb~U9XP|{_}KTXcz%7q~-Vb z4&Vxal;)=(kKy4|?bb$f*^+h0@^pb7MS9#oz@u7Sb*$Cqs%u)X)>JnuAKuS=RD zkU#xGNN2O*)|Mb0*AB)NHM7mNnsm*!3%Oi#YmiHh18KL&kafo$*NwtW$a<^MFqTTulB1zXC=*5qveig>r!(c*KLj5%7ZL%~`PEqA_$YG9A%ZAP5~BC@h_-1z>=@lwv>(s8 zel-3O$47M$jc*^LpErD=N++bB{x15VGSS+E9j>qRNB?M~aaCXCrT>Gdb_i`wI^kO# UaM}>`o$eOD!{qDGGe9){KbmghCjbBd literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_roundl.c b/src/openlibm/src/s_roundl.c new file mode 100644 index 0000000..dbcd651 --- /dev/null +++ b/src/openlibm/src/s_roundl.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_roundl.c,v 1.2 2005/12/02 13:45:06 bde Exp $"); + +#include + +#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 zcmbu9&rj4q6vw{>lvSXq#KR_d=wV|Pe~h~XV`2#5m+ZzMCM4kM!L=+!(C(JBB>^v* zY`pVl_+JQ-gWf!Dvq3pxLQFX6!36WBZ+1(wT=bJPGw=0%-Dvc$vt617g@$po ztu|}j?fHb9PC&;1iuL2vX^=_Nb432~WU1+7jQ6{N2!DoOnkNULccWN8HkxA@8PIex z=F{hmAK?WG|9*1N@Or|dZ+pf1e(KZCL4(v3A0EaPrDu)3q#`_&8cOpKh3V=0X0|ZD zIBe!e#fZq8Be{{gxqLonW*6)gvuFkU;`Y5^pa*~nfEH1hUqlzQUGk}K*VtB{eN}!l zpuJguwqD_+`)CtgSer0x>t8 zM`WQ~UiVkmYwLmSVAXM5&x!I3a6alOt?JKdgoybs#{ASrq6?5cSMe{{PkG|;HTEat zX-^6A)6+uu+tt8YhVTO~8rRg!vmHwW_ErF~Vg(k&vhPE9E*YZY2cr-bw_3Gp0YuFW zY*CnByzK{8i$Jy~#5P;5P>(*QNTeaJl}OGYufig-R-rN$Ovn zv;SW?q1tEK|4Y1Agz{6FWNqRd*Z&|b$o~-aT-8^4%9-4IBFjl{vR;wwAN|KV>5o{y Jt%OWc{};yc$|(Q< 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 zcmbu9L2DC16vzLYR$H~DRTK*KuotBTGtGvoSW1c1nnfgsLLe6@o9)(un@!mrq4lDd z9(wCHXg`DpkGc5~>_@0aPl^bUxBFf)3<(AOL6|rHd2imlH#_;b_4;MWaUeL@z;HIC zH8Henxmm+3X5fe4PJa2%e(O1}=O6dy&U!yDt^xRT^7T8pUA3M&p}x7f<}TG6&1KhH zRaND=)k^ho#q%oe(ss1#`hn(!^3&x!`y>Dt0OhJTnkd2PktR4ims;-fg7aY;&f&bX zI5RbU>HzZq?(-V$N03%wTQrJ)!5Zbf3d%c)AN^5&6N6I?nFVmi&?WCZK93EZnf%31 z#s_2k%j{p=UC}q<$ryiRJ6RaS?Kn{(*eXUI;$)BKJjO}PLTvPu?u34S`UUG;2x-?1 z{kfq}8@kk00`i}*%7*CT=Ucke3zZ#pbkK&%bXtu2Vx>_WC>o4i*CY4;#X^%064qWzt{H0VTf#Q%cop>K$KWFqx!nc|2$ zT;#rsztEzF(Ys{fCg-7^6AL^(WZii7Imf(iBkxRj1mt`EYrMz#A8@xIc=Oc)35S$IeaE lxX=sEdke_#$d13ky3GP_x?wHY{kuIT{*vSAKf=V0{|kf~ld%8* 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 zcmbu8-)a+45XQfgRui?dwFn9=WR-v|nByk2C|+oxt;vPtq7d*#!Y19M#r!F|r_hSj z8y}#LAb8^w^m=m zwLD@!)kH`=PuWlZfROtkYDIg!VSCT$4q9TTRyQ^Kq!T^0Gt*M6CdW?wlD}^GMGqYv z4UFH0j!c-WyJDH(&_M6_#)oc45p-uX7z9HDJsg=p*BZ@oWcnV?J0fO%ne_s@r#!ep|B8$1O(PR*{U67! BY0m%v 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 zcmbu5&q~8U5XQg6`lo`29t6QlJlTR>lVA}%NTJm9AUz0$-Xu*!70DmEE7+5-;-mOD zUVQ*jww+1B+JfNkGCSYwH?uph{o5PcvcOolMwyk2D`Iykcd?H;5cGOiPBR#eT8?)i zeBn91>vvqwbDid0Jaq=4qC)$!1=IjI0JZ@H!x3y)?^OwsphNrz$X>ID2QpOLWqf!5K)#SajGEFOvNG?j@nX% z(G%sf^jYNdERW}EQ4IeF$H4NBJ4TPy?tf$M>xBH}CRY5_e+pm^*yu0zN|^Z>&3E|% z!Sl~qAo%?pJLEUXOo3n@(+98%z-EESDVp!nf32eXnO@BsT^dl-K7Eh`wDR U^+Sq``ToWR{}&m?Y$Qzo4-F4J9smFU 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 zcmbu9OKTHR6vxk`)uvc8vAQT!$P}uy(q1#6wW72Qw3=Cj3c;caVVI^jrnGr5b88=n zt;8KazbxQK_$3q?_r)Ke^qc0^n^~~+cm6qgtr?_?WX}1;cJKws(cD8*pH#2iX z8OqJg4=d^z$q-e^q%-4bRZS~H1-htc2Ez|VCx*ctivj?=UT$t4Vj$UkRAPn_+TB>- z0-n-l0i^Y$)Zfz;-<1F^g7@OQ;ct% z-hkfi0RR#JkZe`Z6`EbcM@W zMzLmj^}IXh&6{`s%kd~-KYZq=1OBH0e^o2!NaOU*lD*-zyRduu%B>3R|4h7@rn#ND||( z3I`(k7pI2tVWx#3MA&^F!2Nx+-AMq*qA=W-n7^Qo^~3RXjK3~~NH~5uV*h1ah}bjV yKmYF%@xsr`gllv5u)erIJy<6k&vS-%&naWlo37OY)B2o?h~LJfo4(Q`9RC}M>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 zcmbuCYiv|S6vxkPDXkRu+(jS|Bwe(S1>xGQEg-SGG;HY_8-$v=dvUcc?OscukL+IM z5uT|8D={I&4}L(?FB-m>K*Cqdt|BEZh>wzp39(u+G#bEBLj}T`Gk0e1aDl|c|A%?} z?m6=~b9ScP+tjkQMAJY@gD|)~SI4Kh?bW=w8W4Q&k`==}x!Az%SpI5YVWCji8|(i) z&~SUfLDVQ&F*Ltns6XnAnY_->9ATIgeQGDv_OON5 zzh!8CE$oKfbeac7oP5!uX!rff;;OSHy|Y?(7og71mEq2JRu3%`6T2TxRF*JuQ3^M8rGc;K-7Ex!hm&rl~%fjFphUOX8gvmU& zZp7pyL-Q;{y^PP=h{=B#nx8XFI)JwmYCCUX@Vs+I+%E4fou*0*Dbw9yXx?Itn8@*U zMCCN{#G*7rRL<3i<_&Qu7Z{o%iISHXnm;g1US^p1kzsP&?(Ux~v112vcAbTBu{QrA zhW^rtBXhy_|r#`y2ApB|T(S0xOITAiRYh>=Ab}PJXLw@$w z{L7J+HqytD-FHvK$L9})FQ)Qy2el=UPbPK0-@iYy>*9rtt1ew>`0eOZ@BVsaWB7S) z|D~9xD4t7P&1=@I3IvW>Wo?=6sWDKt*;4%Y68L5bY~!zvc-pGD;5Jx0e}Di zP;{EtwLuAJIb!mT&_w?cG1W{_Ydc#(+pcT#rk7V7)&S}N;BoP7VJQGK`t<&iHeXHY z6WTPN-sr1nu8cd4SY_!>!I~Xcd(fSLbRvZ;S@g_C*k3%1b^MbojbZr)UKL@eauB% zF9^Qg!#4=t<>7JOpX#9iuL8gfCI0-Z0iYA$zSwhR+q0W{I(oB42N*4DYN-fOQA5Qu zRMb&XPsMU7R!|Xg4EgtGIpFpo?i%7Ap?YvehW7T&>2!KUeO-Gd-QC`|xwjVJIkEB* z0HAcdQ*abjIOVzIGA?9KzXi!RNB;T%#Q?Bq26izuO?T;y(eoK;{R5(4sl8-8! zek79rqHxN2$tM*~7ntNz#1EO)?^C$0a8!7;!s)jp$Jrt{#q2SK?@;X3IPX`u8s`Cp zt8vaLT#fTZg{yJCsc<#U6|_+RzF#%YGZn7JxlZ9~+@cCsDcBhyPAqa$mtR6C*NV083$cc*)7FnW6Jw9&k-ZCTb%b!-v+H+tSQ z`ZB$J>5RPtoWavw?N%n$ofd2PAENzHYItuh=e~sEeI@06FX;ZKe3kZ6lVZR*BCd3n zG>?2&lWefefMq%f9L&kCHF7uHsSA86&=b0B>ki)h3KBRC%5Tu9O3U>m)y71ZZW^tf4%UR z?}U`spWcNB<&Q4@zmj=E`9nzhOHTXo&P^H=^N)!Q(_KYp?DeNR&zn1>eIkFi@t!Mh T{OGQDkbh9D|Dfy2<@Ns;8^YsA literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_sincosf.c b/src/openlibm/src/s_sincosf.c new file mode 100644 index 0000000..62caaac --- /dev/null +++ b/src/openlibm/src/s_sincosf.c @@ -0,0 +1,172 @@ +/* s_sincosf.c -- float version of s_sincos.c + * + * ==================================================== + * 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 + * 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 + +//#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 zcmcJTYiwLc701uoS;uKopLJSNR|UF}(z2n+;&q)TINl~WSs5{#!Q{y^&n~3;< zccCd1?BFD>1yqsRidI5`F9;AtNEKg@D&Zt9xON+C)2eYO&7&yEB0%Zvmpr@Z%$?c$ z_jU6H#QAXN&hO5gIj@-=yT4`Y=88~=tb}L-`8{8b*81;B{hB1E8cMtTz2m9jo5Pd$ zl}e@l)Zjm(MXsG+}bg-cFoP@{tQ6&$oU)Qq(@R$$0I(H|6M`s)z=f{rTc{)B6)kl00;sl~O-?dRbj+IKQm=lF4FzS)JmDnHgy^ zbfvU|XDeNfom3q8gzjDmrGAiKR;}1Msn|K@a%{?^$1W_Xo>APUrz>vL^AtPRT#lVr zI^E7FIC@TT#-u-UQE_HeQpktgN}|Cl6@2J5iTMa0zP(an?wpi5^_FnNxA&CxH8Z2Q z^{+*)-A#qihoutV>*ejtzkZwKp_f8l-hLGl9iFK!$0SduAfA(oozuq5afq#$J)zin z*Q+p_=UHPWY=}gM@3vHAdA#IMs;$b8wyux26lYBMG7{2pQ_;Gbd6)jAi@I?C%~Hv3 zi^J3X)%IO++oV-03VbJ=bFw8RSJrV8yiu?CWZQV#IIzvcDE#)9^478oc}mNc<6tR@ z3D~oesem_C1?Ps&lWeF-eVllSDZF@Hb3Z6^jvLuf|BoZ*u3N;yZfv`8=NvhHlBx>d z*XAe7_7}#kX@6XfU2u7qu5~kBvDAc(mZ)tzsW>yGyb~}jS+6Q2X2+wj@#Y+TplGIO z3XXRjQ=ZQE6lWxT)4Xd+4py(0PHVH0v+UAeK$%p1(5fYcpIs}Jhz>rs=w_*O<_~f% z5M6HGxITPtXZq*O`?ml4?8fJ=ZurzE`O?tHSDRnC-aQslpTA0*_NgX3XKS} zzo{Y9Utm_d)3l*)@1W3uNa&tL^Q(`Bh#HCLgHix%sVrOPi!M$IQ^ZGF7VD=zL}tldhF8y`)`u|F1^7}k zUSfrEzwU%7hLDIJFuXp%y?&V12KXv79uqCH-td%eeeuSH>1#gHvROYR0kdVR?uKdm zY)m^0&jh&F57XWNe@yqQ=EQjq5iN$i=o%oR{X}!dYRR?d_H}pmOdx1IxRBOEpoTJ-!s6` z--Y6+J}XF{O*Rg98!ipnxfD3YVL5PIcP((VKLZ^7-3uJ;>;;bgJ_8)%|2%Mvf29~r zUfs%>XZ^hcINJFDa9np2aP;?K;AsD&z%iar0LM7wfXl13a|k&4`(xnf?<>G-K+h;} z20jT~ehcin?*hm8+yIX8xl@cYamM&Wfn$8?fs0DJZVPaEwfrl<(cj&`G0t7UG0p?P zF+M*5E`JK!bzcUK_47O6X#cCg<<;sr3momg0UYhGmO&<-Xnzzq=4AzN%u6G1%**G1 zV_v+!AH4m7@!1dKF+Kyp_G&Tz)Nf600fR+0)gP z?aouYyCBHBx38x++n0ZeJmuNF?QUO3SJv3_KZy7zN4s&q zEcPB`?-5pl_q%({*>A^NNl9@K(Jzf+$&IWdH6~*3cXEFdZjOPn90?j^#QY4EWrflC z-_B2%^}TzlFVC3udwrzE+Hczpx0tUtnYr7e*!bC2?uFu0@SYl#O-e+c!O3PUwrOA} z51aWx3C2%KNQTa;Z6exk<_GPvep~sjSwA>`z|0TccZ2f}+@gLin*iB5k@}I6vhyt$ ze}Zd^Oq%tt7>DJoz2hV1%h?vJ9g#8lKm>o-c@m7DoLwI^zuNr&bI8oI5}f}ZDsD;3 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 zcmbu9O=}ZT6o%hPtBu$WQ4|C1VuUJFv|}=DX{}&e8%@+wq$MawiPLm!Vv|gm8Ko8c zfIy);e}jKO7cQzO6m+5B4^Z5=5ZZ+saj6oyGv`dg)o%2G;okG!Ip^GubMJ%mGZ$it z0!G1Ew5%389j*Rk(4B;e9^`Wyzvgor-*b(x@uuIei*HAaf4YaJ-#;e4&_0uEywR^O zyl%z8*2ib>U;OxRf92|Cpz04tFAaB%etx_&9@z1|@h3ye%g?vnSAqR>{bl3ryK1WN zWdhmh>2XcZ&gKWS^sr$XY0XTTBdK&crRj6_l9sc48W>&Ufi00VNja_tj1+QEyI$p&nqF#2)!jNBaxK}ENJu}kG zNJ~drT4?3k9pPSaxK}EJB8#>{lQ~SSsF`j6Kbs-P+H`R?tn>cGfZ&TTytS%tEyD18 zH*8DXbM1;{`1Yy~W6AO@7>k|dT)S=5U8iol z{u;tacBydFwW?xg{~xg)QLB5UP~lsE=o}fYH>NkJb433$I=w4gKl>>U*B#gAanjqK zp#YZyN$@>pPEsxZtACpEi}P$}l?>hohUd?mCVyTh6Fz*vDHaHxKey+|UuIht2=-&< z0CdT<2q1Wyfj{OY&;Qmg>rYamE1Zas{Y4duyCd(@H98PJXL0`f+TI=3MH+eU1trc; lt+<;a2Ipsg5mP>U!6pS2>uZO?MI6}0zfM8@=+6+@|2LPRvZw$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 zcmbVOO>7%Q6#ncqt(z84h^i`85p_jD4yqU1O`3vmYbl`#$V8|R8mdT^>#Q3S|3uym zNuk6@k%>5fdO%3MAjFje+$wG^?V*TEiQoVipj;YJq}I6vfmrlr-^7zCzVwqaKi|Bc zd2io5r~X3bbTANrLI5Yx-nDUgS9_h7%QOVSD2U~6KDhOy=Xv$i&*H^Xi~CcaSATZ# z!iG57Y%~|L*9+p%C@{Wqw?Fm$tM8;2V;kaJGxhs-`_p1|89-xAeDo=RmYD7)!{aMA z`qyb8^-@13Zl~WGAft8h{wDx7#B`HnuFG>W#?tSRk~IFypI@fM>bGqCie~(dG<;S% z`r~VH2rbe32yukFRe3E%JdhnJ3oSLMy#fd4>;Let=TUS( ze{A%%zYp(D^W60318QdeuTyJ>kJT^z)aQR;OBr#|utwbal zPY%TsiFhP>#-53c=UhIB4G#c207L*#GRGz+5k#O#oT|A1?{~AqeLM%=K7+tgZ{XnG zU7^bXU=YA#eD*mhm%@=Zd%~fY_M8icUJpltnVxVcvnMzsr;;3v7`A~-?7)4_)^>Dl z-L8!ux$Ks)=n%|DbrRq>b{Z^jfaOER$>YqMc!K$UoovV_we_{k1DoUBu<6s$a~%*Y@O$7vX%Awff&hGR4&X&45HBb%MGYZbec%~zcn zZR->(a$B@*dw6ItTeHjA`C>I$ke356!HXb(E&%^{KEBX+sx!rZ#XNC)HU6q5Pc^FK zZ)iMyMaAFJcxsV~zpL^3eeN@F`rXvzb-!VL7$hIo>_4sX`u!8kQyz3XqZ+U0;f)S< zN}4>?riyDxCc>{8Bh?Ijo1OwP^0I`25JYE{};dB;7WZxY90<*VhgU2$Pm zs;+H~O-#ldHwb$>OV z?4TdvxK;fqsQjrp!}_M5H0wX36d5XhHB&!TYaP{X#oC4`OC>~o$P}Mv!n~J?Tj5>y zZ|Z->#4AdWVd^h+sGoaWkg86oeyC3=jWX}r# 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 zcmbtXZ){Ul6hE&UZ1ShCpyCpiQIo6L3_QDT$RtCGd%A)P!69)`l5T7*8+7Z^Rt2-L zk#4ZDAWbv|6Jx|gKbhzUgJ3kaV;}59VvI5G(e~L56X}NG&j&@3J#+56w|jeR#>8K; zcklhZ^XJ}k&ONW|f2QeKn;-y(08hc(Y7VED&CNY@>H!Ccu-hBE)|>vA3;=+dNcRz^ zcvdD=BNt-1{$ZI^iJ!})GBH!4CIXM>{o-Js01()Mvma~#StYBagT$F#f+l~yDIO0B z$a+WLCBpzPqKsTdy`xilKk7Z?5s#gq7Ro&0U~9qF+cp5Tk5rsn;{gbW*AoHpdW!Ap z=roe)KH>_D$fOQ8RFMu6*TBUUNR+DyHAu?SySAOP0l-xZL{=uAtW3OWQc0?bbUn#TsVQwLFq9UDYiQVFxuV!@n>hHJ01&%f zBo2<#i69QWBLH|~*Bt43qDM&?{!yFW*tm11D4tclvGLxQFNo^~X%-JawSIsr6a)v; zQAN$o{1}LPM+a$cy~(T2EoUx^De?H5v$`JO`WSU1d&YC*CmLWa$)eAroJkqc%#3N% zmMD%E6E%@piQCbp&9=0pl2XT%$#gyOjy93fqmx(#RhMG3YmU5@Rk#w0nAOzplqv0s zHm-iFOlXq}7?@DUVt;KpQlC}Tq~SM{w-~shO`!p80^_bGl&N$*QByN3<5_j4R9xqQ zY&xr^*As18%jZM0y3XUFP15)(H!cLkbus`8gOa0p#Ke4!nO`V7`F*pxzF6wiT)tse z*W>?cLCxhW=w3W4Y=iv5orm*V!Gq(UTfxKR zJY3)70~mM?8XFomJ1ZM^?x}KC*Gg`w+Ua(=H@d2;UCzp8e}~iC7G*CsY^nk%1^_1j z;MHr~xd&_@B#`4hNnq>c>ghLKt?TV7pxB$=x0Ojo6S&YRtyCY_k?E^y5 zTY^0maFb_X9*PR5oCCI90hT}=qe|I`=SJRT;VT$lY2k5=@)%nLx8r7fnT4-syu-pj z%XqHO$6bu);5?#;W^+DXqRXZ8NdWLsri9jk86AwbqKgts=lMhQFrM$9Bf@xoUXC*W zu-X)VS~CD}2;d$Yh!czOrx)QN;)`_k1f_Q9>Up)dE9CC%;8)GM*h5f-cDe6BI1*xMg z+6L0TNCc#C$XFPo)E;ka|KJ5i_ z{o&|gFnstseSvUWx1Vk4{{YX4rDp9g#&1_B+;0wRpIFOc&E+{9tg+=-9phcVDerf@ zuRO|lmWBd;w-OA@Tme|;XwxeGU-he*|9LqEfZNQV^;~@a98WU+)tq3cV};7=h=c3% z(fCeaPo0kzrqAU#c>VKnH}lWGZyc>m;Bihc@c8j@FVnZ;6n9_&*WR@jAo$!~VhbIlqu^L<{|&2Ef5KhP@MW lWYtGE*4jgKVo(6!BV#DQ8b9oH3+b1#|0CZhXd1BU{{wxI&?W!? literal 0 HcmV?d00001 diff --git a/src/openlibm/src/s_tan.c b/src/openlibm/src/s_tan.c new file mode 100644 index 0000000..2b234a2 --- /dev/null +++ b/src/openlibm/src/s_tan.c @@ -0,0 +1,83 @@ +/* @(#)s_tan.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_tan.c,v 1.13 2011/02/10 07:37:50 das Exp $"); + +/* tan(x) + * Return tangent function of x. + * + * kernel function: + * __kernel_tan ... tangent 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 +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 zcmbu9UuzRV6vfY`(N?Y9Sc?Q&$QG)!(2hxHDHPHMi)N7$q!{RfW!bb7Q`-Dtv$d_D zd5Avv)-NQkL=eA4-fW>z&8x!7?B3bbtwGS=%gmgad(Z6L*=aspdlXR=NE9riH|o)e z^!iz^o5f8Gqok{^9sT2pcGq>?X6DD_>B_3=}Nl88baw?LQn3{OwWz}0}asA!b6EWzjv9+n8t{RI@dCL{2)rrh}_U81~ zr+6E=)zu|!I+riZXsLOYW+^S5OfMu;siZc&&bKw)v}s~)amLFZ1)u@A0w9+!AOgh^ zn*3&k#@D>nz!`q&qAF(>s0eROfg0FTpfTljw-fU1Z&uq-JxtZ>@F{~^9Z)b461jsFiI zsEZ_An{lu12-ZttbSOFr*U3j-pg8IGNFR`a#CzEZA@8wd7VvWZYkZ3QlQJP8{qIYG zkp8k=qWCapVS$iwlE(lB!*>Y4H(C(hmpng7k^FzVgW?S!qrb&(_Nm_nC6sj%^%LIG wU+Tgp>@9dg{>QY@8{Ru`IbOU&;o1p06z{)kJxC6?)hE7Ao7xLj`h??u0be +#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 zcmbtWOK%fb6#m9wFfC+4gpgAZaRgL}luT`tG@+7Vq@*|?6d~G(D5~TR$(X0@$R02$ z2v-d(SRiH1iUs@f3mTUoSg>e{!~%p=)NVku3lcVcNK>7ebDYbytV-pRd>`LEuY1oq zBiBAZdMIKT5EwXswcQ%-M%UJMu(Z*JEy$Z!@7-A5>-&B!^UOSau)00t`?dYm>Z;jS zzh1vkTFRSUqd?~8FD~2F)T%jE&;0giyIsw%nC)B0(DlbxW3pZ`Cx2Y@ecyjYCuWz8 z%#+lwcGU^=e);43clDM<@AU(->sk=iA_Y&($_v1@JIEeR;e))IzpNl*n z4ChUCp6$oo`)XI7cGP*cL%x&GJ8fh~Mm|gQWXC6Z6R80!ZKV?FWO^`}N+lCL$K9F4 znB(z5|4=Wm9zX&Br7Jr=fe4H`agtMm_nX4-u#IQqo8vGpwHrG&Z;UM%A-|K)J|gAF z+qQ(;7GtUjB(ffF{H6l{>l)tI@IkPQLN{nKuOo~ziXQEtljZ5oDs}~%DB>y!U^nya z8Xww?Vp!w*Sw5-pX#gF{y@EFaFa$K&CLC(PqmuKSV&0mDb#x>}Lz0F;8U|?CM?;#1 zAsRjfi6fUg=a!4^c~YLC?HSi~hXx07Ww(%k{Ubg58qiyo|E$#bpj_(XrjbEePn{#5aTHCrytx@B(;p*i<-E?;&EZo~h3g6>66 zM>$jxe$&yYV}af$JAyt(LtgM=UAP+NynM)hq`##PKW3iA8<=7}9Xj0y1UCP#ev18f zXpX*SNAeB=iC<>wClb}a2e(=O6H#PH{4!@*U&l`(ph2fk070L +#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 zcmbVNPiPcZ82`oAYgj_;S=}pPSfCq~QbcT~AHL^Q)xWQ2lpl zV>pTiN0zQ=ZZ|_!-}cmC9A@dkGg5`>N}OlB@Kmgc3Gqp(JpV)WBUIP6k^pHQFD@)T zWH0qKo+Md?s=n^2;(wB5sIG65ga0o^QABYCFE9Lg8>^o`J$HwhwO&PFpt&`mtnQ?R^R@;*JSHf0hVi-&F;HTaL1&l~(F01j#S#AgOj z1m4jS20HNYZv@WVtUUvJVyr}u)AT6Q;}kuHK>P5VX&-KDp;1l}N$(oK9ssYS1mnpz zOnyq^>HUh{*Lb=`;qPg@?*A9&$p_Vh=zr7nbnC+ZuIcGr3ICU-->dNtG+xhhTl1sG zeXQ}i|6R?G?*Em>>*t~#Ake+hFNN(dHv(rGwjVT;aaLwc_j|_<+*SblrV}`@r+puG zbDkFVj31oW7v;0CXXYCXcP@ZEHy^lmWwJKl2hPlQyuLMe+g@nSFSyNM8Hsau_J-GV z8g81+dxOqLy=8WUd{Cr*1!leX#eIoXFPNoE1aOHz82dSn^q2J0apqZ`;!CzOVbb({ zA)oJSPi;d!4;g`~97x{3K=PMyq=Wqe+ne_#YZ)ilz9az{ciDbW2nN&XSYvw=e~Zw7 zNmB_?AG}rD0RCa2nU|bf@FT}J?VqrHRfG)FzSW_A{-q`d(mJ8~p*|LSsUHes#wHY* n%yJ&|Pfxa{J$*CG+98yfJQc6nV0S4FcCg>({C`T72~7Jp + +#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 zcmbVNOHUI~6#k}wR>0m$G(OPKg_>euXc5Incu5qEgcwW}0?`aG6{7`gM<^s(5<|q5 z{sdR9U7EOoxY4e3N5T(K<4R}a!eq?3bMEvqu^YdnbMN`)yzZHEZcCSkuS5(33I=*n zkt#^mRrdXI+Yf;lZf3>P4==V(c%E14@w`%L@t7;(2S`IC%dWWdac#S};)=1dNN!Gi zc-7;1Vqo#GE8=@eXKj1=tGF$<6C$}O-OB$7iTnbt(Q%j`7MiOy8#nN&KRN+d_^nZ#Ag;TP@Qtw1e+ z1OPg~&`1Um7#qZ?Z(y*zhXd^A)mRyYQH&eSjk}|-44@6bQGWNG)`3|3StM5g2g~9FamD8g&vt z3-i$se;h!QmXAC$fKvd+-icHd9)-J(H8-0zr(q5crs&Z{k2F0_)1wno0asw@79reCk| z>ze*Pf!a zep6WI0;@iu{-HTm_KN>kY{GAjALW()%E>ltPj^PRcO;nX_N4&qF2KGj_OChr=Ygh= Gu>D^qlrAFx 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 zcmbtXZERCj7=CXz-1zD(sJMh>)Z}P31J|}2f=ht{*X^Q{Opr*Fq?WB^gRWcJs}8d4 zBOS1@U}pTo4}bXa#~((CF$zSn1%6mWe;IQxx2@YSaUUdn{7@8J&3o=S-Q9IdOnj2w zbIx<$uk*g|Ic@u%Yie)^0&obh73NlRm|QwH57212l1X)Hrc6&oo+$K*gHZt>vIS?;4uG7N(~Kx_=a!(!U+#z}4+zLA zBkz$R02tPWucO|;M4=D$9t(&kj!_F00dcUoXzQW_K<^<{=hg%OBI2!7M7)(@Q4LHZ zY4i|JWLPGfF`z0VN<977Rv=NSr}QYPG%AT6B~^FDr%K6PaaAeF5~9{NkBQ> zLz=gra{$03CL$-3Ku#u#p4QTO%J7rygr3PyM2;Kc&;U@)^ zRN#l|E6FSFnKE&m43N{6`&!QhwT&wUJVyr?M+Cocy%a zRz9s|^h?^f;U~&S6Dc1U$Ew%-n4DeH`&LflN+@Dg(|^z=@;CBV^zXH+`SAq|T-7fn z|Ju^)&*^&F^qZZs8Mu+3Km+-!m}fnuO&ETnXJ%H8=Jc6zaa{m%Mou@@ll*jkYN~Ix zP~iE%0(^_LT&M;-^)f(yoG!H6mm{<;=Su)!YW8oMS{Z<)PaC84o+8wR44{wwpWuF3-`6&Bd?sJOm+XJ=j+NgjeR&-PuJy@^`F%qI&}WG_&0QY_Qco8 z?=l^p;IG>%HpnmEe|%~i1aSOw8w8kKfa?c>0R1mO{$_-9C?R zqsQy@xU2VsTir@XWiK{tssShk05<^Ok!jq$4;&z*kmGlWz}Cyz79L@vaBL3<-7aD6 zin8)i0U!zhmF!&%bF|&*N;+g`zfjUEI7fwD&NG7Sd|%k*>=#~K=5%d$mhW1=!#O0# z&QbcJ2}QS}Xp==$HbonjH*g*1V=-XdrErI5d>%@QyPCr?y4NMJnNj6z#C-~|1Uxpr zit*Jp9@i+3xkPX~KE_wrct7J^Hok%JT%V84jOXAyqJ&m&K3=8Ehvt(25Tr~Qt-BSi zjJKnm5)aMuhlnwr$Ip>qJl`+Jy8y7-l7HGG0MHHaFB^zci|~*Ls-aj^YJv9Hn_cal zzP5Hgi*^DML9g1@&S#wS6**s#t1WW1$Vp8*J@|MAA3l84;-d~98zC4x5{}2h(O^8> z5kxn048{Wr+bDh)tN?%q1rvD-k5?z>Ut$Lg&)UNl{v8XCJ;>!RF2euLc=U^BqmKD| zVB^;_z7hoisJzo+zuv-&7Ji3?NBe}?QEWUv`<)gZdxOV+)WV}3evkCoc+4H*a|^%9 zV&{T|M?085M9RiS2E!Yri!1KcOJg8e2ie+xqK9CFyt^IDcWF3&MqX3oyCKEvL|DZiKa z`G1n}tPDkbY9|<&xgxM{(WYJezv_FL|9LeAfV0e?eP29&j%S(vYECfRX8OF3IJiC^ z&HEhhzWH#m#^rJxyr22Fm-*-4LmU-M;Au`U@ci-d0Moalkvp(~>v7=sI+og=KZWVr zAwK`U&H$h`w#B}uFv^}d{fZ>2mtrkhVd@M8rk*H gjlK5}_t=3tV_GZ1o + * 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 zcmbu9&r2IY6vw|4t;YH*7A*yP*pn#em<>w7LlJD7AT|df9t6=z+$iWKvO7ZbVnGCt z9{n>s_84gYm>zm*dli(odC%1eLTNv+%*>nj=KJQ&%$|K*`;<`%g2H>GqZBWb_Lr0H zGKMjP()rKqpV7_s53-fczh{4sZnnRnxU#b3O&80R8P8wP1?_ugaA0ial}AOqDVo8+Q+Jiuv;bE{6*p;|dLInXs63+dUJ8rmkz?9=C~)?1%PB-|bxo zss%x1e^h!v$0wmRRp{78opxV(QE+Iq4O$j@*H{BxjbrFqGYo@E!$po`_oTx?D4 zfX91{V|^4gkAldaptC}-zg>?^7;pyv2knDu+~+LQxkGrUpWxPTlItS=!WX_6Z`kmX zb>yVQKE?JP31l{;;~@7)2z}LTw-+Jc!t~pUTCptgU7Jadko2yME{~G`;&SNlnuif$VzTC4T Xc35Bj6@pv8v1j6M*zr&T88`kOtq@ +#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 zcmbu9!Alfz6vw}#mM&RiCJ`7k9*QmU=Z+Odgc$3#Lx_kVd6RXWNvhqIomtTinwYV3 z5c~t`(yd!ZkGln_r#6bt9Rw?>)Qd{OFMhM{x4RB(M15fS{odR6-uKP#{bpt(eYa~A z1ri0_C|hL)YRmf`Z`*?tI1bBDXI>lbr(15p$p6sXEq6D+*K(fM1B+SZfb;qNQ?qv# z*3|3^0Lz@Ku+-q{hdnpnwjFryT-s5GkBEAf`g6@vJMxo(-9kjqwQad8y>8CPZ)iqf z#WK|7J4+4b-^}k{nQ0Xj=JrtsWWMdF!>gO?mU`}q*VSV7`!CLyIp^Hd`La-O-d1Yt z7TO9zr&o=7)rANNY(BS^Dnmt>`gD?WKDPnjaYWDgTKYQ9Irns*WstqO-Zg`0IDA73 zM*D{@YWh{y$#ktV)OjtW>me;TXpU({%%MNpyDmaJ12h2Q45Ix*sDY9bJ~;!0?0}~N zw9u+N8iX>{q_j5HH!LYd|5^I4Rwn-e5mJZkV)H&~OX_8gd0TH%hiC%OToGT=wnvWE(nW=|)a*eICoq>Jmg+@;Nj zG3J<44%k@CiGhvUHds0(3>LSY>tOLzB4H*Suw=?HS+sws-F9N}2V~z%X4phJHDRWm zX%x$u<0Do&mM}~D|A}}mF`J{lI>mPmP28Coxp zzv6ZG2v@mNe)nan`LFpp={Hk95`% + +#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 zcmbu9&rcIk5XZj@C>YUKiN6vwt`}1hd9(zhF@`j$x|)#25UbqCQg$UuTiksl#e;rn3M$cd(yz-gRSBt`cY(TyT&8$e?0#JN z0$|w{xoTZZ?bOBkwjmx@MY<-QR4GsO$HSMflF8d<)Jmm?%=nlbm2q=4HhLo#kH^gD zq%&(iuoXWTzBvT+05Aa@17M}n=z>uuo9>0d`U!5sSw4+dlQ0SqW3a!s?~Q?`{SrTW z%jch<{5|;IILxQJUA;qpQ>0rSoW|M>;8&x? z{1JBQ4MF~aRRE;FlvVZ&q_4czIj1GhnYX2K3JP-8RyO2}??ZZdQe?(gW00AAHtXaR zWG=59X{FM`zOpkfSbvsVlnY*d!SU1*TIrm*Y1gx}4qxZLq4%O091mq`?KnDpWFlH% z2AlIk+h4QCixXqRNv_k!`b9pkv7KfR(e(7MCQ;o8I;*Dvrz>AR<%hvO+{c=p6+j@NZGY;HsUjl<#-e5s|jXNz$B EZ +#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 zcmbtV-%Aux6h5PtYglViA=r;u7(yd&yHZ#YCb+rtAQqAjJ+13HCA2?e=2|M!x{2Tt zLhtnl_!2}9)#FNm_@)KovPlL#Y!u=`pbz21ojG@Qy1Ethz1(}gd(U^yJ?HFf>RNYK zg(Lxo1np3=N|>uG?K`Y(2YBHSYG<{TwA@@ zu(h-hR0_=YZDxYXw|q<~0Gg079Le zm*u8VPhYbfI8RzhKyLN7UhoG3ez~bv8^><+URZukdx>M;yFQL}T$?A#)Pw5CMT|CEO zYqOu54vqmpy-VN8)d*94BoU2~D2!`*5=eKaA8d*_-$I27tknI0&VZxD^vynu6`V-AbekAyuZ;LJw@@~1IApJR@8KIj5O`YdYxtA7CF|I%Cb9t`B3 zX9m%}g#PtHp6Va`xlR}Q`vw0S=zmV&`TO~L9sNb5_yqwX9R`4EoO?GW@uHX)&zs|Z znfg8dOMku0{CKdTd`{T>9B|d2^DK +#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 zcmbu9L2DC16vzLYRvR^DH=*(B_)*a+$& zU%-#y!GlMSMZNhYJXY{x&O+sF-b>brz32}%Gy9+U&zqU|vTyD^*vc3N1Os<4eVg(z zGwrV@-F2Kr4iBB-4{Kx=a>bEZ*eqrbX>4R#kBZrmY2}J7$9(;{WtKiA1J3Y^)pE@4 z*T>(JHEJ6hYj&wtZ!FuDYpSX$cC}o+UanNic4^z+wH-I+fz=z!iDMps4d4WTTD^e` zj04hS&j!DrN@fG+xiwyH!`QcsrQAaHtpQxb_#tl7&)vK=%xvcEAa8Buv+SCM;>_dc z(d-B?H`&FM(*Vw;^duGl6M!|HHsQiC`qD8vUhH^oGg2O?f%i0U_uz%T+d+HK@5Qok zfje|p^!z#+b0wwIor-=drJqdcboT_6L#iYI6%B&eZ9+wHIBwh03;m9(Vt+q|+I3?W zsu@L4UM~pzZVc7!#lEW58>><5de8WMulro}!(QJH;{nDi`0brm=mtLT;Qyd=P%i0g zX~wn9HIYKk73G8OQRWMWT!;<}lz)<>q83@d%=(-dnOD-$;AJPQ@S6YXuW1mFWt(DxDndG}L>!D;==Vqe=fC+K-c(17jPCypnxTCt literal 0 HcmV?d00001 diff --git a/src/openlibm/src/w_cabsf.c b/src/openlibm/src/w_cabsf.c new file mode 100644 index 0000000..f14c71a --- /dev/null +++ b/src/openlibm/src/w_cabsf.c @@ -0,0 +1,19 @@ +/* + * cabsf() wrapper for hypotf(). + * + * Written by J.T. Conklin, + * 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 zcmbu9&uSA<6vn?vqm3Fn6X~MRg0mPT1$&zWMd?BcttLtdS{hfCI+@HgV*W8RV&kGN zx^m}3xbQJ5_y%sebXmcTWGht8%sI(8H3<5HaPR%*ocrCm=VadA-+GYIGzc2*VX~TV zl9|lcqv<-XA`h>oA0F3^z87nsPR)^C*t8bjZCXpwEI-l@<8|(oQbxM5OQNx3<)VP> zNH6SK#z-&hSo2Y^A%R;~ws!Qn_${)kZfvZX#cI8=Y?g1SiYl9xQss83TrQc#ZMS9C z?2sR<+*yv#nFU}1xB#G9Zy*Ehm^67ejn|jraLn_lz1fC#U}%f^+1z_A)|dEMi^hj@ zrOea0982e*{j>OScJ2XynX&tXD*&z~^vDB10e~?H8?!J)zdl9B>pjPA2A*;djc{Ic z?R^i9@7f&??ctywdH{;-KzBsHpJy>o5<1Z9B?xWjC9n5;uhhWr4_rSSBHqDm z?|Hu6b@>GU2fYW?lHM&z-1`{UNl4dfk?&FBg&bc>jfKnXBMn9MC2p`j!)xJ#Oj1Z+ z3pasi&wtG?vwul8WW;|}1V;R2T;u#SU(y02dBP(Av*{iJaKZuUbIJV)P4@q-2kB1O z=x_PYrqu5-Zzy%5`jNNzi%vFaZ{jZdf8>MG|DS4<&ZqBEx^~1@&ZquJ!txmUe*7uF N&4=oYBV*F}zW}3SiJ1TZ literal 0 HcmV?d00001 diff --git a/src/openlibm/src/w_cabsl.c b/src/openlibm/src/w_cabsl.c new file mode 100644 index 0000000..c10f1d4 --- /dev/null +++ b/src/openlibm/src/w_cabsl.c @@ -0,0 +1,22 @@ +/* + * cabs() wrapper for hypot(). + * + * Written by J.T. Conklin, + * 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 zcmbu9-)a*<6vn?ztF2l~6fcAd?!_Q2*l`mSODPhlnjjjq5a^Axo9)_&n?LN1*vNtx zeF1$7A0roD_zGoTK*5W8FI3LvoMascg8m@P%r|q+nK|cdK0JE*xa2qx96Z2uHDy$q z&TIL!hRaw&8{qBtu?oDS66k#t$NjaUZvu>t2^O=+wcu_}Ky!V2}hs*n=#`2>0u_1r+_<3gQ z#M~s>luH1v7W6y@fGYsX(_<5^&(Lqq(D80B@Y_kG1LPxu*IoZGLJ)_36rnR5^i9OM zA}B}n`*k*EgCmnhxfK0bK|f#6Ddz;WMWHnSoeaCiZ$l?09*-TF#bM-Y6CN4p1K;@2 z?IeK?`rU5WGtj-h33a{MT2G80yy5j>@2wuh{XrO;A;uoU&fcro?}mJX|AXE^wWPNd z8TU9QbrS4at#BUYyl~15*I?ly$B~Aj`VzNTpX0UgNhTK3$HHwO_xZ2(6^`$TLq_7? z5rL8TGH$ZH&BzuQu@jyESg?BtnAqF*lKcs6j{ipw0yyOZf3tr%qkbFgQ0heWqu3H( ubb5~+n{fG|pZOm2{Zox>`wOhwd}Vv;k0N&d=>Nm6J@K3`Mc;f8+x|C{)Q%AV 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)