From dbb5fc97ed3f892041b21d04cb15fb898ac52f55 Mon Sep 17 00:00:00 2001 From: Mikolaj Matalowski Date: Tue, 30 Sep 2025 12:54:52 +0200 Subject: [PATCH 1/3] Add libmcs math library implementation JIRA: RTOS-1132 --- libm/libmcs/.clang-format | 3 + libm/libmcs/.gitattributes | 20 + libm/libmcs/.gitignore | 54 + libm/libmcs/.gitlab-ci.yml | 102 + libm/libmcs/CITATION.cff | 74 + libm/libmcs/CONTRIBUTING.md | 87 + libm/libmcs/COPYING.md | 14 + libm/libmcs/CREDITS.md | 66 + libm/libmcs/Dockerfile | 20 + libm/libmcs/LICENSES/GTDGmbH.md | 27 + libm/libmcs/LICENSES/NetBSD.md | 23 + libm/libmcs/LICENSES/PublicDomain.md | 4 + libm/libmcs/LICENSES/RedHat.md | 5 + libm/libmcs/LICENSES/RichFelker.md | 21 + libm/libmcs/LICENSES/SunMicrosystems.md | 7 + libm/libmcs/Makefile.in | 340 +++ libm/libmcs/README.md | 117 + libm/libmcs/configure | 261 ++ libm/libmcs/doc/_static/css/custom.css | 66 + libm/libmcs/doc/figure/libmcs-complex.png | Bin 0 -> 18554 bytes .../doc/figure/libmcs-include-common.png | Bin 0 -> 10299 bytes libm/libmcs/doc/figure/libmcs-real.png | Bin 0 -> 18050 bytes .../doc/figure/libmcs-static-architecture.png | Bin 0 -> 16401 bytes libm/libmcs/doc/index.html | 117 + libm/libmcs/doc/logo/libmcs-favicon.ico | Bin 0 -> 12862 bytes libm/libmcs/doc/logo/libmcs-logo.png | Bin 0 -> 28336 bytes libm/libmcs/doc/sdd/1_Introduction.rst | 15 + .../2_Applicable_and_Reference_Documents.rst | 46 + libm/libmcs/doc/sdd/3_Abbreviations.rst | 52 + .../doc/sdd/4_Software_Design_Overview.rst | 124 + .../5_Software_Design/0_Software_Design.rst | 11 + .../doc/sdd/5_Software_Design/1_General.rst | 21 + .../2_Overall_Architecture.rst | 387 +++ .../3_Software_Component_Design_General.rst | 112 + ...onent_Design_Aspects_Of_Each_Component.rst | 315 +++ .../0010_fpclassify.rst | 54 + .../0020_isfinite.rst | 34 + .../0030_isinf.rst | 34 + .../0040_isnan.rst | 34 + .../0050_isnormal.rst | 33 + .../0060_signbit.rst | 34 + .../0100_acos.rst | 118 + .../0110_asin.rst | 136 ++ .../0120_atan.rst | 145 ++ .../0130_atan2.rst | 139 ++ .../0140_cos.rst | 85 + .../0150_sin.rst | 83 + .../0160_tan.rst | 162 ++ .../0170_trig.rst | 191 ++ .../0200_acosh.rst | 53 + .../0210_asinh.rst | 52 + .../0220_atanh.rst | 52 + .../0230_cosh.rst | 56 + .../0240_sinh.rst | 55 + .../0250_tanh.rst | 45 + .../0300_exp.rst | 100 + .../0310_exp2.rst | 47 + .../0320_expm1.rst | 49 + .../0330_frexp.rst | 42 + .../0340_ilogb.rst | 45 + .../0350_ldexp.rst | 49 + .../0360_log.rst | 138 ++ .../0370_log10.rst | 87 + .../0380_log1p.rst | 53 + .../0390_log2.rst | 50 + .../0400_logb.rst | 44 + .../0410_modf.rst | 68 + .../0420_scalbn.rst | 81 + .../0430_scalbln.rst | 44 + .../0440_log_internal.rst | 76 + .../0500_cbrt.rst | 42 + .../0510_fabs.rst | 66 + .../0520_hypot.rst | 74 + .../0530_pow.rst | 345 +++ .../0540_sqrt.rst | 124 + .../0600_erf.rst | 51 + .../0610_erfc.rst | 51 + .../0620_lgamma.rst | 52 + .../0630_tgamma.rst | 50 + .../0640_gamma_internal.rst | 42 + .../0650_signgam.rst | 25 + .../0700_ceil.rst | 76 + .../0710_floor.rst | 76 + .../0720_nearbyint.rst | 43 + .../0730_rint.rst | 45 + .../0740_lrint.rst | 51 + .../0750_llrint.rst | 47 + .../0760_round.rst | 77 + .../0770_lround.rst | 51 + .../0780_llround.rst | 47 + .../0790_trunc.rst | 65 + .../0900_fmod.rst | 66 + .../0910_remainder.rst | 46 + .../0920_remquo.rst | 47 + .../1000_copysign.rst | 36 + .../1010_nan.rst | 26 + .../1020_nextafter.rst | 56 + .../1030_nexttoward.rst | 51 + .../1100_fdim.rst | 49 + .../1110_fmax.rst | 51 + .../1120_fmin.rst | 51 + .../1200_fma.rst | 48 + .../1300_isgreater.rst | 38 + .../1310_isgreaterequal.rst | 38 + .../1320_isless.rst | 38 + .../1330_islessequal.rst | 38 + .../1340_islessgreater.rst | 38 + .../1350_isunordered.rst | 35 + .../1400_j0.rst | 48 + .../1410_j1.rst | 48 + .../1420_jn.rst | 49 + .../1430_y0.rst | 60 + .../1440_y1.rst | 61 + .../1450_yn.rst | 55 + .../1500_cacos.rst | 32 + .../1510_casin.rst | 35 + .../1520_catan.rst | 39 + .../1530_ccos.rst | 37 + .../1540_csin.rst | 41 + .../1550_ctan.rst | 36 + .../1600_cacosh.rst | 29 + .../1610_casinh.rst | 31 + .../1620_catanh.rst | 31 + .../1630_ccosh.rst | 38 + .../1640_csinh.rst | 34 + .../1650_ctanh.rst | 39 + .../1700_cexp.rst | 33 + .../1710_clog.rst | 35 + .../1800_cabs.rst | 33 + .../1810_cpow.rst | 38 + .../1820_csqrt.rst | 35 + .../1900_carg.rst | 31 + .../1910_cimag.rst | 30 + .../1920_cmplx.rst | 27 + .../1930_conj.rst | 26 + .../1940_cproj.rst | 30 + .../1950_creal.rst | 30 + .../2000_misc_internal.rst | 40 + .../3000_configure.rst | 56 + .../3100_makefile.rst | 48 + .../5_Internal_Interface_Design.rst | 20 + ...ents_to_Design_Components_Traceability.rst | 761 ++++++ libm/libmcs/doc/sdd/conf.py | 84 + libm/libmcs/doc/sdd/index.rst | 18 + libm/libmcs/doc/sum/10_Bindings.rst | 179 ++ libm/libmcs/doc/sum/1_Abbreviations.rst | 112 + libm/libmcs/doc/sum/2_Conventions.rst | 39 + .../doc/sum/3_Purpose_of_the_Software.rst | 318 +++ libm/libmcs/doc/sum/4_General_Behaviour.rst | 395 +++ .../sum/5_External_View_of_the_Software.rst | 177 ++ .../doc/sum/6_Operations_Environment.rst | 77 + libm/libmcs/doc/sum/7_Operations_Manual.rst | 95 + libm/libmcs/doc/sum/8_Reference_Manual.rst | 556 +++++ libm/libmcs/doc/sum/9_Tutorial.rst | 265 ++ libm/libmcs/doc/sum/conf.py | 84 + libm/libmcs/doc/sum/index.rst | 26 + libm/libmcs/libm/common/cmplx.c | 38 + libm/libmcs/libm/common/fenv.c | 59 + libm/libmcs/libm/common/isfinite.c | 52 + libm/libmcs/libm/common/isgreater.c | 57 + libm/libmcs/libm/common/isgreaterequal.c | 57 + libm/libmcs/libm/common/isinf.c | 51 + libm/libmcs/libm/common/isless.c | 56 + libm/libmcs/libm/common/islessequal.c | 57 + libm/libmcs/libm/common/islessgreater.c | 57 + libm/libmcs/libm/common/isnan.c | 51 + libm/libmcs/libm/common/isnormal.c | 51 + libm/libmcs/libm/common/isunordered.c | 54 + libm/libmcs/libm/common/signgam.c | 26 + libm/libmcs/libm/common/tools.c | 7 + libm/libmcs/libm/common/tools.h | 449 ++++ libm/libmcs/libm/complexd/cabsd.c | 61 + libm/libmcs/libm/complexd/cacosd.c | 71 + libm/libmcs/libm/complexd/cacoshd.c | 65 + libm/libmcs/libm/complexd/cargd.c | 61 + libm/libmcs/libm/complexd/casind.c | 80 + libm/libmcs/libm/complexd/casinhd.c | 70 + libm/libmcs/libm/complexd/catand.c | 91 + libm/libmcs/libm/complexd/catanhd.c | 70 + libm/libmcs/libm/complexd/ccosd.c | 65 + libm/libmcs/libm/complexd/ccoshd.c | 66 + libm/libmcs/libm/complexd/cexpd.c | 67 + libm/libmcs/libm/complexd/cimagd.c | 58 + libm/libmcs/libm/complexd/clogd.c | 70 + libm/libmcs/libm/complexd/conjd.c | 92 + libm/libmcs/libm/complexd/cpowd.c | 85 + libm/libmcs/libm/complexd/cprojd.c | 78 + libm/libmcs/libm/complexd/creald.c | 58 + libm/libmcs/libm/complexd/csind.c | 65 + libm/libmcs/libm/complexd/csinhd.c | 65 + libm/libmcs/libm/complexd/csqrtd.c | 126 + libm/libmcs/libm/complexd/ctand.c | 120 + libm/libmcs/libm/complexd/ctanhd.c | 67 + libm/libmcs/libm/complexd/internal/ctrigd.c | 58 + libm/libmcs/libm/complexd/internal/ctrigd.h | 12 + libm/libmcs/libm/complexf/cabsf.c | 23 + libm/libmcs/libm/complexf/cacosf.c | 30 + libm/libmcs/libm/complexf/cacoshf.c | 25 + libm/libmcs/libm/complexf/cargf.c | 23 + libm/libmcs/libm/complexf/casinf.c | 40 + libm/libmcs/libm/complexf/casinhf.c | 28 + libm/libmcs/libm/complexf/catanf.c | 50 + libm/libmcs/libm/complexf/catanhf.c | 28 + libm/libmcs/libm/complexf/ccosf.c | 29 + libm/libmcs/libm/complexf/ccoshf.c | 29 + libm/libmcs/libm/complexf/cexpf.c | 30 + libm/libmcs/libm/complexf/cimagf.c | 22 + libm/libmcs/libm/complexf/clogf.c | 30 + libm/libmcs/libm/complexf/conjf.c | 23 + libm/libmcs/libm/complexf/cpowf.c | 45 + libm/libmcs/libm/complexf/cprojf.c | 27 + libm/libmcs/libm/complexf/crealf.c | 22 + libm/libmcs/libm/complexf/csinf.c | 29 + libm/libmcs/libm/complexf/csinhf.c | 29 + libm/libmcs/libm/complexf/csqrtf.c | 83 + libm/libmcs/libm/complexf/ctanf.c | 83 + libm/libmcs/libm/complexf/ctanhf.c | 31 + libm/libmcs/libm/complexf/internal/ctrigf.c | 54 + libm/libmcs/libm/complexf/internal/ctrigf.h | 12 + libm/libmcs/libm/complexfe/internal/.gitkeep | 0 libm/libmcs/libm/complexl/internal/.gitkeep | 0 libm/libmcs/libm/include/complex.h | 206 ++ libm/libmcs/libm/include/config.h | 17 + libm/libmcs/libm/include/fenv.h | 41 + libm/libmcs/libm/include/internal_config.h | 156 ++ libm/libmcs/libm/include/math.h | 390 +++ libm/libmcs/libm/include/tgmath.h | 157 ++ .../libm/machine/sparc_v8/mathd/sqrtd.c | 78 + .../libm/machine/sparc_v8/mathf/sqrtf.c | 24 + libm/libmcs/libm/mathd/acosd.c | 145 ++ libm/libmcs/libm/mathd/acoshd.c | 104 + libm/libmcs/libm/mathd/asind.c | 156 ++ libm/libmcs/libm/mathd/asinhd.c | 111 + libm/libmcs/libm/mathd/atan2d.c | 209 ++ libm/libmcs/libm/mathd/atand.c | 171 ++ libm/libmcs/libm/mathd/atanhd.c | 120 + libm/libmcs/libm/mathd/cbrtd.c | 136 ++ libm/libmcs/libm/mathd/ceild.c | 142 ++ libm/libmcs/libm/mathd/copysignd.c | 93 + libm/libmcs/libm/mathd/cosd.c | 121 + libm/libmcs/libm/mathd/coshd.c | 122 + libm/libmcs/libm/mathd/erfcd.c | 253 ++ libm/libmcs/libm/mathd/erfd.c | 242 ++ libm/libmcs/libm/mathd/exp2d.c | 76 + libm/libmcs/libm/mathd/expd.c | 177 ++ libm/libmcs/libm/mathd/expm1d.c | 305 +++ libm/libmcs/libm/mathd/fabsd.c | 77 + libm/libmcs/libm/mathd/fdimd.c | 96 + libm/libmcs/libm/mathd/floord.c | 142 ++ libm/libmcs/libm/mathd/fmad.c | 118 + libm/libmcs/libm/mathd/fmaxd.c | 110 + libm/libmcs/libm/mathd/fmind.c | 110 + libm/libmcs/libm/mathd/fmodd.c | 282 +++ libm/libmcs/libm/mathd/frexpd.c | 118 + libm/libmcs/libm/mathd/hypotd.c | 193 ++ libm/libmcs/libm/mathd/ilogbd.c | 127 + libm/libmcs/libm/mathd/internal/besseld.h | 444 ++++ .../libm/mathd/internal/errorfunctiond.h | 121 + libm/libmcs/libm/mathd/internal/fpclassifyd.c | 77 + libm/libmcs/libm/mathd/internal/gammad.c | 428 ++++ libm/libmcs/libm/mathd/internal/gammad.h | 9 + libm/libmcs/libm/mathd/internal/log1pmfd.h | 43 + libm/libmcs/libm/mathd/internal/signbitd.c | 63 + libm/libmcs/libm/mathd/internal/trigd.c | 627 +++++ libm/libmcs/libm/mathd/internal/trigd.h | 13 + libm/libmcs/libm/mathd/j0d.c | 148 ++ libm/libmcs/libm/mathd/j1d.c | 144 ++ libm/libmcs/libm/mathd/jnd.c | 292 +++ libm/libmcs/libm/mathd/ldexpd.c | 98 + libm/libmcs/libm/mathd/lgammad.c | 78 + libm/libmcs/libm/mathd/llrintd.c | 155 ++ libm/libmcs/libm/mathd/llroundd.c | 137 ++ libm/libmcs/libm/mathd/log10d.c | 146 ++ libm/libmcs/libm/mathd/log1pd.c | 235 ++ libm/libmcs/libm/mathd/log2d.c | 167 ++ libm/libmcs/libm/mathd/logbd.c | 102 + libm/libmcs/libm/mathd/logd.c | 171 ++ libm/libmcs/libm/mathd/lrintd.c | 159 ++ libm/libmcs/libm/mathd/lroundd.c | 141 ++ libm/libmcs/libm/mathd/modfd.c | 128 + libm/libmcs/libm/mathd/nand.c | 64 + libm/libmcs/libm/mathd/nearbyintd.c | 68 + libm/libmcs/libm/mathd/nextafterd.c | 162 ++ libm/libmcs/libm/mathd/nexttowardd.c | 98 + libm/libmcs/libm/mathd/powd.c | 443 ++++ libm/libmcs/libm/mathd/remainderd.c | 176 ++ libm/libmcs/libm/mathd/remquod.c | 210 ++ libm/libmcs/libm/mathd/rintd.c | 143 ++ libm/libmcs/libm/mathd/roundd.c | 131 + libm/libmcs/libm/mathd/scalblnd.c | 142 ++ libm/libmcs/libm/mathd/scalbnd.c | 146 ++ libm/libmcs/libm/mathd/sind.c | 123 + libm/libmcs/libm/mathd/sinhd.c | 131 + libm/libmcs/libm/mathd/sqrtd.c | 199 ++ libm/libmcs/libm/mathd/tand.c | 195 ++ libm/libmcs/libm/mathd/tanhd.c | 118 + libm/libmcs/libm/mathd/tgammad.c | 99 + libm/libmcs/libm/mathd/truncd.c | 109 + libm/libmcs/libm/mathd/y0d.c | 162 ++ libm/libmcs/libm/mathd/y1d.c | 160 ++ libm/libmcs/libm/mathd/ynd.c | 182 ++ libm/libmcs/libm/mathf/acosf.c | 92 + libm/libmcs/libm/mathf/acoshf.c | 52 + libm/libmcs/libm/mathf/asinf.c | 98 + libm/libmcs/libm/mathf/asinhf.c | 59 + libm/libmcs/libm/mathf/atan2f.c | 136 ++ libm/libmcs/libm/mathf/atanf.c | 116 + libm/libmcs/libm/mathf/atanhf.c | 64 + libm/libmcs/libm/mathf/cbrtf.c | 76 + libm/libmcs/libm/mathf/ceilf.c | 67 + libm/libmcs/libm/mathf/copysignf.c | 30 + libm/libmcs/libm/mathf/cosf.c | 70 + libm/libmcs/libm/mathf/coshf.c | 68 + libm/libmcs/libm/mathf/erfcf.c | 106 + libm/libmcs/libm/mathf/erff.c | 103 + libm/libmcs/libm/mathf/exp2f.c | 23 + libm/libmcs/libm/mathf/expf.c | 114 + libm/libmcs/libm/mathf/expm1f.c | 148 ++ libm/libmcs/libm/mathf/fabsf.c | 27 + libm/libmcs/libm/mathf/fdimf.c | 27 + libm/libmcs/libm/mathf/floorf.c | 76 + libm/libmcs/libm/mathf/fmaf.c | 24 + libm/libmcs/libm/mathf/fmaxf.c | 44 + libm/libmcs/libm/mathf/fminf.c | 44 + libm/libmcs/libm/mathf/fmodf.c | 144 ++ libm/libmcs/libm/mathf/frexpf.c | 54 + libm/libmcs/libm/mathf/hypotf.c | 113 + libm/libmcs/libm/mathf/ilogbf.c | 46 + .../libm/mathf/internal/errorfunctionf.h | 95 + libm/libmcs/libm/mathf/internal/fpclassifyf.c | 26 + libm/libmcs/libm/mathf/internal/gammaf.c | 298 +++ libm/libmcs/libm/mathf/internal/gammaf.h | 9 + libm/libmcs/libm/mathf/internal/log1pmff.h | 28 + libm/libmcs/libm/mathf/internal/signbitf.c | 44 + libm/libmcs/libm/mathf/internal/trigf.c | 502 ++++ libm/libmcs/libm/mathf/internal/trigf.h | 13 + libm/libmcs/libm/mathf/ldexpf.c | 27 + libm/libmcs/libm/mathf/lgammaf.c | 24 + libm/libmcs/libm/mathf/llrintf.c | 85 + libm/libmcs/libm/mathf/llroundf.c | 50 + libm/libmcs/libm/mathf/log10f.c | 80 + libm/libmcs/libm/mathf/log1pf.c | 118 + libm/libmcs/libm/mathf/log2f.c | 78 + libm/libmcs/libm/mathf/logbf.c | 51 + libm/libmcs/libm/mathf/logf.c | 119 + libm/libmcs/libm/mathf/lrintf.c | 84 + libm/libmcs/libm/mathf/lroundf.c | 48 + libm/libmcs/libm/mathf/modff.c | 62 + libm/libmcs/libm/mathf/nanf.c | 23 + libm/libmcs/libm/mathf/nearbyintf.c | 18 + libm/libmcs/libm/mathf/nextafterf.c | 77 + libm/libmcs/libm/mathf/nexttowardf.c | 90 + libm/libmcs/libm/mathf/powf.c | 339 +++ libm/libmcs/libm/mathf/remainderf.c | 79 + libm/libmcs/libm/mathf/remquof.c | 97 + libm/libmcs/libm/mathf/rintf.c | 77 + libm/libmcs/libm/mathf/roundf.c | 64 + libm/libmcs/libm/mathf/scalblnf.c | 71 + libm/libmcs/libm/mathf/scalbnf.c | 80 + libm/libmcs/libm/mathf/sinf.c | 70 + libm/libmcs/libm/mathf/sinhf.c | 75 + libm/libmcs/libm/mathf/sqrtf.c | 97 + libm/libmcs/libm/mathf/tanf.c | 133 + libm/libmcs/libm/mathf/tanhf.c | 66 + libm/libmcs/libm/mathf/tgammaf.c | 50 + libm/libmcs/libm/mathf/truncf.c | 52 + libm/libmcs/libm/mathfe/internal/.gitkeep | 0 libm/libmcs/libm/mathl/internal/.gitkeep | 0 libm/libmcs/poetry.lock | 1118 +++++++++ libm/libmcs/pyproject.toml | 21 + libm/libmcs/sw-quality/au-misra3.lnt | 2173 +++++++++++++++++ libm/libmcs/sw-quality/co-gcc.h | 129 + libm/libmcs/sw-quality/co-gcc.lnt | 211 ++ libm/libmcs/sw-quality/co-gcc.mak | 173 ++ .../libmcs/sw-quality/dummy_includes/config.h | 17 + libm/libmcs/sw-quality/gcc-include-path.lnt | 4 + libm/libmcs/sw-quality/lint.sh | 8 + libm/libmcs/sw-quality/lint_cmac.h | 116 + libm/libmcs/sw-quality/lint_cppmac.h | 118 + libm/libmcs/sw-quality/options.lnt | 13 + libm/libmcs/sw-quality/size-options.lnt | 1 + libm/libmcs/sw-quality/sqarg-config.toml | 27 + libm/libmcs/sw-quality/std.lnt | 6 + 383 files changed, 37507 insertions(+) create mode 100644 libm/libmcs/.clang-format create mode 100644 libm/libmcs/.gitattributes create mode 100644 libm/libmcs/.gitignore create mode 100644 libm/libmcs/.gitlab-ci.yml create mode 100644 libm/libmcs/CITATION.cff create mode 100644 libm/libmcs/CONTRIBUTING.md create mode 100644 libm/libmcs/COPYING.md create mode 100644 libm/libmcs/CREDITS.md create mode 100644 libm/libmcs/Dockerfile create mode 100644 libm/libmcs/LICENSES/GTDGmbH.md create mode 100644 libm/libmcs/LICENSES/NetBSD.md create mode 100644 libm/libmcs/LICENSES/PublicDomain.md create mode 100644 libm/libmcs/LICENSES/RedHat.md create mode 100644 libm/libmcs/LICENSES/RichFelker.md create mode 100644 libm/libmcs/LICENSES/SunMicrosystems.md create mode 100644 libm/libmcs/Makefile.in create mode 100644 libm/libmcs/README.md create mode 100755 libm/libmcs/configure create mode 100644 libm/libmcs/doc/_static/css/custom.css create mode 100644 libm/libmcs/doc/figure/libmcs-complex.png create mode 100644 libm/libmcs/doc/figure/libmcs-include-common.png create mode 100644 libm/libmcs/doc/figure/libmcs-real.png create mode 100644 libm/libmcs/doc/figure/libmcs-static-architecture.png create mode 100644 libm/libmcs/doc/index.html create mode 100644 libm/libmcs/doc/logo/libmcs-favicon.ico create mode 100644 libm/libmcs/doc/logo/libmcs-logo.png create mode 100644 libm/libmcs/doc/sdd/1_Introduction.rst create mode 100644 libm/libmcs/doc/sdd/2_Applicable_and_Reference_Documents.rst create mode 100644 libm/libmcs/doc/sdd/3_Abbreviations.rst create mode 100644 libm/libmcs/doc/sdd/4_Software_Design_Overview.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/0_Software_Design.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/1_General.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/2_Overall_Architecture.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/3_Software_Component_Design_General.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0000_Software_Component_Design_Aspects_Of_Each_Component.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0010_fpclassify.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0020_isfinite.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0030_isinf.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0040_isnan.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0050_isnormal.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0060_signbit.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0100_acos.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0110_asin.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0120_atan.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0130_atan2.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0140_cos.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0150_sin.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0160_tan.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0170_trig.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0200_acosh.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0210_asinh.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0220_atanh.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0230_cosh.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0240_sinh.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0250_tanh.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0300_exp.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0310_exp2.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0320_expm1.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0330_frexp.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0340_ilogb.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0350_ldexp.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0360_log.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0370_log10.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0380_log1p.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0390_log2.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0400_logb.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0410_modf.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0420_scalbn.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0430_scalbln.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0440_log_internal.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0500_cbrt.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0510_fabs.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0520_hypot.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0530_pow.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0540_sqrt.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0600_erf.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0610_erfc.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0620_lgamma.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0630_tgamma.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0640_gamma_internal.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0650_signgam.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0700_ceil.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0710_floor.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0720_nearbyint.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0730_rint.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0740_lrint.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0750_llrint.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0760_round.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0770_lround.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0780_llround.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0790_trunc.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0900_fmod.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0910_remainder.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0920_remquo.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1000_copysign.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1010_nan.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1020_nextafter.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1030_nexttoward.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1100_fdim.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1110_fmax.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1120_fmin.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1200_fma.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1300_isgreater.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1310_isgreaterequal.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1320_isless.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1330_islessequal.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1340_islessgreater.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1350_isunordered.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1400_j0.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1410_j1.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1420_jn.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1430_y0.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1440_y1.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1450_yn.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1500_cacos.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1510_casin.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1520_catan.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1530_ccos.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1540_csin.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1550_ctan.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1600_cacosh.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1610_casinh.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1620_catanh.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1630_ccosh.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1640_csinh.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1650_ctanh.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1700_cexp.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1710_clog.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1800_cabs.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1810_cpow.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1820_csqrt.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1900_carg.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1910_cimag.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1920_cmplx.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1930_conj.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1940_cproj.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1950_creal.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/2000_misc_internal.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/3000_configure.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/3100_makefile.rst create mode 100644 libm/libmcs/doc/sdd/5_Software_Design/5_Internal_Interface_Design.rst create mode 100644 libm/libmcs/doc/sdd/6_Requirements_to_Design_Components_Traceability.rst create mode 100644 libm/libmcs/doc/sdd/conf.py create mode 100644 libm/libmcs/doc/sdd/index.rst create mode 100644 libm/libmcs/doc/sum/10_Bindings.rst create mode 100644 libm/libmcs/doc/sum/1_Abbreviations.rst create mode 100644 libm/libmcs/doc/sum/2_Conventions.rst create mode 100644 libm/libmcs/doc/sum/3_Purpose_of_the_Software.rst create mode 100644 libm/libmcs/doc/sum/4_General_Behaviour.rst create mode 100644 libm/libmcs/doc/sum/5_External_View_of_the_Software.rst create mode 100644 libm/libmcs/doc/sum/6_Operations_Environment.rst create mode 100644 libm/libmcs/doc/sum/7_Operations_Manual.rst create mode 100644 libm/libmcs/doc/sum/8_Reference_Manual.rst create mode 100644 libm/libmcs/doc/sum/9_Tutorial.rst create mode 100644 libm/libmcs/doc/sum/conf.py create mode 100644 libm/libmcs/doc/sum/index.rst create mode 100644 libm/libmcs/libm/common/cmplx.c create mode 100644 libm/libmcs/libm/common/fenv.c create mode 100644 libm/libmcs/libm/common/isfinite.c create mode 100644 libm/libmcs/libm/common/isgreater.c create mode 100644 libm/libmcs/libm/common/isgreaterequal.c create mode 100644 libm/libmcs/libm/common/isinf.c create mode 100644 libm/libmcs/libm/common/isless.c create mode 100644 libm/libmcs/libm/common/islessequal.c create mode 100644 libm/libmcs/libm/common/islessgreater.c create mode 100644 libm/libmcs/libm/common/isnan.c create mode 100644 libm/libmcs/libm/common/isnormal.c create mode 100644 libm/libmcs/libm/common/isunordered.c create mode 100644 libm/libmcs/libm/common/signgam.c create mode 100644 libm/libmcs/libm/common/tools.c create mode 100644 libm/libmcs/libm/common/tools.h create mode 100644 libm/libmcs/libm/complexd/cabsd.c create mode 100644 libm/libmcs/libm/complexd/cacosd.c create mode 100644 libm/libmcs/libm/complexd/cacoshd.c create mode 100644 libm/libmcs/libm/complexd/cargd.c create mode 100644 libm/libmcs/libm/complexd/casind.c create mode 100644 libm/libmcs/libm/complexd/casinhd.c create mode 100644 libm/libmcs/libm/complexd/catand.c create mode 100644 libm/libmcs/libm/complexd/catanhd.c create mode 100644 libm/libmcs/libm/complexd/ccosd.c create mode 100644 libm/libmcs/libm/complexd/ccoshd.c create mode 100644 libm/libmcs/libm/complexd/cexpd.c create mode 100644 libm/libmcs/libm/complexd/cimagd.c create mode 100644 libm/libmcs/libm/complexd/clogd.c create mode 100644 libm/libmcs/libm/complexd/conjd.c create mode 100644 libm/libmcs/libm/complexd/cpowd.c create mode 100644 libm/libmcs/libm/complexd/cprojd.c create mode 100644 libm/libmcs/libm/complexd/creald.c create mode 100644 libm/libmcs/libm/complexd/csind.c create mode 100644 libm/libmcs/libm/complexd/csinhd.c create mode 100644 libm/libmcs/libm/complexd/csqrtd.c create mode 100644 libm/libmcs/libm/complexd/ctand.c create mode 100644 libm/libmcs/libm/complexd/ctanhd.c create mode 100644 libm/libmcs/libm/complexd/internal/ctrigd.c create mode 100644 libm/libmcs/libm/complexd/internal/ctrigd.h create mode 100644 libm/libmcs/libm/complexf/cabsf.c create mode 100644 libm/libmcs/libm/complexf/cacosf.c create mode 100644 libm/libmcs/libm/complexf/cacoshf.c create mode 100644 libm/libmcs/libm/complexf/cargf.c create mode 100644 libm/libmcs/libm/complexf/casinf.c create mode 100644 libm/libmcs/libm/complexf/casinhf.c create mode 100644 libm/libmcs/libm/complexf/catanf.c create mode 100644 libm/libmcs/libm/complexf/catanhf.c create mode 100644 libm/libmcs/libm/complexf/ccosf.c create mode 100644 libm/libmcs/libm/complexf/ccoshf.c create mode 100644 libm/libmcs/libm/complexf/cexpf.c create mode 100644 libm/libmcs/libm/complexf/cimagf.c create mode 100644 libm/libmcs/libm/complexf/clogf.c create mode 100644 libm/libmcs/libm/complexf/conjf.c create mode 100644 libm/libmcs/libm/complexf/cpowf.c create mode 100644 libm/libmcs/libm/complexf/cprojf.c create mode 100644 libm/libmcs/libm/complexf/crealf.c create mode 100644 libm/libmcs/libm/complexf/csinf.c create mode 100644 libm/libmcs/libm/complexf/csinhf.c create mode 100644 libm/libmcs/libm/complexf/csqrtf.c create mode 100644 libm/libmcs/libm/complexf/ctanf.c create mode 100644 libm/libmcs/libm/complexf/ctanhf.c create mode 100644 libm/libmcs/libm/complexf/internal/ctrigf.c create mode 100644 libm/libmcs/libm/complexf/internal/ctrigf.h create mode 100644 libm/libmcs/libm/complexfe/internal/.gitkeep create mode 100644 libm/libmcs/libm/complexl/internal/.gitkeep create mode 100644 libm/libmcs/libm/include/complex.h create mode 100644 libm/libmcs/libm/include/config.h create mode 100644 libm/libmcs/libm/include/fenv.h create mode 100644 libm/libmcs/libm/include/internal_config.h create mode 100644 libm/libmcs/libm/include/math.h create mode 100644 libm/libmcs/libm/include/tgmath.h create mode 100644 libm/libmcs/libm/machine/sparc_v8/mathd/sqrtd.c create mode 100644 libm/libmcs/libm/machine/sparc_v8/mathf/sqrtf.c create mode 100644 libm/libmcs/libm/mathd/acosd.c create mode 100644 libm/libmcs/libm/mathd/acoshd.c create mode 100644 libm/libmcs/libm/mathd/asind.c create mode 100644 libm/libmcs/libm/mathd/asinhd.c create mode 100644 libm/libmcs/libm/mathd/atan2d.c create mode 100644 libm/libmcs/libm/mathd/atand.c create mode 100644 libm/libmcs/libm/mathd/atanhd.c create mode 100644 libm/libmcs/libm/mathd/cbrtd.c create mode 100644 libm/libmcs/libm/mathd/ceild.c create mode 100644 libm/libmcs/libm/mathd/copysignd.c create mode 100644 libm/libmcs/libm/mathd/cosd.c create mode 100644 libm/libmcs/libm/mathd/coshd.c create mode 100644 libm/libmcs/libm/mathd/erfcd.c create mode 100644 libm/libmcs/libm/mathd/erfd.c create mode 100644 libm/libmcs/libm/mathd/exp2d.c create mode 100644 libm/libmcs/libm/mathd/expd.c create mode 100644 libm/libmcs/libm/mathd/expm1d.c create mode 100644 libm/libmcs/libm/mathd/fabsd.c create mode 100644 libm/libmcs/libm/mathd/fdimd.c create mode 100644 libm/libmcs/libm/mathd/floord.c create mode 100644 libm/libmcs/libm/mathd/fmad.c create mode 100644 libm/libmcs/libm/mathd/fmaxd.c create mode 100644 libm/libmcs/libm/mathd/fmind.c create mode 100644 libm/libmcs/libm/mathd/fmodd.c create mode 100644 libm/libmcs/libm/mathd/frexpd.c create mode 100644 libm/libmcs/libm/mathd/hypotd.c create mode 100644 libm/libmcs/libm/mathd/ilogbd.c create mode 100644 libm/libmcs/libm/mathd/internal/besseld.h create mode 100644 libm/libmcs/libm/mathd/internal/errorfunctiond.h create mode 100644 libm/libmcs/libm/mathd/internal/fpclassifyd.c create mode 100644 libm/libmcs/libm/mathd/internal/gammad.c create mode 100644 libm/libmcs/libm/mathd/internal/gammad.h create mode 100644 libm/libmcs/libm/mathd/internal/log1pmfd.h create mode 100644 libm/libmcs/libm/mathd/internal/signbitd.c create mode 100644 libm/libmcs/libm/mathd/internal/trigd.c create mode 100644 libm/libmcs/libm/mathd/internal/trigd.h create mode 100644 libm/libmcs/libm/mathd/j0d.c create mode 100644 libm/libmcs/libm/mathd/j1d.c create mode 100644 libm/libmcs/libm/mathd/jnd.c create mode 100644 libm/libmcs/libm/mathd/ldexpd.c create mode 100644 libm/libmcs/libm/mathd/lgammad.c create mode 100644 libm/libmcs/libm/mathd/llrintd.c create mode 100644 libm/libmcs/libm/mathd/llroundd.c create mode 100644 libm/libmcs/libm/mathd/log10d.c create mode 100644 libm/libmcs/libm/mathd/log1pd.c create mode 100644 libm/libmcs/libm/mathd/log2d.c create mode 100644 libm/libmcs/libm/mathd/logbd.c create mode 100644 libm/libmcs/libm/mathd/logd.c create mode 100644 libm/libmcs/libm/mathd/lrintd.c create mode 100644 libm/libmcs/libm/mathd/lroundd.c create mode 100644 libm/libmcs/libm/mathd/modfd.c create mode 100644 libm/libmcs/libm/mathd/nand.c create mode 100644 libm/libmcs/libm/mathd/nearbyintd.c create mode 100644 libm/libmcs/libm/mathd/nextafterd.c create mode 100644 libm/libmcs/libm/mathd/nexttowardd.c create mode 100644 libm/libmcs/libm/mathd/powd.c create mode 100644 libm/libmcs/libm/mathd/remainderd.c create mode 100644 libm/libmcs/libm/mathd/remquod.c create mode 100644 libm/libmcs/libm/mathd/rintd.c create mode 100644 libm/libmcs/libm/mathd/roundd.c create mode 100644 libm/libmcs/libm/mathd/scalblnd.c create mode 100644 libm/libmcs/libm/mathd/scalbnd.c create mode 100644 libm/libmcs/libm/mathd/sind.c create mode 100644 libm/libmcs/libm/mathd/sinhd.c create mode 100644 libm/libmcs/libm/mathd/sqrtd.c create mode 100644 libm/libmcs/libm/mathd/tand.c create mode 100644 libm/libmcs/libm/mathd/tanhd.c create mode 100644 libm/libmcs/libm/mathd/tgammad.c create mode 100644 libm/libmcs/libm/mathd/truncd.c create mode 100644 libm/libmcs/libm/mathd/y0d.c create mode 100644 libm/libmcs/libm/mathd/y1d.c create mode 100644 libm/libmcs/libm/mathd/ynd.c create mode 100644 libm/libmcs/libm/mathf/acosf.c create mode 100644 libm/libmcs/libm/mathf/acoshf.c create mode 100644 libm/libmcs/libm/mathf/asinf.c create mode 100644 libm/libmcs/libm/mathf/asinhf.c create mode 100644 libm/libmcs/libm/mathf/atan2f.c create mode 100644 libm/libmcs/libm/mathf/atanf.c create mode 100644 libm/libmcs/libm/mathf/atanhf.c create mode 100644 libm/libmcs/libm/mathf/cbrtf.c create mode 100644 libm/libmcs/libm/mathf/ceilf.c create mode 100644 libm/libmcs/libm/mathf/copysignf.c create mode 100644 libm/libmcs/libm/mathf/cosf.c create mode 100644 libm/libmcs/libm/mathf/coshf.c create mode 100644 libm/libmcs/libm/mathf/erfcf.c create mode 100644 libm/libmcs/libm/mathf/erff.c create mode 100644 libm/libmcs/libm/mathf/exp2f.c create mode 100644 libm/libmcs/libm/mathf/expf.c create mode 100644 libm/libmcs/libm/mathf/expm1f.c create mode 100644 libm/libmcs/libm/mathf/fabsf.c create mode 100644 libm/libmcs/libm/mathf/fdimf.c create mode 100644 libm/libmcs/libm/mathf/floorf.c create mode 100644 libm/libmcs/libm/mathf/fmaf.c create mode 100644 libm/libmcs/libm/mathf/fmaxf.c create mode 100644 libm/libmcs/libm/mathf/fminf.c create mode 100644 libm/libmcs/libm/mathf/fmodf.c create mode 100644 libm/libmcs/libm/mathf/frexpf.c create mode 100644 libm/libmcs/libm/mathf/hypotf.c create mode 100644 libm/libmcs/libm/mathf/ilogbf.c create mode 100644 libm/libmcs/libm/mathf/internal/errorfunctionf.h create mode 100644 libm/libmcs/libm/mathf/internal/fpclassifyf.c create mode 100644 libm/libmcs/libm/mathf/internal/gammaf.c create mode 100644 libm/libmcs/libm/mathf/internal/gammaf.h create mode 100644 libm/libmcs/libm/mathf/internal/log1pmff.h create mode 100644 libm/libmcs/libm/mathf/internal/signbitf.c create mode 100644 libm/libmcs/libm/mathf/internal/trigf.c create mode 100644 libm/libmcs/libm/mathf/internal/trigf.h create mode 100644 libm/libmcs/libm/mathf/ldexpf.c create mode 100644 libm/libmcs/libm/mathf/lgammaf.c create mode 100644 libm/libmcs/libm/mathf/llrintf.c create mode 100644 libm/libmcs/libm/mathf/llroundf.c create mode 100644 libm/libmcs/libm/mathf/log10f.c create mode 100644 libm/libmcs/libm/mathf/log1pf.c create mode 100644 libm/libmcs/libm/mathf/log2f.c create mode 100644 libm/libmcs/libm/mathf/logbf.c create mode 100644 libm/libmcs/libm/mathf/logf.c create mode 100644 libm/libmcs/libm/mathf/lrintf.c create mode 100644 libm/libmcs/libm/mathf/lroundf.c create mode 100644 libm/libmcs/libm/mathf/modff.c create mode 100644 libm/libmcs/libm/mathf/nanf.c create mode 100644 libm/libmcs/libm/mathf/nearbyintf.c create mode 100644 libm/libmcs/libm/mathf/nextafterf.c create mode 100644 libm/libmcs/libm/mathf/nexttowardf.c create mode 100644 libm/libmcs/libm/mathf/powf.c create mode 100644 libm/libmcs/libm/mathf/remainderf.c create mode 100644 libm/libmcs/libm/mathf/remquof.c create mode 100644 libm/libmcs/libm/mathf/rintf.c create mode 100644 libm/libmcs/libm/mathf/roundf.c create mode 100644 libm/libmcs/libm/mathf/scalblnf.c create mode 100644 libm/libmcs/libm/mathf/scalbnf.c create mode 100644 libm/libmcs/libm/mathf/sinf.c create mode 100644 libm/libmcs/libm/mathf/sinhf.c create mode 100644 libm/libmcs/libm/mathf/sqrtf.c create mode 100644 libm/libmcs/libm/mathf/tanf.c create mode 100644 libm/libmcs/libm/mathf/tanhf.c create mode 100644 libm/libmcs/libm/mathf/tgammaf.c create mode 100644 libm/libmcs/libm/mathf/truncf.c create mode 100644 libm/libmcs/libm/mathfe/internal/.gitkeep create mode 100644 libm/libmcs/libm/mathl/internal/.gitkeep create mode 100644 libm/libmcs/poetry.lock create mode 100644 libm/libmcs/pyproject.toml create mode 100644 libm/libmcs/sw-quality/au-misra3.lnt create mode 100644 libm/libmcs/sw-quality/co-gcc.h create mode 100644 libm/libmcs/sw-quality/co-gcc.lnt create mode 100644 libm/libmcs/sw-quality/co-gcc.mak create mode 100644 libm/libmcs/sw-quality/dummy_includes/config.h create mode 100644 libm/libmcs/sw-quality/gcc-include-path.lnt create mode 100755 libm/libmcs/sw-quality/lint.sh create mode 100644 libm/libmcs/sw-quality/lint_cmac.h create mode 100644 libm/libmcs/sw-quality/lint_cppmac.h create mode 100644 libm/libmcs/sw-quality/options.lnt create mode 100644 libm/libmcs/sw-quality/size-options.lnt create mode 100644 libm/libmcs/sw-quality/sqarg-config.toml create mode 100644 libm/libmcs/sw-quality/std.lnt diff --git a/libm/libmcs/.clang-format b/libm/libmcs/.clang-format new file mode 100644 index 00000000..3637168a --- /dev/null +++ b/libm/libmcs/.clang-format @@ -0,0 +1,3 @@ +--- +DisableFormat: true +--- diff --git a/libm/libmcs/.gitattributes b/libm/libmcs/.gitattributes new file mode 100644 index 00000000..06d51d28 --- /dev/null +++ b/libm/libmcs/.gitattributes @@ -0,0 +1,20 @@ +# -*- conf -*- + +## Set merge driver for ChangeLog files +# See gnulib's lib/git-merge-changelog.c (or git-merge-changelog(1)) +# for per-user setup instructions. +# +# The short version of this (optional) procedure is: +# +# (1) Install git-merge-changelog (this is the tricky part!) +# +# (2) Add something like the following to your ~/.gitconfig: +# +# [merge "merge-changelog"] +# name = GNU-style ChangeLog merge driver +# driver = git-merge-changelog %O %A %B +# +# (3) Enjoy mostly effortless ChangeLog merges, at least until the +# file gets renamed again ... + +ChangeLog merge=merge-changelog diff --git a/libm/libmcs/.gitignore b/libm/libmcs/.gitignore new file mode 100644 index 00000000..20b8bbbf --- /dev/null +++ b/libm/libmcs/.gitignore @@ -0,0 +1,54 @@ +*.diff +*.patch +*.orig +*.rej + +*~ +.#* +*# + +*.flt +*.gmo +*.info +*.la +*.lo +*.o +*.pyc +*.swp +*.tmp + +build* + +.deps +.libs + +autom4te.cache +config.cache +config.intl +config.log +config.status +libtool +POTFILES +*-POTFILES +user_make.mk +Makefile + +tags +TAGS +TAGS.sub + +.gdbinit +.gdb_history + +# ignore core files, but not java/net/protocol/core/ +core +!core/ + +lost+found +html_sdd/ +html_sum/ + +# SW Quality pipeline output +sw-quality/misra-c/* +report.json +*.log diff --git a/libm/libmcs/.gitlab-ci.yml b/libm/libmcs/.gitlab-ci.yml new file mode 100644 index 00000000..09321e5b --- /dev/null +++ b/libm/libmcs/.gitlab-ci.yml @@ -0,0 +1,102 @@ +stages: + - setup + - check + - doc + - pdf + - pages + +variables: + GIT_SUBMODULE_STRATEGY: recursive + +image: $CI_REGISTRY_IMAGE + +setup: + stage: setup + image: docker:stable + before_script: + - docker login -u $CI_REGISTRY_USER -p $CI_JOB_TOKEN $CI_REGISTRY + script: + - docker build -t $CI_REGISTRY_IMAGE -f Dockerfile . + - docker push $CI_REGISTRY_IMAGE + +mcdc-check: + stage: check + image: + name: registry.gitlab.com/gtd-gmbh/mcdc-checker/mcdc-checker + entrypoint: [""] + script: + - echo "#define __LIBMCS_WANT_COMPLEX" > ./libm/include/config.h + - find -regex ".*\.[ch]" | grep -v "lint\|tgmath.h\|fenv.h" | mcdc_checker -j report.json - + artifacts: + reports: + codequality: report.json + allow_failure: true + needs: [] + +code-quality: + stage: check + image: + name: local.gtd-gmbh.de:4567/tools/sqarg + entrypoint: [""] + script: + - ./sw-quality/lint.sh + artifacts: + reports: + codequality: sw-quality/misra-c/report.json + paths: + - sw-quality/misra-c/ + needs: [] + +doc: + stage: doc + script: + - sphinx-build -b html doc/sdd html_sdd 2>&1 | grep -v "duplicate label" | grep -v "documentation comment attached to unexpected cursor" + - sphinx-build -b html doc/sum html_sum 2>&1 | grep -v "duplicate label" | grep -v "documentation comment attached to unexpected cursor" + - sphinx-build -b latex doc/sdd latex_sdd 2>&1 | grep -v "duplicate label" | grep -v "documentation comment attached to unexpected cursor" + - sphinx-build -b latex doc/sum latex_sum 2>&1 | grep -v "duplicate label" | grep -v "documentation comment attached to unexpected cursor" + - chmod -R 777 latex_sdd + - chmod -R 777 latex_sum + artifacts: + paths: + - html_sdd/ + - html_sum/ + - latex_sdd/ + - latex_sum/ + expire_in: 30 days + needs: ["setup"] + +pdf: + stage: pdf + image: local.gtd-gmbh.de:4567/tools/doge:latest + dependencies: + - doc + script: + - cd latex_sdd + - make + - mv ./libmcs-sdd.pdf ../. + - cd ../latex_sum + - make + - mv ./libmcs-sum.pdf ../. + artifacts: + paths: + - ./*.pdf + expire_in: 30 days + needs: ["doc"] + +pages: + stage: pages + image: + name: pandoc/core:2.16.2 + entrypoint: [""] + dependencies: + - doc + needs: ["doc"] + script: + - mkdir public + - cp doc/index.html public + - pandoc -s -o public/README.html --metadata title="LibmCS Readme" --metadata mainfont="Lato,proxima-nova,Helvetica Neue,Arial,sans-serif" README.md + - mv html_sum public/sum + - mv html_sdd public/sdd + artifacts: + paths: + - public diff --git a/libm/libmcs/CITATION.cff b/libm/libmcs/CITATION.cff new file mode 100644 index 00000000..29c92cf1 --- /dev/null +++ b/libm/libmcs/CITATION.cff @@ -0,0 +1,74 @@ +cff-version: 1.2.0 +title: LibmCS +message: >- + If you use this software, please cite it using the + metadata from this file. +type: software +authors: + - name: GTD GmbH + address: Ravensburger Str. 32a + city: Markdorf + country: DE + post-code: '88677' + email: libmcs@gtd-gmbh.de + website: 'https://gtd-gmbh.de' + - name: ESA European Space Research and Technology Centre + address: Keplerlaan 1 + post-code: '2201' + city: Noordwijk + country: NL + website: 'https://www.esa.int' + - given-names: Fabian + family-names: Schriever + email: fabian.schriever@gtd-gmbh.de + affiliation: GTD GmbH + - given-names: Christoph + family-names: Weiß + email: christoph.weiss@gtd-gmbh.de + affiliation: GTD GmbH + - given-names: Thomas + family-names: Wucher + email: thomas.wucher@gtd-gmbh.de + affiliation: GTD GmbH + - given-names: Joan + family-names: Roig + email: joan.roig@gtd-gmbh.de + affiliation: GTD GmbH + - given-names: Andoni + family-names: Arregui + email: andoni.arregui@gtd-gmbh.de + affiliation: GTD GmbH + - given-names: Andreas + family-names: Jung + email: Andreas.Jung@esa.int + affiliation: ESA European Space Research and Technology Centre +identifiers: + - type: url + value: 'https://gtd-gmbh.gitlab.io/libmcs/' + description: LibmCS Documentation +repository-code: 'https://gitlab.com/gtd-gmbh/libmcs' +url: 'https://gtd-gmbh.de/libmcs/' +abstract: >- + The Mathematical Library for Critical Systems (LibmCS) is + an extensively tested and validated mathematical library + (libm), which provides predictable accuracy results in all + domains. The available wrappers give equal results for + auto-coding development approaches and the qualification + data package (QDP) supports an automatic qualification + according to ECSS E-ST-40 and Q-ST-80 Category B. +keywords: + - Mathematical Library + - POSIX + - IEEE-754 2019 + - ISO C18 + - MISRA-C 2012 + - ECSS E-ST-40 and Q-ST-80 Category B + - x86-64 + - ARM + - RISC-V + - SPARC V8 + - Critical Systems + - Embedded Systems +license: BSD-3-Clause +version: 1.2.0 +date-released: '2022-11-18' diff --git a/libm/libmcs/CONTRIBUTING.md b/libm/libmcs/CONTRIBUTING.md new file mode 100644 index 00000000..ebd59350 --- /dev/null +++ b/libm/libmcs/CONTRIBUTING.md @@ -0,0 +1,87 @@ +# Contributing to LibmCS + +## How Can I Contribute? + +### Reporting Bugs + +Report bugs by creating a GitLab issue with the following information: + +1. Give the Issue a meaningful title +2. Write a brief description of the issue you have +3. Describe the issue details answering the following questions: + - What are the steps to reproduce the *bug*? + - What is the current *bug* behavior? + - What is the expected *correct* behavior? + - Relevant logs/screenshots and/or associated data. + +We will pick up the issue and continue its workflow. + +### Suggesting Enhancements + +Suggest enhancements by creating a GitLab issue with the following information: + +1. Problem to solve +2. Proposed solution +3. Intended use-case + +### Pull Requests + +Contribute source code by following the next steps: + +1. Fork the repository +2. Create a branch with your code and/or documentation contribution: + - For the source code format please read the section [Styleguides](#styleguides). + - Corresponding source code documentation must be added + - All pipelines must pass +3. Create a merge request on the LibmCS repository + +We will pick up the merge request and continue its workflow. + +#### Styleguides + +To preformat the LibmCS sources we use Astyle. The concrete Astyle options we use are the following: + +```sh +> astyle --style=linux --indent=spaces=4 --break-blocks \ +--pad-oper --pad-comma --align-pointer=name --add-brackets \ +--convert-tabs --pad-header --unpad-paren \ +--indent-preproc-block --indent-preproc-define --max-code-length=99 +``` + +After running Astyle some further formatting may be carried out to adjust the overall readability. + +As an example you can take the `remquod.c` file in `libm/mathd`. There you +will see how the documentation is written and how the general source code +should look like. + +Here is an example `if` structure with comments: + +```c + /* purge off exception values */ + if ((hx >= 0x7ff00000) || (hy >= 0x7ff00000)) { /* x or y not finite */ + if (isnan(x) || isnan(y)) { /* x or y is NaN */ + return x + y; + } else if (hx == 0x7ff00000) { /* x is infinite */ + return __raise_invalid(); + } else { + /* No action required */ + } + } else if ((hy | ly) == 0) { /* y = 0 */ + return __raise_invalid(); + } else { + /* No action required */ + } +``` + +And here is a `for` loop: + +```c + /* 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; + } +``` diff --git a/libm/libmcs/COPYING.md b/libm/libmcs/COPYING.md new file mode 100644 index 00000000..d23eb122 --- /dev/null +++ b/libm/libmcs/COPYING.md @@ -0,0 +1,14 @@ +The LibmCS is provided under: + + SPDX-License-Identifier: GTDGmbH + +Being under the terms of the following licenses: + + LICENSES/NetBSD.md + LICENSES/PublicDomain.md + LICENSES/RedHat.md + LICENSES/RichFelker.md + LICENSES/SunMicrosystems.md + LICENSES/GTDGmbH.md + +All contributions to the LibmCS are subject to this COPYING file. diff --git a/libm/libmcs/CREDITS.md b/libm/libmcs/CREDITS.md new file mode 100644 index 00000000..dcc5ea85 --- /dev/null +++ b/libm/libmcs/CREDITS.md @@ -0,0 +1,66 @@ +This is at least a partial credits-file of people that have +contributed to the LibmCS project. + +It is sorted by name and formatted to allow easy grepping and +beautification by scripts. The fields are: name (N), email (E), +and description (D). + +Thanks, + +GTD GmbH + +N: Marco Atzeri; +E: marco.atzeri@gmail.com; +D: Integration of complex functions; + +N: Kito Cheng; +E: kito.cheng@sifive.com; +D: Misc fixes; + +N: Matthias Drochner; +E: drochner@NetBSD.org; +D: Some complex functions; + +N: Rich Felker; +E: -; +D: nexttowardf; + +N: Jeff Johnston; +E: jjohnston@redhat.com; +D: Misc fixes, tests, and contributions; + +N: Andreas Jung; +E: andreas.jung@esa.int; +D: Fixes, testing, and qualification to ECSS space software standards; + +N: Stephen L. Moshier; +E: drochner@NetBSD.org; +D: Complex functions (through Cephes -> NetBSD); + +N: Joseph Myers; +E: joseph@codesourcery.com; +D: Misc contributions; + +N: Kwok Choi Ng; +E: kwok.ng@sun.com; +D: Most double implementations of elementary transcendental functions (through FDLIBM); + +N: Keith Packard; +E: keithp@keithp.com; +D: Misc fixes and tests; + +N: Fabian Schriever; +E: fabian.schriever@gtd-gmbh.de; +D: Refactoring and qualification to ECSS space software standards; + +N: Joel Sherrill; +E: joel.sherrill@rtems.org; +D: Misc contributions; + +N: Ian Lance Taylor; +E: ian@cygnus.com; +D: Adapting double functions to float; + +N: Paul Zimmermann; +E: Paul.Zimmermann@inria.fr; +D: Misc contributions; diff --git a/libm/libmcs/Dockerfile b/libm/libmcs/Dockerfile new file mode 100644 index 00000000..7efe236e --- /dev/null +++ b/libm/libmcs/Dockerfile @@ -0,0 +1,20 @@ +FROM python:3.12-slim-bookworm + +# Install needed debian packages +RUN apt-get update \ + && DEBIAN_FRONTEND=noninteractive apt-get -yq --no-install-recommends install \ + sudo \ + clang \ + llvm \ + libclang-dev \ + && apt-get clean && rm -rf /var/lib/apt/lists/* + +# Add a default developer user +RUN useradd -m -G sudo developer \ + && echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers + +# Install dependencies +ADD pyproject.toml poetry.lock / +RUN pip install poetry && poetry config virtualenvs.create false && poetry install --no-root +# Open Links to GitLab in a new tab +RUN sed -i 's/fa-gitlab">/fa-gitlab" target="_blank">/' /usr/local/lib/python3.*/site-packages/sphinx_rtd_theme/breadcrumbs.html diff --git a/libm/libmcs/LICENSES/GTDGmbH.md b/libm/libmcs/LICENSES/GTDGmbH.md new file mode 100644 index 00000000..de0c589d --- /dev/null +++ b/libm/libmcs/LICENSES/GTDGmbH.md @@ -0,0 +1,27 @@ +Valid-License-Identifier: GTDGmbH +License-Text: + +Copyright (c) 2025 GTD GmbH. 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. The name of the company may not be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY GTD GMBH ``AS IS'' AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL GTD GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/libm/libmcs/LICENSES/NetBSD.md b/libm/libmcs/LICENSES/NetBSD.md new file mode 100644 index 00000000..3db18484 --- /dev/null +++ b/libm/libmcs/LICENSES/NetBSD.md @@ -0,0 +1,23 @@ +Valid-License-Identifier: NetBSD +License-Text: + +Redistribution and use in source and binary forms, 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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. \ No newline at end of file diff --git a/libm/libmcs/LICENSES/PublicDomain.md b/libm/libmcs/LICENSES/PublicDomain.md new file mode 100644 index 00000000..1b9e71a9 --- /dev/null +++ b/libm/libmcs/LICENSES/PublicDomain.md @@ -0,0 +1,4 @@ +Valid-License-Identifier: PublicDomain +License-Text: + +Public domain. \ No newline at end of file diff --git a/libm/libmcs/LICENSES/RedHat.md b/libm/libmcs/LICENSES/RedHat.md new file mode 100644 index 00000000..4b01484e --- /dev/null +++ b/libm/libmcs/LICENSES/RedHat.md @@ -0,0 +1,5 @@ +Valid-License-Identifier: RedHat +License-Text: + +Permission to use, copy, modify, and distribute this software +is freely granted, provided that this notice is preserved. diff --git a/libm/libmcs/LICENSES/RichFelker.md b/libm/libmcs/LICENSES/RichFelker.md new file mode 100644 index 00000000..b6c92a54 --- /dev/null +++ b/libm/libmcs/LICENSES/RichFelker.md @@ -0,0 +1,21 @@ +Valid-License-Identifier: RichFelker +License-Text: + +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. \ No newline at end of file diff --git a/libm/libmcs/LICENSES/SunMicrosystems.md b/libm/libmcs/LICENSES/SunMicrosystems.md new file mode 100644 index 00000000..adb04a34 --- /dev/null +++ b/libm/libmcs/LICENSES/SunMicrosystems.md @@ -0,0 +1,7 @@ +Valid-License-Identifier: SunMicrosystems +License-Text: + +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. \ No newline at end of file diff --git a/libm/libmcs/Makefile.in b/libm/libmcs/Makefile.in new file mode 100644 index 00000000..6bcdb1af --- /dev/null +++ b/libm/libmcs/Makefile.in @@ -0,0 +1,340 @@ +# SPDX-License-Identifier: GTDGmbH +# Copyright 2020-2025 by GTD GmbH. + +# SHELL := bash +# +# -include user_make.mk +# +# ifndef ARCH +# ARCH = $(shell $(CROSS_COMPILE)gcc -v 2>&1 | grep Target | cut -d' ' -f 2) +# endif +# +# CC = $(CROSS_COMPILE)gcc +# AR = $(CROSS_COMPILE)ar +# MKDIR = mkdir -p +# CP = cp +# MV = mv +# RM = rm -rf +# DATE = date +# WHICH = which +# SHA256 = sha256sum +# INFO_FILENAME = build_info.yml +# +# ifeq ($(V),1) +# Q = +# else +# Q = @ +# endif +# +# ifeq ($(V),2) +# Q = +# CC += -v -Wl,-v +# endif + +INCLUDE = -Ilibm/include -Ilibm/common -Ilibm/mathd/internal -Ilibm/mathf/internal + +SRC_LIBMCS = libm/complexd/cabsd.c \ + libm/complexd/cacosd.c \ + libm/complexd/cacoshd.c \ + libm/complexd/cargd.c \ + libm/complexd/casind.c \ + libm/complexd/casinhd.c \ + libm/complexd/catand.c \ + libm/complexd/catanhd.c \ + libm/complexd/ccosd.c \ + libm/complexd/ccoshd.c \ + libm/complexd/cexpd.c \ + libm/complexd/cimagd.c \ + libm/complexd/clogd.c \ + libm/complexd/conjd.c \ + libm/complexd/cpowd.c \ + libm/complexd/cprojd.c \ + libm/complexd/creald.c \ + libm/complexd/csind.c \ + libm/complexd/csinhd.c \ + libm/complexd/csqrtd.c \ + libm/complexd/ctand.c \ + libm/complexd/ctanhd.c \ + libm/complexd/internal/ctrigd.c \ + libm/complexf/cabsf.c \ + libm/complexf/cacosf.c \ + libm/complexf/cacoshf.c \ + libm/complexf/cargf.c \ + libm/complexf/casinf.c \ + libm/complexf/casinhf.c \ + libm/complexf/catanf.c \ + libm/complexf/catanhf.c \ + libm/complexf/ccosf.c \ + libm/complexf/ccoshf.c \ + libm/complexf/cexpf.c \ + libm/complexf/cimagf.c \ + libm/complexf/clogf.c \ + libm/complexf/conjf.c \ + libm/complexf/cpowf.c \ + libm/complexf/cprojf.c \ + libm/complexf/crealf.c \ + libm/complexf/csinf.c \ + libm/complexf/csinhf.c \ + libm/complexf/csqrtf.c \ + libm/complexf/ctanf.c \ + libm/complexf/ctanhf.c \ + libm/complexf/internal/ctrigf.c + +SRC_LIBMCS += libm/common/signgam.c \ + libm/common/tools.c \ + libm/mathd/acosd.c \ + libm/mathd/acoshd.c \ + libm/mathd/asind.c \ + libm/mathd/asinhd.c \ + libm/mathd/atan2d.c \ + libm/mathd/atand.c \ + libm/mathd/atanhd.c \ + libm/mathd/cbrtd.c \ + libm/mathd/ceild.c \ + libm/mathd/copysignd.c \ + libm/mathd/cosd.c \ + libm/mathd/coshd.c \ + libm/mathd/erfcd.c \ + libm/mathd/erfd.c \ + libm/mathd/exp2d.c \ + libm/mathd/expd.c \ + libm/mathd/expm1d.c \ + libm/mathd/fabsd.c \ + libm/mathd/fdimd.c \ + libm/mathd/floord.c \ + libm/mathd/fmad.c \ + libm/mathd/fmaxd.c \ + libm/mathd/fmind.c \ + libm/mathd/fmodd.c \ + libm/mathd/frexpd.c \ + libm/mathd/hypotd.c \ + libm/mathd/ilogbd.c \ + libm/mathd/internal/fpclassifyd.c \ + libm/mathd/internal/gammad.c \ + libm/mathd/internal/signbitd.c \ + libm/mathd/internal/trigd.c \ + libm/mathd/j0d.c \ + libm/mathd/j1d.c \ + libm/mathd/jnd.c \ + libm/mathd/ldexpd.c \ + libm/mathd/lgammad.c \ + libm/mathd/llrintd.c \ + libm/mathd/llroundd.c \ + libm/mathd/log10d.c \ + libm/mathd/log1pd.c \ + libm/mathd/log2d.c \ + libm/mathd/logbd.c \ + libm/mathd/logd.c \ + libm/mathd/lrintd.c \ + libm/mathd/lroundd.c \ + libm/mathd/modfd.c \ + libm/mathd/nand.c \ + libm/mathd/nearbyintd.c \ + libm/mathd/nextafterd.c \ + libm/mathd/nexttowardd.c \ + libm/mathd/powd.c \ + libm/mathd/remainderd.c \ + libm/mathd/remquod.c \ + libm/mathd/rintd.c \ + libm/mathd/roundd.c \ + libm/mathd/scalblnd.c \ + libm/mathd/scalbnd.c \ + libm/mathd/sind.c \ + libm/mathd/sinhd.c \ + libm/mathd/sqrtd.c \ + libm/mathd/tand.c \ + libm/mathd/tanhd.c \ + libm/mathd/tgammad.c \ + libm/mathd/truncd.c \ + libm/mathd/y0d.c \ + libm/mathd/y1d.c \ + libm/mathd/ynd.c \ + libm/mathf/acosf.c \ + libm/mathf/acoshf.c \ + libm/mathf/asinf.c \ + libm/mathf/asinhf.c \ + libm/mathf/atan2f.c \ + libm/mathf/atanf.c \ + libm/mathf/atanhf.c \ + libm/mathf/cbrtf.c \ + libm/mathf/ceilf.c \ + libm/mathf/copysignf.c \ + libm/mathf/cosf.c \ + libm/mathf/coshf.c \ + libm/mathf/erfcf.c \ + libm/mathf/erff.c \ + libm/mathf/exp2f.c \ + libm/mathf/expf.c \ + libm/mathf/expm1f.c \ + libm/mathf/fabsf.c \ + libm/mathf/fdimf.c \ + libm/mathf/floorf.c \ + libm/mathf/fmaf.c \ + libm/mathf/fmaxf.c \ + libm/mathf/fminf.c \ + libm/mathf/fmodf.c \ + libm/mathf/frexpf.c \ + libm/mathf/hypotf.c \ + libm/mathf/ilogbf.c \ + libm/mathf/internal/fpclassifyf.c \ + libm/mathf/internal/gammaf.c \ + libm/mathf/internal/signbitf.c \ + libm/mathf/internal/trigf.c \ + libm/mathf/ldexpf.c \ + libm/mathf/lgammaf.c \ + libm/mathf/llrintf.c \ + libm/mathf/llroundf.c \ + libm/mathf/log10f.c \ + libm/mathf/log1pf.c \ + libm/mathf/log2f.c \ + libm/mathf/logbf.c \ + libm/mathf/logf.c \ + libm/mathf/lrintf.c \ + libm/mathf/lroundf.c \ + libm/mathf/modff.c \ + libm/mathf/nanf.c \ + libm/mathf/nearbyintf.c \ + libm/mathf/nextafterf.c \ + libm/mathf/nexttowardf.c \ + libm/mathf/powf.c \ + libm/mathf/remainderf.c \ + libm/mathf/remquof.c \ + libm/mathf/rintf.c \ + libm/mathf/roundf.c \ + libm/mathf/scalblnf.c \ + libm/mathf/scalbnf.c \ + libm/mathf/sinf.c \ + libm/mathf/sinhf.c \ + libm/mathf/sqrtf.c \ + libm/mathf/tanf.c \ + libm/mathf/tanhf.c \ + libm/mathf/tgammaf.c \ + libm/mathf/truncf.c + +ifeq ($(WANT_COMPLEX),1) + SRC += $(CSRC) + EXTRA_CFLAGS += -DLIBMCS_WANT_COMPLEX +endif + +# SRC_ROOT = . +# SRC_DIRS = $(sort $(dir $(SRC))) + +# BUILD_ROOT = build-$(ARCH) +# +# BUILD_INFO = $(BUILD_ROOT)/$(INFO_FILENAME) +# +# OBJ_ROOT = $(BUILD_ROOT)/obj +# OBJ_DIRS = $(addprefix $(OBJ_ROOT)/,$(SRC_DIRS)) +# +# BIN_DIR = $(BUILD_ROOT)/bin +# +# OUT = $(BIN_DIR)/libm.a + +CFLAGS += -Wall -std=c99 -pedantic -Wextra +CFLAGS += -Wstrict-prototypes +CFLAGS += -frounding-math -fsignaling-nans -g3 -O2 -fno-builtin $(EXTRA_CFLAGS) + +# ifndef COVERAGE +# COVERAGE=0 +# endif + +# ifeq ($(COVERAGE),1) +# CFLAGS +=-O0 -fprofile-arcs -ftest-coverage +# GCCVERSIONGTEQ14 := $(shell expr `$(CC) -dumpversion | cut -f1 -d.` \>= 14) +# ifeq "$(GCCVERSIONGTEQ14)" "1" +# CFLAGS += -fcondition-coverage +# endif +# endif + +# OBJ = $(addprefix $(OBJ_ROOT)/, $(SRC:.c=.o)) +# +# .SUFFIXES: +# .SUFFIXES: .o .c +# +# .PHONY: all debug release clean cleanall distclean install check_config help +# all: $(OUT) $(BUILD_INFO) +# @echo "[CP] include" +# $(Q)$(CP) -r $(SRC_ROOT)/libm/include/ $(BUILD_ROOT)/include/ +# +# check_config: +# @[ "1" == "$(CONFIGURE_SUCCESS)" ] || (echo "Either configuration was faulty or not done, please run configure" && exit 1) +# +# $(BUILD_INFO): $(OUT) +# @echo "[LOG] $(BUILD_INFO)" +# @echo "---" > $(BUILD_INFO) +# @printf "date: " >> $(BUILD_INFO) +# $(Q)$(DATE) +"%Y-%m-%dT%H:%M:%S%z" >> $(BUILD_INFO) +# @printf "compiler_path: " >> $(BUILD_INFO) +# $(Q)$(WHICH) $(CC) >> $(BUILD_INFO) +# @echo "compiler_information: |" >> $(BUILD_INFO) +# $(Q)$(CC) -v 2>&1 | sed 's/^/ /' >> $(BUILD_INFO) +# @echo "binutils_information: |" >> $(BUILD_INFO) +# $(Q)$(AR) -V 2>&1 | sed 's/^/ /' >> $(BUILD_INFO) +# @echo "cflags_and_include: $(CFLAGS) $(CFLAGS_TARGET) $(INCLUDE)" >> $(BUILD_INFO) +# @echo "git_info:" >> $(BUILD_INFO) +# @printf " branch: " >> $(BUILD_INFO) +# $(Q)(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "-") >> $(BUILD_INFO) +# @printf " commit: " >> $(BUILD_INFO) +# $(Q)(git rev-parse HEAD 2>/dev/null || echo "-") >> $(BUILD_INFO) +# @printf " dirty: " >> $(BUILD_INFO) +# $(Q)((git diff --exit-code > /dev/null 2>&1 && echo "no") || ([ $$? -eq 1 ] && echo "yes") || echo "-") >> $(BUILD_INFO) +# @printf "libm_sha256: " >> $(BUILD_INFO) +# $(Q)echo `$(SHA256) $(OUT) | head -c 64` >> $(BUILD_INFO) +# @echo "..." >> $(BUILD_INFO) +# +# # Include dependency info for *existing* .o files +# -include $(OBJ:.o=.d) +# +# $(OUT): $(OBJ) | check_config $(BIN_DIR) +# @echo "[AR] $@" +# $(Q)$(AR) -scr $@ $? +# +# $(OBJ_ROOT)/%.o: $(SRC_ROOT)/%.c | check_config $(OBJ_DIRS) +# @echo "[CC] $< > $@" +# $(Q)$(CC) $(CFLAGS) $(CFLAGS_TARGET) $(INCLUDE) -MD -MP $< -o $@ +# +# $(OBJ_DIRS) $(BIN_DIR): check_config +# @echo "[MKDIR] $@" +# $(Q)$(MKDIR) $@ +# +# debug: all +# +# release: CFLAGS += -DNDEBUG +# release: all +# +# clean: +# @echo "[RM] $(BUILD_ROOT)" +# $(Q)$(RM) $(BUILD_ROOT) +# +# cleanall: +# @echo "[RM] build-*" +# $(Q)$(RM) build-* +# +# distclean: cleanall +# @echo "[RM] user_make.mk" +# $(Q)$(RM) user_make.mk +# @echo "[RM] config.h" +# $(Q)$(RM) libm/include/config.h +# $(Q)$(RM) sizeoftypes.c +# $(Q)$(RM) sizeoftypes.o +# $(Q)$(RM) Makefile +# +# install: +# @echo "LibmCS cannot be installed." +# +# help: +# @echo "LibmCS make has the following targets:" +# @echo " all:" +# @echo " Builds the library. This is the default target." +# @echo " debug:" +# @echo " Builds the library. Currently equivalent to 'all'." +# @echo " release:" +# @echo " Builds the library. Equivalent to 'all' with the additional flag '-DNDEBUG' set." +# @echo " clean:" +# @echo " Removes the build directory of the library of the current ARCH. (ARCH can be set" +# @echo " manually or is extracted from using the compiler)" +# @echo " cleanall:" +# @echo " Removes all build directories of the library." +# @echo " distclean:" +# @echo " Removes all files created by 'configure' and all builds." +# \ No newline at end of file diff --git a/libm/libmcs/README.md b/libm/libmcs/README.md new file mode 100644 index 00000000..8d4200fd --- /dev/null +++ b/libm/libmcs/README.md @@ -0,0 +1,117 @@ +# LibmCS + +This is the mathematical library for critical systems (LibmCS). + +It has been developed in compliance with the European Cooperation for Space Standardization (ECSS) standards E-ST-40 and Q-ST-80 to criticality Category B and it is also compliant to the standards: + +- IEEE-754, +- C18, +- POSIX, and +- MISRA C + +The library has been developed by GTD GmbH under the ESA Contract No. 4000130278/20/NL/AS. + +The copyright and licensing condition of the library can be found in the COPYING.md file. + + +## Getting Started + +### Documentation Entry Point + +If you are a software architect interested in assessing the possibility to include the LibmCS in your software project you may start reading the: + +- Software Release Document (OR-SRelD.00-ML) + +If you are a software product assurance engineer interested in the aspects for the delta-qualification of the LibmCS for your specific project you may start reading the: + +- Qualification Guideline (OP-QG.00-ML) + +If you are a software engineer interested in using the library in your software project you can continue reading the following section and taking a look at the Software User Manual available in this repository. + +*Note*: The OR-SRelD.00-ML and OP-QG.00-ML documents are accessible through the [ESA ESSR (European Space Software Repository)](https://essr.esa.int/) site, which is accessible to all ESA member states (search this site for LibmCS). The documents and the qualification-kit can also be obtained through GTD GmbH (contact libmcs@gtd-gmbh.de). + +### Programmer's Entry Point + +To start using the LibmCS in your software project you can clone this repository and start configuring and compiling the library: + +``` +> ./configure +> make +``` + +#### Using Configure With Flags + +For CI and similar activities it can be useful to not use an interactive script for the configuration as such it is also possible to call `configure` with flags which answer the questions otherwise asked interactively (if only some flags are set, the remaining questions will still be asked). The following flags can be set: + +| Configure Flag | Description | +|------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `--cross-compile ` | Tells `make` which toolchain to use. | +| `--compilation-flags ` | Used do define additional flags to the compiler. Takes both user and library specific flags/defines, e.g. `-mcpu=...`. | +| `--enable-denormal-handling` | The library will assume the platform does not provide denormals and use the platform to convert denormal inputs/outputs to 0. | +| `--disable-denormal-handling` | The library will assume the platform does provide denormals properly. | +| `--enable-long-double-procedures` | Should be set if the size of `long double` is 64 bit and the procedures shall be provided. | +| `--disable-long-double-procedures` | Should be set if the size of `long double` is not 64 bit or the procedures shall not be provided. If this is set, the library will not have `long double` procedures built. | +| `--enable-complex-procedures` | If this is set complex procedures are available. | +| `--disable-complex-procedures` | If this is set the library will not have complex procedures built. | +| `--big-endian` | Tells the compilation that variables are in big endian. | +| `--little-endian` | Tells the compilation that variables are in little endian. | + +Of special note here is also that the library needs to know which endianness the platform uses (big endian for SPARC processors and little usually for the rest). Most compilers use the define `__BYTE_ORDER__` with either `__ORDER_BIG_ENDIAN__` or `__ORDER_LITTLE_ENDIAN__` set, but if your toolchain does not provide this define you have to do it yourself (e.g. the EDISOFT RTEMS does not). + +##### Some Examples + +1. For a LEON2 processor and the EDISOFT RTEMS 4.8 tool-chain, without `long double` functions nor complex functions, the configuration would look like this: + +``` +> ./configure --cross-compile /opt/rtems-4.8/bin/sparc-rtems4.8- --compilation-flags "-mcpu=leon" --enable-denormal-handling --disable-long-double-procedures --disable-complex-procedures --big-endian +``` + +2. For a LEON3/LEON4 processor and an OAR RTEMS 4.11 tool-chain, without `long double` functions nor complex functions, the configuration would look like this: + +``` +> ./configure --cross-compile /opt/rtems-4.11-2016.04.01.FPU/bin/sparc-rtems4.11- --compilation-flags "-mcpu=leon3" --disable-denormal-handling --disable-long-double-procedures --disable-complex-procedures --big-endian +``` + +3. For an ARM R52 processor and a certain GCC cross compiler, without `long double` functions nor complex functions, the configuration would look like this: + +``` +> ./configure --cross-compile --compilation-flags "-mcpu=cortex-r52" --enable-denormal-handling --disable-long-double-procedures --disable-complex-procedures --little-endian +``` + +4. For a LEON3/LEON4 processor and an RTEMS 6 UNI/SMP tool-chain, without `long double` functions nor complex functions, the configuration would look like this: + +``` +> ./configure --cross-compile /opt/rtems/rtems-6-sparc-gr712rc-smp-6/bin/sparc-rtems6- --compilation-flags "-mcpu=leon3" --disable-denormal-handling --disable-long-double-procedures --disable-complex-procedures --big-endian +``` + + +#### Test Coverage + +Test coverage is not set using `configure`, it can be enabled by adding `COVERAGE=1` to the `make` call. Note that `configure` still has to be run first before `make` also for this case. + +#### Make Targets + +| Make Target | Description | +|-------------|------------------------------------------------------------------------------------------------------------------------------------| +| `all` | Builds the library. This is the default target. | +| `debug` | Builds the library. Currently equivalent to `all`. | +| `release` | Builds the library. Equivalent to `all` with the additional flag `-DNDEBUG` set. | +| `clean` | Removes the build directory of the library of the current ARCH. (ARCH can be set manually or is extracted from using the compiler) | +| `cleanall` | Removes all build directories of the library. | +| `distclean` | Removes all files created by 'configure' and all builds. | + +Note: LibmCS does not have an `install` target. + +#### Using Hardware Instructions + +To replace LibmCS procedures with custom procedures, such as hardware instruction calling procedures (e.g., using the CPU hardware implementation of procedures such as square root), several steps need to be followed: + ++ Add the file containing the procedure into an architecture specific sub-directory within the `libm/machine` directory. If the directory does not exist, make one for your architecture. An example for this step has already been added to the library for the SPARC V8 architecture. ++ Replace the file you want to replace in the `Makefile.in`. As an example for this step check the branch `makefile-sparc-v8-hardware-sqrt` where this is done for the SPARC V8 `sqrt` procedure. + +Note that replacing procedures may cause different results and in turn may cause unit tests to fail. You will have to justify those fails, or change the respective tests and justify that change. + + +## How to Contribute + +To learn how to contribute to the LibmCS please read the CONTRIBUTING.md file. diff --git a/libm/libmcs/configure b/libm/libmcs/configure new file mode 100755 index 00000000..8f407b29 --- /dev/null +++ b/libm/libmcs/configure @@ -0,0 +1,261 @@ +#!/usr/bin/env bash +# shellcheck disable=all +# SPDX-License-Identifier: GTDGmbH +# Copyright 2020-2025 by GTD GmbH. + +pwd + +# Filenames +sizecheck=libm/libmcs/sizeoftypes.c +user_make=libm/libmcs/user_make.mk +user_config=libm/libmcs/libm/include/config.h +makefile_in=libm/libmcs/Makefile.in +makefile_out=libm/generated_make.mk + +usage() +{ + echo "Usage: configure [--help] [ --cross-compile CROSS_COMPILE ] [ --compilation-flags CFLAGS ] [ --enable-denormal-handling ] [ --disable-denormal-handling ] [ --enable-long-double-procedures ] [ --disable-long-double-procedures ] [ --enable-complex-procedures ] [ --disable-complex-procedures ] [ --big-endian ] [ --little-endian ]" + exit 2 +} + +help_message() +{ + echo "Usage: configure [--help] [ --cross-compile CROSS_COMPILE ] [ --compilation-flags CFLAGS ] [ --enable-denormal-handling ] [ --disable-denormal-handling ] [ --enable-long-double-procedures ] [ --disable-long-double-procedures ] [ --enable-complex-procedures ] [ --disable-complex-procedures ] [ --big-endian ] [ --little-endian ]" + echo "" + echo "This configuration file offers the following flags to directly answer the" + echo "questions otherwise asked within:" + echo " --cross-compile " + echo " Tells the Makefile which toolchain suffix to use for the compilation," + echo " linking, etc. For example 'sparc-rtems-'." + echo " --compilation-flags " + echo " Adds additional flags to the compilation. For example '-mlong-double-64'" + echo " to get 64 bit long doubles on x86 targets using gcc." + echo " --enable-denormal-handling" + echo " --disable-denormal-handling" + echo " Enables/Disables the use of DAZ/FTZ mode for handling denormal numbers." + echo " This hingly depends on the user's hardware, so please check whether your" + echo " platform supports/requires the use of DAZ/FTZ." + echo " --enable-long-double-procedures" + echo " --disable-long-double-procedures" + echo " Enables/Disables the compilation of long double procedures. Disabling" + echo " them causes the Makefile to not build long double procedures into the" + echo " libm. Long double procedures can only be enabled if the platform supports" + echo " and is configured with long double with a size of 64bit." + echo " --enable-complex-procedures" + echo " --disable-complex-procedures" + echo " Enables/Disables the compilation of complex procedures. Disabling them" + echo " causes the Makefile to not build complex procedures into the libm" + echo " (everything that is usually included with complex.h)." + echo " --big-endian" + echo " --little-endian" + echo " Manually inform the compiler which endianess the platform uses. This" + echo " question only needs to be answered if the toolchain compiler does not" + echo " provide the answer itself." + exit 2 +} + +PARSED_ARGUMENTS=$(getopt -a -n configure -o h --long help,cross-compile:,compilation-flags:,enable-denormal-handling,disable-denormal-handling,enable-long-double-procedures,disable-long-double-procedures,enable-complex-procedures,disable-complex-procedures,big-endian,little-endian -- "$@") +VALID_ARGUMENTS=$? +if [ "$VALID_ARGUMENTS" != "0" ]; then + usage +fi + +echo "Arguments are: $PARSED_ARGUMENTS" +eval set -- "$PARSED_ARGUMENTS" +while : +do + case "$1" in + -h) help_message ;; + --help) help_message ;; + --cross-compile) CROSS_COMPILE="$2" ; shift 2 ;; + --compilation-flags) extra_cflags="$2" ; shift 2 ;; + --enable-denormal-handling) WANT_DAZ=1 ; shift ;; + --disable-denormal-handling) WANT_DAZ=0 ; shift ;; + --enable-long-double-procedures) WANT_LD=1 ; shift ;; + --disable-long-double-procedures) WANT_LD=0 ; shift ;; + --enable-complex-procedures) WANT_COMPLEX=1 ; shift ;; + --disable-complex-procedures) WANT_COMPLEX=0 ; shift ;; + --big-endian) BIG_ENDIAN=1 ; shift ;; + --little-endian) BIG_ENDIAN=0 ; shift ;; + --) shift ; break ;; + *) echo "Unexpected option: $1" + usage ;; + esac +done + +# Delete old files created by configure if there are any +[ -f "${user_make}" ] && rm ${user_make} +[ -f "${user_config}" ] && rm ${user_config} +[ -f "${makefile_out}" ] && rm ${makefile_out} + +# Create .c file to check type sizes +echo "Creating minimal .c file to check type sizes." +printf "double d_data[16];\\nlong double l_data[16];\\nlong int li_data[16];\\n" > ${sizecheck} + +# Ask user for toolchain +if [ -z ${CROSS_COMPILE+x} ]; then echo "Please enter the path to your compiler toolchain including prefix (e.g. /opt/rtems-4.11/bin/sparc-rtems-), leave empty if compiling on & for host:"; fi +while true +do + if [ -z ${CROSS_COMPILE+x} ]; then read -r CROSS_COMPILE; fi + CC=${CROSS_COMPILE}gcc + CC_version=$($CC --version) + if [[ "$CC_version" == "" ]]; then + echo "No compiler found at specified location. Try entering path+prefix of your toolchain again:" + read -r CROSS_COMPILE + else + break + fi +done +echo "Found compiler:" +echo "${CC_version}" + +# Ask for CFLAGS +if [ -z ${extra_cflags+x} ]; then echo "Please enter additional compiler flags (e.g. -mlong-double-64):"; fi +while true +do + if [ -z ${extra_cflags+x} ]; then read -r extra_cflags; fi + if $($CC -c ${sizecheck} ${extra_cflags}); then + break + else + echo "Your compiler did not recognise all your flags. Try again:" + read -r extra_cflags + fi +done + +# Ask user for DAZ/FTZ +if [ -z ${WANT_DAZ+x} ]; then + echo "Does your platform by default use, or is configured to use, DAZ/FTZ (Denormals Are Zero / Flush To Zero) mode (e.g. your platform has an older GRFPU which does not support subnormals)?" + select yn in "Yes" "No"; do + case $yn in + Yes ) WANT_DAZ=1; extra_cflags="${extra_cflags} -DLIBMCS_FPU_DAZ"; break;; + No ) WANT_DAZ=0; break;; + esac + done +elif [ ${WANT_DAZ} -eq 1 ]; then + extra_cflags="${extra_cflags} -DLIBMCS_FPU_DAZ"; +fi + +# Build and run type sizes check to assign defines +echo "Build and run type sizes check to assign defines." +$CC -c ${sizecheck} ${extra_cflags} +long_int_size=$("${CROSS_COMPILE}"nm -S -t d ${sizecheck%.*}.o | grep "li_data" | awk '{print $2/16*8}') +if [ "$long_int_size" -eq "32" ]; then + extra_cflags="${extra_cflags} -DLIBMCS_LONG_IS_32BITS"; + echo "Found long int to be 32bit."; + LONG_INT_32=1; +else + LONG_INT_32=0; +fi +double_size=$("${CROSS_COMPILE}"nm -S -t d ${sizecheck%.*}.o | grep "d_data" | awk '{print $2/16*8}') +if [ "$double_size" -eq "32" ]; then + extra_cflags="${extra_cflags} -DLIBMCS_DOUBLE_IS_32BITS"; + echo "Found double to be 32bit."; + DOUBLE_32=1; + WANT_LD=0; +else + DOUBLE_32=0; + long_double_size=$("${CROSS_COMPILE}"nm -S -t d ${sizecheck%.*}.o | grep "l_data" | awk '{print $2/16*8}') + if [ "$long_double_size" -eq "64" ]; then + echo "Found long double to be 64bit."; + if [ -z ${WANT_LD+x} ]; then + echo "Do you want long double procedures? If 'No' is chosen long double procedures will not be compiled into the library, and will not need to be qualified."; + select yn in "Yes" "No"; do + case $yn in + Yes ) WANT_LD=1; extra_cflags="${extra_cflags} -DLIBMCS_LONG_DOUBLE_IS_64BITS"; break;; + No ) WANT_LD=0; break;; + esac + done + elif [ ${WANT_LD} -eq 1 ]; then + extra_cflags="${extra_cflags} -DLIBMCS_LONG_DOUBLE_IS_64BITS"; + fi + else + echo "Found long double to be not 64bit. The library will not have long double procedures."; + WANT_LD=0; + fi +fi + +# Check toolchain for endianness +echo "Check toolchain for endianness." +endianness=$($CC -dM -E ${extra_cflags} - < /dev/null | grep "__BYTE_ORDER__" | awk '{print $3}') +if [ "$endianness" != "__ORDER_LITTLE_ENDIAN__" ] && [ "$endianness" != "__ORDER_BIG_ENDIAN__" ] ; then + if [ -z ${BIG_ENDIAN+x} ]; then + echo "Your toolchain does not define endianness (__BYTE_ORDER__ is not defined as either __ORDER_BIG_ENDIAN__ or __ORDER_LITTLE_ENDIAN__). Which endianness is appropriate for your target platform (e.g. SPARCs are usually Big Endian)?"; + select endian in "Little Endian" "Big Endian"; do + case $endian in + "Little Endian" ) BIG_ENDIAN=0; extra_cflags="${extra_cflags} -D__BYTE_ORDER__=__ORDER_LITTLE_ENDIAN__"; break;; + "Big Endian" ) BIG_ENDIAN=1; extra_cflags="${extra_cflags} -D__BYTE_ORDER__=__ORDER_BIG_ENDIAN__"; break;; + esac + done + elif [ ${BIG_ENDIAN} -eq 1 ]; then + extra_cflags="${extra_cflags} -D__BYTE_ORDER__=__ORDER_BIG_ENDIAN__" + elif [ ${BIG_ENDIAN} -eq 0 ]; then + extra_cflags="${extra_cflags} -D__BYTE_ORDER__=__ORDER_LITTLE_ENDIAN__" + fi +else + echo "Found endianness to be ${endianness}."; +fi + +# Create configuration Makefile +echo "Creating configuration Makefile." +{ echo "ifndef CROSS_COMPILE"; +echo " CROSS_COMPILE = ${CROSS_COMPILE}"; +echo "endif"; +echo "EXTRA_CFLAGS += ${extra_cflags}"; } > ${user_make} +echo "Added the following extra compilation flags to make: ${extra_cflags}" + +# Ask user for complex procedures +if [ -z ${WANT_COMPLEX+x} ]; then + echo "Do you want complex procedures? If 'No' is chosen complex procedures will not be compiled into the library, and will not need to be qualified." + select yn in "Yes" "No"; do + case $yn in + Yes ) WANT_COMPLEX=1; echo "WANT_COMPLEX = 1" >> ${user_make}; echo "See user manual (SUM) for the limitations and inaccuracies in complex procedures!"; break;; + No ) WANT_COMPLEX=0; echo "WANT_COMPLEX = 0" >> ${user_make}; break;; + esac + done +elif [ ${WANT_COMPLEX} -eq 1 ]; then + echo "WANT_COMPLEX = 1" >> ${user_make} + echo "See user manual (SUM) for the limitations and inaccuracies in complex procedures!" +elif [ ${WANT_COMPLEX} -eq 0 ]; then + echo "WANT_COMPLEX = 0" >> ${user_make} +fi + +# Create config.h +printf "/* SPDX-License-Identifier: GTDGmbH */\\n/* Copyright 2020-2022 by GTD GmbH. */\\n" > ${user_config} +printf "\\n#ifndef LIBMCS_CONFIG_H\\n#define LIBMCS_CONFIG_H\\n\\n" >> ${user_config} +if [ ${WANT_DAZ} -eq 1 ]; then + printf "#ifndef LIBMCS_FPU_DAZ\\n #define LIBMCS_FPU_DAZ\\n#endif /* !LIBMCS_FPU_DAZ */\\n" >> ${user_config} +else + printf "#ifdef LIBMCS_FPU_DAZ\\n #undef LIBMCS_FPU_DAZ\\n#endif /* LIBMCS_FPU_DAZ */\\n" >> ${user_config} +fi +if [ ${LONG_INT_32} -eq 1 ]; then + printf "#ifndef LIBMCS_LONG_IS_32BITS\\n #define LIBMCS_LONG_IS_32BITS\\n#endif /* !LIBMCS_LONG_IS_32BITS */\\n" >> ${user_config} +fi +if [ ${DOUBLE_32} -eq 1 ]; then + printf "#ifndef LIBMCS_DOUBLE_IS_32BITS\\n #define LIBMCS_DOUBLE_IS_32BITS\\n#endif /* !LIBMCS_DOUBLE_IS_32BITS */\\n" >> ${user_config} +fi +if [ ${WANT_LD} -eq 1 ]; then + printf "#ifndef LIBMCS_LONG_DOUBLE_IS_64BITS\\n #define LIBMCS_LONG_DOUBLE_IS_64BITS\\n#endif /* !LIBMCS_LONG_DOUBLE_IS_64BITS */\\n" >> ${user_config} +else + printf "#ifdef LIBMCS_LONG_DOUBLE_IS_64BITS\\n #undef LIBMCS_LONG_DOUBLE_IS_64BITS\\n#endif /* LIBMCS_LONG_DOUBLE_IS_64BITS */\\n" >> ${user_config} +fi +if [ ${WANT_COMPLEX} -eq 1 ]; then + printf "#ifndef LIBMCS_WANT_COMPLEX\\n #define LIBMCS_WANT_COMPLEX\\n#endif /* !LIBMCS_WANT_COMPLEX */\\n" >> ${user_config} +else + printf "#ifdef LIBMCS_WANT_COMPLEX\\n #undef LIBMCS_WANT_COMPLEX\\n#endif /* LIBMCS_WANT_COMPLEX */\\n" >> ${user_config} +fi +if ! [ -z ${BIG_ENDIAN+x} ]; then + printf "#ifndef __BYTE_ORDER__\\n" >> ${user_config} + if [ ${BIG_ENDIAN} -eq 1 ]; then + printf " #define __BYTE_ORDER__ __ORDER_BIG_ENDIAN__\\n" >> ${user_config} + else + printf " #define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__\\n" >> ${user_config} + fi + printf "#endif /* __BYTE_ORDER__ */\\n" >> ${user_config} +fi +printf "\\n#endif /* !LIBMCS_CONFIG_H */\\n" >> ${user_config} + +# Cleanup +rm ${sizecheck} +rm ${sizecheck%.*}.o +echo "CONFIGURE_SUCCESS = 1" >> ${user_make} +cp ${makefile_in} ${makefile_out} diff --git a/libm/libmcs/doc/_static/css/custom.css b/libm/libmcs/doc/_static/css/custom.css new file mode 100644 index 00000000..63a143b0 --- /dev/null +++ b/libm/libmcs/doc/_static/css/custom.css @@ -0,0 +1,66 @@ +.wy-nav-content { + max-width: 1200px !important; +} + +.wy-side-nav-search { + background-color: #80a2b4; +} + +.wy-side-nav-search a { + color: #404040; +} + +.wy-side-nav-search a:visited { + color: #404040; +} + +.wy-side-nav-search input[type=text] { + border-color: #536974; +} + +a { + color: #6e8b9a; +} + +a:visited { + color: #b49d80; +} + +a:hover { + color: #536974; +} + +.wy-menu-vertical a:active { + color: #404040 !important; + background-color: #d9d9d9; +} + +.wy-menu-vertical a:hover { + color: #404040 !important; + background-color: #d9d9d9 !important; +} + +.wy-menu-vertical li.toctree-l1 a { + font-weight: bold; +} + +.wy-menu-vertical li.toctree-l1 a:visited { + color: #d9d9d9; +} + +.wy-menu-vertical li.toctree-l1 a:hover { + color: #d9d9d9; +} + +.wy-menu-vertical li.current a:visited { + color: #404040; +} + +.wy-menu-vertical li.current a:hover { + color: #404040; +} + +.rst-content dl:not(.docutils) dt { + color: #536974; + border-top: solid 3px #536974; +} diff --git a/libm/libmcs/doc/figure/libmcs-complex.png b/libm/libmcs/doc/figure/libmcs-complex.png new file mode 100644 index 0000000000000000000000000000000000000000..850cab431cb55cc5bfd7fe1d9823a0356f3f0432 GIT binary patch literal 18554 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 {eK`W`EN{qo}tEo1Bj=a87fD5K_JBxf@r)l zU|q_Czm&~i!w21_1vUM_%>w~h2*d<{IYzp=PQ#T4*Y`or$J{~C0xVPVVej7nzQ^vr z_HnNZDbqo@y(z>Dxm_)V0k`PErQ75~knjd7WfyZxXA xxn{-=aSjiMgVq+mHxB$?BZQ#ee$SE*9E2B+wQuKzfiFOmVCwQ&H*P=vzW@*mLizvz literal 0 HcmV?d00001 diff --git a/libm/libmcs/doc/figure/libmcs-include-common.png b/libm/libmcs/doc/figure/libmcs-include-common.png new file mode 100644 index 0000000000000000000000000000000000000000..9798d0c6d2d451a7a7c0dbc62cc2421444d89ada GIT binary patch literal 10299 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�?fHNJvmS;(G!wc?^r` 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 literal 0 HcmV?d00001 diff --git a/libm/libmcs/doc/index.html b/libm/libmcs/doc/index.html new file mode 100644 index 00000000..f73d33db --- /dev/null +++ b/libm/libmcs/doc/index.html @@ -0,0 +1,117 @@ + + + + + + + LibmCS Documentation Resources + + + + +
+ + + +
+ + +
+ +
+ +
+ +
+ +
+ +
+ + + + diff --git a/libm/libmcs/doc/logo/libmcs-favicon.ico b/libm/libmcs/doc/logo/libmcs-favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..ac9ec21ad0fe141133d3770e4d219af292f4fe7c GIT binary patch literal 12862 zcmeHO`BxJ=6dwNxkH5R|RMwUjE7d+Kt>Ae@3bIIPQJ@qMeRhQ+Z9%kdD2pJV$mYI0 z72hBDK1>OD(@q7NnGVOH>72|>a`WX&<|g+}5rhNySS$jrhlGMMK{zM~LIJ)I2?=~R zd_Xa&|6Xo+8t8sr%{q_{R+Ma@p_;{Fu*7p>)=UqqG1 zEb4J>I$$=Q`Z)#1r^dXrG$Z~G^Mh7%F&S@isDoC{Z^rLUO~I9V3(O7ylM#O+aD{*e z`CncR=NC5Z9aC_&Vsi@cz*3W#j{nnQ^t`!*RJ$Kl3;AReH@oTptgP_JlSDU>%q9DA z3t_0Yfkg*Mt7xTaJDgVfT+i-s)4CB`=d-#1hc6ZPn>2LhFkh1W2c(F}j zJ6M{y$+lHV9^1hVlS%-yFklHm?6sEaYt6q%eV&U;6MwU9)sTdt3k51xAA|s%Jdh zPIn6V_{TnF(*J>T0!^MKE6n~L_)iXbs1lM{cyL`l0l;3PTi6P{;{_z|sym;smYI2x!$N#6P=-pgIZniV(M*t^x z{JkDUEe|^ogf6>UZMmF(5Qtcx4zM~E&ch8P!Gt}W-(EipDQ|Y9_}K$~DOGuq?-IX3 zZT>HbzmXl`msf`k{<~U&pJciNJ|~4;eXbN<6(XE8-5c__8dCc;syS;->IvQw{KH%E zAM8go1j?@DH?v`QC}fN(jQ@aef^8FjJQc$IKmHI2KBHQDV-*hJY-!%}aOw$uTx+WI zSTIjVy)?nc?`S$tD|ENn5zEaxW){HW!vSO2wo`^#5G4v;S9CNw(8RV?LmunFVk)8_ zvt%%?dHLfEyX6GlQ)i1U3v60sHJ4<3qrKZ6x!0c@^HPvmGB~ht@0yE3m~@BTm<2hC z;B_uM9N^NO97>)hy0hcQ%L_!n zn*JLP`C#Otd3o}d-Lm=f5}GP>1vm>S8R5wVKiaNL`W@A&XBlojcISNro{SxDtMNLr qwo0!+R6IwvrJBP*Rx+w71w)f-3}_5!3}_6bGa&VU0h;{xVBkN+N#Q&I literal 0 HcmV?d00001 diff --git a/libm/libmcs/doc/logo/libmcs-logo.png b/libm/libmcs/doc/logo/libmcs-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..c431b9a2590b02d9c638e3760b103c3f2e2382ce GIT binary patch literal 28336 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%0A{*0&7BycSiLj6?s@YIElmFGBAl66A^Ozi z6L44Zh4-x|Qyt6%Pih_ARmoZKNSHY|zW%p#_tvIV5*OF^%$`M@#2o8mzbGu{OS{tOqCD*q;lZyHO;N82jG5+^6Dj-4 zNoJ?cMbq8D&xHiN*p#e61=-dcfX{@bllU4C!st{J5y7%3)e~od!$2Nqbo)&6R%e`~_PvU( z*@B>fG15t{tq&dW25lbj4ealOZ9(b4?X!#*`#JJLBK@V{^soMnjs_yaii02wbW+%zk|L9vGQEUQYbJ!dQZBI5- zG!cJWQ=e)0P1D;Ni}XZ4q4{3qy>brlxyiJWr|lw%ZlOQcG1jx25|F4JsV*w2hm%ea z&<3|q$?BTRYQY&9sDiH%CSA~XyqmxXq&oxreo~ndbb9gvZHd4&!f-H*`LL$^#rk_gt!$#x9I{zt!r4bdJwS!%`EkS6#-)hH1hG%)%vW#? z?0~x{+sVe_1Hc{Zq^s=A&r`7@R>Q6Olha#ho7G-oNF)=qc=2YGYoo(bM^$VZ_oqsI z0eIkzplL$AebbY*D$xtg_lB&HDgn>B^9I%q7?88EX1m&~{YhucV0Xq!pE^_^2r!TAM|&g{9*Qe>1WVTrFk3aZvGW+K4O>ZWBA$jElj zuibOr^hm>1=(ngk%mslxxx=->BpVjwV31$mvM^6v+qJ8%PRY>ibM*Ldbu~S{4=Rp= z2q|n!wO0n`F9jJ^KGqgFV|S%}7zXIX>)wvom>X$_t$qbX9tq?2Ga6ONO)XzXB3G;Q zT&3{xRnzftHZ#jx=gXDm96hsMs+Q#umoOek_1F z%m|uSN{9Q`RSNt!38{$;+#ar1R#Q@ppOp@sssO=b@Z5Ej91ioSF?^-BEDQ%J`H0XX zHhEWfbc2V);kFpTJHd2_TM!b7T$I~T~@4!TbZKAtvRDtDJPwKh-zHy!0eZsuD~I~r<0 z5CalQafhpnp{%tCSPF8D%5Sd^LTnO%tDO4PEl5#GzyW+XGJmj=mnQ?H^XuR8vya4_ zBu~2!U1l9OM%#j*KIzCc*uTA$#%7?VKyQNsNTiJic}Ud{O1_MnOmc3z>H?kaaDf5= zkmRdsGbnvTI?Lj?@3os5QDjW`q2MuJ~n=@KS}(s0`C&>?}2Bf^S;^ViC!*T`gcjLy~#E;aSDtUM4o zG+TUfp_=!k8(uJxpZuAepo!M#i@@{P-lu4!Adka@7O=bHy%h>nEtdNfqwhVinJRH$ zrzdk{?(1i4#P+wezb~yx|NM01_LA0PRD*yoCUkmtol%Nnub23X3BNOPFF?Q1WGUqL zX^vf1a6ye){%{V5_URe##ePK5vs1cD%T1N!YbnD8?$n)Nt9;GP9}TbVan-@hNtGu~ zZA#d@cqaX_on^yboBT_xX5w+bxKVaeXcPR($$ry0MJqm~>nN94_=Nr$Wm)av<*QX& zTY2AcQg8E5Zi|^_bXE-JvG-OHE!GHR<*11NlJ6E0c%hzRYB5y&HhPcQ zO!PH`bM;SXtg}TLl>uF3K3}_lA<4?A6rZ*q_%_o#>!h7#((}a2T#l=~Wo~{q0?pTcg1*cCNCe;bj0x!k00qxg;|6KDS@OJVZ-9!zK zKZI7hlIdnv;z_=yMvwq@>>DxhosLz#7|{)Zzj^0pR=jFzxrZJk3CG)Is8ipJ8W)8v zzW)Au)R?mf`sh}B*?$T{Nu_6hv)a*TF9l**I=CF3_@1FM&W~j@U2sZb@$6@n=w_g) zo_0R0Emx)>pT(tmB!8+uD!u)xN+&Nw3+)KvYSK3ArW}Ra71EY*dELVo?3~ z6dC&9)rF;h-^YsdEpJYS|9w;=_*9d1?$Y_v_*jg(9K0wD6>Lh882$Hai~8?X4OaT+ z&8$a|KedUR?A|`f6SqGR#twVM94+T?aw6QPcQm=U?hm#u?8OX@I{%tLPI{;F1~ohX z;eS)jkm>t|^<92!vU={Kzpi*2xebU2^AtHS2vNar!(9Ii#gk}dt>=eKOBS=CP|-FfJ0x?rHBi2cQNO=s{xaBX(U^379OmG8X{ z?-xr*f2%0(ToVs+R$+U4J0}Z7s@G~*Qc6iFVM$po=2xI6#g&;(tmF|Wmrl#<05=r z+2M{2JF_|j%eMmY2dp>feB{*ABy#16-YAS1Z3IL1h;XIp!bbZ?gelcWYUo|7n%3Lj zLJuW+uKvRW#`&#naqEjf5}!Iv1vweU1L2dfhS;v)Ve^m9!0AUOt!V$JuNnJlAhy9?vNrSq>5F7R7uz9OWujFm?shZy%~O&j-#iB`er4&DAW}fY z+&>6RwPsBJkk4m|7oO;S2`oa3+5;C&bbk29FexbGA~715`?*Irh61TFi1?tMrKVPJ zBrohm!9DTQQFt~gLI}b^dZc=Bh?&&1FHtD8TIvCO1Y{zsIF)5(s#OOI_cmK%z>uz| zd3J-zr&HZR@w@a{Xj|V={*BhF-%;TdsDH-41L6R4?jDvO0o zf;j|S4%@$l?D4hmt~MCb$=Z3cdW<{YURu`Nsabgfr$OLDRtmVZyZm<@hB~Dfl_dHL z$jE4fMJeXYj7O?H&pUNH75}6LRmv4*IXOZ$(DIStRYu`Xaz{tgkIs(}ieCWW`_5NR zFMWH!@;P7OolW}$vg^0Dv)$_yIr>Oj|A*-Yw!hv3UqKvq{Akd;Io}=Ye(2I&G4b19 zBg@sUY60`OW5Qsopgr8yFL`UOzU#gYq`&f_-ycy{nQgjr=9qDiz5xC~D*797prZhp z@IYhfO>O0&oZMt(ukQtKwOv0*+fMlhvX zWy}z5rLmZqVxows+|i0VfKJFY?%d$KV43=bS_-;hmf?TErT;>l{$DiH1>^Uh--HO_ z|KoVX|MH)&M%fG!79l;mts}-R0Noy%s;A^m;$1--d@k0X?aYhAG8LpUd70lJG#+t}*X(+U!5P#nyQcqL$zOVMA-_HK%psuAPlOT5y;7J+n2&W$CB`+;BHs@s)j}ndP z@pL+zJN(nlR(6~f!=B3l`ZExnOCjZ7YY1;omDGV|YJ7V>;7f4kKWiuoNWde0BWWG4 zd%idB{$Q`V41BG|)ahbH;n0x9T@?n|F8)!O9H?3iqq$9^JV=^5N%(=>Bw1@G4^9`f zt+KJOjPH|wm}ilwLxC$&gd~E0&e1;9a%zhNA!_aMAOdbE2ioOer`1AzM#)YeXvx}&A73o%gbhp?90A`48c<0_g zg0&*4(0o}&!JQJIo9iDR6k*rgG0Jq->-2}FV#3AF^wB68FvMODv+$jrb(%Vd&W?Z75h+&tBu?6j0^G(KcJ{e zEW>D<#tUCuf5Gs0cUYVqUmEVNa*ws=Ou>Lfxo&M%+XSqM+|KCUAyV>#YSU+gK&OY+ zn*U^HZK?fxe=>ngj8DVU#C6X}Xf309kENNEKrzu*I5`>zKF55@;7#xG zuxUl#qAir3%wsfcTJQl(ZY@+&FHoVV0&+NAn_FOEN;w_t)R$b=)x8z+ToF^lT@t3< zKX!r@R2uF6T@3tl$e{{015=577|yrFeP(u1JA=An2?YDy`%4zNNh3ctm*-~JG3ruH z>pOn71a3mz#e=HdtK|$DX@*L!wY@#u7k|bzviAl^xot&Uc>Gw8Ha$gA{R6oP8fFOZ zA5*@{kLamvW139X8b9uCvT2TZx4^o#420o}qRlg>dQ+$MzqlV-NI^!)JjoNFth7J< z8<-qU35)A^!2`_AX~)M4HhFpB28hiaUKOfw=e{Ae2J59APn~0JU&wlRnR4isrByKKwE6zChB#Yuy0$QISO{a69y0K)c_B2 zDo<;e(I}?rszFnV<=S}mPom@3hZ7o=;|~*0$1uRcfC@zoT1=Ak-m^~@51V4LbT!s@FB14E6h%8WG z<|4B*1eXza?dh--|_P-dtG7;$Dvq zHtR1An+md^QgXOZBnPvMj$~sBx+qshctDW7`5+=`iYe=t7qjaI zqHHrsP1TXGXYA`7w0Tg81E9uAXyIjn^o3p<_|xkmKEm;q$W{QcN_Au@xoUZ z&#a>(;q8ggx+|1=&}%6_WkQQKYwHa3Z_$b_?YuJb$vquYVtWK(}6`^8aJ&uT<+BbmMgM0B1o~W+! zT8Vlpuw%NK#DI9_`g$~2wNYV#+9vjjT51g)e~)pR=kRi7tIo>9cLjq>@+r|DG+ zpg>S=ZU^Srvm(P)kQxro1#N#XnwW~<=L@aAZm#<6b1Y&9QR%N{ON=M1EBGfl+JH5^ zA);}ylB?XXrDc^kb=uO=VPL4t2@hOsi%zk-ZemkkzeZRk={@Q0X59^c2`m-d3G;_{ z^uqt73tQ*PbPKOtdBY;&N@WICh{C>@zJ{*Dt*l?wem;ZX-puSiRAh@x*;;z@DNK9O zgMf3LA){$~cN722qM4M1@P%1zFUmEybR~q9htH6%#@lpCWbH$ zH?M;)z4s`mfh;P~A6oj%^v+esqJlg2Rk%`;HTsu|kezmQgcD2h?A}VQ4Taw_kqQD% z{vs|t=Ik24V=fE|!Y0R!xcL>yntWB^%&mig<8Cq2-OlN*S^0NY-ZGELq{>I0ZokG7}rImXm(}*|N zJFmz3)SpB};T1e3R8dMt4acN&z6ucC2wTs2?1&~w+Uylo#ZgnAvbIW!iT+kurA$GF z(UAr747P0jz7nT_b@Sg{FE-!;FSbY2?B=az>~iXG+#InfNiV+lx^8VPOh$kSs>0hR zsU4o7RIi0*(qSYY(+3!#Df^X)-^6Bb`<7(GR)9VM0*NV`1>4Jmdl!VpBt^L71tWS2 z?MnXKf~L|IM(ADUft6Q~AvhpZry@hi*~395-hsT9tg!!X^`%C35bx_)eH)oyUiqxE z9}%WmGyEgEW8VI7lBqLu+f~qL_9hNhxim-`Z*1OyXPoX0^(@H$MvW_zZ?~e!VK~R` zLNEGvyr4@hQ7;e3)4UhRtxKZ2uA7u($L-v`C*fB4iQix>90LakcA)MI7b+^@i4b%8 z#!F*h5FAfK@~LUnbbq|lytnTmy$Xgxa*m&euZ1vyo2xA|?KXjP zK7Qm=svRVw)RZ$tbA|$fRn<-d6EfJR^Swjm?GcHvFNJ!qo}sv>*D~GkeT^cK`z~5t zr?As6t7U7LQs9>o{!H5>!F-ipA-$rn{fbC7_-dwS^g)&Bvrchs1ek>zNYX^_1Mful z-9?^LiOKqaiTU!qhCF+K3A$XcyvJ*$9{9XIpfbBOKxSa;TDWURk_o@XQ$51Mn)ooENtA8^-pJs$n811JYyC5a#uP7p z{2uz&InJM&4A~~|Ei}8KA&-x)*{4q)_pzjsZ{4c>hbWCw4cJM3v4&M# zWotjvzjk!snd9pde|&(gW6Etv|Ly?59rcUczqNevc(v0y{Jc>mHh6EPov@G(X8)4YMvXZL(-`M!Ycm%?8 zPVzfT633#U6CIn`fOU?b-80kuy@Hz9S@eGxdgjyV80ECh?^awS!Qrijlv9YW)-e7H zGs|5r!v$g5APnP|_bHm+%`Mw3xqk}sKgYiOkYCKi>fCjsKAWWuN9&biUsHx2$O)`6)W%7#*w+_4HE97yHz1cJA9|V#T84br4>fZu z&%1I@YhqBE$C&W;g!8VYhr)&$78ZWp#d`r5j?+Bgkkv4$rwetbpLX28-0!Hr&N?vk z$azV5DPQ*Fa8T(WLQ@`}cakHxHdAqnB`RH?;%bgL*e5Vvlv0r8sOQG|?F|SOe-I#f z)MmEVME&4lHW0O@V=DhI)sK6EpPJ|NOT=ZQ@bbQ+?r0VfpHmLZA&A3Mos8Y7jL%9= zx`H1VHgk4K)pTCswYrdi-}}0|x07l(Ei4AQNw|JThWHDRH;cLhO9|AR13_W3)iZc{ zWVE6+_r#5q%n|0o?_5NFC9S$t=^%V)`L=er*el2>KfnkF=;G*{gT3dWVM?0LFC>lC z9t>haV|caxd9K3zwikEzB$|=r6HU(UvHRr-mVsT(L6F}t6T}7@T|$&)_DI*9oVq#U zY=ZN`>|z#jrMhV1!U8$q_>KB{4Nm39y9>SGk>QJ(7TGr4iCuPCDppF~`KL|Ubp9yE zTg0=DuaDqfV}X?9mO7HkYp9ST%DX8N3`3Z*>}Hv zfo4qZ&sTy!)+#3SLbStDh)Sz5PO;g)Hy17K(o7SV%zuKlVz|_Ydpdzmx;pN23Y)_byS=Y42x!PV7nF@^RnW~&%6a*;@2v5TZ`J;d=ybDbGl?Yd7nbW0=9 zYF}X=2w!Yq;(y#-p}a14zJ=|m&#V>6t;Rf%pLh7XEB4R$^M(;VOV*bv4!7cP@idB$ z(7(q7lI0YdE+%kFe+@1^8-&c@k}C1C3aa^JY0{h zIdt>j6+<3$5mTOUy*e=A=oACG{m~sET)Io1=n_!Vn)0XqWw%s#2K_wKDkgU`a>{m> z=OcUqWNd!+hFPsrcMN3VtJ?_G04_v3}SW5Mu^6HS(UD+jpB5^OL7x5CD8epcq6H1kH$S%?Ol zYeVb75O5Ts$%wYGo;7$37;*e7wWzOjeKl_iR6{`dH0&#hHz)a=qL3Yk^V;yV$_iN_ zLJGkLGbgg#J}@VUyNiaGQQrhR1zZDHxg_y@C@y;Jfo#tTQVynIsD&N?5a=c>GAk~r zxneUE@rea{8`=fP5s*B~B+9h!HNA{h$(jTF-&~gWX+Gb33q2 z5qPJwTQTCtFlaO<#SjT2aahJx9LdPQC`wBR3v5)QeTac{f&TqQ41Iv+y>|mMu?ZQ> zMbp#OSG7SZD!VV={N}UuA_KB{{TH7p5v7^?Q}iY?5cLp^xnE%8(ec8& zwY~HCy{w!7RuK7cA}UzGMe`Fa63tgAx=)3O^`=(ftGZTVn&kP14q^Npc6|Th*U#VS zTsMNw3`IGBO#3%b*a(8JAa}22bm{kGCG6?w`O#~bt*i6&c%T&YF17D2NzJZ167Mbb zL&L=FzO%MFCmR`$gulAwRhKTv#c}sW5IS!0p|N>hPm--i$cxXo`^?%p{%i~f;{tYL zLGNvLk`?cDjFA)QuZr;8_P-3>9e6NyuA03<#Gf=5Xd_?#*zm91s_qSC)t^7!YZ;46 zs>ahTA-^Q*0ZXYzq?UK0LOx365l@QRtHP09ZELNKb`HO>QJNjIiF8FY$3 zx@~BMfJ1yhmpEaz$zX&B0p zMz^oI9(A3}2;#C4YwwoW79p)#giJ}B5-i%y7FrOfsuF1TVU`LEJ?G{KMwvOoJ0)Py z67ABCaZ^^p@;3%-`%^jgOF2#6P`_cJ0#(AV$eX^$`@XV}1;Q*NY&I}A?!3HjaRaw` zy%i(~dCFMNCyroa2|JGvueE%c)u8siKxmYWZjvr~tdQnNLuI$V&y#wigRH%}w>utQ z-tdZf0P8{LyJ4~3L1eKj%+mk&dw>4Nn!XrA`p?UN{{7+qZh;dvpI>u{W(e=$I}wJr Q9$`I`R(zT(Y2g2V0E#qSX#fBK literal 0 HcmV?d00001 diff --git a/libm/libmcs/doc/sdd/1_Introduction.rst b/libm/libmcs/doc/sdd/1_Introduction.rst new file mode 100644 index 00000000..4e118c2c --- /dev/null +++ b/libm/libmcs/doc/sdd/1_Introduction.rst @@ -0,0 +1,15 @@ +Introduction +============ + +.. raw:: html + + + +This document is the :ref:`SDD ` for the development of a qualified mathematical library for critical systems and is prepared in response to ECSS-E-ST-40C :ref:`[AD01] `, section F.2. + +Its purpose is to describe the software architectural design and the software detailed design, by listing the software components, explaining the purpose of each and documenting the design decisions which led to +the implementation of the software as is. It further includes the internal interfaces design. + +The mathematical library is an :ref:`ECSS ` category B software. diff --git a/libm/libmcs/doc/sdd/2_Applicable_and_Reference_Documents.rst b/libm/libmcs/doc/sdd/2_Applicable_and_Reference_Documents.rst new file mode 100644 index 00000000..be93c1a7 --- /dev/null +++ b/libm/libmcs/doc/sdd/2_Applicable_and_Reference_Documents.rst @@ -0,0 +1,46 @@ +Applicable and Reference Documents +================================== + +.. raw:: html + + + +In case no issue number is specified for a document, the latest issue shall be applicable. + +.. _AD: + +Applicable Documents +-------------------- + +The documents listed below form part of this document. + +.. table:: Applicable Documents + :name: applicable_documents + + ============== ================ ========= ====================================================== + Reference Identification Issue Title + ============== ================ ========= ====================================================== + AD01 ECSS-E-ST-40 C Space Engineering - Software + AD02 ECSS-Q-ST-80 C Rev. 1 Space Product Assurance - Software Product Assurance + ============== ================ ========= ====================================================== + +.. _RD: + +Reference Documents +------------------- + +The documents listed below were used to prepare this document and contain background information on topics discussed in this document. + +.. table:: Reference Documents + :name: reference_documents + + ============== ================ ========= ======================================================== + Reference Identification Issue Title + ============== ================ ========= ======================================================== + RD01 ES-SRS.00-ML \- Software Requirements Specification + RD02 ED-ICD.00-ML \- Interface Control Document + RD03 ISO/IEC 9899 2018 Programming languages - C + RD04 MISRA C:2012 03/2013 Guidelines for the use of C language in critical systems + ============== ================ ========= ======================================================== diff --git a/libm/libmcs/doc/sdd/3_Abbreviations.rst b/libm/libmcs/doc/sdd/3_Abbreviations.rst new file mode 100644 index 00000000..4c24f2d3 --- /dev/null +++ b/libm/libmcs/doc/sdd/3_Abbreviations.rst @@ -0,0 +1,52 @@ +.. _ABBR: + +Terms, Definitions and Abbreviated Terms +======================================== + +.. raw:: html + + + +Agency + refers to :ref:`ESA ` + +DAZ + Denormals are Zero + +denormal + See subnormal. + +DRD + Document Requirements Definition + +ECSS + European Cooperation for Space Standardization + +ESA + European Space Agency + +FPU + Floating Point Unit + +ICD + Interface Control Document + +SDD + Software Design Document + +SPDX + Software Package Data Exchange + +SRS + Software Requirements Specification + +subnormal + See IEEE-754 standard for the definition. + +SUM + Software Users Manual + +ULP + Unit in the Last Place diff --git a/libm/libmcs/doc/sdd/4_Software_Design_Overview.rst b/libm/libmcs/doc/sdd/4_Software_Design_Overview.rst new file mode 100644 index 00000000..3bf38291 --- /dev/null +++ b/libm/libmcs/doc/sdd/4_Software_Design_Overview.rst @@ -0,0 +1,124 @@ +Software Design Overview +======================== + +Software Static Architecture +---------------------------- + +.. raw:: html + + + +The mathematical library is a software library. The library is a fully passive library and provides solutions for mathematical procedures to the calling software. As such it can be seen as a replacement of the +``libm`` standard library. The procedures the library implements are listed in :ref:`Overall Architecture`. + +The library has no separate operational modes or states, it simply provides the above mentioned procedures. + +Further the library does not store data of any kind. + +Software Dynamic Architecture +----------------------------- + +.. raw:: html + + + +The library has no real-time constraints, all procedures provided calculate a response right away. Each procedure however has a bounded execution time (refer to :ref:`SRS ` :ref:`[RD01] ` §5.3). + +Software Behaviour +------------------ + +As previously noted, the library’s behaviour is that of a passive library. It never executes code of any kind without being explicitly called by another program. + +Interfaces Context +------------------ + +.. raw:: html + + + +No :ref:`ICD ` will be provided for this project and its contents are part of the :ref:`SUM ` and this :ref:`SDD `. All of the :ref:`ICDs ` contents required by :ref:`ECSS ` are part of these two documents without any loss. + +Section :ref:`Software Components Design – Aspects of Each Component` provides information on the function signatures of all library procedures. The library is meant to be included in other software projects. + +The interface provided is that of a C library that can be compiled to an object file to be statically or dynamically linked to the calling software. + +The library and all its components are compliant to the IEEE 754-2019 (Information technology – Microprocessor Systems – Floating-Point arithmetic), IEEE 1003.1-2017 (POSIX) and ISO/IEC 9899 (Programming languages – C) standards. + +Long Lifetime Software +---------------------- + +.. raw:: html + + + +The library does not cause restrictions regarding the longevity of the operating software. It does not depend on a particular operating system or hardware setup. + +Memory and CPU Budget +--------------------- + +.. raw:: html + + + +The library uses 100% of available processing time while executing a procedure and 0% while it doesn’t. This is due to the library not having any tasks that run continuously or periodically. It simply executes one function, returns its result and stops. + +The static memory needed for the library differs depending on the used toolchain and on which procedures are used by the user (due to ``gc-sections`` flags to the compiler). Still the library targets to use +as little static memory as possible while providing its functionality. The library’s allocation of dynamic memory is marginal - each procedure only requires several bytes to save intermediate variables. This however +is only stack memory, no ``malloc`` is used, therefore no memory will be allocated from heap. + +Design Standards, Conventions and Procedures +-------------------------------------------- + +.. raw:: html + + + +The main design method of this project is ‘reuse’, therefore the design of the functions highly depends on the already existing implementation, which in turn causes this :ref:`SDD ` to be more of a description of an existing design rather than a design produced before implementation. However the procedures and their designs may be improved during this project, turning the design method into ‘reuse with improvements’. + +Source code documentation is done using the restructured text format for file, procedure and variable documentation, it will then be interpreted by Sphinx to generate HTML/PDF documents. Additionally the software engineer may use further comments within the code to describe parts of their implementation. + +All aspects regarding the design that are not explicitly stated shall remain as they were in newlib’s libm. + +The library will guarantee thread safety and reentrancy for all procedures unless explicitly stated otherwise. The only exception will be the ``lgamma`` procedures due to the requirement to have the global variable ``signgam``, as such the content of the variable is not thread safe when ``lgamma`` procedures are executed in multiple threads at the same time. + +We define the set of all floating-point numbers as :math:`\mathbb{F}` and the set of all subnormal numbers as :math:`\mathbb{S}` to be used in mathematical formulae. The set of floating-point numbers :math:`\mathbb{F}` contains all floating-point numbers, that is normals, subnormals (therefore :math:`\mathbb{S} \subset \mathbb{F}`), zeroes, infinities and ``NaN``, of the type given by the context. If a reduction to a specific type is needed, this will be indicated as follows: :math:`\mathbb{F}_s` for single precision, :math:`\mathbb{F}_d` for double precision, and :math:`\mathbb{F}_{ld}` for long double precision. The same will be done for :math:`\mathbb{S}` with :math:`\mathbb{S}_s`, :math:`\mathbb{S}_d`, and :math:`\mathbb{S}_{ld}` respectively. Furthermore :math:`\mathbb{F}^{+}` symbolizes all floating-point numbers where the sign bit is not set, while :math:`\mathbb{F}^{-}` contains all those where the sign bit is set (this includes :math:`-0.0`, ``-Inf``, and ``NaNs`` where the signbit is set). Using these sets we are able to express floating-point numbers in mathematical formulae, for example the formula :math:`x \in \mathbb{F} \setminus \left \{ \pm \text{Inf}, \text{NaN} \right \}` denotes that `x` is a floating-point number that is neither infinity nor ``NaN``, which leaves `x` to be either zero, a normal or a subnormal number. :math:`\mathbb{F}` cannot be fully represented by conventional number classifications due to the introduction of :math:`\pm 0.0`, explicit infinities and ``NaNs``, however the following is valid: :math:`(\mathbb{F} \setminus \left \{ -0.0, \pm \text{Inf}, \text{NaN} \right \}) \subset \mathbb{Q}`. + +Similarly we define the set of all 32bit integer numbers as :math:`\mathbb{I}`. :math:`\mathbb{I}` is a subset of :math:`\mathbb{Z}` limited by the size of the integer, therefore :math:`\mathbb{I} \subset \mathbb{Z}`. The same concept applies for :math:`\mathbb{I}_{l}` which represents either 32bit or 64bit integer numbers depending on the size of ``long int``, and :math:`\mathbb{I}_{ll}` which represents 64bit integer numbers. + +To denote the similarity, but not always equality, between the mathematical function and its representing procedure we use :math:`\approx` where appropriate. This is not used if a procedure is able to exactly mimic the functionality of the mathematical function. diff --git a/libm/libmcs/doc/sdd/5_Software_Design/0_Software_Design.rst b/libm/libmcs/doc/sdd/5_Software_Design/0_Software_Design.rst new file mode 100644 index 00000000..6fc8efe2 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/0_Software_Design.rst @@ -0,0 +1,11 @@ +Software Design +=============== + +.. toctree:: + :maxdepth: 3 + + 1_General.rst + 2_Overall_Architecture.rst + 3_Software_Component_Design_General.rst + 4_Software_Component_Design_Aspects_Of_Each_Component/0000_Software_Component_Design_Aspects_Of_Each_Component.rst + 5_Internal_Interface_Design.rst diff --git a/libm/libmcs/doc/sdd/5_Software_Design/1_General.rst b/libm/libmcs/doc/sdd/5_Software_Design/1_General.rst new file mode 100644 index 00000000..4a1eefc2 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/1_General.rst @@ -0,0 +1,21 @@ +General +------- + +.. raw:: html + + + +The herein described software is a mathematical library, not designed for independent execution, but for embedding into other software projects. This chapter describes the software design in a top-bottom approach: First in :ref:`Overall Architecture` a common overview over the structure of the software is given. The section afterwards :ref:`Software Components Design - General` identifies each component in the software. All components are described in :ref:`Software Components Design – Aspects of Each Component`. The last section :ref:`Internal Interface Design` gives an overview about the internal usage between the components. + +The library is a reuse of the mathematical library contained in ``newlib`` called ``libm``, specifically we use the ``libm`` contained in ``newlib`` v4.0.0. + +In the process of improving the reused software several design and implementation changes have to be made to the library. + +This document follows in structure and content the :ref:`DRD ` in ECSS-E-ST-40 :ref:`[AD01] `, but because of the type of the reused software some required items have to be redefined for an appropriate design description or are not relevant. The reinterpreting/redefining of items is done at the start of each section. All items not relevant in this context are mentioned at the end of each section to be compliant with :ref:`ECSS `. + +The source code is designed to be compliant to the mandatory and required rules depicted in MISRA C:2012 :ref:`[AD04] `. diff --git a/libm/libmcs/doc/sdd/5_Software_Design/2_Overall_Architecture.rst b/libm/libmcs/doc/sdd/5_Software_Design/2_Overall_Architecture.rst new file mode 100644 index 00000000..23118b6f --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/2_Overall_Architecture.rst @@ -0,0 +1,387 @@ +Overall Architecture +-------------------- + +.. raw:: html + + + +One of the project’s goals is having an easy access to all of the library’s procedures. To attain this goal, only the header files ``math.h`` and ``complex.h`` (if complex procedures are wanted by the given project) have to be included to use all the mathematical procedures provided by the library. These header files contain all procedure definitions, while their implementation can be found in separate ``.c`` files. + +A further difference to other projects is the definition of a software component. In most other projects, this library would be considered as one single component, but in the context of describing the library a component/unit is one procedure, e.g. ``sin``, ``sinf``, ``sinl``, ``cos``, ``cosf``, ``cosl``, ``atan2``, &c. Most of the procedures are implemented in one or more separate translation units. The following procedures are accessible (the list contains the names of the double precision procedures, the single precision procedure names are the same but suffixed with an ``f``, the long double precision procedure names are the same but suffixed with an ``l``): + +.. table:: List of all procedures in math.h + :name: List of math procedures + + +--------------------+-----------------------------------------------------------+ + | Procedure | Description | + +====================+===========================================================+ + | ``fpclassify`` | Procedure returning the classification of the argument | + +--------------------+-----------------------------------------------------------+ + | ``isfinite`` | Procedure returning whether the value of the argument is | + | | finite or not (not :math:`±Inf` and not :math:`NaN`) | + +--------------------+-----------------------------------------------------------+ + | ``isinf`` | Procedure returning whether the value of the argument is | + | | positive or negative Infinity or not | + +--------------------+-----------------------------------------------------------+ + | ``isnan`` | Procedure returning whether the argument is a | + | | :math:`NaN` floating-point value or not | + +--------------------+-----------------------------------------------------------+ + | ``isnormal`` | Procedure returning whether the argument is a normal | + | | floating-point value or not | + +--------------------+-----------------------------------------------------------+ + | ``signbit`` | Procedure returning whether the argument is negative or | + | | not | + +--------------------+-----------------------------------------------------------+ + | ``acos`` | Procedure returning the trigonometric arccosine | + +--------------------+-----------------------------------------------------------+ + | ``asin`` | Procedure returning the trigonometric arcsine | + +--------------------+-----------------------------------------------------------+ + | ``atan`` | Procedure returning the trigonometric arctangent | + +--------------------+-----------------------------------------------------------+ + | ``atan2`` | Procedure returning the trigonometric arctangent of | + | | :math:`\frac{y}{x}` | + +--------------------+-----------------------------------------------------------+ + | ``cos`` | Procedure returning the trigonometric cosine | + +--------------------+-----------------------------------------------------------+ + | ``sin`` | Procedure returning the trigonometric sine | + +--------------------+-----------------------------------------------------------+ + | ``tan`` | Procedure returning the trigonometric tangent | + +--------------------+-----------------------------------------------------------+ + | ``acosh`` | Procedure returning the hyperbolic arccosine | + +--------------------+-----------------------------------------------------------+ + | ``asinh`` | Procedure returning the hyperbolic arcsine | + +--------------------+-----------------------------------------------------------+ + | ``atanh`` | Procedure returning the hyperbolic arctangent | + +--------------------+-----------------------------------------------------------+ + | ``cosh`` | Procedure returning the hyperbolic cosine | + +--------------------+-----------------------------------------------------------+ + | ``sinh`` | Procedure returning the hyperbolic sine | + +--------------------+-----------------------------------------------------------+ + | ``tanh`` | Procedure returning the hyperbolic tangent | + +--------------------+-----------------------------------------------------------+ + | ``exp`` | Procedure returning the base :math:`e` exponential of | + | | :math:`x` | + +--------------------+-----------------------------------------------------------+ + | ``exp2`` | Procedure returning the base :math:`2` exponential of | + | | :math:`x` | + +--------------------+-----------------------------------------------------------+ + | ``expm1`` | Procedure returning the base :math:`e` exponential of | + | | :math:`x` minus :math:`1` | + +--------------------+-----------------------------------------------------------+ + | ``frexp`` | Procedure breaking :math:`x` into a normalized fraction | + | | and an integral power of :math:`2` | + +--------------------+-----------------------------------------------------------+ + | ``ilogb`` | Procedure returning the binary exponent of :math:`x` as | + | | integer | + +--------------------+-----------------------------------------------------------+ + | ``ldexp`` | Procedure returning :math:`x` multiplied by an integral | + | | power of :math:`2` | + +--------------------+-----------------------------------------------------------+ + | ``log`` | Procedure returning the natural logarithm | + +--------------------+-----------------------------------------------------------+ + | ``log10`` | Procedure returning the base :math:`10` logarithm | + +--------------------+-----------------------------------------------------------+ + | ``log1p`` | Procedure returning the natural logarithm of | + | | :math:`x + 1` | + +--------------------+-----------------------------------------------------------+ + | ``log2`` | Procedure returning the base :math:`2` logarithm | + +--------------------+-----------------------------------------------------------+ + | ``logb`` | Procedure returning the binary exponent of :math:`x` | + +--------------------+-----------------------------------------------------------+ + | ``modf`` | Procedure breaking :math:`x` in its integral and | + | | fractional part | + +--------------------+-----------------------------------------------------------+ + | ``scalbn`` | Procedure returning :math:`x` multiplied by an integral | + | | power of :math:`2` | + +--------------------+-----------------------------------------------------------+ + | ``scalbln`` | Procedure returning :math:`x` multiplied by an integral | + | | power of :math:`2` | + +--------------------+-----------------------------------------------------------+ + | ``cbrt`` | Procedure returning the cubic root | + +--------------------+-----------------------------------------------------------+ + | ``fabs`` | Procedure returning the absolute value | + +--------------------+-----------------------------------------------------------+ + | ``hypot`` | Procedure returning the square root of :math:`x^2+y^2` | + +--------------------+-----------------------------------------------------------+ + | ``pow`` | Procedure returning :math:`x` raised to the power of | + | | :math:`y` | + +--------------------+-----------------------------------------------------------+ + | ``sqrt`` | Procedure returning the square root | + +--------------------+-----------------------------------------------------------+ + | ``erf`` | Procedure returning the error function | + +--------------------+-----------------------------------------------------------+ + | ``erfc`` | Procedure returning the complementary error function | + | | (``erfc`` = :math:`1 -` ``erf``) | + +--------------------+-----------------------------------------------------------+ + | ``lgamma`` | Procedure returning the natural logarithm of the absolute | + | | value of gamma of :math:`x` | + +--------------------+-----------------------------------------------------------+ + | ``tgamma`` | Procedure returning gamma function of :math:`x` | + +--------------------+-----------------------------------------------------------+ + | ``ceil`` | Procedure for rounding upwards to the nearest integer | + +--------------------+-----------------------------------------------------------+ + | ``floor`` | Procedure for rounding downwards to the nearest integer | + +--------------------+-----------------------------------------------------------+ + | ``nearbyint`` | Procedure for rounding to the nearest integer using the | + | | current rounding direction | + +--------------------+-----------------------------------------------------------+ + | ``rint`` | Procedure for rounding to the nearest integer using the | + | | current rounding direction (raises inexact) | + +--------------------+-----------------------------------------------------------+ + | ``lrint`` | Procedure for rounding to the nearest integer using the | + | | current rounding direction | + +--------------------+-----------------------------------------------------------+ + | ``llrint`` | Procedure for rounding to the nearest integer using the | + | | current rounding direction | + +--------------------+-----------------------------------------------------------+ + | ``round`` | Procedure for rounding to the nearest integer (Halfway | + | | values rounded away from :math:`0`) | + +--------------------+-----------------------------------------------------------+ + | ``lround`` | Procedure for rounding to the nearest integer (Halfway | + | | values rounded away from :math:`0`) | + +--------------------+-----------------------------------------------------------+ + | ``llround`` | Procedure for rounding to the nearest integer (Halfway | + | | values rounded away from :math:`0`) | + +--------------------+-----------------------------------------------------------+ + | ``trunc`` | Procedure for rounding towards :math:`0` to the nearest | + | | integer | + +--------------------+-----------------------------------------------------------+ + | ``fmod`` | Procedure returning the floating-point remainder of | + | | :math:`\frac{y}{x}` (rounded towards zero) | + +--------------------+-----------------------------------------------------------+ + | ``remainder`` | Procedure returning the floating-point remainder of | + | | :math:`\frac{y}{x}` (rounded to nearest integral value) | + +--------------------+-----------------------------------------------------------+ + | ``remquo`` | Procedure returning the same value as ``remainder`` and | + | | puts the quotient in :math:`*quo` | + +--------------------+-----------------------------------------------------------+ + | ``copysign`` | Procedure returning a floating-point number with the | + | | magnitude of :math:`x` and the sign of :math:`y` | + +--------------------+-----------------------------------------------------------+ + | ``nan`` | Procedure returning a :math:`NaN` | + +--------------------+-----------------------------------------------------------+ + | ``nextafter`` | Procedure returning the next floating-point value after | + | | :math:`x` in direction of :math:`y` | + +--------------------+-----------------------------------------------------------+ + | ``nexttoward`` | Procedure returning the next floating-point value after | + | | :math:`x` in direction of :math:`y` | + +--------------------+-----------------------------------------------------------+ + | ``fdim`` | Procedure returning the positive difference between the | + | | arguments | + +--------------------+-----------------------------------------------------------+ + | ``fmax`` | Procedure returning the larger of two values | + +--------------------+-----------------------------------------------------------+ + | ``fmin`` | Procedure returning the smaller of two values | + +--------------------+-----------------------------------------------------------+ + | ``fma`` | Procedure returning the result of :math:`x \cdot y + z` | + +--------------------+-----------------------------------------------------------+ + | ``isgreater`` | Procedure returning whether :math:`x` is greater than | + | | :math:`y` | + +--------------------+-----------------------------------------------------------+ + | ``isgreaterequal`` | Procedure returning whether :math:`x` is greater than or | + | | equal to :math:`y` | + +--------------------+-----------------------------------------------------------+ + | ``isless`` | Procedure returning whether :math:`x` is less than | + | | :math:`y` | + +--------------------+-----------------------------------------------------------+ + | ``islessequal`` | Procedure returning whether :math:`x` is less than or | + | | equal to :math:`y` | + +--------------------+-----------------------------------------------------------+ + | ``islessgreater`` | Procedure returning whether :math:`x` is less or greater | + | | than :math:`y` | + +--------------------+-----------------------------------------------------------+ + | ``isunordered`` | Procedure returning whether the arguments are unordered | + | | (aka at least one is :math:`NaN`) | + +--------------------+-----------------------------------------------------------+ + | ``j0`` | Procedure returning the Bessel value of :math:`x` of the | + | | first kind of order :math:`0` | + +--------------------+-----------------------------------------------------------+ + | ``j1`` | Procedure returning the Bessel value of :math:`x` of the | + | | first kind of order :math:`1` | + +--------------------+-----------------------------------------------------------+ + | ``jn`` | Procedure returning the Bessel value of :math:`x` of the | + | | first kind of order :math:`n` | + +--------------------+-----------------------------------------------------------+ + | ``y0`` | Procedure returning the Bessel value of :math:`x` of the | + | | second kind of order :math:`0` | + +--------------------+-----------------------------------------------------------+ + | ``y1`` | Procedure returning the Bessel value of :math:`x` of the | + | | second kind of order :math:`1` | + +--------------------+-----------------------------------------------------------+ + | ``yn`` | Procedure returning the Bessel value of :math:`x` of the | + | | second kind of order :math:`n` | + +--------------------+-----------------------------------------------------------+ + +.. table:: List of all procedures in complex.h + :name: List of complex procedures + + +--------------------+-----------------------------------------------------------+ + | Procedure | Description | + +====================+===========================================================+ + | ``cacos`` | Procedure returning the complex trigonometric arccosine | + +--------------------+-----------------------------------------------------------+ + | ``casin`` | Procedure returning the complex trigonometric arcsine | + +--------------------+-----------------------------------------------------------+ + | ``catan`` | Procedure returning the complex trigonometric arctangent | + +--------------------+-----------------------------------------------------------+ + | ``ccos`` | Procedure returning the complex trigonometric cosine | + +--------------------+-----------------------------------------------------------+ + | ``csin`` | Procedure returning the complex trigonometric sine | + +--------------------+-----------------------------------------------------------+ + | ``ctan`` | Procedure returning the complex trigonometric tangent | + +--------------------+-----------------------------------------------------------+ + | ``cacosh`` | Procedure returning the complex hyperbolic arccosine | + +--------------------+-----------------------------------------------------------+ + | ``casinh`` | Procedure returning the complex hyperbolic arcsine | + +--------------------+-----------------------------------------------------------+ + | ``catanh`` | Procedure returning the complex hyperbolic arctangent | + +--------------------+-----------------------------------------------------------+ + | ``ccosh`` | Procedure returning the complex hyperbolic cosine | + +--------------------+-----------------------------------------------------------+ + | ``csinh`` | Procedure returning the complex hyperbolic sine | + +--------------------+-----------------------------------------------------------+ + | ``ctanh`` | Procedure returning the complex hyperbolic tangent | + +--------------------+-----------------------------------------------------------+ + | ``cexp`` | Procedure returning the complex base :math:`e` | + | | exponential of :math:`z` | + +--------------------+-----------------------------------------------------------+ + | ``clog`` | Procedure returning the complex natural logarithm | + +--------------------+-----------------------------------------------------------+ + | ``cabs`` | Procedure returning the complex absolute value | + +--------------------+-----------------------------------------------------------+ + | ``cpow`` | Procedure returning the complex value :math:`x` raised to | + | | the power of :math:`y` | + +--------------------+-----------------------------------------------------------+ + | ``csqrt`` | Procedure returning the complex square root | + +--------------------+-----------------------------------------------------------+ + | ``carg`` | Procedure returning the value of :math:`z` in the | + | | interval [:math:`-\pi`, :math:`+\pi`] | + +--------------------+-----------------------------------------------------------+ + | ``cimag`` | Procedure returning the imaginary part of the value of | + | | :math:`z` | + +--------------------+-----------------------------------------------------------+ + | ``CMPLX`` | Procedure returning the complex value with real part | + | | :math:`x` and imaginary part :math:`y` | + +--------------------+-----------------------------------------------------------+ + | ``conj`` | Procedure returning the complex conjugate value of | + | | :math:`z` | + +--------------------+-----------------------------------------------------------+ + | ``cproj`` | Procedure returning the value of the projection onto the | + | | Riemann sphere of :math:`z` | + +--------------------+-----------------------------------------------------------+ + | ``creal`` | Procedure returning the real part of the value of | + | | :math:`z` | + +--------------------+-----------------------------------------------------------+ + +Furthermore the library shall provide a number of constants, as such the following defines are to be added to ``math.h``: + +.. table:: List of all constant defines in math.h + :name: List of math constants + + ================ =============================================== + Name Description + ================ =============================================== + ``M_E`` Value of :math:`e` + ``M_LOG2E`` Value of :math:`log_{2} e` + ``M_LOG10E`` Value of :math:`log_{10} e` + ``M_LN2`` Value of :math:`log_e 2` + ``M_LN10`` Value of :math:`log_e 10` + ``M_PI`` Value of :math:`\pi` + ``M_PI_2`` Value of :math:`\frac{\pi}{2}` + ``M_PI_4`` Value of :math:`\frac{\pi}{4}` + ``M_1_PI`` Value of :math:`\frac{1}{\pi}` + ``M_2_PI`` Value of :math:`\frac{2}{\pi}` + ``M_2_SQRTPI`` Value of :math:`\frac{2}{\sqrt{\pi}}` + ``M_SQRT2`` Value of :math:`\sqrt{2}` + ``M_SQRT1_2`` Value of :math:`\sqrt{\frac{1}{2}}` + ``HUGE_VAL`` Value of :math:`+Inf` (double) + ``HUGE_VALF`` Value of :math:`+Inf` (float) + ``INFINITY`` Value of :math:`+Inf` + ``NAN`` Value of :math:`NaN` + ``MAXFLOAT`` Synonym of ``FLT_MAX`` + ``FP_INFINITE`` :math:`1` + ``FP_NAN`` :math:`0` + ``FP_NORMAL`` :math:`4` + ``FP_SUBNORMAL`` :math:`3` + ``FP_ZERO`` :math:`2` + ``FP_ILOGB0`` Value to return for :ref:`ilogb` (:math:`0`) + ``FP_ILOGBNAN`` Value to return for :ref:`ilogb` (:math:`NaN`) + ================ =============================================== + +*Remark:* Both ``INFINITY`` and ``NAN`` expand to floats or doubles depending on the context. + +Directory Structure and Naming Scheme +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. figure:: ../../figure/libmcs-static-architecture.png + :name: static-architecture + + Folder structure + +The :numref:`Fig. %s ` shows the planned directory and file structure for the ``libm``. As can be seen in the figure the main directory of the ``LibmCS`` will contain eight elements: + +- the library contents are in ``libm``, +- the licenses of all files are in ``LICENSES``, +- the combined license file for the library ``COPYING.md``, +- the credits to the main contributors are in ``CREDITS.md``, +- the explanations on how to contribute to the library are in ``CONTRIBUTING.md``, +- the ``configure`` script to configure the library, +- the ``Makefile`` to build the library, and finally +- there is a ``README.md`` containing general information about the library. + +The ``libm`` directory contains four types of subdirectories: + +- ``include``: This directory contains the header files available to the users. +- ``common``: This directory contains helper functionalities which are used by many library files, for example macros to easily switch between floating-point datums and their integer representation. +- ``math/complex/d/f/l/fe``: These directories contain the implementation files of the mathematical functions. They are named after the header file they cater to and a suffix for the type they contain. Possible suffixes are ``d`` for ``double``-type procedures, ``f`` for ``float``-type procedures, ``fe`` for ``float``-type procedures which use ``double``-type variables/procedures as part of their implementation (thus called ``float-extended``), and ``l`` for ``long double``-type procedures. Some procedures use multiple types for their inputs/outputs but usually have a proper place in this setup; refer to :ref:`Software Components Design – Aspects of Each Component` to see where each file is placed. These directories furthermore each contain an ``internal`` directory which will be used for internal functions which are used by multiple similar functions (e.g., range reduction functions for the trigonometric procedures). Internal functions which are only used by a single function will be placed in their parent function’s file. +- ``machine``: This directory is meant to be used for machine (hardware/toolchain) specific implementations of library functions. In this activity there will only be an example such that the user may include their own implementations for their machine. + +The ``LICENSES`` directory contains a file for each individual license used within the library. All library files contain an :ref:`SPDX `-license-identifier to refer to the licenses within this directory. + +.. figure:: ../../figure/libmcs-include-common.png + :name: include-common + + Folders include and common + +.. figure:: ../../figure/libmcs-real.png + :name: real-procedures + + Real procedures + +.. figure:: ../../figure/libmcs-complex.png + :name: complex-procedures + + Complex procedures + +The C-Functions directly representing a required procedure are named the same as the procedure (e.g., ``asin``, ``asinf``, ``asinl``). The same applies to their filenames with the exception of the ``double``-type versions which have an additional ``d`` suffix (e.g., ``asind.c``), and the ``float-extended``-type which add an ``e`` to the already existing ``f`` suffix. + +Internal procedures shall be named after the procedure they are mainly called by prefixed with a double underscore (e.g., ``__asin``). There is a bit more freedom in the case of multiple internal functions, but all should at least contain the double underscore prefix as well as the procedure name (in some cases it might make sense to use a conglomerate instead of a specific procedure e.g. use ``__trig_rempio2`` for the range reduction function for all trigonometric procedures). The same freedom is given for naming the files containing internal functions: the name should represent the content (e.g., ``trig.c`` contains the internal procedures used by both ``sin`` and ``cos`` as well as the range reduction function used by all three trigonometric functions). + +If the user were to add a separate implementation for a procedure, we suggest to add another suffix using an underscore (e.g., ``expd_table.c`` for a table based implementation of the ``exp`` procedure). Choosing between implementations should be done with changes to the ``Makefile``. diff --git a/libm/libmcs/doc/sdd/5_Software_Design/3_Software_Component_Design_General.rst b/libm/libmcs/doc/sdd/5_Software_Design/3_Software_Component_Design_General.rst new file mode 100644 index 00000000..93fdb24e --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/3_Software_Component_Design_General.rst @@ -0,0 +1,112 @@ +Software Components Design - General +------------------------------------ + +.. raw:: html + + + +fenv.h +~~~~~~ + +Due to requirement REQ-ML-8700: When compiling user software with ``fenv.h`` included the compiler shall throw an error and stop. To achieve this the file shall contain the preprocessing directive ``#error`` before any other statement with an additional message, that if the user removes this error he shall provide his own implementations of these procedures and be aware that they are not part of this qualification effort and need to be qualified separately. + +The library provides an ``fenv.c`` file in the ``libm/common`` directory which contains stub implementations for all ``fenv.h`` procedures which return an error value (:math:`-1`) in line with the ISO C18 standard :ref:`[RD03] `. + +tgmath.h +~~~~~~~~ + +Due to requirement REQ-ML-8800: When compiling user software with ``tgmath.h`` included the compiler shall throw an error and stop. To achieve this the file shall contain the preprocessing directive ``#error`` before any other statement with an additional message, that if the user removes this error he’s left to his own devices and he’s using a not qualified library. + +Long Double +~~~~~~~~~~~ + +The library is limited in that it only offers ``long double`` procedures when ``long double`` has the same size as ``double``. As such there will be no independent implementation of ``long double`` procedures, instead there will only be additional wrappers to call the ``double`` procedures. These wrappers are very simple in that they only have a call to their respective ``double`` version, accompanied by an ``#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS``-structure, to only include the procedure if the preprocessor macro ``LIBMCS_LONG_DOUBLE_IS_64BITS`` is set. For example for ``acoshl``: + +.. code:: c + + #include + + #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + long double acoshl (long double x) + { + return acosh(x); + } + #endif + +As all the ``long double`` procedures look the same there is no need to add them to :ref:`Software Components Design – Aspects of Each Component` individually. + +Handling of Subnormal Numbers +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Each of the procedures defined in ``math.h`` and ``complex.h`` shall enforce the behaviour of the :ref:`FPU ` regarding subnormal numbers if the preprocessor macro ``LIBMCS_FPU_DAZ`` is set (for example during the ``make`` call). This is done by multiplying all floating point input arguments with :math:`1.0` to force the compiler to move the argument into an :ref:`FPU ` register (care needs to be taken that the multiplication can not be thrown out by the compiler, for example by using a volatile variable to contain the :math:`1.0`). Depending on the :ref:`FPU `'s configuration copying a subnormal value into an :ref:`FPU ` register will either + +- set the register to zero (this would be :ref:`DAZ ` behaviour, and can for example be seen when using a GRFPU set to non-standard mode), +- produce an appropriate :ref:`FPU ` exception (for example a GRFPU without being set to the non-standard mode), +- set the register to the input argument in case the :ref:`FPU ` is able to handle subnormal inputs (for example a MEIKO FPU), +- or do whatever else the :ref:`FPU ` does in case of a subnormal input, + +thus enforcing the inherent behaviour of the :ref:`FPU ` to be represented by the library. + +No procedure shall be able to generate subnormal numbers if the preprocessor macro ``LIBMCS_FPU_DAZ`` is set on a platform that can not produce subnormals. When using the preprocessor macro it is up to the user to inhibit their platform if it is inherently able to produce subnormals. + +NaNs +~~~~ + +All procedures accept ``NaNs`` of both varieties, quiet and signaling, as valid inputs. In case the input is a signaling ``NaN``, an invalid operation exception will be raised by the :ref:`FPU ` (except for the procedures ``fabs`` and ``copysign``), and a quiet ``NaN`` will be returned (unless there is a special case that returns a result different to ``NaN``). + +The procedures will never produce a signaling ``NaN`` and only return quiet ``NaNs`` (except for the procedures ``fabs`` and ``copysign``). The procedures use the :ref:`FPU ` to generate :ref:`FPU ` native ``NaNs`` if ``NaNs`` need to be produced artificially. Trying to produce fixed ``NaNs`` would slow down the whole code since there would be a need to check everywhere and produce the *artificial* ``NaNs``. As the overall numerical code will anyways produce :ref:`FPU ` native ``NaNs``, it would also not help the reproducibility objective. + +In case any of the inputs of a procedure is ``NaN`` and the output also is a ``NaN``, the procedure does not necessarily return the (or one of the) input ``NaN`` but may produce a different one. + +The tables within this document will not differentiate between quiet and signaling ``NaNs`` as inputs as the behaviour is always the same. + +In some places of this document there will be ``NaNs`` accompanied by a sign, this is to symbolize that the signbit of the ``NaN`` is set or not to be used by the ``fabs`` and ``copysign`` procedures. + +Exceptions +~~~~~~~~~~ + +The library causes the :ref:`FPU ` to produce exceptions. Those exceptions are ``invalid operation``, ``divide-by-zero``, ``overflow``, ``underflow``, and ``inexact``. This :ref:`SDD ` details where the exceptions are intentionally produced but not when they appear during a mathematical operation within the procedure. A comprehensive list of all exceptions thrown by each procedure can be found in :ref:`Software Components Design – Aspects of Each Component`. + +Errno +~~~~~ + +The library does not set the ``errno`` variable to report errors. It is explicitly ignored and will not be defined or changed as to not interfere with the user using ``errno`` elsewhere in their project. + +Implementation Tricks +~~~~~~~~~~~~~~~~~~~~~ + +The implementation of the library employs a number of tricks to achieve the intended results. For example the following tricks are used: + +- ``if (huge+x>0) return x;`` is used to produce an ``inexact`` exception for ``x`` close to zero (``huge`` is a very large floating point number). Producing the exception is ``huge+x``, as ``huge`` is a lot larger than ``x`` and in turn the result cannot be an exact value, unless ``x`` is zero. This calculation is placed into an if-clause to ensure that the compiler may not remove the calculation during optimization. As this if-clause is always true, it creates an unreachable branch. This downside however is offset by producing the intended results. +- ``if (x is not finite) return x+x;`` is used when ``x`` is either infinite or ``NaN`` to return a same signed infinity or the ``NaN``. The addition is needed to create the ``invalid operation`` exception in the case a signaling ``NaN`` was used as input. +- ``if (x is not finite) return x-x;`` is used when ``x`` is either infinite or ``NaN`` to return ``NaN``. Subtracting two same signed infinity values produces a ``NaN`` as result as well as an ``invalid operation`` exception. +- ``return (x-x)/zero;`` is used to produce a ``NaN`` regardless of the input value. This statement also produces an ``invalid operation`` exception by dividing zero by zero (or in the case of an infinite ``x``, even earlier). +- ``return x/zero;`` is used to produce an infinity with the sign of ``x``. This statement also produces a ``divide-by-zero`` exception. This trick shall not be used when ``x`` is zero. diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0000_Software_Component_Design_Aspects_Of_Each_Component.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0000_Software_Component_Design_Aspects_Of_Each_Component.rst new file mode 100644 index 00000000..590ac382 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0000_Software_Component_Design_Aspects_Of_Each_Component.rst @@ -0,0 +1,315 @@ +Software Components Design – Aspects of Each Component +------------------------------------------------------ + +.. raw:: html + + + +Classification Macros +""""""""""""""""""""" + +.. toctree:: + :maxdepth: 1 + + 0010_fpclassify.rst + 0020_isfinite.rst + 0030_isinf.rst + 0040_isnan.rst + 0050_isnormal.rst + 0060_signbit.rst + +Trigonometric Functions +""""""""""""""""""""""" + +.. toctree:: + :maxdepth: 1 + + 0100_acos.rst + 0110_asin.rst + 0120_atan.rst + 0130_atan2.rst + 0140_cos.rst + 0150_sin.rst + 0160_tan.rst + 0170_trig.rst + +Hyperbolic Functions +"""""""""""""""""""" + +.. toctree:: + :maxdepth: 1 + + 0200_acosh.rst + 0210_asinh.rst + 0220_atanh.rst + 0230_cosh.rst + 0240_sinh.rst + 0250_tanh.rst + +Exponential and Logarithmic Functions +""""""""""""""""""""""""""""""""""""" + +.. toctree:: + :maxdepth: 1 + + 0300_exp.rst + 0310_exp2.rst + 0320_expm1.rst + 0330_frexp.rst + 0340_ilogb.rst + 0350_ldexp.rst + 0360_log.rst + 0370_log10.rst + 0380_log1p.rst + 0390_log2.rst + 0400_logb.rst + 0410_modf.rst + 0420_scalbn.rst + 0430_scalbln.rst + 0440_log_internal.rst + +Power and Absolute-value Functions +"""""""""""""""""""""""""""""""""" + +.. toctree:: + :maxdepth: 1 + + 0500_cbrt.rst + 0510_fabs.rst + 0520_hypot.rst + 0530_pow.rst + 0540_sqrt.rst + +Error and Gamma Functions +""""""""""""""""""""""""" + +.. toctree:: + :maxdepth: 1 + + 0600_erf.rst + 0610_erfc.rst + 0620_lgamma.rst + 0630_tgamma.rst + 0640_gamma_internal.rst + 0650_signgam.rst + +Nearest Integer Functions +""""""""""""""""""""""""" + +.. toctree:: + :maxdepth: 1 + + 0700_ceil.rst + 0710_floor.rst + 0720_nearbyint.rst + 0730_rint.rst + 0740_lrint.rst + 0750_llrint.rst + 0760_round.rst + 0770_lround.rst + 0780_llround.rst + 0790_trunc.rst + +Remainder Functions +""""""""""""""""""" + +.. toctree:: + :maxdepth: 1 + + 0900_fmod.rst + 0910_remainder.rst + 0920_remquo.rst + +Manipulation Functions +"""""""""""""""""""""" + +.. toctree:: + :maxdepth: 1 + + 1000_copysign.rst + 1010_nan.rst + 1020_nextafter.rst + 1030_nexttoward.rst + +Maximum, Minimum and Positive Difference Functions +"""""""""""""""""""""""""""""""""""""""""""""""""" + +.. toctree:: + :maxdepth: 1 + + 1100_fdim.rst + 1110_fmax.rst + 1120_fmin.rst + +Floating Multiply-Add +""""""""""""""""""""" + +.. toctree:: + :maxdepth: 1 + + 1200_fma.rst + +Comparison Macros +""""""""""""""""" + +.. toctree:: + :maxdepth: 1 + + 1300_isgreater.rst + 1310_isgreaterequal.rst + 1320_isless.rst + 1330_islessequal.rst + 1340_islessgreater.rst + 1350_isunordered.rst + +Bessel Functions (POSIX) +"""""""""""""""""""""""" + +.. toctree:: + :maxdepth: 1 + + 1400_j0.rst + 1410_j1.rst + 1420_jn.rst + 1430_y0.rst + 1440_y1.rst + 1450_yn.rst + +Complex Trigonometric Functions +""""""""""""""""""""""""""""""" + +.. toctree:: + :maxdepth: 1 + + 1500_cacos.rst + 1510_casin.rst + 1520_catan.rst + 1530_ccos.rst + 1540_csin.rst + 1550_ctan.rst + +Complex Hyperbolic Functions +"""""""""""""""""""""""""""" + +.. toctree:: + :maxdepth: 1 + + 1600_cacosh.rst + 1610_casinh.rst + 1620_catanh.rst + 1630_ccosh.rst + 1640_csinh.rst + 1650_ctanh.rst + +Complex Exponential and Logarithmic Functions +""""""""""""""""""""""""""""""""""""""""""""" + +.. toctree:: + :maxdepth: 1 + + 1700_cexp.rst + 1710_clog.rst + +Complex Power and Absolute-value Functions +"""""""""""""""""""""""""""""""""""""""""" + +.. toctree:: + :maxdepth: 1 + + 1800_cabs.rst + 1810_cpow.rst + 1820_csqrt.rst + +Complex Manipulation Functions +"""""""""""""""""""""""""""""" + +.. toctree:: + :maxdepth: 1 + + 1900_carg.rst + 1910_cimag.rst + 1920_cmplx.rst + 1930_conj.rst + 1940_cproj.rst + 1950_creal.rst + +Miscellaneous Internal Functions +"""""""""""""""""""""""""""""""" + +.. toctree:: + :maxdepth: 1 + + 2000_misc_internal.rst + +Build and Configuration Files +""""""""""""""""""""""""""""" + +.. toctree:: + :maxdepth: 1 + + 3000_configure.rst + 3100_makefile.rst diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0010_fpclassify.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0010_fpclassify.rst new file mode 100644 index 00000000..b2272a8b --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0010_fpclassify.rst @@ -0,0 +1,54 @@ +fpclassify +~~~~~~~~~~ + +.. c:autodoc:: mathd/internal/fpclassifyd.c + +Special cases +^^^^^^^^^^^^^ + ++------------------------------+--------------------------+ +| x | Result | ++==============================+==========================+ +| :math:`±0` | ``FP_ZERO`` | ++------------------------------+--------------------------+ +| :math:`\in \mathbb{S}` | ``FP_SUBNORMAL`` | ++------------------------------+--------------------------+ +| :math:`±Inf` | ``FP_INFINITE`` | ++------------------------------+--------------------------+ +| :math:`NaN` | ``FP_NAN`` | ++------------------------------+--------------------------+ +| all others | ``FP_NORMAL`` | ++------------------------------+--------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +The approach is to call one of two internal procedures named ``__fpclassifyd`` or ``__fpclassifyf`` depending on the type of the input. These procedures follow the following approach: + +#. For :math:`x` is :math:`-0` or :math:`+0`, return ``FP_ZERO``. +#. For :math:`x` is finite and not subnormal, return ``FP_NORMAL``. +#. For :math:`x` is subnormal, return ``FP_SUBNORMAL``. +#. For :math:`x` is infinite (:math:`±Inf`), return ``FP_INFINITE``. +#. For :math:`x` is :math:`NaN`, return ``FP_NAN``. + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-5700 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/internal/fpclassifyd.c +* libm/mathf/internal/fpclassifyf.c + +References +^^^^^^^^^^ + +* :numref:`Tbl. %s ` +* :ref:`isfinite` +* :ref:`isinf` +* :ref:`isnan` +* :ref:`isnormal` +* :ref:`isunordered` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0020_isfinite.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0020_isfinite.rst new file mode 100644 index 00000000..312f7fd1 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0020_isfinite.rst @@ -0,0 +1,34 @@ +isfinite +~~~~~~~~ + +.. c:autodoc:: common/isfinite.c + +Special cases +^^^^^^^^^^^^^ + +This macro does not have special cases. + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +The approach is to call ``fpclassify`` and decide on the return value depending on the result: + +#. Call ``fpclassify`` with input :math:`x`, return :math:`0` if the call returned ``FP_INFINITE`` or ``FP_NAN``. +#. Else return :math:`1`. + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-1300 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/common/isfinite.c + +References +^^^^^^^^^^ + +* :ref:`fpclassify` +* :ref:`ldexp` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0030_isinf.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0030_isinf.rst new file mode 100644 index 00000000..c102d926 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0030_isinf.rst @@ -0,0 +1,34 @@ +isinf +~~~~~ + +.. c:autodoc:: common/isinf.c + +Special cases +^^^^^^^^^^^^^ + +This macro does not have special cases. + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +The approach is to call ``fpclassify`` and decide on the return value depending on the result: + +#. Call ``fpclassify`` with input :math:`x`, return :math:`1` if the call returned ``FP_INFINITE``. +#. Else return :math:`0`. + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-1320 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/common/isinf.c + +References +^^^^^^^^^^ + +* :ref:`cproj` +* :ref:`fpclassify` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0040_isnan.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0040_isnan.rst new file mode 100644 index 00000000..e9de3c80 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0040_isnan.rst @@ -0,0 +1,34 @@ +isnan +~~~~~ + +.. c:autodoc:: common/isnan.c + +Special cases +^^^^^^^^^^^^^ + +This macro does not have special cases. + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +The approach is to call ``fpclassify`` and decide on the return value depending on the result: + +#. Call ``fpclassify`` with input :math:`x`, return :math:`1` if the call returned ``FP_NAN``. +#. Else return :math:`0`. + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-1340 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/common/isnan.c + +References +^^^^^^^^^^ + +* :ref:`fpclassify` +* :ref:`nexttowardf ` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0050_isnormal.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0050_isnormal.rst new file mode 100644 index 00000000..c8408640 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0050_isnormal.rst @@ -0,0 +1,33 @@ +isnormal +~~~~~~~~ + +.. c:autodoc:: common/isnormal.c + +Special cases +^^^^^^^^^^^^^ + +This macro does not have special cases. + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +The approach is to call ``fpclassify`` and decide on the return value depending on the result: + +#. Call ``fpclassify`` with input :math:`x`, return :math:`1` if the call returned ``FP_NORMAL``. +#. Else return :math:`0`. + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-5500 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/common/isnormal.c + +References +^^^^^^^^^^ + +* :ref:`fpclassify` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0060_signbit.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0060_signbit.rst new file mode 100644 index 00000000..7447c83c --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0060_signbit.rst @@ -0,0 +1,34 @@ +signbit +~~~~~~~ + +.. c:autodoc:: mathd/internal/signbitd.c + +Special cases +^^^^^^^^^^^^^ + +This macro does not have special cases. + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +The approach is to call one of two internal procedures named ``__signbitd`` or ``__signbitf`` depending on the type of the input. These procedures follow the following approach: + +#. Use a mask to get the sign bit of the input value. +#. If the sign bit is set, return :math:`1`, else return :math:`0`. + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-1360 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/internal/signbitd.c +* libm/mathf/internal/signbitf.c + +References +^^^^^^^^^^ + +* :ref:`nexttowardf ` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0100_acos.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0100_acos.rst new file mode 100644 index 00000000..7bb82944 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0100_acos.rst @@ -0,0 +1,118 @@ +acos +~~~~ + +.. c:autodoc:: mathd/acosd.c + +Special cases +^^^^^^^^^^^^^ + ++--------------------------+--------------------------+ +| x | Result | ++==========================+==========================+ +| :math:`+1` | :math:`+0` | ++--------------------------+--------------------------+ +| :math:`\notin [-1, 1]` | :math:`qNaN` | ++--------------------------+--------------------------+ +| :math:`±Inf` | :math:`qNaN` | ++--------------------------+--------------------------+ +| :math:`NaN` | :math:`qNaN` | ++--------------------------+--------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +The approach is to first work on special values and then use rational approximation for the calculation. + +The ``acos`` functionality is highly similar to the :ref:`asin` function, therefore it will be heavily referenced here even though it is not called. Assume all mentioned constants that are not expressed here, are taken from :ref:`asin`. + +Use the following constants as calculation/return values: + +* :math:`\pi \approx PI =` ``0x400921FB54442D18 (0x40490FDA)`` + +#. For :math:`x` is ``NaN``, return ``qNaN``. +#. For :math:`|x| > 1`, return ``qNaN``. +#. For :math:`x` is :math:`1`, return :math:`0`. +#. For :math:`x` is :math:`-1`, return :math:`PI`. +#. For :math:`|x| < 2^{-57}`, return :math:`pio2_{hi} + pio2_{lo}`. +#. All the following return values shall have the same sign as the input value. +#. The following identity provides the reason ``acos`` and :ref:`asin` are so closely related: + + .. math:: + :label: formula_acos_1 + + cos^{-1}(x) &= \frac{\pi}{2} - sin^{-1}(x) \\ + \wedge \qquad cos^{-1}(-x) &= \frac{\pi}{2} + sin^{-1}(x) + + #. For :math:`|x| < 0.5`: + + #. Using the identity shown in formula :math:numref:`formula_acos_1` and converting the approximation of :ref:`asin` shown in formula :math:numref:`formula_asin_2` to approximate ``acos`` as: + + .. math:: + :label: formula_acos_2 + + acos(x) = \frac{\pi}{2} - (x + x \cdot x^2 \cdot R(x^2)) + + #. Return [#]_ :math:`pio2_{hi} - (x - (pio2_{lo} - x \cdot R(x^2)))`. + + #. For the following steps use formula :math:numref:`formula_asin_4` to reduce the range. + #. For :math:`x <= -0.5`: + + \item With formula :math:numref:`formula_acos_1` and :math:numref:`formula_acos_2`, as well as applying the range reduction, the approximation of ``acos`` changes to: + + .. math:: + :label: formula_acos_3 + + acos(x) &= \pi - 2 \cdot (s + s \cdot z \cdot R(z)) \\ + &= PI - 2 \cdot (s+s \cdot z \cdot R(z) - pio2_{lo}) + + with + + #. :math:`z = \frac{1-|x|}{2}` + #. :math:`s = \sqrt{z}` + + #. Return the result of the approximation. + + #. Otherwise (:math:`x >= 0.5`): + + #. With formula :math:numref:`formula_acos_1` and :math:numref:`formula_acos_2`, as well as applying the range reduction, the approximation of ``acos`` changes to: + + .. math:: + :label: formula_acos_4 + + acos(x) &= \frac{\pi}{2} - \Big(\frac{\pi}{2} - 2 \cdot \big(s + s \cdot z \cdot R(z)\big)\Big) \\ + &= 2 \cdot (s + s \cdot z \cdot R(z)) \\ + &= 2s + 2s \cdot z \cdot R(z) \\ + &= (2f + 2c) + (2s \cdot z \cdot R(z)) \\ + &= 2 \cdot (f + (c + s \cdot z \cdot R(z))) + + with + + #. :math:`f =` ``highword`` of :math:`s` (float: :math:`f =` integer representation of :math:`s` with the last 12 bits masked to 0) + #. :math:`c = \frac{z-f^2}{s+f}`, which is the correction term for :math:`f` so that :math:`f+c \sim \sqrt{z}` + + #. Return the result of the approximation. + +.. [#] Formula :math:numref:`formula_acos_2` with some accuracy improvements + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-0450 +* REQ-ML-0460 +* REQ-ML-0470 +* REQ-ML-0480 +* REQ-ML-0490 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/mathd/acosd.c +* libm/mathf/mathf/acosf.c + +References +^^^^^^^^^^ + +* :ref:`asin` +* :ref:`cos` +* :ref:`sqrt` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0110_asin.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0110_asin.rst new file mode 100644 index 00000000..fc2b070d --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0110_asin.rst @@ -0,0 +1,136 @@ +asin +~~~~ + +.. c:autodoc:: mathd/asind.c + +Special cases +^^^^^^^^^^^^^ + ++--------------------------+--------------------------+ +| x | Result | ++==========================+==========================+ +| :math:`±0` | :math:`x` | ++--------------------------+--------------------------+ +| :math:`\notin [-1, 1]` | :math:`qNaN` | ++--------------------------+--------------------------+ +| :math:`±Inf` | :math:`qNaN` | ++--------------------------+--------------------------+ +| :math:`NaN` | :math:`qNaN` | ++--------------------------+--------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +The approach is to first work on special values and then use rational approximation for the calculation. + +Use the following constants as calculation/return values: + +* :math:`\frac{\pi}{2} \approx pio2_{hi} + pio2_{lo}` +* :math:`pio2_{hi} =` ``0x3FF921FB54442D18 (0x3FC90FDB)`` +* :math:`pio2_{lo} =` ``0x3C91A62633145C07 (0xC08BE05E)`` +* :math:`pio4_{hi} = \frac{pio2_{hi}}{2} =` ``0x3FE921FB54442D18 (0x3F490FDB)`` +* :math:`P0 =` ``0x3FC5555555555555 (0x3E2AAAAB)`` +* :math:`P1 =` ``0xBFD4D61203EB6F7D (0xBEA6B090)`` +* :math:`P2 =` ``0x3FC9C1550E884455 (0x3E4E0AA8)`` +* :math:`P3 =` ``0xBFA48228B5688F3B (0xBD241146)`` +* :math:`P4 =` ``0x3F49EFE07501B288 (0x3A4F7F04)`` +* :math:`P5 =` ``0x3F023DE10DFDF709 (0x3811EF08)`` +* :math:`Q1 =` ``0xC0033A271C8A2D4B (0xC019D139)`` +* :math:`Q2 =` ``0x40002AE59C598AC8 (0x4001572D)`` +* :math:`Q3 =` ``0xBFE6066C1B8D0159 (0xBF303361)`` +* :math:`Q4 =` ``0x3FB3B8C5B12E9282 (0x3D9DC62E)`` + +#. For :math:`x` is ``NaN``, return ``qNaN``. +#. For :math:`|x| > 1`, return ``qNaN``. +#. For :math:`|x|` is :math:`1`, return :math:`x \cdot pio2_{hi} + x \cdot pio2_{lo}`. +#. For :math:`|x| < 2^{-57}`, return :math:`pio2_{hi} + pio2_{lo}`. +#. All the following return values shall have the same sign as the input value. +#. For :math:`|x| < 0.5` [#]_: + + #. Use the identity + + .. math:: + :label: formula_asin_1 + + sin^{-1}(x) &= x + \frac{1}{2} \frac{x^3}{3} + \frac{1 \cdot 3}{2 \cdot 4} \frac{x^5}{5} + ... \\ + &= \sum\limits_{i=0}^{\infty} \frac{\binom{2i}{i} \cdot x^{2i+1}}{4^i \cdot (2i+1)} + + to approximate ``asin`` as: + + .. math:: + :label: formula_asin_2 + + asin(x) &= x + x \cdot x^2 \cdot R(x^2) \nonumber \\ + R(x^2) &= \frac{asin(x)-x}{x^3} + + #. :math:`R(x^2)` can be rationally approximated with [#]_: + + .. math:: + :label: formula_asin_3 + + t &= x^2 \\ + R(t) &\sim \frac{P0 \cdot t + P1 \cdot t^2 + P2 \cdot t^3 + P3 \cdot t^4 + P4 \cdot t^5 + P5 \cdot t^6}{1 + Q1 \cdot t + Q2 \cdot t^2 + Q3 \cdot t^3 + Q4 \cdot t^4} + + The error of this approximation is smaller than :math:`2^{-58.75}`. + #. Return :math:`x + x \cdot R(t)`. + +#. Use the identity (set :math:`x = |x|`, use :ref:`fabs` to calculate the absolute value [#]_) + + .. math:: + :label: formula_asin_4 + + sin^{-1}(x) = \frac{\pi}{2} - 2 \cdot sin^{-1}\bigg(\sqrt{\frac{1-x}{2}}\bigg) + + for range reduction purposes. +#. Let :math:`y = (1-x)`, :math:`z = \frac{y}{2}`, :math:`s = \sqrt{z}`, and split :math:`\frac{\pi}{2}` into :math:`pio2_{hi}` and :math:`pio2_{lo}` for more accuracy, then: + + #. For :math:`|x| >= 0.975` [#]_, return + + .. math:: + :label: formula_asin_5 + + asin(x) &= \frac{\pi}{2} - 2 \cdot (s + s \cdot z \cdot R(z)) \\ + &= pio2_{hi} - (2 \cdot (s + s \cdot z \cdot R(z)) - pio2_{lo}) + + with + + #. :math:`R(z)` approximated as in :math:numref:`formula_asin_3`. + #. Use :ref:`sqrt` to calculate the square root of :math:`z`. + + #. Otherwise, let :math:`pio4_{hi} = \frac{pio2_{hi}}{2}`, :math:`f =` highword of :math:`s` (float: :math:`f =` integer representation of :math:`s` with the last 12 bits masked to 0), :math:`c = \sqrt{z} - f = \frac{z-f^2}{s+f}`, then return + + .. math:: + :label: formula_asin_6 + + asin(x) &= \frac{\pi}{2} - 2 \cdot (s + s \cdot z \cdot R(z)) \\ + &= pio4_{hi} + (pio4_{hi} - 2s) - (2 \cdot s \cdot z \cdot R(z) - pio2_{lo}) \\ + &= pio4_{hi} - \Big(\big(2 \cdot s \cdot z \cdot R(z) - (pio2_{lo}+2c)\big) - (pio4_{hi} - 2f)\Big) + +.. [#] This implementation of ``asin`` is a variation of the algorithm proposed by W. J. Cody, Jr. and W. Waite in *Software Manual for the Elementary Functions*. +.. [#] Use Horner's method for implementation. +.. [#] Remember that the final results still have the same sign as the initial :math:`x`! +.. [#] Use ``highword`` :math:`>=` ``0x3FEF3333`` (float: use integer representation of :math:`x >=` ``0x3F79999A``). + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-0250 +* REQ-ML-0260 +* REQ-ML-0270 +* REQ-ML-0280 +* REQ-ML-0281 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/asind.c +* libm/mathf/asinf.c + +References +^^^^^^^^^^ + +* :ref:`acos` +* :ref:`fabs` +* :ref:`sin` +* :ref:`sqrt` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0120_atan.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0120_atan.rst new file mode 100644 index 00000000..bc43dc71 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0120_atan.rst @@ -0,0 +1,145 @@ +atan +~~~~ + +.. c:autodoc:: mathd/atand.c + +Special cases +^^^^^^^^^^^^^ + ++--------------------------+--------------------------+ +| x | Result | ++==========================+==========================+ +| :math:`±0` | :math:`x` | ++--------------------------+--------------------------+ +| :math:`-Inf` | :math:`-\frac{\pi}{2}` | ++--------------------------+--------------------------+ +| :math:`+Inf` | :math:`+\frac{\pi}{2}` | ++--------------------------+--------------------------+ +| :math:`NaN` | :math:`qNaN` | ++--------------------------+--------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +The approach is to first work on special values and then use rational approximation for the calculation. + +Use the following constants as calculation/return values: + +* :math:`tan^{-1}(0.5) \approx atan0.5_{hi} + atan0.5_{lo}` +* :math:`atan0.5_{hi} =` ``0x3FDDAC670561BB4F (0x3EED6338)`` +* :math:`atan0.5_{lo} =` ``0x3C7A2B7F222F65E2 (0x31AC3769)`` +* :math:`tan^{-1}(1) = \frac{\pi}{4} \approx atan1_{hi} + atan1_{lo}` +* :math:`atan1_{hi} =` ``0x3FE921FB54442D18 (0x3F490FDA)`` +* :math:`atan1_{lo} =` ``0x3C81A62633145C07 (0x33222168)`` +* :math:`tan^{-1}(1.5) \approx atan1.5_{hi} + atan1.5_{lo}` +* :math:`atan1.5_{hi} =` ``0x3FEF730BD281F69B (0x3F7B985E)`` +* :math:`atan1.5_{lo} =` ``0x3C7007887AF0CBBD (0x33140FB4)`` +* :math:`\lim\limits_{n \rightarrow \infty}tan^{-1}(n) = \frac{\pi}{2} \approx atanInf_{hi} + atanInf_{lo}` +* :math:`atanInf_{hi} =` ``0x3FF921FB54442D18 (0x3FC90FDA)`` +* :math:`atanInf_{lo} =` ``0x3C91A62633145C07 (0x33A22168)`` +* :math:`A0 =` ``0x3FD555555555550D (0x3EAAAAAA)`` +* :math:`A1 =` ``0xBFC999999998EBC4 (0xBE4CCCCD)`` +* :math:`A2 =` ``0x3FC24924920083FF (0x3E124925)`` +* :math:`A3 =` ``0xBFBC71C6FE231671 (0xBDE38E38)`` +* :math:`A4 =` ``0x3FB745CDC54C206E (0x3DBA2E6E)`` +* :math:`A5 =` ``0xBFB3B0F2AF749A6D (0xBD9D8795)`` +* :math:`A6 =` ``0x3FB10D66A0D03D51 (0x3D886B35)`` +* :math:`A7 =` ``0xBFADDE2D52DEFD9A (0xBD6EF16B)`` +* :math:`A8 =` ``0x3FA97B4B24760DEB (0x3D4BDA59)`` +* :math:`A9 =` ``0xBFA2B4442C6A6C2F (0xBD15A221)`` +* :math:`A10 =` ``0x3F90AD3AE322DA11 (0x3C8569D7)`` + +#. For :math:`x` is ``NaN``, return ``qNaN``. +#. For :math:`|x| > 2^{66}` (float: :math:`|x| > 2^{34}`), return :math:`atanInf_{hi} + atanInf_{lo}` (which represents :math:`\frac{\pi}{2}`) with the sign of :math:`x`. +#. For :math:`|x| < 2^{-27}`, return :math:`x`. +#. Use the identity :math:`tan^{-1}(x) = -tan^{-1}(-x)` to reduce :math:`x` to positive. +#. For :math:`x < \frac{7}{16}` [#]_, use the identity + + .. math:: + :label: formula_atan_1 + + tan^{-1}(x) &= x - \frac{x^3}{3} + \frac{x^5}{5} - \frac{x^7}{7} + ... \\ + &= \sum\limits_{i=0}^{\infty} \frac{(-1)^i \cdot x^{2i+1}}{2i+1} + + to approximate ``atan`` rationally as [#]_: + + .. math:: + :label: formula_atan_2 + + atan(x) = & x - x \cdot R(x) \\ + R(x) = & A0 \cdot x^2 - A1 \cdot x^4 + A2 \cdot x^6 - A3 \cdot x^8 + A4 \cdot x^{10} - A5 \cdot x^{12} \\ + &+ A6 \cdot x^{14} - A7 \cdot x^{16} + A8 \cdot x^{18} - A9 \cdot x^{20} + A10 \cdot x^{22} + +#. If :math:`x < \frac{11}{16}` [#]_, use the identity :math:`tan^{-1}(x) = tan^{-1}(\frac{1}{2}) + tan^{-1}(\frac{x-\frac{1}{2}}{1+\frac{x}{2}})` to modify the approximation of ``atan`` as in formula :math:numref:`formula_atan_2` to: + + .. math:: + :label: formula_atan_3 + + z &= \frac{2x - 1}{2 + x} \\ + atan(x) &= tan^{-1}\Big(\frac{1}{2}\Big) + (z - z \cdot R(z)) \\ + &= atan0.5_{hi} - ((z \cdot R(z) - atan0.5_{lo}) - z) + +#. If :math:`x < \frac{19}{16}` [#]_, use the identity :math:`tan^{-1}(x) = tan^{-1}(1) + tan^{-1}(\frac{x-1}{1+x}) = \frac{\pi}{4} + tan^{-1}(\frac{x-1}{1+x})` to modify the approximation of ``atan`` to: + + .. math:: + :label: formula_atan_4 + + z &= \frac{x - 1}{x + 1} \\ + atan(x) &= \frac{\pi}{4} + (z - z \cdot R(z)) \\ + &= atan1_{hi} - ((z \cdot R(z) - atan1_{lo}) - z) + +#. If :math:`x < \frac{39}{16}` [#]_, use the identity :math:`tan^{-1}(x) = tan^{-1}(\frac{3}{2}) + tan^{-1}(\frac{x-\frac{3}{2}}{1+\frac{3}{2}x})` to modify the approximation of ``atan`` to: + + .. math:: + :label: formula_atan_5 + + z &= \frac{2x-3}{2+3x} \\ + atan(x) &= tan^{-1}\Big(\frac{3}{2}\Big) + (z - z \cdot R(z)) \\ + &= atan1.5_{hi} - ((z \cdot R(z) - atan1.5_{lo}) - z) + +#. Otherwise (:math:`x >= \frac{39}{16}`), use the identity :math:`tan^{-1}(x) = \lim\limits_{n \rightarrow \infty}(tan^{-1}(n)) + tan^{-1}(-\frac{1}{x}) = \frac{\pi}{2} + tan^{-1}(-\frac{1}{x})` to modify the approximation of ``atan`` to: + + .. math:: + :label: formula_atan_6 + + z &= -\frac{1}{x} \\ + atan(x) &= \frac{\pi}{2} + (z - z \cdot R(z)) \\ + &= atanInf_{hi} - ((z \cdot R(z) - atanInf_{lo}) - z) + +#. Return the result of the appropriate approximation, with the sign of the original input value. + +.. raw:: html + + + +.. [#] Test with ``highword`` :math:`<` ``0x3FDC0000``. (float: use integer representation of :math:`x >=` ``0x3EE00000``). +.. [#] Use Horner's method for implementation. +.. [#] Test with ``highword`` :math:`<` ``0x3FE60000``. (float: use integer representation of :math:`x >=` ``0x3F300000``). +.. [#] Test with ``highword`` :math:`<` ``0x3FF30000``. (float: use integer representation of :math:`x >=` ``0x3F980000``). +.. [#] Test with ``highword`` :math:`<` ``0x40038000``. (float: use integer representation of :math:`x >=` ``0x401C0000``). + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-0600 +* REQ-ML-0610 +* REQ-ML-0620 +* REQ-ML-0621 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/atand.c +* libm/mathf/atanf.c + +References +^^^^^^^^^^ + +* :ref:`atan2` +* :ref:`fabs` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0130_atan2.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0130_atan2.rst new file mode 100644 index 00000000..8fc546c7 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0130_atan2.rst @@ -0,0 +1,139 @@ +atan2 +~~~~~ + +.. c:autodoc:: mathd/atan2d.c + +Special cases +^^^^^^^^^^^^^ + ++------------------------+------------------------------+--------------------------+ +| x | y | Result | ++========================+==============================+==========================+ +| :math:`<0` | :math:`-0` | :math:`-\pi` | ++------------------------+------------------------------+--------------------------+ +| :math:`<0` | :math:`+0` | :math:`+\pi` | ++------------------------+------------------------------+--------------------------+ +| :math:`-0` | :math:`-0` | :math:`-\pi` | ++------------------------+------------------------------+--------------------------+ +| :math:`-0` | :math:`+0` | :math:`+\pi` | ++------------------------+------------------------------+--------------------------+ +| :math:`±0` | :math:`<0` | :math:`-\frac{\pi}{2}` | ++------------------------+------------------------------+--------------------------+ +| :math:`±0` | :math:`>0` | :math:`+\frac{\pi}{2}` | ++------------------------+------------------------------+--------------------------+ +| :math:`+0` | :math:`-0` | :math:`-0` | ++------------------------+------------------------------+--------------------------+ +| :math:`+0` | :math:`+0` | :math:`+0` | ++------------------------+------------------------------+--------------------------+ +| :math:`>0` | :math:`-0` | :math:`-0` | ++------------------------+------------------------------+--------------------------+ +| :math:`>0` | :math:`+0` | :math:`+0` | ++------------------------+------------------------------+--------------------------+ +| :math:`-Inf` | :math:`<0 \wedge \neq -Inf` | :math:`-\pi` | ++------------------------+------------------------------+--------------------------+ +| :math:`-Inf` | :math:`>0 \wedge \neq +Inf` | :math:`+\pi` | ++------------------------+------------------------------+--------------------------+ +| :math:`+Inf` | :math:`<0 \wedge \neq -Inf` | :math:`-0` | ++------------------------+------------------------------+--------------------------+ +| :math:`+Inf` | :math:`>0 \wedge \neq +Inf` | :math:`+0` | ++------------------------+------------------------------+--------------------------+ +| :math:`\neq ±Inf` | :math:`-Inf` | :math:`-\frac{\pi}{2}` | ++------------------------+------------------------------+--------------------------+ +| :math:`\neq ±Inf` | :math:`+Inf` | :math:`+\frac{\pi}{2}` | ++------------------------+------------------------------+--------------------------+ +| :math:`-Inf` | :math:`-Inf` | :math:`-\frac{3 \pi}{4}` | ++------------------------+------------------------------+--------------------------+ +| :math:`-Inf` | :math:`+Inf` | :math:`+\frac{3 \pi}{4}` | ++------------------------+------------------------------+--------------------------+ +| :math:`+Inf` | :math:`-Inf` | :math:`-\frac{\pi}{4}` | ++------------------------+------------------------------+--------------------------+ +| :math:`+Inf` | :math:`+Inf` | :math:`+\frac{\pi}{4}` | ++------------------------+------------------------------+--------------------------+ +| :math:`NaN` | :math:`\in \mathbb{F}` | :math:`qNaN` | ++------------------------+------------------------------+--------------------------+ +| :math:`\in \mathbb{F}` | :math:`NaN` | :math:`qNaN` | ++------------------------+------------------------------+--------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +The approach is to first work on special values and then use :ref:`atan` for the calculation. + +Use the following constants as calculation/return values: + +* :math:`\pi \approx PI + PI_{lo}` +* :math:`PI =` ``0x400921FB54442D18 (0x40490FDB)`` +* :math:`PI_{lo} =` ``0x3CA1A62633145C07 (0xB3BBBD2E)`` +* :math:`\frac{\pi}{2} \approx PIo2 =` ``0x3FF921FB54442D18 (0x3FC90FDB)`` +* :math:`\frac{\pi}{4} \approx PIo4 =` ``0x3FE921FB54442D18 (0x3F490FDB)`` + +#. For :math:`x` or :math:`y` is ``NaN``, return ``qNaN``. +#. For :math:`x==1.0`, return :ref:`atan`:math:`(\frac{y}{x})`. +#. Create :math:`m` to contain the sign bits of both input values for later use: :math:`m = 2 \cdot sign_x + sign_y`. :math:`m` can have values from :math:`0` to :math:`3`. +#. For :math:`y` is zero: + + #. For :math:`m<=1`, return :math:`y`. + #. For :math:`m==2`, return :math:`PI`. + #. For :math:`m==3` (which is the only remaining option), return :math:`-PI`. + +#. For :math:`x` is zero, return :math:`PIo2` with sign of :math:`y`. +#. For :math:`x` is infinite: + + #. For :math:`y` is infinite: + + #. For :math:`m==0`, return :math:`PIo4`. + #. For :math:`m==1`, return :math:`-PIo4`. + #. For :math:`m==2`, return :math:`3 \cdot PIo4`. + #. For :math:`m==3`, return :math:`-3 \cdot PIo4`. + + #. For :math:`m==0`, return :math:`+0`. + #. For :math:`m==1`, return :math:`-0`. + #. For :math:`m==2`, return :math:`PI`. + #. For :math:`m==3`, return :math:`-PI`. + +#. For :math:`y` is infinite, return :math:`PIo2` with sign of :math:`y`. +#. For :math:`|\frac{y}{x}|>2^{60}` (float: :math:`|\frac{y}{x}|>2^{26}`), create :math:`z = PIo2 + 0.5 \cdot PI_{lo}` and mask off all but the last bit of :math:`m`. Else: + + #. For :math:`\frac{|y|}{x}<-2^{-60}` (float: :math:`\frac{|y|}{x}<-2^{-26}`), create :math:`z = 0` [#]_. + #. Else create :math:`z = tan^{-1}|\frac{y}{x}|`, using the procedures :ref:`atan` and :ref:`fabs`. + +#. For :math:`m==0`, return :math:`z`. +#. For :math:`m==1`, return :math:`-z`. +#. For :math:`m==2`, return :math:`PI - (z - PI_{lo})`. +#. For :math:`m==3`, return :math:`(z - PI_{lo}) - PI`. + +.. [#] This is an optimization which omits the call to :ref:`atan` and :ref:`fabs` as the result is so much smaller than :math:`PI` that the result has no significance to the final result (as :math:`m` can only be :math:`2` or :math:`3` for negative :math:`x`). + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-0650 +* REQ-ML-0652 +* REQ-ML-0660 +* REQ-ML-0661 +* REQ-ML-0662 +* REQ-ML-0663 +* REQ-ML-0670 +* REQ-ML-0680 +* REQ-ML-0681 +* REQ-ML-0682 +* REQ-ML-0683 +* REQ-ML-0684 +* REQ-ML-0685 +* REQ-ML-0686 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/atan2d.c +* libm/mathf/atan2f.c + +References +^^^^^^^^^^ + +* :ref:`atan` +* :ref:`carg` +* :ref:`catan` +* :ref:`clog` +* :ref:`fabs` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0140_cos.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0140_cos.rst new file mode 100644 index 00000000..2286e955 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0140_cos.rst @@ -0,0 +1,85 @@ +cos +~~~ + +.. c:autodoc:: mathd/cosd.c + +Special cases +^^^^^^^^^^^^^ + ++--------------------------+--------------------------+ +| x | Result | ++==========================+==========================+ +| :math:`±0` | :math:`1` | ++--------------------------+--------------------------+ +| :math:`±Inf` | :math:`qNaN` | ++--------------------------+--------------------------+ +| :math:`NaN` | :math:`qNaN` | ++--------------------------+--------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +The ``cos`` functionality is highly similar to the :ref:`sin` function, therefore both of them use the same :ref:`internal_trig`. + +The approach is to first work on special values, reduce the range of the input value to :math:`\left[-\frac{\pi}{4},\frac{\pi}{4}\right]` and then use :ref:`__cos ` and :ref:`__sin ` for the actual calculation. + +The input value :math:`x` is interpreted in radians. + +#. For :math:`x` is :math:`NaN` or infinite, return :math:`qNaN`. +#. If the input argument is already within the range :math:`\left[-\frac{\pi}{4},\frac{\pi}{4}\right]`: + + #. If the input argument is smaller than :math:`2^{-27}` (float: :math:`2^{-12}`), return :math:`1`. + #. Otherwise use :ref:`__cos `. + +#. The input value :math:`x` is reduced to the range :math:`\left[-\frac{\pi}{4},\frac{\pi}{4}\right]` by using the function :ref:`__rem_pio2 `. +#. The return value is computed according to the last two bits of the return value :math:`n` of :ref:`__rem_pio2 ` (count :math:`n` of reminded :math:`\frac{\pi}{2}`): + ++-----------------------------------------+-----------------------------------------+ +| last two bits of :math:`n` | Return | ++=========================================+=========================================+ +| ``00`` | :ref:`__cos ` | ++-----------------------------------------+-----------------------------------------+ +| ``01`` | :math:`-` :ref:`__sin ` | ++-----------------------------------------+-----------------------------------------+ +| ``10`` | :math:`-` :ref:`__cos ` | ++-----------------------------------------+-----------------------------------------+ +| ``11`` | :ref:`__sin ` | ++-----------------------------------------+-----------------------------------------+ + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-0300 +* REQ-ML-0310 +* REQ-ML-0320 +* REQ-ML-0330 + + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/cosd.c +* libm/mathf/cosf.c + +References +^^^^^^^^^^ + +* :ref:`__cos ` +* :ref:`__rem_pio2 ` +* :ref:`__sin ` +* :ref:`acos` +* :ref:`ccos` +* :ref:`ccosh` +* :ref:`cexp` +* :ref:`cpow` +* :ref:`csinh` +* :ref:`ctan` +* :ref:`ctanh` +* :ref:`j0` +* :ref:`j1` +* :ref:`jn` +* :ref:`sin` +* :ref:`y0` +* :ref:`y1` +* :ref:`yn` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0150_sin.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0150_sin.rst new file mode 100644 index 00000000..35b57c40 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0150_sin.rst @@ -0,0 +1,83 @@ +sin +~~~ + +.. c:autodoc:: mathd/sind.c + +Special cases +^^^^^^^^^^^^^ + ++--------------------------+--------------------------+ +| x | Result | ++==========================+==========================+ +| :math:`±0` | :math:`x` | ++--------------------------+--------------------------+ +| :math:`±Inf` | :math:`qNaN` | ++--------------------------+--------------------------+ +| :math:`NaN` | :math:`qNaN` | ++--------------------------+--------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +The ``sin`` functionality is highly similar to the :ref:`cos` function, therefore both of them use the same :ref:`internal_trig`. + +The approach is to first work on special values, reduce the range of the input value to :math:`\left[-\frac{\pi}{4},\frac{\pi}{4}\right]` and then use :ref:`__cos ` and :ref:`__sin ` for the actual calculation. + +The input value :math:`x` is interpreted in radians. + +#. For :math:`x` is :math:`NaN` or infinite, return :math:`qNaN`. +#. If the input argument is already within the range :math:`\left[-\frac{\pi}{4},\frac{\pi}{4}\right]`: + + #. If the input argument is smaller than :math:`2^{-26}` (float: :math:`2^{-13}`), return :math:`x`. + #. Otherwise use :ref:`__sin `. + +#. The input value :math:`x` is reduced to the range :math:`\left[-\frac{\pi}{4},\frac{\pi}{4}\right]` by using the function :ref:`__rem_pio2 `. +#. The return value is computed according to the last two bits of the return value :math:`n` of :ref:`__rem_pio2 ` (count :math:`n` of reminded :math:`\frac{\pi}{2}`): + ++-----------------------------------------+-----------------------------------------+ +| last two bits of :math:`n` | Return | ++=========================================+=========================================+ +| ``00`` | :ref:`__sin ` | ++-----------------------------------------+-----------------------------------------+ +| ``01`` | :ref:`__cos ` | ++-----------------------------------------+-----------------------------------------+ +| ``10`` | :math:`-` :ref:`__sin ` | ++-----------------------------------------+-----------------------------------------+ +| ``11`` | :math:`-` :ref:`__cos ` | ++-----------------------------------------+-----------------------------------------+ + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-0200 +* REQ-ML-0210 +* REQ-ML-0220 +* REQ-ML-0240 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/sind.c +* libm/mathf/sinf.c + +References +^^^^^^^^^^ + +* :ref:`__cos ` +* :ref:`__rem_pio2 ` +* :ref:`__sin ` +* :ref:`asin` +* :ref:`ccosh` +* :ref:`cexp` +* :ref:`cpow` +* :ref:`cos` +* :ref:`csin` +* :ref:`csinh` +* :ref:`ctan` +* :ref:`j0` +* :ref:`j1` +* :ref:`jn` +* :ref:`y0` +* :ref:`y1` +* :ref:`yn` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0160_tan.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0160_tan.rst new file mode 100644 index 00000000..81d7e42f --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0160_tan.rst @@ -0,0 +1,162 @@ +tan +~~~ + +.. c:autodoc:: mathd/tand.c + +Special cases +^^^^^^^^^^^^^ + ++--------------------------+--------------------------+ +| x | Result | ++==========================+==========================+ +| :math:`±0` | :math:`x` | ++--------------------------+--------------------------+ +| :math:`±Inf` | :math:`qNaN` | ++--------------------------+--------------------------+ +| :math:`NaN` | :math:`qNaN` | ++--------------------------+--------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +``tan``: The ``tan`` functionality is similar to the :ref:`cos` and :ref:`sin` functions in that they use the same range reduction function from :ref:`internal_trig`. + +The approach is to first work on special values, reduce the range of the input value to :math:`\left[-\frac{\pi}{4},\frac{\pi}{4}\right]` and then use ``__tan`` for the actual calculation. + +The input value :math:`x` is interpreted in radians. + +#. If the input argument is already within the range :math:`\left[-\frac{\pi}{4},\frac{\pi}{4}\right]`: + + #. If the input argument is smaller than :math:`2^{-27}` (float: :math:`2^{-12}`), return :math:`x`. + #. Otherwise use ``__tan``. + +#. For :math:`x` is :math:`NaN` or infinite, return :math:`qNaN`. +#. The input value :math:`x` is reduced to the range :math:`\left[-\frac{\pi}{4},\frac{\pi}{4}\right]` by using the function :ref:`__rem_pio2 `. Save the return value as :math:`n`. +#. For :math:`n` is even, return the result of ``__tan`` with the third input set to :math:`1`. +#. Else, return the result of ``__tan`` with the third input set to :math:`-1`. + +-------------------------- + +``__tan``: The approach is to use a polynomial approximation for the calculation. + +Use the following constants as calculation/return values: + +* :math:`\frac{\pi}{4} \approx pio4 + pio4_{lo}` +* :math:`pio4 =` ``0x3FE921FB54442D18 (0x3F490FDA)`` +* :math:`pio4_{lo} =` ``0x3C81A62633145C07 (0x33222168)`` +* :math:`T0 =` ``0x3FC5555555555555 (0x3EAAAAAB)`` :math:`\approx \frac{1}{3}` +* :math:`T1 =` ``0x3FC111111110FE7A (0x3E088889)`` :math:`\approx \frac{2}{15}` +* :math:`T2 =` ``0x3FABA1BA1BB341FE (0x3D5D0DD1)`` :math:`\approx \frac{17}{315}` +* :math:`T3 =` ``0x3F9664F48406D637 (0x3CB327A4)`` :math:`\approx ...` +* :math:`T4 =` ``0x3F8226E3E96E8493 (0x3C11371F)`` +* :math:`T5 =` ``0x3F6D6D22C9560328 (0x3B6B6916)`` +* :math:`T6 =` ``0x3F57DBC8FEE08315 (0x3ABEDE48)`` +* :math:`T7 =` ``0x3F4344D8F2F26501 (0x3A1A26C8)`` +* :math:`T8 =` ``0x3F3026F71A8D1068 (0x398137B9)`` +* :math:`T9 =` ``0x3F147E88A03792A6 (0x38A3F445)`` +* :math:`T10 =` ``0x3F12B80F32F0A7E9 (0x3895C07A)`` +* :math:`T11 =` ``0xBEF375CBDB605373 (0xB79BAE5F)`` +* :math:`T12 =` ``0x3EFB2A7074BF7AD4 (0x37D95384)`` + +#. The identity :math:`tan(-x) = -tan(x)` can be used to reduce :math:`x` to positive. +#. The tangent of an argument can be calculated with: + + .. math:: + :label: formula_tan_1 + + tan(x) &= x + \frac{1}{3}x^3 + \frac{2}{15}x^5 + \frac{17}{315}x^7 + ... \\ + &= \sum\limits_{i=1}^{\infty} \frac{(-1)^{i-1} \cdot 2^{2i} \cdot (2^{2i}-1) \cdot B_{2i} \cdot x^{2i-1}}{(2i)!} + + with :math:`B_{n}` being the :math:`n`-th Bernoulli number. +#. If :math:`|x| < 0.67434` [#]_: + + #. Use a polynomial approximation of formula :math:numref:`formula_tan_1` to calculate the tangent [#]_: + + .. math:: + :label: formula_tan_2 + + tan(x) \sim x \cdot (T0 \cdot x + T1 \cdot x^3 + T2 \cdot x^5 + ... + T12 \cdot x^{27}) + + #. To increase the accuracy make use of the identity + + .. math:: + :label: formula_tan_3 + + tan(x+y) &= tan(x) + tan'(x) \cdot y \\ + &\sim tan(x) + (1+ x^2) \cdot y + + to change the approximation to: + + .. math:: + :label: formula_tan_4 + + r(x) &= x^3 \cdot (T1 + x \cdot (T2 + x \cdot (... + x \cdot (T11 + x \cdot T12)))) \\ + R(x) &= T0 \cdot x^3 + (x^2 \cdot (r(x)+y) +y) \\ + tan(x+y) &= x + R(x) + + #. If :math:`k` is :math:`1`, return the result of the approximation. + #. Return :math:`-\frac{1}{tan(x+y)}`, to not loose precision on this arithmetic operation, use this formula to create the return value: + + .. math:: + :label: formula_tan_5 + + -\frac{1}{tan(x+y)} = t + a \cdot (s + t \cdot v) + + with + + #. :math:`z = tan(x+y)` with the ``lowword`` masked to zero (float: last 12 bits of the integer representation masked to zero). + #. :math:`v = R(x) - (z - x)`. + #. :math:`a = -\frac{1}{tan(x+y)}`. + #. :math:`t = a` with the ``lowword`` masked to zero (float: last 12 bits of the integer representation masked to zero). + #. :math:`s = 1 + t \cdot z`. + +#. As the approximation in formula :math:numref:`formula_tan_2` is only reliable for :math:`|x| < 0.67434`, make use of the identity + + .. math:: + :label: formula_tan_6 + + tan(x) &= tan\bigg(\frac{\pi}{4}-f\bigg) \\ + &= \frac{1-tan(f)}{1+tan(f)} \\ + &= 1-2 \cdot \bigg(tan(f) - \frac{tan(f)^2}{1+tan(f)}\bigg) + + with + + #. If :math:`x` is negative, replace :math:`x` with :math:`x = -x`` and :math:`y` with :math:`y = -y`. + #. :math:`f = \frac{\pi}{4} - x`. + + to change the approximation of the tangent. +#. Let :math:`f = \frac{\pi}{4} - x = PIo4 - x + (PIo4_{lo} - y)`. +#. Calculate :math:`tan(f)` as in formula :math:numref:`formula_tan_4`, with :math:`x = f` and :math:`y = 0`. +#. Use formula :math:numref:`formula_tan_6` to calculate :math:`tan(x)`: + + .. math:: + :label: formula_tan_7 + + tan(x) = k - 2 \cdot \bigg(f-\Big(\frac{tan(f)^2}{tan(f)+k}-R(f)\Big)\bigg) + +#. Return :math:`tan(x)` with the sign of the original :math:`x`. + +.. [#] Use ``highword`` :math:`<` ``0x3FE59428`` (float: use integer representation of :math:`x <` ``0x3F2CA140``). +.. [#] The error of this approximation is less than :math:`2^{-59.2}`. + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-0500 +* REQ-ML-0520 +* REQ-ML-0530 +* REQ-ML-0550 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/tand.c +* libm/mathf/tanf.c + +References +^^^^^^^^^^ + +* :ref:`__rem_pio2 ` +* :ref:`cos` +* :ref:`sin` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0170_trig.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0170_trig.rst new file mode 100644 index 00000000..c4258060 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0170_trig.rst @@ -0,0 +1,191 @@ +.. _internal_trig: + +Internal Trigonometric Functions +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. c:autodoc:: mathd/internal/trigd.c + +Special cases +^^^^^^^^^^^^^ + +The special cases are in the respective external functions :ref:`cos` and :ref:`sin`. + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +``__cos``: The approach is to use a polynomial approximation for the calculation. + +Use the following constants as calculation/return values: + +* :math:`C1 =` ``0x3FA555555555554C (0x3D2AAAA5)`` +* :math:`C2 =` ``0xBF56C16C16C15177 (0xBAB60615)`` +* :math:`C3 =` ``0x3EFA01A019CB1590 (0x37CCF47C)`` +* :math:`C4 =` ``0xBE927E4F809C52AD`` +* :math:`C5 =` ``0x3E21EE9EBDB4B1C4`` +* :math:`C6 =` ``0xBDA8FAE9BE8838D4`` + +The cosine is computed by evaluating the following polynomial: + +.. math:: + + r &= C1 \cdot x^2 + C2 \cdot x^4 + C3 \cdot x^6 + C4 \cdot x^{8} + C5 \cdot x^{10} + C6 \cdot x^{12} \\ + cos(x+y) &= w + (((1 - w) - hz) + (x^2 \cdot r - x \cdot y)) + +with: + +* :math:`hz = 0.5 \cdot x^2` +* :math:`w = 1 - hz` + +For the float version the polynomial can be shortened to: + +.. math:: + + r = C1 \cdot x^2 + C2 \cdot x^4 + C3 \cdot x^6 + +-------------------------- + +``__sin``: The approach is to use a polynomial approximation for the calculation. + +Use the following constants as calculation/return values: + +* :math:`S1 =` ``0xBFC5555555555549 (0xBE2AAAAB)`` +* :math:`S2 =` ``0x3F8111111110F8A6 (0x3C0888BB)`` +* :math:`S3 =` ``0xBF2A01A019C161D5 (0xB9502DE1)`` +* :math:`S4 =` ``0x3EC71DE357B1FE7D (0x363E6DBE)`` +* :math:`S5 =` ``0xBE5AE5E68A2B9CEB`` +* :math:`S6 =` ``0x3DE5D93A5ACFD57C`` + +The sine is computed by evaluating the following polynomial: + +.. math:: + + r &= S2 \cdot x^3 + S3 \cdot x^5 + S4 \cdot x^7 + S5 \cdot x^{9} + S6 \cdot x^{11} \\ + sin(x+y) &= x + (S1 \cdot x + ( x \cdot (r - \frac{y}{2}) + y)) + +For the float version the polynomial can be shortened to: + +.. math:: + + r = S2 \cdot x^3 + S3 \cdot x^5 + S4 \cdot x^7 + +-------------------------- + +``__rem_pio2``: The approach is to use a polynomial approximation for the calculation. + +Use the following constants as calculation/return values: + +* :math:`invpio2 =` ``0x3FE45F306DC9C883 (0x3F22F984)``, equals the first 53 bit of :math:`\frac{2}{\pi}` +* :math:`pio2_1 =` ``0x3FF921FB54400000 (0x3FC90F80)``, equals the first 33 bit of :math:`\frac{\pi}{2}` +* :math:`pio2_{1t} =` ``0x3DD0B4611A626331 (0x37354443)``, equals :math:`\frac{\pi}{2} - pio2_1` +* :math:`pio2_2 =` ``0x3DD0B4611A600000 (0x37354400)``, equals the second 33 bit of :math:`\frac{\pi}{2}` +* :math:`pio2_{2t} =` ``0x3BA3198A2E037073 (0x2E85A308)``, equals :math:`\frac{\pi}{2} - (pio2_1 + pio2_2)` +* :math:`pio2_3 =` ``0x3BA3198A2E000000 (0x2E85A300)``, equals the second 33 bit of :math:`\frac{\pi}{2}` +* :math:`pio2_{3t} =` ``0x397B839A252049C1 (0x248D3132)``, equals :math:`\frac{\pi}{2} - (pio2_1 + pio2_2 + pio2_3)` + +#. For :math:`|x| < \frac{\pi}{4}`, there is no need for reduction: Set :math:`y_0 = x` and :math:`y_1 = 0`, and return :math:`0`. +#. For :math:`|x| < 3 \cdot \frac{\pi}{4}`, one addition or subtraction of :math:`pio2` is enough: + + #. For :math:`x` is positive: + + #. For ``highword`` of :math:`x` is ``0x3FF921FB`` (this means :math:`x` is close to :math:`\frac{\pi}{2}`) (float: For integer representation of :math:`x`, with the last 17 bit masked off, is ``0x3FC80000``): + + #. Set :math:`y_0 = x - pio2_1 - pio2_2 - pio2_{2t}`. + #. Set :math:`y_1 = (x - pio2_1 - pio2_2 - y_0) - pio2_{2t}`. + + Oherwise a less precise :math:`pio2` is sufficient: + + #. Set :math:`y_0 = x - pio2_1 - pio2_{1t}`. + #. Set :math:`y_1 = (x - pio2_1 - y_0) - pio2_{1t}`. + + #. Return :math:`1`. + + Otherwise for :math:`x` is negative: + + #. For ``highword`` of :math:`x` is ``0x3FF921FB`` (this means :math:`x` is close to :math:`\frac{\pi}{2}`) (float: For integer representation of :math:`x`, with the last 17 bit masked off, is ``0x3FC80000``): + + #. Set :math:`y_0 = x + pio2_1 + pio2_2 + pio2_{2t}`. + #. Set :math:`y_1 = (x + pio2_1 + pio2_2 - y_0) + pio2_{2t}`. + + Oherwise a less precise :math:`pio2` is sufficient: + + #. Set :math:`y_0 = x + pio2_1 + pio2_{1t}`. + #. Set :math:`y_1 = (x + pio2_1 - y_0) + pio2_{1t}`. + + #. Return :math:`-1`. + +#. For :math:`|x| < 2^{19} \cdot \frac{\pi}{2}` (float: :math:`|x| < 2^{7} \cdot \frac{\pi}{2}`), an addition or subtraction of multiple :math:`pio2` is enough: + + #. :math:`n` shall be an integer. Set :math:`n = |x| \cdot invpio2 + 0.5` (use :ref:`fabs` to calculate the absolute value of :math:`x`). + #. Set :math:`r = |x| - n \cdot pio2_1`. + #. Set :math:`w = n \cdot pio2_{1t}`. + #. Set :math:`y_0 = r - w`. + #. Set :math:`i =` exponent bits of :math:`x -` exponent bits of :math:`y_0`. + #. For :math:`i > 16` (float: :math:`i > 8`), a second iteration is necessary: + + #. Set :math:`t = r`. + #. Set :math:`r = r - n \cdot pio2_{2}`. + #. Set :math:`w = n \cdot pio2_{2t} - ((t - r) - n \cdot pio2_{2})`. + #. Set :math:`y_0 = r - w`. + #. Set :math:`i =` exponent bits of :math:`x -` exponent bits of :math:`y_0`. + #. For :math:`i > 49` (float: :math:`i > 25`), a second iteration is necessary: + + #. Set :math:`t = r`. + #. Set :math:`r = r - n \cdot pio2_{3}`. + #. Set :math:`w = n \cdot pio2_{3t} - ((t - r) - n \cdot pio2_{3})`. + #. Set :math:`y_0 = r - w`. + + #. Set :math:`y_1 = (r - y_0) - w`. + #. For :math:`x` is negative, negate :math:`y_0` and :math:`y_1`, and return :math:`-n`. + #. Return :math:`n`. + +#. For :math:`x` is infinite or :math:`NaN`, set both :math:`y_0` and :math:`y_1` to :math:`NaN`, and return :math:`0`. +#. Set :math:`e0 =` (exponent of :math:`|x|`) :math:`- 23` (float: :math:`e0 =` (exponent of :math:`|x|`) :math:`- 7`). +#. Set :math:`z = |x|` with exponent set to :math:`e0`. +#. Create array :math:`tx` for three values. +#. Set :math:`tx[0] =` integer part of :math:`z`. +#. Set :math:`z = (z-tx[0]) \cdot 2^{24}` (float: :math:`z = (z-tx[0]) \cdot 2^{8}`). +#. Set :math:`tx[1] =` integer part of :math:`z`. +#. Set :math:`z = (z-tx[1]) \cdot 2^{24}` (float: :math:`z = (z-tx[1]) \cdot 2^{8}`). +#. Set :math:`tx[2] = z`. +#. Loop over the array :math:`tx` from back to front, break the loop if the element is equal to zero. Set :math:`nx` to the index of the element that caused the break, or :math:`0` if no break was triggered. +#. Call ``__rem_pio2_internal`` with arguments :math:`tx`, :math:`y`, :math:`e0`, and :math:`nx`. Save the return value in :math:`n`. +#. For :math:`x` is negative, negate :math:`y_0` and :math:`y_1`, and return :math:`-n`. +#. Return :math:`n`. + +-------------------------- + +``__rem_pio2_internal``: Use Payne and Hanek's method for range reduction as described in the article *Radian reduction for trigonometric functions* [PH]_. The design of the algorithm is further detailed in [NG]_. As the description in the article is quite extensive it will only be outlined here. + +The external range reduction ``__rem_pio2`` will split the angle :math:`x` into an array :math:`x[0]+x[1]+x[2]` where each :math:`x[i]` item contains 24 bits of the original angle, and it will set the unbiased exponent of :math:`x` in :math:`e0`. + +The internal range reduction will compute the integer and fractional parts of the angle :math:`q = x/(\frac{\pi}{2}) = x\cdot(\frac{2}{\pi})`. The constant :math:`\frac{2}{\pi}` is stored in high precision in an array containing 24 bit chunks of the constant. + +The method is to compute the integer (mod 8) and fraction parts of :math:`x\cdot(\frac{2}{\pi})` without doing the full multiplication. In general the part of the product that are known to be a huge integer (more accurately the integer part that is 0 mod 8) are skipped. Thus the number of operations are independent of the exponent of the input. + +.. [PH] *Radian reduction for trigonometric functions* by Mary H. Payne and Robert N. Hanek (https://dl.acm.org/doi/pdf/10.1145/1057600.1057602). +.. [NG] *ARGUMENT REDUCTION FOR HUGE ARGUMENTS: Good to the Last Bit* by K.C. NG and the members of the FP group of SunPro (https://www.csee.umbc.edu/~phatak/645/supl/Ng-ArgReduction.pdf) + +Requirements +^^^^^^^^^^^^ + +Internal functions do not directly implement requirements. + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/internal/trigd.h +* libm/mathd/internal/trigd.c +* libm/mathf/internal/trigf.h +* libm/mathf/internal/trigf.c + +References +^^^^^^^^^^ + +* :ref:`__lgamma ` +* :ref:`cos` +* :ref:`fabs` +* :ref:`floor` +* :ref:`scalbn` +* :ref:`sin` +* :ref:`tan` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0200_acosh.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0200_acosh.rst new file mode 100644 index 00000000..73d20e7a --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0200_acosh.rst @@ -0,0 +1,53 @@ +acosh +~~~~~ + +.. c:autodoc:: mathd/acoshd.c + +Special cases +^^^^^^^^^^^^^ + ++--------------------------+--------------------------+ +| x | Result | ++==========================+==========================+ +| :math:`+1` | :math:`+0` | ++--------------------------+--------------------------+ +| :math:`<+1` | :math:`qNaN` | ++--------------------------+--------------------------+ +| :math:`-Inf` | :math:`qNaN` | ++--------------------------+--------------------------+ +| :math:`+Inf` | :math:`+Inf` | ++--------------------------+--------------------------+ +| :math:`NaN` | :math:`qNaN` | ++--------------------------+--------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +Implement based on :math:`cosh^{-1}(x) = ln(x + \sqrt{x^2-1})` using :ref:`log`, :ref:`log1p`, and :ref:`sqrt`: + +#. For large :math:`x` (:math:`x > 2^{28}`): :math:`acosh(x) = log(x) + log(2)` +#. For :math:`x > 2`: :math:`acosh(x) = log\Big(\frac{2x - 1}{x + \sqrt{x^2 - 1}}\Big)` +#. For smaller :math:`x`: :math:`acosh(x) = log1p(t + \sqrt{2t+t^2}) \wedge t = x - 1` + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-2710 +* REQ-ML-3010 +* REQ-ML-3020 +* REQ-ML-3030 +* REQ-ML-3040 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/acoshd.c +* libm/mathf/acoshf.c + +References +^^^^^^^^^^ + +* :ref:`log` +* :ref:`log1p` +* :ref:`sqrt` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0210_asinh.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0210_asinh.rst new file mode 100644 index 00000000..e9d48ecb --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0210_asinh.rst @@ -0,0 +1,52 @@ +asinh +~~~~~ + +.. c:autodoc:: mathd/asinhd.c + +Special cases +^^^^^^^^^^^^^ + ++--------------------------+--------------------------+ +| x | Result | ++==========================+==========================+ +| :math:`±0` | :math:`x` | ++--------------------------+--------------------------+ +| :math:`±Inf` | :math:`x` | ++--------------------------+--------------------------+ +| :math:`NaN` | :math:`qNaN` | ++--------------------------+--------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +Implement based on :math:`sinh^{-1}(x) = sign(x) \cdot ln(|x| + \sqrt{x^2+1})` using :ref:`log`, :ref:`log1p`, and :ref:`sqrt`: + +#. For large :math:`x` (:math:`|x| > 2^{28}`): :math:`asinh(x) = sign(x) \cdot log(|x|) + log(2)` +#. For :math:`x > 2`: :math:`asinh(x) = sign(x) \cdot log\Big(\frac{|2x| + 1}{|x| + \sqrt{x^2 + 1}}\Big)` +#. For smaller :math:`x`: :math:`asinh(x) = sign(x) \cdot log1p(|x| + \frac{x^2}{1 + \sqrt{1+x^2}})` +#. For very small :math:`x` (:math:`|x| < 2^{-28}`): :math:`asinh(x) = x` + +.. Here there be dragons. (TODO) + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-2620 +* REQ-ML-2630 +* REQ-ML-2640 +* REQ-ML-2700 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/asinhd.c +* libm/mathf/asinhf.c + +References +^^^^^^^^^^ + +* :ref:`fabs` +* :ref:`log` +* :ref:`log1p` +* :ref:`sqrt` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0220_atanh.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0220_atanh.rst new file mode 100644 index 00000000..afdd57b1 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0220_atanh.rst @@ -0,0 +1,52 @@ +atanh +~~~~~ + +.. c:autodoc:: mathd/atanhd.c + +Special cases +^^^^^^^^^^^^^ + ++--------------------------+--------------------------+ +| x | Result | ++==========================+==========================+ +| :math:`±0` | :math:`x` | ++--------------------------+--------------------------+ +| :math:`\notin [-1, 1]` | :math:`qNaN` | ++--------------------------+--------------------------+ +| :math:`±1` | :math:`±Inf` | ++--------------------------+--------------------------+ +| :math:`±Inf` | :math:`qNaN` | ++--------------------------+--------------------------+ +| :math:`NaN` | :math:`qNaN` | ++--------------------------+--------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +Implement based on :math:`tanh^{-1}(x) = \frac{1}{2} ln \left( \frac{1+x}{1-x} \right)` using :ref:`log1p`: + +#. Reduce to positive as :math:`tanh^{-1}(-x) = -tanh^{-1}(x)` +#. For :math:`x >= \frac{1}{2}`: :math:`atanh(x) = \frac{1}{2} log\Big(1 + \frac{2x}{1 - x}\Big) = \frac{1}{2} log1p\Big(\frac{2x}{1 - x}\Big)` +#. Otherwise: :math:`atanh(x) = \frac{1}{2} log1p\Big(2x + \frac{2x^2}{1-x}\Big)` + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-3100 +* REQ-ML-3110 +* REQ-ML-3120 +* REQ-ML-3121 +* REQ-ML-3140 +* REQ-ML-3141 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/atanhd.c +* libm/mathf/atanhf.c + +References +^^^^^^^^^^ + +* :ref:`log1p` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0230_cosh.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0230_cosh.rst new file mode 100644 index 00000000..9d84a787 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0230_cosh.rst @@ -0,0 +1,56 @@ +cosh +~~~~ + +.. c:autodoc:: mathd/coshd.c + +Special cases +^^^^^^^^^^^^^ + ++--------------------------+--------------------------+ +| x | Result | ++==========================+==========================+ +| :math:`±0` | :math:`1` | ++--------------------------+--------------------------+ +| :math:`±Inf` | :math:`+Inf` | ++--------------------------+--------------------------+ +| :math:`NaN` | :math:`qNaN` | ++--------------------------+--------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +Implement based on :math:`cosh(x) = \frac{e^x+e^{-x}}{2}` using :ref:`exp` and :ref:`expm1`: + +#. Reduce to positive as :math:`cosh(-x) = cosh(x)` +#. For :math:`0 <= x <= \frac{ln(2)}{2}`: :math:`cosh(x) = 1 + \frac{(exp(x) - 1)^2}{2 \cdot exp(x)}` +#. For :math:`\frac{ln(2)}{2} <= x <= 22`: :math:`cosh(x) = \frac{exp(x) + \frac{1}{exp(x)}}{2}` +#. For :math:`22 <= x`: :math:`cosh(x) = \frac{exp(x)}{2}` + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-2200 +* REQ-ML-2210 +* REQ-ML-2220 +* REQ-ML-2240 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/coshd.c +* libm/mathf/coshf.c + +References +^^^^^^^^^^ + +* :ref:`__ccoshsinh ` +* :ref:`ccos` +* :ref:`ccosh` +* :ref:`csin` +* :ref:`csinh` +* :ref:`ctan` +* :ref:`ctanh` +* :ref:`exp` +* :ref:`expm1` +* :ref:`fabs` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0240_sinh.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0240_sinh.rst new file mode 100644 index 00000000..6ff9543d --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0240_sinh.rst @@ -0,0 +1,55 @@ +sinh +~~~~ + +.. c:autodoc:: mathd/sinhd.c + +Special cases +^^^^^^^^^^^^^ + ++--------------------------+--------------------------+ +| x | Result | ++==========================+==========================+ +| :math:`±0` | :math:`x` | ++--------------------------+--------------------------+ +| :math:`±Inf` | :math:`x` | ++--------------------------+--------------------------+ +| :math:`NaN` | :math:`qNaN` | ++--------------------------+--------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +Implement based on :math:`sinh(x) = \frac{e^x-e^{-x}}{2}` using :ref:`exp` and :ref:`expm1`: + +#. Reduce to positive as :math:`sinh(-x) = -sinh(x)` +#. For :math:`0 <= x <= 22`: :math:`sinh(x) = \frac{expm1(x) + \frac{expm1(x)}{exp(x)}}{2}` +#. For :math:`22 <= x`: :math:`sinh(x) = \frac{exp(x)}{2}` + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-2100 +* REQ-ML-2110 +* REQ-ML-2120 +* REQ-ML-2140 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/sinhd.c +* libm/mathf/sinhf.c + +References +^^^^^^^^^^ + +* :ref:`__ccoshsinh ` +* :ref:`ccos` +* :ref:`ccosh` +* :ref:`csin` +* :ref:`csinh` +* :ref:`ctan` +* :ref:`ctanh` +* :ref:`exp` +* :ref:`expm1` +* :ref:`fabs` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0250_tanh.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0250_tanh.rst new file mode 100644 index 00000000..5061d197 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0250_tanh.rst @@ -0,0 +1,45 @@ +tanh +~~~~ + +.. c:autodoc:: mathd/tanhd.c + +Special cases +^^^^^^^^^^^^^ + ++--------------------------+--------------------------+ +| x | Result | ++==========================+==========================+ +| :math:`±0` | :math:`x` | ++--------------------------+--------------------------+ +| :math:`±Inf` | :math:`±1` | ++--------------------------+--------------------------+ +| :math:`NaN` | :math:`qNaN` | ++--------------------------+--------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +Implement based on :math:`tanh(x) = \frac{e^x-e^{-x}}{e^x+e^{-x}}` using :ref:`expm1`: + +#. Reduce to positive as :math:`tanh(-x) = -tanh(x)` +#. For :math:`0 <= x <= 1`: :math:`tanh(x) = -\frac{t}{t + 2} \wedge t = expm1(-2x)` +#. For :math:`1 <= x <= 22`: :math:`tanh(x) = 1 - \frac{2}{t + 2} \wedge t = expm1(2x)` +#. For :math:`22 <= x`: :math:`tanh(x) = 1` + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-2540 +* REQ-ML-2550 +* REQ-ML-2600 +* REQ-ML-2610 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/tanhd.c +* libm/mathf/tanhf.c + +References +^^^^^^^^^^ diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0300_exp.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0300_exp.rst new file mode 100644 index 00000000..34e4a57f --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0300_exp.rst @@ -0,0 +1,100 @@ +exp +~~~ + +.. c:autodoc:: mathd/expd.c + +Special cases +^^^^^^^^^^^^^ + ++--------------------------+--------------------------+ +| x | Result | ++==========================+==========================+ +| :math:`±0` | :math:`1` | ++--------------------------+--------------------------+ +| :math:`-Inf` | :math:`+0` | ++--------------------------+--------------------------+ +| :math:`+Inf` | :math:`+Inf` | ++--------------------------+--------------------------+ +| :math:`NaN` | :math:`qNaN` | ++--------------------------+--------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +The approach is to first work on special values and then use polynomial approximation for the calculation. + +Use the following constants as calculation/return values: + +* :math:`P1 =` ``0x3FC555555555553E (0x3E2AAAAB)`` +* :math:`P2 =` ``0xBF66C16C16BEBD93 (0xBB360B61)`` +* :math:`P3 =` ``0x3F11566AAF25DE2C (0x388AB355)`` +* :math:`P4 =` ``0xBEBBBD41C5D26BF1 (0xB5DDEA0E)`` +* :math:`P5 =` ``0x3E66376972BEA4D0 (0x3331BB4C)`` + +#. For :math:`x` is :math:`NaN`, return :math:`qNaN`. [#]_ +#. For :math:`x` is :math:`+Inf`, return :math:`x`. +#. For :math:`x` is :math:`-Inf`, return :math:`+0`. +#. If :math:`e^x` produces an overflow, return positive infinity [#]_, with ``overflow`` exception. +#. If :math:`e^x` produces an underflow, return :math:`0` [#]_. +#. For :math:`|x| < 2^{-28}`, return :math:`1`. [#]_ +#. For :math:`|x| > 0.5 \cdot ln(2)`, an argument reduction is necessary. Given :math:`x` find :math:`r` and integer :math:`k` such that the formula + + .. math:: + :label: formula_exp_1 + + x = k \cdot ln(2) + r \wedge |r| <= 0.5 \cdot ln(2) + + holds true. To increase accuracy save :math:`r` using two double precision floating point values. +#. If no argument reduction was necessary in step 7, :math:`r` equals :math:`x`. +#. Calculate :math:`e^r` with the following formulae using Horner's method: + + .. math:: + :label: formula_exp_2 + + c = r - P1 \cdot r^2 - P2 \cdot r^4 - P3 \cdot r^6 - P4 \cdot r^8 - P5 \cdot r^{10} \\ + e^r = 1 - \frac{r \cdot c}{c - 2} - r + +#. If no argument reduction was necessary in step 7, return :math:`e^r`. +#. Use the formula + + .. math:: + :label: formula_exp_3 + + e^x = 2^k \cdot e^r + + to scale back from :math:`r` to :math:`x`, and return the calculated value for :math:`e^x`. + +.. [#] For optimization the steps 1 through 5 can be combined in a single if-statement using :math:`|x| >=` the overflow threshold, therefore making the execution time of non-special cases shorter. +.. [#] This is the case when :math:`x` is :math:`>` ``0x40862E42FEFA39EF`` (:math:`7.09782712893383973096 \cdot 10^2`). +.. [#] This is the case when :math:`x` is :math:`<` ``0xC0874910D52D3051`` (:math:`-7.45133219101941108420 \cdot 10^2`). +.. [#] This is faster than the calculation and the result would be indistinguishable from :math:`1` using double precision. + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-0800 +* REQ-ML-0831 +* REQ-ML-0832 +* REQ-ML-0833 +* REQ-ML-0834 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/expd.c +* libm/mathf/expf.c + +References +^^^^^^^^^^ + +* :ref:`__ccoshsinh ` +* :ref:`ccos` +* :ref:`cexp` +* :ref:`cosh` +* :ref:`cpow` +* :ref:`csin` +* :ref:`erf` +* :ref:`erfc` +* :ref:`sinh` +* :ref:`tgamma` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0310_exp2.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0310_exp2.rst new file mode 100644 index 00000000..388fc3e5 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0310_exp2.rst @@ -0,0 +1,47 @@ +exp2 +~~~~ + +.. c:autodoc:: mathd/exp2d.c + +Special cases +^^^^^^^^^^^^^ + ++--------------------------+--------------------------+ +| x | Result | ++==========================+==========================+ +| :math:`±0` | :math:`1` | ++--------------------------+--------------------------+ +| :math:`-Inf` | :math:`+0` | ++--------------------------+--------------------------+ +| :math:`+Inf` | :math:`+Inf` | ++--------------------------+--------------------------+ +| :math:`NaN` | :math:`qNaN` | ++--------------------------+--------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +Implement based on :ref:`pow`. + +.. Here there be dragons. (TODO) + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-3200 +* REQ-ML-3210 +* REQ-ML-3220 +* REQ-ML-3240 +* REQ-ML-3250 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/exp2d.c +* libm/mathf/exp2f.c + +References +^^^^^^^^^^ + +* :ref:`pow` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0320_expm1.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0320_expm1.rst new file mode 100644 index 00000000..6ad8f107 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0320_expm1.rst @@ -0,0 +1,49 @@ +expm1 +~~~~~ + +.. c:autodoc:: mathd/expm1d.c + +Special cases +^^^^^^^^^^^^^ + ++--------------------------+--------------------------+ +| x | Result | ++==========================+==========================+ +| :math:`±0` | :math:`+0` | ++--------------------------+--------------------------+ +| :math:`-Inf` | :math:`-1` | ++--------------------------+--------------------------+ +| :math:`+Inf` | :math:`+Inf` | ++--------------------------+--------------------------+ +| :math:`NaN` | :math:`qNaN` | ++--------------------------+--------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +Implement based on a rational approximation. + +.. Here there be dragons. (TODO) + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-2500 +* REQ-ML-2510 +* REQ-ML-2520 +* REQ-ML-2540 +* REQ-ML-2550 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/expm1d.c +* libm/mathf/expm1f.c + +References +^^^^^^^^^^ + +* :ref:`cosh` +* :ref:`sinh` +* :ref:`tanh` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0330_frexp.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0330_frexp.rst new file mode 100644 index 00000000..a134c40a --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0330_frexp.rst @@ -0,0 +1,42 @@ +frexp +~~~~~ + +.. c:autodoc:: mathd/frexpd.c + +Special cases +^^^^^^^^^^^^^ + ++------------------------------+------------------------------+--------------------------+ +| x | :math:`*eptr` | Result | ++==============================+==============================+==========================+ +| :math:`±0` | :math:`0` | :math:`±0` | ++------------------------------+------------------------------+--------------------------+ +| :math:`±Inf` | :math:`0` | :math:`qNaN` | ++------------------------------+------------------------------+--------------------------+ +| :math:`NaN` | :math:`0` | :math:`qNaN` | ++------------------------------+------------------------------+--------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +Implement based on bit-fiddling. + +.. Here there be dragons. (TODO) + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-4000 +* REQ-ML-4010 +* REQ-ML-4020 +* REQ-ML-4040 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/frexpd.c +* libm/mathf/frexpf.c + +References +^^^^^^^^^^ diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0340_ilogb.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0340_ilogb.rst new file mode 100644 index 00000000..3e800724 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0340_ilogb.rst @@ -0,0 +1,45 @@ +ilogb +~~~~~ + +.. c:autodoc:: mathd/ilogbd.c + +Special cases +^^^^^^^^^^^^^ + ++--------------------------+--------------------------+ +| x | Result | ++==========================+==========================+ +| :math:`±0` | min :math:`\mathbb{I}` | ++--------------------------+--------------------------+ +| :math:`±Inf` | max :math:`\mathbb{I}` | ++--------------------------+--------------------------+ +| :math:`NaN` | max :math:`\mathbb{I}` | ++--------------------------+--------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +Implement based on bit-fiddling. + +.. Here there be dragons. (TODO) + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-4300 +* REQ-ML-4310 +* REQ-ML-4320 +* REQ-ML-4340 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/ilogbd.c +* libm/mathf/ilogbf.c + +References +^^^^^^^^^^ + +* :numref:`Tbl. %s ` +* :ref:`logb` \ No newline at end of file diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0350_ldexp.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0350_ldexp.rst new file mode 100644 index 00000000..f95c63f3 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0350_ldexp.rst @@ -0,0 +1,49 @@ +ldexp +~~~~~ + +.. c:autodoc:: mathd/ldexpd.c + +Special cases +^^^^^^^^^^^^^ + ++------------------------+------------------------+------------------------+ +| x | exp | Result | ++========================+========================+========================+ +| :math:`±0` | :math:`\in \mathbb{I}` | :math:`x` | ++------------------------+------------------------+------------------------+ +| :math:`\in \mathbb{F}` | :math:`0` | :math:`x` | ++------------------------+------------------------+------------------------+ +| :math:`±Inf` | :math:`\in \mathbb{I}` | :math:`x` | ++------------------------+------------------------+------------------------+ +| :math:`NaN` | :math:`\in \mathbb{I}` | :math:`qNaN` | ++------------------------+------------------------+------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +The approach is to first work on special values and then use :ref:`scalbn`. + +#. For :math:`x` is zero, infinite or ``NaN``, return :math:`x`. +#. Else use :ref:`scalbn` and return its result. + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-4100 +* REQ-ML-4110 +* REQ-ML-4120 +* REQ-ML-4130 +* REQ-ML-4140 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/ldexpd.c +* libm/mathf/ldexpf.c + +References +^^^^^^^^^^ + +* :ref:`isfinite` +* :ref:`scalbn` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0360_log.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0360_log.rst new file mode 100644 index 00000000..ad0f938a --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0360_log.rst @@ -0,0 +1,138 @@ +log +~~~ + +.. c:autodoc:: mathd/logd.c + +Special cases +^^^^^^^^^^^^^ + ++--------------------------+--------------------------+ +| x | Result | ++==========================+==========================+ +| :math:`<0` | :math:`qNaN` | ++--------------------------+--------------------------+ +| :math:`±0` | :math:`-Inf` | ++--------------------------+--------------------------+ +| :math:`1` | :math:`+0` | ++--------------------------+--------------------------+ +| :math:`+Inf` | :math:`+Inf` | ++--------------------------+--------------------------+ +| :math:`NaN` | :math:`qNaN` | ++--------------------------+--------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +The approach is to first work on special values and then use polynomial approximation for the calculation. + +Use the following constants as calculation/return values: + +* :math:`L1 =` ``0x3FE5555555555593 (0x3E2AAAAB)`` +* :math:`L2 =` ``0x3FD999999997FA04 (0x3ECCCCCD)`` +* :math:`L3 =` ``0x3FD2492494229359 (0x3E924925)`` +* :math:`L4 =` ``0x3FCC71C51D8E78AF (0x3E638E29)`` +* :math:`L5 =` ``0x3FC7466496CB03DE (0x3E3A3325)`` +* :math:`L6 =` ``0x3FC39A09D078C69F (0x3E1CD04F)`` +* :math:`L7 =` ``0x3FC2F112DF3E5244 (0x3E178897)`` +* :math:`ln(2) \approx Ln2_{hi} + Ln2_{lo}` +* :math:`Ln2_{hi} =` ``0x3FE62E42FEE00000 (0x3F317180)`` +* :math:`Ln2_{lo} =` ``0x3DEA39EF35793C76 (0x3717F7D1)`` + +#. For :math:`x` is :math:`NaN` or positive infinity, return :math:`x+x`. +#. For :math:`x` is a zero, return negative infinity. +#. For :math:`x` is negative, return :math:`NaN`. +#. For :math:`x` is subnormal, scale up by multiplying with :math:`2^{54}` (float: :math:`2^{25}`). +#. Given :math:`x` find :math:`f` and integer :math:`k` such that the formulae [#]_ + + .. math:: + :label: formula_log_1 + + x &= 2^k \cdot (1 + f) \\ + \frac{\sqrt{2}}{2} &< (1 + f) < \sqrt{2} + + hold true [#]_. Decrease :math:`k` by :math:`54` (float: :math:`25`) if :math:`x` was subnormal in the previous step. +#. Approximate :math:`\log{(1+f)}`: + + #. Let :math:`s` be :math:`\frac{f}{2+f}`, based on: + + .. math:: + :label: formula_log_2 + + \log{(1+f)} &= \log{(1+s)} - \log{(1-s)} \\ + &= 2s + s \cdot \sum\limits_{i=1}^{\infty} \bigg(\frac{2}{2i+1} \cdot s^2\bigg) \\ + &= 2s + s \cdot R(z) \wedge z = 2s + + #. Use the following polynomial to approximate :math:`R(z)`: + + .. math:: + :label: formula_log_3 + + R(z) \sim L1 \cdot s^2 + L2 \cdot s^4 + L3 \cdot s^6 + L4 \cdot s^8 + L5 \cdot s^{10} +L6 \cdot s^{12} + L7 \cdot s^{14} + + The error of this approximation is smaller than or equal to :math:`2^{-58.45}`. + #. To ensure that the error of :math:`\log{(1+f)}` is below 1 :ref:`ULP ` use the identity: + + .. math:: + :label: formula_log_4 + + 2s = f - s \cdot f = f - \frac{f^2}{2} + s \cdot \frac{f^2}{2} + + Therefore if :math:`f` is not too large [#]_: + + .. math:: + :label: formula_log_5 + + \log{(1+f)} = f - s \cdot (f - R) + + Otherwise: + + .. math:: + :label: formula_log_6 + + \log{(1+f)} = f - \bigg(\frac{f^2}{2} - s \cdot \Big(\frac{f^2}{2} - R\Big)\bigg) + +#. For :math:`k` is :math:`0`, return :math:`\log{(1+f)}`. +#. Return (split :math:`ln(2)` into :math:`Ln2_{hi}` and :math:`Ln2_{lo}` for more accuracy) + + .. math:: + :label: formula_log_7 + + \log{(x)} &= k \cdot Ln2 + \log{(1+f)} \\ + &= k \cdot Ln2_{hi} + (f - (s \cdot (f - R) + k \cdot Ln2_{lo})) \\ + \vee \qquad &= k \cdot Ln2_{hi} + \Bigg(f - \bigg(\frac{f^2}{2} - s \cdot \Big(\frac{f^2}{2} - R\Big) + k \cdot Ln2_{lo}\bigg)\Bigg) + + Use the first version if formula :math:numref:`formula_log_5` was used earlier, otherwise use the second one. + +.. [#] This implementation of log is a variation of the algorithm proposed by W. J. Cody, JR. and W. Waite in *Software Manual for the Elementary Functions* +.. [#] Use mantissa part of ``highword`` + ``0x95f64`` (float: integer representation + ``0x95f64 << 3``) to find :math:`k`. +.. [#] :math:`f` is too large when ``0x6147A`` :math:`<` mantissa part of ``highword`` of :math:`x <` ``0x6B851`` (float: ``0x6147A << 3`` :math:`<` mantissa part of integer representation of :math:`x <` ``0x6B851 << 3``). + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-0900 +* REQ-ML-0910 +* REQ-ML-0920 +* REQ-ML-0921 +* REQ-ML-0930 +* REQ-ML-0931 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/logd.c +* libm/mathf/logf.c + +References +^^^^^^^^^^ + +* :ref:`__lgamma ` +* :ref:`acosh` +* :ref:`asinh` +* :ref:`catan` +* :ref:`clog` +* :ref:`cpow` +* :ref:`jn` +* :ref:`y0` +* :ref:`y1` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0370_log10.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0370_log10.rst new file mode 100644 index 00000000..ff821f99 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0370_log10.rst @@ -0,0 +1,87 @@ +log10 +~~~~~ + +.. c:autodoc:: mathd/log10d.c + +Special cases +^^^^^^^^^^^^^ + ++--------------------------+--------------------------+ +| x | Result | ++==========================+==========================+ +| :math:`<0` | :math:`qNaN` | ++--------------------------+--------------------------+ +| :math:`±0` | :math:`-Inf` | ++--------------------------+--------------------------+ +| :math:`1` | :math:`+0` | ++--------------------------+--------------------------+ +| :math:`+Inf` | :math:`+Inf` | ++--------------------------+--------------------------+ +| :math:`NaN` | :math:`qNaN` | ++--------------------------+--------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +The approach is to first work on special values and then use polynomial approximation for the calculation. + +Use the following constants as calculation/return values: + +* :math:`log_{10}(2) \approx Log_{10}2_{hi} + Log_{10}2_{lo}` +* :math:`Log_{10}2_{hi} =` ``0x3FD34413509F6000 (0x3E9A2080)`` +* :math:`Log_{10}2_{lo} =` ``0x3D59FEF311F12B36 (0x355427DB)`` +* :math:`\frac{1}{ln(10)} \approx invln10_{hi} + invln10_{lo}` +* :math:`invln10_{hi} =` ``0x3FDBCB7B15200000 (0x3EDE6000)`` +* :math:`invln10_{lo} =` ``0x3DBB9438CA9AADD5 (0xB804EAD9)`` + +#. For :math:`x` is :math:`NaN` or positive infinity, return :math:`x+x`. +#. For :math:`x` is a zero, return negative infinity. +#. For :math:`x` is negative, return :math:`NaN`. +#. For :math:`x` is subnormal, scale up by multiplying with :math:`2^{54}` (float: :math:`2^{25}`). +#. Given :math:`x` find :math:`f` and integer :math:`k` such that the formulae [#]_ + + .. math:: + :label: formula_log10_1 + + x &= 2^k \cdot (1 + f) \\ + \frac{\sqrt{2}}{2} &< (1 + f) < \sqrt{2} + + hold true [#]_. +#. Use :ref:`__log1p ` to return the result of: + + .. math:: + :label: formula_log10_2 + + hfsq &= \frac{f^2}{2} \\ + r &= \_\_log1p(f) \\ + hi &= f - hfsq,\ with\ the\ lowword\ masked\ off \\ + lo &= (f - hi) - hfsq + r \\ + z &= k \cdot Log_{10}2_{hi} \\ + w &= z + hi \cdot invln10_{hi} \\ + log_{10}{x} &= \Big(\big(k \cdot Log_{10}2_{lo} + (lo + hi) \cdot invln10_{lo} + lo \cdot invln10_{hi}\big) \\ + &\qquad + (z - w) + hi \cdot invln10_{hi}\Big) + w + +.. [#] This implementation of log is a variation of the algorithm proposed by W. J. Cody, JR. and W. Waite in *Software Manual for the Elementary Functions* +.. [#] Use mantissa part of ``highword`` + ``0x95f64`` (float: integer representation + ``0x95f64 << 3``) to find :math:`k`. + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-0950 +* REQ-ML-0960 +* REQ-ML-0970 +* REQ-ML-0971 +* REQ-ML-0980 +* REQ-ML-0981 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/log10d.c +* libm/mathf/log10f.c + +References +^^^^^^^^^^ + +* :ref:`__log1pmf ` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0380_log1p.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0380_log1p.rst new file mode 100644 index 00000000..83500d83 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0380_log1p.rst @@ -0,0 +1,53 @@ +log1p +~~~~~ + +.. c:autodoc:: mathd/log1pd.c + +Special cases +^^^^^^^^^^^^^ + ++--------------------------+--------------------------+ +| x | Result | ++==========================+==========================+ +| :math:`<-1` | :math:`qNaN` | ++--------------------------+--------------------------+ +| :math:`-1` | :math:`-Inf` | ++--------------------------+--------------------------+ +| :math:`±0` | :math:`x` | ++--------------------------+--------------------------+ +| :math:`+Inf` | :math:`+Inf` | ++--------------------------+--------------------------+ +| :math:`NaN` | :math:`qNaN` | ++--------------------------+--------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +Implement similarly to :ref:`log10` using :ref:`__log1pmf `. + +.. Here there be dragons. (TODO) + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-3400 +* REQ-ML-3410 +* REQ-ML-3420 +* REQ-ML-3430 +* REQ-ML-3440 +* REQ-ML-3450 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/log1pd.c +* libm/mathf/log1pf.c + +References +^^^^^^^^^^ + +* :ref:`__log1pmf ` +* :ref:`acosh` +* :ref:`asinh` +* :ref:`atanh` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0390_log2.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0390_log2.rst new file mode 100644 index 00000000..98a6aec0 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0390_log2.rst @@ -0,0 +1,50 @@ +log2 +~~~~ + +.. c:autodoc:: mathd/log2d.c + +Special cases +^^^^^^^^^^^^^ + ++--------------------------+--------------------------+ +| x | Result | ++==========================+==========================+ +| :math:`<0` | :math:`qNaN` | ++--------------------------+--------------------------+ +| :math:`±0` | :math:`-Inf` | ++--------------------------+--------------------------+ +| :math:`1` | :math:`+0` | ++--------------------------+--------------------------+ +| :math:`+Inf` | :math:`+Inf` | ++--------------------------+--------------------------+ +| :math:`NaN` | :math:`qNaN` | ++--------------------------+--------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +Implement similarly to :ref:`log10` using :ref:`__log1pmf `. + +.. Here there be dragons. (TODO) + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-3300 +* REQ-ML-3310 +* REQ-ML-3320 +* REQ-ML-3330 +* REQ-ML-3340 +* REQ-ML-3350 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/log2d.c +* libm/mathf/log2f.c + +References +^^^^^^^^^^ + +* :ref:`__log1pmf ` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0400_logb.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0400_logb.rst new file mode 100644 index 00000000..7f8be7a3 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0400_logb.rst @@ -0,0 +1,44 @@ +logb +~~~~ + +.. c:autodoc:: mathd/logbd.c + +Special cases +^^^^^^^^^^^^^ + ++--------------------------+--------------------------+ +| x | Result | ++==========================+==========================+ +| :math:`±0` | :math:`-Inf` | ++--------------------------+--------------------------+ +| :math:`±Inf` | :math:`+Inf` | ++--------------------------+--------------------------+ +| :math:`NaN` | :math:`NaN` | ++--------------------------+--------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +Implement based on bit-fiddling. + +.. Here there be dragons. (TODO) + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-3500 +* REQ-ML-3510 +* REQ-ML-3520 +* REQ-ML-3540 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/logbd.c +* libm/mathf/logbf.c + +References +^^^^^^^^^^ + +* :ref:`ilogb` \ No newline at end of file diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0410_modf.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0410_modf.rst new file mode 100644 index 00000000..55c5af0c --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0410_modf.rst @@ -0,0 +1,68 @@ +modf +~~~~ + +.. c:autodoc:: mathd/modfd.c + +Special cases +^^^^^^^^^^^^^ + ++------------------------------+------------------------------+--------------------------+ +| x | :math:`*iptr` | Result | ++==============================+==============================+==========================+ +| :math:`-Inf` | :math:`-Inf` | :math:`-0` | ++------------------------------+------------------------------+--------------------------+ +| :math:`+Inf` | :math:`+Inf` | :math:`+0` | ++------------------------------+------------------------------+--------------------------+ +| :math:`NaN` | :math:`qNaN` | :math:`qNaN` | ++------------------------------+------------------------------+--------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +The approach is to first work on special values and then use bit-fiddling tricks. + +All the following outputs (both return value and out-pointer) shall have the same sign as the input value. + +#. If the argument :math:`*iptr` is a NULL-pointer replace the pointer internally with a valid one. At the end place a NULL-pointer to the out-pointer regardless of what is otherwise stated at that branch. The return value remains unchanged. +#. Return :math:`qNaN` to both outputs if the input value is :math:`NaN`. +#. Return a zero if the input value is infinite, and place the infinity to the out-pointer. +#. If the exponent is :math:`< 20`, the integral part of :math:`x` is in the double's highword: + + #. If the exponent is :math:`< 0`, there is no integral part, return the input and place a zero to the out-pointer. + #. If the input is integral, return a zero and place the input value to the out-pointer. + #. Return the fractional part of the input and place the integral part to the out-pointer. + +#. If the exponent is :math:`> 51`, there is no fractional part, return a zero and place the input value to the out-pointer. +#. If the input is integral, return a zero and place the input value to the out-pointer. +#. Return the fractional part of the input and place the integral part to the out-pointer. + +For the float version: + +#. Same as the first 3 steps as the double version. +#. If the exponent is :math:`< 23`, there may be a fractional part: + + #. If the exponent is :math:`< 0`, there is no integral part, return the input and place a zero to the out-pointer. + #. If the input is integral, return a zero and place the input value to the out-pointer. + #. Return the fractional part of the input and place the integral part to the out-pointer. + +#. Return a zero and place the input value to the out-pointer. + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-1200 +* REQ-ML-1201 +* REQ-ML-1210 +* REQ-ML-1211 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/modfd.c +* libm/mathf/modff.c + +References +^^^^^^^^^^ + +* :ref:`isnan` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0420_scalbn.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0420_scalbn.rst new file mode 100644 index 00000000..9416dce9 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0420_scalbn.rst @@ -0,0 +1,81 @@ +scalbn +~~~~~~ + +.. c:autodoc:: mathd/scalbnd.c + +Special cases +^^^^^^^^^^^^^ + ++------------------------+------------------------+------------------------+ +| x | n | Result | ++========================+========================+========================+ +| :math:`±0` | :math:`\in \mathbb{I}` | :math:`x` | ++------------------------+------------------------+------------------------+ +| :math:`\in \mathbb{F}` | :math:`0` | :math:`x` | ++------------------------+------------------------+------------------------+ +| :math:`±Inf` | :math:`\in \mathbb{I}` | :math:`x` | ++------------------------+------------------------+------------------------+ +| :math:`NaN` | :math:`\in \mathbb{I}` | :math:`qNaN` | ++------------------------+------------------------+------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +The approach is to first work on special values and then use bit-fiddling tricks. + +All the following return values shall have the same sign as the input value, use :ref:`copysign`. + +#. For :math:`x` is zero, infinite or ``NaN``, return :math:`x`. + +#. If the input is subnormal or zero: + + #. If the input is zero, return a zero. + #. Scale up the input by multiplying with :math:`2^{54}`. + #. If :math:`n` is :math:`< -50000` return a zero. + +#. If the exponent of :math:`x` is :math:`1024`, :math:`x` is :math:`NaN` or infinite, return :math:`x+x`. +#. If the exponent of :math:`x` :math:`+ n` is :math:`> 1023`, return an infinity, with overflow. +#. If the exponent of :math:`x` :math:`+ n` is :math:`> 0`, return :math:`x` with the exponent increased by :math:`n`. +#. If the exponent of :math:`x` :math:`+ n` is :math:`> -54`, return :math:`x` with the exponent increased by :math:`n` and then multiplied with :math:`2^{-54}`. +#. If :math:`n` is :math:`> 50000` return an infinity, with overflow. +#. Return a zero. + +For the float version: + +#. If the input is zero, return a zero. +#. If the input is not finite, return :math:`x+x`. +#. If the input is subnormal: + + #. Scale up the input by multiplying with :math:`2^{25}`. + #. If :math:`n` is :math:`< -50000` return a zero. + +#. If the exponent :math:`x` :math:`+ n` is :math:`> 254`, return an infinity, with overflow. +#. If the exponent :math:`x` :math:`+ n` is :math:`> 0`, return :math:`x` with the exponent increased by :math:`n`. +#. If the exponent :math:`x` :math:`+ n` is :math:`>= -22`, return :math:`x` with the exponent increased by :math:`n` and then multiplied with :math:`2^{-25}`. +#. If :math:`n` is :math:`> 50000` return an infinity, with overflow. +#. Return a zero. + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-4200 +* REQ-ML-4210 +* REQ-ML-4220 +* REQ-ML-4230 +* REQ-ML-4240 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/scalbnd.c +* libm/mathf/scalbnf.c + +References +^^^^^^^^^^ + +* :ref:`__rem_pio2_internal ` +* :ref:`copysign` +* :ref:`ldexp` +* :ref:`pow` +* :ref:`scalbln` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0430_scalbln.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0430_scalbln.rst new file mode 100644 index 00000000..37dde320 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0430_scalbln.rst @@ -0,0 +1,44 @@ +scalbln +~~~~~~~ + +.. c:autodoc:: mathd/scalblnd.c + +Special cases +^^^^^^^^^^^^^ + ++------------------------+------------------------+------------------------+ +| x | n | Result | ++========================+========================+========================+ +| :math:`±0` | :math:`\in \mathbb{I}` | :math:`x` | ++------------------------+------------------------+------------------------+ +| :math:`\in \mathbb{F}` | :math:`0` | :math:`x` | ++------------------------+------------------------+------------------------+ +| :math:`±Inf` | :math:`\in \mathbb{I}` | :math:`x` | ++------------------------+------------------------+------------------------+ +| :math:`NaN` | :math:`\in \mathbb{I}` | :math:`qNaN` | ++------------------------+------------------------+------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +Implement similarly to :ref:`scalbn`. + +.. Here there be dragons. (TODO) + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-4250 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/scalblnd.c +* libm/mathf/scalblnf.c + +References +^^^^^^^^^^ + +* :ref:`copysign` +* :ref:`scalbn` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0440_log_internal.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0440_log_internal.rst new file mode 100644 index 00000000..9126c076 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0440_log_internal.rst @@ -0,0 +1,76 @@ +.. _internal_log: + +Internal Logarithm Functions +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. c:autodoc:: mathd/internal/log1pmfd.h + +.. raw:: html + + + +Special cases +^^^^^^^^^^^^^ + +The special cases are in the respective external functions :ref:`log2` and :ref:`log10`. + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +``__log1pmf``: The approach is to use a polynomial approximation for the calculation. + +The procedure shall be always inlined. + +This calculation is a simplification of the theory employed and described in :ref:`log10` and omits the considerations regarding extra precision, as this is done by the upper level procedures. + +Use the following constants as calculation/return values: + +* :math:`L1 =` ``0x3FE5555555555593 (0x3F2AAAAA)`` +* :math:`L2 =` ``0x3FD999999997FA04 (0x3ECCCE13)`` +* :math:`L3 =` ``0x3FD2492494229359 (0x3E91E9EE)`` +* :math:`L4 =` ``0x3FCC71C51D8E78AF (0x3E789E26)`` +* :math:`L5 =` ``0x3FC7466496CB03DE`` +* :math:`L6 =` ``0x3FC39A09D078C69F`` +* :math:`L7 =` ``0x3FC2F112DF3E5244`` + +The logarithm is computed by evaluating the following polynomial and return :math:`r`: + +.. math:: + :label: formula_log_internal_1 + + s &= \frac{f}{2+f} \\ + R &= L1 \cdot s^2 + L2 \cdot s^4 + L3 \cdot s^6 + L4 \cdot s^8 + L5 \cdot s^{10} +L6 \cdot s^{12} + L7 \cdot s^{14} \\ + r &= s \cdot \Big(\frac{f^2}{2} + R\Big) + +For the float version the polynomial can be shortened to: + +.. math:: + :label: formula_log_internal_2 + + s &= \frac{f}{2+f} \\ + R &= L1 \cdot s^2 + L2 \cdot s^4 + L3 \cdot s^6 + L4 \cdot s^8 \\ + r &= s \cdot \Big(\frac{f^2}{2} + R\Big) + +Requirements +^^^^^^^^^^^^ + +Internal functions do not directly implement requirements. + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/mathd/internal/log1pmfd.h +* libm/mathf/internal/log1pmff.h +* libm/mathd/internal/log1pmfd.c +* libm/mathf/internal/log1pmff.c + +References +^^^^^^^^^^ + +* :ref:`log10` +* :ref:`log1p` +* :ref:`log2` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0500_cbrt.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0500_cbrt.rst new file mode 100644 index 00000000..cb8cfc14 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0500_cbrt.rst @@ -0,0 +1,42 @@ +cbrt +~~~~ + +.. c:autodoc:: mathd/cbrtd.c + +Special cases +^^^^^^^^^^^^^ + ++--------------------------+--------------------------+ +| x | Result | ++==========================+==========================+ +| :math:`±0` | :math:`x` | ++--------------------------+--------------------------+ +| :math:`±Inf` | :math:`x` | ++--------------------------+--------------------------+ +| :math:`NaN` | :math:`qNaN` | ++--------------------------+--------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +Implement based on the Newton-Raphson method. + +.. Here there be dragons. (TODO) + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-2300 +* REQ-ML-2310 +* REQ-ML-2320 +* REQ-ML-2340 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/cbrtd.c +* libm/mathf/cbrtf.c + +References +^^^^^^^^^^ diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0510_fabs.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0510_fabs.rst new file mode 100644 index 00000000..19ca1835 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0510_fabs.rst @@ -0,0 +1,66 @@ +fabs +~~~~ + +.. c:autodoc:: mathd/fabsd.c + +Special cases +^^^^^^^^^^^^^ + ++--------------------------+--------------------------+ +| x | Result | ++==========================+==========================+ +| :math:`±0` | :math:`+0` | ++--------------------------+--------------------------+ +| :math:`±Inf` | :math:`+Inf` | ++--------------------------+--------------------------+ +| :math:`qNaN` | :math:`qNaN` | ++--------------------------+--------------------------+ +| :math:`sNaN` | :math:`sNaN` | ++--------------------------+--------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +The approach is to mask off the signbit of :math:`x` and return :math:`x`. + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-1000 +* REQ-ML-1010 +* REQ-ML-1011 +* REQ-ML-1012 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/fabsd.c +* libm/mathf/fabsf.c + +References +^^^^^^^^^^ + +* :ref:`__ccoshsinh ` +* :ref:`__lgamma ` +* :ref:`__rem_pio2 ` +* :ref:`catan` +* :ref:`ccos` +* :ref:`csqrt` +* :ref:`csin` +* :ref:`ctan` +* :ref:`asin` +* :ref:`asinh` +* :ref:`atan` +* :ref:`atan2` +* :ref:`cosh` +* :ref:`erf` +* :ref:`erfc` +* :ref:`j0` +* :ref:`j1` +* :ref:`jn` +* :ref:`pow` +* :ref:`remainder` +* :ref:`remquo` +* :ref:`sinh` +* :ref:`tanh` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0520_hypot.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0520_hypot.rst new file mode 100644 index 00000000..c715a334 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0520_hypot.rst @@ -0,0 +1,74 @@ +hypot +~~~~~ + +.. c:autodoc:: mathd/hypotd.c + +Special cases +^^^^^^^^^^^^^ + ++-----------------------------+-----------------------------+------------------------------+ +| x | y | Result | ++=============================+=============================+==============================+ +| :math:`\in \mathbb{F}` | :math:`±Inf` | :math:`+Inf` | ++-----------------------------+-----------------------------+------------------------------+ +| :math:`±Inf` | :math:`\in \mathbb{F}` | :math:`+Inf` | ++-----------------------------+-----------------------------+------------------------------+ +| :math:`NaN` | :math:`\neq ±Inf` | :math:`qNaN` | ++-----------------------------+-----------------------------+------------------------------+ +| :math:`\neq ±Inf` | :math:`NaN` | :math:`qNaN` | ++-----------------------------+-----------------------------+------------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +The approach is to first work on special values and overflows, then use :ref:`sqrt` for the calculation. + +#. Assume :math:`x > y`, otherwise replace :math:`x` with :math:`y` and :math:`y` with :math:`x`. +#. Set both :math:`x` and :math:`y` to their absolute value. +#. For :math:`\frac{x}{y} > 2^{60}` (float: :math:`2^{30}`), :math:`y` is too small to matter when the result is represented with double (float) precision, return :math:`x`. +#. For :math:`x` or :math:`y` is infinite, return ``+Inf``. +#. For :math:`x` or :math:`y` is ``NaN``, return :math:`x + y`. +#. For :math:`x > 2^{500}` (float: :math:`2^{50}`), scale down :math:`x` and :math:`y` by multiplying them with :math:`2^{-600}` (float: :math:`2^{-68}`), otherwise their combined squares will overflow the double (float) range. +#. For :math:`y < 2^{-500}` (float: :math:`2^{-50}`), scale up :math:`x` and :math:`y` by multiplying them with :math:`2^{600}` (float: :math:`2^{68}`), otherwise their combined squares will underflow the double (float) range. + +#. If :math:`z = x \cdot x + y \cdot y` has an error of less than :math:`\frac{\sqrt{2}}{2}` :ref:`ULPs `, then :math:`\sqrt{z}` has an error of less than 1 :ref:`ULP `. Using this relation calculate :math:`\sqrt{x \cdot x + y \cdot y}` as follows: + + #. If :math:`x > 2y` use the following to replace :math:`x \cdot x + y \cdot y`: + + .. math:: + :label: formula_hypot_1 + + x_1 \cdot x_1 + (y \cdot y + (x_2 \cdot (x+x_1))) + + with :math:`x_1 = x` with the lower 32bits (float: 12bits) cleared and :math:`x_2 = x - x_1`. + #. Otherwise use: + + .. math:: + :label: formula_hypot_2 + + t_1 \cdot y_1 + ((x-y) \cdot (x-y)+(t_1 \cdot y_2 + t_2 \cdot y)) + + with :math:`t_1 = 2x` with the lower 32bits (float: 12bits) cleared and :math:`t_2 = 2x - t_1`, and :math:`y_1 = y` with the lower 32bits (float: 12bits) cleared and :math:`y_2 = y - y_1`. + #. Use :ref:`sqrt` to calculate the square root of the replacement :math:numref:`formula_hypot_1` or :math:numref:`formula_hypot_2`. + +#. Revert the scaling on the resulting square root if any was done in an earlier step. +#. Return the calculated square root. + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-1260 +* REQ-ML-1270 +* REQ-ML-1271 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/hypotd.c +* libm/mathf/hypotf.c + +References +^^^^^^^^^^ + +* :ref:`sqrt` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0530_pow.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0530_pow.rst new file mode 100644 index 00000000..2ac2c504 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0530_pow.rst @@ -0,0 +1,345 @@ +pow +~~~~~ + +.. c:autodoc:: mathd/powd.c + +Special cases +^^^^^^^^^^^^^ + ++-------------------------------------------+---------------------------------------------------------------------+------------------------------+ +| :math:`x` | :math:`y` | Result | ++===========================================+=====================================================================+==============================+ +| :math:`<0\ \wedge \neq -Inf` | :math:`\notin \mathbb{Z}^{*}` | :math:`qNaN` | ++-------------------------------------------+---------------------------------------------------------------------+------------------------------+ +| :math:`-0` | :math:`\{2k + 1 : k \in \mathbb{Z}_{<0}\}` | :math:`-Inf` | ++-------------------------------------------+---------------------------------------------------------------------+------------------------------+ +| :math:`-0` | :math:`\in \mathbb{F}_{<0} \setminus \{2k + 1 : k \in \mathbb{Z}\}` | :math:`+Inf` | ++-------------------------------------------+---------------------------------------------------------------------+------------------------------+ +| :math:`+0` | :math:`<0` | :math:`+Inf` | ++-------------------------------------------+---------------------------------------------------------------------+------------------------------+ +| :math:`±0` | :math:`\{2k - 1 : k \in \mathbb{Z}_{>0}\}` | :math:`x` | ++-------------------------------------------+---------------------------------------------------------------------+------------------------------+ +| :math:`±0` | :math:`\in \mathbb{F}_{>0} \setminus \{2k - 1 : k \in \mathbb{Z}\}` | :math:`+0` | ++-------------------------------------------+---------------------------------------------------------------------+------------------------------+ +| :math:`-1` | :math:`±Inf` | :math:`+1` | ++-------------------------------------------+---------------------------------------------------------------------+------------------------------+ +| :math:`+1` | :math:`\in \mathbb{F} \setminus \{sNaN\}` | :math:`+1` | ++-------------------------------------------+---------------------------------------------------------------------+------------------------------+ +| :math:`\in \mathbb{F} \setminus \{sNaN\}` | :math:`±0` | :math:`+1` | ++-------------------------------------------+---------------------------------------------------------------------+------------------------------+ +| :math:`\in ]-1;1[` | :math:`-Inf` | :math:`+Inf` | ++-------------------------------------------+---------------------------------------------------------------------+------------------------------+ +| :math:`\notin [-1;1]` | :math:`-Inf` | :math:`+0` | ++-------------------------------------------+---------------------------------------------------------------------+------------------------------+ +| :math:`\in ]-1;1[` | :math:`+Inf` | :math:`+0` | ++-------------------------------------------+---------------------------------------------------------------------+------------------------------+ +| :math:`\notin [-1;1]` | :math:`+Inf` | :math:`+Inf` | ++-------------------------------------------+---------------------------------------------------------------------+------------------------------+ +| :math:`-Inf` | :math:`\{2k + 1 : k \in \mathbb{Z}_{<0}\}` | :math:`-0` | ++-------------------------------------------+---------------------------------------------------------------------+------------------------------+ +| :math:`-Inf` | :math:`\in \mathbb{F}_{<0} \setminus \{2k + 1 : k \in \mathbb{Z}\}` | :math:`+0` | ++-------------------------------------------+---------------------------------------------------------------------+------------------------------+ +| :math:`-Inf` | :math:`\{2k - 1 : k \in \mathbb{Z}_{>0}\}` | :math:`-Inf` | ++-------------------------------------------+---------------------------------------------------------------------+------------------------------+ +| :math:`-Inf` | :math:`\in \mathbb{F}_{>0} \setminus \{2k - 1 : k \in \mathbb{Z}\}` | :math:`+Inf` | ++-------------------------------------------+---------------------------------------------------------------------+------------------------------+ +| :math:`+Inf` | :math:`<0` | :math:`+0` | ++-------------------------------------------+---------------------------------------------------------------------+------------------------------+ +| :math:`+Inf` | :math:`>0` | :math:`+Inf` | ++-------------------------------------------+---------------------------------------------------------------------+------------------------------+ +| :math:`NaN` | :math:`\neq ±0` | :math:`qNaN` | ++-------------------------------------------+---------------------------------------------------------------------+------------------------------+ +| :math:`qNaN` | :math:`±0` | :math:`+1` | ++-------------------------------------------+---------------------------------------------------------------------+------------------------------+ +| :math:`sNaN` | :math:`±0` | :math:`qNaN` | ++-------------------------------------------+---------------------------------------------------------------------+------------------------------+ +| :math:`\neq +1` | :math:`NaN` | :math:`qNaN` | ++-------------------------------------------+---------------------------------------------------------------------+------------------------------+ +| :math:`+1` | :math:`qNaN` | :math:`+1` | ++-------------------------------------------+---------------------------------------------------------------------+------------------------------+ +| :math:`+1` | :math:`sNaN` | :math:`qNaN` | ++-------------------------------------------+---------------------------------------------------------------------+------------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +The approach is to first work on special values then use the following approach for the calculation: + +#. Compute :math:`log_2(x)`, with increased accuracy. +#. Find an integral value :math:`n` where :math:`y \cdot log_2(x) = n + m`, and :math:`|m| <= 0.5`. +#. Then :math:`x^y = 2^n \cdot e^{m \cdot log_2(x)}`. + +Use the following constants as calculation values: + +* :math:`ln(2) \approx lg2_h + lg2_l \approx lg2` +* :math:`lg2 =` ``0x3FE62E42FEFA39EF (0x3F317218)`` +* :math:`lg2_h =` ``0x3FE62E4300000000 (0x3F317200)`` +* :math:`lg2_l =` ``0xBE205C610CA86C39 (0x35BFBE8C)`` +* :math:`\frac{1}{ln(2)} \approx invln2_h + invln2_l \approx invln2` +* :math:`invln2 =` ``0x3FF71547652B82FE (0x3FB8AA3B)`` +* :math:`invln2_h =` ``0x3FF7154760000000 (0x3FB8AA00)`` +* :math:`invln2_l =` ``0x3E54AE0BF85DDF44 (0x36ECA570)`` +* :math:`\frac{2}{3 \cdot ln(2)} \approx cp_h + cp_l \approx cp` +* :math:`cp =` ``0x3FEEC709DC3A03FD (0x3F76384F)`` +* :math:`cp_h =` ``0x3FEEC709E0000000 (0x3F764000)`` +* :math:`cp_l =` ``0xBE3E2FE0145B01F5 (0xB8F623C6)`` +* :math:`dp_h =` ``0x3FE2B80340000000 (0x3F15C000)`` +* :math:`dp_l =` ``0x3E4CFDEB43CFD006 (0x35D1CFDC)`` +* :math:`L1 =` ``0x3FE3333333333303 (0x3F19999A)`` +* :math:`L2 =` ``0x3FDB6DB6DB6FABFF (0x3EDB6DB7)`` +* :math:`L3 =` ``0x3FD55555518F264D (0x3EAAAAAB)`` +* :math:`L4 =` ``0x3FD17460A91D4101 (0x3E8BA305)`` +* :math:`L5 =` ``0x3FCD864A93C9DB65 (0x3E6C3255)`` +* :math:`L6 =` ``0x3FCA7E284A454EEF (0x3E53f142)`` +* :math:`P1 =` ``0x3FC555555555553E (0x3E2AAAAB)`` +* :math:`P2 =` ``0xBF66C16C16BEBD93 (0xBB360B61)`` +* :math:`P3 =` ``0x3F11566AAF25DE2C (0x388AB355)`` +* :math:`P4 =` ``0xBEBBBD41C5D26BF1 (0xB5DDEA0E)`` +* :math:`P5 =` ``0x3E66376972BEA4D0 (0x3331BB4C)`` + +#. For :math:`y` is zero, return :math:`1`. +#. For :math:`x` is :math:`+1` and :math:`y` is ``NaN``, return :math:`1`. +#. For :math:`x` or :math:`y` is ``NaN``, return the result of a call to :ref:`nan`. +#. For :math:`x < 0`, determine if :math:`y` is an odd integer as follows (the result shall be saved in the variable :math:`yisint`, it shall be :math:`0` if :math:`y` is not an integer, :math:`1` if it is odd, :math:`2` if it is even): + + #. For ``highword`` of :math:`y >=` ``0x43400000`` (float: integer representation of :math:`y >=` ``0x4B800000``) [#]_, set :math:`yisint` to :math:`2`. + #. For :math:`y >= 1`: + + #. For binary exponent :math:`k` of :math:`y > 20`: + + #. Set :math:`j` to the ``lowword`` of :math:`y` shifted right by :math:`(52 - k)`. [#]_ + #. For :math:`(j` shifted left by :math:`(52 - k))` equals the ``lowword`` of :math:`y` [#]_, set :math:`yisint` to :math:`(2 -` last bit of :math:`j)`. + + #. For the ``lowword`` of :math:`y` is :math:`0`: + + #. Set :math:`j` to the ``highword`` of :math:`y` shifted right by :math:`(20 - k)`. + #. For :math:`(j` shifted left by :math:`(20 - k))` equals the ``highword`` of :math:`y`, set :math:`yisint` to :math:`(2 -` last bit of :math:`j)`. + + #. For the float version of this procedure skip the previous two steps and their substeps and replace them with: + + #. Let :math:`k` be the binary exponent of :math:`y`. + #. Set :math:`j` to the integer representation of :math:`y` shifted right by :math:`(23 - k)`. + #. For :math:`(j` shifted left by :math:`(23 - k))` equals the integer representation of :math:`y`, set :math:`yisint` to :math:`(2 -` last bit of :math:`j)`. + + #. If :math:`yisint` has not yet been set in the earlier steps, set it to :math:`0`. + +#. For ``lowword`` of :math:`y` is :math:`0` (float: omit this if-clause, but use its contents) [#]_: + + #. For :math:`y` is infinite: + + #. For :math:`x` is :math:`1`, return :math:`1`. + #. For :math:`|x| > 1`: + + #. For :math:`y` is positive, return :math:`y`. + #. Return :math:`0`. + + #. Otherwise: + + #. For :math:`y` is positive, return :math:`0`. + #. Return :math:`-y`. + + #. For :math:`y` is :math:`1`, return :math:`x`. + #. For :math:`y` is :math:`-1`, return :math:`\frac{1}{x}`. + #. For :math:`y` is :math:`2`, return :math:`x \cdot x`. + #. For :math:`y` is :math:`0.5` and :math:`x` greater than or equal to positive zero, return :math:`\sqrt{x}`, using :ref:`sqrt` to calculate the square root of :math:`x`. + +#. Let :math:`ax = |x|`, using :ref:`fabs` to calculate the absolute value of :math:`x`. +#. For :math:`x` is infinite, a zero, :math:`-1` or :math:`1`: + + #. For :math:`y < 0`, let :math:`z = \frac{1}{|x|} = \frac{1}{ax}`. + #. For :math:`x < 0`: + + #. For :math:`yisint` is :math:`0` (:math:`y` is not an integer) and :math:`x` is :math:`-1`, let :math:`z =` ``NaN``. + #. For :math:`yisint` is :math:`1` (:math:`y` is an odd integer), let :math:`z = -z`. + + #. Return :math:`z`. + +#. For :math:`yisint` is :math:`0` (:math:`y` is not an integer) and :math:`x < 0`, return ``NaN``. +#. For :math:`yisint` is :math:`1` (:math:`y` is an odd integer) and :math:`x < 0`, set :math:`sn = -1`, otherwise set :math:`sn = +1` (this contains the sign for the final result). +#. For :math:`|y| > 2^{31}` (float: :math:`|y| > 2^{27}`): + + #. For :math:`|y| > 2^{64}`, as for such high :math:`y` either an under- or overflow is guaranteed (float: omit this step and its substeps): + + #. For :math:`|x| < 1`: + + #. For :math:`y < 0`, return infinity with sign of :math:`sn`. + #. Return :math:`0` with sign of :math:`sn`. + + #. Otherwise: + + #. For :math:`y > 0`, return infinity with sign of :math:`sn`. + #. Return :math:`0` with sign of :math:`sn`. + + #. For ``highword`` of :math:`|x| <` ``0x3FEFFFFF`` (float: integer representation of :math:`|x| <` ``0x3F7FFFF4``) [#]_: + + #. For :math:`y < 0`, return positive infinity (float: return infinity with sign of :math:`sn`). + #. Return :math:`0` (float: return :math:`0` with sign of :math:`sn`). + + #. For ``highword`` of :math:`|x| >` ``0x3FF00000`` (float: integer representation of :math:`|x| >` ``0x3F800007``) [#]_: + + #. For :math:`y > 0`, return positive infinity (float: return infinity with sign of :math:`sn`). + #. Return :math:`0` (float: return :math:`0` with sign of :math:`sn`). + + #. Set :math:`t = |x| - 1 = ax - 1`. + #. Set :math:`w = t^2 \cdot (\frac{1}{2} - t \cdot (\frac{1}{3} - t \cdot \frac{1}{4}))` which is an approximation for :math:`log(x)` for :math:`x` close to :math:`1`. + #. Set :math:`t1 = invln2_{h} \cdot t + (t \cdot invln2_{l} - w \cdot invln2)`, with ``lowword`` masked to :math:`0` (float: with the 12 lowest bits masked to :math:`0`). + #. Set :math:`t2 = (t \cdot invln2_{l} - w \cdot invln2) - (t1 - invln2_{h} \cdot t)`. + +#. Otherwise: + + #. For :math:`x` is subnormal, scale :math:`x` and :math:`ax` by multiplying them with :math:`2^{53}` (float: :math:`2^{24}`). + #. Set :math:`n` to the exponent of the original :math:`x` [#]_. + #. Normalize :math:`ix` by setting the exponent to :math:`0` [#]_. + #. For :math:`|x| < \sqrt{\frac{3}{2}}` [#]_, set :math:`k` to :math:`0`. + #. For :math:`|x| < \sqrt{3}` [#]_, set :math:`k` to :math:`1`. + #. If :math:`k` has not been set in the two previous steps, set :math:`k` to :math:`0`, increase :math:`n` by :math:`1`, and decrease the exponent of :math:`ix` by :math:`1`. + #. Set the ``highword`` of :math:`ax` to :math:`ix` (float: Set :math:`ax` to :math:`ix`). + #. Compute :math:`s = \frac{ax-bp}{ax+bp}`, with :math:`bp = 1+\frac{k}{2}`, with increased accuracy by splitting :math:`s` into :math:`s_{h} + s_{l}` by using the following formulae: + + .. math:: + :label: formula_pow_1 + + s &= \frac{ax-bp}{ax+bp} \\ + s_{h} &= highword\ of \bigg(\frac{ax-bp}{ax+bp}\bigg) \\ + s_{l} &= \frac{1}{ax+bp} \cdot (((ax-bp) - s_{h} \cdot t_{h}) - s_{h} \cdot t_{l}) + + with + + #. :math:`t_{h} = ax + bp` with ``lowword`` (float: lowest 12 bits) set to all zeroes. + #. :math:`t_{l} = ax - (t_{h}-bp)`. + + For float replace :math:`s_{h}` in formula :math:numref:`formula_pow_1` with :math:`s_{h} = \bigg(\frac{ax-bp}{ax+bp}\bigg)` with the lowest 12 bits set to all zeroes. + + #. Compute the logarithm of :math:`ax` with the following approximation (the theory behind the approximation is similar (smaller polynomial and in range :math:`[\frac{\sqrt{3}}{2}, \sqrt{3}]`) to the one expressed for :ref:`log` and will not be presented here): + + .. math:: + :label: formula_pow_2 + + R(s) &= s^2 \cdot (L1 + s^2 \cdot (L2 + s^2 \cdot (L3 + s^2 \cdot (L4 + s^2 \cdot (L5 + s^2 \cdot L6))))) \\ + r &= s^2 \cdot R(s) + s_{l} \cdot (s_{h} + s) \\ + t_{h} &= 3 + s_{h}^2 + r \quad \wedge \quad lowword\ of\ t_{h}\ set\ to\ all\ zeroes \\ + t_{l} &= r - ((t_{h} - 3) - s_{h}^2) \\ + p_{h} &= s_{h} \cdot t_{h} + (s_{l} \cdot t_{h} + t_{l} \cdot s) \quad \wedge \quad lowword\ of\ p_{h}\ set\ to\ all\ zeroes \\ + p_{l} &= (s_{l} \cdot t_{h} + t_{l} \cdot s) - (p_{h} - (s_{h} \cdot t_{h})) \\ + z_{h} &= cp_h \cdot p_h \\ + z_{l} &= cp_l \cdot p_h + p_l \cdot cp + dp_l \\ + t1 &= z_h+z_l+dp_h+n \\ + t2 &= z_l-(((t1-n)-dp_h)-z_h) + + with + + #. :math:`dp_h` and :math:`dp_l` are zero if :math:`k` is zero, otherwise they have the values described at the beginning. + + For float replace :math:`t_{h}` in formula :math:numref:`formula_pow_2` with :math:`t_{h} = 3 + s_{h}^2 + r` with the lowest 12 bits set to all zeroes, and replace :math:`p_{h}` with :math:`p_{h} = s_{h} \cdot t_{h} + (s_{l} \cdot t_{h} + t_{l} \cdot s)` with the lowest 12 bits set to all zeroes. + +#. Split :math:`y` into :math:`y1 + y2`: + + #. :math:`y1 = y` with ``lowword`` (float: lowest 12 bits) set to all zeroes. + #. :math:`y2 = y - y1`. + +#. Calculate :math:`y \cdot log_2(x)` as follows: + + .. math:: + :label: formula_pow_3 + + p_{l} &= y2 \cdot t1 + y \cdot t2 \\ + p_{h} &= y1 \cdot t1 \\ + y \cdot log_2(x) &= p_l + p_h + +#. For :math:`y \cdot log_2(x) >= 1024` (float: :math:`y \cdot log_2(x) >= 128`): + + #. For :math:`y \cdot log_2(x) > 1024` (float: :math:`y \cdot log_2(x) > 128`) return infinity with the sign of :math:`s`. + #. For :math:`p_l + ovt > y \cdot log_2(x) - p_h`, with :math:`ovt = 8.0085662595372944372 \cdot 10^{-17}` (float: :math:`ovt = 4.2995665694 \cdot 10^{-8}`) [#]_, return infinity with the sign of :math:`s`. + +#. For :math:`y \cdot log_2(x) <= -1075` (float: :math:`y \cdot log_2(x) <= -150`): + + #. For :math:`y \cdot log_2(x) < -1075` (float: :math:`y \cdot log_2(x) < -150`) return zero with the sign of :math:`s`. + #. For :math:`p_l <= y \cdot log_2(x) - p_h` return zero with the sign of :math:`s`. + +#. Calculate :math:`e^{m \cdot log_2(x)}`: + + #. Set :math:`k =` exponent of :math:`y \cdot log_2(x)`, and :math:`n = 0`. + #. For :math:`|y \cdot log_2(x)| > 0.5`: + + #. Set :math:`n = ` ``highword`` (float: integer representation) of :math:`(y \cdot log_2(x) + 0.5)`. + #. Set :math:`k =` exponent of :math:`n`. + #. Set :math:`t` to a new double (float) with (exponent of :math:`n` including sign) right shifted by :math:`k` as ``highword``, and all zeros as ``lowword`` (float: right shift by :math:`k`). + #. Replace the exponent of :math:`n` with :math:`1`, then right shift :math:`n` by :math:`(20-k)` (float: :math:`(23-k)`). + #. For :math:`y \cdot log_2(x) < 0` set the sign of :math:`n`. + #. Set :math:`p_h = p_h - t`. + + #. Calculate :math:`e^{m \cdot log_2(x)}` with the following approximation (the theory behind the approximation is the one expressed for :ref:`exp` and will not be presented here): + + .. math:: + :label: formula_pow_4 + + t &= p_l + p_h \quad \wedge \quad lowword\ of\ t\ set\ to\ all\ zeroes \\ + z &= (t \cdot lg2_h) + ((p_l-(t-p_h)) \cdot lg2 + t \cdot lg2_l) \\ + w &= ((p_l-(t-p_h)) \cdot lg2 + t \cdot lg2_l) - (z - (t \cdot lg2_h)) \\ + t1 &= z - z^2 \cdot (P1 + z^2 \cdot (P2 + z^2 \cdot (P3 + z^2 \cdot (P4 + z^2 \cdot P5)))) \\ + r &= \frac{z \cdot t1}{t1-2}-(w+z \cdot w) \\ + e^{m \cdot log_2(x)} &= 1 - (r-z) + + For float replace :math:`t` in formula :math:numref:`formula_pow_4` with :math:`t = p_l + p_h` with the lowest 12 bits set to all zeroes. + +#. For (exponent of :math:`e^{m \cdot log_2(x)} + n) <= 0`: + + #. Set :math:`z = e^{m \cdot log_2(x)} \cdot 2^n`, using the :ref:`scalbn` function. + #. Return :math:`z` with sign of :math:`s`. + +#. Set :math:`z = e^{m \cdot log_2(x)}` with exponent set to :math:`n`. +#. Return :math:`z` with sign of :math:`sn`. + +.. [#] This means that :math:`y` can only be even, as the exponent is so high that only integral values that are multiples of :math:`2` are possible. +.. [#] In this case the lowest bit of :math:`j` is the lowest bit that is in the integer part of :math:`y`. +.. [#] In this case the lowest :math:`(52 - k)` bits of :math:`y` are :math:`0`, therefore :math:`y` has no fractional part and is integral. +.. [#] This is used to combine the other special cases for :math:`y`, so that they can be skipped altogether instead of one after another which improves the performance of the 'normal' cases. +.. [#] This means that :math:`(1-x) >= 2^{-20}`. +.. [#] This means that :math:`(1-x) <= -2^{-20}`. +.. [#] This shall be the real binary exponent: subnormals have an exponent :math:`< -1022` (float: :math:`< -128`). +.. [#] Set the three highest bytes of :math:`ix` to ``0x3FF0`` (float: ``0x3F80``). +.. [#] This is when (:math:`ix` with exponent masked) :math:`<` ``0x3988E`` (float: :math:`<` ``0x1CC471``). +.. [#] This is when (:math:`ix` with exponent masked) :math:`<` ``0xBB67A`` (float: :math:`<` ``0x5DB3D7``). +.. [#] Which equals :math:`-(1024-log_2(overflow+0.5\ ULP))` (float: :math:`-(128-log_2(overflow+0.5\ ULP))`). + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-0850 +* REQ-ML-0860 +* REQ-ML-0864 +* REQ-ML-0870 +* REQ-ML-0871 +* REQ-ML-0872 +* REQ-ML-0873 +* REQ-ML-0874 +* REQ-ML-0875 +* REQ-ML-0876 +* REQ-ML-0877 +* REQ-ML-0878 +* REQ-ML-0879 +* REQ-ML-0880 +* REQ-ML-0881 +* REQ-ML-0882 +* REQ-ML-0883 +* REQ-ML-0885 +* REQ-ML-0886 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/powd.c +* libm/mathf/powf.c + +References +^^^^^^^^^^ + +* :ref:`cpow` +* :ref:`exp` +* :ref:`exp2` +* :ref:`fabs` +* :ref:`log` +* :ref:`nan` +* :ref:`scalbn` +* :ref:`sqrt` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0540_sqrt.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0540_sqrt.rst new file mode 100644 index 00000000..e7108816 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0540_sqrt.rst @@ -0,0 +1,124 @@ +sqrt +~~~~ + +.. c:autodoc:: mathd/sqrtd.c + +Special cases +^^^^^^^^^^^^^ + ++--------------------------+--------------------------+ +| x | Result | ++==========================+==========================+ +| :math:`<0` | :math:`qNaN` | ++--------------------------+--------------------------+ +| :math:`±0` | :math:`x` | ++--------------------------+--------------------------+ +| :math:`-Inf` | :math:`qNaN` | ++--------------------------+--------------------------+ +| :math:`+Inf` | :math:`+Inf` | ++--------------------------+--------------------------+ +| :math:`NaN` | :math:`qNaN` | ++--------------------------+--------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +The approach is to first work on special values and then use mostly bit-fiddling for the calculation. + +#. For :math:`x` is :math:`NaN`, return :math:`qNaN`. +#. For :math:`x` is positive infinity, return positive infinity. +#. For :math:`x` is negative infinity, return :math:`qNaN`. [#]_ +#. For :math:`x` is a zero, return the zero with the same sign. +#. For :math:`x` is negative, return :math:`qNaN`. +#. Given :math:`x` find :math:`y` and integer :math:`k` such that the formula + + .. math:: + :label: formula_sqrt_1 + + y &= x \cdot 2 ^ {-2k} \\ + \Leftrightarrow \qquad \sqrt{x} &= 2^{k} \cdot \sqrt{y} + + with :math:`y \in [1.0, 4.0)` [#]_ \\ + holds true. [#]_ +#. Compute the square root bit by bit [#]_: + + #. Let :math:`q_i` be :math:`\sqrt{y}` truncated to :math:`i` bit after the binary point (:math:`q_0 = 1`), then + + .. math:: + :label: formula_sqrt_2 + + y_i = 2 ^ {i+1} \cdot (y - q_i^2) + + #. To compute :math:`q_{i+1}` from :math:`q_i`, check whether + + .. math:: + :label: formula_sqrt_3 + + (q_i + 2^{-(i+1)})^2 <= y + + is false, if yes :math:`q_{i+1} = q_i`, else :math:`q_{i+1} = q_i + 2^{-(i+1)}`. + #. With :math:`s_i = 2 q_i` formula :math:numref:`formula_sqrt_3` is equivalent to [#]_ + + .. math:: + :label: formula_sqrt_4 + + s_i + 2^{-(i+1)} <= y_i + + #. With formula :math:numref:`formula_sqrt_4` one can compute :math:`s_i` and :math:`y_i` with the following recurrence formula: + + If formula :math:numref:`formula_sqrt_4` is false: + + .. math:: + :label: formula_sqrt_5 + + s_{i+1} = s_i \wedge y_{i+1} = y_i + + otherwise: + + .. math:: + :label: formula_sqrt_6 + + s_{i+1} = s_i + 2^{-i} \wedge y_{i+1} = y_i - s_i - 2^{-(i+1)} + +#. When done with computing the 53-bit result in the previous step, compute another bit. Use this bit added to the remainder to correctly round the calculated square root. +#. Use formula :math:numref:`formula_sqrt_1` to return :math:`y` to :math:`x`. +#. Return :math:`x`. + +.. [#] The first three steps can be combined by checking that :math:`x` is not finite and returning :math:`x \cdot x + x`, which returns the correct value for all three cases +.. [#] With this trick one can ensure that :math:`\sqrt{y}` truncates to :math:`1`. +.. [#] Take special care with subnormal numbers. +.. [#] As shown in John von Neumann's *First Draft of a Report on the EDVAC* in section 10.1. +.. [#] Since the left hand side of this formula only contains :math:`i+2` bits it is not necessary to do a full (53-bit) comparison. + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-0700 +* REQ-ML-0710 +* REQ-ML-0720 +* REQ-ML-0730 +* REQ-ML-0740 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/sqrtd.c +* libm/mathf/sqrtf.c + +References +^^^^^^^^^^ + +* :ref:`acos` +* :ref:`acosh` +* :ref:`asin` +* :ref:`asinh` +* :ref:`csqrt` +* :ref:`hypot` +* :ref:`j0` +* :ref:`j1` +* :ref:`jn` +* :ref:`pow` +* :ref:`y0` +* :ref:`y1` +* :ref:`yn` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0600_erf.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0600_erf.rst new file mode 100644 index 00000000..0d300628 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0600_erf.rst @@ -0,0 +1,51 @@ +erf +~~~ + +.. c:autodoc:: mathd/erfd.c + +Special cases +^^^^^^^^^^^^^ + ++--------------------------------------+--------------------------------------+ +| x | Result | ++======================================+======================================+ +| :math:`±0` | :math:`x` | ++--------------------------------------+--------------------------------------+ +| :math:`±Inf` | :math:`x` | ++--------------------------------------+--------------------------------------+ +| :math:`\in \mathbb{S}` | :math:`\frac{2}{\sqrt{\pi}} \cdot x` | ++--------------------------------------+--------------------------------------+ +| :math:`NaN` | :math:`qNaN` | ++--------------------------------------+--------------------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +Implement based on a polynomial approximation. + +.. Here there be dragons. (TODO) + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-3600 +* REQ-ML-3610 +* REQ-ML-3620 +* REQ-ML-3630 +* REQ-ML-3640 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/erfd.c +* libm/mathf/erff.c +* libm/mathd/internal/errorfunctiond.h +* libm/mathf/internal/errorfunctionf.h + +References +^^^^^^^^^^ + +* :ref:`erfc` +* :ref:`exp` +* :ref:`fabs` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0610_erfc.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0610_erfc.rst new file mode 100644 index 00000000..e975887c --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0610_erfc.rst @@ -0,0 +1,51 @@ +erfc +~~~~ + +.. c:autodoc:: mathd/erfcd.c + +Special cases +^^^^^^^^^^^^^ + ++--------------------------------------+--------------------------------------+ +| x | Result | ++======================================+======================================+ +| :math:`±0` | :math:`+1` | ++--------------------------------------+--------------------------------------+ +| :math:`-Inf` | :math:`+2` | ++--------------------------------------+--------------------------------------+ +| :math:`+Inf` | :math:`+0` | ++--------------------------------------+--------------------------------------+ +| :math:`NaN` | :math:`qNaN` | ++--------------------------------------+--------------------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +Implement based on a polynomial approximation. + +.. Here there be dragons. (TODO) + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-3700 +* REQ-ML-3710 +* REQ-ML-3720 +* REQ-ML-3730 +* REQ-ML-3740 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/erfcd.c +* libm/mathf/erfcf.c +* libm/mathd/internal/errorfunctiond.h +* libm/mathf/internal/errorfunctionf.h + +References +^^^^^^^^^^ + +* :ref:`erf` +* :ref:`exp` +* :ref:`fabs` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0620_lgamma.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0620_lgamma.rst new file mode 100644 index 00000000..5aecaf6f --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0620_lgamma.rst @@ -0,0 +1,52 @@ +lgamma +~~~~~~ + +.. c:autodoc:: mathd/lgammad.c + +Special cases +^^^^^^^^^^^^^ + ++--------------------------------------+--------------------------------------+ +| x | Result | ++======================================+======================================+ +| :math:`\in \mathbb{Z}_{<0}` | :math:`+Inf` | ++--------------------------------------+--------------------------------------+ +| :math:`±0` | :math:`+Inf` | ++--------------------------------------+--------------------------------------+ +| :math:`+1` | :math:`+0` | ++--------------------------------------+--------------------------------------+ +| :math:`+2` | :math:`+0` | ++--------------------------------------+--------------------------------------+ +| :math:`±Inf` | :math:`+Inf` | ++--------------------------------------+--------------------------------------+ +| :math:`NaN` | :math:`qNaN` | ++--------------------------------------+--------------------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +Call :ref:`__lgamma ` with :math:`x` and a pointer to :ref:`signgam`. + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-3800 +* REQ-ML-3810 +* REQ-ML-3820 +* REQ-ML-3830 +* REQ-ML-3840 +* REQ-ML-3850 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/lgammad.c +* libm/mathf/lgammaf.c + +References +^^^^^^^^^^ + +* :ref:`__lgamma ` +* :ref:`signgam` +* :ref:`tgamma` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0630_tgamma.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0630_tgamma.rst new file mode 100644 index 00000000..b3262c9a --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0630_tgamma.rst @@ -0,0 +1,50 @@ +tgamma +~~~~~~ + +.. c:autodoc:: mathd/tgammad.c + +Special cases +^^^^^^^^^^^^^ + ++--------------------------------------+--------------------------------------+ +| x | Result | ++======================================+======================================+ +| :math:`-Inf` | :math:`qNaN` | ++--------------------------------------+--------------------------------------+ +| :math:`\in \mathbb{Z}_{<0}` | :math:`qNaN` | ++--------------------------------------+--------------------------------------+ +| :math:`±0` | :math:`±Inf` | ++--------------------------------------+--------------------------------------+ +| :math:`+Inf` | :math:`+Inf` | ++--------------------------------------+--------------------------------------+ +| :math:`NaN` | :math:`qNaN` | ++--------------------------------------+--------------------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +Call :ref:`__lgamma ` with :math:`x` and a local pointer to receive the sign. Use the result of :ref:`__lgamma ` as input for :ref:`exp` and use the local pointer with the sign to decide the sign of the result of the :ref:`exp` call. Return the now correctly signed result. + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-5800 +* REQ-ML-5810 +* REQ-ML-5820 +* REQ-ML-5830 +* REQ-ML-5840 +* REQ-ML-5841 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/tgammad.c +* libm/mathf/tgammaf.c + +References +^^^^^^^^^^ + +* :ref:`__lgamma ` +* :ref:`exp` +* :ref:`lgamma` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0640_gamma_internal.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0640_gamma_internal.rst new file mode 100644 index 00000000..003052fc --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0640_gamma_internal.rst @@ -0,0 +1,42 @@ +.. _internal_gamma: + +Internal Gamma Functions +~~~~~~~~~~~~~~~~~~~~~~~~ + +.. c:autodoc:: mathd/internal/gammad.c + +Special cases +^^^^^^^^^^^^^ + +The special cases are in the external functions :ref:`lgamma` and :ref:`tgamma`. + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +``__lgamma``: Implement based on a rational approximation. + +.. Here there be dragons. (TODO) + +``__sin_pi``: Implement based on :ref:`__cos `, and :ref:`__sin `. + +.. Here there be dragons. (TODO) + +Requirements +^^^^^^^^^^^^ + +Internal functions do not directly implement requirements. + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/mathd/internal/gammad.c +* libm/mathd/internal/gammad.h +* libm/mathf/internal/gammaf.c +* libm/mathf/internal/gammaf.h + +References +^^^^^^^^^^ + +* :ref:`__cos, __sin ` +* :ref:`lgamma` +* :ref:`tgamma` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0650_signgam.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0650_signgam.rst new file mode 100644 index 00000000..a4a0086d --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0650_signgam.rst @@ -0,0 +1,25 @@ +signgam +~~~~~~~ + +.. c:autodoc:: common/signgam.c + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +Simply provide a global variable :math:`signgam` by using a macro around an internal variable :math:`\_\_signgam`. + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-3850 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/common/signgam.c + +References +^^^^^^^^^^ + +* :ref:`lgamma` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0700_ceil.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0700_ceil.rst new file mode 100644 index 00000000..2951846b --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0700_ceil.rst @@ -0,0 +1,76 @@ +ceil +~~~~ + +.. c:autodoc:: mathd/ceild.c + +Special cases +^^^^^^^^^^^^^ + ++--------------------------+--------------------------+ +| x | Result | ++==========================+==========================+ +| :math:`±0` | :math:`x` | ++--------------------------+--------------------------+ +| :math:`±Inf` | :math:`x` | ++--------------------------+--------------------------+ +| :math:`NaN` | :math:`NaN` | ++--------------------------+--------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +The approach is to first check whether the input is fractional, then remove the fraction and round in the correct direction. + +#. All the following return values shall have the same sign as the input value. +#. If the exponent is :math:`< 20`, the integral part of :math:`x` is in the double's highword: + + #. If the exponent is :math:`< 0`, there is no integral part: + + #. If the input is :math:`<= 0`, return a zero. + #. Return :math:`1`. + + #. If :math:`x` is integral, return :math:`x`. + #. Return :math:`x` rounded towards positive infinity. + +#. If the exponent is :math:`> 51`, there is no fractional part: + + #. If the exponent is :math:`= 1024`, :math:`x` is :math:`NaN` or infinite, return :math:`x+x`. + #. Return :math:`x`. + +#. If :math:`x` is integral, return :math:`x`. +#. Return :math:`x` rounded towards positive infinity. + +For the float version the approach can be shortened: + +#. All the following return values shall have the same sign as the input value. +#. If the exponent is :math:`< 23`, there may be a fractional part: + + #. If the exponent is :math:`< 0`, there is no integral part: + + #. If the input is :math:`<= 0`, return a zero. + #. Return :math:`1`. + + #. If :math:`x` is integral, return :math:`x`. + #. Return :math:`x` rounded towards positive infinity. + +#. If the input is not finite, return :math:`x+x`. +#. Return :math:`x`. + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-1080 +* REQ-ML-1091 +* REQ-ML-1092 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/ceild.c +* libm/mathf/ceilf.c + +References +^^^^^^^^^^ + +* :ref:`floor` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0710_floor.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0710_floor.rst new file mode 100644 index 00000000..20dd779b --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0710_floor.rst @@ -0,0 +1,76 @@ +floor +~~~~~ + +.. c:autodoc:: mathd/floord.c + +Special cases +^^^^^^^^^^^^^ + ++--------------------------+--------------------------+ +| x | Result | ++==========================+==========================+ +| :math:`±0` | :math:`x` | ++--------------------------+--------------------------+ +| :math:`±Inf` | :math:`x` | ++--------------------------+--------------------------+ +| :math:`NaN` | :math:`NaN` | ++--------------------------+--------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +The approach is to first check whether the input is fractional, then remove the fraction and round in the correct direction. + +#. All the following return values shall have the same sign as the input value. +#. If the exponent is :math:`< 20`, the integral part of :math:`x` is in the double's highword: + + #. If the exponent is :math:`< 0`, there is no integral part: + + #. If the input is :math:`>= 0`, return a zero. + #. Return :math:`-1`. + + #. If :math:`x` is integral, return :math:`x`. + #. Return :math:`x` rounded towards negative infinity. + +#. If the exponent is :math:`> 51`, there is no fractional part: + + #. If the exponent is :math:`= 1024`, :math:`x` is :math:`NaN` or infinite, return :math:`x+x`. + #. Return :math:`x`. + +#. If :math:`x` is integral, return :math:`x`. +#. Return :math:`x` rounded towards negative infinity. + +For the float version the approach can be shortened: + +#. All the following return values shall have the same sign as the input value. +#. If the exponent is :math:`< 23`, there may be a fractional part: + + #. If the exponent is :math:`< 0`, there is no integral part: + + #. If the input is :math:`>= 0`, return a zero. + #. Return :math:`-1`. + + #. If :math:`x` is integral, return :math:`x`. + #. Return :math:`x` rounded towards negative infinity. + +#. If the input is not finite, return :math:`x+x`. +#. Return :math:`x`. + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-1040 +* REQ-ML-1051 +* REQ-ML-1052 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/floord.c +* libm/mathf/floorf.c + +References +^^^^^^^^^^ + +* :ref:`ceil` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0720_nearbyint.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0720_nearbyint.rst new file mode 100644 index 00000000..17fefc39 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0720_nearbyint.rst @@ -0,0 +1,43 @@ +nearbyint +~~~~~~~~~ + +.. c:autodoc:: mathd/nearbyintd.c + +Special cases +^^^^^^^^^^^^^ + ++--------------------------+--------------------------+ +| x | Result | ++==========================+==========================+ +| :math:`±0` | :math:`x` | ++--------------------------+--------------------------+ +| :math:`±Inf` | :math:`x` | ++--------------------------+--------------------------+ +| :math:`NaN` | :math:`NaN` | ++--------------------------+--------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +Call :ref:`rint`. + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-4500 +* REQ-ML-4510 +* REQ-ML-4520 +* REQ-ML-4540 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/nearbyintd.c +* libm/mathf/nearbyintf.c + +References +^^^^^^^^^^ + +* :ref:`rint` +* :ref:`round` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0730_rint.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0730_rint.rst new file mode 100644 index 00000000..8a662176 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0730_rint.rst @@ -0,0 +1,45 @@ +rint +~~~~ + +.. c:autodoc:: mathd/rintd.c + +Special cases +^^^^^^^^^^^^^ + ++--------------------------+--------------------------+ +| x | Result | ++==========================+==========================+ +| :math:`±0` | :math:`x` | ++--------------------------+--------------------------+ +| :math:`±Inf` | :math:`x` | ++--------------------------+--------------------------+ +| :math:`NaN` | :math:`NaN` | ++--------------------------+--------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +Implement based on bit-fiddling. + +.. Here there be dragons. (TODO) + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-4600 +* REQ-ML-4610 +* REQ-ML-4620 +* REQ-ML-4640 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/rintd.c +* libm/mathf/rintf.c + +References +^^^^^^^^^^ + +* :ref:`nearbyint` +* :ref:`round` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0740_lrint.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0740_lrint.rst new file mode 100644 index 00000000..6cd2a35f --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0740_lrint.rst @@ -0,0 +1,51 @@ +lrint +~~~~~ + +.. c:autodoc:: mathd/lrintd.c + +Special cases +^^^^^^^^^^^^^ + ++------------------------------------+------------------------------------+ +| x | Result | ++====================================+====================================+ +| :math:`±0` | :math:`0` | ++------------------------------------+------------------------------------+ +| :math:`-Inf` | min :math:`\mathbb{I}_l` | ++------------------------------------+------------------------------------+ +| :math:`<` min :math:`\mathbb{I}_l` | min :math:`\mathbb{I}_l` | ++------------------------------------+------------------------------------+ +| :math:`>` max :math:`\mathbb{I}_l` | max :math:`\mathbb{I}_l` | ++------------------------------------+------------------------------------+ +| :math:`+Inf` | max :math:`\mathbb{I}_l` | ++------------------------------------+------------------------------------+ +| :math:`NaN` | :math:`lrint(±Inf)` | ++------------------------------------+------------------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +Implement based on bit-fiddling. + +.. Here there be dragons. (TODO) + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-4650 +* REQ-ML-4653 +* REQ-ML-4656 +* REQ-ML-4659 +* REQ-ML-4662 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/lrintd.c +* libm/mathf/lrintff.c + +References +^^^^^^^^^^ + +* :ref:`rint` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0750_llrint.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0750_llrint.rst new file mode 100644 index 00000000..8710906e --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0750_llrint.rst @@ -0,0 +1,47 @@ +llrint +~~~~~~ + +.. c:autodoc:: mathd/llrintd.c + +Special cases +^^^^^^^^^^^^^ + ++---------------------------------------+---------------------------------------+ +| x | Result | ++=======================================+=======================================+ +| :math:`±0` | :math:`0` | ++---------------------------------------+---------------------------------------+ +| :math:`-Inf` | min :math:`\mathbb{I}_{ll}` | ++---------------------------------------+---------------------------------------+ +| :math:`<` min :math:`\mathbb{I}_{ll}` | min :math:`\mathbb{I}_{ll}` | ++---------------------------------------+---------------------------------------+ +| :math:`>` max :math:`\mathbb{I}_{ll}` | max :math:`\mathbb{I}_{ll}` | ++---------------------------------------+---------------------------------------+ +| :math:`+Inf` | max :math:`\mathbb{I}_{ll}` | ++---------------------------------------+---------------------------------------+ +| :math:`NaN` | :math:`llrint(±Inf)` | ++---------------------------------------+---------------------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +Implement based on bit-fiddling. + +.. Here there be dragons. (TODO) + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-4670 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/llrintd.c +* libm/mathf/llrintf.c + +References +^^^^^^^^^^ + +* :ref:`lrint` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0760_round.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0760_round.rst new file mode 100644 index 00000000..a20dcac9 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0760_round.rst @@ -0,0 +1,77 @@ +round +~~~~~ + +.. c:autodoc:: mathd/roundd.c + +Special cases +^^^^^^^^^^^^^ + ++--------------------------+--------------------------+ +| x | Result | ++==========================+==========================+ +| :math:`±0` | :math:`x` | ++--------------------------+--------------------------+ +| :math:`±Inf` | :math:`x` | ++--------------------------+--------------------------+ +| :math:`NaN` | :math:`NaN` | ++--------------------------+--------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +The approach is to first check whether the input is fractional, then remove the fraction and round in the correct direction. + +#. All the following return values shall have the same sign as the input value. +#. If the exponent is :math:`< 20`, the integral part of :math:`x` is in the double's highword: + + #. If the exponent is :math:`< 0`, there is no integral part: + + #. If the exponent is :math:`-1`, return a zero. + #. Return a one. + + #. If the input is integral, return :math:`x`. + #. Return :math:`x` rounded to the nearest integer, with halfway cases rounded away from zero, regardless of the current rounding direction. + +#. If the exponent is :math:`> 51`, there is no fractional part: + + #. If the exponent is :math:`= 1024`, :math:`x` is :math:`NaN` or infinite, return :math:`x+x`. + #. Return :math:`x`. + +#. If the input is integral, return :math:`x`. +#. Return :math:`x` rounded to the nearest integer, with halfway cases rounded away from zero, regardless of the current rounding direction. + +For the float version the approach can be shortened: + +#. All the following return values shall have the same sign as the input value. +#. If the exponent is :math:`< 23`, there may be a fractional part: + + #. If the exponent is :math:`< 0`, there is no integral part: + + #. If the exponent is :math:`-1`, return a zero. + #. Return a one. + + #. If the input is integral, return :math:`x`. + #. Return :math:`x` rounded to the nearest integer, with halfway cases rounded away from zero, regardless of the current rounding direction. + +#. If the exponent is :math:`= 128`, :math:`x` is :math:`NaN` or infinite, return :math:`x+x`. +#. Return :math:`x`. + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-1020 +* REQ-ML-1031 +* REQ-ML-1032 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/roundd.c +* libm/mathf/roundf.c + +References +^^^^^^^^^^ + +* :ref:`nearbyint` +* :ref:`rint` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0770_lround.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0770_lround.rst new file mode 100644 index 00000000..3a0b3a02 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0770_lround.rst @@ -0,0 +1,51 @@ +lround +~~~~~~ + +.. c:autodoc:: mathd/lroundd.c + +Special cases +^^^^^^^^^^^^^ + ++------------------------------------+------------------------------------+ +| x | Result | ++====================================+====================================+ +| :math:`±0` | :math:`0` | ++------------------------------------+------------------------------------+ +| :math:`-Inf` | min :math:`\mathbb{I}_l` | ++------------------------------------+------------------------------------+ +| :math:`<` min :math:`\mathbb{I}_l` | min :math:`\mathbb{I}_l` | ++------------------------------------+------------------------------------+ +| :math:`>` max :math:`\mathbb{I}_l` | max :math:`\mathbb{I}_l` | ++------------------------------------+------------------------------------+ +| :math:`+Inf` | max :math:`\mathbb{I}_l` | ++------------------------------------+------------------------------------+ +| :math:`NaN` | :math:`lround(±Inf)` | ++------------------------------------+------------------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +Implement based on bit-fiddling. + +.. Here there be dragons. (TODO) + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-8300 +* REQ-ML-8310 +* REQ-ML-8320 +* REQ-ML-8330 +* REQ-ML-8340 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/lroundd.c +* libm/mathf/lroundf.c + +References +^^^^^^^^^^ + +* :ref:`round` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0780_llround.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0780_llround.rst new file mode 100644 index 00000000..6f440590 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0780_llround.rst @@ -0,0 +1,47 @@ +llround +~~~~~~~ + +.. c:autodoc:: mathd/llroundd.c + +Special cases +^^^^^^^^^^^^^ + ++---------------------------------------+---------------------------------------+ +| x | Result | ++=======================================+=======================================+ +| :math:`±0` | :math:`0` | ++---------------------------------------+---------------------------------------+ +| :math:`-Inf` | min :math:`\mathbb{I}_{ll}` | ++---------------------------------------+---------------------------------------+ +| :math:`<` min :math:`\mathbb{I}_{ll}` | min :math:`\mathbb{I}_{ll}` | ++---------------------------------------+---------------------------------------+ +| :math:`>` max :math:`\mathbb{I}_{ll}` | max :math:`\mathbb{I}_{ll}` | ++---------------------------------------+---------------------------------------+ +| :math:`+Inf` | max :math:`\mathbb{I}_{ll}` | ++---------------------------------------+---------------------------------------+ +| :math:`NaN` | :math:`llround(±Inf)` | ++---------------------------------------+---------------------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +Implement based on bit-fiddling. + +.. Here there be dragons. (TODO) + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-8400 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/llroundd.c +* libm/mathf/llroundf.c + +References +^^^^^^^^^^ + +* :ref:`lround` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0790_trunc.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0790_trunc.rst new file mode 100644 index 00000000..d56a8b6b --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0790_trunc.rst @@ -0,0 +1,65 @@ +trunc +~~~~~ + +.. c:autodoc:: mathd/truncd.c + +Special cases +^^^^^^^^^^^^^ + ++--------------------------+--------------------------+ +| x | Result | ++==========================+==========================+ +| :math:`±0` | :math:`x` | ++--------------------------+--------------------------+ +| :math:`±Inf` | :math:`x` | ++--------------------------+--------------------------+ +| :math:`NaN` | :math:`NaN` | ++--------------------------+--------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +The approach is to first check whether the input is fractional, then remove the fraction and round in the correct direction. + +#. All the following return values shall have the same sign as the input value. +#. If the exponent is :math:`< 20`, the integral part of :math:`x` is in the double's highword: + + #. If the exponent is :math:`< 0`, there is no integral part, return a zero. + #. Return :math:`x` rounded to the nearest integer no greater in magnitude than :math:`x`. + +#. If the exponent is :math:`> 51`, there is no fractional part: + + #. If the exponent is :math:`= 1024`, :math:`x` is :math:`NaN` or infinite, return :math:`x+x`. + #. Return :math:`x`. + +#. Return :math:`x` rounded to the nearest integer no greater in magnitude than :math:`x`. + +For the float version the approach can be shortened: + +#. All the following return values shall have the same sign as the input value. +#. If the exponent is :math:`< 23`, there may be a fractional part: + + #. If the exponent is :math:`< 0`, there is no integral part, return a zero. + #. Return :math:`x` rounded to the nearest integer no greater in magnitude than :math:`x`. + +#. If the exponent is :math:`= 128`, :math:`x` is :math:`NaN` or infinite, return :math:`x+x`. +#. Return :math:`x`. + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-1060 +* REQ-ML-1070 +* REQ-ML-1071 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/truncd.c +* libm/mathf/truncf.c + +References +^^^^^^^^^^ + +* :ref:`round` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0900_fmod.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0900_fmod.rst new file mode 100644 index 00000000..fcd41b48 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0900_fmod.rst @@ -0,0 +1,66 @@ +fmod +~~~~ + +.. c:autodoc:: mathd/fmodd.c + +Special cases +^^^^^^^^^^^^^ + ++-----------------------------+-----------------------------+-----------------------------+ +| x | y | Result | ++=============================+=============================+=============================+ +| :math:`\in \mathbb{F}` | :math:`±0` | :math:`qNaN` | ++-----------------------------+-----------------------------+-----------------------------+ +| :math:`±Inf` | :math:`\in \mathbb{F}` | :math:`qNaN` | ++-----------------------------+-----------------------------+-----------------------------+ +| :math:`±0` | :math:`\neq ±0` | :math:`x` | ++-----------------------------+-----------------------------+-----------------------------+ +| :math:`\neq ±Inf` | :math:`±Inf` | :math:`x` | ++-----------------------------+-----------------------------+-----------------------------+ +| :math:`NaN` | :math:`\in \mathbb{F}` | :math:`qNaN` | ++-----------------------------+-----------------------------+-----------------------------+ +| :math:`\in \mathbb{F}` | :math:`NaN` | :math:`qNaN` | ++-----------------------------+-----------------------------+-----------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +The approach is to first work on special values and overflows, then use :ref:`sqrt` for the calculation. + +#. All return values mentioned hereafter shall have the same sign as :math:`x` at this point. +#. If :math:`x` is not finite, or :math:`y` is :math:`NaN` or zero, return :math:`NaN`. +#. If :math:`|x| < |y|`, return :math:`x`. +#. If :math:`|x|` equals :math:`|y|`, return a zero. +#. Remove the sign bits from :math:`x` and :math:`y`. +#. Extract the binary exponents of :math:`x` and :math:`y` into :math:`ix` and :math:`iy` respectively.\footnote{Take care with subnormals.} +#. Normalize :math:`x` and :math:`y` by replacing their exponent with :math:`1`.\footnote{Subnormal :math:`x` or :math:`y` instead need to be shifted left until the exponent is :math:`1`.} +#. Loop for :math:`ix - iy` steps, add an additional step if :math:`x` is :math:`> y` at the end: + + #. Set :math:`x` to :math:`x - y`. + #. If :math:`x` is :math:`0`, return a zero. + +#. If the exponent of :math:`x` is :math:`< 1`, normalize :math:`x` by shifting left until the exponent is :math:`1`. While doing so decrease :math:`iy` once for every necessary shifting step. +#. Set :math:`iy` as the new exponent of :math:`x`.\footnote{If :math:`iy` is :math:`<= -1023` (this means the result is subnormal), :math:`x` needs to be shifted right while increasing :math:`iy` for every step until :math:`iy` is :math:`-1022`.} +#. Return :math:`x`. + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-1100 +* REQ-ML-1120 +* REQ-ML-1121 +* REQ-ML-1122 +* REQ-ML-1130 +* REQ-ML-1131 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/fmodd.c +* libm/mathf/fmodf.c + +References +^^^^^^^^^^ + +* :ref:`remainder` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0910_remainder.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0910_remainder.rst new file mode 100644 index 00000000..fd9e3d05 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0910_remainder.rst @@ -0,0 +1,46 @@ +remainder +~~~~~~~~~ + +.. c:autodoc:: mathd/remainderd.c + +Special cases +^^^^^^^^^^^^^ + ++-----------------------------+-----------------------------+-----------------------------+ +| x | y | Result | ++=============================+=============================+=============================+ +| :math:`\in \mathbb{F}` | :math:`±0` | :math:`qNaN` | ++-----------------------------+-----------------------------+-----------------------------+ +| :math:`±Inf` | :math:`\in \mathbb{F}` | :math:`qNaN` | ++-----------------------------+-----------------------------+-----------------------------+ +| :math:`NaN` | :math:`\in \mathbb{F}` | :math:`qNaN` | ++-----------------------------+-----------------------------+-----------------------------+ +| :math:`\in \mathbb{F}` | :math:`NaN` | :math:`qNaN` | ++-----------------------------+-----------------------------+-----------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +Implement based on :ref:`fmod`. + +.. Here there be dragons. (TODO) + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-3900 +* REQ-ML-3910 +* REQ-ML-3920 +* REQ-ML-3940 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/remainderd.c +* libm/mathf/remainderf.c + +References +^^^^^^^^^^ + +* :ref:`fmod` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0920_remquo.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0920_remquo.rst new file mode 100644 index 00000000..da17de0b --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0920_remquo.rst @@ -0,0 +1,47 @@ +remquo +~~~~~~ + +.. c:autodoc:: mathd/remquod.c + +Special cases +^^^^^^^^^^^^^ + ++-----------------------------+-----------------------------+-----------------------------+-----------------------------+ +| x | y | Result | :math:`*quo` | ++=============================+=============================+=============================+=============================+ +| :math:`\in \mathbb{F}` | :math:`±0` | :math:`qNaN` | :math:`0` | ++-----------------------------+-----------------------------+-----------------------------+-----------------------------+ +| :math:`±Inf` | :math:`\in \mathbb{F}` | :math:`qNaN` | :math:`0` | ++-----------------------------+-----------------------------+-----------------------------+-----------------------------+ +| :math:`NaN` | :math:`\in \mathbb{F}` | :math:`qNaN` | :math:`0` | ++-----------------------------+-----------------------------+-----------------------------+-----------------------------+ +| :math:`\in \mathbb{F}` | :math:`NaN` | :math:`qNaN` | :math:`0` | ++-----------------------------+-----------------------------+-----------------------------+-----------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +Implement similarly to :ref:`remainder`, and calculate the quotient while at it. + +.. Here there be dragons. (TODO) + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-5600 +* REQ-ML-5601 +* REQ-ML-5620 +* REQ-ML-5620 +* REQ-ML-5640 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/remquod.c +* libm/mathf/remquof.c + +References +^^^^^^^^^^ + +* :ref:`remainder` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1000_copysign.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1000_copysign.rst new file mode 100644 index 00000000..de251142 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1000_copysign.rst @@ -0,0 +1,36 @@ +copysign +~~~~~~~~ + +.. c:autodoc:: mathd/copysignd.c + +Special cases +^^^^^^^^^^^^^ + ++-----------------------------+-----------------------------+-----------------------------+ +| x | y | Result | ++=============================+=============================+=============================+ +| :math:`NaN` | :math:`\in \mathbb{F}` | :math:`qNaN` | ++-----------------------------+-----------------------------+-----------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +Return the value with the magnitude of :math:`x` and sign of :math:`y`. + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-1380 +* REQ-ML-1381 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/copysignd.c +* libm/mathf/copysignf.c + +References +^^^^^^^^^^ + +* :ref:`cproj` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1010_nan.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1010_nan.rst new file mode 100644 index 00000000..70348ecb --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1010_nan.rst @@ -0,0 +1,26 @@ +nan +~~~ + +.. c:autodoc:: mathd/nand.c + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +The approach is to return ``0x7FF80000000D067D`` as ``double`` (float: ``0x7FCF067D``). This is a quiet ``NaN`` with the fixed payload ``D067D`` (float: ``F067D``). + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-4400 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/nand.c +* libm/mathf/nanf.c + +References +^^^^^^^^^^ + +* NAN in :numref:`Tbl. %s ` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1020_nextafter.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1020_nextafter.rst new file mode 100644 index 00000000..acc7135b --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1020_nextafter.rst @@ -0,0 +1,56 @@ +nextafter +~~~~~~~~~ + +.. c:autodoc:: mathd/nextafterd.c + +Special cases +^^^^^^^^^^^^^ + ++-----------------------------+-----------------------------+--------------------------------------------------------------------+ +| x | y | Result | ++=============================+=============================+====================================================================+ +| :math:`Any` | :math:`x` | :math:`y` | ++-----------------------------+-----------------------------+--------------------------------------------------------------------+ +| :math:`-Inf` | :math:`>-Inf` | min :math:`(\mathbb{F} \setminus \left \{ \pm Inf, NaN \right \})` | ++-----------------------------+-----------------------------+--------------------------------------------------------------------+ +| :math:`±0` | :math:`<0` | max :math:`\mathbb{S}^{-}` | ++-----------------------------+-----------------------------+--------------------------------------------------------------------+ +| :math:`±0` | :math:`±0` | :math:`y` | ++-----------------------------+-----------------------------+--------------------------------------------------------------------+ +| :math:`±0` | :math:`>0` | min :math:`\mathbb{S}^{+}` | ++-----------------------------+-----------------------------+--------------------------------------------------------------------+ +| :math:`+Inf` | :math:`<+Inf` | max :math:`(\mathbb{F} \setminus \left \{ \pm Inf, NaN \right \})` | ++-----------------------------+-----------------------------+--------------------------------------------------------------------+ +| :math:`NaN` | :math:`\in \mathbb{F}` | :math:`qNaN` | ++-----------------------------+-----------------------------+--------------------------------------------------------------------+ +| :math:`\in \mathbb{F}` | :math:`NaN` | :math:`qNaN` | ++-----------------------------+-----------------------------+--------------------------------------------------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +Implement based on bit-fiddling. + +.. Here there be dragons. (TODO) + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-4700 +* REQ-ML-4710 +* REQ-ML-4720 +* REQ-ML-4731 +* REQ-ML-4740 +* REQ-ML-4741 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/nextafterd.c +* libm/mathf/nextafterf.c + +References +^^^^^^^^^^ + +* :ref:`nexttoward` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1030_nexttoward.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1030_nexttoward.rst new file mode 100644 index 00000000..7444fc0f --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1030_nexttoward.rst @@ -0,0 +1,51 @@ +nexttoward +~~~~~~~~~~ + +.. c:autodoc:: mathd/nexttowardd.c + +Special cases +^^^^^^^^^^^^^ + ++-----------------------------+-----------------------------+--------------------------------------------------------------------+ +| x | y | Result | ++=============================+=============================+====================================================================+ +| :math:`Any` | :math:`x` | :math:`y` | ++-----------------------------+-----------------------------+--------------------------------------------------------------------+ +| :math:`-Inf` | :math:`>-Inf` | min :math:`(\mathbb{F} \setminus \left \{ \pm Inf, NaN \right \})` | ++-----------------------------+-----------------------------+--------------------------------------------------------------------+ +| :math:`±0` | :math:`<0` | max :math:`\mathbb{S}^{-}` | ++-----------------------------+-----------------------------+--------------------------------------------------------------------+ +| :math:`±0` | :math:`±0` | :math:`y` | ++-----------------------------+-----------------------------+--------------------------------------------------------------------+ +| :math:`±0` | :math:`>0` | min :math:`\mathbb{S}^{+}` | ++-----------------------------+-----------------------------+--------------------------------------------------------------------+ +| :math:`+Inf` | :math:`<+Inf` | max :math:`(\mathbb{F} \setminus \left \{ \pm Inf, NaN \right \})` | ++-----------------------------+-----------------------------+--------------------------------------------------------------------+ +| :math:`NaN` | :math:`\in \mathbb{F}` | :math:`qNaN` | ++-----------------------------+-----------------------------+--------------------------------------------------------------------+ +| :math:`\in \mathbb{F}` | :math:`NaN` | :math:`qNaN` | ++-----------------------------+-----------------------------+--------------------------------------------------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +The approach is to call :ref:`nextafter`. + +Float: Implement based on bit-fiddling. + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-4750 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/nexttowardd.c +* libm/mathf/nexttowardf.c + +References +^^^^^^^^^^ + +* :ref:`nextafter` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1100_fdim.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1100_fdim.rst new file mode 100644 index 00000000..cde43b02 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1100_fdim.rst @@ -0,0 +1,49 @@ +fdim +~~~~ + +.. c:autodoc:: mathd/fdimd.c + +Special cases +^^^^^^^^^^^^^ + ++-----------------------------+-----------------------------+-----------------------------+ +| x | y | Result | ++=============================+=============================+=============================+ +| :math:`-Inf` | :math:`±Inf` | :math:`+0` | ++-----------------------------+-----------------------------+-----------------------------+ +| :math:`±0` | :math:`<0` | :math:`x` | ++-----------------------------+-----------------------------+-----------------------------+ +| :math:`±0` | :math:`>=±0` | :math:`+0` | ++-----------------------------+-----------------------------+-----------------------------+ +| :math:`+Inf` | :math:`-Inf` | :math:`+Inf` | ++-----------------------------+-----------------------------+-----------------------------+ +| :math:`+Inf` | :math:`+Inf` | :math:`+0` | ++-----------------------------+-----------------------------+-----------------------------+ +| :math:`NaN` | :math:`\in \mathbb{F}` | :math:`qNaN` | ++-----------------------------+-----------------------------+-----------------------------+ +| :math:`\in \mathbb{F}` | :math:`NaN` | :math:`qNaN` | ++-----------------------------+-----------------------------+-----------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +If :math:`x` is greater than :math:`y` return :math:`x - y`, otherwise return :math:`0`. + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-2600 +* REQ-ML-2610 +* REQ-ML-2620 +* REQ-ML-2630 +* REQ-ML-2640 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/fdimd.c +* libm/mathf/fdimf.c + +References +^^^^^^^^^^ diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1110_fmax.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1110_fmax.rst new file mode 100644 index 00000000..8cb72382 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1110_fmax.rst @@ -0,0 +1,51 @@ +fmax +~~~~ + +.. c:autodoc:: mathd/fmaxd.c + +Special cases +^^^^^^^^^^^^^ + ++-----------------------------+-----------------------------+-----------------------------+ +| x | y | Result | ++=============================+=============================+=============================+ +| :math:`±0` | :math:`±0` | :math:`y` | ++-----------------------------+-----------------------------+-----------------------------+ +| :math:`NaN` | :math:`\neq NaN` | :math:`y` | ++-----------------------------+-----------------------------+-----------------------------+ +| :math:`\neq NaN` | :math:`NaN` | :math:`x` | ++-----------------------------+-----------------------------+-----------------------------+ +| :math:`sNaN` | :math:`Any` | :math:`qNaN` | ++-----------------------------+-----------------------------+-----------------------------+ +| :math:`Any` | :math:`sNaN` | :math:`qNaN` | ++-----------------------------+-----------------------------+-----------------------------+ +| :math:`NaN` | :math:`NaN` | :math:`qNaN` | ++-----------------------------+-----------------------------+-----------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +The approach is to first check the arguments for any :math:`NaN` values and then compare the inputs to return the maximum: + +#. Return :math:`NaN` if both input values are :math:`NaN`. +#. Return the remaining value if one of the input values is :math:`NaN`. +#. If :math:`x > y` return :math:`x`, else return :math:`y`. + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-1240 +* REQ-ML-1250 +* REQ-ML-1252 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/fmaxd.c +* libm/mathf/fmaxf.c + +References +^^^^^^^^^^ + +* :ref:`fmin` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1120_fmin.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1120_fmin.rst new file mode 100644 index 00000000..e287a465 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1120_fmin.rst @@ -0,0 +1,51 @@ +fmin +~~~~ + +.. c:autodoc:: mathd/fmind.c + +Special cases +^^^^^^^^^^^^^ + ++-----------------------------+-----------------------------+-----------------------------+ +| x | y | Result | ++=============================+=============================+=============================+ +| :math:`±0` | :math:`±0` | :math:`y` | ++-----------------------------+-----------------------------+-----------------------------+ +| :math:`NaN` | :math:`\neq NaN` | :math:`y` | ++-----------------------------+-----------------------------+-----------------------------+ +| :math:`\neq NaN` | :math:`NaN` | :math:`x` | ++-----------------------------+-----------------------------+-----------------------------+ +| :math:`sNaN` | :math:`Any` | :math:`qNaN` | ++-----------------------------+-----------------------------+-----------------------------+ +| :math:`Any` | :math:`sNaN` | :math:`qNaN` | ++-----------------------------+-----------------------------+-----------------------------+ +| :math:`NaN` | :math:`NaN` | :math:`qNaN` | ++-----------------------------+-----------------------------+-----------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +The approach is to first check the arguments for any :math:`NaN` values and then compare the inputs to return the minimum: + +#. Return :math:`NaN` if both input values are :math:`NaN`. +#. Return the remaining value if one of the input values is :math:`NaN`. +#. If :math:`x < y` return :math:`x`, else return :math:`y`. + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-1220 +* REQ-ML-1230 +* REQ-ML-1232 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/fmind.c +* libm/mathf/fminf.c + +References +^^^^^^^^^^ + +* :ref:`fmax` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1200_fma.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1200_fma.rst new file mode 100644 index 00000000..87986ef6 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1200_fma.rst @@ -0,0 +1,48 @@ +fma +~~~~ + +.. c:autodoc:: mathd/fmad.c + +Special cases +^^^^^^^^^^^^^ + ++-----------------------------+-----------------------------+-----------------------------+-----------------------------+ +| x | y | z | Result | ++=============================+=============================+=============================+=============================+ +| :math:`±0` | :math:`±Inf` | :math:`\in \mathbb{F}` | :math:`qNaN` | ++-----------------------------+-----------------------------+-----------------------------+-----------------------------+ +| :math:`±Inf` | :math:`±0` | :math:`\in \mathbb{F}` | :math:`qNaN` | ++-----------------------------+-----------------------------+-----------------------------+-----------------------------+ +| :math:`x \cdot y = -Inf` | :math:`+Inf` | :math:`qNaN` | ++-----------------------------+-----------------------------+-----------------------------+-----------------------------+ +| :math:`x \cdot y = +Inf` | :math:`-Inf` | :math:`qNaN` | ++-----------------------------+-----------------------------+-----------------------------+-----------------------------+ +| :math:`NaN` | :math:`\in \mathbb{F}` | :math:`\in \mathbb{F}` | :math:`qNaN` | ++-----------------------------+-----------------------------+-----------------------------+-----------------------------+ +| :math:`\in \mathbb{F}` | :math:`NaN` | :math:`\in \mathbb{F}` | :math:`qNaN` | ++-----------------------------+-----------------------------+-----------------------------+-----------------------------+ +| :math:`\in \mathbb{F}` | :math:`\in \mathbb{F}` | :math:`NaN` | :math:`qNaN` | ++-----------------------------+-----------------------------+-----------------------------+-----------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +The approach is to naively implement :math:`x \cdot y + z`. + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-2700 +* REQ-ML-2500 +* REQ-ML-2510 +* REQ-ML-2520 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/fmad.c +* libm/mathf/fmaf.c + +References +^^^^^^^^^^ diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1300_isgreater.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1300_isgreater.rst new file mode 100644 index 00000000..617421b2 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1300_isgreater.rst @@ -0,0 +1,38 @@ +isgreater +~~~~~~~~~ + +.. c:autodoc:: common/isgreater.c + +Special cases +^^^^^^^^^^^^^ + ++-----------------------------+-----------------------------+-----------------------------+ +| x | y | Result | ++=============================+=============================+=============================+ +| :math:`NaN` | :math:`\in \mathbb{F}` | :math:`0` | ++-----------------------------+-----------------------------+-----------------------------+ +| :math:`\in \mathbb{F}` | :math:`NaN` | :math:`0` | ++-----------------------------+-----------------------------+-----------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +#. Use :ref:`isunordered` to return :math:`0` if either input is :math:`NaN`. +#. If :math:`x > y`, return :math:`1`, otherwise return :math:`0`. + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-5000 +* REQ-ML-5010 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/common/isgreater.c + +References +^^^^^^^^^^ + +* :ref:`isunordered` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1310_isgreaterequal.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1310_isgreaterequal.rst new file mode 100644 index 00000000..b66130b1 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1310_isgreaterequal.rst @@ -0,0 +1,38 @@ +isgreaterequal +~~~~~~~~~~~~~~ + +.. c:autodoc:: common/isgreaterequal.c + +Special cases +^^^^^^^^^^^^^ + ++-----------------------------+-----------------------------+-----------------------------+ +| x | y | Result | ++=============================+=============================+=============================+ +| :math:`NaN` | :math:`\in \mathbb{F}` | :math:`0` | ++-----------------------------+-----------------------------+-----------------------------+ +| :math:`\in \mathbb{F}` | :math:`NaN` | :math:`0` | ++-----------------------------+-----------------------------+-----------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +#. Use :ref:`isunordered` to return :math:`0` if either input is :math:`NaN`. +#. If :math:`x >= y`, return :math:`1`, otherwise return :math:`0`. + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-5100 +* REQ-ML-5110 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/common/isgreaterequal.c + +References +^^^^^^^^^^ + +* :ref:`isunordered` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1320_isless.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1320_isless.rst new file mode 100644 index 00000000..3b17cfd6 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1320_isless.rst @@ -0,0 +1,38 @@ +isless +~~~~~~ + +.. c:autodoc:: common/isless.c + +Special cases +^^^^^^^^^^^^^ + ++-----------------------------+-----------------------------+-----------------------------+ +| x | y | Result | ++=============================+=============================+=============================+ +| :math:`NaN` | :math:`\in \mathbb{F}` | :math:`0` | ++-----------------------------+-----------------------------+-----------------------------+ +| :math:`\in \mathbb{F}` | :math:`NaN` | :math:`0` | ++-----------------------------+-----------------------------+-----------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +#. Use :ref:`isunordered` to return :math:`0` if either input is :math:`NaN`. +#. If :math:`x < y`, return :math:`1`, otherwise return :math:`0`. + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-5200 +* REQ-ML-5210 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/common/isless.c + +References +^^^^^^^^^^ + +* :ref:`isunordered` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1330_islessequal.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1330_islessequal.rst new file mode 100644 index 00000000..ffe9ef99 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1330_islessequal.rst @@ -0,0 +1,38 @@ +islessequal +~~~~~~~~~~~ + +.. c:autodoc:: common/islessequal.c + +Special cases +^^^^^^^^^^^^^ + ++-----------------------------+-----------------------------+-----------------------------+ +| x | y | Result | ++=============================+=============================+=============================+ +| :math:`NaN` | :math:`\in \mathbb{F}` | :math:`0` | ++-----------------------------+-----------------------------+-----------------------------+ +| :math:`\in \mathbb{F}` | :math:`NaN` | :math:`0` | ++-----------------------------+-----------------------------+-----------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +#. Use :ref:`isunordered` to return :math:`0` if either input is :math:`NaN`. +#. If :math:`x <= y`, return :math:`1`, otherwise return :math:`0`. + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-5300 +* REQ-ML-5310 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/common/islessequal.c + +References +^^^^^^^^^^ + +* :ref:`isunordered` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1340_islessgreater.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1340_islessgreater.rst new file mode 100644 index 00000000..cac66f9f --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1340_islessgreater.rst @@ -0,0 +1,38 @@ +islessgreater +~~~~~~~~~~~~~ + +.. c:autodoc:: common/islessgreater.c + +Special cases +^^^^^^^^^^^^^ + ++-----------------------------+-----------------------------+-----------------------------+ +| x | y | Result | ++=============================+=============================+=============================+ +| :math:`NaN` | :math:`\in \mathbb{F}` | :math:`0` | ++-----------------------------+-----------------------------+-----------------------------+ +| :math:`\in \mathbb{F}` | :math:`NaN` | :math:`0` | ++-----------------------------+-----------------------------+-----------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +#. Use :ref:`isunordered` to return :math:`0` if either input is :math:`NaN`. +#. If :math:`x < y` or :math:`x > y`, return :math:`1`, otherwise return :math:`0`. + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-5400 +* REQ-ML-5410 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/common/islessgreater.c + +References +^^^^^^^^^^ + +* :ref:`isunordered` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1350_isunordered.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1350_isunordered.rst new file mode 100644 index 00000000..1674ae23 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1350_isunordered.rst @@ -0,0 +1,35 @@ +isunordered +~~~~~~~~~~~ + +.. c:autodoc:: common/isunordered.c + +Special cases +^^^^^^^^^^^^^ + +This macro does not have special cases. + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +If at least one input is :math:`NaN` return :math:`1`, else return :math:`0`. + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-4900 +* REQ-ML-4910 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/common/isunordered.c + +References +^^^^^^^^^^ + +* :ref:`isgreater` +* :ref:`isgreaterequal` +* :ref:`isless` +* :ref:`islessequal` +* :ref:`islessgreater` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1400_j0.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1400_j0.rst new file mode 100644 index 00000000..5bd18457 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1400_j0.rst @@ -0,0 +1,48 @@ +j0 +~~~ + +.. c:autodoc:: mathd/j0d.c + +Special cases +^^^^^^^^^^^^^ + ++--------------------------------------+--------------------------------------+ +| x | Result | ++======================================+======================================+ +| :math:`±Inf` | :math:`+0` | ++--------------------------------------+--------------------------------------+ +| :math:`NaN` | :math:`qNaN` | ++--------------------------------------+--------------------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +#. Check for special cases and handle them. +#. Reduce :math:`x` to :math:`|x|` using :ref:`fabs` as :math:`j0(x) = j0(-x)`. +#. For small :math:`x` (:math:`x < 2`) use :math:`j0(x) = 1 - \frac{x^2}{4} + \frac{x^4}{64} - \cdots`. +#. For larger :math:`x` use :math:`j0(x) = \sqrt{\frac{2}{\pi x}} \cdot (p0(x) \cdot cos(x0) - q0(x) \cdot sin(x0))`, where :math:`x0 = x - \frac{\pi}{4}`, with :math:`p0` and :math:`q0`. Use asymptotic expansions for :math:`p0` and :math:`q0`. +#. Make use of the existing trigonometric procedures :ref:`sin` and :ref:`cos` as well as :ref:`sqrt`, but use :math:`cos(x0) = cos(x)cos(\frac{\pi}{4}) + sin(x)sin(\frac{\pi}{4}) = \frac{1}{\sqrt{2}} \cdot (cos(x) + sin(x))` and :math:`sin(x0) = sin(x)cos(\frac{\pi}{4}) - cos(x)sin(\frac{\pi}{4}) = \frac{1}{\sqrt{2}} \cdot (sin(x) - cos(x))` to calculate their values for :math:`x0`. To avoid cancellation, use :math:`sin(x) \pm cos(x) = -\frac{cos(2x)}{(sin(x) \mp cos(x)}` to compute the worse one. + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-8500 +* REQ-ML-8510 +* REQ-ML-8520 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/internal/besseld.h +* libm/mathd/j0d.c + +References +^^^^^^^^^^ + +* :ref:`cos` +* :ref:`fabs` +* :ref:`jn` +* :ref:`sin` +* :ref:`sqrt` +* :ref:`y0` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1410_j1.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1410_j1.rst new file mode 100644 index 00000000..49bfc2b8 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1410_j1.rst @@ -0,0 +1,48 @@ +j1 +~~~ + +.. c:autodoc:: mathd/j1d.c + +Special cases +^^^^^^^^^^^^^ + ++--------------------------------------+--------------------------------------+ +| x | Result | ++======================================+======================================+ +| :math:`±Inf` | :math:`+0` | ++--------------------------------------+--------------------------------------+ +| :math:`NaN` | :math:`qNaN` | ++--------------------------------------+--------------------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +#. Check for special cases and handle them. +#. Reduce :math:`x` to :math:`|x|` using :ref:`fabs` as :math:`j1(x) = -j1(-x)`. +#. For small :math:`x` (:math:`x < 2`) use :math:`j1(x) = \frac{x}{2} - \frac{x^3}{16} + \frac{x^5}{384} - \cdots`. +#. For larger :math:`x` use :math:`j1(x) = \sqrt{\frac{2}{\pi x}} \cdot (p1(x) \cdot cos(x1) - q1(x) \cdot sin(x1))`, where :math:`x1 = x - \frac{3\pi}{4}`, with :math:`p1` and :math:`q1`. Use asymptotic expansions for :math:`p1` and :math:`q1`. +#. Make use of the existing trigonometric procedures :ref:`sin` and :ref:`cos` as well as :ref:`sqrt`, but use :math:`cos(x1) = cos(x)cos(\frac{3\pi}{4}) + sin(x)sin(\frac{3\pi}{4}) = \frac{1}{\sqrt{2}} \cdot (sin(x) - cos(x))` and :math:`sin(x1) = sin(x)cos(\frac{3\pi}{4}) - cos(x)sin(\frac{3\pi}{4}) = -\frac{1}{\sqrt{2}} \cdot (sin(x) + cos(x))` to calculate their values for :math:`x1`. To avoid cancellation, use :math:`sin(x) \pm cos(x) = -\frac{cos(2x)}{(sin(x) \mp cos(x)}` to compute the worse one. + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-8530 +* REQ-ML-8540 +* REQ-ML-8550 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/internal/besseld.h +* libm/mathd/j1d.c + +References +^^^^^^^^^^ + +* :ref:`cos` +* :ref:`fabs` +* :ref:`jn` +* :ref:`sin` +* :ref:`sqrt` +* :ref:`y1` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1420_jn.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1420_jn.rst new file mode 100644 index 00000000..88a94d1a --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1420_jn.rst @@ -0,0 +1,49 @@ +jn +~~~ + +.. c:autodoc:: mathd/jnd.c + +Special cases +^^^^^^^^^^^^^ + ++--------------------------------------+--------------------------------------+--------------------------------------+ +| n | x | Result | ++======================================+======================================+======================================+ +| :math:`\in \mathbb{I}` | :math:`±Inf` | :math:`+0` | ++--------------------------------------+--------------------------------------+--------------------------------------+ +| :math:`\in \mathbb{I}` | :math:`NaN` | :math:`qNaN` | ++--------------------------------------+--------------------------------------+--------------------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +#. Check for special cases and handle them. +#. For :math:`n` is zero or one use :ref:`j0` and :ref:`j1`. +#. For :math:`n < x` use forward recursion starting from the values of :math:`j0(x)` and :math:`j1(x)`. +#. For :math:`n > x` use a continued fraction approximation to calculate :math:`\frac{j(n,x)}{j(n-1,x)}` and then use backward recursion starting from a supposed value for :math:`j(n,x)`. The resulting value of :math:`j(0,x)` is compared with the actual value to correct the supposed value of :math:`j(n,x)`. + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-8560 +* REQ-ML-8570 +* REQ-ML-8580 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/internal/besseld.h +* libm/mathd/jnd.c + +References +^^^^^^^^^^ + +* :ref:`cos` +* :ref:`fabs` +* :ref:`j0` +* :ref:`j1` +* :ref:`log` +* :ref:`sin` +* :ref:`sqrt` +* :ref:`yn` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1430_y0.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1430_y0.rst new file mode 100644 index 00000000..0f954b9f --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1430_y0.rst @@ -0,0 +1,60 @@ +y0 +~~~ + +.. c:autodoc:: mathd/y0d.c + +Special cases +^^^^^^^^^^^^^ + ++--------------------------------------+--------------------------------------+ +| x | Result | ++======================================+======================================+ +| :math:`-Inf` | :math:`qNaN` | ++--------------------------------------+--------------------------------------+ +| :math:`<0` | :math:`qNaN` | ++--------------------------------------+--------------------------------------+ +| :math:`±0` | :math:`-Inf` | ++--------------------------------------+--------------------------------------+ +| :math:`+Inf` | :math:`+0` | ++--------------------------------------+--------------------------------------+ +| :math:`NaN` | :math:`qNaN` | ++--------------------------------------+--------------------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +#. Check for special cases and handle them. +#. For small :math:`x` (:math:`x < 2`): + + #. Since :math:`y0(x) = \frac{2}{\pi} \cdot \Big(j0(x) \cdot \Big(ln\Big(\frac{x}{2}\Big) + Euler\Big) + \frac{x^2}{4} - \cdots\Big)` therefore :math:`y0(x) - \frac{2}{\pi} \cdot j0(x) \cdot ln(x)` is an even function. + #. Use :math:`y0(x) = \frac{U(z)}{V(z)} + \frac{2}{\pi} \cdot j0(x) \cdot ln(x) \wedge z = x^2`, and use approximations for :math:`U` and :math:`V`. (For tiny :math:`x` this can be further simplified to :math:`U/V = u0 \wedge j0(x) \approx 1`) + +#. For larger :math:`x` use :math:`y0(x) = \sqrt{\frac{2}{\pi x}} \cdot (p0(x) \cdot cos(x0) + q0(x) \cdot sin(x0))`, where :math:`x0 = x - \frac{\pi}{4}`, with :math:`p0` and :math:`q0`. Use asymptotic expansions for :math:`p0` and :math:`q0`. +#. Make use of the existing trigonometric procedures :ref:`sin` and :ref:`cos` as well as :ref:`sqrt`, but use :math:`cos(x0) = cos(x)cos(\frac{\pi}{4}) + sin(x)sin(\frac{\pi}{4}) = \frac{1}{\sqrt{2}} \cdot (cos(x) + sin(x))` and :math:`sin(x0) = sin(x)cos(\frac{\pi}{4}) - cos(x)sin(\frac{\pi}{4}) = \frac{1}{\sqrt{2}} \cdot (sin(x) - cos(x))` to calculate their values for :math:`x0`. To avoid cancellation, use :math:`sin(x) \pm cos(x) = -\frac{cos(2x)}{(sin(x) \mp cos(x)}` to compute the worse one. + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-8600 +* REQ-ML-8601 +* REQ-ML-8605 +* REQ-ML-8610 +* REQ-ML-8620 +* REQ-ML-8621 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/internal/besseld.h +* libm/mathd/y0d.c + +References +^^^^^^^^^^ + +* :ref:`cos` +* :ref:`j0` +* :ref:`log` +* :ref:`sin` +* :ref:`sqrt` +* :ref:`yn` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1440_y1.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1440_y1.rst new file mode 100644 index 00000000..d0b9687d --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1440_y1.rst @@ -0,0 +1,61 @@ +y1 +~~~ + +.. c:autodoc:: mathd/y1d.c + +Special cases +^^^^^^^^^^^^^ + ++--------------------------------------+--------------------------------------+ +| x | Result | ++======================================+======================================+ +| :math:`-Inf` | :math:`qNaN` | ++--------------------------------------+--------------------------------------+ +| :math:`<0` | :math:`qNaN` | ++--------------------------------------+--------------------------------------+ +| :math:`±0` | :math:`-Inf` | ++--------------------------------------+--------------------------------------+ +| :math:`+Inf` | :math:`+0` | ++--------------------------------------+--------------------------------------+ +| :math:`NaN` | :math:`qNaN` | ++--------------------------------------+--------------------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +#. Check for special cases and handle them. +#. If :math:`x` is negative return :math:`NaN`. +#. For small :math:`x` (:math:`x < 2`): + + #. Since :math:`y1(x) = \frac{2}{\pi} \cdot \Big(j1(x) \cdot \Big(ln\Big(\frac{x}{2}\Big) + Euler\Big) - \frac{1}{x} - \frac{x}{2} + \frac{5x^3}{64} - \cdots\Big)` therefore :math:`y1(x) - \frac{2}{\pi} \cdot j1(x) \cdot ln(x) - \frac{1}{x}` is an odd function. + #. Use :math:`y1(x) = x\frac{U(z)}{V(z)} + \frac{2}{\pi} \cdot \Big(j1(x) \cdot ln(x) - \frac{1}{x}\Big) \wedge z = x^2`, and use approximations for :math:`U` and :math:`V`. (For tiny :math:`x` this can be further simplified to :math:`y1(x) = -\frac{2}{\pi x}`) + +#. For larger :math:`x` use :math:`y1(x) = \sqrt{\frac{2}{\pi x}} \cdot (p1(x) \cdot sin(x1) + q1(x) \cdot cos(x1))`, where :math:`x1 = x - \frac{3\pi}{4}`, with :math:`p1` and :math:`q1`. Use asymptotic expansions for :math:`p1` and :math:`q1`. +#. Make use of the existing trigonometric procedures :ref:`sin` and :ref:`cos` as well as :ref:`sqrt`, but use :math:`cos(x1) = cos(x)cos(\frac{3\pi}{4}) + sin(x)sin(\frac{3\pi}{4}) = \frac{1}{\sqrt{2}} \cdot (sin(x) - cos(x))` and :math:`sin(x1) = sin(x)cos(\frac{3\pi}{4}) - cos(x)sin(\frac{3\pi}{4}) = -\frac{1}{\sqrt{2}} \cdot (sin(x) + cos(x))` to calculate their values for :math:`x1`. To avoid cancellation, use :math:`sin(x) \pm cos(x) = -\frac{cos(2x)}{(sin(x) \mp cos(x)}` to compute the worse one. + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-8630 +* REQ-ML-8631 +* REQ-ML-8635 +* REQ-ML-8640 +* REQ-ML-8650 +* REQ-ML-8651 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/internal/besseld.h +* libm/mathd/y1d.c + +References +^^^^^^^^^^ + +* :ref:`cos` +* :ref:`j1` +* :ref:`log` +* :ref:`sin` +* :ref:`sqrt` +* :ref:`yn` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1450_yn.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1450_yn.rst new file mode 100644 index 00000000..536fd0c9 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1450_yn.rst @@ -0,0 +1,55 @@ +yn +~~~ + +.. c:autodoc:: mathd/ynd.c + +Special cases +^^^^^^^^^^^^^ + ++--------------------------------------+--------------------------------------+--------------------------------------+ +| n | x | Result | ++======================================+======================================+======================================+ +| :math:`\in \mathbb{I}` | :math:`-Inf` | :math:`qNaN` | ++--------------------------------------+--------------------------------------+--------------------------------------+ +| :math:`\in \mathbb{I}` | :math:`<0` | :math:`qNaN` | ++--------------------------------------+--------------------------------------+--------------------------------------+ +| :math:`\in \mathbb{I}` | :math:`±0` | :math:`-Inf` | ++--------------------------------------+--------------------------------------+--------------------------------------+ +| :math:`\in \mathbb{I}` | :math:`+Inf` | :math:`+0` | ++--------------------------------------+--------------------------------------+--------------------------------------+ +| :math:`\in \mathbb{I}` | :math:`NaN` | :math:`qNaN` | ++--------------------------------------+--------------------------------------+--------------------------------------+ + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +#. Check for special cases and handle them. +#. For :math:`n` is zero or one use :ref:`y0` and :ref:`y1`. +#. For :math:`n > 1` use forward recursion starting from the values of :math:`y0(x)` and :math:`y1(x)`. + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-8660 +* REQ-ML-8661 +* REQ-ML-8665 +* REQ-ML-8670 +* REQ-ML-8680 +* REQ-ML-8681 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/math.h +* libm/mathd/internal/besseld.h +* libm/mathd/y1n.c + +References +^^^^^^^^^^ + +* :ref:`cos` +* :ref:`jn` +* :ref:`sin` +* :ref:`sqrt` +* :ref:`y0` +* :ref:`y1` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1500_cacos.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1500_cacos.rst new file mode 100644 index 00000000..765a101e --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1500_cacos.rst @@ -0,0 +1,32 @@ +cacos +~~~~~ + +.. c:autodoc:: complexd/cacosd.c + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +Implement based on :ref:`casin`. + +.. Here there be dragons. (TODO) + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-6000 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/complex.h +* libm/complexd/cacosd.c +* libm/complexf/cacosf.c + +References +^^^^^^^^^^ + +* :numref:`Tbl. %s ` +* :ref:`casin` +* :ref:`cimag` +* :ref:`CMPLX` +* :ref:`creal` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1510_casin.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1510_casin.rst new file mode 100644 index 00000000..bca3afbe --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1510_casin.rst @@ -0,0 +1,35 @@ +casin +~~~~~ + +.. c:autodoc:: complexd/casind.c + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +Implement based on :ref:`clog` and :ref:`csqrt`. + +.. Here there be dragons. (TODO) + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-6100 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/complex.h +* libm/complexd/casind.c +* libm/complexf/casinf.c + +References +^^^^^^^^^^ + +* :numref:`Tbl. %s ` +* :ref:`cacos` +* :ref:`casinh` +* :ref:`cimag` +* :ref:`clog` +* :ref:`CMPLX` +* :ref:`creal` +* :ref:`csqrt` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1520_catan.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1520_catan.rst new file mode 100644 index 00000000..79dad9fb --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1520_catan.rst @@ -0,0 +1,39 @@ +catan +~~~~~ + +.. c:autodoc:: complexd/catand.c + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +Implement based on :ref:`atan2`. + +.. Here there be dragons. (TODO) + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-6200 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/complex.h +* libm/complexd/catand.c +* libm/complexd/internal/ctrigd.h +* libm/complexd/internal/ctrigd.c +* libm/complexf/catanf.c +* libm/complexf/internal/ctrigf.h +* libm/complexf/internal/ctrigf.c + + +References +^^^^^^^^^^ + +* :numref:`Tbl. %s ` +* :ref:`atan2` +* :ref:`catanh` +* :ref:`cimag` +* :ref:`CMPLX` +* :ref:`creal` +* :ref:`log` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1530_ccos.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1530_ccos.rst new file mode 100644 index 00000000..5b4f0aba --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1530_ccos.rst @@ -0,0 +1,37 @@ +ccos +~~~~ + +.. c:autodoc:: complexd/ccosd.c + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +Implement based on :ref:`cos` and :ref:`sin`. + +.. Here there be dragons. (TODO) + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-6300 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/complex.h +* libm/complexd/ccosd.c +* libm/complexf/ccosf.c + +References +^^^^^^^^^^ + +* :numref:`Tbl. %s ` +* :ref:`cimag` +* :ref:`CMPLX` +* :ref:`cos` +* :ref:`cosh` +* :ref:`creal` +* :ref:`exp` +* :ref:`fabs` +* :ref:`sin` +* :ref:`sinh` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1540_csin.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1540_csin.rst new file mode 100644 index 00000000..792aae05 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1540_csin.rst @@ -0,0 +1,41 @@ +csin +~~~~ + +.. c:autodoc:: complexd/csind.c + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +Implement based on :ref:`cos` and :ref:`sin`. + +.. Here there be dragons. (TODO) + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-6400 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/complex.h +* libm/complexd/csind.c +* libm/complexd/internal/ctrigd.h +* libm/complexd/internal/ctrigd.c +* libm/complexf/csinf.c +* libm/complexf/internal/ctrigf.h +* libm/complexf/internal/ctrigf.c + +References +^^^^^^^^^^ + +* :numref:`Tbl. %s ` +* :ref:`cimag` +* :ref:`CMPLX` +* :ref:`cos` +* :ref:`cosh` +* :ref:`creal` +* :ref:`exp` +* :ref:`fabs` +* :ref:`sin` +* :ref:`sinh` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1550_ctan.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1550_ctan.rst new file mode 100644 index 00000000..74bf7ec7 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1550_ctan.rst @@ -0,0 +1,36 @@ +ctan +~~~~ + +.. c:autodoc:: complexd/ctand.c + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +Implement based on :ref:`cos`, :ref:`sin`, :ref:`cosh`, and :ref:`sinh`. + +.. Here there be dragons. (TODO) + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-6500 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/complex.h +* libm/complexd/ctand.c +* libm/complexf/ctanf.c + +References +^^^^^^^^^^ + +* :numref:`Tbl. %s ` +* :ref:`cimag` +* :ref:`CMPLX` +* :ref:`cos` +* :ref:`cosh` +* :ref:`creal` +* :ref:`fabs` +* :ref:`sin` +* :ref:`sinh` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1600_cacosh.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1600_cacosh.rst new file mode 100644 index 00000000..048c210f --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1600_cacosh.rst @@ -0,0 +1,29 @@ +cacosh +~~~~~~ + +.. c:autodoc:: complexd/cacoshd.c + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +Implement based on :ref:`clog` and :ref:`csqrt`. + +.. Here there be dragons. (TODO) + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-6600 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/complex.h +* libm/complexd/cacoshd.c +* libm/complexf/cacoshf.c + +References +^^^^^^^^^^ + +* :ref:`clog` +* :ref:`csqrt` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1610_casinh.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1610_casinh.rst new file mode 100644 index 00000000..cd7ca786 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1610_casinh.rst @@ -0,0 +1,31 @@ +casinh +~~~~~~ + +.. c:autodoc:: complexd/casinhd.c + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +Implement based on :ref:`casin`. + +.. Here there be dragons. (TODO) + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-6700 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/complex.h +* libm/complexd/casinhd.c +* libm/complexf/casinhf.c + +References +^^^^^^^^^^ + +* :ref:`casin` +* :ref:`cimag` +* :ref:`CMPLX` +* :ref:`creal` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1620_catanh.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1620_catanh.rst new file mode 100644 index 00000000..7d29f1b5 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1620_catanh.rst @@ -0,0 +1,31 @@ +catanh +~~~~~~ + +.. c:autodoc:: complexd/catanhd.c + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +Implement based on :ref:`catan`. + +.. Here there be dragons. (TODO) + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-6800 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/complex.h +* libm/complexd/catanhd.c +* libm/complexf/catanhf.c + +References +^^^^^^^^^^ + +* :ref:`catan` +* :ref:`cimag` +* :ref:`CMPLX` +* :ref:`creal` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1630_ccosh.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1630_ccosh.rst new file mode 100644 index 00000000..75943f2f --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1630_ccosh.rst @@ -0,0 +1,38 @@ +ccosh +~~~~~ + +.. c:autodoc:: complexd/ccoshd.c + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +Implement based on :ref:`cos`, :ref:`sin`, :ref:`cosh`, and :ref:`cosh`. + +.. Here there be dragons. (TODO) + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-6900 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/complex.h +* libm/complexd/ccoshd.c +* libm/complexd/internal/ctrigd.h +* libm/complexd/internal/ctrigd.c +* libm/complexf/ccoshf.c +* libm/complexf/internal/ctrigf.h +* libm/complexf/internal/ctrigf.c + +References +^^^^^^^^^^ + +* :ref:`cimag` +* :ref:`CMPLX` +* :ref:`cos` +* :ref:`cosh` +* :ref:`creal` +* :ref:`sin` +* :ref:`sinh` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1640_csinh.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1640_csinh.rst new file mode 100644 index 00000000..5fd539b8 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1640_csinh.rst @@ -0,0 +1,34 @@ +csinh +~~~~~ + +.. c:autodoc:: complexd/csinhd.c + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +Implement based on :ref:`cos`, :ref:`sin`, :ref:`cosh`, and :ref:`cosh`. + +.. Here there be dragons. (TODO) + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-7000 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/complex.h +* libm/complexd/csinhd.c +* libm/complexf/csinhf.c + +References +^^^^^^^^^^ + +* :ref:`cimag` +* :ref:`CMPLX` +* :ref:`cos` +* :ref:`cosh` +* :ref:`creal` +* :ref:`sin` +* :ref:`sinh` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1650_ctanh.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1650_ctanh.rst new file mode 100644 index 00000000..ed9c6b55 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1650_ctanh.rst @@ -0,0 +1,39 @@ +ctanh +~~~~~ + +.. c:autodoc:: complexd/ctanhd.c + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +Implement based on :ref:`cos`, :ref:`sin`, :ref:`cosh`, and :ref:`cosh`. + +.. Here there be dragons. (TODO) + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-7100 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/complex.h +* libm/complexd/ctanhd.c +* libm/complexd/internal/ctrigd.h +* libm/complexd/internal/ctrigd.c +* libm/complexf/ctanhf.c +* libm/complexf/internal/ctrigf.h +* libm/complexf/internal/ctrigf.c + + +References +^^^^^^^^^^ + +* :ref:`cimag` +* :ref:`CMPLX` +* :ref:`cos` +* :ref:`cosh` +* :ref:`creal` +* :ref:`sin` +* :ref:`sinh` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1700_cexp.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1700_cexp.rst new file mode 100644 index 00000000..c1427fe5 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1700_cexp.rst @@ -0,0 +1,33 @@ +cexp +~~~~ + +.. c:autodoc:: complexd/cexpd.c + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +Implement based on :ref:`cos`, :ref:`sin`, and :ref:`exp`. + +.. Here there be dragons. (TODO) + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-7200 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/complex.h +* libm/complexd/cexpd.c +* libm/complexf/cexpf.c + +References +^^^^^^^^^^ + +* :ref:`cimag` +* :ref:`CMPLX` +* :ref:`cos` +* :ref:`creal` +* :ref:`exp` +* :ref:`sin` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1710_clog.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1710_clog.rst new file mode 100644 index 00000000..a2c128de --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1710_clog.rst @@ -0,0 +1,35 @@ +clog +~~~~ + +.. c:autodoc:: complexd/clogd.c + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +Implement based on :ref:`atan2`, and :ref:`log`. + +.. Here there be dragons. (TODO) + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-7300 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/complex.h +* libm/complexd/clogd.c +* libm/complexf/clogf.c + +References +^^^^^^^^^^ + +* :ref:`atan2` +* :ref:`cabs` +* :ref:`cacosh` +* :ref:`casin` +* :ref:`cimag` +* :ref:`CMPLX` +* :ref:`creal` +* :ref:`log` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1800_cabs.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1800_cabs.rst new file mode 100644 index 00000000..f3459df5 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1800_cabs.rst @@ -0,0 +1,33 @@ +cabs +~~~~ + +.. c:autodoc:: complexd/cabsd.c + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +Implement based on :ref:`hypot`. + +.. Here there be dragons. (TODO) + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-7400 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/complex.h +* libm/complexd/cabsd.c +* libm/complexf/cabsf.c + +References +^^^^^^^^^^ + +* :ref:`cimag` +* :ref:`clog` +* :ref:`cpow` +* :ref:`creal` +* :ref:`csqrt` +* :ref:`hypot` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1810_cpow.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1810_cpow.rst new file mode 100644 index 00000000..c55fb882 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1810_cpow.rst @@ -0,0 +1,38 @@ +cpow +~~~~~ + +.. c:autodoc:: complexd/cpowd.c + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +Implement based on :ref:`cos`, :ref:`sin`, :ref:`log`, :ref:`exp`, :ref:`pow`, and :ref:`carg`. + +.. Here there be dragons. (TODO) + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-7500 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/complex.h +* libm/complexd/cpowd.c +* libm/complexf/cpowf.c + +References +^^^^^^^^^^ + +* :ref:`cabs` +* :ref:`carg` +* :ref:`cimag` +* :ref:`CMPLX` +* :ref:`cos` +* :ref:`creal` +* :ref:`csqrt` +* :ref:`exp` +* :ref:`log` +* :ref:`pow` +* :ref:`sin` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1820_csqrt.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1820_csqrt.rst new file mode 100644 index 00000000..49cdaf4b --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1820_csqrt.rst @@ -0,0 +1,35 @@ +csqrt +~~~~~ + +.. c:autodoc:: complexd/csqrtd.c + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +Implement based on :ref:`sqrt`. + +.. Here there be dragons. (TODO) + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-7600 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/complex.h +* libm/complexd/csqrtd.c +* libm/complexf/csqrtf.c + +References +^^^^^^^^^^ + +* :ref:`cabs` +* :ref:`cacosh` +* :ref:`casin` +* :ref:`cimag` +* :ref:`CMPLX` +* :ref:`creal` +* :ref:`fabs` +* :ref:`sqrt` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1900_carg.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1900_carg.rst new file mode 100644 index 00000000..54f1f4de --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1900_carg.rst @@ -0,0 +1,31 @@ +carg +~~~~ + +.. c:autodoc:: complexd/cargd.c + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +Implement based on :ref:`atan2`. + +.. Here there be dragons. (TODO) + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-7700 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/complex.h +* libm/complexd/cargd.c +* libm/complexf/cargf.c + +References +^^^^^^^^^^ + +* :ref:`atan2` +* :ref:`cimag` +* :ref:`cpow` +* :ref:`creal` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1910_cimag.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1910_cimag.rst new file mode 100644 index 00000000..8dacbcd5 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1910_cimag.rst @@ -0,0 +1,30 @@ +cimag +~~~~~ + +.. c:autodoc:: complexd/cimagd.c + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +Return the imaginary part of the input. + +.. Here there be dragons. (TODO) + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-7800 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/complex.h +* libm/complexd/cimagd.c +* libm/complexf/cimagf.c + +References +^^^^^^^^^^ + +* :ref:`creal` + +Nearly all complex procedures use ``cimag``. diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1920_cmplx.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1920_cmplx.rst new file mode 100644 index 00000000..b8d5bb52 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1920_cmplx.rst @@ -0,0 +1,27 @@ +CMPLX +~~~~~~~~~ + +.. c:autodoc:: common/cmplx.c + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +Use inherent procedures in accordance with C standard compliant toolchains. + +.. Here there be dragons. (TODO) + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-7900 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/complex.h +* libm/common/cmplx.c + +References +^^^^^^^^^^ + +Nearly all complex procedures use ``CMPLX``. diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1930_conj.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1930_conj.rst new file mode 100644 index 00000000..0e945cab --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1930_conj.rst @@ -0,0 +1,26 @@ +conj +~~~~~ + +.. c:autodoc:: complexd/conjd.c + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +Inverse the imaginary part of the input. + +.. Here there be dragons. (TODO) + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-8000 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/complex.h +* libm/complexd/conjd.c +* libm/complexf/conjf.c + +References +^^^^^^^^^^ diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1940_cproj.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1940_cproj.rst new file mode 100644 index 00000000..08ade237 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1940_cproj.rst @@ -0,0 +1,30 @@ +cproj +~~~~~ + +.. c:autodoc:: complexd/cprojd.c + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +Implement based on :ref:`copysign`. + +.. Here there be dragons. (TODO) + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-8100 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/complex.h +* libm/complexd/cprojd.c +* libm/complexf/cprojf.c + +References +^^^^^^^^^^ + +* :ref:`cimag` +* :ref:`copysign` +* :ref:`isinf` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1950_creal.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1950_creal.rst new file mode 100644 index 00000000..0510b24e --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1950_creal.rst @@ -0,0 +1,30 @@ +creal +~~~~~ + +.. c:autodoc:: complexd/creald.c + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +Return the real part of the input. + +.. Here there be dragons. (TODO) + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-8200 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/include/complex.h +* libm/complexd/creald.c +* libm/complexf/crealf.c + +References +^^^^^^^^^^ + +* :ref:`cimag` + +Nearly all complex procedures use ``creal``. diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/2000_misc_internal.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/2000_misc_internal.rst new file mode 100644 index 00000000..33c2d4f8 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/2000_misc_internal.rst @@ -0,0 +1,40 @@ +.. _internal_misc: + +Exception Raising And Floating-Point/Integer Conversion Functions +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. c:autodoc:: common/tools.h + +Special cases +^^^^^^^^^^^^^ + +The exception raising procedures are themselves special cases but do not have any. + +The floating-point to integer conversion (and vice-versa) procedures do not have any. + +Mathematical Approach +^^^^^^^^^^^^^^^^^^^^^ + +Implement based on bit-fiddling and tricks for forcing the FPU to do as it should. + +.. Here there be dragons. (TODO) + +Requirements +^^^^^^^^^^^^ + +Internal functions do not directly implement requirements. + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* libm/common/tools.h +* libm/common/tools.c + +References +^^^^^^^^^^ + +Exception raising procedures are used in a lot of other procedures. They are used whenever the `Mathematical Approach` of the procedure explicitly states raising an exception. + +Floating-point to integer conversion (and vice-versa) procedures are used in a lot of other procedures. They are used whenever the `Mathematical Approach` of the procedure makes use of, or manipulates, the hexadecimal representation of floating-point datums, for example for checking/extracting/manipulating the sign/exponent/mantissa. They are used quite liberally. + +``SAFE_RIGHT_SHIFT`` is used by :ref:`lrint`, :ref:`llrint`, :ref:`lround` and :ref:`llround`. diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/3000_configure.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/3000_configure.rst new file mode 100644 index 00000000..863fb333 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/3000_configure.rst @@ -0,0 +1,56 @@ +configure +~~~~~~~~~ + +Description and Use +^^^^^^^^^^^^^^^^^^^ + +The ``configure`` file shall be a script to prepare for running the :ref:`Makefile`. It's intention is to smoothen the process of building and rebuilding the library for multiple platforms, toolchains and configurations. + +For this the user has to be asked multiple questions to configure the library for the project's use-case. + +Alternatively the script should be callable with command line options to enable/disable the flags and input paths. The use should be very similar to ``configure`` scripts created using an ``autoconf/automake`` setup. + +Approach +^^^^^^^^ + +#. Use ``getopt`` to define usable flags. +#. Parse user arguments into variables. +#. Create a user help (flag ``-h`` or on unexpected options). +#. Create a an empty ``user_make`` file which will later be read by the :ref:`Makefile`. +#. Create a minimal C program to check preset defines of the toolchain (e.g., type sizes). +#. Before asking the following questions first check if the user has already provided the answer via flag. +#. If any of the below questions was answered with a faulty value, ask again. +#. Ask for path to toolchain. +#. Ask for additional compilation flags. +#. Ask for DAZ/FTZ mode. +#. Use the previously created C program to check the size of ``long int``, if it is 32bit add ``-DLIBMCS_LONG_IS_32BITS`` to the additional compilation flags. +#. Use the previously created C program to check the size of ``double``, if it is 32bit add ``-DLIBMCS_DOUBLE_IS_32BITS`` to the additional compilation flags. +#. Use the previously created C program to check the size of ``long double``, if it is 64bit ask if ``long double`` procedures shall be compiled into the library, and if so add ``-DLIBMCS_LONG_DOUBLE_IS_64BITS`` to the additional compilation flags. +#. Use the previously created C program to check the endianess of the toolchain/platform/flag-combination, if no endianess is found ask the user whether it is little or big endian, and add the specific flag to the additional compilation flags (either ``-D__BYTE_ORDER__=__ORDER_BIG_ENDIAN__`` or ``-D__BYTE_ORDER__=__ORDER_LITTLE_ENDIAN__``). +#. Add the path to the toolchain and the accumulated additional compilation flags to the ``user_make``. +#. Ask if ``complex`` procedures shall be compiled into the library, and if so add a variable to the ``user_make``. +#. Finish of the ``user_make`` with a variable that tells the :ref:`Makefile` that the configuration was successful. + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-0024 +* REQ-ML-0025 +* REQ-ML-0026 +* REQ-ML-0027 +* REQ-ML-0028 +* REQ-ML-0090 +* REQ-ML-0100 +* REQ-ML-0115 +* REQ-ML-0180 +* REQ-ML-1901 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* configure + +References +^^^^^^^^^^ + +* :ref:`Makefile` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/3100_makefile.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/3100_makefile.rst new file mode 100644 index 00000000..3cbfd92f --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/3100_makefile.rst @@ -0,0 +1,48 @@ +Makefile +~~~~~~~~ + +Description and Use +^^^^^^^^^^^^^^^^^^^ + +The ``Makefile`` is a commonly used script to build software, in this case a library. + +This ``Makefile`` has to be run after :ref:`configure` was run successfully, otherwise it shall throw an error. This may be avoidable by adding the configuration successful variable to the ``make`` call, but shall not be encouraged. + +This ``Makefile`` shall provide the following targets: ``all`` (builds the library), ``debug`` (same as ``all``), ``release`` (same as ``debug`` but with extra flag ``-DNDBUG``), ``clean`` (removes the build corresponding to the current configuration), ``cleanall`` (removes all builds), and ``distclean`` (removes ``user_make`` and the C program built for testing purposes within :ref:`configure` (if :ref:`configure` was run successfully the testing files should already be removed)). + +Approach +^^^^^^^^ + +#. Include ``user_make``. +#. Check for the configuration successful variable, if it is not set (either via ``user_make`` or manually) stop and throw an error. +#. Check if the user provided a build name, if not create one based on toolchain and target. +#. Define include paths. +#. Define source paths. Check if the user wanted ``long double`` and/or ``complex`` procedures and add them if so. +#. Add compilation/linking flags (library specific flags, user flags, coverage, etc.). +#. Build it all. +#. Add mechanism for verbose output throughout all steps. +#. Add mechanism to create a ``build_log`` in YAML format. + +Requirements +^^^^^^^^^^^^ + +* REQ-ML-0024 +* REQ-ML-0025 +* REQ-ML-0026 +* REQ-ML-0027 +* REQ-ML-0028 +* REQ-ML-0090 +* REQ-ML-0100 +* REQ-ML-0115 +* REQ-ML-0180 +* REQ-ML-1901 + +Source Code Files +^^^^^^^^^^^^^^^^^ + +* Makefile + +References +^^^^^^^^^^ + +* :ref:`configure` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/5_Internal_Interface_Design.rst b/libm/libmcs/doc/sdd/5_Software_Design/5_Internal_Interface_Design.rst new file mode 100644 index 00000000..be5a9784 --- /dev/null +++ b/libm/libmcs/doc/sdd/5_Software_Design/5_Internal_Interface_Design.rst @@ -0,0 +1,20 @@ +Internal Interface Design +------------------------- + +.. raw:: html + + + +The internal interface design is limited to the interactions between different procedures. + +For each procedure :ref:`Software Components Design – Aspects of Each Component` describes which other procedures are called. diff --git a/libm/libmcs/doc/sdd/6_Requirements_to_Design_Components_Traceability.rst b/libm/libmcs/doc/sdd/6_Requirements_to_Design_Components_Traceability.rst new file mode 100644 index 00000000..feffffee --- /dev/null +++ b/libm/libmcs/doc/sdd/6_Requirements_to_Design_Components_Traceability.rst @@ -0,0 +1,761 @@ +Requirements to Design Components Traceability +============================================== + +.. raw:: html + + + +The :numref:`Tbl. %s ` contains the traceability of the software components in :ref:`Software Components Design – Aspects of Each Component` (or the :ref:`SDD ` section responing to the requirement) to the :ref:`SRS ` :ref:`[RD01] ` requirements. + +.. table:: Requirement upward traceability + :name: req-upward + + ========================================== =========== + Component Requirement + ========================================== =========== + acos REQ-ML-0450 + acos REQ-ML-0460 + acos REQ-ML-0470 + acos REQ-ML-0480 + acos REQ-ML-0490 + acosh REQ-ML-2710 + acosh REQ-ML-3010 + acosh REQ-ML-3020 + acosh REQ-ML-3030 + acosh REQ-ML-3040 + asin REQ-ML-0250 + asin REQ-ML-0260 + asin REQ-ML-0270 + asin REQ-ML-0280 + asin REQ-ML-0281 + asinh REQ-ML-2620 + asinh REQ-ML-2630 + asinh REQ-ML-2640 + asinh REQ-ML-2700 + atan REQ-ML-0600 + atan REQ-ML-0610 + atan REQ-ML-0620 + atan REQ-ML-0621 + atan2 REQ-ML-0650 + atan2 REQ-ML-0652 + atan2 REQ-ML-0660 + atan2 REQ-ML-0661 + atan2 REQ-ML-0662 + atan2 REQ-ML-0663 + atan2 REQ-ML-0670 + atan2 REQ-ML-0680 + atan2 REQ-ML-0681 + atan2 REQ-ML-0682 + atan2 REQ-ML-0683 + atan2 REQ-ML-0684 + atan2 REQ-ML-0685 + atan2 REQ-ML-0686 + atanh REQ-ML-3100 + atanh REQ-ML-3110 + atanh REQ-ML-3120 + atanh REQ-ML-3121 + atanh REQ-ML-3140 + atanh REQ-ML-3141 + cabs REQ-ML-7400 + cacos REQ-ML-6000 + cacosh REQ-ML-6600 + carg REQ-ML-7700 + casin REQ-ML-6100 + casinh REQ-ML-6700 + catan REQ-ML-6200 + catanh REQ-ML-6800 + cbrt REQ-ML-2300 + cbrt REQ-ML-2310 + cbrt REQ-ML-2320 + cbrt REQ-ML-2340 + ccos REQ-ML-6300 + ccosh REQ-ML-6900 + ceil REQ-ML-1080 + ceil REQ-ML-1091 + ceil REQ-ML-1092 + cexp REQ-ML-7200 + cimag REQ-ML-7800 + clog REQ-ML-7300 + cmplx REQ-ML-7900 + conj REQ-ML-8000 + copysign REQ-ML-1380 + copysign REQ-ML-1381 + cos REQ-ML-0300 + cos REQ-ML-0310 + cos REQ-ML-0320 + cos REQ-ML-0330 + cosh REQ-ML-2200 + cosh REQ-ML-2210 + cosh REQ-ML-2220 + cosh REQ-ML-2240 + cpow REQ-ML-7500 + cproj REQ-ML-8100 + creal REQ-ML-8200 + csin REQ-ML-6400 + csinh REQ-ML-7000 + csqrt REQ-ML-7600 + ctan REQ-ML-6500 + ctanh REQ-ML-7100 + erf REQ-ML-3600 + erf REQ-ML-3610 + erf REQ-ML-3620 + erf REQ-ML-3630 + erf REQ-ML-3640 + erfc REQ-ML-3700 + erfc REQ-ML-3710 + erfc REQ-ML-3720 + erfc REQ-ML-3730 + erfc REQ-ML-3740 + exp REQ-ML-0800 + exp REQ-ML-0831 + exp REQ-ML-0832 + exp REQ-ML-0833 + exp REQ-ML-0834 + exp2 REQ-ML-3200 + exp2 REQ-ML-3210 + exp2 REQ-ML-3220 + exp2 REQ-ML-3240 + exp2 REQ-ML-3250 + expm1 REQ-ML-2500 + expm1 REQ-ML-2510 + expm1 REQ-ML-2520 + expm1 REQ-ML-2540 + expm1 REQ-ML-2550 + fabs REQ-ML-1012 + fabs REQ-ML-1000 + fabs REQ-ML-1010 + fabs REQ-ML-1011 + fdim REQ-ML-2600 + fdim REQ-ML-2610 + fdim REQ-ML-2620 + fdim REQ-ML-2630 + fdim REQ-ML-2640 + floor REQ-ML-1040 + floor REQ-ML-1051 + floor REQ-ML-1052 + fma REQ-ML-2500 + fma REQ-ML-2510 + fma REQ-ML-2520 + fma REQ-ML-2700 + fmax REQ-ML-1240 + fmax REQ-ML-1250 + fmax REQ-ML-1252 + fmin REQ-ML-1220 + fmin REQ-ML-1230 + fmin REQ-ML-1232 + fmod REQ-ML-1100 + fmod REQ-ML-1120 + fmod REQ-ML-1121 + fmod REQ-ML-1122 + fmod REQ-ML-1130 + fmod REQ-ML-1131 + fpclassify REQ-ML-5700 + frexp REQ-ML-4000 + frexp REQ-ML-4010 + frexp REQ-ML-4020 + frexp REQ-ML-4040 + hypot REQ-ML-1260 + hypot REQ-ML-1270 + hypot REQ-ML-1271 + ilogb REQ-ML-4300 + ilogb REQ-ML-4310 + ilogb REQ-ML-4320 + ilogb REQ-ML-4340 + isfinite REQ-ML-1300 + isgreater REQ-ML-5000 + isgreater REQ-ML-5010 + isgreaterequal REQ-ML-5100 + isgreaterequal REQ-ML-5110 + isinf REQ-ML-1320 + isless REQ-ML-5200 + isless REQ-ML-5210 + islessequal REQ-ML-5300 + islessequal REQ-ML-5310 + islessgreater REQ-ML-5400 + islessgreater REQ-ML-5410 + isnan REQ-ML-1340 + isnormal REQ-ML-5500 + isunordered REQ-ML-4900 + isunordered REQ-ML-4910 + j0 REQ-ML-8500 + j0 REQ-ML-8510 + j0 REQ-ML-8520 + j1 REQ-ML-8530 + j1 REQ-ML-8540 + j1 REQ-ML-8550 + jn REQ-ML-8560 + jn REQ-ML-8570 + jn REQ-ML-8580 + ldexp REQ-ML-4100 + ldexp REQ-ML-4110 + ldexp REQ-ML-4120 + ldexp REQ-ML-4130 + ldexp REQ-ML-4140 + lgamma REQ-ML-3800 + lgamma REQ-ML-3810 + lgamma REQ-ML-3820 + lgamma REQ-ML-3830 + lgamma REQ-ML-3840 + lgamma REQ-ML-3850 + llrint REQ-ML-4670 + llround REQ-ML-8400 + log REQ-ML-0900 + log REQ-ML-0910 + log REQ-ML-0920 + log REQ-ML-0921 + log REQ-ML-0930 + log REQ-ML-0931 + log10 REQ-ML-0950 + log10 REQ-ML-0960 + log10 REQ-ML-0970 + log10 REQ-ML-0971 + log10 REQ-ML-0980 + log10 REQ-ML-0981 + log1p REQ-ML-3400 + log1p REQ-ML-3410 + log1p REQ-ML-3420 + log1p REQ-ML-3430 + log1p REQ-ML-3440 + log1p REQ-ML-3450 + log2 REQ-ML-3300 + log2 REQ-ML-3310 + log2 REQ-ML-3320 + log2 REQ-ML-3330 + log2 REQ-ML-3340 + log2 REQ-ML-3350 + logb REQ-ML-3500 + logb REQ-ML-3510 + logb REQ-ML-3520 + logb REQ-ML-3540 + lrint REQ-ML-4650 + lrint REQ-ML-4653 + lrint REQ-ML-4656 + lrint REQ-ML-4659 + lrint REQ-ML-4662 + lround REQ-ML-8300 + lround REQ-ML-8310 + lround REQ-ML-8320 + lround REQ-ML-8330 + lround REQ-ML-8340 + modf REQ-ML-1200 + modf REQ-ML-1201 + modf REQ-ML-1210 + modf REQ-ML-1211 + nan REQ-ML-4400 + nearbyint REQ-ML-4500 + nearbyint REQ-ML-4510 + nearbyint REQ-ML-4520 + nearbyint REQ-ML-4540 + nextafter REQ-ML-4700 + nextafter REQ-ML-4710 + nextafter REQ-ML-4720 + nextafter REQ-ML-4731 + nextafter REQ-ML-4740 + nextafter REQ-ML-4741 + nexttoward REQ-ML-4750 + pow REQ-ML-0850 + pow REQ-ML-0860 + pow REQ-ML-0864 + pow REQ-ML-0870 + pow REQ-ML-0871 + pow REQ-ML-0872 + pow REQ-ML-0873 + pow REQ-ML-0874 + pow REQ-ML-0875 + pow REQ-ML-0876 + pow REQ-ML-0877 + pow REQ-ML-0878 + pow REQ-ML-0879 + pow REQ-ML-0880 + pow REQ-ML-0881 + pow REQ-ML-0882 + pow REQ-ML-0883 + pow REQ-ML-0885 + pow REQ-ML-0886 + remainder REQ-ML-3900 + remainder REQ-ML-3910 + remainder REQ-ML-3920 + remainder REQ-ML-3940 + remquo REQ-ML-5600 + remquo REQ-ML-5601 + remquo REQ-ML-5620 + remquo REQ-ML-5620 + remquo REQ-ML-5640 + rint REQ-ML-4600 + rint REQ-ML-4610 + rint REQ-ML-4620 + rint REQ-ML-4640 + round REQ-ML-1020 + round REQ-ML-1031 + round REQ-ML-1032 + scalbln REQ-ML-4250 + scalbn REQ-ML-4200 + scalbn REQ-ML-4210 + scalbn REQ-ML-4220 + scalbn REQ-ML-4230 + scalbn REQ-ML-4240 + signbit REQ-ML-1360 + signgam REQ-ML-3850 + sin REQ-ML-0200 + sin REQ-ML-0210 + sin REQ-ML-0220 + sin REQ-ML-0240 + sinh REQ-ML-2100 + sinh REQ-ML-2110 + sinh REQ-ML-2120 + sinh REQ-ML-2140 + sqrt REQ-ML-0700 + sqrt REQ-ML-0710 + sqrt REQ-ML-0720 + sqrt REQ-ML-0730 + sqrt REQ-ML-0740 + tan REQ-ML-0500 + tan REQ-ML-0520 + tan REQ-ML-0530 + tan REQ-ML-0550 + tanh REQ-ML-2540 + tanh REQ-ML-2550 + tanh REQ-ML-2600 + tanh REQ-ML-2610 + tgamma REQ-ML-5800 + tgamma REQ-ML-5810 + tgamma REQ-ML-5820 + tgamma REQ-ML-5830 + tgamma REQ-ML-5840 + tgamma REQ-ML-5841 + trunc REQ-ML-1060 + trunc REQ-ML-1070 + trunc REQ-ML-1071 + y0 REQ-ML-8600 + y0 REQ-ML-8601 + y0 REQ-ML-8605 + y0 REQ-ML-8610 + y0 REQ-ML-8620 + y0 REQ-ML-8621 + y1 REQ-ML-8630 + y1 REQ-ML-8631 + y1 REQ-ML-8635 + y1 REQ-ML-8640 + y1 REQ-ML-8650 + y1 REQ-ML-8651 + yn REQ-ML-8660 + yn REQ-ML-8661 + yn REQ-ML-8665 + yn REQ-ML-8670 + yn REQ-ML-8680 + yn REQ-ML-8681 + all REQ-ML-0020 + all REQ-ML-0021 + all REQ-ML-0061 + all REQ-ML-0062 + all REQ-ML-0063 + all REQ-ML-0064 + all REQ-ML-0110 + all REQ-ML-0112 + all REQ-ML-1600 + all REQ-ML-1800 + all REQ-ML-1900 + all REQ-ML-2000 + :ref:`Makefile`/:ref:`configure` REQ-ML-0024 + :ref:`Makefile`/:ref:`configure` REQ-ML-0025 + :ref:`Makefile`/:ref:`configure` REQ-ML-0026 + :ref:`Makefile`/:ref:`configure` REQ-ML-0027 + :ref:`Makefile`/:ref:`configure` REQ-ML-0028 + :ref:`Makefile`/:ref:`configure` REQ-ML-0090 + :ref:`Makefile`/:ref:`configure` REQ-ML-0100 + :ref:`Makefile`/:ref:`configure` REQ-ML-0115 + :ref:`Makefile`/:ref:`configure` REQ-ML-0180 + :ref:`Makefile`/:ref:`configure` REQ-ML-1901 + :ref:`Interfaces Context` REQ-ML-0010 + :ref:`Interfaces Context` REQ-ML-0011 + :ref:`Software Design - General ` REQ-ML-1499 + :ref:`Software Design - General ` REQ-ML-1500 + :ref:`Software Design - General ` REQ-ML-1501 + :ref:`Software Design - General ` REQ-ML-1502 + :ref:`Software Design - General ` REQ-ML-1503 + :ref:`Software Design - General ` REQ-ML-1504 + :ref:`fenv ` REQ-ML-8700 + :ref:`tgmath ` REQ-ML-8800 + :ref:`Handling of Subnormal Numbers` REQ-ML-0029 + :ref:`Errno` REQ-ML-0022 + ========================================== =========== + +The :numref:`Tbl. %s ` contains the traceability of the :ref:`SRS ` :ref:`[RD01] ` requirements to the software components in :ref:`Software Components Design – Aspects of Each Component` (or the :ref:`SDD ` section responing to the requirement). + +.. table:: Requirement downward traceability + :name: req-downward + + ============== ========================================== + Requirement Component + ============== ========================================== + REQ-ML-0010 :ref:`Interfaces Context` + REQ-ML-0011 :ref:`Interfaces Context` + REQ-ML-0020 all + REQ-ML-0021 all + REQ-ML-0022 :ref:`Errno` + REQ-ML-0024 :ref:`Makefile`/:ref:`configure` + REQ-ML-0025 :ref:`Makefile`/:ref:`configure` + REQ-ML-0026 :ref:`Makefile`/:ref:`configure` + REQ-ML-0027 :ref:`Makefile`/:ref:`configure` + REQ-ML-0028 :ref:`Makefile`/:ref:`configure` + REQ-ML-0029 :ref:`Handling of Subnormal Numbers` + REQ-ML-0061 all + REQ-ML-0062 all + REQ-ML-0063 all + REQ-ML-0064 all + REQ-ML-0090 :ref:`Makefile`/:ref:`configure` + REQ-ML-0100 :ref:`Makefile`/:ref:`configure` + REQ-ML-0110 all + REQ-ML-0112 all + REQ-ML-0115 :ref:`Makefile`/:ref:`configure` + REQ-ML-0180 :ref:`Makefile`/:ref:`configure` + REQ-ML-0200 sin + REQ-ML-0210 sin + REQ-ML-0220 sin + REQ-ML-0240 sin + REQ-ML-0250 asin + REQ-ML-0260 asin + REQ-ML-0270 asin + REQ-ML-0280 asin + REQ-ML-0281 asin + REQ-ML-0300 cos + REQ-ML-0310 cos + REQ-ML-0320 cos + REQ-ML-0330 cos + REQ-ML-0450 acos + REQ-ML-0460 acos + REQ-ML-0470 acos + REQ-ML-0480 acos + REQ-ML-0490 acos + REQ-ML-0500 tan + REQ-ML-0520 tan + REQ-ML-0530 tan + REQ-ML-0550 tan + REQ-ML-0600 atan + REQ-ML-0610 atan + REQ-ML-0620 atan + REQ-ML-0621 atan + REQ-ML-0650 atan2 + REQ-ML-0652 atan2 + REQ-ML-0660 atan2 + REQ-ML-0661 atan2 + REQ-ML-0662 atan2 + REQ-ML-0663 atan2 + REQ-ML-0670 atan2 + REQ-ML-0680 atan2 + REQ-ML-0681 atan2 + REQ-ML-0682 atan2 + REQ-ML-0683 atan2 + REQ-ML-0684 atan2 + REQ-ML-0685 atan2 + REQ-ML-0686 atan2 + REQ-ML-0700 sqrt + REQ-ML-0710 sqrt + REQ-ML-0720 sqrt + REQ-ML-0730 sqrt + REQ-ML-0740 sqrt + REQ-ML-0800 exp + REQ-ML-0831 exp + REQ-ML-0832 exp + REQ-ML-0833 exp + REQ-ML-0834 exp + REQ-ML-0850 pow + REQ-ML-0860 pow + REQ-ML-0864 pow + REQ-ML-0870 pow + REQ-ML-0871 pow + REQ-ML-0872 pow + REQ-ML-0873 pow + REQ-ML-0874 pow + REQ-ML-0875 pow + REQ-ML-0876 pow + REQ-ML-0877 pow + REQ-ML-0878 pow + REQ-ML-0879 pow + REQ-ML-0880 pow + REQ-ML-0881 pow + REQ-ML-0882 pow + REQ-ML-0883 pow + REQ-ML-0885 pow + REQ-ML-0886 pow + REQ-ML-0900 log + REQ-ML-0910 log + REQ-ML-0920 log + REQ-ML-0921 log + REQ-ML-0930 log + REQ-ML-0931 log + REQ-ML-0950 log10 + REQ-ML-0960 log10 + REQ-ML-0970 log10 + REQ-ML-0971 log10 + REQ-ML-0980 log10 + REQ-ML-0981 log10 + REQ-ML-1000 fabs + REQ-ML-1010 fabs + REQ-ML-1011 fabs + REQ-ML-1012 fabs + REQ-ML-1020 round + REQ-ML-1031 round + REQ-ML-1032 round + REQ-ML-1040 floor + REQ-ML-1051 floor + REQ-ML-1052 floor + REQ-ML-1060 trunc + REQ-ML-1070 trunc + REQ-ML-1071 trunc + REQ-ML-1080 ceil + REQ-ML-1091 ceil + REQ-ML-1092 ceil + REQ-ML-1100 fmod + REQ-ML-1120 fmod + REQ-ML-1121 fmod + REQ-ML-1122 fmod + REQ-ML-1130 fmod + REQ-ML-1131 fmod + REQ-ML-1200 modf + REQ-ML-1201 modf + REQ-ML-1210 modf + REQ-ML-1211 modf + REQ-ML-1220 fmin + REQ-ML-1230 fmin + REQ-ML-1232 fmin + REQ-ML-1240 fmax + REQ-ML-1250 fmax + REQ-ML-1252 fmax + REQ-ML-1260 hypot + REQ-ML-1270 hypot + REQ-ML-1271 hypot + REQ-ML-1300 isfinite + REQ-ML-1320 isinf + REQ-ML-1340 isnan + REQ-ML-1360 signbit + REQ-ML-1380 copysign + REQ-ML-1381 copysign + REQ-ML-1499 :ref:`Software Design - General ` + REQ-ML-1500 :ref:`Software Design - General ` + REQ-ML-1501 :ref:`Software Design - General ` + REQ-ML-1502 :ref:`Software Design - General ` + REQ-ML-1504 :ref:`Software Design - General ` + REQ-ML-1600 all + REQ-ML-1800 all + REQ-ML-1900 all + REQ-ML-1901 :ref:`Makefile`/:ref:`configure` + REQ-ML-2000 all + REQ-ML-2100 sinh + REQ-ML-2110 sinh + REQ-ML-2120 sinh + REQ-ML-2140 sinh + REQ-ML-2200 cosh + REQ-ML-2210 cosh + REQ-ML-2220 cosh + REQ-ML-2240 cosh + REQ-ML-2300 cbrt + REQ-ML-2310 cbrt + REQ-ML-2320 cbrt + REQ-ML-2340 cbrt + REQ-ML-2500 expm1 + REQ-ML-2500 fma + REQ-ML-2510 expm1 + REQ-ML-2510 fma + REQ-ML-2520 expm1 + REQ-ML-2520 fma + REQ-ML-2540 expm1 + REQ-ML-2540 tanh + REQ-ML-2550 expm1 + REQ-ML-2550 tanh + REQ-ML-2600 fdim + REQ-ML-2600 tanh + REQ-ML-2610 fdim + REQ-ML-2610 tanh + REQ-ML-2620 asinh + REQ-ML-2620 fdim + REQ-ML-2630 asinh + REQ-ML-2630 fdim + REQ-ML-2640 asinh + REQ-ML-2640 fdim + REQ-ML-2700 asinh + REQ-ML-2700 fma + REQ-ML-2710 acosh + REQ-ML-3010 acosh + REQ-ML-3020 acosh + REQ-ML-3030 acosh + REQ-ML-3040 acosh + REQ-ML-3100 atanh + REQ-ML-3110 atanh + REQ-ML-3120 atanh + REQ-ML-3121 atanh + REQ-ML-3140 atanh + REQ-ML-3141 atanh + REQ-ML-3200 exp2 + REQ-ML-3210 exp2 + REQ-ML-3220 exp2 + REQ-ML-3240 exp2 + REQ-ML-3250 exp2 + REQ-ML-3300 log2 + REQ-ML-3310 log2 + REQ-ML-3320 log2 + REQ-ML-3330 log2 + REQ-ML-3340 log2 + REQ-ML-3350 log2 + REQ-ML-3400 log1p + REQ-ML-3410 log1p + REQ-ML-3420 log1p + REQ-ML-3430 log1p + REQ-ML-3440 log1p + REQ-ML-3450 log1p + REQ-ML-3500 logb + REQ-ML-3510 logb + REQ-ML-3520 logb + REQ-ML-3540 logb + REQ-ML-3600 erf + REQ-ML-3610 erf + REQ-ML-3620 erf + REQ-ML-3630 erf + REQ-ML-3640 erf + REQ-ML-3700 erfc + REQ-ML-3710 erfc + REQ-ML-3720 erfc + REQ-ML-3730 erfc + REQ-ML-3740 erfc + REQ-ML-3800 lgamma + REQ-ML-3810 lgamma + REQ-ML-3820 lgamma + REQ-ML-3830 lgamma + REQ-ML-3840 lgamma + REQ-ML-3850 lgamma + REQ-ML-3850 signgam + REQ-ML-3900 remainder + REQ-ML-3910 remainder + REQ-ML-3920 remainder + REQ-ML-3940 remainder + REQ-ML-4000 frexp + REQ-ML-4010 frexp + REQ-ML-4020 frexp + REQ-ML-4040 frexp + REQ-ML-4100 ldexp + REQ-ML-4110 ldexp + REQ-ML-4120 ldexp + REQ-ML-4130 ldexp + REQ-ML-4140 ldexp + REQ-ML-4200 scalbn + REQ-ML-4210 scalbn + REQ-ML-4220 scalbn + REQ-ML-4230 scalbn + REQ-ML-4240 scalbn + REQ-ML-4250 scalbln + REQ-ML-4300 ilogb + REQ-ML-4310 ilogb + REQ-ML-4320 ilogb + REQ-ML-4340 ilogb + REQ-ML-4400 nan + REQ-ML-4500 nearbyint + REQ-ML-4510 nearbyint + REQ-ML-4520 nearbyint + REQ-ML-4540 nearbyint + REQ-ML-4600 rint + REQ-ML-4610 rint + REQ-ML-4620 rint + REQ-ML-4640 rint + REQ-ML-4650 lrint + REQ-ML-4653 lrint + REQ-ML-4656 lrint + REQ-ML-4659 lrint + REQ-ML-4662 lrint + REQ-ML-4670 llrint + REQ-ML-4700 nextafter + REQ-ML-4710 nextafter + REQ-ML-4720 nextafter + REQ-ML-4731 nextafter + REQ-ML-4740 nextafter + REQ-ML-4741 nextafter + REQ-ML-4750 nexttoward + REQ-ML-4900 isunordered + REQ-ML-4910 isunordered + REQ-ML-5000 isgreater + REQ-ML-5010 isgreater + REQ-ML-5100 isgreaterequal + REQ-ML-5110 isgreaterequal + REQ-ML-5200 isless + REQ-ML-5210 isless + REQ-ML-5300 islessequal + REQ-ML-5310 islessequal + REQ-ML-5400 islessgreater + REQ-ML-5410 islessgreater + REQ-ML-5500 isnormal + REQ-ML-5600 remquo + REQ-ML-5601 remquo + REQ-ML-5620 remquo + REQ-ML-5620 remquo + REQ-ML-5640 remquo + REQ-ML-5700 fpclassify + REQ-ML-5800 tgamma + REQ-ML-5810 tgamma + REQ-ML-5820 tgamma + REQ-ML-5830 tgamma + REQ-ML-5840 tgamma + REQ-ML-5841 tgamma + REQ-ML-6000 cacos + REQ-ML-6100 casin + REQ-ML-6200 catan + REQ-ML-6300 ccos + REQ-ML-6400 csin + REQ-ML-6500 ctan + REQ-ML-6600 cacosh + REQ-ML-6700 casinh + REQ-ML-6800 catanh + REQ-ML-6900 ccosh + REQ-ML-7000 csinh + REQ-ML-7100 ctanh + REQ-ML-7200 cexp + REQ-ML-7300 clog + REQ-ML-7400 cabs + REQ-ML-7500 cpow + REQ-ML-7600 csqrt + REQ-ML-7700 carg + REQ-ML-7800 cimag + REQ-ML-7900 cmplx + REQ-ML-8000 conj + REQ-ML-8100 cproj + REQ-ML-8200 creal + REQ-ML-8300 lround + REQ-ML-8310 lround + REQ-ML-8320 lround + REQ-ML-8330 lround + REQ-ML-8340 lround + REQ-ML-8400 llround + REQ-ML-8500 j0 + REQ-ML-8510 j0 + REQ-ML-8520 j0 + REQ-ML-8530 j1 + REQ-ML-8540 j1 + REQ-ML-8550 j1 + REQ-ML-8560 jn + REQ-ML-8570 jn + REQ-ML-8580 jn + REQ-ML-8600 y0 + REQ-ML-8601 y0 + REQ-ML-8605 y0 + REQ-ML-8610 y0 + REQ-ML-8620 y0 + REQ-ML-8621 y0 + REQ-ML-8630 y1 + REQ-ML-8631 y1 + REQ-ML-8635 y1 + REQ-ML-8640 y1 + REQ-ML-8650 y1 + REQ-ML-8651 y1 + REQ-ML-8660 yn + REQ-ML-8661 yn + REQ-ML-8665 yn + REQ-ML-8670 yn + REQ-ML-8680 yn + REQ-ML-8681 yn + REQ-ML-8700 :ref:`fenv ` + REQ-ML-8800 :ref:`tgmath ` + ============== ========================================== diff --git a/libm/libmcs/doc/sdd/conf.py b/libm/libmcs/doc/sdd/conf.py new file mode 100644 index 00000000..d310fae8 --- /dev/null +++ b/libm/libmcs/doc/sdd/conf.py @@ -0,0 +1,84 @@ +# Configuration file for the Sphinx documentation builder. +# +# This file only contains a selection of the most common options. For a +# full list see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Path setup ------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another +# directory, add these directories to sys.path here. If the directory is +# relative to the documentation root, use os.path.abspath to make it +# absolute, like shown here. +# +import os +import sys +from shutil import copyfile +import sphinx_rtd_theme # pylint: disable=unused-import +from sphinx.errors import ConfigError + +sys.path.insert(0, os.path.abspath("..")) + +# -- Project information ---------------------------------------------- + +project = "LibmCS - SDD" +copyright = "2025, GTD GmbH" +author = "GTD GmbH" + + +# -- General configuration -------------------------------------------- + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + "matplotlib.sphinxext.plot_directive", + "sphinx.ext.autodoc", + "sphinx.ext.autosectionlabel", + "sphinx.ext.mathjax", + "sphinx-mathjax-offline", + "sphinx_rtd_theme", + "hawkmoth", +] + +# Figures are referenced by number +numfig = True + +# Configuration for hawkmoth +hawkmoth_clang = ["-Ilibm/include", "-Isw-quality/dummy_includes"] +hawkmoth_root = os.path.abspath("../../libm") + +# Add any paths that contain templates here, relative to this directory. +templates_path = ["../_templates"] + +# -- Options for HTML output ------------------------------------------ + +# The theme to use for HTML and HTML Help pages. See the documentation +# for a list of builtin themes. +# +html_theme = "sphinx_rtd_theme" + +html_theme_options = { + "collapse_navigation": False, + "logo_only": True, +} + +html_logo = "../logo/libmcs-logo.png" +html_favicon = "../logo/libmcs-favicon.ico" + +# Add any paths that contain custom static files (such as style sheets) +# here, relative to this directory. They are copied after the builtin +# static files, so a file named "default.css" will overwrite the builtin +# "default.css". +html_static_path = ["../_static"] + +html_css_files = ["css/custom.css"] + +html_context = { + "display_gitlab": True, # Integrate Gitlab + "gitlab_host": "gitlab.com", + "gitlab_user": "gtd-gmbh", # Organization or User + "gitlab_repo": "libmcs", # Repo name + "gitlab_version": "development", # Version + "conf_py_path": "/doc/sdd/", # Path in the checkout to the docs root +} diff --git a/libm/libmcs/doc/sdd/index.rst b/libm/libmcs/doc/sdd/index.rst new file mode 100644 index 00000000..dd3ec3ef --- /dev/null +++ b/libm/libmcs/doc/sdd/index.rst @@ -0,0 +1,18 @@ +Mathematical Library for Critical Systems +========================================== + +The LibmCS library has been developed by re-engineering the ``libm`` included in the ``Newlib`` library version 4.0.0. The work has been carried out under ESA Contract No. 4000130278/20/NL/AS. + +The following pages in this documentation try to give a xenodochial introduction into LibmCS with focus on the software design. + +.. toctree:: + :numbered: + :maxdepth: 4 + :caption: Software Design Document + + 1_Introduction + 2_Applicable_and_Reference_Documents + 3_Abbreviations + 4_Software_Design_Overview + 5_Software_Design/0_Software_Design + 6_Requirements_to_Design_Components_Traceability diff --git a/libm/libmcs/doc/sum/10_Bindings.rst b/libm/libmcs/doc/sum/10_Bindings.rst new file mode 100644 index 00000000..d2e1e2eb --- /dev/null +++ b/libm/libmcs/doc/sum/10_Bindings.rst @@ -0,0 +1,179 @@ +Bindings for LibmCS +=================== + +.. raw:: html + + + +To enable the usage of the library from Matlab and using the Ada programming language we wish to provide some best practices and examples. This will cover the usage of library functions, but not the macros and constants as those are not directly accessible, they can however be easily wrapped with C-functions that return the result/value of the macros and constants. These functions can then be placed into Matlab/Ada the same as all other functions. + +Matlab +~~~~~~ + +This section describes the best practice to use the library from within Matlab using the sine function as an example. + +.. _BindingsMatlabGCC: + +Wrapper for GCC +^^^^^^^^^^^^^^^ + +Verify that your system has a working :ref:`GCC ` toolchain. Officially supported by Matlab is :ref:`GCC ` 4.9, but newer versions seem to work as well (at least for this example). Next, create a file named ``gcc`` with the following content: + +.. code-block:: bash + + #!/bin/bash + + /usr/bin/gcc $(echo $@ | sed 's/-lm //g') + +Place this script in your path before the real :ref:`GCC ` and check that ``which gcc`` in your shell returns the path to this script instead of the real :ref:`GCC `: + +.. code-block:: bash + + % which gcc + + /home//bin/gcc + +This strips ``-lm``, the default math library from the :ref:`GCC ` command line which allows to use the library's ``libm.a`` instead. Now start Matlab. + +Wrapper for a C Function +^^^^^^^^^^^^^^^^^^^^^^^^ + +Create a wrapper for the :ref:`sin` function available in the library's ``libm.a``. Name the file ``libmcs_sin.m`` and fill it with this content: + +.. code-block:: matlab + + function y = libmcs_sin(u) + + y = 0.0; + + y = coder.ceval('sin', u); + +Using the C Function Wrapper from Matlab +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The wrapper cannot be called directly because ``ceval`` cannot be called from Matlab. Thus it is necessary to generate a MEX function from this wrapper with ``codegen``. Generate and compile the code with the following command: + +.. code-block:: matlab + + codegen -config:mex -args 0.0 -o libmcs_sin ../libmcs/build-/bin/libm.a libmcs_sin + +Then calling the C function is possible from Matlab as one would expect. Matlab automatically uses the generated MEX function instead of the ``.m`` function: + +.. code-block:: matlab + + >> libmcs_sin(3.14) + + ans = + + 0.0016 + +After all MEX functions are generated, remove the :ref:`GCC ` wrapper created in :ref:`BindingsMatlabGCC`. Otherwise you may not be able to build other software correctly. + +Using the Wrapper from Simulink +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Create a new Model. Go to ``Simulation -> Model Configuration Parameters -> Simulation Target``. Under ``Additional Build Information -> Libraries`` enter the path to the library's ``libm.a``. In the reserved name field enter the function which shall not be used from the default libm, in this example ``sin``. The options are shown in the figure: + +.. raw:: html + + + +Go to ``Simulation -> Model Configuration Parameters -> Code Generation -> Custom Code`` and check the checkbox reading "Use the same custom code settings as simulation target". The options are shown in the figure: + +.. raw:: html + + + +Now add a Constant Block, a Matlab Function Block and a Scope Block to your model, so it looks like shown in the figure: + +.. raw:: html + + + +Double-click the Matlab Function Block and type in your Matlab Code calling the previously defined Wrapper: + +.. code-block:: matlab + + function y = fcn(u) + + y = libmcs_sin(u); + +You can now run your model as usual or use code generation. + +Verify that the Correct Function is Called +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +If you want to check whether the correct function is called, go to the library source code and edit the file ``libm/mathd/sind.c``. Change the sin function to return an arbitrary, but fixed value by inserting a ``return 99;`` statement right at the beginning of the function. After recompiling the library, as well as the MEX and S-functions, using the libmcs_sin function in Matlab and Simulink should then return ``99`` for all input values. This proves that the library's :ref:`sin` function is called and not the one from standard libm. + +Ada +~~~ + +This section describes the best practice to use the library as part of the Ada programming language using the sine function as an example. + +Create Bindings for Functions +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +For function bindings first create a thin binding that uses C-type input and output objects, then create a thick binding to convert the C-types to Ada-types. The following two example files contain some more description in the form of comments. + +.. code-block:: ada + + with Interfaces.C; + + -- This package contains thin & thick bindings for the mathematical functions + -- as defined in Ada LRM Annex A.5.1. + package LIBMCS.Elementary_Functions is + + -- Declaration of the thick binding function that should + -- be used to call 'sinf'. This function converts the Math_Float to the + -- appropriate C types and calls 'c_sinf' that is declared in + -- the private part of this package. + function Sinf (X : Math_Float) return Math_Float; + + -- ... More functions see Ada LRM Annex A.5.1 + + private + use Interfaces.C; + + -- The thin binding declaration for 'sinf'. + function c_sinf (X : c_float) return c_float; + + -- This import pragma tells the compiler to substitute calls to 'c_sinf' + -- with appropriate calls to the C function 'sinf' + -- This pragma could be an aspect in Ada2012. + pragma Import (Convention => C, + Entity => c_sinf, + External_Name => "sinf"); + + end LIBMCS.Elementary_Functions; + +.. code-block:: ada + + -- Implementation file for the LIBMCS.Elementary_Functions package. + package body LIBMCS.Elementary_Functions is + use Interfaces.C; + + -- Thick binding for 'sinf'. This function converts the argument given as + -- the native Ada type 'Math_Float' to the appropriate C type. + -- This function can be responsible for additional range/boundary checking + -- and raise exceptions if invalid values are provided. + -- The function also converts the return value of 'sinf' from the C type to + -- the native Ada type. + function Sinf (X : Math_Float) return Math_Float is + c_X : c_float := c_float (X); + Sine : c_float; + begin + Sine := c_sinf (c_X); + return Math_Float (Sine); + end Sinf; + + -- ... More functions see Ada LRM Annex A.5.1 + + end LIBMCS.Elementary_Functions; diff --git a/libm/libmcs/doc/sum/1_Abbreviations.rst b/libm/libmcs/doc/sum/1_Abbreviations.rst new file mode 100644 index 00000000..f2d094af --- /dev/null +++ b/libm/libmcs/doc/sum/1_Abbreviations.rst @@ -0,0 +1,112 @@ +.. _ABBR: + +Terms, Definitions and Abbreviated Terms +======================================== + +.. raw:: html + + + +Agency + refers to :ref:`ESA ` + +BSP + Board Support Package + +CPU + Central Processing Unit + +DAZ + Denormals are Zero (see also :ref:`FTZ `) + +denormal + See subnormal. + +DRD + Document Requirements Definition + +ECSS + European Cooperation for Space Standardization + +ESA + European Space Agency + +FMA + Fused-Multiply-Add + +FPU + Floating Point Unit + +FSR + :ref:`FPU ` State Register + +FTZ + Flush to Zero (see also :ref:`DAZ `) + +GCC + :ref:`GNU ` Compiler Collection + +GNU + recursive acronym for "GNU's Not Unix!", GNU is an extensive collection of free software which can be used as (or as part of) an operating system + +ICD + Interface Control Document + +IEEE + Institute of Electrical and Electronics Engineers + +ISO + International Organization for Standardization + +OS + Operating System + +POSIX + Portable Operating System Interface + +PSR + Processor State Register + +QG + Qualification Guideline + +RAM + Random Access Memory + +RTEMS + Real-Time Executive for Multiprocessor Systems + +SCF + Software Configuration File + +SDD + Software Design Document + +SPDX + Software Package Data Exchange + +SRF + Software Reuse File + +SRS + Software Requirements Specification + +subnormal + See IEEE-754 standard for the definition. + +SUITR + Software Unit- and Integration-Test Report + +SValR + Software Validation-Test Report + +SVR + Software Verification Report + +ULP + Unit in the Last Place + +YAML + YAML Ain't Markup Language (formerly: Yet Another Markup Language) diff --git a/libm/libmcs/doc/sum/2_Conventions.rst b/libm/libmcs/doc/sum/2_Conventions.rst new file mode 100644 index 00000000..b009841c --- /dev/null +++ b/libm/libmcs/doc/sum/2_Conventions.rst @@ -0,0 +1,39 @@ +Conventions +=========== + +This chapter lists the symbols, stylistic conventions, and command syntax used in this document. Each convention is identified by a name and described by an example and the additional +explanation. + +.. table:: Notation conventions + :width: 100% + + +---------------------------+---------------------------+----------------------------------------------------------+ + | Convention | Example | Explanation | + +===========================+===========================+==========================================================+ + | Pi | :math:`\pi` | The mathematical constant :math:`\pi` | + +---------------------------+---------------------------+----------------------------------------------------------+ + | Not a Number | NaN or ``NaN`` | Representation for "not a number"-value | + +---------------------------+---------------------------+----------------------------------------------------------+ + | Quiet NaN | qNaN, ``qNaN`` | Representation for "quiet not a number"-value | + +---------------------------+---------------------------+----------------------------------------------------------+ + | Signalling NaN | sNaN, ``sNaN`` | Representation for "signalling not a number"-value | + +---------------------------+---------------------------+----------------------------------------------------------+ + | Signed NaN | +NaN or -NaN | Representation for "not a number"-value, that explicitly | + | | | has the signbit unset/set. This definition does not | + | | | exist within the IEEE-754 standard and is added for | + | | | better readability of the table | + +---------------------------+---------------------------+----------------------------------------------------------+ + | Infinity | +/-Inf or ±Inf | Representation for an Infinity value | + +---------------------------+---------------------------+----------------------------------------------------------+ + | File | ``k_sin.c`` | Indication of a code file | + +---------------------------+---------------------------+----------------------------------------------------------+ + | Source Code | ``sin(double x)`` | Indication of code | + +---------------------------+---------------------------+----------------------------------------------------------+ + | Constants | ``M_PI``, ``FLT_MAX`` | Indication of code | + +---------------------------+---------------------------+----------------------------------------------------------+ + +We define the set of all floating-point numbers as :math:`\mathbb{F}` and the set of all subnormal numbers as :math:`\mathbb{S}` to be used in mathematical formulae. The set of floating-point numbers :math:`\mathbb{F}` contains all floating-point numbers, that is normals, subnormals (therefore :math:`\mathbb{S} \subset \mathbb{F}`), zeroes, infinities and ``NaN``, of the type given by the context. If a reduction to a specific type is needed, this will be indicated as follows: :math:`\mathbb{F}_s` for single precision, :math:`\mathbb{F}_d` for double precision, and :math:`\mathbb{F}_{ld}` for long double precision. The same will be done for :math:`\mathbb{S}` with :math:`\mathbb{S}_s`, :math:`\mathbb{S}_d`, and :math:`\mathbb{S}_{ld}` respectively. Furthermore :math:`\mathbb{F}^{+}` symbolizes all floating-point numbers where the sign bit is not set, while :math:`\mathbb{F}^{-}` contains all those where the sign bit is set (this includes :math:`-0.0`, ``-Inf``, and ``NaNs`` where the signbit is set). Using these sets we are able to express floating-point numbers in mathematical formulae, for example the formula :math:`x \in \mathbb{F} \setminus \left \{ \pm \text{Inf}, \text{NaN} \right \}` denotes that `x` is a floating-point number that is neither infinity nor ``NaN``, which leaves `x` to be either zero, a normal or a subnormal number. :math:`\mathbb{F}` cannot be fully represented by conventional number classifications due to the introduction of :math:`\pm 0.0`, explicit infinities and ``NaNs``, however the following is valid: :math:`(\mathbb{F} \setminus \left \{ -0.0, \pm \text{Inf}, \text{NaN} \right \}) \subset \mathbb{Q}`. + +Similarly we define the set of all 32bit integer numbers as :math:`\mathbb{I}`. :math:`\mathbb{I}` is a subset of :math:`\mathbb{Z}` limited by the size of the integer, therefore :math:`\mathbb{I} \subset \mathbb{Z}`. The same concept applies for :math:`\mathbb{I}_{l}` which represents either 32bit or 64bit integer numbers depending on the size of ``long int``, and :math:`\mathbb{I}_{ll}` which represents 64bit integer numbers. + +To denote the similarity, but not always equality, between the mathematical function and its representing procedure we use :math:`\approx` where appropriate. This is not used if a procedure is able to exactly mimic the functionality of the mathematical function. diff --git a/libm/libmcs/doc/sum/3_Purpose_of_the_Software.rst b/libm/libmcs/doc/sum/3_Purpose_of_the_Software.rst new file mode 100644 index 00000000..cbd93ddf --- /dev/null +++ b/libm/libmcs/doc/sum/3_Purpose_of_the_Software.rst @@ -0,0 +1,318 @@ +Purpose of the Software +======================= + +The software in this project is intended to be included in other software projects. It is designed +and developed to be integrated in other software projects up to criticality B. + +The library contains the following procedures which can be included with ``math.h`` (these lists only contain the name of the ``double`` procedure, you can expect all procedures (except for the Bessel functions) to have versions for ``float`` suffixed with ``f`` and ``long double`` suffixed with ``l`` (note however that ``long double`` only exists when it has the same size as ``double``)): + +.. table:: List of all procedures in math.h + :name: List of math procedures + + +--------------------+-----------------------------------------------------------+ + | Procedure | Description | + +====================+===========================================================+ + | ``fpclassify`` | Procedure returning the classification of the argument | + +--------------------+-----------------------------------------------------------+ + | ``isfinite`` | Procedure returning whether the value of the argument is | + | | finite or not (not :math:`±Inf` and not :math:`NaN`) | + +--------------------+-----------------------------------------------------------+ + | ``isinf`` | Procedure returning whether the value of the argument is | + | | positive or negative Infinity or not | + +--------------------+-----------------------------------------------------------+ + | ``isnan`` | Procedure returning whether the argument is a | + | | :math:`NaN` floating-point value or not | + +--------------------+-----------------------------------------------------------+ + | ``isnormal`` | Procedure returning whether the argument is a normal | + | | floating-point value or not | + +--------------------+-----------------------------------------------------------+ + | ``signbit`` | Procedure returning whether the argument is negative or | + | | not | + +--------------------+-----------------------------------------------------------+ + | ``acos`` | Procedure returning the trigonometric arccosine | + +--------------------+-----------------------------------------------------------+ + | ``asin`` | Procedure returning the trigonometric arcsine | + +--------------------+-----------------------------------------------------------+ + | ``atan`` | Procedure returning the trigonometric arctangent | + +--------------------+-----------------------------------------------------------+ + | ``atan2`` | Procedure returning the trigonometric arctangent of | + | | :math:`\frac{y}{x}` | + +--------------------+-----------------------------------------------------------+ + | ``cos`` | Procedure returning the trigonometric cosine | + +--------------------+-----------------------------------------------------------+ + | ``sin`` | Procedure returning the trigonometric sine | + +--------------------+-----------------------------------------------------------+ + | ``tan`` | Procedure returning the trigonometric tangent | + +--------------------+-----------------------------------------------------------+ + | ``acosh`` | Procedure returning the hyperbolic arccosine | + +--------------------+-----------------------------------------------------------+ + | ``asinh`` | Procedure returning the hyperbolic arcsine | + +--------------------+-----------------------------------------------------------+ + | ``atanh`` | Procedure returning the hyperbolic arctangent | + +--------------------+-----------------------------------------------------------+ + | ``cosh`` | Procedure returning the hyperbolic cosine | + +--------------------+-----------------------------------------------------------+ + | ``sinh`` | Procedure returning the hyperbolic sine | + +--------------------+-----------------------------------------------------------+ + | ``tanh`` | Procedure returning the hyperbolic tangent | + +--------------------+-----------------------------------------------------------+ + | ``exp`` | Procedure returning the base :math:`e` exponential of | + | | :math:`x` | + +--------------------+-----------------------------------------------------------+ + | ``exp2`` | Procedure returning the base :math:`2` exponential of | + | | :math:`x` | + +--------------------+-----------------------------------------------------------+ + | ``expm1`` | Procedure returning the base :math:`e` exponential of | + | | :math:`x` minus :math:`1` | + +--------------------+-----------------------------------------------------------+ + | ``frexp`` | Procedure breaking :math:`x` into a normalized fraction | + | | and an integral power of :math:`2` | + +--------------------+-----------------------------------------------------------+ + | ``ilogb`` | Procedure returning the binary exponent of :math:`x` as | + | | integer | + +--------------------+-----------------------------------------------------------+ + | ``ldexp`` | Procedure returning :math:`x` multiplied by an integral | + | | power of :math:`2` | + +--------------------+-----------------------------------------------------------+ + | ``log`` | Procedure returning the natural logarithm | + +--------------------+-----------------------------------------------------------+ + | ``log10`` | Procedure returning the base :math:`10` logarithm | + +--------------------+-----------------------------------------------------------+ + | ``log1p`` | Procedure returning the natural logarithm of | + | | :math:`x + 1` | + +--------------------+-----------------------------------------------------------+ + | ``log2`` | Procedure returning the base :math:`2` logarithm | + +--------------------+-----------------------------------------------------------+ + | ``logb`` | Procedure returning the binary exponent of :math:`x` | + +--------------------+-----------------------------------------------------------+ + | ``modf`` | Procedure breaking :math:`x` in its integral and | + | | fractional part | + +--------------------+-----------------------------------------------------------+ + | ``scalbn`` | Procedure returning :math:`x` multiplied by an integral | + | | power of :math:`2` | + +--------------------+-----------------------------------------------------------+ + | ``scalbln`` | Procedure returning :math:`x` multiplied by an integral | + | | power of :math:`2` | + +--------------------+-----------------------------------------------------------+ + | ``cbrt`` | Procedure returning the cubic root | + +--------------------+-----------------------------------------------------------+ + | ``fabs`` | Procedure returning the absolute value | + +--------------------+-----------------------------------------------------------+ + | ``hypot`` | Procedure returning the square root of :math:`x^2+y^2` | + +--------------------+-----------------------------------------------------------+ + | ``pow`` | Procedure returning :math:`x` raised to the power of | + | | :math:`y` | + +--------------------+-----------------------------------------------------------+ + | ``sqrt`` | Procedure returning the square root | + +--------------------+-----------------------------------------------------------+ + | ``erf`` | Procedure returning the error function | + +--------------------+-----------------------------------------------------------+ + | ``erfc`` | Procedure returning the complementary error function | + | | (``erfc`` = :math:`1 -` ``erf``) | + +--------------------+-----------------------------------------------------------+ + | ``lgamma`` | Procedure returning the natural logarithm of the absolute | + | | value of gamma of :math:`x` | + +--------------------+-----------------------------------------------------------+ + | ``tgamma`` | Procedure returning gamma function of :math:`x` | + +--------------------+-----------------------------------------------------------+ + | ``ceil`` | Procedure for rounding upwards to the nearest integer | + +--------------------+-----------------------------------------------------------+ + | ``floor`` | Procedure for rounding downwards to the nearest integer | + +--------------------+-----------------------------------------------------------+ + | ``nearbyint`` | Procedure for rounding to the nearest integer using the | + | | current rounding direction | + +--------------------+-----------------------------------------------------------+ + | ``rint`` | Procedure for rounding to the nearest integer using the | + | | current rounding direction (raises inexact) | + +--------------------+-----------------------------------------------------------+ + | ``lrint`` | Procedure for rounding to the nearest integer using the | + | | current rounding direction | + +--------------------+-----------------------------------------------------------+ + | ``llrint`` | Procedure for rounding to the nearest integer using the | + | | current rounding direction | + +--------------------+-----------------------------------------------------------+ + | ``round`` | Procedure for rounding to the nearest integer (Halfway | + | | values rounded away from :math:`0`) | + +--------------------+-----------------------------------------------------------+ + | ``lround`` | Procedure for rounding to the nearest integer (Halfway | + | | values rounded away from :math:`0`) | + +--------------------+-----------------------------------------------------------+ + | ``llround`` | Procedure for rounding to the nearest integer (Halfway | + | | values rounded away from :math:`0`) | + +--------------------+-----------------------------------------------------------+ + | ``trunc`` | Procedure for rounding towards :math:`0` to the nearest | + | | integer | + +--------------------+-----------------------------------------------------------+ + | ``fmod`` | Procedure returning the floating-point remainder of | + | | :math:`\frac{y}{x}` (rounded towards zero) | + +--------------------+-----------------------------------------------------------+ + | ``remainder`` | Procedure returning the floating-point remainder of | + | | :math:`\frac{y}{x}` (rounded to nearest integral value) | + +--------------------+-----------------------------------------------------------+ + | ``remquo`` | Procedure returning the same value as ``remainder`` and | + | | puts the quotient in :math:`*quo` | + +--------------------+-----------------------------------------------------------+ + | ``copysign`` | Procedure returning a floating-point number with the | + | | magnitude of :math:`x` and the sign of :math:`y` | + +--------------------+-----------------------------------------------------------+ + | ``nan`` | Procedure returning a :math:`NaN` | + +--------------------+-----------------------------------------------------------+ + | ``nextafter`` | Procedure returning the next floating-point value after | + | | :math:`x` in direction of :math:`y` | + +--------------------+-----------------------------------------------------------+ + | ``nexttoward`` | Procedure returning the next floating-point value after | + | | :math:`x` in direction of :math:`y` | + +--------------------+-----------------------------------------------------------+ + | ``fdim`` | Procedure returning the positive difference between the | + | | arguments | + +--------------------+-----------------------------------------------------------+ + | ``fmax`` | Procedure returning the larger of two values | + +--------------------+-----------------------------------------------------------+ + | ``fmin`` | Procedure returning the smaller of two values | + +--------------------+-----------------------------------------------------------+ + | ``fma`` | Procedure returning the result of :math:`x \cdot y + z` | + +--------------------+-----------------------------------------------------------+ + | ``isgreater`` | Procedure returning whether :math:`x` is greater than | + | | :math:`y` | + +--------------------+-----------------------------------------------------------+ + | ``isgreaterequal`` | Procedure returning whether :math:`x` is greater than or | + | | equal to :math:`y` | + +--------------------+-----------------------------------------------------------+ + | ``isless`` | Procedure returning whether :math:`x` is less than | + | | :math:`y` | + +--------------------+-----------------------------------------------------------+ + | ``islessequal`` | Procedure returning whether :math:`x` is less than or | + | | equal to :math:`y` | + +--------------------+-----------------------------------------------------------+ + | ``islessgreater`` | Procedure returning whether :math:`x` is less or greater | + | | than :math:`y` | + +--------------------+-----------------------------------------------------------+ + | ``isunordered`` | Procedure returning whether the arguments are unordered | + | | (aka at least one is :math:`NaN`) | + +--------------------+-----------------------------------------------------------+ + | ``j0`` | Procedure returning the Bessel value of :math:`x` of the | + | | first kind of order :math:`0` | + +--------------------+-----------------------------------------------------------+ + | ``j1`` | Procedure returning the Bessel value of :math:`x` of the | + | | first kind of order :math:`1` | + +--------------------+-----------------------------------------------------------+ + | ``jn`` | Procedure returning the Bessel value of :math:`x` of the | + | | first kind of order :math:`n` | + +--------------------+-----------------------------------------------------------+ + | ``y0`` | Procedure returning the Bessel value of :math:`x` of the | + | | second kind of order :math:`0` | + +--------------------+-----------------------------------------------------------+ + | ``y1`` | Procedure returning the Bessel value of :math:`x` of the | + | | second kind of order :math:`1` | + +--------------------+-----------------------------------------------------------+ + | ``yn`` | Procedure returning the Bessel value of :math:`x` of the | + | | second kind of order :math:`n` | + +--------------------+-----------------------------------------------------------+ + +Additionally ``complex.h`` includes the following procedures: + +.. table:: List of all procedures in complex.h + :name: List of complex procedures + + +--------------------+-----------------------------------------------------------+ + | Procedure | Description | + +====================+===========================================================+ + | ``cacos`` | Procedure returning the complex trigonometric arccosine | + +--------------------+-----------------------------------------------------------+ + | ``casin`` | Procedure returning the complex trigonometric arcsine | + +--------------------+-----------------------------------------------------------+ + | ``catan`` | Procedure returning the complex trigonometric arctangent | + +--------------------+-----------------------------------------------------------+ + | ``ccos`` | Procedure returning the complex trigonometric cosine | + +--------------------+-----------------------------------------------------------+ + | ``csin`` | Procedure returning the complex trigonometric sine | + +--------------------+-----------------------------------------------------------+ + | ``ctan`` | Procedure returning the complex trigonometric tangent | + +--------------------+-----------------------------------------------------------+ + | ``cacosh`` | Procedure returning the complex hyperbolic arccosine | + +--------------------+-----------------------------------------------------------+ + | ``casinh`` | Procedure returning the complex hyperbolic arcsine | + +--------------------+-----------------------------------------------------------+ + | ``catanh`` | Procedure returning the complex hyperbolic arctangent | + +--------------------+-----------------------------------------------------------+ + | ``ccosh`` | Procedure returning the complex hyperbolic cosine | + +--------------------+-----------------------------------------------------------+ + | ``csinh`` | Procedure returning the complex hyperbolic sine | + +--------------------+-----------------------------------------------------------+ + | ``ctanh`` | Procedure returning the complex hyperbolic tangent | + +--------------------+-----------------------------------------------------------+ + | ``cexp`` | Procedure returning the complex base :math:`e` | + | | exponential of :math:`z` | + +--------------------+-----------------------------------------------------------+ + | ``clog`` | Procedure returning the complex natural logarithm | + +--------------------+-----------------------------------------------------------+ + | ``cabs`` | Procedure returning the complex absolute value | + +--------------------+-----------------------------------------------------------+ + | ``cpow`` | Procedure returning the complex value :math:`x` raised to | + | | the power of :math:`y` | + +--------------------+-----------------------------------------------------------+ + | ``csqrt`` | Procedure returning the complex square root | + +--------------------+-----------------------------------------------------------+ + | ``carg`` | Procedure returning the value of :math:`z` in the | + | | interval [:math:`-\pi`, :math:`+\pi`] | + +--------------------+-----------------------------------------------------------+ + | ``cimag`` | Procedure returning the imaginary part of the value of | + | | :math:`z` | + +--------------------+-----------------------------------------------------------+ + | ``CMPLX`` | Procedure returning the complex value with real part | + | | :math:`x` and imaginary part :math:`y` | + +--------------------+-----------------------------------------------------------+ + | ``conj`` | Procedure returning the complex conjugate value of | + | | :math:`z` | + +--------------------+-----------------------------------------------------------+ + | ``cproj`` | Procedure returning the value of the projection onto the | + | | Riemann sphere of :math:`z` | + +--------------------+-----------------------------------------------------------+ + | ``creal`` | Procedure returning the real part of the value of | + | | :math:`z` | + +--------------------+-----------------------------------------------------------+ + +Furthermore the library provides a number of constants, as part of ``math.h``: + +.. table:: List of all constant defines in math.h + :name: List of math constants + + ===================== =============================================== + Name Description + ===================== =============================================== + ``M_E`` Value of :math:`e` + ``M_LOG2E`` Value of :math:`log_{2} e` + ``M_LOG10E`` Value of :math:`log_{10} e` + ``M_LN2`` Value of :math:`log_e 2` + ``M_LN10`` Value of :math:`log_e 10` + ``M_PI`` Value of :math:`\pi` + ``M_PI_2`` Value of :math:`\frac{\pi}{2}` + ``M_PI_4`` Value of :math:`\frac{\pi}{4}` + ``M_1_PI`` Value of :math:`\frac{1}{\pi}` + ``M_2_PI`` Value of :math:`\frac{2}{\pi}` + ``M_2_SQRTPI`` Value of :math:`\frac{2}{\sqrt{\pi}}` + ``M_SQRT2`` Value of :math:`\sqrt{2}` + ``M_SQRT1_2`` Value of :math:`\sqrt{\frac{1}{2}}` + ``HUGE_VAL`` Value of :math:`+Inf` (double) + ``HUGE_VALF`` Value of :math:`+Inf` (float) + ``HUGE_VALL`` Value of :math:`+Inf` (long double) + ``INFINITY`` Value of :math:`+Inf` + ``NAN`` Value of :math:`NaN` + ``MAXFLOAT`` Synonym of ``FLT_MAX`` + ``FP_INFINITE`` :math:`1` + ``FP_NAN`` :math:`0` + ``FP_NORMAL`` :math:`4` + ``FP_SUBNORMAL`` :math:`3` + ``FP_ZERO`` :math:`2` + ``FP_ILOGB0`` Value to return for :ref:`ilogb` (:math:`0`) + ``FP_ILOGBNAN`` Value to return for :ref:`ilogb` (:math:`NaN`) + ``MATH_ERRNO`` :math:`1` + ``MATH_ERREXCEPT`` :math:`2` + ``math_errhandling`` ``MATH_ERREXCEPT`` + ===================== =============================================== + +*Remark:* Both ``INFINITY`` and ``NAN`` expand to floats or doubles depending on the context. + +``math.h`` further declares the types ``double_t`` and ``float_t`` as ``double`` and ``float``. + +``complex.h`` declares the types ``complex``, ``imaginary``, ``_Complex_I``, ``_Imaginary_I`` and ``I`` as ``_Complex``, ``_Imaginary``, ``const float _Complex``, ``const float _Imaginary``, and ``_Complex_I`` respectively. (Note that your toolchain (such as GCC) may not properly implement imaginary types, as such it is likely that all definitions are complex types.) \ No newline at end of file diff --git a/libm/libmcs/doc/sum/4_General_Behaviour.rst b/libm/libmcs/doc/sum/4_General_Behaviour.rst new file mode 100644 index 00000000..fa7fbfd4 --- /dev/null +++ b/libm/libmcs/doc/sum/4_General_Behaviour.rst @@ -0,0 +1,395 @@ +General Behaviour +================= + +All procedures can handle all input values of its respective types, including special values such as ``NaNs`` or infinities. Pointers used to output additional return values are under the user’s control, using misplaced or ``NULL`` pointers may cause unwanted behaviour or even a crash of the system. The ``NULL`` pointers are handled appropriately by the library, but no action can be taken against using misplaced pointers. + +NaN Values +~~~~~~~~~~ + +As can be seen in :ref:`Conventions` there exist different types of ``NaNs``. + +What are they? ``NaN`` is the result of a procedure that does not generate a valid and representable result. This happens for example with :math:`\frac{0.0}{0.0}`, with ``sqrt(-1.0)`` :math:`(= \sqrt{-1})`, or with ``Inf - Inf``, in the first and third cases because the behavior is undefined, in the second because complex/imaginary numbers cannot be represented in the data type of the procedure. ``NaN`` can also be used as an input argument for procedures, in most cases this results in a ``NaN`` return value. + +What's the difference between ``NaN``, ``qNaN`` and ``sNaN``? Both ``qNaNs`` and ``sNaNs`` are a subgroup of all ``NaNs``, they differ in a specific bit that is either set (``qNaN``) or not set (``sNaN``). All procedures will only return ``qNaNs`` and never ``sNaNs``. The difference is on the other side: when an ``sNaN`` is put as an argument to a procedure, the :ref:`FPU ` shall signal an ``invalid operation`` exception, while a ``qNaN`` is quietly accepted, hence the names. As ``sNaNs`` are never produced by the :ref:`FPU ` they can be regarded as a testing feature. + +In :ref:`Conventions` we also differentiate between ``-NaN`` (``NaN`` where the signbit is set) and ``+NaN`` (``NaN`` where the signbit is not set). This separation does not exist anywhere within the :ref:`IEEE-754 ` or C18 standards, ``NaNs`` are simply ``NaNs`` regardless of their sign. We however need this differentiation for the procedures :ref:`signbit` and :ref:`copysign`, as both only check the sign of a value and ignore the rest. + +The ``nan (const char *payload)``, ``nanf (const char *payload)``, and ``nanl (const char *payload)`` functions of the library are not fully ISO C compliant as they return a fix defined ``NaN`` regardless of the function parameter. The rationale for this is to keep the LibmCS standalone, without any dependency to other standard C library functions. A workaround is proposed in the section describing these functions. + +.. _GeneralBehaviourSubnormalValues: + +Subnormal Values +~~~~~~~~~~~~~~~~ + +The library regards subnormals the same as any other value, meaning when a procedure is called with a subnormal input argument, the procedures will do their work just as well as for any non subnormal value. This however only works as expected, if the :ref:`FPU ` in use supports subnormal values. + +In case the :ref:`FPU ` does not fully support subnormals the user should enable the preprocessor define ``LIBMCS_FPU_DAZ`` while running the library's configuration when prompted to make the decision. This forces every input value to first be checked by the :ref:`FPU ` for being a subnormal, and if it is, act according to the implementation of the :ref:`FPU `. This behavior will apply to most of the procedures contained in the library. Exceptions to this behavior being (i.e., the following procedures do correctly handle subnormals even if the FPU has no subnormal support): + +* ``fabs`` and ``fabsf`` +* ``copysign`` and ``copysignf`` +* ``fpclassify`` +* ``isfinite`` +* ``isinf`` +* ``isnan`` +* ``isnormal`` +* ``signbit`` +* ``isunordered`` +* ``isgreater`` (only on GRFPUs before GRFPU5) +* ``isgreaterequal`` (only on GRFPUs before GRFPU5) +* ``isless`` (only on GRFPUs before GRFPU5) +* ``islessequal`` (only on GRFPUs before GRFPU5) +* ``islessgreater`` (only on GRFPUs before GRFPU5) + +In addition to this the following procedures implement a non-standard behavior to ensure that they don't get stuck at subnormals when using them on FPUs without subnormal support (i.e., they jump over the subnormal range): + +* ``nextafter`` and ``nextafterf`` +* ``nexttoward`` and ``nexttowardf`` + +One example of such a non-supporting :ref:`FPU ` is the :ref:`GRFPU ` from CAES/Gaisler. The :ref:`GRFPU ` causes a trap if subnormal numbers occur and the :ref:`GRFPU ` is not configured to use non-standard mode [#]_. If the non-standard mode is enabled however, the :ref:`FPU ` behaves in a :ref:`DAZ ` and :ref:`FTZ ` way. This means when ``LIBMCS_FPU_DAZ`` is defined, every call to the library's procedures with a subnormal input will either cause a trap (in standard mode) or behave as if the input was zero (in non-standard mode). + +If the user's :ref:`FPU ` behaves as the :ref:`GRFPU ` we suggest using the standard mode during production and switching to non-standard mode after sufficient testing (or if the user decides that subnormals are part of normal behaviour). This has the benefit that errors can be found more easily during production (as subnormal numbers in most cases should be an error in the source code), and not causing a trap on the final product in the odd case that a subnormal still appears. + +The following table shows some FPUs, their support regarding subnormal floating-point numbers and the particularities of the supported :ref:`DAZ ` and :ref:`FTZ ` mode: + ++--------------------------+-----------------------+-------------------------------------------------------------+ +| FPU | Subnormal support | Operations not affected by FTZ/DAZ mode | ++==========================+=======================+=============================================================+ +| MEIKO FPU | Yes | Not applicable | ++--------------------------+-----------------------+-------------------------------------------------------------+ +| GRFPU (until v4) | No | compare, move, negate, and absolute value | ++--------------------------+-----------------------+-------------------------------------------------------------+ +| GRFPU-Lite | No | compare, move, negate, and absolute value | ++--------------------------+-----------------------+-------------------------------------------------------------+ +| GRFPU5 | Yes | Not applicable | ++--------------------------+-----------------------+-------------------------------------------------------------+ +| Gaisler NanoFPU | No | compare, move, negate, and absolute value | ++--------------------------+-----------------------+-------------------------------------------------------------+ +| GRFPUnv | Yes | Not applicable | ++--------------------------+-----------------------+-------------------------------------------------------------+ +| ARM FPUs (NEON and VFPU) | Selectable | V{Q}ABS, V{Q}NEG, VMOV, VMVN, VDUP, VLDR VSTR, VLDM, VSTM | ++--------------------------+-----------------------+-------------------------------------------------------------+ +| SiFive FPU | Yes | Not applicable | ++--------------------------+-----------------------+-------------------------------------------------------------+ +| x86 | Selectable | x87 floating point instructions | ++--------------------------+-----------------------+-------------------------------------------------------------+ + +This table is by no means exhaustive and shall only be used for preliminary iformation purposes. The user of the library shall the concretely check the specification of the :ref:`FPU ` as there are may additional particularities to be taken into account. For example we have the particular case of ARM FPUs: + +* NEON and VFPv3 flush-to-zero preserves the sign bit. VFPv2 flush-to-zero flushes to +0. +* NEON always uses flush-to-zero mode. + +.. [#] See `Handling denormalized numbers with the GRFPU `_ Section 4.1 for more information on how to enable non-standard mode on the :ref:`GRFPU `. + +Fused Multiply-Add +~~~~~~~~~~~~~~~~~~ + +The IEEE-754 floating-point arithmetic standard requires since its 2008 version that compliant systems must support the :ref:`FMA ` operation. This operation is also required by the ISO C standard. Older FPUs and the SPARC V8 instruction set however do not support nor require this operation. + +Because of this reason the LibmCS includes the ``fma`` and ``fmaf`` procedures but only with a non-standard conform naive implementation carrying out a multiplication and addition in sequence with two roundings instead of the single rounding step required by the :ref:`FMA ` operation. + +On systems supporting the :ref:`FMA ` operation users can use compiler built-ins to explicitely call ``fma`` if needed. + +Exceptions +~~~~~~~~~~ + +Exceptions raised by the procedures are listed in the :ref:`Reference Manual`. These are in accordance with the :ref:`ISO ` C, :ref:`IEEE-754 ` and :ref:`POSIX ` standards. The :ref:`Reference Manual` will only list the exceptions ``invalid operation``, ``divide by zero`` and ``overflow`` while not stating ``underflow`` and ``inexact``. These are the three exceptions deemed as important in *IEEE 754 Error Handling and Programming Languages* [NM]_. + +The :ref:`POSIX ` standard does not define errors/exceptions for complex procedures. The implementations however make use of multiple non-complex procedures which do raise exceptions. As such the :ref:`Reference Manual` does not list the exceptions thrown by complex procedures, it is assumed that the exceptions of their underlying procedures apply. + +All procedures raise ``invalid operation`` exception when the input argument is ``sNaN`` unless stated otherwise in the :ref:`Reference Manual`. + +.. [NM] *IEEE 754 Error Handling and Programming Languages* by Nick Maclaren. + +Limitations of the Libm +~~~~~~~~~~~~~~~~~~~~~~~ + +Qualification Status +^^^^^^^^^^^^^^^^^^^^ + +This software release is qualified to :ref:`ECSS ` category B, but only for the following configurations: + +#. target GR-CPCI-AT697 ("Compact PCI LEON2-FT (AT697E) Development Board") with a compiler toolchain based on EDISOFT's :ref:`RTEMS ` 4.8 (including :ref:`GCC ` 4.2.1), and +#. target GR-CPCI-LEON4-N2X ("Quad-Core LEON4 Next Generation Microprocessor Evaluation Board") with a compiler toolchain based on OAR's :ref:`RTEMS ` 4.11 (including :ref:`GCC ` 4.9.3), +#. using DMON (2.0.11.13) to connect to the targets, +#. build as per build instructions in :ref:`Operations Environment` and :ref:`Operations Manual` as well as using the configuration and Makefile included in the release, +#. ``LIBMCS_DOUBLE_IS_32BITS`` is not defined, +#. the :ref:`FPU's ` rounding direction is set to *round to nearest with tie to even*. + +The general configuration status of the library can be found in the :ref:`SCF ` and the specific qualification evidences (for the above configuration) are in the :ref:`SUITR `, :ref:`SValR `, and :ref:`SVR `. All life-cycle documents apart from the specific qualification evidences are part of the qualification kit provided to the user. + +If this release is intended to be used in a different configuration then the one given above, then the qualification status needs to be reassessed in a :ref:`SRF ` and a delta-qualification carried out following the :ref:`QG ` OP-QG.00-ML. + +Compliance +^^^^^^^^^^ + +This software is compliant to :ref:`ISO ` C18 (ISO/IEC 9899:2018), :ref:`IEEE-754-2019 `, POSIX (IEEE Std 1003.1-2017), and MISRA C:2012. + +The use of some library macros will issue justifiable MISRA C non-compliances. These MISRA C non-compliances have been justified within the qualification of the LibmCS but in the case of macros, these non-compliances will be visible while compiling the software that is using the LibmCS. + +Compliance to :ref:`ISO ` TS 18661-1 is not yet met. + +Rounding Mode +^^^^^^^^^^^^^ + +The library is only qualified for the rounding mode *round to nearest, tie to even*. + +Platform Architecture +^^^^^^^^^^^^^^^^^^^^^ + +In case the :ref:`FPU ` of the target platform is not implementing all :ref:`IEEE-754 ` features, the :ref:`FPU ` has to be configured appropriately otherwise the library may trap on those missing features. One such example is the GRFPU as seen in :ref:`GeneralBehaviourSubnormalValues`. + +Errno +^^^^^ + +The library does not set the ``errno`` variable to report errors nor does the library read it, ``errno`` is completely ignored. + +Compiler +^^^^^^^^ + +In general the library is prepared to be used with a :ref:`GCC ` toolchain. It might be necessary to change parts of the library when using a different toolchain. +The compiler used on the library shall be able to understand the ``asm`` keyword. For example :ref:`GCC ` has the flag ``-std=gnu99`` to enable the :ref:`GNU ` C language extensions which contain ``asm``. + +Data Model +^^^^^^^^^^ + +The library is compatibility with the following data model processor and compiler tool-chains combinations: + +* ILP32 or 4/4/4 (``int`` and ``long int`` are 32 bit) +* LP64 or 4/8/8 (``int`` is 32 bit and ``long int`` is 64-bit) + +.. note:: + The ``long long int`` type shall always be 64 bits. + +Bessel functions +^^^^^^^^^^^^^^^^ + +The procedures :ref:`jn` and :ref:`yn` have only been qualified until an ``n`` value of 15. If you for some reason need to use them with higher values for ``n``, just change the value in the unit- and validation-tests. The other Bessel procedures (:ref:`j0`, :ref:`j1`, :ref:`y0`, and :ref:`y1`) however are fully qualified. + +Complex procedures +^^^^^^^^^^^^^^^^^^ + +The complex procedures have a lower number of requirements than the procedures defined in ``math.h`` and are less detailed. This mirrors what happens in the :ref:`ISO ` C and :ref:`POSIX ` standards where far less information and requirements are defined for these procedures. As such their requirements fall short of what one could usually expect for Cat. B software. However the fact that these procedures are seldom if ever used in flight and critical software justifies their subpar requirements, while their existence is justified by the need to be able to integrate the library with other :ref:`COTS ` software without restrictions (be aware that having them for integration purposes does not necessarily mean that they are used by other software components but that they expect them to exist). + +fenv.h +^^^^^^ + +The mathematical library contains the header file ``fenv.h``. It declares - but does not implement - the functionalities listed in this section. The ``fenv.h`` header does not contain type definitions nor macros. This header file is only provided as the starting point for the user of the library to implement their own ``fenv.h`` as it is highly hardware dependent. Inclusion of the ``fenv.h`` file in an unmodified version produces an error at compile time, which should be removed by the user after implementing their own procedures. The library also provides an implementation file ``fenv.c`` which contains stub implementations for all procedures in ``fenv.h`` which simply return :math:`-1` which is a valid return value for all procedures and denotes that an error has accrued while calling said procedure. User software will have to check for negative output values anyway as this is how the procedures are defined to give notice of errors. As such this is a reliable way to tell the user that an implementation of the procedures still needs to be provided. + +A custom ``fenv.h`` file needs to contain the type definition of ``fenv_t`` and ``fexcept_t`` provided by the user: + +* ``fenv_t`` represents the entire state of the floating-point environment including its status flags and control modes. +* ``fexcept_t`` represents the state of all floating-point status flags collectively, including the active floating-point exceptions along with additional information the implementation associates with their status. + +A custom ``fenv.h`` file needs to contain the following defines and constants: + +* Constants which need to contain the position of their respective exception flag in the given hardware environment in the form of a bitmask (and as such be easily combineable), their type is ``int`` and should be used by the functions ``feclearexcept``, ``feraiseexcept``, ``fegetexceptflag`` and ``fesetexceptflag``: + + * ``FE_DIVBYZERO`` + * ``FE_INEXACT`` + * ``FE_INVALID`` + * ``FE_OVERFLOW`` + * ``FE_UNDERFLOW`` + * ``FE_ALL_EXCEPT`` + +* Constants which need to represent the given rounding mode in the given hardware environment, their type is ``int`` and should be used by the functions ``fegetround`` and ``fesetround``: + + * ``FE_DOWNWARD`` + * ``FE_TONEAREST`` + * ``FE_TOWARDSZERO`` + * ``FE_UPWARD`` + +* Constant pointer to access the environment in the given hardware environment, the type is ``fenv_t*`` and should be used as input for the functions ``fesetenv`` and ``fegetenv``: + + * ``FE_DFL_ENV`` + +These are the expected procedures of a proper ``fenv.h`` implementation: + +* Floating-point Exceptions + + #. Clear floating-point exceptions + + * ``int feclearexcept(int excepts)`` + + #. Raise floating-point exceptions + + * ``int feraiseexcept(int excepts)`` + + #. Get floating-point exception flags + + * ``int fegetexceptflag(fexcept_t* flagp, int excepts)`` + + #. Set floating-point exception flags + + * ``int fesetexceptflag(const fexcept_t* flagp, int excepts)`` + +* Rounding Direction + + #. Get rounding direction mode + + * ``int fegetround(void)`` + + #. Set rounding direction mode + + * ``int fesetround(int rdir)`` + +* Entire Environment + + #. Get floating-point environment + + * ``int fegetenv(fenv_t* envp)`` + + #. Set floating-point environment + + * ``int fesetenv(const fenv_t* envp)`` + + #. Hold floating-point exceptions + + * ``int feholdexcept(fenv_t* envp)`` + + #. Update floating-point environment + + * ``int feupdateenv(const fenv_t* envp)`` + +* Other + + #. Test for floating-point exceptions + + * ``int fetestexcept(int excepts)`` + +A typical use of the floating-point environment for critical systems will anyways be a direct writing to the floating point registers once during initialization (e.g., setting the rounding mode) thus, avoiding the interface provided by ``fenv.h``. + +tgmath.h +^^^^^^^^ + +The mathematical library contains the header file ``tgmath.h`` which except for adding an error message upon compilation has not been changed from its ``Newlib`` state. ``tgmath.h`` procedures are not qualified. + +Inclusion of the ``tgmath.h`` file produces an intentional error at compile time. Contrary to the ``fenv.h`` header file we descourage any use of the ``tgmath.h`` header and suggest users to not create their own. Type generic function calls should never be used in critical software. + +Thread Safety and Reentrancy +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The library is thread safe and reentrant. For software that is using the library it has to be noted that usage of the ``signgam`` variable is not thread safe when executing the ``lgamma`` procedures on +multiple threads at once, as each procedure call operates on the same variable. This is a limitation forced on the library by the :ref:`POSIX ` standard that demands the availability of the ``signgam`` global variable. + +Other Header Files +^^^^^^^^^^^^^^^^^^ + +The library does not contain any externally available header files other than those that should be part of a ``libm`` according to the ISO C and :ref:`POSIX ` standards. It contains ``math.h``, ``complex.h``, ``fenv.h``, and ``tgmath.h``, although the limitations of the latter two have already been stated in this chapter. This means there will be no ``float.h`` or ``limits.h`` or any other header that does not belong into a ``libm``. All those headers need to be provided by the toolchain. + +Assert Usage +~~~~~~~~~~~~ + +The library contains an ``assert`` in its source code. More specifically assertions are used in the :ref:`frexp`, :ref:`modf` and :ref:`remquo` procedures to ensure that the library does not cause a trap when the procedures are called with a NULL-pointer. + +The implementation of the library assumes that the used toolchain contains an ``assert.h`` file with the standard implementation of ``assert``. That being the case, the ``assert`` can be disabled by defining ``NDEBUG`` either in source code or during compilation. The easiest way to do this would be using the ``make release`` command. + +It is of course possible to add your own definition of ``assert`` using a custom ``assert.h`` file. + +We suggest enabling the ``assert`` during production and disabling it after sufficient testing. This has the benefit that errors can be found more easily during production, and not having the assertion in the object code of the final product. + +Modular Arithmetic Procedures +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +As the modular arithmetic functions are often a source of confusion we want to use this section to show the differences between the modular arithmetic functions and give examples for each. This information is specific to the C programming language, and the C99 and :ref:`IEEE-754 ` standards. + +Modulus Operator: ``%`` +^^^^^^^^^^^^^^^^^^^^^^^ + +Although this operator is not part of the library but of the C language itself, we include it here to complete the overview of modular arithmetic. The ``%`` operator is specific to integers and shall only be used with integer types. The result of using the ``%`` operator is the remainder of using the ``/`` operator on the same operands. Given two variables ``a`` and ``b`` the following must be true: :math:`a \% b = a - (\frac{a}{b} \cdot b)` with integral truncation of :math:`\frac{a}{b}` towards zero. + +Examples: + ++-----------+------------+-------------+--------------+ +| 4 % 1 = 0 | 4 % -1 = 0 | -4 % 1 = 0 | -4 % -1 = 0 | ++-----------+------------+-------------+--------------+ +| 4 % 2 = 0 | 4 % -2 = 0 | -4 % 2 = 0 | -4 % -2 = 0 | ++-----------+------------+-------------+--------------+ +| 4 % 3 = 1 | 4 % -3 = 1 | -4 % 3 = -1 | -4 % -3 = -1 | ++-----------+------------+-------------+--------------+ +| 4 % 4 = 0 | 4 % -4 = 0 | -4 % 4 = 0 | -4 % -4 = 0 | ++-----------+------------+-------------+--------------+ +| 4 % 5 = 4 | 4 % -5 = 4 | -4 % 5 = -4 | -4 % -5 = -4 | ++-----------+------------+-------------+--------------+ +| 4 % 6 = 4 | 4 % -6 = 4 | -4 % 6 = -4 | -4 % -6 = -4 | ++-----------+------------+-------------+--------------+ + +The fmod procedure +^^^^^^^^^^^^^^^^^^ + +The :ref:`fmod` procedure returns the remainder of :math:`x` divided by :math:`y`. Given two variables :math:`x` and :math:`y` the following must be true: :math:`fmod(x, y) = x - n \cdot y`, for an integer :math:`n` such that the result has the same sign as :math:`x` and magnitude less than the magnitude of :math:`y`. If :math:`y` is zero the result will be ``qNaN``. + +Examples: + ++--------------+--------+---+---------------+--------+---+---------------+--------+---+----------------+--------+ +| Input (x, y) | Return | | Input (x, y) | Return | | Input (x, y) | Return | | Input (x, y) | Return | ++==============+========+===+===============+========+===+===============+========+===+================+========+ +| (3.14, 0.2) | 0.14 | | (3.14, -0.2) | 0.14 | | (-3.14, 0.2) | -0.14 | | (-3.14, -0.2) | -0.14 | ++--------------+--------+ +---------------+--------+ +---------------+--------+ +----------------+--------+ +| (3.14, 1.0) | 0.14 | | (3.14, -1.0) | 0.14 | | (-3.14, 1.0) | -0.14 | | (-3.14, -1.0) | -0.14 | ++--------------+--------+ +---------------+--------+ +---------------+--------+ +----------------+--------+ +| (3.14, 1.5) | 0.14 | | (3.14, -1.5) | 0.14 | | (-3.14, 1.5) | -0.14 | | (-3.14, -1.5) | -0.14 | ++--------------+--------+ +---------------+--------+ +---------------+--------+ +----------------+--------+ +| (3.14, 2.0) | 1.14 | | (3.14, -2.0) | 1.14 | | (-3.14, 2.0) | -1.14 | | (-3.14, -2.0) | -1.14 | ++--------------+--------+ +---------------+--------+ +---------------+--------+ +----------------+--------+ +| (3.14, 2.34) | 0.80 | | (3.14, -2.34) | 0.80 | | (-3.14, 2.34) | -0.80 | | (-3.14, -2.34) | -0.80 | ++--------------+--------+ +---------------+--------+ +---------------+--------+ +----------------+--------+ +| (3.14, 3.0) | 0.14 | | (3.14, -3.0) | 0.14 | | (-3.14, 3.0) | -0.14 | | (-3.14, -3.0) | -0.14 | ++--------------+--------+ +---------------+--------+ +---------------+--------+ +----------------+--------+ +| (3.14, 3.7) | 3.14 | | (3.14, -3.7) | 3.14 | | (-3.14, 3.7) | -3.14 | | (-3.14, -3.7) | -3.14 | ++--------------+--------+ +---------------+--------+ +---------------+--------+ +----------------+--------+ +| (3.14, 4.0) | 3.14 | | (3.14, -4.0) | 3.14 | | (-3.14, 4.0) | -3.14 | | (-3.14, -4.0) | -3.14 | ++--------------+--------+---+---------------+--------+---+---------------+--------+---+----------------+--------+ + +The remainder and remquo procedures +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The :ref:`remainder` and :ref:`remquo` procedures returns the remainder of :math:`x` divided by :math:`y`. Given two variables :math:`x` and :math:`y` the following must be true: :math:`remainder(x, y) = x - n \cdot y`, where :math:`n` is the integer nearest to the exact result of :math:`\frac{x}{y}` (when the exact result is exactly in the middle of two integers, :math:`n` is even). If :math:`y` is zero the result will be ``qNaN``. + +Examples: + ++--------------+--------+---+---------------+--------+---+---------------+--------+---+----------------+--------+ +| Input (x, y) | Return | | Input (x, y) | Return | | Input (x, y) | Return | | Input (x, y) | Return | ++==============+========+===+===============+========+===+===============+========+===+================+========+ +| (3.14, 0.2) | -0.06 | | (3.14, -0.2) | -0.06 | | (-3.14, 0.2) | -0.06 | | (-3.14, -0.2) | -0.06 | ++--------------+--------+ +---------------+--------+ +---------------+--------+ +----------------+--------+ +| (3.14, 1.0) | 0.14 | | (3.14, -1.0) | 0.14 | | (-3.14, 1.0) | 0.14 | | (-3.14, -1.0) | 0.14 | ++--------------+--------+ +---------------+--------+ +---------------+--------+ +----------------+--------+ +| (3.14, 1.5) | 0.14 | | (3.14, -1.5) | 0.14 | | (-3.14, 1.5) | 0.14 | | (-3.14, -1.5) | 0.14 | ++--------------+--------+ +---------------+--------+ +---------------+--------+ +----------------+--------+ +| (3.14, 2.0) | -0.86 | | (3.14, -2.0) | -0.86 | | (-3.14, 2.0) | -0.86 | | (-3.14, -2.0) | -0.86 | ++--------------+--------+ +---------------+--------+ +---------------+--------+ +----------------+--------+ +| (3.14, 2.34) | 0.80 | | (3.14, -2.34) | 0.80 | | (-3.14, 2.34) | -0.80 | | (-3.14, -2.34) | -0.80 | ++--------------+--------+ +---------------+--------+ +---------------+--------+ +----------------+--------+ +| (3.14, 3.0) | 0.14 | | (3.14, -3.0) | 0.14 | | (-3.14, 3.0) | 0.14 | | (-3.14, -3.0) | 0.14 | ++--------------+--------+ +---------------+--------+ +---------------+--------+ +----------------+--------+ +| (3.14, 3.7) | -0.56 | | (3.14, -3.7) | -0.56 | | (-3.14, 3.7) | -0.56 | | (-3.14, -3.7) | -0.56 | ++--------------+--------+ +---------------+--------+ +---------------+--------+ +----------------+--------+ +| (3.14, 4.0) | -0.86 | | (3.14, -4.0) | -0.86 | | (-3.14, 4.0) | -0.86 | | (-3.14, -4.0) | -0.86 | ++--------------+--------+---+---------------+--------+---+---------------+--------+---+----------------+--------+ + +The modf procedure +^^^^^^^^^^^^^^^^^^ + +The :ref:`modf` procedure returns the fractional part of :math:`x` and puts the integral part of :math:`x` to the outward pointer :math:`iptr`. It's easier to think of :ref:`modf` as a procedure with one input and two outputs. + +Examples: + ++---------+--------+-------------+---+---------+--------+-------------+ +| Input x | Return | Output iptr | | Input x | Return | Output iptr | ++=========+========+=============+===+=========+========+=============+ +| 0.14 | 0.14 | 0.0 | | -0.14 | -0.14 | -0.0 | ++---------+--------+-------------+ +---------+--------+-------------+ +| 3.0 | 0.0 | 3.0 | | -3.0 | -0.0 | -3.0 | ++---------+--------+-------------+ +---------+--------+-------------+ +| 3.14 | 0.14 | 3.0 | | -3.14 | -0.14 | -3.0 | ++---------+--------+-------------+---+---------+--------+-------------+ + +Side Effects +~~~~~~~~~~~~ + +This library does not produce any side effects, apart from the exceptions that have been described, + +* to the software that uses the library, +* nor to the hardware, + +as it does not configure any hardware. diff --git a/libm/libmcs/doc/sum/5_External_View_of_the_Software.rst b/libm/libmcs/doc/sum/5_External_View_of_the_Software.rst new file mode 100644 index 00000000..366563df --- /dev/null +++ b/libm/libmcs/doc/sum/5_External_View_of_the_Software.rst @@ -0,0 +1,177 @@ +External View of the Software +============================= + +The library is delivered as an archive consisting of the source files, licenses, a Makefile, a configuration script, and everything to create documentation. + +The following is a depiction of the directory structure: + + libmcs/ + doc/ + _static/css/custom.css + CSS file to be used by the HTML documentation. + figure/ + Directory to contain figures used by one or multiple generated documents. + sdd/ + conf.py + Configuration file for the Sphinx documentation builder. + index.rst + Index file for the document. This is the starting point for document generation, all + other files should be referenced directly or indirectly by this one. + other files + Other reStructuredText files for the document. Usually each chapter either has its + own directory or at least its own file. + sum/ + conf.py + Configuration file for the Sphinx documentation builder. + index.rst + Index file for the document. This is the starting point for document generation, all + other files should be referenced directly or indirectly by this one. + other files + Other reStructuredText files for the document. Usually each chapter has its own + file. You're currently reading one of them. + libm/ + common/ + fenv.c + Implementation file for ``fenv.h`` which contains only stub implementations that + return an error value. + signgam.c + This file only provides the ``signgam`` global variable used by the :ref:`lgamma` + procedures. + tool.[c|h] + Header file that provides several library internal convenience procedures to be used + by many library procedures. + other files + Other ``.c`` files which have no content other than comments to describe procedures + (mostly macros) that are implemented in ``math.h`` or ``complex.h``. + complexd/ + internal/ + Internal ``.c`` files only used by procedures in the directory above. + + Contains all ``.c`` files for double precision complex procedures. + complexf/ + internal/ + Internal ``.c`` files only used by procedures in the directory above. + + Contains all ``.c`` files for single precision complex procedures. + complexfe/ + internal/ + .gitkeep + Placeholder file that only exists so that git does not remove the otherwise empty + directory. + + Placeholder directory which shall contain all ``.c`` files for single precision complex + procedures which have been implemented using double precision. + complexl/ + internal/ + .gitkeep + Placeholder file that only exists so that git does not remove the otherwise empty + directory. + + Placeholder directory which shall contain all ``.c`` files for long double precision + complex procedures which do not have the same size as double. + include/ + config.h + Header file that contains the configuration of the library, as chosen during the + configuration step. This file gets generated by running ``configure``. + complex.h + Header file which needs to be included when building the user project and complex + procedures are needed. + fenv.h + Header file which should not be included as is. The procedures have no functionality + other than returning an error value and providing prototypes. If the user wants to + use ``fenv`` s/he will have to implement the features her/himself (or copy them from + somewhere). We cannot provide these functionalities for the user as their + implementation is highly platform dependant. + internal_config.h + Header file that converts the choices the user has made during configuration into + defines used by the library. + math.h + Header file which needs to be included when building the user project. + tgmath.h + Header file which should never be included. + machine/ + .gitkeep + Placeholder file that only exists so that git does not remove the otherwise empty + directory. + + Placeholder directory which shall contain sub-directories for each architecture that + needs a hardware specific implementation of a procedure. Those files are only compiled + if the appropriate changes are made to the Makefile. Example structure if the user + were to add a procedure to directly call a hardware square root instruction on a SPARC + V8 platform: + + sparc_v8/ + mathd/ + sqrtd.c + mathf/ + sqrtf.c + mathd/ + internal/ + Internal ``.c`` files only used by procedures in the directory above. + + Contains all ``.c`` files for double precision procedures. + mathf/ + internal/ + Internal ``.c`` files only used by procedures in the directory above. + + Contains all ``.c`` files for single precision procedures. + mathfe/ + internal/ + .gitkeep + Placeholder file that only exists so that git does not remove the otherwise empty + directory. + + Placeholder directory which shall contain all ``.c`` files for single precision + procedures which have been implemented using double precision. + mathl/ + internal/ + .gitkeep + Placeholder file that only exists so that git does not remove the otherwise empty + directory. + + Placeholder directory which shall contain all ``.c`` files for long double precision + procedures which do not have the same size as double. + LICENSES/ + Contains license files which are referenced by the :ref:`SPDX ` headers in the other + implementation files. + sw-quality/ + Contains the configuration and scripts to run pc-lint. + .gitignore + Typical gitignore file. + .gitlab-ci.yml + Continuous integration file for usage with Gitlab. Automatically runs documentation + generation. + configure + Configuration script that has to be run by the user before running ``make``. + COPYING.md + License file which lists all other licenses and states the overall license of the library. + Dockerfile + Dockerfile used for continuous integration. + Makefile + Build the library. + README.md + Typical readme file. + requirements.in + Contains the python package requirements used for document generation, it's fed into + ``pip-compile`` to create the ``requirements.txt`` file. + requirements.txt + Contains the python package requirements used for document generation. Autogenerated from + ``requirements.in`` and used by the Dockerfile. + +After using the included Makefile the directory structure will be extended with build specific directories: + + libmcs/ + build-ARCH/ + bin/ + libm.a + This is the final static library, the product and heart of the library. + obj/ + Contains the intermediate object files which were created by the Makefile to produce + the static library. + build-info.yml + Contains information on the built library, such as its build date, toolchain used, + compilation flags used, and git commit used. + [...] + Each architecture has its own build directory. + +How to use the Makefile is depicted in :ref:`Operations Manual` diff --git a/libm/libmcs/doc/sum/6_Operations_Environment.rst b/libm/libmcs/doc/sum/6_Operations_Environment.rst new file mode 100644 index 00000000..b36fad6a --- /dev/null +++ b/libm/libmcs/doc/sum/6_Operations_Environment.rst @@ -0,0 +1,77 @@ +Operations Environment +====================== + +General +~~~~~~~ + +The software in this project is designed to be included in other software. + +Other than a compiler no additional software is necessary to build, or access the library's procedures. + +The hardware parts used by the library are the :ref:`CPU `, :ref:`FPU ` and :ref:`RAM `. + +The following sections describe additional constraints which have to be considered when using the library on specific hardware platforms. + +.. _OperationsEnviromentHardwareConfiguration: + +Hardware Configuration +~~~~~~~~~~~~~~~~~~~~~~ + +The software described here contains several mathematical procedures which execute floating point operations. For this to be possible the target platform's configuration needs to be modified, in particular the :ref:`FPU `: + +#. Enable the :ref:`FPU ` before executing any floating-point procedure. +#. Configure the :ref:`FPU ` regarding subnormal numbers and other trap causing situations. See also :ref:`GeneralBehaviourSubnormalValues`. + +As these are platform dependent actions, their procedures cannot reasonably be described here for every platform and have to be researched in the corresponding hardware manuals. + +.. _OperationsEnviromentSoftwareConfiguration: + +Software Configuration +~~~~~~~~~~~~~~~~~~~~~~ + +The software configuration is confined to the configuration script and the compile switches. At runtime, there is no option to configure the library itself. + +To include the library in other software projects while guaranteeing :ref:`IEEE-754 ` standard compliance, the following compilation flags should be enabled when building the project when using :ref:`GCC `: + +* ``-frounding-math`` +* ``-fsignaling-nans`` +* ``-fno-builtin`` + +We advise using the following flag combination to include exclusively those procedures into the final executable that are actually used within your software: + +* ``-ffunction-sections -fdata-sections`` + +For this to work you also have to add the linker option ``-gc-sections`` while building your project. + +On the other hand the following compilation flags shall not be used, since they can produce code which is not compliant to the :ref:`IEEE-754 ` standard: + +* ``-O3`` +* ``-ffast-math``, it activates ``-funsafe-math-optimizations``, ``-fno-rounding-math``, ``-ffinite-math-only``, ``-fno-signaling-nans``, and ``-fcx-limited-range`` + +Depending on the processor and :ref:`FPU ` you are using consider adding architecture specific flags, for example those listed in `SPARC Options `_ (especially those starting with ``-mfix``). + +Additionally we have tested the following compilation flags which caused no problems to the behaviour of the library (tested with the :ref:`RTEMS ` 4.8 toolchain provided by EDISOFT): + +* ``-O2`` +* ``-mhard-float`` [#]_ +* ``-mcpu=v8`` +* ``-fno-zero-initialized-in-bss`` +* ``-fno-inline-functions-called-once`` + +In case the used architecture and toolchain support :ref:`FMA ` instructions we advise using the flag ``-mno-fused-madd`` as the library was not tested for compatibility with said instruction. + +Remember to also add flags that alter the sizes of different types such as ``long double`` or ``long int`` to those appropriate for your hardware, for example ``-mlong-double-64`` can be set for x86 targets that typically use 80-bit ``long double``. These flags are different depending on the toolchain and should be in line with the rest of your software. + +.. _OperationsEnviromentUsingHardwareInstructions: + +Using Hardware Instructions +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To replace LibmCS procedures with custom procedures, such as hardware instruction calling procedures, several steps need to be followed: + +* Add the file containing the procedure into an architecture specific sub-directory within the ``libm/machine`` directory. If the directory does not exist, make one for your architecture. An example for this step has already been added to the library for the SPARC V8 architecture. +* Replace the file you want to replace in the ``Makefile.in``. As an example for this step we have added a patch for the library where this is done for the SPARC V8 ``sqrt`` procedure. + +Note that replacing procedures may cause different results and in turn may cause unit tests to fail. You will have to justify those fails, or change the respective tests and justify that change. + +.. [#] The flag ``-mhard-float`` is the default behaviour for SPARC compilations with :ref:`GCC `. diff --git a/libm/libmcs/doc/sum/7_Operations_Manual.rst b/libm/libmcs/doc/sum/7_Operations_Manual.rst new file mode 100644 index 00000000..9b137cef --- /dev/null +++ b/libm/libmcs/doc/sum/7_Operations_Manual.rst @@ -0,0 +1,95 @@ +Operations Manual +================= + +Set-up and Initialization +~~~~~~~~~~~~~~~~~~~~~~~~~ + +In short: + +* call ``configure`` +* call ``make`` + +The first step to include the mathematical library into another software project is to build the static library from the library source code. For this procedure, a configuration script and a Makefile are prepared. + +First the user has to run the configuration script which will interactively ask for several configuration items. To reduce the number of questions asked interactively the ``configure`` script can be called with flags. During configuration you will be asked ... + +* ... for the path to the compilation toolchain. (Flag: ``--cross-compile ``) +* ... for additional compilation flags. (Flag: ``--compilation-flags ``) +* ... whether the platform does not support subnormals and as such uses a non-standard :ref:`FTZ/DAZ ` mode. (Flag: ``--enable-denormal-handling`` or ``--disable-denormal-handling``) +* ... whether you want ``long double`` procedures (this will only be asked if the toolchain informs the configuration script that ``long double`` are 64 bit in size). (Flag: ``--enable-long-double-procedures`` or ``--disable-long-double-procedures``) +* ... for your platforms endianess (this will only be asked if the toolchain does not provide the answer). (Flag: ``--big-endian`` or ``--little-endian``) +* ... whether you want complex procedures. (Flag: ``--enable-complex-procedures`` or ``--disable-complex-procedures``) + +The configuration creates a secondary Makefile ``user_make.mk``, which will then be used by the primary Makefile. As such it should not be moved elsewhere (if it is not where it should be the primary Makefile will assume ``configure`` has not been executed and display an error). It contains flags and variables based on the choices made during ``configure`` as well as an additional variable which tells the primary Makefile that the configuration was properly finished. + +The Makefile provides the following targets: + +* ``all``: Compiles and builds the library. +* ``debug``: Compiles and builds the library. Same as ``all``. +* ``release``: Compiles and builds the library. Add the compilation flag ``-DNDEBUG``, afterwards runs ``all``. +* ``clean``: Removes the object files and the static library of the chosen build. +* ``cleanall``: Removes the object files and static libraries from all builds. +* ``distclean``: Removes files generated by the configuration script. +* ``install``: The library does not need to be installed. As such running ``install`` only yields an information message. + +The targets ``all``, ``debug``, ``release``, and ``clean`` can be modified using the following constants: + +* ``CROSS_COMPILE``: Prefix to tell the Makefile which compiler to use. This is usually already set during configuration. +* ``ARCH``: Tells the Makefile for which architecture the build is intended. If not provided this defaults to a target stated by the :ref:`GCC ` provided via ``CROSS_COMPILE``. +* ``COVERAGE=true``: Tells the Makefile to use flags specific to the generation of coverage reports. + +.. note:: + The library has been built to compile without warnings but the compilation process might show some warnings about the use of potentially + uninitialized variables depending on the compiler version (and or specific compiler flags). These warnings can be + disregarded as all variable uses have been statically analyzed and shown to be correct + in all cases. + +The resulting libraries can be found in the ``build-ARCH/bin`` directory, with ``ARCH`` being the provided constant, or if not provided defaults to the target defined by :ref:`GCC ` (this can be inspected with the shell command ``gcc -v``). The intermediate object files can be found in the ``build-ARCH/obj`` directory. + +After finishing the build `make` will also create a build info file within the ``build-ARCH`` directory. This file is aptly named ``build_info.yml`` and contains the following information in :ref:`YAML ` format: + +* timestamp on when the build was made, +* path to the compiler, information provided by the compiler (such as version), compilation flags, includes, +* git information: branch name, commit hash, check if the commit is clean or if changes were made (dirty), +* sha256 of the generated libm.a + +Both of the files ``build_info.yml`` and ``user_make.mk`` provide information to MAXI while creating the final reports, as such they need to stay at the path they were generated at. The same applies to the ``libm.a`` itself. + +Getting Started +~~~~~~~~~~~~~~~ + +In the last section, the code of the mathematical library is prepared in a static library. To use the library, the library header files have to be included in the user's source code. The useable header files are ``math.h``, and ``complex.h``. The complex procedures however will only exist if they were chosen to during configuration. + +Mode Selection and Control +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +After writing the project specific code, the last step to build a program which includes the library is to compile the new software. During the compilation two steps are necessary for success: + +#. Link to the static library (``libm.a``). +#. Include the header files located in ``libm/include`` + +As an example by using :ref:`GCC ` the following line should work:: + + $ gcc -o new_executable_software new_software_source_code.c libmcs/build-x86_64-linux-gnu/bin/libm.a -Ilibmcs/libm/include + +The user has to add a number of additional flags, beginning with those listed in :ref:`OperationsEnviromentSoftwareConfiguration`. One might also need a number of platform or hardware specific flags, e.g. the flag ``-qleon2`` when building for the Leon2 platform with Gaisler's :ref:`RTEMS `. Extra flags depend on the :ref:`OS `, the compilation toolchain, and possibly a :ref:`BSP `; please check the corresponding documentation for your situation. It is suggested to write a Makefile for this (or use tools for the creation of Makefiles). + +Normal Operations +~~~~~~~~~~~~~~~~~ + +All accessible procedures within the library are shown in chapter :ref:`Purpose of the Software`. For detailed information on each procedure, take a look at the related subsection in :ref:`Reference Manual`. + +Normal Termination +~~~~~~~~~~~~~~~~~~ + +Each procedure in the library is executed when called and computes a result. There is no software interruption foreseen during the computation and the procedure terminates by returning the result. If there is an interrupt, e.g. a context switch caused by the underlying operating system, the correct re-schedule has to be managed by the causing operating system. + +.. _OperationsManualErrorConditions: + +Error Conditions +~~~~~~~~~~~~~~~~ + +There is no error condition handling in the library. The ``errno`` variable proposed by the :ref:`ISO ` C standard is not set by the library. Error states may only be caused by the used hardware and must be handled by the user's software. For example the following errors may occur: + +* Any :ref:`FPU ` can produce traps depending on its configuration. See :ref:`OperationsEnviromentHardwareConfiguration` for more information. +* The program stack can overflow if the stack size limit is exceeded by calling one of the provided procedures, even though their memory footprint is rather low. diff --git a/libm/libmcs/doc/sum/8_Reference_Manual.rst b/libm/libmcs/doc/sum/8_Reference_Manual.rst new file mode 100644 index 00000000..5c1efa59 --- /dev/null +++ b/libm/libmcs/doc/sum/8_Reference_Manual.rst @@ -0,0 +1,556 @@ +Reference Manual +================ + +This chapter provides the detailed documentation of all the procedures (C functions and macros) listed in chapter :ref:`Purpose of the Software`. + +Each procedure is described in a separate subsection with the style similar to the documentation of the procedures in the ISO C and POSIX standards. Each subsection starts with a synopsis specifying the +procedure’s signature, followed by a short description of the evaluated mathematical function and its return value. Further the raised exceptions are noted. + +Classification Macros +""""""""""""""""""""" + +fpclassify +~~~~~~~~~~ + +.. c:autodoc:: mathd/internal/fpclassifyd.c + +isfinite +~~~~~~~~ + +.. c:autodoc:: common/isfinite.c + +isinf +~~~~~ + +.. c:autodoc:: common/isinf.c + +isnan +~~~~~ + +.. c:autodoc:: common/isnan.c + +isnormal +~~~~~~~~ + +.. c:autodoc:: common/isnormal.c + +signbit +~~~~~~~ + +.. c:autodoc:: mathd/internal/signbitd.c + +Trigonometric Functions +""""""""""""""""""""""" + +acos +~~~~ + +.. c:autodoc:: mathd/acosd.c + +asin +~~~~ + +.. c:autodoc:: mathd/asind.c + +atan +~~~~ + +.. c:autodoc:: mathd/atand.c + +atan2 +~~~~~ + +.. c:autodoc:: mathd/atan2d.c + +cos +~~~ + +.. c:autodoc:: mathd/cosd.c + +sin +~~~ + +.. c:autodoc:: mathd/sind.c + +tan +~~~ + +.. c:autodoc:: mathd/tand.c + +Hyperbolic Functions +"""""""""""""""""""" + +acosh +~~~~~ + +.. c:autodoc:: mathd/acoshd.c + +asinh +~~~~~ + +.. c:autodoc:: mathd/asinhd.c + +atanh +~~~~~ + +.. c:autodoc:: mathd/atanhd.c + +cosh +~~~~ + +.. c:autodoc:: mathd/coshd.c + +sinh +~~~~ + +.. c:autodoc:: mathd/sinhd.c + +tanh +~~~~ + +.. c:autodoc:: mathd/tanhd.c + +Exponential and Logarithmic Functions +""""""""""""""""""""""""""""""""""""" + +exp +~~~ + +.. c:autodoc:: mathd/expd.c + +exp2 +~~~~ + +.. c:autodoc:: mathd/exp2d.c + +expm1 +~~~~~ + +.. c:autodoc:: mathd/expm1d.c + +frexp +~~~~~ + +.. c:autodoc:: mathd/frexpd.c + +ilogb +~~~~~ + +.. c:autodoc:: mathd/ilogbd.c + +ldexp +~~~~~ + +.. c:autodoc:: mathd/ldexpd.c + +log +~~~ + +.. c:autodoc:: mathd/logd.c + +log10 +~~~~~ + +.. c:autodoc:: mathd/log10d.c + +log1p +~~~~~ + +.. c:autodoc:: mathd/log1pd.c + +log2 +~~~~ + +.. c:autodoc:: mathd/log2d.c + +logb +~~~~ + +.. c:autodoc:: mathd/logbd.c + +modf +~~~~ + +.. c:autodoc:: mathd/modfd.c + +scalbn +~~~~~~ + +.. c:autodoc:: mathd/scalbnd.c + +scalbln +~~~~~~~ + +.. c:autodoc:: mathd/scalblnd.c + +Power and Absolute-value Functions +"""""""""""""""""""""""""""""""""" + +cbrt +~~~~ + +.. c:autodoc:: mathd/cbrtd.c + +fabs +~~~~ + +.. c:autodoc:: mathd/fabsd.c + +hypot +~~~~~ + +.. c:autodoc:: mathd/hypotd.c + +pow +~~~ + +.. c:autodoc:: mathd/powd.c + +sqrt +~~~~ + +.. c:autodoc:: mathd/sqrtd.c + +Error and Gamma Functions +""""""""""""""""""""""""" + +erf +~~~ + +.. c:autodoc:: mathd/erfd.c + +erfc +~~~~ + +.. c:autodoc:: mathd/erfcd.c + +lgamma +~~~~~~ + +.. c:autodoc:: mathd/lgammad.c + +tgamma +~~~~~~ + +.. c:autodoc:: mathd/tgammad.c + +signgam +~~~~~~~ + +.. c:autodoc:: common/signgam.c + +Nearest Integer Functions +""""""""""""""""""""""""" + +ceil +~~~~ + +.. c:autodoc:: mathd/ceild.c + +floor +~~~~~ + +.. c:autodoc:: mathd/floord.c + +nearbyint +~~~~~~~~~ + +.. c:autodoc:: mathd/nearbyintd.c + +rint +~~~~ + +.. c:autodoc:: mathd/rintd.c + +lrint +~~~~~ + +.. c:autodoc:: mathd/lrintd.c + +llrint +~~~~~~ + +.. c:autodoc:: mathd/llrintd.c + +round +~~~~~ + +.. c:autodoc:: mathd/roundd.c + +lround +~~~~~~ + +.. c:autodoc:: mathd/lroundd.c + +llround +~~~~~~~ + +.. c:autodoc:: mathd/llroundd.c + +trunc +~~~~~ + +.. c:autodoc:: mathd/truncd.c + +Remainder Functions +""""""""""""""""""" + +fmod +~~~~ + +.. c:autodoc:: mathd/fmodd.c + +remainder +~~~~~~~~~ + +.. c:autodoc:: mathd/remainderd.c + +remquo +~~~~~~ + +.. c:autodoc:: mathd/remquod.c + +Manipulation Functions +"""""""""""""""""""""" + +copysign +~~~~~~~~ + +.. c:autodoc:: mathd/copysignd.c + +nan +~~~ + +.. c:autodoc:: mathd/nand.c + +nextafter +~~~~~~~~~ + +.. c:autodoc:: mathd/nextafterd.c + +nexttoward +~~~~~~~~~~ + +.. c:autodoc:: mathd/nexttowardd.c + +Maximum, Minimum and Positive Difference Functions +"""""""""""""""""""""""""""""""""""""""""""""""""" + +fdim +~~~~ + +.. c:autodoc:: mathd/fdimd.c + +fmax +~~~~ + +.. c:autodoc:: mathd/fmaxd.c + +fmin +~~~~ + +.. c:autodoc:: mathd/fmind.c + +Floating Multiply-Add +""""""""""""""""""""" + +fma +~~~ + +.. c:autodoc:: mathd/fmad.c + +Comparison Macros +""""""""""""""""" + +isgreater +~~~~~~~~~ + +.. c:autodoc:: common/isgreater.c + +isgreaterequal +~~~~~~~~~~~~~~ + +.. c:autodoc:: common/isgreaterequal.c + +isless +~~~~~~ + +.. c:autodoc:: common/isless.c + +islessequal +~~~~~~~~~~~ + +.. c:autodoc:: common/islessequal.c + +islessgreater +~~~~~~~~~~~~~ + +.. c:autodoc:: common/islessgreater.c + +isunordered +~~~~~~~~~~~ + +.. c:autodoc:: common/isunordered.c + +Bessel Functions (POSIX) +"""""""""""""""""""""""" + +j0 +~~ + +.. c:autodoc:: mathd/j0d.c + +j1 +~~ + +.. c:autodoc:: mathd/j1d.c + +jn +~~ + +.. c:autodoc:: mathd/jnd.c + +y0 +~~ + +.. c:autodoc:: mathd/y0d.c + +y1 +~~ + +.. c:autodoc:: mathd/y1d.c + +yn +~~ + +.. c:autodoc:: mathd/ynd.c + +Complex Trigonometric Functions +""""""""""""""""""""""""""""""" + +cacos +~~~~~ + +.. c:autodoc:: complexd/cacosd.c + +casin +~~~~~ + +.. c:autodoc:: complexd/casind.c + +catan +~~~~~ + +.. c:autodoc:: complexd/catand.c + +ccos +~~~~ + +.. c:autodoc:: complexd/ccosd.c + +csin +~~~~ + +.. c:autodoc:: complexd/csind.c + +ctan +~~~~ + +.. c:autodoc:: complexd/ctand.c + +Complex Hyperbolic Functions +"""""""""""""""""""""""""""" + +cacosh +~~~~~~ + +.. c:autodoc:: complexd/cacoshd.c + +casinh +~~~~~~ + +.. c:autodoc:: complexd/casinhd.c + +catanh +~~~~~~ + +.. c:autodoc:: complexd/catanhd.c + +ccosh +~~~~~ + +.. c:autodoc:: complexd/ccoshd.c + +csinh +~~~~~ + +.. c:autodoc:: complexd/csinhd.c + +ctanh +~~~~~ + +.. c:autodoc:: complexd/ctanhd.c + +Complex Exponential and Logarithmic Functions +""""""""""""""""""""""""""""""""""""""""""""" + +cexp +~~~~ + +.. c:autodoc:: complexd/cexpd.c + +clog +~~~~ + +.. c:autodoc:: complexd/clogd.c + +Complex Power and Absolute-value Functions +"""""""""""""""""""""""""""""""""""""""""" + +cabs +~~~~ + +.. c:autodoc:: complexd/cabsd.c + +cpow +~~~~ + +.. c:autodoc:: complexd/cpowd.c + +csqrt +~~~~~ + +.. c:autodoc:: complexd/csqrtd.c + +Complex Manipulation Functions +"""""""""""""""""""""""""""""" + +carg +~~~~ + +.. c:autodoc:: complexd/cargd.c + +cimag +~~~~~ + +.. c:autodoc:: complexd/cimagd.c + +CMPLX +~~~~~ + +.. c:autodoc:: common/cmplx.c + +conj +~~~~ + +.. c:autodoc:: complexd/conjd.c + +cproj +~~~~~ + +.. c:autodoc:: complexd/cprojd.c + +creal +~~~~~ + +.. c:autodoc:: complexd/creald.c diff --git a/libm/libmcs/doc/sum/9_Tutorial.rst b/libm/libmcs/doc/sum/9_Tutorial.rst new file mode 100644 index 00000000..5817b9ad --- /dev/null +++ b/libm/libmcs/doc/sum/9_Tutorial.rst @@ -0,0 +1,265 @@ +Tutorial +======== + +This tutorial presents how to implement the library into user software, how to use the provided procedures, how to build it, and the execution's output. + +The examples use an :ref:`RTEMS ` :ref:`OS ` (version 4.10, it includes :ref:`GCC ` 4.4.6) provided by Cobham Gaisler including their :ref:`BSP `. + +The user's experience will vary (possibly heavily) when using different hardware and/or :ref:`OS `. + +It is assumed, that the library was built as shown in the :ref:`Operations Manual`. + +Example 1: LEON2 with Meiko FPU +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The first example is done for a LEON2 platform with a Meiko :ref:`FPU `. This :ref:`FPU ` is perfectly able to work with subnormal numbers and does not throw any traps when executed with those. + +Getting Started +^^^^^^^^^^^^^^^ + +The first important step is to include the library part we want to use: + +.. code-block:: c + + #include "math.h" + +The second step is to start the :ref:`FPU `. This step is :ref:`FPU ` and :ref:`BSP ` specific and simply enables the :ref:`FPU ` in the :ref:`PSR `: + +.. code-block:: c + + uint32_t psr; + sparc_get_psr(psr); + psr |= SPARC_PSR_EF_MASK; + sparc_set_psr(psr); + +The Meiko :ref:`FPU ` has an :ref:`ISO ` C18 standard conform handling of subnormal numbers, and the non-standard bit in the :ref:`FSR ` cannot be set. + +The final step is an actual call to some library procedures: + +.. code-block:: c + + double input = M_PI_4; + double result = sin(input); + + float inputX = 3.5f; + float inputY = 1.2f; + float resultf = fmodf(inputX, inputY); + +Using all those snipets we can create a small test program. Sadly :ref:`RTEMS ` and the :ref:`BSP ` need some more configuring, but as the program would not run without them, we're going to show that as well. We've also added some ``printf`` to actually get a visible output (which one can only see if some type of console output is possible...): + +.. code-block:: c + + #include + + #include + + #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER + #define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER + + #define CONFIGURE_RTEMS_INIT_TASKS_TABLE + #define CONFIGURE_MAXIMUM_TASKS 1 + + #define CONFIGURE_INIT + #include + + #include + #include + + #include "math.h" + + void test() + { + double dbuf, ret; + + double d1 = 0.5, d2 = -2.0; + float f1 = 0.5f, f2 = -2.0f; + + printf("sin(%lf) = %lf\n", d1, sin(d1)); + printf("atan2(%lf, %lf) = %lf\n", d1, d2, atan2(d1, d2)); + ret = modf(d1, &dbuf); + printf("modf(%lf, %lf) = %lf\n", d1, dbuf, ret); + printf("isfinite(%lf) = %d\n", d1, isfinite(d1)); + + printf("cosf(%f) = %f\n", f1, cosf(f1)); + printf("powf(%f, %f) = %f\n", f1, f2, powf(f1, f2)); + printf("fmodf(%f, %f) = %f\n", f1, f2, fmodf(f1, f2)); + printf("signbit(%f) = %d\n", f1, signbit(f1)); + } + + void ConfigurationMultiprocessingEnableFpu() + { + uint32_t psr; + sparc_get_psr(psr); + psr |= SPARC_PSR_EF_MASK; + sparc_set_psr(psr); + } + + rtems_task Init(rtems_task_argument arg) + { + ConfigurationMultiprocessingEnableFpu(); + + test(); + exit(0); + } + +Using the Software on a Typical Task +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Let's build the software using a shell command:: + + $ sparc-rtems-gcc test test_rtems.c libmcs/build-sparc_v8/bin/libm.a -Ilibmcs/libm/include -qleon2 -frounding-math -fsignaling-nans -fno-builtin + +As one can see the command builds with the library, includes the header files, uses the LEON2 specific flag ``-qleon2``, and uses the flags provided in :ref:`OperationsEnviromentSoftwareConfiguration`, before finally producing the ``test`` executable. + +After running this program on the LEON2 platform it produces the following output on the console: + +.. code-block:: none + + sin(0.500000) = 0.479426 + atan2(0.500000, -2.000000) = 2.896614 + modf(0.500000, 0.000000) = 0.500000 + isfinite(0.500000) = 1 + + cosf(0.500000) = 0.877583 + powf(0.500000, -2.000000) = 4.000000 + fmodf(0.500000, -2.000000) = 0.500000 + signbit(0.500000) = 0 + +Example 2: LEON4 with GRFPU +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The second example is done for a LEON4 platform with a GRFPU. This :ref:`FPU ` has to be configured to prevent traps on subnormal numbers as described in :ref:`OperationsManualErrorConditions`. + +Getting Started +^^^^^^^^^^^^^^^ + +The first important step is to include the library: + +.. code-block:: c + + #include "math.h" + +The second step is to start the :ref:`FPU `. This step is :ref:`FPU ` and :ref:`BSP ` specific and simply enables the :ref:`FPU ` in the :ref:`PSR `: + +.. code-block:: c + + uint32_t psr; + sparc_get_psr(psr); + psr |= SPARC_PSR_EF_MASK; + sparc_set_psr(psr); + +The third step is to set the :ref:`FPU ` to non-standard mode (if wanted). This step is :ref:`FPU ` and :ref:`BSP ` specific and sets the appropriate bit in the :ref:`FSR `. The :ref:`BSP ` did not provide direct access to the :ref:`FSR ` therefore some asm-macros were needed: + +.. code-block:: c + + #define GET_FSR(fsr) \ + asm volatile("st %%fsr, %[reg]" : [reg] "=g" (fsr) : "0" (fsr)); + #define SET_FSR(fsr) \ + asm volatile("ld %[reg], %%fsr" : : [reg] "g" (fsr)); + + uint32_t fsr; + GET_FSR(fsr); + fsr |= (1 << 22); + SET_FSR(fsr); + +The final step is an actual call to some library procedures: + +.. code-block:: c + + double input = M_PI_4; + double result = sin(input); + + float inputX = 3.5f; + float inputY = 1.2f; + float resultf = fmodf(inputX, inputY); + +Using all those snipets we can create a small test program. Sadly :ref:`RTEMS ` and the :ref:`BSP ` need some more configuring, but as the program would not run without them, we're going to show that as well. We've also added some ``printf`` to actually get a visible output (which one can only see if some type of console output is possible...): + +.. code-block:: c + + #include + + #include + + #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER + #define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER + + #define CONFIGURE_RTEMS_INIT_TASKS_TABLE + #define CONFIGURE_MAXIMUM_TASKS 1 + + #define CONFIGURE_INIT + #include + + #include + #include + + #include "math.h" + + void test() + { + double dbuf, ret; + + double d1 = 0.5, d2 = -2.0; + float f1 = 0.5f, f2 = -2.0f; + + printf("sin(%lf) = %lf\n", d1, sin(d1)); + printf("atan2(%lf, %lf) = %lf\n", d1, d2, atan2(d1, d2)); + ret = modf(d1, &dbuf); + printf("modf(%lf, %lf) = %lf\n", d1, dbuf, ret); + printf("isfinite(%lf) = %d\n", d1, isfinite(d1)); + + printf("cosf(%f) = %f\n", f1, cosf(f1)); + printf("powf(%f, %f) = %f\n", f1, f2, powf(f1, f2)); + printf("fmodf(%f, %f) = %f\n", f1, f2, fmodf(f1, f2)); + printf("signbit(%f) = %d\n", f1, signbit(f1)); + } + + #define GET_FSR(fsr) \ + asm volatile("st %%fsr, %[reg]" : [reg] "=g" (fsr) : "0" (fsr)); + + #define SET_FSR(fsr) \ + asm volatile("ld %[reg], %%fsr" : : [reg] "g" (fsr)); + + void ConfigurationMultiprocessingEnableFpu() + { + uint32_t psr; + sparc_get_psr(psr); + psr |= SPARC_PSR_EF_MASK; + sparc_set_psr(psr); + + uint32_t fsr; + GET_FSR(fsr); + fsr |= (1 << 22); + SET_FSR(fsr); + } + + rtems_task Init(rtems_task_argument arg) + { + ConfigurationMultiprocessingEnableFpu(); + + test(); + exit(0); + } + +Using the Software on a Typical Task +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Let's build the software using a shell command:: + + $ sparc-rtems-gcc test test_rtems.c libmcs/build-sparc_v8/bin/libm.a -Ilibmcs/libm/include -qleon3mp -frounding-math -fsignaling-nans -fno-builtin + +As one can see the command builds with the library, includes the header files, uses the LEON4 specific flag ``-qleon3mp`` (LEON3 and LEON4 use the same in this toolchain), and uses the flags provided in :ref:`OperationsEnviromentSoftwareConfiguration`, before finally producing the ``test`` executable. + +After running this program on the LEON4 platform it produces the following output on the console: + +.. code-block:: none + + sin(0.500000) = 0.479426 + atan2(0.500000, -2.000000) = 2.896614 + modf(0.500000, 0.000000) = 0.500000 + isfinite(0.500000) = 1 + + cosf(0.500000) = 0.877583 + powf(0.500000, -2.000000) = 4.000000 + fmodf(0.500000, -2.000000) = 0.500000 + signbit(0.500000) = 0 diff --git a/libm/libmcs/doc/sum/conf.py b/libm/libmcs/doc/sum/conf.py new file mode 100644 index 00000000..4414b1e1 --- /dev/null +++ b/libm/libmcs/doc/sum/conf.py @@ -0,0 +1,84 @@ +# Configuration file for the Sphinx documentation builder. +# +# This file only contains a selection of the most common options. For a +# full list see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Path setup ------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another +# directory, add these directories to sys.path here. If the directory is +# relative to the documentation root, use os.path.abspath to make it +# absolute, like shown here. +# +import os +import sys +from shutil import copyfile +import sphinx_rtd_theme # pylint: disable=unused-import +from sphinx.errors import ConfigError + +sys.path.insert(0, os.path.abspath("..")) + +# -- Project information ---------------------------------------------- + +project = "LibmCS - SUM" +copyright = "2025, GTD GmbH" +author = "GTD GmbH" + + +# -- General configuration -------------------------------------------- + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + "matplotlib.sphinxext.plot_directive", + "sphinx.ext.autodoc", + "sphinx.ext.autosectionlabel", + "sphinx.ext.mathjax", + "sphinx-mathjax-offline", + "sphinx_rtd_theme", + "hawkmoth", +] + +# Figures are referenced by number +numfig = True + +# Configuration for hawkmoth +hawkmoth_clang = ["-Ilibm/include", "-Isw-quality/dummy_includes"] +hawkmoth_root = os.path.abspath("../../libm") + +# Add any paths that contain templates here, relative to this directory. +templates_path = ["../_templates"] + +# -- Options for HTML output ------------------------------------------ + +# The theme to use for HTML and HTML Help pages. See the documentation +# for a list of builtin themes. +# +html_theme = "sphinx_rtd_theme" + +html_theme_options = { + "collapse_navigation": False, + "logo_only": True, +} + +html_logo = "../logo/libmcs-logo.png" +html_favicon = "../logo/libmcs-favicon.ico" + +# Add any paths that contain custom static files (such as style sheets) +# here, relative to this directory. They are copied after the builtin +# static files, so a file named "default.css" will overwrite the builtin +# "default.css". +html_static_path = ["../_static"] + +html_css_files = ["css/custom.css"] + +html_context = { + "display_gitlab": True, # Integrate Gitlab + "gitlab_host": "gitlab.com", + "gitlab_user": "gtd-gmbh", # Organization or User + "gitlab_repo": "libmcs", # Repo name + "gitlab_version": "development", # Version + "conf_py_path": "/doc/sum/", # Path in the checkout to the docs root +} diff --git a/libm/libmcs/doc/sum/index.rst b/libm/libmcs/doc/sum/index.rst new file mode 100644 index 00000000..dfe87533 --- /dev/null +++ b/libm/libmcs/doc/sum/index.rst @@ -0,0 +1,26 @@ +Mathematical Library for Critical Systems +========================================== + +The LibmCS library has been developed by re-engineering the ``libm`` included in the ``Newlib`` library version 4.0.0. The work has been carried out under ESA Contract No. 4000130278/20/NL/AS. + +Whenever changes were made to ``Newlib`` after version 4.0.0 they were checked and tested before being added to the library. Only those changes that made sense to be a part of the library were added. + +The following pages in this documentation try to give a xenodochial introduction into LibmCS to the user. + +This user manual also contains the :ref:`ICD `, most of its information can be found in the :ref:`Reference Manual`. + +.. toctree:: + :numbered: + :maxdepth: 2 + :caption: Software User Manual + + 1_Abbreviations + 2_Conventions + 3_Purpose_of_the_Software + 4_General_Behaviour + 5_External_View_of_the_Software + 6_Operations_Environment + 7_Operations_Manual + 8_Reference_Manual + 9_Tutorial + 10_Bindings diff --git a/libm/libmcs/libm/common/cmplx.c b/libm/libmcs/libm/common/cmplx.c new file mode 100644 index 00000000..53f7d0ed --- /dev/null +++ b/libm/libmcs/libm/common/cmplx.c @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: GTDGmbH */ +/* Copyright 2020-2025 by GTD GmbH. */ + +/** + * + * This family of macros is used to create a complex value out of the two + * inputs where :math:`x` is real and :math:`y` is the imaginary part. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float complex CMPLXF(float x, float y); + * double complex CMPLX(double x, double y); + * long double complex CMPLXL(long double x, long double y); + * + * Description + * =========== + * + * ``CMPLX`` creates a complex value out of the two inputs where :math:`x` is + * real and :math:`y` is the imaginary part. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * CMPLX(x, y) = x + iy + * + * Returns + * ======= + * + * ``CMPLX`` returns a complex value where :math:`x` is real and :math:`y` is + * the imaginary part. + * + */ diff --git a/libm/libmcs/libm/common/fenv.c b/libm/libmcs/libm/common/fenv.c new file mode 100644 index 00000000..ae91ab2e --- /dev/null +++ b/libm/libmcs/libm/common/fenv.c @@ -0,0 +1,59 @@ +/* SPDX-License-Identifier: GTDGmbH */ +/* Copyright 2020-2025 by GTD GmbH. */ + +#include "fenv.h" + +int feclearexcept(int excepts) +{ + return -1; +} + +int feraiseexcept(int excepts) +{ + return -1; +} + +int fegetexceptflag(fexcept_t *flagp, int excepts) +{ + return -1; +} + +int fesetexceptflag(const fexcept_t *flagp, int excepts) +{ + return -1; +} + +int fegetround(void) +{ + return -1; +} + +int fesetround(int rdir) +{ + return -1; +} + +int fegetenv(fenv_t *envp) +{ + return -1; +} + +int fesetenv(const fenv_t *envp) +{ + return -1; +} + +int feholdexcept(fenv_t *envp) +{ + return -1; +} + +int feupdateenv(const fenv_t *envp) +{ + return -1; +} + +int fetestexcept(int excepts) +{ + return -1; +} diff --git a/libm/libmcs/libm/common/isfinite.c b/libm/libmcs/libm/common/isfinite.c new file mode 100644 index 00000000..1e5fd687 --- /dev/null +++ b/libm/libmcs/libm/common/isfinite.c @@ -0,0 +1,52 @@ +/* SPDX-License-Identifier: GTDGmbH */ +/* Copyright 2020-2025 by GTD GmbH. */ + +/** + * + * This macro is used to test if :math:`x` is a finite floating-point value. It + * can be called with ``float``, ``double`` or ``long double`` input. This + * macro is implemented in ``math.h``. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * int isfinite(x); + * + * Description + * =========== + * + * ``isfinite`` tests whether the input value is finite (neither infinite nor + * :math:`NaN`) or not. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * isfinite(x) = \left\{\begin{array}{ll} 1, & x \in \mathbb{F} \setminus \left \{ \pm Inf, NaN \right \} \\ + * 0, & otherwise \end{array}\right. + * + * Returns + * ======= + * + * ``isfinite`` returns :math:`1` if the input is finite, else :math:`0`. + * + * Exceptions + * ========== + * + * Does not raise exceptions. + * + * Output map + * ========== + * + * +---------------------+--------------+------------------------------------------------------------------+--------------+-------------+ + * | **x** | :math:`-Inf` | :math:`\in \mathbb{F} \setminus \left \{ \pm Inf, NaN \right \}` | :math:`+Inf` | :math:`NaN` | + * +=====================+==============+==================================================================+==============+=============+ + * | **isfinite(x)** | :math:`0` | :math:`1` | :math:`0` | :math:`0` | + * +---------------------+--------------+------------------------------------------------------------------+--------------+-------------+ + * + */ + diff --git a/libm/libmcs/libm/common/isgreater.c b/libm/libmcs/libm/common/isgreater.c new file mode 100644 index 00000000..62d8e2db --- /dev/null +++ b/libm/libmcs/libm/common/isgreater.c @@ -0,0 +1,57 @@ +/* SPDX-License-Identifier: GTDGmbH */ +/* Copyright 2020-2025 by GTD GmbH. */ + +/** + * + * This macro is used to test if :math:`x` is greater than :math:`y` without + * throwing an ``invalid operation`` exception on ``NaN`` inputs (this even + * includes ``sNaN``). + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * int isgreater(x, y); + * + * Description + * =========== + * + * ``isgreater`` tests whether :math:`x` is greater than :math:`y` without + * throwing an ``invalid operation`` exception on ``NaN`` inputs. Not throwing + * an exception is the only difference to using a relational comparison + * operator. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * isgreater(x, y) = \left\{\begin{array}{ll} 1, & x > y \\ + * 0, & otherwise \end{array}\right. + * + * Returns + * ======= + * + * ``isgreater`` returns :math:`1` if :math:`x > y`, else :math:`0`. + * + * Exceptions + * ========== + * + * Does not raise exceptions. This includes ``sNaN`` inputs. + * + * Output map + * ========== + * + * +--------------------------+--------------------------+--------------------------+ + * | isgreater(x,y) | x | + * +--------------------------+--------------------------+--------------------------+ + * | y | :math:`\neq NaN` | :math:`NaN` | + * +==========================+==========================+==========================+ + * | :math:`\neq NaN` | :math:`x > y\ ?\ 1 : 0` | :math:`0` | + * +--------------------------+--------------------------+ + + * | :math:`NaN` | :math:`0` | | + * +--------------------------+--------------------------+--------------------------+ + * + */ diff --git a/libm/libmcs/libm/common/isgreaterequal.c b/libm/libmcs/libm/common/isgreaterequal.c new file mode 100644 index 00000000..394e4119 --- /dev/null +++ b/libm/libmcs/libm/common/isgreaterequal.c @@ -0,0 +1,57 @@ +/* SPDX-License-Identifier: GTDGmbH */ +/* Copyright 2020-2025 by GTD GmbH. */ + +/** + * + * This macro is used to test if :math:`x` is greater than or equal to + * :math:`y` without throwing an ``invalid operation`` exception on ``NaN`` + * inputs (this even includes ``sNaN``). + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * int isgreaterequal(x, y); + * + * Description + * =========== + * + * ``isgreaterequal`` tests whether :math:`x` is greater than or equal to + * :math:`y` without throwing an ``invalid operation`` exception on ``NaN`` + * inputs. Not throwing an exception is the only difference to using a + * relational comparison operator. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * isgreaterequal(x, y) = \left\{\begin{array}{ll} 1, & x \geq y \\ + * 0, & otherwise \end{array}\right. + * + * Returns + * ======= + * + * ``isgreaterequal`` returns :math:`1` if :math:`x \geq y`, else :math:`0`. + * + * Exceptions + * ========== + * + * Does not raise exceptions. This includes ``sNaN`` inputs. + * + * Output map + * ========== + * + * +--------------------------+--------------------------+--------------------------+ + * | isgreaterequal(x,y) | x | + * +--------------------------+--------------------------+--------------------------+ + * | y | :math:`\neq NaN` | :math:`NaN` | + * +==========================+==========================+==========================+ + * | :math:`\neq NaN` | :math:`x >= y\ ?\ 1 : 0` | :math:`0` | + * +--------------------------+--------------------------+ + + * | :math:`NaN` | :math:`0` | | + * +--------------------------+--------------------------+--------------------------+ + * + */ diff --git a/libm/libmcs/libm/common/isinf.c b/libm/libmcs/libm/common/isinf.c new file mode 100644 index 00000000..ac2af2a7 --- /dev/null +++ b/libm/libmcs/libm/common/isinf.c @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: GTDGmbH */ +/* Copyright 2020-2025 by GTD GmbH. */ + +/** + * + * This macro is used to test if :math:`x` is an infinite floating-point value. + * It can be called with ``float``, ``double`` or ``long double`` input. This + * macro is implemented in ``math.h``. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * int isinf(x); + * + * Description + * =========== + * + * ``isinf`` tests whether the input value is infinite or not. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * isinf(x) = \left\{\begin{array}{ll} 1, & x = \pm Inf \\ + * 0, & otherwise \end{array}\right. + * + * Returns + * ======= + * + * ``isinf`` returns :math:`1` if the input is infinite, else :math:`0`. + * + * Exceptions + * ========== + * + * Does not raise exceptions. + * + * Output map + * ========== + * + * +---------------------+--------------+------------------------------------------------------------------+--------------+-------------+ + * | **x** | :math:`-Inf` | :math:`\in \mathbb{F} \setminus \left \{ \pm Inf, NaN \right \}` | :math:`+Inf` | :math:`NaN` | + * +=====================+==============+==================================================================+==============+=============+ + * | **isinf(x)** | :math:`1` | :math:`0` | :math:`1` | :math:`0` | + * +---------------------+--------------+------------------------------------------------------------------+--------------+-------------+ + * + */ + diff --git a/libm/libmcs/libm/common/isless.c b/libm/libmcs/libm/common/isless.c new file mode 100644 index 00000000..0fa33c27 --- /dev/null +++ b/libm/libmcs/libm/common/isless.c @@ -0,0 +1,56 @@ +/* SPDX-License-Identifier: GTDGmbH */ +/* Copyright 2020-2025 by GTD GmbH. */ + +/** + * + * This macro is used to test if :math:`x` is less than :math:`y` without + * throwing an ``invalid operation`` exception on ``NaN`` inputs (this even + * includes ``sNaN``). + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * int isless(x, y); + * + * Description + * =========== + * + * ``isless`` tests whether :math:`x` is less than :math:`y` without throwing + * an ``invalid operation`` exception on ``NaN`` inputs. Not throwing an + * exception is the only difference to using a relational comparison operator. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * isless(x, y) = \left\{\begin{array}{ll} 1, & x < y \\ + * 0, & otherwise \end{array}\right. + * + * Returns + * ======= + * + * ``isless`` returns :math:`1` if :math:`x < y`, else :math:`0`. + * + * Exceptions + * ========== + * + * Does not raise exceptions. This includes ``sNaN`` inputs. + * + * Output map + * ========== + * + * +--------------------------+--------------------------+--------------------------+ + * | isless(x,y) | x | + * +--------------------------+--------------------------+--------------------------+ + * | y | :math:`\neq NaN` | :math:`NaN` | + * +==========================+==========================+==========================+ + * | :math:`\neq NaN` | :math:`x < y\ ?\ 1 : 0` | :math:`0` | + * +--------------------------+--------------------------+ + + * | :math:`NaN` | :math:`0` | | + * +--------------------------+--------------------------+--------------------------+ + * + */ diff --git a/libm/libmcs/libm/common/islessequal.c b/libm/libmcs/libm/common/islessequal.c new file mode 100644 index 00000000..63ed3e79 --- /dev/null +++ b/libm/libmcs/libm/common/islessequal.c @@ -0,0 +1,57 @@ +/* SPDX-License-Identifier: GTDGmbH */ +/* Copyright 2020-2025 by GTD GmbH. */ + +/** + * + * This macro is used to test if :math:`x` is less than or equal to :math:`y` + * without throwing an ``invalid operation`` exception on ``NaN`` inputs (this + * even includes ``sNaN``). + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * int islessequal(x, y); + * + * Description + * =========== + * + * ``islessequal`` tests whether :math:`x` is less than or equal to :math:`y` + * without throwing an ``invalid operation`` exception on ``NaN`` inputs. Not + * throwing an exception is the only difference to using a relational + * comparison operator. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * islessequal(x, y) = \left\{\begin{array}{ll} 1, & x \leq y \\ + * 0, & otherwise \end{array}\right. + * + * Returns + * ======= + * + * ``islessequal`` returns :math:`1` if :math:`x \leq y`, else :math:`0`. + * + * Exceptions + * ========== + * + * Does not raise exceptions. This includes ``sNaN`` inputs. + * + * Output map + * ========== + * + * +--------------------------+--------------------------+--------------------------+ + * | islessequal(x,y) | x | + * +--------------------------+--------------------------+--------------------------+ + * | y | :math:`\neq NaN` | :math:`NaN` | + * +==========================+==========================+==========================+ + * | :math:`\neq NaN` | :math:`x <= y\ ?\ 1 : 0` | :math:`0` | + * +--------------------------+--------------------------+ + + * | :math:`NaN` | :math:`0` | | + * +--------------------------+--------------------------+--------------------------+ + * + */ diff --git a/libm/libmcs/libm/common/islessgreater.c b/libm/libmcs/libm/common/islessgreater.c new file mode 100644 index 00000000..81309800 --- /dev/null +++ b/libm/libmcs/libm/common/islessgreater.c @@ -0,0 +1,57 @@ +/* SPDX-License-Identifier: GTDGmbH */ +/* Copyright 2020-2025 by GTD GmbH. */ + +/** + * + * This macro is used to test if :math:`x` is less than or greater than + * :math:`y` without throwing an ``invalid operation`` exception on ``NaN`` + * inputs (this even includes ``sNaN``). + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * int islessgreater(x, y); + * + * Description + * =========== + * + * ``islessgreater`` tests whether :math:`x` is less than or greater than + * :math:`y` without throwing an ``invalid operation`` exception on ``NaN`` + * inputs. Not throwing an exception is the only difference to using a + * relational comparison operator. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * islessgreater(x, y) = \left\{\begin{array}{ll} 1, & x < y \vee x > y \\ + * 0, & otherwise \end{array}\right. + * + * Returns + * ======= + * + * ``islessgreater`` returns :math:`1` if :math:`x < y \vee x > y`, else :math:`0`. + * + * Exceptions + * ========== + * + * Does not raise exceptions. This includes ``sNaN`` inputs. + * + * Output map + * ========== + * + * +--------------------------+--------------------------+--------------------------+ + * | islessgreater(x,y) | x | + * +--------------------------+--------------------------+--------------------------+ + * | y | :math:`\neq NaN` | :math:`NaN` | + * +==========================+==========================+==========================+ + * | :math:`\neq NaN` | :math:`x <> y\ ?\ 1 : 0` | :math:`0` | + * +--------------------------+--------------------------+ + + * | :math:`NaN` | :math:`0` | | + * +--------------------------+--------------------------+--------------------------+ + * + */ diff --git a/libm/libmcs/libm/common/isnan.c b/libm/libmcs/libm/common/isnan.c new file mode 100644 index 00000000..29f73288 --- /dev/null +++ b/libm/libmcs/libm/common/isnan.c @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: GTDGmbH */ +/* Copyright 2020-2025 by GTD GmbH. */ + +/** + * + * This macro is used to test if :math:`x` is a :math:`NaN`. It can be called + * with ``float``, ``double`` or ``long double`` input. This macro is + * implemented in ``math.h``. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * int isnan(x); + * + * Description + * =========== + * + * ``isnan`` tests whether the input value is a :math:`NaN` or not. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * isnan(x) = \left\{\begin{array}{ll} 1, & x = NaN \\ + * 0, & otherwise \end{array}\right. + * + * Returns + * ======= + * + * ``isnan`` returns :math:`1` if the input is a :math:`NaN`, else :math:`0`. + * + * Exceptions + * ========== + * + * Does not raise exceptions. + * + * Output map + * ========== + * + * +---------------------+--------------+------------------------------------------------------------------+--------------+-------------+ + * | **x** | :math:`-Inf` | :math:`\in \mathbb{F} \setminus \left \{ \pm Inf, NaN \right \}` | :math:`+Inf` | :math:`NaN` | + * +=====================+==============+==================================================================+==============+=============+ + * | **isnan(x)** | :math:`0` | :math:`0` | :math:`0` | :math:`1` | + * +---------------------+--------------+------------------------------------------------------------------+--------------+-------------+ + * + */ + diff --git a/libm/libmcs/libm/common/isnormal.c b/libm/libmcs/libm/common/isnormal.c new file mode 100644 index 00000000..f2565c0f --- /dev/null +++ b/libm/libmcs/libm/common/isnormal.c @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: GTDGmbH */ +/* Copyright 2020-2025 by GTD GmbH. */ + +/** + * + * This macro is used to test if :math:`x` is a normal floating-point value. It + * can be called with ``float``, ``double`` or ``long double`` input. This + * macro is implemented in ``math.h``. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * int isnormal(x); + * + * Description + * =========== + * + * ``isnormal`` tests whether the input value is a normal value or not. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * isnormal(x) = \left\{\begin{array}{ll} 1, & x \in \mathbb{F} \setminus (\left \{ \pm 0.0, \pm Inf, NaN \right \} \cup \mathbb{S}) \\ + * 0, & otherwise \end{array}\right. + * + * Returns + * ======= + * + * ``isnormal`` returns :math:`1` if the input is a normal value, else :math:`0`. + * + * Exceptions + * ========== + * + * Does not raise exceptions. + * + * Output map + * ========== + * + * +---------------------+--------------+---------------------------------------------------------------------------------------------+-----------------+------------------------+--------------+-------------+ + * | **x** | :math:`-Inf` | :math:`\in \mathbb{F} \setminus (\left \{ \pm 0.0, \pm Inf, NaN \right \} \cup \mathbb{S})` | :math:`\pm 0.0` | :math:`\in \mathbb{S}` | :math:`+Inf` | :math:`NaN` | + * +=====================+==============+=============================================================================================+=================+========================+==============+=============+ + * | **isnormal(x)** | :math:`0` | :math:`1` | :math:`0` | :math:`0` | :math:`0` | :math:`0` | + * +---------------------+--------------+---------------------------------------------------------------------------------------------+-----------------+------------------------+--------------+-------------+ + * + */ + diff --git a/libm/libmcs/libm/common/isunordered.c b/libm/libmcs/libm/common/isunordered.c new file mode 100644 index 00000000..e6df648b --- /dev/null +++ b/libm/libmcs/libm/common/isunordered.c @@ -0,0 +1,54 @@ +/* SPDX-License-Identifier: GTDGmbH */ +/* Copyright 2020-2025 by GTD GmbH. */ + +/** + * + * This macro is used to test if :math:`x` or :math:`y` are ``NaN``. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * int isunordered(x, y); + * + * Description + * =========== + * + * ``isunordered`` tests whether :math:`x` or :math:`y` are ``NaN`` as ``NaN`` + * values are neither less than, greater than, nor equal to another value, and + * as such cannot be ordered. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * isunordered(x, y) = \left\{\begin{array}{ll} 1, & x = \text{NaN} \vee y = \text{NaN} \\ + * 0, & otherwise \end{array}\right. + * + * Returns + * ======= + * + * ``isunordered`` returns :math:`1` if either input is ``NaN``, else :math:`0`. + * + * Exceptions + * ========== + * + * Does not raise exceptions. This includes ``sNaN`` inputs. + * + * Output map + * ========== + * + * +--------------------------+--------------------------+--------------------------+ + * | isunordered(x,y) | x | + * +--------------------------+--------------------------+--------------------------+ + * | y | :math:`\neq NaN` | :math:`NaN` | + * +==========================+==========================+==========================+ + * | :math:`\neq NaN` | :math:`0` | :math:`1` | + * +--------------------------+--------------------------+ + + * | :math:`NaN` | :math:`1` | | + * +--------------------------+--------------------------+--------------------------+ + * + */ diff --git a/libm/libmcs/libm/common/signgam.c b/libm/libmcs/libm/common/signgam.c new file mode 100644 index 00000000..ea38c7b0 --- /dev/null +++ b/libm/libmcs/libm/common/signgam.c @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GTDGmbH */ +/* Copyright 2020-2025 by GTD GmbH. */ + +/** + * + * This global variable is used to contain the sign of the integral within + * :ref:`lgamma`. Each call to :ref:`lgamma` will update :math:`signgam`. + * + * Note that usage of :math:`signgam` is not thread-safe when calling + * :ref:`lgamma` on multiple threads. + * + * The declaration of the macro :math:`signgam` is in ``math.h``. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * int signgam; + * + */ + +#include "math.h" + +int __signgam; diff --git a/libm/libmcs/libm/common/tools.c b/libm/libmcs/libm/common/tools.c new file mode 100644 index 00000000..bad606b2 --- /dev/null +++ b/libm/libmcs/libm/common/tools.c @@ -0,0 +1,7 @@ +/* SPDX-License-Identifier: GTDGmbH */ +/* Copyright 2020-2025 by GTD GmbH. */ + +#include "tools.h" + +const float __inff = 1.0f/0.0f; +const double __infd = 1.0/0.0; diff --git a/libm/libmcs/libm/common/tools.h b/libm/libmcs/libm/common/tools.h new file mode 100644 index 00000000..7b97d700 --- /dev/null +++ b/libm/libmcs/libm/common/tools.h @@ -0,0 +1,449 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +/** + * + * This file contains a set of functions used by multiple procedures as + * internal functions. These procedures should not be accessed directly by a + * user. Note that all procedures are either macros or static inline procedures. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include "tools.h" + * EXTRACT_WORDS(ix0,ix1,d); // this macro has no return value, the inputs are expected to be (int, int, double) + * GET_HIGH_WORD(i,d); // this macro has no return value, the inputs are expected to be (int, double) + * GET_LOW_WORD(i,d); // this macro has no return value, the inputs are expected to be (int, double) + * INSERT_WORDS(d,ix0,ix1); // this macro has no return value, the inputs are expected to be (double, int, int) + * SET_HIGH_WORD(d,v); // this macro has no return value, the inputs are expected to be (double, int) + * SET_LOW_WORD(d,v); // this macro has no return value, the inputs are expected to be (double, int) + * GET_FLOAT_WORD(i,d); // this macro has no return value, the inputs are expected to be (int, float) + * SET_FLOAT_WORD(d,i); // this macro has no return value, the inputs are expected to be (float, int) + * SAFE_RIGHT_SHIFT(op,amt); // this macros return value has the same type as input `op`, the inputs are expected to be integer types + * double __forced_calculation(double x); + * float __forced_calculationf(float x); + * double __raise_invalid(void); + * float __raise_invalidf(void); + * double __raise_div_by_zero(double x); + * float __raise_div_by_zerof(float x); + * double __raise_overflow(double x); + * float __raise_overflowf(float x); + * double __raise_underflow(double x); + * float __raise_underflowf(float x); + * double __raise_inexact(double x); + * float __raise_inexactf(float x); + * int __issignaling(double x); + * int __issignalingf(float x); + * REAL_PART(z); // this macros return value has the non-complex type of input `z`, the input is expected to be a complex floating-point datum + * IMAG_PART(z); // this macros return value has the non-complex type of input `z`, the input is expected to be a complex floating-point datum + * + * Description + * =========== + * + * ``EXTRACT_WORDS`` is a macro to extract two integer words from a double + * floating-point datum. + * + * ``GET_HIGH_WORD`` is a macro to extract only the highword of the two integer + * words from a double floating-point datum. + * + * ``GET_LOW_WORD`` is a macro to extract only the lowword of the two integer + * words from a double floating-point datum. + * + * ``INSERT_WORDS`` is a macro to insert two integer words into a double + * floating-point datum. + * + * ``SET_HIGH_WORD`` is a macro to insert only the highword of the two integer + * words into a double floating-point datum. + * + * ``SET_LOW_WORD`` is a macro to insert only the lowword of the two integer + * words into a double floating-point datum. + * + * ``GET_FLOAT_WORD`` is a macro to extract the integer representation from a + * single floating-point datum. + * + * ``SET_FLOAT_WORD`` is a macro to insert the integer representation into a + * single floating-point datum. + * + * ``SAFE_RIGHT_SHIFT`` is a macro to avoid undefined behaviour that can arise + * if the amount of a right shift is exactly equal to the size of the shifted + * operand. If the amount is equal to the size the macro returns 0. + * + * ``__forced_calculation`` is a function to force the execution of the input + * to go through the :ref:`FPU `. The input for this function is usually + * an arithmetic operation and not a single value. At the moment the function + * is only used by others within this file and not expected to be called from + * outside. + * + * ``__raise_invalid`` is a function to force the :ref:`FPU ` to generate + * an ``invalid operation`` exception. + * + * ``__raise_div_by_zero`` is a function to force the :ref:`FPU ` to + * generate an ``divide by zero`` exception. + * + * ``__raise_overflow`` is a function to force the :ref:`FPU ` to + * generate an ``overflow`` exception. + * + * ``__raise_underflow`` is a function to force the :ref:`FPU ` to + * generate an ``underflow`` exception. Even though the library usually does + * not care about this exception for qualification purposes, the library still + * tries to conform to the standards (mainly POSIX) in regards to where the + * exception shall be raised intentionally. In those places this function is + * used. + * + * ``__raise_inexact`` is a function to force the :ref:`FPU ` to generate + * an ``inexact`` exception. Even though the library usually does not care + * about this exception for qualification purposes, the library still tries to + * conform to the standards (mainly POSIX) in regards to where the exception + * shall be raised intentionally. In those places this function is used. + * + * ``__issignaling`` is a function to check if a value is a signaling NaN. + * + * ``REAL_PART`` is a macro to extract only the real part of a complex + * floating-point datum. + * + * ``IMAG_PART`` is a macro to extract only the imaginary part of a complex + * floating-point datum. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * EXTRACT\_WORDS_{ix0}(d) &= \text{highword of } d \\ + * EXTRACT\_WORDS_{ix1}(d) &= \text{lowword of } d \\ + * GET\_HIGH\_WORD_{i}(d) &= \text{highword of } d \\ + * GET\_LOW\_WORD_{i}(d) &= \text{lowword of } d \\ + * SET\_HIGH\_WORD_{\text{highword of } d}(d, v) &= d \text{ with highword } v \\ + * SET\_LOW\_WORD_{\text{lowword of } d}(d, v) &= d \text{ with lowword } v \\ + * GET\_FLOAT\_WORD_{i}(d) &= \text{integer representation of } d \\ + * SET\_FLOAT\_WORD_{d}(i) &= \text{floating-point representation of } i \\ + * SAFE\_RIGHT\_SHIFT(op, amt) &= \left\{\begin{array}{ll} op \gg amt, & amt < \text{size of } op \\ 0, & otherwise \end{array}\right. \\ + * \_\_forced\_calculation(x) &= x \\ + * \_\_raise\_invalid() &= NaN \\ + * \_\_raise\_div\_by\_zero(x) &= \left\{\begin{array}{ll} -Inf, & x \in \mathbb{F}^{-} \\ +Inf, & otherwise \end{array}\right. \\ + * \_\_raise\_overflow(x) &= \left\{\begin{array}{ll} -Inf, & x \in \mathbb{F}^{-} \\ +Inf, & otherwise \end{array}\right. \\ + * \_\_raise\_underflow(x) &= \left\{\begin{array}{ll} -0.0, & x \in \mathbb{F}^{-} \\ +0.0, & otherwise \end{array}\right. \\ + * \_\_raise\_inexact(x) &= x \\ + * \_\_issignaling(x) &= \left\{\begin{array}{ll} 1, & x = sNaN \\ 0, & otherwise \end{array}\right. \\ + * REAL\_PART(z) &= \Re(z) \\ + * IMAG\_PART(z) &= \Im(z) + * + * Returns + * ======= + * + * ``EXTRACT_WORDS`` has no return value. It places the two extracted integer + * words into the parameters ``ix0`` and ``ix1``. + * + * ``GET_HIGH_WORD`` has no return value. It places the extracted integer word + * into the parameter ``i``. + * + * ``GET_LOW_WORD`` has no return value. It places the extracted integer word + * into the parameter ``i``. + * + * ``INSERT_WORDS`` has no return value. It places the created double + * floating-point datum into the parameter ``d``. + * + * ``SET_HIGH_WORD`` has no return value. It places the created double + * floating-point datum into the parameter ``d``. + * + * ``SET_LOW_WORD`` has no return value. It places the created double + * floating-point datum into the parameter ``d``. + * + * ``GET_FLOAT_WORD`` has no return value. It places the extracted integer word + * into the parameter ``i``. + * + * ``SET_FLOAT_WORD`` has no return value. It places the created single + * floating-point datum into the parameter ``d``. + * + * ``SAFE_RIGHT_SHIFT`` returns the value ``op`` right shifted by ``amt`` if + * ``amt`` is smaller than the size of ``op``, otherwise it returns zero. + * + * ``__forced_calculation`` returns the input value, or rather the result of + * the arithmetic calculation used as an input. + * + * ``__raise_invalid`` returns ``NaN``. + * + * ``__raise_div_by_zero`` returns ``-Inf`` for negative inputs and ``+Inf`` + * for positive inputs. + * + * ``__raise_overflow`` returns ``-Inf`` for negative inputs and ``+Inf`` for + * positive inputs. + * + * ``__raise_underflow`` returns ``-0.0`` for negative inputs and ``+0.0`` for + * positive inputs. + * + * ``__raise_inexact`` returns the input value. + * + * ``__issignaling`` returns ``1`` if the input value is a signaling ``NaN``, + * else ``0``. + * + * ``REAL_PART`` returns the real part of the input as a floating-point datum + * of the adequate size. + * + * ``IMAG_PART`` returns the imaginary part of the input as a floating-point + * datum of the adequate size. + * + * Exceptions + * ========== + * + * The macros do not raise exceptions. + * + * The functions raise the exceptions they are named after, it is their sole + * purpose. Additionally the procedures ``__raise_overflow`` and + * ``__raise_underflow`` may raise ``inexact``. + * + */ + +#ifndef LIBMCS_TOOLS_H +#define LIBMCS_TOOLS_H + +#include +#include +#include + +#include + +#ifdef __LIBMCS_WANT_COMPLEX + #include +#endif /* __LIBMCS_WANT_COMPLEX */ + +/* A union which permits us to convert between a double and two 32 bit + ints. */ + +#ifdef __IEEE_BIG_ENDIAN + +typedef union { + double value; + struct { + uint32_t msw; + uint32_t lsw; + } parts; +} ieee_double_shape_type; + +#endif + +#ifdef __IEEE_LITTLE_ENDIAN + +typedef union { + double value; + struct { + uint32_t lsw; + uint32_t msw; + } parts; +} 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 == 1) + +/* 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 == 1) + +/* 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 == 1) + +/* 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 == 1) + +/* 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 == 1) + +/* 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 == 1) + +/* A union which permits us to convert between a float and a 32 bit + int. */ + +typedef union { + float value; + uint32_t 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 == 1) + +/* 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 == 1) + +/* Macros to avoid undefined behaviour that can arise if the amount + of a shift is exactly equal to the size of the shifted operand. */ + +#define SAFE_RIGHT_SHIFT(op,amt) \ + (((amt) < 8 * sizeof(op)) ? ((op) >> (amt)) : 0) + +/* Exception raising and signaling check functions */ + +static inline double __forced_calculation(double x); +static inline float __forced_calculationf(float x); + +static inline double __raise_invalid(void); +static inline double __raise_div_by_zero(double x); +static inline double __raise_overflow(double x); +static inline double __raise_underflow(double x); +static inline double __raise_inexact(double x); + +static inline float __raise_invalidf(void); +static inline float __raise_div_by_zerof(float x); +static inline float __raise_overflowf(float x); +static inline float __raise_underflowf(float x); +static inline float __raise_inexactf(float x); + +static inline int __issignaling(double x); +static inline int __issignalingf(float x); + + +static inline double __forced_calculation(double x) { + volatile double r = x; + return r; +} +static inline float __forced_calculationf(float x) { + volatile float r = x; + return r; +} + +static inline double __raise_invalid(void) { + double r = __forced_calculation(0.0 / 0.0); + return r; +} +static inline double __raise_div_by_zero(double x) { + return (signbit(x) != 0) ? __forced_calculation(-1.0 / 0.0) : __forced_calculation(1.0 / 0.0); +} +static inline double __raise_overflow(double x) { + volatile double huge = 1.0e300; + return (signbit(x) != 0) ? -__forced_calculation(huge * huge) : __forced_calculation(huge * huge); +} +static inline double __raise_underflow(double x) { + volatile double tiny = 1.0e-300; + return (signbit(x) != 0) ? -__forced_calculation(tiny * tiny) : __forced_calculation(tiny * tiny); +} +static inline double __raise_inexact(double x) { + volatile double huge = 1.0e300; + return (__forced_calculation(huge - 1.0e-300) != 0.0) ? x : 0.0; +} +static inline float __raise_invalidf(void) { + float r = __forced_calculationf(0.0f / 0.0f); + return r; +} +static inline float __raise_div_by_zerof(float x) { + return (signbit(x) != 0) ? __forced_calculationf(-1.0f / 0.0f) : __forced_calculationf(1.0f / 0.0f); +} +static inline float __raise_overflowf(float x) { + volatile float huge = 1.0e30f; + return (signbit(x) != 0) ? -__forced_calculationf(huge * huge) : __forced_calculationf(huge * huge); +} +static inline float __raise_underflowf(float x) { + volatile float tiny = 1.0e-30f; + return (signbit(x) != 0) ? -__forced_calculationf(tiny * tiny) : __forced_calculationf(tiny * tiny); +} +static inline float __raise_inexactf(float x) { + volatile float huge = 1.0e30f; + return (__forced_calculationf(huge - 1.0e-30f) != 0.0f) ? x : 0.0f; +} + +static inline int __issignaling(double x) { + uint32_t hx; + GET_HIGH_WORD(hx, x); + if (isnan(x) && (hx & 0x00080000U) == 0) { + return 1; + } + else { + return 0; + } +} +static inline int __issignalingf(float x) { + uint32_t ix; + GET_FLOAT_WORD(ix, x); + if (FLT_UWORD_IS_NAN(ix & 0x7fffffffU) && (ix & 0x00400000U) == 0) { + return 1; + } + else { + return 0; + } +} + +#ifdef __LIBMCS_WANT_COMPLEX + /* + * Quoting from ISO/IEC 9899:TC2: + * + * 6.2.5.13 Types + * Each complex type has the same representation and alignment requirements as + * an array type containing exactly two elements of the corresponding real type; + * the first element is equal to the real part, and the second element to the + * imaginary part, of the complex number. + */ + typedef union { + float complex z; + float parts[2]; + } float_complex; + + typedef union { + double complex z; + double parts[2]; + } double_complex; + + typedef union { + long double complex z; + long double parts[2]; + } long_double_complex; + + #define REAL_PART(z) ((z).parts[0]) + #define IMAG_PART(z) ((z).parts[1]) + +#endif /* __LIBMCS_WANT_COMPLEX */ + +#endif /* !LIBMCS_TOOLS_H */ diff --git a/libm/libmcs/libm/complexd/cabsd.c b/libm/libmcs/libm/complexd/cabsd.c new file mode 100644 index 00000000..86c89288 --- /dev/null +++ b/libm/libmcs/libm/complexd/cabsd.c @@ -0,0 +1,61 @@ +/* SPDX-License-Identifier: PublicDomain */ +/* Written by Matthias Drochner . */ + +/** + * + * This family of functions implements the absolute value ot the complex + * argument :math:`z`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float cabsf(float z); + * double cabs(double z); + * long double cabsl(long double z); + * + * Description + * =========== + * + * ``cabs`` computes the absolute value (also called norm, modulus, or + * magnitude) of the input value. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * cabs(z) \approx |z| + * + * Returns + * ======= + * + * ``cabs`` returns the absolute value of :math:`z`. + * + */ + +#include +#include + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +double cabs(double complex z) +{ +#ifdef __LIBMCS_FPU_DAZ + z *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + return hypot(creal(z), cimag(z)); +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double cabsl(long double complex z) +{ + return (long double) cabs((double complex) z); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/complexd/cacosd.c b/libm/libmcs/libm/complexd/cacosd.c new file mode 100644 index 00000000..47b86ed1 --- /dev/null +++ b/libm/libmcs/libm/complexd/cacosd.c @@ -0,0 +1,71 @@ +/* SPDX-License-Identifier: NetBSD */ + +/** + * + * This family of functions implements the complex arc cosine of :math:`z`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float complex cacosf(float complex z); + * double complex cacos(double complex z); + * long double complex cacosl(long double complex z); + * + * Description + * =========== + * + * ``cacos`` computes the complex inverse cosine (*arc cosine*) of the input + * value, with branch cuts outside the interval :math:`[-1, +1]` along the real + * axis. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * cacos(z) \approx cos^{-1}(z) + * + * Returns + * ======= + * + * ``cacos`` returns the complex inverse cosine of the input value in the + * output range of a strip mathematically unbounded along the imaginary axis + * and in the interval :math:`[0, \pi]` radians along the real axis. + * + */ + +#include +#include + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +double complex cacos(double complex z) +{ +#ifdef __LIBMCS_FPU_DAZ + z *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + double complex w; + double complex tmp0; + double tmp1; + + tmp0 = casin(z); + tmp1 = M_PI_2 - creal(tmp0); + /* w = tmp1 - (cimag(tmp0) * I); */ + w = CMPLX(tmp1, -cimag(tmp0)); + + return w; +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double complex cacosl(long double complex z) +{ + return (long double complex) cacos((double complex) z); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/complexd/cacoshd.c b/libm/libmcs/libm/complexd/cacoshd.c new file mode 100644 index 00000000..c83643ac --- /dev/null +++ b/libm/libmcs/libm/complexd/cacoshd.c @@ -0,0 +1,65 @@ +/* SPDX-License-Identifier: NetBSD */ + +/** + * + * This family of functions implements the complex hyperbolic arc cosine of :math:`z`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float complex cacoshf(float complex z); + * double complex cacosh(double complex z); + * long double complex cacoshl(long double complex z); + * + * Description + * =========== + * + * ``cacosh`` computes the complex hyperbolic inverse cosine (*arc cosine*) of + * the input value, with a branch cut at values less than :math:`+1` along the + * real axis. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * cacosh(z) \approx cosh^{-1}(z) + * + * Returns + * ======= + * + * ``cacosh`` returns the complex hyperbolic inverse cosine of the input value + * in the output range of a half-strip of non-negative values along the real + * axis and in the interval :math:`[-\pi i, +\pi i]` along the imaginary axis. + * + */ + +#include + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +double complex cacosh(double complex z) +{ +#ifdef __LIBMCS_FPU_DAZ + z *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + double complex w; + + w = clog(z + csqrt(z + 1) * csqrt(z - 1)); + + return w; +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double complex cacoshl(long double complex z) +{ + return (long double complex) cacosh((double complex) z); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/complexd/cargd.c b/libm/libmcs/libm/complexd/cargd.c new file mode 100644 index 00000000..c1c76f4f --- /dev/null +++ b/libm/libmcs/libm/complexd/cargd.c @@ -0,0 +1,61 @@ +/* SPDX-License-Identifier: PublicDomain */ +/* Written by Matthias Drochner . */ + +/** + * + * This family of functions implements the argument of :math:`z`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float cargf(float complex z); + * double carg(double complex z); + * long double cargl(long double complex z); + * + * Description + * =========== + * + * ``carg`` computes the argument (also called phase angle) of the input value, + * with a branch cut along the negative real axis. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * carg(z) \approx \varphi (z) = \tan^{-1} \frac{\Im(z)}{\Re(z)} + * + * Returns + * ======= + * + * ``carg`` returns the argument of the input value in the interval + * :math:`[-\pi, \pi]`. + * + */ + +#include +#include + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +double carg(double complex z) +{ +#ifdef __LIBMCS_FPU_DAZ + z *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + return atan2(cimag(z), creal(z)); +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double cargl(long double complex z) +{ + return (long double) carg((double complex) z); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/complexd/casind.c b/libm/libmcs/libm/complexd/casind.c new file mode 100644 index 00000000..b0a62e48 --- /dev/null +++ b/libm/libmcs/libm/complexd/casind.c @@ -0,0 +1,80 @@ +/* SPDX-License-Identifier: NetBSD */ + +/** + * + * This family of functions implements the complex arc sine of :math:`z`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float complex casinf(float complex z); + * double complex casin(double complex z); + * long double complex casinl(long double complex z); + * + * Description + * =========== + * + * ``casin`` computes the complex inverse sine (*arc sine*) of the input value, + * with branch cuts outside the interval :math:`[-1, +1]` along the real axis. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * casin(z) \approx sin^{-1}(z) + * + * Returns + * ======= + * + * ``casin`` returns the complex inverse sine of the input value in the output + * range of a strip mathematically unbounded along the imaginary axis and in + * the interval :math:`[-\frac{\pi}{2}, \frac{\pi}{2}]` radians along the real + * axis. + * + */ + +#include + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +double complex casin(double complex z) +{ +#ifdef __LIBMCS_FPU_DAZ + z *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + double complex w; + double complex ct, zz, z2; + double x, y; + + x = creal(z); + y = cimag(z); + + ct = CMPLX(-y, x); + /* zz = (x - y) * (x + y) + (2.0 * x * y) * I; */ + zz = CMPLX((x - y) * (x + y), 2.0 * x * y); + + /* zz = 1.0 - creal(zz) - cimag(zz) * I; */ + zz = CMPLX(1.0 - creal(zz), -cimag(zz)); + z2 = csqrt(zz); + + zz = ct + z2; + zz = clog(zz); + /* w = zz * (-1.0 * I); */ + w = CMPLX(cimag(zz), -creal(zz)); + return w; +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double complex casinl(long double complex z) +{ + return (long double complex) casin((double complex) z); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/complexd/casinhd.c b/libm/libmcs/libm/complexd/casinhd.c new file mode 100644 index 00000000..bb6f6595 --- /dev/null +++ b/libm/libmcs/libm/complexd/casinhd.c @@ -0,0 +1,70 @@ +/* SPDX-License-Identifier: NetBSD */ + +/** + * + * This family of functions implements the complex hyperbolic arc sine of + * :math:`z`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float complex casinhf(float complex z); + * double complex casinh(double complex z); + * long double complex casinhl(long double complex z); + * + * Description + * =========== + * + * ``casinh`` computes the complex hyperbolic inverse sine (*arc sine*) of the + * input value, with branch cuts outside the interval :math:`[-i, +i]` along + * the imaginary axis. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * casinh(z) \approx sinh^{-1}(z) + * + * Returns + * ======= + * + * ``casinh`` returns the complex hyperbolic inverse sine of the input value in + * the output range of a strip mathematically unbounded along the real axis and + * in the interval :math:`[-\frac{\pi}{2}i, \frac{\pi}{2}i]` along the + * imaginary axis. + * + */ + +#include + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +double complex casinh(double complex z) +{ +#ifdef __LIBMCS_FPU_DAZ + z *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + double complex w; + double complex tmp; + + /* w = -1.0 * I * casin(z * I); */ + tmp = CMPLX(-cimag(z), creal(z)); + tmp = casin(tmp); + w = CMPLX(cimag(tmp), -creal(tmp)); + return w; +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double complex casinhl(long double complex z) +{ + return (long double complex) casinh((double complex) z); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/complexd/catand.c b/libm/libmcs/libm/complexd/catand.c new file mode 100644 index 00000000..f2f00c90 --- /dev/null +++ b/libm/libmcs/libm/complexd/catand.c @@ -0,0 +1,91 @@ +/* SPDX-License-Identifier: NetBSD */ + +/** + * + * This family of functions implements the complex arc tangent of :math:`z`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float complex catanf(float complex z); + * double complex catan(double complex z); + * long double complex catanl(long double complex z); + * + * Description + * =========== + * + * ``catan`` computes the complex inverse tangent (*arc tangent*) of the input + * value, with branch cuts outside the interval :math:`[-i, +i]` along the + * imaginary axis. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * catan(z) \approx tan^{-1}(z) + * + * Returns + * ======= + * + * ``catan`` returns the complex inverse tangent of the input value in the + * output range of a strip mathematically unbounded along the imaginary axis + * and in the interval :math:`[-\frac{\pi}{2}, \frac{\pi}{2}]` radians along + * the real axis. + * + */ + +#include +#include +#include "internal/ctrigd.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +double complex catan(double complex z) +{ +#ifdef __LIBMCS_FPU_DAZ + z *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + double complex w; + double a, t, x, x2, y, tmp; + + x = creal(z); + y = cimag(z); + + if ((x == 0.0) && (y > 1.0)) { + goto ovrf; + } + + x2 = x * x; + a = 1.0 - x2 - (y * y); + + t = 0.5 * atan2(2.0 * x, a); + tmp = __redupi(t); + + t = y - 1.0; + a = x2 + (t * t); + + t = y + 1.0; + a = (x2 + (t * t)) / a; + /* w = tmp + (0.25 * log(a)) * I; */ + w = CMPLX(tmp, 0.25 * log(a)); + return w; + +ovrf: + w = CMPLX(HUGE_VAL, HUGE_VAL); + return w; +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double complex catanl(long double complex z) +{ + return (long double complex) catan((double complex) z); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/complexd/catanhd.c b/libm/libmcs/libm/complexd/catanhd.c new file mode 100644 index 00000000..a2dce220 --- /dev/null +++ b/libm/libmcs/libm/complexd/catanhd.c @@ -0,0 +1,70 @@ +/* SPDX-License-Identifier: NetBSD */ + +/** + * + * This family of functions implements the complex hyperbolic arc tangent of + * :math:`z`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float complex catanhf(float complex z); + * double complex catanh(double complex z); + * long double complex catanhl(long double complex z); + * + * Description + * =========== + * + * ``catanh`` computes the complex hyperbolic inverse tangent (*arc tangent*) + * of the input value, with branch cuts outside the interval :math:`[-1, +1]` + * along the real axis. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * catanh(z) \approx tanh^{-1}(z) + * + * Returns + * ======= + * + * ``catanh`` returns the complex hyperbolic inverse tangent of the input value + * in the output range of a strip mathematically unbounded along the real axis + * and in the interval :math:`[-\frac{\pi}{2}i, \frac{\pi}{2}i]` along the + * imaginary axis. + * + */ + +#include + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +double complex catanh(double complex z) +{ +#ifdef __LIBMCS_FPU_DAZ + z *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + double complex w; + double complex tmp; + + /* w = -1.0 * I * catan(z * I) */ + tmp = CMPLX(-cimag(z), creal(z)); + tmp = catan(tmp); + w = CMPLX(cimag(tmp), -creal(tmp)); + return w; +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double complex catanhl(long double complex z) +{ + return (long double complex) catanh((double complex) z); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/complexd/ccosd.c b/libm/libmcs/libm/complexd/ccosd.c new file mode 100644 index 00000000..de0116a3 --- /dev/null +++ b/libm/libmcs/libm/complexd/ccosd.c @@ -0,0 +1,65 @@ +/* SPDX-License-Identifier: NetBSD */ + +/** + * + * This family of functions implements the complex cosine of :math:`z`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float complex ccosf(float complex z); + * double complex ccos(double complex z); + * long double complex ccosl(long double complex z); + * + * Description + * =========== + * + * ``ccos`` computes the complex cosine of the input value. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * ccos(z) \approx cos(z) + * + * Returns + * ======= + * + * ``ccos`` returns the complex cosine of the input value. + * + */ + +#include +#include +#include "internal/ctrigd.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +double complex ccos(double complex z) +{ +#ifdef __LIBMCS_FPU_DAZ + z *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + double complex w; + double ch, sh; + + __ccoshsinh(cimag(z), &ch, &sh); + /* w = cos(creal(z)) * ch - (sin(creal(z)) * sh) * I; */ + w = CMPLX(cos(creal(z)) * ch, -(sin(creal(z)) * sh)); + return w; +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double complex ccosl(long double complex z) +{ + return (long double complex) ccos((double complex) z); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/complexd/ccoshd.c b/libm/libmcs/libm/complexd/ccoshd.c new file mode 100644 index 00000000..ed6f61f7 --- /dev/null +++ b/libm/libmcs/libm/complexd/ccoshd.c @@ -0,0 +1,66 @@ +/* SPDX-License-Identifier: NetBSD */ + +/** + * + * This family of functions implements the complex hyperbolic cosine of + * :math:`z`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float complex ccoshf(float complex z); + * double complex ccosh(double complex z); + * long double complex ccoshl(long double complex z); + * + * Description + * =========== + * + * ``ccosh`` computes the complex hyperbolic cosine of the input value. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * ccosh(z) \approx cosh(z) + * + * Returns + * ======= + * + * ``ccosh`` returns the complex hyperbolic cosine of the input value. + * + */ + +#include +#include + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +double complex ccosh(double complex z) +{ +#ifdef __LIBMCS_FPU_DAZ + z *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + double complex w; + double x, y; + + x = creal(z); + y = cimag(z); + /* w = cosh(x) * cos(y) + (sinh(x) * sin(y)) * I; */ + w = CMPLX(cosh(x) * cos(y), sinh(x) * sin(y)); + return w; +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double complex ccoshl(long double complex z) +{ + return (long double complex) ccosh((double complex) z); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/complexd/cexpd.c b/libm/libmcs/libm/complexd/cexpd.c new file mode 100644 index 00000000..102dbf38 --- /dev/null +++ b/libm/libmcs/libm/complexd/cexpd.c @@ -0,0 +1,67 @@ +/* SPDX-License-Identifier: NetBSD */ + +/** + * + * This family of functions implements the complex exponential function, that + * is :math:`e` powered by :math:`z`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float complex cexpf(float z); + * double complex cexp(double z); + * long double complex cexpl(long double z); + * + * Description + * =========== + * + * ``cexp`` computes :math:`e` powered by the input value. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * cexp(z) \approx e^z + * + * Returns + * ======= + * + * ``cexp`` returns :math:`e` powered by :math:`z`. + * + */ + +#include +#include + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +double complex cexp(double complex z) +{ +#ifdef __LIBMCS_FPU_DAZ + z *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + double complex w; + double r, x, y; + + x = creal(z); + y = cimag(z); + r = exp(x); + /* w = r * cos(y) + r * sin(y) * I; */ + w = CMPLX(r * cos(y), r * sin(y)); + return w; +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double complex cexpl(long double complex z) +{ + return (long double complex) cexp((double complex) z); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/complexd/cimagd.c b/libm/libmcs/libm/complexd/cimagd.c new file mode 100644 index 00000000..10400a30 --- /dev/null +++ b/libm/libmcs/libm/complexd/cimagd.c @@ -0,0 +1,58 @@ +/* SPDX-License-Identifier: PublicDomain */ +/* Written by Matthias Drochner . */ + +/** + * + * This family of functions returns the imaginary part of :math:`z` as a real. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float cimagf(float complex z); + * double cimag(double complex z); + * long double cimagl(long double complex z); + * + * Description + * =========== + * + * ``cimag`` computes the imaginary part of :math:`z` as a real. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * cimag(z) = \Im(z) + * + * Returns + * ======= + * + * ``cimag`` returns the imaginary part of :math:`z` as a real. + * + */ + +#include +#include "../common/tools.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +double cimag(double complex z) +{ + double_complex w; + w.z = z; + + return (IMAG_PART(w)); +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double cimagl(long double complex z) +{ + return (long double) cimag((double complex) z); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/complexd/clogd.c b/libm/libmcs/libm/complexd/clogd.c new file mode 100644 index 00000000..739bacaa --- /dev/null +++ b/libm/libmcs/libm/complexd/clogd.c @@ -0,0 +1,70 @@ +/* SPDX-License-Identifier: NetBSD */ + +/** + * + * This family of functions implements the complex natural logarithm function, + * that is :math:`ln(z)`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float complex clogf(float z); + * double complex clog(double z); + * long double complex clogl(long double z); + * + * Description + * =========== + * + * ``clog`` computes the complex natural logarithm of :math:`z`, with a branch + * cut along the negative real axis. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * clog(z) \approx ln(z) + * + * Returns + * ======= + * + * ``clog`` returns the complex natural logarithm of the input value in the + * output range of a strip mathematically unbounded along the real axis and in + * the interval :math:`[-\pi i, \pi i]` along the imaginary axis. + * + */ + +#include +#include + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +double complex clog(double complex z) +{ +#ifdef __LIBMCS_FPU_DAZ + z *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + double complex w; + double p, rr; + + rr = cabs(z); + p = log(rr); + rr = atan2(cimag(z), creal(z)); + /* w = p + rr * I; */ + w = CMPLX(p, rr); + return w; +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double complex clogl(long double complex z) +{ + return (long double complex) clog((double complex) z); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/complexd/conjd.c b/libm/libmcs/libm/complexd/conjd.c new file mode 100644 index 00000000..29877a65 --- /dev/null +++ b/libm/libmcs/libm/complexd/conjd.c @@ -0,0 +1,92 @@ +/* SPDX-License-Identifier: PublicDomain */ +/* Written by Matthias Drochner . */ + +/** + * + * This family of functions evaluates the complex conjugate of :math:`z`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float complex conjf(float complex z); + * double complex conj(double complex z); + * long double complex conjl(long double complex z); + * + * Description + * =========== + * + * ``conj`` computes the complex conjugate of :math:`z`. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * conj(z) = \Re(z) - \Im(z) \cdot i + * + * Returns + * ======= + * + * ``conj`` returns the complex conjugate of :math:`z`. + * + */ + +/* +FUNCTION + <>, <>---complex conjugate + +INDEX + conj +INDEX + conjf + +SYNOPSIS + #include + double complex conj(double complex <[z]>); + float complex conjf(float complex <[z]>); + + +DESCRIPTION + These functions compute the complex conjugate of <[z]>, + by reversing the sign of its imaginary part. + + <> is identical to <>, except that it performs + its calculations on <>. + +RETURNS + The conj functions return the complex conjugate value. + +PORTABILITY + <> and <> are ISO C99 + +QUICKREF + <> and <> are ISO C99 + +*/ + +#include +#include "../common/tools.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +double complex conj(double complex z) +{ + double_complex w = { .z = z }; + + IMAG_PART(w) = -IMAG_PART(w); + + return (w.z); +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double complex conjl(long double complex z) +{ + return (long double complex) conj((double complex) z); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/complexd/cpowd.c b/libm/libmcs/libm/complexd/cpowd.c new file mode 100644 index 00000000..63a15d6d --- /dev/null +++ b/libm/libmcs/libm/complexd/cpowd.c @@ -0,0 +1,85 @@ +/* SPDX-License-Identifier: NetBSD */ + +/** + * + * This family of functions implements the value of complex :math:`x` raised to + * the power of complex :math:`y`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float complex cpowf(float complex x, float complex y); + * double complex cpow(double complex x, double complex y); + * long double complex cpowl(long double complex x, long double complex y); + * + * Description + * =========== + * + * ``cpow`` computes the value of complex :math:`x` raised to the power of + * complex :math:`y`, with a branch cut for the first parameter along the + * negative real axis. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * cpow(x, y) \approx x^y + * + * Returns + * ======= + * + * ``cpow`` returns the value of complex :math:`x` raised to the power of + * complex :math:`y`. + * + */ + +#include +#include + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +double complex cpow(double complex x, double complex y) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_one; + y *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + double complex w; + double realz, imagz, result, theta, absx, argx; + + realz = creal(y); + imagz = cimag(y); + absx = cabs(x); + + if (absx == 0.0) { + return CMPLX(0.0, 0.0); + } + + argx = carg(x); + result = pow(absx, realz); + theta = realz * argx; + + if (imagz != 0.0) { + result = result * exp(-imagz * argx); + theta = theta + imagz * log(absx); + } + + /* w = result * cos(theta) + (result * sin(theta)) * I; */ + w = CMPLX(result * cos(theta), result * sin(theta)); + return w; +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double complex cpowl(long double complex x, long double complex y) +{ + return (long double complex) cpow((double complex) x, (double complex) y); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/complexd/cprojd.c b/libm/libmcs/libm/complexd/cprojd.c new file mode 100644 index 00000000..cb9aa153 --- /dev/null +++ b/libm/libmcs/libm/complexd/cprojd.c @@ -0,0 +1,78 @@ +/* SPDX-License-Identifier: NetBSD */ + +/** + * + * This family of functions evaluates the value of the projection of the + * complex argument :math:`z` onto the Riemann sphere. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float complex cprojf(float complex z); + * double complex cproj(double complex z); + * long double complex cprojl(long double complex z); + * + * Description + * =========== + * + * ``cproj`` computes the value of the projection of :math:`z` onto the Riemann + * sphere. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * cproj(z) = \left\{\begin{array}{ll} z, & \Re(z) \neq \pm Inf \wedge \Im(z) \neq \pm Inf \\ +Inf \pm 0i, & otherwise \end{array}\right. + * + * Returns + * ======= + * + * ``cproj`` returns the value of the projection of :math:`z` onto the Riemann + * sphere. + * + */ + +#include +#include + +#include "../common/tools.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +/* + * cproj(double complex z) + * + * These functions return the value of the projection (not stereographic!) + * onto the Riemann sphere. + * + * z projects to z, except that all complex infinities (even those with one + * infinite part and one NaN part) project to positive infinity on the real axis. + * If z has an infinite part, then cproj(z) shall be equivalent to: + * + * INFINITY + I * copysign(0.0, cimag(z)) + */ +double complex cproj(double complex z) +{ + double_complex w = { .z = z }; + + if (isinf(REAL_PART(w)) || isinf(IMAG_PART(w))) { + REAL_PART(w) = INFINITY; + IMAG_PART(w) = copysign(0.0, cimag(z)); + } + + return (w.z); +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double complex cprojl(long double complex z) +{ + return (long double complex) cproj((double complex) z); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/complexd/creald.c b/libm/libmcs/libm/complexd/creald.c new file mode 100644 index 00000000..de49cfc3 --- /dev/null +++ b/libm/libmcs/libm/complexd/creald.c @@ -0,0 +1,58 @@ +/* SPDX-License-Identifier: PublicDomain */ +/* Written by Matthias Drochner . */ + +/** + * + * This family of functions returns the real part of :math:`z` as a real. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float crealf(float complex z); + * double creal(double complex z); + * long double creall(long double complex z); + * + * Description + * =========== + * + * ``creal`` computes the real part of :math:`z` as a real. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * creal(z) = \Re(z) + * + * Returns + * ======= + * + * ``creal`` returns the real part of :math:`z` as a real. + * + */ + +#include +#include "../common/tools.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +double creal(double complex z) +{ + double_complex w; + w.z = z; + + return (REAL_PART(w)); +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double creall(long double complex z) +{ + return (long double) creal((double complex) z); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/complexd/csind.c b/libm/libmcs/libm/complexd/csind.c new file mode 100644 index 00000000..c1f799c1 --- /dev/null +++ b/libm/libmcs/libm/complexd/csind.c @@ -0,0 +1,65 @@ +/* SPDX-License-Identifier: NetBSD */ + +/** + * + * This family of functions implements the complex sine of :math:`z`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float complex csinf(float complex z); + * double complex csin(double complex z); + * long double complex csinl(long double complex z); + * + * Description + * =========== + * + * ``csin`` computes the complex sine of the input value. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * csin(z) \approx sin(z) + * + * Returns + * ======= + * + * ``csin`` returns the complex sine of the input value. + * + */ + +#include +#include +#include "internal/ctrigd.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +double complex csin(double complex z) +{ +#ifdef __LIBMCS_FPU_DAZ + z *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + double complex w; + double ch, sh; + + __ccoshsinh(cimag(z), &ch, &sh); + /* w = sin(creal(z)) * ch + (cos(creal(z)) * sh) * I; */ + w = CMPLX(sin(creal(z)) * ch, cos(creal(z)) * sh); + return w; +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double complex csinl(long double complex z) +{ + return (long double complex) csin((double complex) z); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/complexd/csinhd.c b/libm/libmcs/libm/complexd/csinhd.c new file mode 100644 index 00000000..1c2ae076 --- /dev/null +++ b/libm/libmcs/libm/complexd/csinhd.c @@ -0,0 +1,65 @@ +/* SPDX-License-Identifier: NetBSD */ + +/** + * + * This family of functions implements the complex hyperbolic sine of :math:`z`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float complex csinhf(float complex z); + * double complex csinh(double complex z); + * long double complex csinhl(long double complex z); + * + * Description + * =========== + * + * ``csinh`` computes the complex hyperbolic sine of the input value. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * csinh(z) \approx sinh(z) + * + * Returns + * ======= + * + * ``csinh`` returns the complex hyperbolic sine of the input value. + * + */ + +#include +#include + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +double complex csinh(double complex z) +{ +#ifdef __LIBMCS_FPU_DAZ + z *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + double complex w; + double x, y; + + x = creal(z); + y = cimag(z); + /* w = sinh(x) * cos(y) + (cosh(x) * sin(y)) * I; */ + w = CMPLX(sinh(x) * cos(y), cosh(x) * sin(y)); + return w; +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double complex csinhl(long double complex z) +{ + return (long double complex) csinh((double complex) z); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/complexd/csqrtd.c b/libm/libmcs/libm/complexd/csqrtd.c new file mode 100644 index 00000000..0f0865bd --- /dev/null +++ b/libm/libmcs/libm/complexd/csqrtd.c @@ -0,0 +1,126 @@ +/* SPDX-License-Identifier: NetBSD */ + +/** + * + * This family of functions implements the complex square root of :math:`z`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float complex csqrtf(float complex z); + * double complex csqrt(double complex z); + * long double complex csqrtl(long double complex z); + * + * Description + * =========== + * + * ``csqrt`` computes the complex square root of the input value, with a branch + * cut along the negative real axis. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * csqrt(z) \approx \sqrt{z} + * + * Returns + * ======= + * + * ``csqrt`` returns the complex square root of the input value, in the range + * of the right halfplane (including the imaginary axis). + * + */ + +#include +#include + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +double complex csqrt(double complex z) +{ +#ifdef __LIBMCS_FPU_DAZ + z *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + double complex w; + double x, y, r, t, scale; + + x = creal(z); + y = cimag(z); + + if (y == 0.0) { + if (x == 0.0) { + w = CMPLX(0.0, y); + } else { + r = fabs(x); + r = sqrt(r); + + if (x < 0.0) { + w = CMPLX(0.0, r); + } else { + w = CMPLX(r, y); + } + } + + return w; + } + + if (x == 0.0) { + r = fabs(y); + r = sqrt(0.5 * r); + + if (y > 0) { + w = CMPLX(r, r); + } else { + w = CMPLX(r, -r); + } + + return w; + } + + /* Rescale to avoid internal overflow or underflow. */ + if ((fabs(x) > 4.0) || (fabs(y) > 4.0)) { + x *= 0.25; + y *= 0.25; + scale = 2.0; + } else { + x *= 1.8014398509481984e16; /* 2^54 */ + y *= 1.8014398509481984e16; + scale = 7.450580596923828125e-9; /* 2^-27 */ + } + + w = CMPLX(x, y); + r = cabs(w); + + if (x > 0) { + t = sqrt(0.5 * r + 0.5 * x); + r = scale * fabs((0.5 * y) / t); + t *= scale; + } else { + r = sqrt(0.5 * r - 0.5 * x); + t = scale * fabs((0.5 * y) / r); + r *= scale; + } + + if (y < 0) { + w = CMPLX(t, -r); + } else { + w = CMPLX(t, r); + } + + return w; +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double complex csqrtl(long double complex z) +{ + return (long double complex) csqrt((double complex) z); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/complexd/ctand.c b/libm/libmcs/libm/complexd/ctand.c new file mode 100644 index 00000000..3590645d --- /dev/null +++ b/libm/libmcs/libm/complexd/ctand.c @@ -0,0 +1,120 @@ +/* SPDX-License-Identifier: NetBSD */ + +/** + * + * This family of functions implements the complex tangent of :math:`z`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float complex ctanf(float complex z); + * double complex ctan(double complex z); + * long double complex ctanl(long double complex z); + * + * Description + * =========== + * + * ``ctan`` computes the complex tangent of the input value. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * ctan(z) \approx tan(z) + * + * Returns + * ======= + * + * ``ctan`` returns the complex tangent of the input value. + * + */ + +#include +#include +#include "internal/ctrigd.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +/* Taylor series expansion for cosh(2y) - cos(2x) */ + +static inline 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) +{ +#ifdef __LIBMCS_FPU_DAZ + z *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + 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) { + w = CMPLX(HUGE_VAL, HUGE_VAL); + return w; + } + + /* w = sin(2.0 * creal(z)) / d + (sinh(2.0 * cimag(z)) / d) * I; */ + w = CMPLX(sin(2.0 * creal(z)) / d, sinh(2.0 * cimag(z)) / d); + return w; +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double complex ctanl(long double complex z) +{ + return (long double complex) ctan((double complex) z); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/complexd/ctanhd.c b/libm/libmcs/libm/complexd/ctanhd.c new file mode 100644 index 00000000..5f9cd3ce --- /dev/null +++ b/libm/libmcs/libm/complexd/ctanhd.c @@ -0,0 +1,67 @@ +/* SPDX-License-Identifier: NetBSD */ + +/** + * + * This family of functions implements the complex hyperbolic tangent of :math:`z`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float complex ctanhf(float complex z); + * double complex ctanh(double complex z); + * long double complex ctanhl(long double complex z); + * + * Description + * =========== + * + * ``ctanh`` computes the complex hyperbolic tangent of the input value. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * ctanh(z) \approx tanh(z) + * + * Returns + * ======= + * + * ``ctanh`` returns the complex hyperbolic tangent of the input value. + * + */ + +#include +#include + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +double complex ctanh(double complex z) +{ +#ifdef __LIBMCS_FPU_DAZ + z *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + double complex w; + double x, y, d; + + x = creal(z); + y = cimag(z); + d = cosh(2.0 * x) + cos(2.0 * y); + /* w = sinh(2.0 * x) / d + (sin(2.0 * y) / d) * I; */ + w = CMPLX(sinh(2.0 * x) / d, sin(2.0 * y) / d); + + return w; +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double complex ctanhl(long double complex z) +{ + return (long double complex) ctanh((double complex) z); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/complexd/internal/ctrigd.c b/libm/libmcs/libm/complexd/internal/ctrigd.c new file mode 100644 index 00000000..db08cdc8 --- /dev/null +++ b/libm/libmcs/libm/complexd/internal/ctrigd.c @@ -0,0 +1,58 @@ +/* SPDX-License-Identifier: NetBSD */ + +#include +#include + +#include "ctrigd.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +/* calculate cosh and sinh */ + +void __ccoshsinh(double x, double *c, double *s) +{ + double e, ei; + + if (fabs(x) <= 0.5) { + *c = cosh(x); + *s = sinh(x); + } else { + e = exp(x); + if (__fpclassifyd(e) != FP_ZERO) { + ei = 0.5 / e; + } else { + ei = HUGE_VAL; + } + e = 0.5 * e; + *s = e - ei; + *c = e + ei; + } +} + +/* Program to subtract nearest integer multiple of PI */ + +/* extended precision value of PI: */ +static const double DP1 = 3.14159265160560607910E0; +static const double DP2 = 1.98418714791870343106E-9; +static const double DP3 = 1.14423774522196636802E-17; + +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; +} + +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/complexd/internal/ctrigd.h b/libm/libmcs/libm/complexd/internal/ctrigd.h new file mode 100644 index 00000000..cf3180ad --- /dev/null +++ b/libm/libmcs/libm/complexd/internal/ctrigd.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GTDGmbH */ +/* Copyright 2020-2025 by GTD GmbH. */ + +#ifndef LIBMCS_CTRIGD_H +#define LIBMCS_CTRIGD_H + +#define MACHEP 1.1e-16 + +extern void __ccoshsinh(double x, double *c, double *s); +extern double __redupi(double x); + +#endif /* !LIBMCS_CTRIGD_H */ diff --git a/libm/libmcs/libm/complexf/cabsf.c b/libm/libmcs/libm/complexf/cabsf.c new file mode 100644 index 00000000..1f3eccc6 --- /dev/null +++ b/libm/libmcs/libm/complexf/cabsf.c @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: PublicDomain */ +/* Written by Matthias Drochner . */ + +#include +#include + +float cabsf(float complex z) +{ +#ifdef __LIBMCS_FPU_DAZ + z *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + return hypotf(crealf(z), cimagf(z)); +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double cabs(double complex z) +{ + return (double) cabsf((float complex) z); +} + +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/complexf/cacosf.c b/libm/libmcs/libm/complexf/cacosf.c new file mode 100644 index 00000000..ca1a3234 --- /dev/null +++ b/libm/libmcs/libm/complexf/cacosf.c @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: NetBSD */ + +#include +#include + +float complex cacosf(float complex z) +{ +#ifdef __LIBMCS_FPU_DAZ + z *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + float complex w; + float complex tmp0; + float tmp1; + + tmp0 = casinf(z); + tmp1 = (float)M_PI_2 - crealf(tmp0); + w = CMPLXF(tmp1, -cimagf(tmp0)); + + return w; +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double complex cacos(double complex z) +{ + return (double complex) cacosf((float complex) z); +} + +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/complexf/cacoshf.c b/libm/libmcs/libm/complexf/cacoshf.c new file mode 100644 index 00000000..de5febae --- /dev/null +++ b/libm/libmcs/libm/complexf/cacoshf.c @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: NetBSD */ + +#include + +float complex cacoshf(float complex z) +{ +#ifdef __LIBMCS_FPU_DAZ + z *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + float complex w; + + w = clogf(z + csqrtf(z + 1) * csqrtf(z - 1)); + + return w; +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double complex cacosh(double complex z) +{ + return (double complex) cacoshf((float complex) z); +} + +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/complexf/cargf.c b/libm/libmcs/libm/complexf/cargf.c new file mode 100644 index 00000000..b4260015 --- /dev/null +++ b/libm/libmcs/libm/complexf/cargf.c @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: PublicDomain */ +/* Written by Matthias Drochner . */ + +#include +#include + +float cargf(float complex z) +{ +#ifdef __LIBMCS_FPU_DAZ + z *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + return atan2f(cimagf(z), crealf(z)); +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double carg(double complex z) +{ + return (double) cargf((float complex) z); +} + +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/complexf/casinf.c b/libm/libmcs/libm/complexf/casinf.c new file mode 100644 index 00000000..a38b9481 --- /dev/null +++ b/libm/libmcs/libm/complexf/casinf.c @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: NetBSD */ + +#include + +float complex casinf(float complex z) +{ +#ifdef __LIBMCS_FPU_DAZ + z *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + float complex w; + float complex ct, zz, z2; + float x, y; + + x = crealf(z); + y = cimagf(z); + + ct = CMPLXF(-y, x); + /* zz = (x - y) * (x + y) + (2.0f * x * y) * I; */ + zz = CMPLXF((x - y) * (x + y), 2.0f * x * y); + + /* zz = 1.0f - crealf(zz) - cimagf(zz) * I; */ + zz = CMPLXF(1.0f - crealf(zz), -cimagf(zz)); + z2 = csqrtf(zz); + + zz = ct + z2; + zz = clogf(zz); + /* w = zz * (-1.0f * I); */ + w = CMPLXF(cimagf(zz), -crealf(zz)); + return w; +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double complex casin(double complex z) +{ + return (double complex) casinf((float complex) z); +} + +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/complexf/casinhf.c b/libm/libmcs/libm/complexf/casinhf.c new file mode 100644 index 00000000..d827b3fc --- /dev/null +++ b/libm/libmcs/libm/complexf/casinhf.c @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: NetBSD */ + +#include + +float complex casinhf(float complex z) +{ +#ifdef __LIBMCS_FPU_DAZ + z *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + float complex w; + float complex tmp; + + /* w = -1.0f * I * casinf(z * I); */ + tmp = CMPLXF(-cimagf(z), crealf(z)); + tmp = casinf(tmp); + w = CMPLXF(cimagf(tmp), -crealf(tmp)); + return w; +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double complex casinh(double complex z) +{ + return (double complex) casinhf((float complex) z); +} + +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/complexf/catanf.c b/libm/libmcs/libm/complexf/catanf.c new file mode 100644 index 00000000..f8d034e8 --- /dev/null +++ b/libm/libmcs/libm/complexf/catanf.c @@ -0,0 +1,50 @@ +/* SPDX-License-Identifier: NetBSD */ + +#include +#include +#include "internal/ctrigf.h" + +float complex catanf(float complex z) +{ +#ifdef __LIBMCS_FPU_DAZ + z *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + float complex w; + float a, t, x, x2, y, tmp; + + x = crealf(z); + y = cimagf(z); + + if ((x == 0.0f) && (y > 1.0f)) { + goto ovrf; + } + + x2 = x * x; + a = 1.0f - x2 - (y * y); + + t = 0.5f * atan2f(2.0f * x, a); + tmp = __redupif(t); + + t = y - 1.0f; + a = x2 + (t * t); + + t = y + 1.0f; + a = (x2 + (t * t)) / a; + /* w = tmp + (0.25f * logf(a)) * I; */ + w = CMPLXF(tmp, 0.25f * logf(a)); + return w; + +ovrf: + w = CMPLXF(HUGE_VALF, HUGE_VALF); + return w; +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double complex catan(double complex z) +{ + return (double complex) catanf((float complex) z); +} + +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/complexf/catanhf.c b/libm/libmcs/libm/complexf/catanhf.c new file mode 100644 index 00000000..5660d20b --- /dev/null +++ b/libm/libmcs/libm/complexf/catanhf.c @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: NetBSD */ + +#include + +float complex catanhf(float complex z) +{ +#ifdef __LIBMCS_FPU_DAZ + z *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + float complex w; + float complex tmp; + + /* w = -1.0f * I * catanf(z * I); */ + tmp = CMPLXF(-cimagf(z), crealf(z)); + tmp = catanf(tmp); + w = CMPLXF(cimagf(tmp), -crealf(tmp)); + return w; +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double complex catanh(double complex z) +{ + return (double complex) catanhf((float complex) z); +} + +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/complexf/ccosf.c b/libm/libmcs/libm/complexf/ccosf.c new file mode 100644 index 00000000..0df90fa4 --- /dev/null +++ b/libm/libmcs/libm/complexf/ccosf.c @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: NetBSD */ + +#include +#include +#include "internal/ctrigf.h" + +float complex ccosf(float complex z) +{ +#ifdef __LIBMCS_FPU_DAZ + z *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + float complex w; + float ch, sh; + + __ccoshsinhf(cimagf(z), &ch, &sh); + /* w = cosf(crealf(z)) * ch - (sinf(crealf(z)) * sh) * I; */ + w = CMPLXF(cosf(crealf(z)) * ch, -(sinf(crealf(z)) * sh)); + return w; +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double complex ccos(double complex z) +{ + return (double complex) ccosf((float complex) z); +} + +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/complexf/ccoshf.c b/libm/libmcs/libm/complexf/ccoshf.c new file mode 100644 index 00000000..79c1fd8c --- /dev/null +++ b/libm/libmcs/libm/complexf/ccoshf.c @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: NetBSD */ + +#include +#include + +float complex ccoshf(float complex z) +{ +#ifdef __LIBMCS_FPU_DAZ + z *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + float complex w; + float x, y; + + x = crealf(z); + y = cimagf(z); + /* w = coshf(x) * cosf(y) + (sinhf(x) * sinf(y)) * I; */ + w = CMPLXF(coshf(x) * cosf(y), sinhf(x) * sinf(y)); + return w; +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double complex ccosh(double complex z) +{ + return (double complex) ccoshf((float complex) z); +} + +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/complexf/cexpf.c b/libm/libmcs/libm/complexf/cexpf.c new file mode 100644 index 00000000..b27fe943 --- /dev/null +++ b/libm/libmcs/libm/complexf/cexpf.c @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: NetBSD */ + +#include +#include + +float complex cexpf(float complex z) +{ +#ifdef __LIBMCS_FPU_DAZ + z *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + float complex w; + float r, x, y; + + x = crealf(z); + y = cimagf(z); + r = expf(x); + /* w = r * cosf(y) + r * sinf(y) * I; */ + w = CMPLXF(r * cosf(y), r * sinf(y)); + return w; +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double complex cexp(double complex z) +{ + return (double complex) cexpf((float complex) z); +} + +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/complexf/cimagf.c b/libm/libmcs/libm/complexf/cimagf.c new file mode 100644 index 00000000..b0115327 --- /dev/null +++ b/libm/libmcs/libm/complexf/cimagf.c @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: PublicDomain */ +/* Written by Matthias Drochner . */ + +#include +#include "../common/tools.h" + +float cimagf(float complex z) +{ + float_complex w; + w.z = z; + + return (IMAG_PART(w)); +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double cimag(double complex z) +{ + return (double) cimagf((float complex) z); +} + +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/complexf/clogf.c b/libm/libmcs/libm/complexf/clogf.c new file mode 100644 index 00000000..31bc1af3 --- /dev/null +++ b/libm/libmcs/libm/complexf/clogf.c @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: NetBSD */ + +#include +#include + +float complex clogf(float complex z) +{ +#ifdef __LIBMCS_FPU_DAZ + z *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + float complex w; + float p, rr; + + rr = cabsf(z); + p = logf(rr); + rr = atan2f(cimagf(z), crealf(z)); + /* w = p + rr * I; */ + w = CMPLXF(p, rr); + return w; +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double complex clog(double complex z) +{ + return (double complex) clogf((float complex) z); +} + +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/complexf/conjf.c b/libm/libmcs/libm/complexf/conjf.c new file mode 100644 index 00000000..8a783f0e --- /dev/null +++ b/libm/libmcs/libm/complexf/conjf.c @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: PublicDomain */ +/* Written by Matthias Drochner . */ + +#include +#include "../common/tools.h" + +float complex conjf(float complex z) +{ + float_complex w = { .z = z }; + + IMAG_PART(w) = -IMAG_PART(w); + + return (w.z); +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double complex conj(double complex z) +{ + return (double complex) conjf((float complex) z); +} + +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/complexf/cpowf.c b/libm/libmcs/libm/complexf/cpowf.c new file mode 100644 index 00000000..f18b6aad --- /dev/null +++ b/libm/libmcs/libm/complexf/cpowf.c @@ -0,0 +1,45 @@ +/* SPDX-License-Identifier: NetBSD */ + +#include +#include + +float complex cpowf(float complex x, float complex y) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_onef; + y *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + float complex w; + float realz, imagz, result, theta, absx, argx; + + realz = crealf(y); + imagz = cimagf(y); + absx = cabsf(x); + + if (absx == 0.0f) { + return CMPLXF(0.0f, 0.0f); + } + + argx = cargf(x); + result = powf(absx, realz); + theta = realz * argx; + + if (imagz != 0.0f) { + result = result * expf(-imagz * argx); + theta = theta + imagz * logf(absx); + } + + /*w = result * cosf(theta) + (result * sinf(theta)) * I; */ + w = CMPLXF(result * cosf(theta), result * sinf(theta)); + return w; +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double complex cpow(double complex x, double complex y) +{ + return (double complex) cpowf((float complex) x, (float complex) y); +} + +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/complexf/cprojf.c b/libm/libmcs/libm/complexf/cprojf.c new file mode 100644 index 00000000..aed288de --- /dev/null +++ b/libm/libmcs/libm/complexf/cprojf.c @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: NetBSD */ + +#include +#include + +#include "../common/tools.h" + +float complex cprojf(float complex z) +{ + float_complex w = { .z = z }; + + if (isinf(REAL_PART(w)) || isinf(IMAG_PART(w))) { + REAL_PART(w) = INFINITY; + IMAG_PART(w) = copysignf(0.0, cimagf(z)); + } + + return (w.z); +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double complex cproj(double complex z) +{ + return (double complex) cprojf((float complex) z); +} + +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/complexf/crealf.c b/libm/libmcs/libm/complexf/crealf.c new file mode 100644 index 00000000..a70bddbb --- /dev/null +++ b/libm/libmcs/libm/complexf/crealf.c @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: PublicDomain */ +/* Written by Matthias Drochner . */ + +#include +#include "../common/tools.h" + +float crealf(float complex z) +{ + float_complex w; + w.z = z; + + return (REAL_PART(w)); +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double creal(double complex z) +{ + return (double) crealf((float complex) z); +} + +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/complexf/csinf.c b/libm/libmcs/libm/complexf/csinf.c new file mode 100644 index 00000000..da3b305a --- /dev/null +++ b/libm/libmcs/libm/complexf/csinf.c @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: NetBSD */ + +#include +#include +#include "internal/ctrigf.h" + +float complex csinf(float complex z) +{ +#ifdef __LIBMCS_FPU_DAZ + z *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + float complex w; + float ch, sh; + + __ccoshsinhf(cimagf(z), &ch, &sh); + /* w = sinf(crealf(z)) * ch + (cosf(crealf(z)) * sh) * I; */ + w = CMPLXF(sinf(crealf(z)) * ch, cosf(crealf(z)) * sh); + return w; +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double complex csin(double complex z) +{ + return (double complex) csinf((float complex) z); +} + +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/complexf/csinhf.c b/libm/libmcs/libm/complexf/csinhf.c new file mode 100644 index 00000000..1f1b347f --- /dev/null +++ b/libm/libmcs/libm/complexf/csinhf.c @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: NetBSD */ + +#include +#include + +float complex csinhf(float complex z) +{ +#ifdef __LIBMCS_FPU_DAZ + z *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + float complex w; + float x, y; + + x = crealf(z); + y = cimagf(z); + /* w = sinhf(x) * cosf(y) + (coshf(x) * sinf(y)) * I; */ + w = CMPLXF(sinhf(x) * cosf(y), coshf(x) * sinf(y)); + return w; +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double complex csinh(double complex z) +{ + return (double complex) csinhf((float complex) z); +} + +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/complexf/csqrtf.c b/libm/libmcs/libm/complexf/csqrtf.c new file mode 100644 index 00000000..cadba7a8 --- /dev/null +++ b/libm/libmcs/libm/complexf/csqrtf.c @@ -0,0 +1,83 @@ +/* SPDX-License-Identifier: NetBSD */ + +#include +#include + +float complex csqrtf(float complex z) +{ +#ifdef __LIBMCS_FPU_DAZ + z *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + float complex w; + float x, y, r, t, scale; + + x = crealf(z); + y = cimagf(z); + + if (y == 0.0f) { + if (x < 0.0f) { + w = CMPLXF(0.0f, sqrtf(-x)); + } else if (x == 0.0f) { + w = CMPLXF(0.0f, y); + } else { + w = CMPLXF(sqrtf(x), y); + } + + return w; + } + + if (x == 0.0f) { + r = fabsf(y); + r = sqrtf(0.5f * r); + + if (y > 0) { + w = CMPLXF(r, r); + } else { + w = CMPLXF(r, -r); + } + + return w; + } + + /* Rescale to avoid internal overflow or underflow. */ + if ((fabsf(x) > 4.0f) || (fabsf(y) > 4.0f)) { + x *= 0.25f; + y *= 0.25f; + scale = 2.0f; + } else { + x *= 6.7108864e7f; /* 2^26 */ + y *= 6.7108864e7f; + scale = 1.220703125e-4f; /* 2^-13 */ + } + + w = CMPLXF(x, y); + r = cabsf(w); + + if (x > 0) { + t = sqrtf(0.5f * r + 0.5f * x); + r = scale * fabsf((0.5f * y) / t); + t *= scale; + } else { + r = sqrtf(0.5f * r - 0.5f * x); + t = scale * fabsf((0.5f * y) / r); + r *= scale; + } + + if (y < 0) { + w = CMPLXF(t, -r); + } else { + w = CMPLXF(t, r); + } + + return w; +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double complex csqrt(double complex z) +{ + return (double complex) csqrtf((float complex) z); +} + +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/complexf/ctanf.c b/libm/libmcs/libm/complexf/ctanf.c new file mode 100644 index 00000000..1351a3c4 --- /dev/null +++ b/libm/libmcs/libm/complexf/ctanf.c @@ -0,0 +1,83 @@ +/* SPDX-License-Identifier: NetBSD */ + +#include +#include +#include "internal/ctrigf.h" + +/* Taylor series expansion for cosh(2y) - cos(2x) */ + +static inline 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) +{ +#ifdef __LIBMCS_FPU_DAZ + z *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + 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) { + w = CMPLXF(HUGE_VALF, HUGE_VALF); + return w; + } + + /* w = sinf(2.0f * crealf(z)) / d + (sinhf(2.0f * cimagf(z)) / d) * I; */ + w = CMPLXF(sinf(2.0f * crealf(z)) / d, sinhf(2.0f * cimagf(z)) / d); + return w; +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double complex ctan(double complex z) +{ + return (double complex) ctanf((float complex) z); +} + +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/complexf/ctanhf.c b/libm/libmcs/libm/complexf/ctanhf.c new file mode 100644 index 00000000..ce67a824 --- /dev/null +++ b/libm/libmcs/libm/complexf/ctanhf.c @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: NetBSD */ + +#include +#include + +float complex ctanhf(float complex z) +{ +#ifdef __LIBMCS_FPU_DAZ + z *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + float complex w; + float x, y, d; + + x = crealf(z); + y = cimagf(z); + d = coshf(2.0f * x) + cosf(2.0f * y); + /* w = sinhf(2.0f * x) / d + (sinf(2.0f * y) / d) * I; */ + w = CMPLXF(sinhf(2.0f * x) / d, sinf(2.0f * y) / d); + + return w; +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double complex ctanh(double complex z) +{ + return (double complex) ctanhf((float complex) z); +} + +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/complexf/internal/ctrigf.c b/libm/libmcs/libm/complexf/internal/ctrigf.c new file mode 100644 index 00000000..872c28a9 --- /dev/null +++ b/libm/libmcs/libm/complexf/internal/ctrigf.c @@ -0,0 +1,54 @@ +/* SPDX-License-Identifier: NetBSD */ + +#include +#include + +#include "ctrigf.h" + +/* calculate cosh and sinh */ + +void __ccoshsinhf(float x, float *c, float *s) +{ + float e, ei; + + if (fabsf(x) <= 0.5f) { + *c = coshf(x); + *s = sinhf(x); + } else { + e = expf(x); + if (__fpclassifyf(e) != FP_ZERO) { + ei = 0.5f / e; + } else { + ei = HUGE_VALF; + } + e = 0.5f * e; + *s = e - ei; + *c = e + ei; + } +} + +/* Program to subtract nearest integer multiple of PI */ + +/* extended precision value of PI: */ +static const float DP1 = 3.140625; +static const float DP2 = 9.67502593994140625E-4; +static const float DP3 = 1.509957990978376432E-7; + +float __redupif(float x) +{ + float t; + long i; + + t = x / (float)M_PI; + + if (t >= 0.0f) { + t += 0.5f; + } else { + t -= 0.5f; + } + + i = t; /* the multiple */ + t = i; + t = ((x - t * DP1) - t * DP2) - t * DP3; + return t; +} diff --git a/libm/libmcs/libm/complexf/internal/ctrigf.h b/libm/libmcs/libm/complexf/internal/ctrigf.h new file mode 100644 index 00000000..debc58a4 --- /dev/null +++ b/libm/libmcs/libm/complexf/internal/ctrigf.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GTDGmbH */ +/* Copyright 2020-2025 by GTD GmbH. */ + +#ifndef LIBMCS_CTRIGF_H +#define LIBMCS_CTRIGF_H + +#define MACHEPF 3.0e-8 + +extern void __ccoshsinhf(float x, float *c, float *s); +extern float __redupif(float x); + +#endif /* !LIBMCS_CTRIGF_H */ diff --git a/libm/libmcs/libm/complexfe/internal/.gitkeep b/libm/libmcs/libm/complexfe/internal/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/libm/libmcs/libm/complexl/internal/.gitkeep b/libm/libmcs/libm/complexl/internal/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/libm/libmcs/libm/include/complex.h b/libm/libmcs/libm/include/complex.h new file mode 100644 index 00000000..1daf671f --- /dev/null +++ b/libm/libmcs/libm/include/complex.h @@ -0,0 +1,206 @@ +/* SPDX-License-Identifier: NetBSD */ +/* Written by Matthias Drochner. */ + +#ifndef LIBMCS_COMPLEX_H +#define LIBMCS_COMPLEX_H + +#ifdef __STDC_NO_COMPLEX__ + #error Your toolchain has defined __STDC_NO_COMPLEX__ which indicates that \ + it does not support complex types as such you should not include \ + complex.h in your software. (Hint: When running configure for the \ + LibmCS choose not to use complex procedures.) +#endif + +#ifdef __cplusplus +extern "C"{ +#endif + +#include "config.h" +#include "internal_config.h" + +#ifndef __LIBMCS_WANT_COMPLEX + #error During the configure step you have chosen not to compile complex \ + procedures as such you should not include complex.h in your software. +#endif + +#define complex _Complex +#define _Complex_I __extension__ 1.0fi +#define I _Complex_I + +/* 7.3.5 Trigonometric functions */ +/* 7.3.5.1 The cacos functions */ +double complex cacos(double complex); +float complex cacosf(float complex); + +/* 7.3.5.2 The casin functions */ +double complex casin(double complex); +float complex casinf(float complex); + +/* 7.3.5.1 The catan functions */ +double complex catan(double complex); +float complex catanf(float complex); + +/* 7.3.5.1 The ccos functions */ +double complex ccos(double complex); +float complex ccosf(float complex); + +/* 7.3.5.1 The csin functions */ +double complex csin(double complex); +float complex csinf(float complex); + +/* 7.3.5.1 The ctan functions */ +double complex ctan(double complex); +float complex ctanf(float complex); + +/* 7.3.6 Hyperbolic functions */ +/* 7.3.6.1 The cacosh functions */ +double complex cacosh(double complex); +float complex cacoshf(float complex); + +/* 7.3.6.2 The casinh functions */ +double complex casinh(double complex); +float complex casinhf(float complex); + +/* 7.3.6.3 The catanh functions */ +double complex catanh(double complex); +float complex catanhf(float complex); + +/* 7.3.6.4 The ccosh functions */ +double complex ccosh(double complex); +float complex ccoshf(float complex); + +/* 7.3.6.5 The csinh functions */ +double complex csinh(double complex); +float complex csinhf(float complex); + +/* 7.3.6.6 The ctanh functions */ +double complex ctanh(double complex); +float complex ctanhf(float complex); + +/* 7.3.7 Exponential and logarithmic functions */ +/* 7.3.7.1 The cexp functions */ +double complex cexp(double complex); +float complex cexpf(float complex); + +/* 7.3.7.2 The clog functions */ +double complex clog(double complex); +float complex clogf(float complex); + +/* 7.3.8 Power and absolute-value functions */ +/* 7.3.8.1 The cabs functions */ +double cabs(double complex) ; +float cabsf(float complex) ; + +/* 7.3.8.2 The cpow functions */ +double complex cpow(double complex, double complex); +float complex cpowf(float complex, float complex); + +/* 7.3.8.3 The csqrt functions */ +double complex csqrt(double complex); +float complex csqrtf(float complex); + +/* 7.3.9 Manipulation functions */ +/* 7.3.9.1 The carg functions */ +double carg(double complex); +float cargf(float complex); + +/* 7.3.9.2 The cimag functions */ +double cimag(double complex); +float cimagf(float complex); + +/* 7.3.9.3 The conj functions */ +double complex conj(double complex); +float complex conjf(float complex); + +/* 7.3.9.4 The cproj functions */ +double complex cproj(double complex); +float complex cprojf(float complex); + +/* 7.3.9.5 The creal functions */ +double creal(double complex); +float crealf(float complex); + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + + 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 /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ + +/* The C11 CMPLX macros are compiler dependant and only available starting at + * GCC 4.7+ or with clang! If need be define them yourself. */ +#if defined(__clang__) || (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) + #define CMPLX(x, y) __builtin_complex ((double) (x), (double) (y)) + #define CMPLXF(x, y) __builtin_complex ((float) (x), (float) (y)) + #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + #define CMPLXL(x, y) __builtin_complex ((long double) (x), (long double) (y)) + #endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#else + /* Due to the used compiler being too old the library cannot provide fully + * C11 standard compliant macros CMPLX, CMPLXF, CMPLXL. The library + * provides functionally equivalent inline functions with the same symbol + * name with the only limitation in that they cannot be used for static + * initialisation. */ + + 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); + } + + #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + 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 /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* !LIBMCS_COMPLEX_H */ diff --git a/libm/libmcs/libm/include/config.h b/libm/libmcs/libm/include/config.h new file mode 100644 index 00000000..1b79f95e --- /dev/null +++ b/libm/libmcs/libm/include/config.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GTDGmbH */ +/* Copyright 2020-2022 by GTD GmbH. */ + +#ifndef LIBMCS_CONFIG_H +#define LIBMCS_CONFIG_H + +// #ifndef LIBMCS_FPU_DAZ +// #define LIBMCS_FPU_DAZ +// #endif /* !LIBMCS_FPU_DAZ */ +// #ifdef LIBMCS_LONG_DOUBLE_IS_64BITS +// #undef LIBMCS_LONG_DOUBLE_IS_64BITS +// #endif /* LIBMCS_LONG_DOUBLE_IS_64BITS */ +// #ifndef LIBMCS_WANT_COMPLEX +// #define LIBMCS_WANT_COMPLEX +// #endif /* !LIBMCS_WANT_COMPLEX */ + +#endif /* !LIBMCS_CONFIG_H */ diff --git a/libm/libmcs/libm/include/fenv.h b/libm/libmcs/libm/include/fenv.h new file mode 100644 index 00000000..71381734 --- /dev/null +++ b/libm/libmcs/libm/include/fenv.h @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: GTDGmbH */ +/* Copyright 2020-2025 by GTD GmbH. */ + +#ifndef LIBMCS_FENV_H +#define LIBMCS_FENV_H + +#error fenv.h/fenv.c shall not be used as is. They have no functionality \ + other than returning an error value and providing prototypes. \ + If you, the user, want to use fenv you will have to implement the \ + features yourself (or copy them from somewhere). We can not \ + provide these functionalities for you as their implementation is \ + highly platform dependant. + +#ifdef __cplusplus +extern "C"{ +#endif + +/* Floating-point Exceptions */ +extern int feclearexcept(int); +extern int feraiseexcept(int); +extern int fegetexceptflag(fexcept_t *, int); +extern int fesetexceptflag(const fexcept_t *, int); + +/* Rounding Direction */ +extern int fegetround(void); +extern int fesetround(int); + +/* Entire Environment */ +extern int fegetenv(fenv_t *); +extern int fesetenv(const fenv_t *); +extern int feholdexcept(fenv_t *); +extern int feupdateenv(const fenv_t *); + +/* Other */ +extern int fetestexcept(int); + +#ifdef __cplusplus +} +#endif + +#endif /* !LIBMCS_FENV_H */ diff --git a/libm/libmcs/libm/include/internal_config.h b/libm/libmcs/libm/include/internal_config.h new file mode 100644 index 00000000..9260178e --- /dev/null +++ b/libm/libmcs/libm/include/internal_config.h @@ -0,0 +1,156 @@ +/* SPDX-License-Identifier: GTDGmbH */ +/* Copyright 2020-2025 by GTD GmbH. */ + +#ifndef LIBMCS_INTERNAL_CONFIG_H +#define LIBMCS_INTERNAL_CONFIG_H + +/* If an FPU is not standard compliant for subnormal values, use the define LIBMCS_FPU_DAZ to force + * each procedure to first multiply the input value(s) by 1, therefore using the FPUs defined + * behaviour for subnormal values as follows: + * If the FPU is standard compliant for subnormals, the multiplication does not cause any + * difference in the behaviour of the procedure. + * If the FPU can not handle subnormals at all, it's very likely that a special FPU trap will be + * thrown. This trap can then be handled by the user if so inclined. + * If the FPU has an internal implementation for DAZ (denormals are zero), the input values will be + * reduced to zero and the procedures will then behave as if a zero was used as an input. Usually + * this will also generate an inexact exception. */ +#ifdef LIBMCS_FPU_DAZ + #define __LIBMCS_FPU_DAZ + static volatile double __volatile_one = 1.0; + static volatile float __volatile_onef = 1.0f; +#endif /* LIBMCS_FPU_DAZ */ + +/* Define to tell the libm to not exclude complex procedures. */ +#ifdef LIBMCS_WANT_COMPLEX + #define __LIBMCS_WANT_COMPLEX +#endif /* LIBMCS_WANT_COMPLEX */ + +/* Define to tell the libm to be built for 32bit doubles. */ +#ifdef LIBMCS_DOUBLE_IS_32BITS + #define __LIBMCS_DOUBLE_IS_32BITS +#endif /* LIBMCS_DOUBLE_IS_32BITS */ + +/* Define to tell the libm to be built for 64bit long doubles. */ +#ifdef LIBMCS_LONG_DOUBLE_IS_64BITS + #define __LIBMCS_LONG_DOUBLE_IS_64BITS + #ifdef LIBMCS_DOUBLE_IS_32BITS + #error Cannot define both LIBMCS_DOUBLE_IS_32BITS and LIBMCS_LONG_DOUBLE_IS_64BITS at once. + #endif /* LIBMCS_DOUBLE_IS_32BITS */ +#endif /* LIBMCS_LONG_DOUBLE_IS_64BITS */ + +/* Define to tell the libm to be built for 32bit long int. */ +#define __MAX_LONG_LONG 0x7FFFFFFFFFFFFFFFLL +#define __MIN_LONG_LONG 0x8000000000000000LL +#ifdef LIBMCS_LONG_IS_32BITS + #define __LIBMCS_LONG_IS_32BITS + #define __MAX_LONG 0x7FFFFFFFL + #define __MIN_LONG 0x80000000L +#else + #define __MAX_LONG 0x7FFFFFFFFFFFFFFFL + #define __MIN_LONG 0x8000000000000000L +#endif /* LIBMCS_LONG_IS_32BITS */ + +/* Most routines need to check whether a float is finite, infinite, or not a + number, and many need to know whether the result of an operation will + overflow. The macros below wrap up that kind of information: + + FLT_UWORD_IS_FINITE(X) + True if a positive float with bitmask X is finite. + + FLT_UWORD_IS_NAN(X) + True if a positive float with bitmask X is not a number. + + FLT_UWORD_IS_INFINITE(X) + True if a positive float with bitmask X is +infinity. + + FLT_UWORD_MAX + The bitmask of FLT_MAX. + + FLT_UWORD_HALF_MAX + The bitmask of FLT_MAX/2. + + FLT_UWORD_EXP_MAX + The bitmask of the largest finite exponent (129 if the largest + exponent is used for finite numbers, 128 otherwise). + + FLT_UWORD_LOG_MAX + The bitmask of log(FLT_MAX), rounded down. This value is the largest + input that can be passed to exp() without producing overflow. + + FLT_UWORD_LOG_2MAX + The bitmask of log(2*FLT_MAX), rounded down. This value is the + largest input than can be passed to cosh() without producing + overflow. + + FLT_LARGEST_EXP + The largest biased exponent that can be used for finite numbers + (255 if the largest exponent is used for finite numbers, 254 + otherwise) */ + +#define FLT_UWORD_IS_FINITE(x) ((x)<0x7f800000L) +#define FLT_UWORD_IS_NAN(x) ((x)>0x7f800000L) +#define FLT_UWORD_IS_INFINITE(x) ((x)==0x7f800000L) +#define FLT_UWORD_MAX 0x7f7fffffL +#define FLT_UWORD_EXP_MAX 0x43000000 +#define FLT_UWORD_LOG_MAX 0x42b17217 +#define FLT_UWORD_LOG_2MAX 0x42b2d4fc +#define HUGE ((float)3.40282346638528860e+38) +#define FLT_UWORD_HALF_MAX (FLT_UWORD_MAX-(1L<<23)) +#define FLT_LARGEST_EXP (FLT_UWORD_MAX>>23) + +/* Many routines check for zero and subnormal numbers. Such things depend + on whether the target supports denormals or not: + + FLT_UWORD_IS_ZERO(X) + True if a positive float with bitmask X is +0. Without denormals, + any float with a zero exponent is a +0 representation. With + denormals, the only +0 representation is a 0 bitmask. + + FLT_UWORD_IS_SUBNORMAL(X) + True if a non-zero positive float with bitmask X is subnormal. + (Routines should check for zeros first.) + + FLT_UWORD_MIN + The bitmask of the smallest float above +0. Call this number + REAL_FLT_MIN... + + FLT_UWORD_EXP_MIN + The bitmask of the float representation of REAL_FLT_MIN's exponent. + + FLT_UWORD_LOG_MIN + The bitmask of |log(REAL_FLT_MIN)|, rounding down. + + FLT_SMALLEST_EXP + REAL_FLT_MIN's exponent - EXP_BIAS (1 if denormals are not supported, + -22 if they are). +*/ + +#ifdef __LIBMCS_FPU_DAZ + #define FLT_UWORD_IS_ZERO(x) ((x)<0x00800000L) + #define FLT_UWORD_IS_SUBNORMAL(x) 0 + #define FLT_UWORD_MIN 0x00800000 + #define FLT_UWORD_EXP_MIN 0x42fc0000 + #define FLT_UWORD_LOG_MIN 0x42aeac50 + #define FLT_SMALLEST_EXP 1 +#else + #define FLT_UWORD_IS_ZERO(x) ((x)==0) + #define FLT_UWORD_IS_SUBNORMAL(x) ((x)<0x00800000L) + #define FLT_UWORD_MIN 0x00000001 + #define FLT_UWORD_EXP_MIN 0x43160000 + #define FLT_UWORD_LOG_MIN 0x42cff1b5 + #define FLT_SMALLEST_EXP -22 +#endif + +#if defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + #define __IEEE_BIG_ENDIAN +#elif defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + #define __IEEE_LITTLE_ENDIAN +#endif + +#ifndef __IEEE_BIG_ENDIAN + #ifndef __IEEE_LITTLE_ENDIAN + #error Must define endianness + #endif +#endif + +#endif /* !LIBMCS_INTERNAL_CONFIG_H */ diff --git a/libm/libmcs/libm/include/math.h b/libm/libmcs/libm/include/math.h new file mode 100644 index 00000000..1bbdf20c --- /dev/null +++ b/libm/libmcs/libm/include/math.h @@ -0,0 +1,390 @@ +#ifndef LIBMCS_MATH_H +#define LIBMCS_MATH_H + +#ifdef __cplusplus +extern "C"{ +#endif + +#include "config.h" +#include "internal_config.h" + +/* + * These macros define the errno and exception behaviour of the library. This + * library enforces the use of math_errhandling as MATH_ERREXCEPT. + * See ISO C18 standard §7.12 wrt. math_errhandling. + */ +#define MATH_ERRNO 1 +#define MATH_ERREXCEPT 2 +#define math_errhandling MATH_ERREXCEPT + +typedef float float_t; +typedef double double_t; + +#define MAXFLOAT 3.40282347e+38F + +#define M_E 2.7182818284590452354 +#define M_LOG2E 1.4426950408889634074 +#define M_LOG10E 0.43429448190325182765 +#define M_LN2 0.693147180559945309417 +#define M_LN10 2.30258509299404568402 +#define M_PI 3.14159265358979323846 +#define M_PI_2 1.57079632679489661923 +#define M_PI_4 0.78539816339744830962 +#define M_1_PI 0.31830988618379067154 +#define M_2_PI 0.63661977236758134308 +#define M_2_SQRTPI 1.12837916709551257390 +#define M_SQRT2 1.41421356237309504880 +#define M_SQRT1_2 0.70710678118654752440 + +#define HUGE_VAL (__infd) +#define HUGE_VALF (__inff) +#define HUGE_VALL ((long double) HUGE_VAL) +#define INFINITY HUGE_VALF + +/* Global constants that contain infinities. */ +extern const float __inff; +extern const double __infd; + +#define NAN (nanf("")) + +#define FP_NAN 0 +#define FP_INFINITE 1 +#define FP_ZERO 2 +#define FP_SUBNORMAL 3 +#define FP_NORMAL 4 + +#define FP_ILOGB0 (-INT_MAX) +#define FP_ILOGBNAN INT_MAX + +/* Double trigonometric functions */ +extern double acos(double); +extern double asin(double); +extern double atan(double); +extern double atan2(double, double); +extern double cos(double); +extern double sin(double); +extern double tan(double); + +/* Double hyperbolic functions */ +extern double acosh(double); +extern double asinh(double); +extern double atanh(double); +extern double cosh(double); +extern double sinh(double); +extern double tanh(double); + +/* Double exponential and logarithmic functions */ +extern double exp(double); +extern double exp2(double); +extern double expm1(double); +extern double frexp(double, int *); +extern int ilogb(double); +extern double ldexp(double, int); +extern double log(double); +extern double log10(double); +extern double log1p(double); +extern double log2(double); +extern double logb(double); +extern double modf(double, double *); +extern double scalbn(double, int); +extern double scalbln(double, long int); + +/* Double power and absolute-value functions */ +extern double cbrt(double); +extern double fabs(double); +extern double hypot(double, double); +extern double pow(double, double); +extern double sqrt(double); + +/* Double error and gamma functions */ +extern double erf(double); +extern double erfc(double); +extern double lgamma(double); +extern double tgamma(double); + +/* Double nearest integer functions */ +extern double ceil(double); +extern double floor(double); +extern double nearbyint(double); +extern double rint(double); +extern long int lrint(double); +extern long long int llrint(double); +extern double round(double); +extern long int lround(double); +extern long long int llround(double); +extern double trunc(double); + +/* Double remainder functions */ +extern double fmod(double, double); +extern double remainder(double, double); +extern double remquo(double, double, int *); + +/* Double manipulation functions */ +extern double copysign(double, double); +extern double nan(const char *); +extern double nextafter(double, double); + +/* Double maximum, minimum and positive difference functions */ +extern double fdim(double, double); +extern double fmax(double, double); +extern double fmin(double, double); + +/* Double float-multiply-add function */ +extern double fma(double, double, double); + +/* Double Bessel functions */ +extern double y0(double); +extern double y1(double); +extern double yn(int, double); +extern double j0(double); +extern double j1(double); +extern double jn(int, double); + + +/* Float trigonometric functions */ +extern float acosf(float); +extern float asinf(float); +extern float atanf(float); +extern float atan2f(float, float); +extern float cosf(float); +extern float sinf(float); +extern float tanf(float); + +/* Float hyperbolic functions */ +extern float acoshf(float); +extern float asinhf(float); +extern float atanhf(float); +extern float coshf(float); +extern float sinhf(float); +extern float tanhf(float); + +/* Float exponential and logarithmic functions */ +extern float expf(float); +extern float exp2f(float); +extern float expm1f(float); +extern float frexpf(float, int *); +extern int ilogbf(float); +extern float ldexpf(float, int); +extern float logf(float); +extern float log10f(float); +extern float log1pf(float); +extern float log2f(float); +extern float logbf(float); +extern float modff(float, float *); +extern float scalbnf(float, int); +extern float scalblnf(float, long int); + +/* Float power and absolute-value functions */ +extern float cbrtf(float); +extern float fabsf(float); +extern float hypotf(float, float); +extern float powf(float, float); +extern float sqrtf(float); + +/* Float error and gamma functions */ +extern float erff(float); +extern float erfcf(float); +extern float lgammaf(float); +extern float tgammaf(float); + +/* Float nearest integer functions */ +extern float ceilf(float); +extern float floorf(float); +extern float nearbyintf(float); +extern float rintf(float); +extern long int lrintf(float); +extern long long int llrintf(float); +extern float roundf(float); +extern long int lroundf(float); +extern long long int llroundf(float); +extern float truncf(float); + +/* Float remainder functions */ +extern float fmodf(float, float); +extern float remainderf(float, float); +extern float remquof(float, float, int *); + +/* Float manipulation functions */ +extern float copysignf(float, float); +extern float nanf(const char *); +extern float nextafterf(float, float); + +/* Float maximum, minimum and positive difference functions */ +extern float fdimf(float, float); +extern float fmaxf(float, float); +extern float fminf(float, float); + +/* Float float-multiply-add function */ +extern float fmaf(float, float, float); + + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + + /* Long double trigonometric functions */ + extern long double acosl(long double); + extern long double asinl(long double); + extern long double atanl(long double); + extern long double atan2l(long double, long double); + extern long double cosl(long double); + extern long double sinl(long double); + extern long double tanl(long double); + + /* Long double hyperbolic functions */ + extern long double acoshl(long double); + extern long double asinhl(long double); + extern long double atanhl(long double); + extern long double coshl(long double); + extern long double sinhl(long double); + extern long double tanhl(long double); + + /* Long double exponential and logarithmic functions */ + extern long double expl(long double); + extern long double exp2l(long double); + extern long double expm1l(long double); + extern long double frexpl(long double, int *); + extern int ilogbl(long double); + extern long double ldexpl(long double, int); + extern long double logl(long double); + extern long double log10l(long double); + extern long double log1pl(long double); + extern long double log2l(long double); + extern long double logbl(long double); + extern long double modfl(long double, long double *); + extern long double scalbnl(long double, int); + extern long double scalblnl(long double, long); + + /* Long double power and absolute-value functions */ + extern long double cbrtl(long double); + extern long double fabsl(long double); + extern long double hypotl(long double, long double); + extern long double powl(long double, long double); + extern long double sqrtl(long double); + + /* Long double error and gamma functions */ + extern long double erfl(long double); + extern long double erfcl(long double); + extern long double lgammal(long double); + extern long double tgammal(long double); + + /* Long double nearest integer functions */ + extern long double ceill(long double); + extern long double floorl(long double); + extern long double nearbyintl(long double); + extern long double rintl(long double); + extern long int lrintl(long double); + extern long long int llrintl(long double); + extern long double roundl(long double); + extern long lroundl(long double); + extern long long int llroundl(long double); + extern long double truncl(long double); + + /* Long double remainder functions */ + extern long double fmodl(long double, long double); + extern long double remainderl(long double, long double); + extern long double remquol(long double, long double, int *); + + /* Long double manipulation functions */ + extern long double copysignl(long double, long double); + extern long double nanl(const char *); + extern long double nextafterl(long double, long double); + + /* Long double maximum, minimum and positive difference functions */ + extern long double fdiml(long double, long double); + extern long double fmaxl(long double, long double); + extern long double fminl(long double, long double); + + /* Long double float-multiply-add function */ + extern long double fmal(long double, long double, long double); + + /* nexttoward procedures, they're seperated from the manipulation functions + * due to containing long double inputs for all procedures */ + extern float nexttowardf(float, long double); + extern double nexttoward(double, long double); + extern long double nexttowardl(long double, long double); + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ + +/* signgam global variable used by the lgamma procedures to return the sign of gamma */ +#define signgam (__signgam) +extern int __signgam; + +/* Internal procedures used by the classification macros */ +extern int __fpclassifyf(float); +extern int __fpclassifyd(double); +extern int __signbitf(float); +extern int __signbitd(double); + +/* Classification macros */ +#define fpclassify(__x) ((sizeof(__x) == sizeof(float)) ? __fpclassifyf(__x) \ + : __fpclassifyd(__x)) +#define isfinite(__y) (__extension__ \ + ({int __cy = fpclassify(__y); \ + __cy != FP_INFINITE && __cy != FP_NAN;})) + +#define isinf(__x) (fpclassify(__x) == FP_INFINITE) +#define isnan(__x) (fpclassify(__x) == FP_NAN) +#define isnormal(__x) (fpclassify(__x) == FP_NORMAL) + +#define signbit(__x) ((sizeof(__x) == sizeof(float)) ? __signbitf(__x) \ + : __signbitd(__x)) + +/* Comparison macros */ +#define isgreater(x,y) (__extension__ ({ \ + __typeof__(x) __x = (x); __typeof__(y) __y = (y); \ + int __result; \ + if (isunordered(__x, __y)) { \ + __result = 0; \ + } else { \ + __result = (__x > __y); \ + } \ + __result; \ + })) +#define isgreaterequal(x,y) (__extension__ ({ \ + __typeof__(x) __x = (x); __typeof__(y) __y = (y); \ + int __result; \ + if (isunordered(__x, __y)) { \ + __result = 0; \ + } else { \ + __result = (__x >= __y); \ + } \ + __result; \ + })) +#define isless(x,y) (__extension__ ({ \ + __typeof__(x) __x = (x); __typeof__(y) __y = (y); \ + int __result; \ + if (isunordered(__x, __y)) { \ + __result = 0; \ + } else { \ + __result = (__x < __y); \ + } \ + __result; \ + })) +#define islessequal(x,y) (__extension__ ({ \ + __typeof__(x) __x = (x); __typeof__(y) __y = (y); \ + int __result; \ + if (isunordered(__x, __y)) { \ + __result = 0; \ + } else { \ + __result = (__x <= __y); \ + } \ + __result; \ + })) +#define islessgreater(x,y) (__extension__ ({ \ + __typeof__(x) __x = (x); __typeof__(y) __y = (y); \ + int __result; \ + if (isunordered(__x, __y)) { \ + __result = 0; \ + } else { \ + __result = (__x < __y) || (__x > __y); \ + } \ + __result; \ + })) +#define isunordered(a,b) (__extension__ \ + ({__typeof__(a) __a = (a); __typeof__(b) __b = (b); \ + fpclassify(__a) == FP_NAN || fpclassify(__b) == FP_NAN;})) + +#ifdef __cplusplus +} +#endif + +#endif /* !LIBMCS_MATH_H */ diff --git a/libm/libmcs/libm/include/tgmath.h b/libm/libmcs/libm/include/tgmath.h new file mode 100644 index 00000000..1a43b56b --- /dev/null +++ b/libm/libmcs/libm/include/tgmath.h @@ -0,0 +1,157 @@ +/* SPDX-License-Identifier: NetBSD */ +/* Copyright (c) 2004 Stefan Farfeleder. */ + +#ifndef LIBMCS_TGMATH_H +#define LIBMCS_TGMATH_H + +#error tgmath.h should never be used in critical systems. If you insist on \ + doing it anyway you are on your own. The given tgmath.h implementation \ + is taken from newlib as is and has not been reviewed by us and as such \ + is wholely unqualified. + +#include +#include + +/* + * This implementation of requires two implementation-dependent + * macros to be defined: + * __tg_impl_simple(x, y, z, fn, fnf, fnl, ...) + * Invokes fnl() if the corresponding real type of x, y or z is long + * double, fn() if it is double or any has an integer type, and fnf() + * otherwise. + * __tg_impl_full(x, y, z, fn, fnf, fnl, cfn, cfnf, cfnl, ...) + * Invokes [c]fnl() if the corresponding real type of x, y or z is long + * double, [c]fn() if it is double or any has an integer type, and + * [c]fnf() otherwise. The function with the 'c' prefix is called if + * any of x, y or z is a complex number. + * Both macros call the chosen function with all additional arguments passed + * to them, as given by __VA_ARGS__. + * + * Note that these macros cannot be implemented with C's ?: operator, + * because the return type of the whole expression would incorrectly be long + * double complex regardless of the argument types. + */ + +/* requires GCC >= 3.1 */ +#if !__GNUC_PREREQ (3, 1) + #error " not implemented for this compiler" +#endif + +#define __tg_type(__e, __t) \ + __builtin_types_compatible_p(__typeof__(__e), __t) +#define __tg_type3(__e1, __e2, __e3, __t) \ + (__tg_type(__e1, __t) || __tg_type(__e2, __t) || \ + __tg_type(__e3, __t)) +#define __tg_type_corr(__e1, __e2, __e3, __t) \ + (__tg_type3(__e1, __e2, __e3, __t) || \ + __tg_type3(__e1, __e2, __e3, __t _Complex)) +#define __tg_integer(__e1, __e2, __e3) \ + (((__typeof__(__e1))1.5 == 1) || ((__typeof__(__e2))1.5 == 1) || \ + ((__typeof__(__e3))1.5 == 1)) +#define __tg_is_complex(__e1, __e2, __e3) \ + (__tg_type3(__e1, __e2, __e3, float _Complex) || \ + __tg_type3(__e1, __e2, __e3, double _Complex) || \ + __tg_type3(__e1, __e2, __e3, long double _Complex) || \ + __tg_type3(__e1, __e2, __e3, __typeof__(_Complex_I))) + +#if defined (_LDBL_EQ_DBL) || defined (__CYGWIN__) +#define __tg_impl_simple(x, y, z, fn, fnf, fnl, ...) \ + __builtin_choose_expr(__tg_type_corr(x, y, z, long double), \ + fnl(__VA_ARGS__), __builtin_choose_expr( \ + __tg_type_corr(x, y, z, double) || __tg_integer(x, y, z), \ + fn(__VA_ARGS__), fnf(__VA_ARGS__))) +#else +#define __tg_impl_simple(__x, __y, __z, __fn, __fnf, __fnl, ...) \ + (__tg_type_corr(__x, __y, __z, double) || __tg_integer(__x, __y, __z)) \ + ? __fn(__VA_ARGS__) : __fnf(__VA_ARGS__) +#endif + +#define __tg_impl_full(__x, __y, __z, __fn, __fnf, __fnl, __cfn, __cfnf, __cfnl, ...) \ + __builtin_choose_expr(__tg_is_complex(__x, __y, __z), \ + __tg_impl_simple(__x, __y, __z, __cfn, __cfnf, __cfnl, __VA_ARGS__), \ + __tg_impl_simple(__x, __y, __z, __fn, __fnf, __fnl, __VA_ARGS__)) + +/* Macros to save lots of repetition below */ +#define __tg_simple(__x, __fn) \ + __tg_impl_simple(__x, __x, __x, __fn, __fn##f, __fn##l, __x) +#define __tg_simple2(__x, __y, __fn) \ + __tg_impl_simple(__x, __x, __y, __fn, __fn##f, __fn##l, __x, __y) +#define __tg_simplev(__x, __fn, ...) \ + __tg_impl_simple(__x, __x, __x, __fn, __fn##f, __fn##l, __VA_ARGS__) +#define __tg_full(__x, __fn) \ + __tg_impl_full(__x, __x, __x, __fn, __fn##f, __fn##l, c##__fn, c##__fn##f, c##__fn##l, __x) + +/* 7.22#4 -- These macros expand to real or complex functions, depending on + * the type of their arguments. */ +#define acos(__x) __tg_full(__x, acos) +#define asin(__x) __tg_full(__x, asin) +#define atan(__x) __tg_full(__x, atan) +#define acosh(__x) __tg_full(__x, acosh) +#define asinh(__x) __tg_full(__x, asinh) +#define atanh(__x) __tg_full(__x, atanh) +#define cos(__x) __tg_full(__x, cos) +#define sin(__x) __tg_full(__x, sin) +#define tan(__x) __tg_full(__x, tan) +#define cosh(__x) __tg_full(__x, cosh) +#define sinh(__x) __tg_full(__x, sinh) +#define tanh(__x) __tg_full(__x, tanh) +#define exp(__x) __tg_full(__x, exp) +#define log(__x) __tg_full(__x, log) +#define pow(__x, __y) __tg_impl_full(__x, __x, __y, pow, powf, powl, \ + cpow, cpowf, cpowl, __x, __y) +#define sqrt(__x) __tg_full(__x, sqrt) + +/* "The corresponding type-generic macro for fabs and cabs is fabs." */ +#define fabs(__x) __tg_impl_full(__x, __x, __x, fabs, fabsf, fabsl, cabs, cabsf, \ + cabsl, __x) + +/* 7.22#5 -- These macros are only defined for arguments with real type. */ +#define atan2(__x, __y) __tg_simple2(__x, __y, atan2) +#define cbrt(__x) __tg_simple(__x, cbrt) +#define ceil(__x) __tg_simple(__x, ceil) +#define copysign(__x, __y) __tg_simple2(__x, __y, copysign) +#define erf(__x) __tg_simple(__x, erf) +#define erfc(__x) __tg_simple(__x, erfc) +#define exp2(__x) __tg_simple(__x, exp2) +#define expm1(__x) __tg_simple(__x, expm1) +#define fdim(__x, __y) __tg_simple2(__x, __y, fdim) +#define floor(__x) __tg_simple(__x, floor) +#define fma(__x, __y, __z) __tg_impl_simple(__x, __y, __z, fma, fmaf, fmal, __x, __y, __z) +#define fmax(__x, __y) __tg_simple2(__x, __y, fmax) +#define fmin(__x, __y) __tg_simple2(__x, __y, fmin) +#define fmod(__x, __y) __tg_simple2(__x, __y, fmod) +#define frexp(__x, __y) __tg_simplev(__x, frexp, __x, __y) +#define hypot(__x, __y) __tg_simple2(__x, __y, hypot) +#define ilogb(__x) __tg_simple(__x, ilogb) +#define ldexp(__x, __y) __tg_simplev(__x, ldexp, __x, __y) +#define lgamma(__x) __tg_simple(__x, lgamma) +#define llrint(__x) __tg_simple(__x, llrint) +#define llround(__x) __tg_simple(__x, llround) +#define log10(__x) __tg_simple(__x, log10) +#define log1p(__x) __tg_simple(__x, log1p) +#define log2(__x) __tg_simple(__x, log2) +#define logb(__x) __tg_simple(__x, logb) +#define lrint(__x) __tg_simple(__x, lrint) +#define lround(__x) __tg_simple(__x, lround) +#define nearbyint(__x) __tg_simple(__x, nearbyint) +#define nextafter(__x, __y) __tg_simple2(__x, __y, nextafter) +/* not yet implemented even for _LDBL_EQ_DBL platforms */ +#define nexttoward(__x, __y) __tg_simplev(__x, nexttoward, __x, __y) +#define remainder(__x, __y) __tg_simple2(__x, __y, remainder) +#define remquo(__x, __y, __z) __tg_impl_simple(__x, __x, __y, remquo, remquof, remquol, \ + __x, __y, __z) +#define rint(__x) __tg_simple(__x, rint) +#define round(__x) __tg_simple(__x, round) +#define scalbn(__x, __y) __tg_simplev(__x, scalbn, __x, __y) +#define scalbln(__x, __y) __tg_simplev(__x, scalbln, __x, __y) +#define tgamma(__x) __tg_simple(__x, tgamma) +#define trunc(__x) __tg_simple(__x, trunc) + +/* 7.22#6 -- These macros always expand to complex functions. */ +#define carg(__x) __tg_simple(__x, carg) +#define cimag(__x) __tg_simple(__x, cimag) +#define conj(__x) __tg_simple(__x, conj) +#define cproj(__x) __tg_simple(__x, cproj) +#define creal(__x) __tg_simple(__x, creal) + +#endif /* !LIBMCS_TGMATH_H */ diff --git a/libm/libmcs/libm/machine/sparc_v8/mathd/sqrtd.c b/libm/libmcs/libm/machine/sparc_v8/mathd/sqrtd.c new file mode 100644 index 00000000..3367a5af --- /dev/null +++ b/libm/libmcs/libm/machine/sparc_v8/mathd/sqrtd.c @@ -0,0 +1,78 @@ +/* SPDX-License-Identifier: GTDGmbH */ +/* Copyright 2017-2022 by GTD GmbH. */ + +/** + * + * This family of functions implements the square root of :math:`x` using the + * SPARC V8 hardware instruction directly. + * Use this file (and the float version) to replace the software square root + * when using a SPARC V8 machine. The replacement shall take place in the + * Makefile. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float sqrtf(float x); + * double sqrt(double x); + * long double sqrtl(long double x); + * + * Description + * =========== + * + * ``sqrt`` computes the square root of the input value. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * sqrt(x) \approx \sqrt{x} + * + * Returns + * ======= + * + * ``sqrt`` returns the square root of the input value. + * + * Exceptions + * ========== + * + * Raise ``invalid operation`` exception when :math:`x` is negative. + * + * Output map + * ========== + * + * +---------------------+--------------+------------------+--------------+--------------+------------------+--------------+--------------+ + * | **x** | :math:`-Inf` | :math:`<0` | :math:`-0` | :math:`+0` | :math:`>0` | :math:`+Inf` | :math:`NaN` | + * +=====================+==============+==================+==============+==============+==================+==============+==============+ + * | **sqrt(x)** | :math:`qNaN` | :math:`qNaN` | :math:`x` | :math:`\sqrt{x}` | :math:`+Inf` | :math:`qNaN` | + * +---------------------+--------------+------------------+--------------+--------------+------------------+--------------+--------------+ + * + */ + +#include + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +double sqrt(double x) +{ + double root = 0.0; + + __asm__ volatile ("fsqrtd %[x], %[root]" + : [root] "=f" (root) + : [x] "f" (x)); + + return root; +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double sqrtl(long double x) +{ + return (long double) sqrt((double) x); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/machine/sparc_v8/mathf/sqrtf.c b/libm/libmcs/libm/machine/sparc_v8/mathf/sqrtf.c new file mode 100644 index 00000000..43fa0838 --- /dev/null +++ b/libm/libmcs/libm/machine/sparc_v8/mathf/sqrtf.c @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GTDGmbH */ +/* Copyright 2017-2022 by GTD GmbH. */ + +#include + +float sqrtf(float x) +{ + float root = 0.0f; + + __asm__ volatile ("fsqrts %[x], %[root]" + : [root] "=f" (root) + : [x] "f" (x)); + + return root; +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double sqrt(double x) +{ + return (double) sqrtf((float) x); +} + +#endif /* #ifdef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/acosd.c b/libm/libmcs/libm/mathd/acosd.c new file mode 100644 index 00000000..6b4dc530 --- /dev/null +++ b/libm/libmcs/libm/mathd/acosd.c @@ -0,0 +1,145 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +/** + * + * This family of functions implements the arc cosine of :math:`x`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float acosf(float x); + * double acos(double x); + * long double acosl(long double x); + * + * Description + * =========== + * + * ``acos`` computes the inverse cosine (*arc cosine*) of the input value. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * acos(x) \approx cos^{-1}(x) + * + * Returns + * ======= + * + * ``acos`` returns value in radians, in the range :math:`[0, \pi]`. + * + * Exceptions + * ========== + * + * Raise ``invalid operation`` exception when the input value is not in the + * interval :math:`[-1, 1]`. + * + * .. May raise ``underflow`` exception. + * + * Output map + * ========== + * + * +---------------------+--------------+--------------+---------------------+--------------+--------------+--------------+--------------+ + * | **x** | :math:`-Inf` | :math:`<-1` | :math:`\in [-1,+1[` | :math:`+1` | :math:`>+1` | :math:`+Inf` | :math:`NaN` | + * +=====================+==============+==============+=====================+==============+==============+==============+==============+ + * | **acos(x)** | :math:`qNaN` | :math:`qNaN` | :math:`cos^{-1} x` | :math:`+0` | :math:`qNaN` | :math:`qNaN` | :math:`qNaN` | + * +---------------------+--------------+--------------+---------------------+--------------+--------------+--------------+--------------+ + * + */ + +#include +#include "../common/tools.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +static const double +one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */ +pi = 3.14159265358979311600e+00, /* 0x400921FB, 0x54442D18 */ +pio2_hi = 1.57079632679489655800e+00, /* 0x3FF921FB, 0x54442D18 */ +pio2_lo = 6.12323399573676603587e-17, /* 0x3C91A626, 0x33145C07 */ +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 */ + +double acos(double x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + 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 */ + uint32_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 __raise_inexact(pi); /* acos(-1)= pi */ + } + } + + if (isnan(x)) { + return x + x; + } + + return __raise_invalid(); /* acos(|x|>1) is NaN */ + } + + if (ix < 0x3fe00000) { /* |x| < 0.5 */ + if (ix <= 0x3c600000) { + return __raise_inexact(pio2_hi); /*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); + } +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double acosl(long double x) +{ + return (long double) acos((double) x); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/acoshd.c b/libm/libmcs/libm/mathd/acoshd.c new file mode 100644 index 00000000..f939fc34 --- /dev/null +++ b/libm/libmcs/libm/mathd/acoshd.c @@ -0,0 +1,104 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +/** + * + * This family of functions implements the hyperbolic arc cosine of :math:`x`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float acoshf(float x); + * double acosh(double x); + * long double acoshl(long double x); + * + * Description + * =========== + * + * ``acosh`` computes the hyperbolic inverse cosine (*hyperbolic arc cosine*) + * of the input value. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * acosh(x) \approx cosh^{-1}(x) = ln \left( x + \sqrt{x^2-1} \right) + * + * Returns + * ======= + * + * ``acosh`` returns the hyperbolic inverse cosine, in the range + * :math:`\mathbb{F}^{+}`. + * + * Exceptions + * ========== + * + * Raise ``invalid operation`` exception when the input value is :math:`<1`. + * + * Output map + * ========== + * + * +---------------------+----------------------+----------------------+----------------------+----------------------+----------------------+----------------------+ + * | **x** | :math:`-Inf` | :math:`<+1` | :math:`+1` | :math:`>+1` | :math:`+Inf` | :math:`NaN` | + * +=====================+======================+======================+======================+======================+======================+======================+ + * | **acosh(x)** | :math:`qNaN` | :math:`qNaN` | :math:`+0` | :math:`cosh^{-1}(x)` | :math:`+Inf` | :math:`qNaN` | + * +---------------------+----------------------+----------------------+----------------------+----------------------+----------------------+----------------------+ + * + */ + +#include +#include "../common/tools.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +static const double +one = 1.0, +ln2 = 6.93147180559945286227e-01; /* 0x3FE62E42, 0xFEFA39EF */ + +double acosh(double x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + double t; + int32_t hx; + uint32_t lx; + EXTRACT_WORDS(hx, lx, x); + + if (hx < 0x3ff00000) { /* x < 1 */ + if (isnan(x)) { + return x + x; + } else { + return __raise_invalid(); + } + } else if (hx >= 0x41b00000) { /* x > 2**28 */ + if (hx >= 0x7ff00000) { /* x is +inf or NaN */ + return x + x; + } else { + return 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 log(2.0 * x - one / (x + sqrt(t - one))); + } else { /* 1 + * float asinf(float x); + * double asin(double x); + * long double asinl(long double x); + * + * Description + * =========== + * + * ``asin`` computes the inverse sine (*arc sine*) of the input value. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * asin(x) \approx sin^{-1}(x) + * + * Returns + * ======= + * + * ``asin`` returns value in radians, in the range :math:`[-\frac{\pi}{2}, + * \frac{\pi}{2}]`. + * + * Exceptions + * ========== + * + * Raise ``invalid operation`` exception when the input value is not in the + * interval :math:`[-1, 1]`. + * + * .. May raise ``underflow`` exception. + * + * Output map + * ========== + * + * +---------------------+--------------+--------------+---------------------+--------------+--------------+---------------------+--------------+--------------+--------------+ + * | **x** | :math:`-Inf` | :math:`<-1` | :math:`\in [-1,-0[` | :math:`-0` | :math:`+0` | :math:`\in ]+0,+1]` | :math:`>+1` | :math:`+Inf` | :math:`NaN` | + * +=====================+==============+==============+=====================+==============+==============+=====================+==============+==============+==============+ + * | **asin(x)** | :math:`qNaN` | :math:`qNaN` | :math:`sin^{-1} x` | :math:`x` | :math:`sin^{-1} x` | :math:`qNaN` | :math:`qNaN` | :math:`qNaN` | + * +---------------------+--------------+--------------+---------------------+--------------+--------------+---------------------+--------------+--------------+--------------+ + * + */ + +#include +#include "../common/tools.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +static const double +one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */ +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 */ + +double asin(double x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + double t, w, p, q, c, r, s; + int32_t hx, ix; + GET_HIGH_WORD(hx, x); + ix = hx & 0x7fffffff; + + if (ix >= 0x3ff00000) { /* |x|>= 1 */ + uint32_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; + } + + if (isnan(x)) { + return x + x; + } + + return __raise_invalid(); /* asin(|x|>1) is NaN */ + } else if (ix < 0x3fe00000) { /* |x|<0.5 */ + if (ix < 0x3e500000) { /* if |x| < 2**-26 */ + if (x == 0.0) { /* return x inexact except 0 */ + return x; + } else { + return __raise_inexact(x); + } + } else { + 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; + } + } else { + /* No action required */ + } + + /* 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; + } +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double asinl(long double x) +{ + return (long double) asin((double) x); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/asinhd.c b/libm/libmcs/libm/mathd/asinhd.c new file mode 100644 index 00000000..9a081891 --- /dev/null +++ b/libm/libmcs/libm/mathd/asinhd.c @@ -0,0 +1,111 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +/** + * + * This family of functions implements the hyperbolic arc sine of :math:`x`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float asinhf(float x); + * double asinh(double x); + * long double asinhl(long double x); + * + * Description + * =========== + * + * ``asinh`` computes the hyperbolic inverse sine (*hyperbolic arc sine*) of + * the input value. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * asinh(x) \approx sinh^{-1}(x) = ln \left( x + \sqrt{x^2+1} \right) + * + * Returns + * ======= + * + * ``asinh`` returns the hyperbolic inverse sine. + * + * Exceptions + * ========== + * + * Does not raise overflow, division by zero, and invalid exceptions. + * + * .. May raise ``underflow`` exception. + * + * Output map + * ========== + * + * +---------------------+----------------------+----------------------+--------------+--------------+----------------------+----------------------+----------------------+ + * | **x** | :math:`-Inf` | :math:`<0` | :math:`-0` | :math:`+0` | :math:`>0` | :math:`+Inf` | :math:`NaN` | + * +=====================+======================+======================+==============+==============+======================+======================+======================+ + * | **asinh(x)** | :math:`-Inf` | :math:`sinh^{-1}(x)` | :math:`x` | :math:`sinh^{-1}(x)` | :math:`+Inf` | :math:`qNaN` | + * +---------------------+----------------------+----------------------+--------------+--------------+----------------------+----------------------+----------------------+ + * + */ + +#include +#include "../common/tools.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +static const double +one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */ +ln2 = 6.93147180559945286227e-01; /* 0x3FE62E42, 0xFEFA39EF */ + +double asinh(double x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + 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 (x == 0.0) { /* return x inexact except 0 */ + return x; + } else { + return __raise_inexact(x); + } + } + + if (ix > 0x41b00000) { /* |x| > 2**28 */ + w = log(fabs(x)) + ln2; + } else if (ix > 0x40000000) { /* 2**28 > |x| > 2.0 */ + t = fabs(x); + w = log(2.0 * t + one / (sqrt(x * x + one) + t)); + } else { /* 2.0 > |x| > 2**-28 */ + t = x * x; + w = log1p(fabs(x) + t / (one + sqrt(one + t))); + } + + if (hx > 0) { + return w; + } else { + return -w; + } +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double asinhl(long double x) +{ + return (long double) asinh((double) x); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/atan2d.c b/libm/libmcs/libm/mathd/atan2d.c new file mode 100644 index 00000000..bbfdb011 --- /dev/null +++ b/libm/libmcs/libm/mathd/atan2d.c @@ -0,0 +1,209 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +/** + * + * This family of functions implements the arc tangent of :math:`\frac{y}{x}`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float atan2f(float y, float x); + * double atan2(double y, double x); + * long double atan2l(long double y, long double x); + * + * Description + * =========== + * + * ``atan2`` computes the inverse tangent (*arc tangent*) of the division of + * the input values. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * atan2(y, x) \approx \left\{\begin{array}{ll} + * tan^{-1}\left(\frac{y}{x}\right), & x > 0 \\ + * tan^{-1}\left(\frac{y}{x}\right) + \pi, & x < 0 \wedge y > 0 \\ + * tan^{-1}\left(\frac{y}{x}\right) - \pi, & x < 0 \wedge y < 0 \end{array}\right. + * + * For the other cases (which do not need formulae) refer to the output map below. + * + * Returns + * ======= + * + * ``atan2`` returns value in radians, in the range :math:`[-\pi, \pi]`. + * + * Exceptions + * ========== + * + * Does not raise overflow, division by zero, and invalid exceptions. Does not raise ``divide-by-zero`` + * exception even if argument :math:`x` is zero. + * + * .. May raise ``underflow`` exception. + * + * Output map + * ========== + * + * +--------------+--------------------------+-----------------------------------+--------------+--------------+-----------------------------------+--------------------------+--------------+ + * | atan2(y,x) | y | + * +--------------+--------------------------+-----------------------------------+--------------+--------------+-----------------------------------+--------------------------+--------------+ + * | x | :math:`-Inf` | :math:`<0` | :math:`-0` | :math:`+0` | :math:`>0` | :math:`+Inf` | :math:`NaN` | + * +==============+==========================+===================================+==============+==============+===================================+==========================+==============+ + * | :math:`-Inf` | :math:`-\frac{3}{4} \pi` | :math:`-\pi` | :math:`+\pi` | :math:`+\frac{3}{4} \pi` | :math:`qNaN` | + * +--------------+--------------------------+-----------------------------------+--------------+--------------+-----------------------------------+--------------------------+ + + * | :math:`<0` | :math:`-\frac{\pi}{2}` | :math:`tan^{-1}(\frac{y}{x})-\pi` | :math:`-\pi` | :math:`+\pi` | :math:`tan^{-1}(\frac{y}{x})+\pi` | :math:`+\frac{\pi}{2}` | | + * +--------------+ +-----------------------------------+ + +-----------------------------------+ + + + * | :math:`-0` | | :math:`-\frac{\pi}{2}` | | | :math:`+\frac{\pi}{2}` | | | + * +--------------+ + +--------------+--------------+ + + + + * | :math:`+0` | | | :math:`-0` | :math:`+0` | | | | + * +--------------+ +-----------------------------------+ + +-----------------------------------+ + + + * | :math:`>0` | | :math:`tan^{-1}(\frac{y}{x})` | | | :math:`tan^{-1}(\frac{y}{x})` | | | + * +--------------+--------------------------+-----------------------------------+--------------+--------------+-----------------------------------+--------------------------+ + + * | :math:`+Inf` | :math:`-\frac{\pi}{4}` | :math:`-0` | :math:`+0` | :math:`+\frac{\pi}{4}` | | + * +--------------+--------------------------+-----------------------------------+--------------+--------------+-----------------------------------+--------------------------+--------------+ + * | :math:`NaN` | :math:`qNaN` | + * +--------------+--------------------------+-----------------------------------+--------------+--------------+-----------------------------------+--------------------------+--------------+ + * + */ + +#include +#include "../common/tools.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +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 */ +pi_lo = 1.2246467991473531772E-16; /* 0x3CA1A626, 0x33145C07 */ + +double atan2(double y, double x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_one; + y *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + double z; + int32_t k, m, hx, hy, ix, iy; + uint32_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) { + default: /* FALLTHRU */ + case 0: /* FALLTHRU */ + case 1: + return y; /* atan(+-0,+anything)=+-0 */ + + case 2: + return __raise_inexact(pi); /* atan(+0,-anything) = pi */ + + case 3: + return -__raise_inexact(pi); /* atan(-0,-anything) =-pi */ + } + } + + /* when x = 0 */ + if ((ix | lx) == 0) { + return (hy < 0) ? -__raise_inexact(pi_o_2) : __raise_inexact(pi_o_2); + } + + /* when x is INF */ + if (ix == 0x7ff00000) { + if (iy == 0x7ff00000) { + switch (m) { + default: /* FALLTHRU */ + case 0: + return __raise_inexact(pi_o_4); /* atan(+INF,+INF) */ + + case 1: + return -__raise_inexact(pi_o_4); /* atan(-INF,+INF) */ + + case 2: + return __raise_inexact(3.0 * pi_o_4); /* atan(+INF,-INF) */ + + case 3: + return -__raise_inexact(3.0 * pi_o_4); /* atan(-INF,-INF) */ + } + } else { + switch (m) { + default: /* FALLTHRU */ + case 0: + return zero; /* atan(+...,+INF) */ + + case 1: + return -zero; /* atan(-...,+INF) */ + + case 2: + return __raise_inexact(pi); /* atan(+...,-INF) */ + + case 3: + return -__raise_inexact(pi); /* atan(-...,-INF) */ + } + } + } + + /* when y is INF */ + if (iy == 0x7ff00000) { + return (hy < 0) ? -__raise_inexact(pi_o_2) : __raise_inexact(pi_o_2); + } + + /* compute y/x */ + k = (iy - ix) >> 20; + + if (k > 60) { + z = __raise_inexact(pi_o_2); /* |y/x| > 2**60 */ + 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(-,-) */ + } +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double atan2l(long double y, long double x) +{ + return (long double) atan2((double) y, (double) x); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/atand.c b/libm/libmcs/libm/mathd/atand.c new file mode 100644 index 00000000..286f0df1 --- /dev/null +++ b/libm/libmcs/libm/mathd/atand.c @@ -0,0 +1,171 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +/** + * + * This family of functions implements the arc tangent of :math:`x`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float atanf(float x); + * double atan(double x); + * long double atanl(long double x); + * + * Description + * =========== + * + * ``atan`` computes the inverse tangent (*arc tangent*) of the input value. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * atan(x) \approx tan^{-1}(x) + * + * Returns + * ======= + * + * ``atan`` returns value in radians, in the range :math:`[-\frac{\pi}{2}, \frac{\pi}{2}]`. + * + * Exceptions + * ========== + * + * Does not raise overflow, division by zero, and invalid exceptions. + * + * .. May raise ``underflow`` exception. + * + * Output map + * ========== + * + * +---------------------+------------------------+---------------------+--------------+--------------+---------------------+------------------------+--------------+ + * | **x** | :math:`-Inf` | :math:`<0` | :math:`-0` | :math:`+0` | :math:`>0` | :math:`+Inf` | :math:`NaN` | + * +=====================+========================+=====================+==============+==============+=====================+========================+==============+ + * | **atan(x)** | :math:`-\frac{\pi}{2}` | :math:`tan^{-1} x` | :math:`x` | :math:`tan^{-1} x` | :math:`+\frac{\pi}{2}` | :math:`qNaN` | + * +---------------------+------------------------+---------------------+--------------+--------------+---------------------+------------------------+--------------+ + * + */ + +#include +#include "../common/tools.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +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; + +double atan(double x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + 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 */ + uint32_t low; + GET_LOW_WORD(low, x); + + if (ix > 0x7ff00000 || + (ix == 0x7ff00000 && (low != 0))) { + return x + x; /* NaN */ + } + + if (hx > 0) { + return __raise_inexact(atanhi[3]); + } else { + return -__raise_inexact(atanhi[3]); + } + } + + if (ix < 0x3fdc0000) { /* |x| < 0.4375 */ + if (ix < 0x3e400000) { /* |x| < 2^-27 */ + if (x == 0.0) { /* return x inexact except 0 */ + return x; + } else { + return __raise_inexact(x); + } + } + + 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; + } +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double atanl(long double x) +{ + return (long double) atan((double) x); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/atanhd.c b/libm/libmcs/libm/mathd/atanhd.c new file mode 100644 index 00000000..62dda470 --- /dev/null +++ b/libm/libmcs/libm/mathd/atanhd.c @@ -0,0 +1,120 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +/** + * + * This family of functions implements the hyperbolic arc tangent of :math:`x`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float atanhf(float x); + * double atanh(double x); + * long double atanhl(long double x); + * + * Description + * =========== + * + * ``atanh`` computes the hyperbolic inverse tangent (*hyperbolic arc tangent*) + * of the input value. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * atanh(x) \approx tanh^{-1}(x) = \frac{1}{2} ln \left( \frac{1+x}{1-x} \right) + * + * Returns + * ======= + * + * ``atanh`` returns the hyperbolic inverse tangent. + * + * Exceptions + * ========== + * + * Raise ``invalid operation`` exception when the input value is not in the + * interval :math:`[-1, 1]`. + * + * Raise ``divide by zero`` exception when the input value is :math:`-1` or + * :math:`+1`. + * + * .. May raise ``underflow`` exception. + * + * Output map + * ========== + * + * +---------------------+--------------+--------------+--------------+---------------------+--------------+--------------+---------------------+--------------+--------------+--------------+--------------+ + * | **x** | :math:`-Inf` | :math:`<-1` | :math:`-1` | :math:`\in ]-1,-0[` | :math:`-0` | :math:`+0` | :math:`\in ]+0,+1[` | :math:`+1` | :math:`>+1` | :math:`+Inf` | :math:`NaN` | + * +=====================+==============+==============+==============+=====================+==============+==============+=====================+==============+==============+==============+==============+ + * | **atanh(x)** | :math:`qNaN` | :math:`qNaN` | :math:`-Inf` | :math:`tanh^{-1} x` | :math:`x` | :math:`tanh^{-1} x` | :math:`+Inf` | :math:`qNaN` | :math:`qNaN` | :math:`qNaN` | + * +---------------------+--------------+--------------+--------------+---------------------+--------------+--------------+---------------------+--------------+--------------+--------------+--------------+ + * + */ + +#include +#include "../common/tools.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +static const double one = 1.0; + +double atanh(double x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + double t; + int32_t hx, ix; + uint32_t lx; + EXTRACT_WORDS(hx, lx, x); + ix = hx & 0x7fffffff; + + if ((ix | ((lx | (-lx)) >> 31)) > 0x3ff00000) { /* |x|>1 */ + if (isnan(x)) { + return x + x; + } else { + return __raise_invalid(); + } + } + + if (ix == 0x3ff00000) { + return __raise_div_by_zero(x); + } + + if (ix < 0x3e300000) { /* x<2**-28 */ + if (x == 0.0) { /* return x inexact except 0 */ + return x; + } else { + return __raise_inexact(x); + } + } + + 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; + } +} +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double atanhl(long double x) +{ + return (long double) atanh((double) x); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/cbrtd.c b/libm/libmcs/libm/mathd/cbrtd.c new file mode 100644 index 00000000..9736b5d6 --- /dev/null +++ b/libm/libmcs/libm/mathd/cbrtd.c @@ -0,0 +1,136 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +/** + * + * This family of functions implements the cubic root of :math:`x`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float cbrtf(float x); + * double cbrt(double x); + * long double cbrtl(long double x); + * + * Description + * =========== + * + * ``cbrt`` computes the cubic root of the input value. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * cbrt(x) \approx \sqrt[3]{x} + * + * Returns + * ======= + * + * ``cbrt`` returns the cubic root of the input value. + * + * Exceptions + * ========== + * + * Does not raise exceptions. + * + * Output map + * ========== + * + * +---------------------+--------------+---------------------+--------------+--------------+---------------------+--------------+--------------+ + * | **x** | :math:`-Inf` | :math:`<0` | :math:`-0` | :math:`+0` | :math:`>0` | :math:`+Inf` | :math:`NaN` | + * +=====================+==============+=====================+==============+==============+=====================+==============+==============+ + * | **cbrt(x)** | :math:`-Inf` | :math:`\sqrt[3]{x}` | :math:`x` | :math:`\sqrt[3]{x}` | :math:`+Inf` | :math:`qNaN` | + * +---------------------+--------------+---------------------+--------------+--------------+---------------------+--------------+--------------+ + * + */ + +#include +#include "../common/tools.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +static const uint32_t +B1 = 715094163, /* B1 = (682-0.03306235651)*2**20 */ +B2 = 696219795; /* B2 = (664-0.03306235651)*2**20 */ + +static const double +C = 5.42857142857142815906e-01, /* 19/35 = 0x3FE15F15, 0xF15F15F1 */ +D = -7.05306122448979611050e-01, /* -864/1225 = 0xBFE691DE, 0x2532C834 */ +E = 1.41428571428571436819e+00, /* 99/70 = 0x3FF6A0EA, 0x0EA0EA0F */ +F = 1.60714285714285720630e+00, /* 45/28 = 0x3FF9B6DB, 0x6DB6DB6E */ +G = 3.57142857142857150787e-01; /* 5/14 = 0x3FD6DB6D, 0xB6DB6DB7 */ + +double cbrt(double x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + int32_t hx; + double r, s, t = 0.0, w; + uint32_t sign; + uint32_t high, low; + + GET_HIGH_WORD(hx, x); + sign = hx & 0x80000000U; /* sign= sign(x) */ + hx ^= sign; + + if (hx >= 0x7ff00000) { + return (x + x); /* cbrt(NaN,INF) is itself */ + } + + GET_LOW_WORD(low, x); + + if ((hx | low) == 0) { + return (x); /* cbrt(0) is itself */ + } + + SET_HIGH_WORD(x, hx); /* x <- |x| */ + + /* rough cbrt to 5 bits */ + if (hx < 0x00100000) { /* subnormal number */ + SET_HIGH_WORD(t, 0x43500000); /* set t= 2**54 */ + t *= x; + GET_HIGH_WORD(high, t); + SET_HIGH_WORD(t, high / 3 + B2); + } else { + SET_HIGH_WORD(t, hx / 3 + B1); + } + + + /* new cbrt to 23 bits, may be implemented in single precision */ + r = t * t / x; + s = C + r * t; + t *= G + F / (s + E + D / s); + + /* chopped to 20 bits and make it larger than cbrt(x) */ + GET_HIGH_WORD(high, t); + INSERT_WORDS(t, high + 0x00000001, 0); + + + /* one step newton iteration to 53 bits with error less than 0.667 ulps */ + s = t * t; /* t*t is exact */ + r = x / s; + w = t + t; + r = (r - t) / (w + r); /* r-s is exact */ + t = t + t * r; + + /* retore the sign bit */ + GET_HIGH_WORD(high, t); + SET_HIGH_WORD(t, high | sign); + return (t); +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double cbrtl(long double x) +{ + return (long double) cbrt((double) x); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/ceild.c b/libm/libmcs/libm/mathd/ceild.c new file mode 100644 index 00000000..6fbc81c4 --- /dev/null +++ b/libm/libmcs/libm/mathd/ceild.c @@ -0,0 +1,142 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +/** + * + * This family of functions implements rounding towards positive infinity of + * :math:`x`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float ceilf(float x); + * double ceil(double x); + * long double ceill(long double x); + * + * Description + * =========== + * + * ``ceil`` computes the input value rounded towards positive infinity. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * ceil(x) = \lceil x \rceil + * + * Returns + * ======= + * + * ``ceil`` returns the input value rounded towards positive infinity. + * + * Exceptions + * ========== + * + * Does not raise exceptions. + * + * Output map + * ========== + * + * +---------------------+--------------+-------------------------+--------------+--------------+-------------------------+--------------+--------------+ + * | **x** | :math:`-Inf` | :math:`<0` | :math:`-0` | :math:`+0` | :math:`>0` | :math:`+Inf` | :math:`NaN` | + * +=====================+==============+=========================+==============+==============+=========================+==============+==============+ + * | **ceil(x)** | :math:`-Inf` | :math:`\lceil x \rceil` | :math:`x` | :math:`\lceil x \rceil` | :math:`+Inf` | :math:`qNaN` | + * +---------------------+--------------+-------------------------+--------------+--------------+-------------------------+--------------+--------------+ + * + */ + +#include +#include "../common/tools.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +double ceil(double x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + int32_t _i0, _i1, _j0; + uint32_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 (((_i0 & 0x7fffffff) | _i1) == 0) { + return x; + } + + (void) __raise_inexact(x); + + if (_i0 < 0) { /* return 0*sign(x) if |x|<1 */ + _i0 = (int32_t)0x80000000U; + _i1 = 0; + } else { + _i0 = 0x3ff00000; + _i1 = 0; + } + } else { + i = (0x000fffff) >> _j0; + + if (((_i0 & i) | _i1) == 0) { + return x; /* x is integral */ + } + + (void) __raise_inexact(x); /* 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 = ((uint32_t)0xffffffffU) >> (_j0 - 20); + + if ((_i1 & i) == 0) { + return x; /* x is integral */ + } + + (void) __raise_inexact(x); /* raise inexact flag */ + if (_i0 > 0) { + if (_j0 == 20) { + _i0 += 1; + } else { + j = _i1 + (1 << (52 - _j0)); + + if (j < (uint32_t)_i1) { + _i0 += 1; /* got a carry */ + } + + _i1 = j; + } + } + + _i1 &= (~i); + } + + INSERT_WORDS(x, _i0, _i1); + return x; +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double ceill(long double x) +{ + return (long double) ceil((double) x); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/copysignd.c b/libm/libmcs/libm/mathd/copysignd.c new file mode 100644 index 00000000..ec3b4b84 --- /dev/null +++ b/libm/libmcs/libm/mathd/copysignd.c @@ -0,0 +1,93 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +/** + * + * This family of functions copies the sign of :math:`y` onto :math:`x`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float copysignf(float x, float y); + * double copysign(double x, double y); + * long double copysignl(long double x, long double y); + * + * Description + * =========== + * + * ``copysign`` computes the value with the magnitude of :math:`x` and sign of + * :math:`y`. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * copysign(x, y) = |x| \cdot sgn\ y + * + * Returns + * ======= + * + * ``copysign`` returns the value with the magnitude of :math:`x` and sign of + * :math:`y`. + * + * Exceptions + * ========== + * + * Does not raise exceptions. + * + * Does not raise ``invalid operation`` exception on ``sNaN`` input. + * + * Output map + * ========== + * + * +--------------------------+--------------------------+--------------------------+ + * | copysign(x,y) | x | + * +--------------------------+--------------------------+--------------------------+ + * | y | :math:`\neq NaN` | :math:`NaN` | + * +==========================+==========================+==========================+ + * | :math:`-NaN` | :math:`-|x|` | :math:`qNaN` | + * +--------------------------+ + + + * | :math:`-Inf` | | | + * +--------------------------+ + + + * | :math:`<0` | | | + * +--------------------------+ + + + * | :math:`-0` | | | + * +--------------------------+--------------------------+ + + * | :math:`+0` | :math:`|x|` | | + * +--------------------------+ + + + * | :math:`>0` | | | + * +--------------------------+ + + + * | :math:`+Inf` | | | + * +--------------------------+ + + + * | :math:`+NaN` | | | + * +--------------------------+--------------------------+--------------------------+ + * + */ + +#include +#include "../common/tools.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +double copysign(double x, double y) +{ + uint32_t hx, hy; + GET_HIGH_WORD(hx, x); + GET_HIGH_WORD(hy, y); + SET_HIGH_WORD(x, (hx & 0x7fffffffU) | (hy & 0x80000000U)); + return x; +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double copysignl(long double x, long double y) +{ + return (long double) copysign((double) x, (double) y); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/cosd.c b/libm/libmcs/libm/mathd/cosd.c new file mode 100644 index 00000000..2a6d9d3f --- /dev/null +++ b/libm/libmcs/libm/mathd/cosd.c @@ -0,0 +1,121 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +/** + * + * This family of functions implements the cosine of :math:`x`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float cosf(float x); + * double cos(double x); + * long double cosl(long double x); + * + * Description + * =========== + * + * ``cos`` computes the cosine of the input value. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * cos(x) \approx cos(x) + * + * Returns + * ======= + * + * ``cos`` returns the cosine of the input value, in the range :math:`[-1, 1]`. + * + * Exceptions + * ========== + * + * Raise ``invalid operation`` exception when the input value is infinite. + * + * Output map + * ========== + * + * +---------------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+ + * | **x** | :math:`-Inf` | :math:`<0` | :math:`-0` | :math:`+0` | :math:`>0` | :math:`+Inf` | :math:`NaN` | + * +=====================+================+================+================+================+================+================+================+ + * | **cos(x)** | :math:`qNaN` | :math:`cos(x)` | :math:`1` | :math:`cos(x)` | :math:`qNaN` | :math:`qNaN` | + * +---------------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+ + * + */ + +#include +#include "../common/tools.h" +#include "internal/trigd.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +double cos(double x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + 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 (x == 0.0) { /* return 1 inexact except 0 */ + return 1.0; + } else { + return __raise_inexactf(1.0); + } + } + + return __cos(x, z); + } + + /* cos(Inf or NaN) is NaN */ + else if (ix >= 0x7ff00000) { + if (isnan(x)) { + return x + x; + } else { + return __raise_invalid(); + } + } + + /* argument reduction needed */ + else { + n = __rem_pio2(x, y); + + switch (n & 3) { + case 0: + return __cos(y[0], y[1]); + + case 1: + return -__sin(y[0], y[1], 1); + + case 2: + return -__cos(y[0], y[1]); + + default: + return __sin(y[0], y[1], 1); + } + } +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double cosl(long double x) +{ + return (long double) cos((double) x); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/coshd.c b/libm/libmcs/libm/mathd/coshd.c new file mode 100644 index 00000000..1ed4033a --- /dev/null +++ b/libm/libmcs/libm/mathd/coshd.c @@ -0,0 +1,122 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +/** + * + * This family of functions implements the hyperbolic cosine of :math:`x`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float coshf(float x); + * double cosh(double x); + * long double coshl(long double x); + * + * Description + * =========== + * + * ``cosh`` computes the hyperbolic cosine of the input value. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * cosh(x) \approx cosh(x) = \frac{e^x+e^{-x}}{2} + * + * Returns + * ======= + * + * ``cosh`` returns the hyperbolic cosine, in the range :math:`\mathbb{F}_{>=1}`. + * + * Exceptions + * ========== + * + * Raise ``overflow`` exception when the magnitude of the input value is too large. + * + * Output map + * ========== + * + * +---------------------+--------------+-----------------+--------------+--------------+-----------------+--------------+--------------+ + * | **x** | :math:`-Inf` | :math:`<0` | :math:`-0` | :math:`+0` | :math:`>0` | :math:`+Inf` | :math:`NaN` | + * +=====================+==============+=================+==============+==============+=================+==============+==============+ + * | **cosh(x)** | :math:`+Inf` | :math:`cosh(x)` | :math:`1` | :math:`cosh(x)` | :math:`+Inf` | :math:`qNaN` | + * +---------------------+--------------+-----------------+--------------+--------------+-----------------+--------------+--------------+ + * + */ + +#include +#include "../common/tools.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +static const double one = 1.0, half = 0.5; + +double cosh(double x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + double t, w; + int32_t ix; + uint32_t lx; + + /* 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 = exp(fabs(x)); + return half * t + half / t; + } + + /* |x| in [22, log(maxdouble)] return half*exp(|x|) */ + if (ix < 0x40862E42) { + return half * exp(fabs(x)); + } + + /* |x| in [log(maxdouble), overflowthresold] */ + GET_LOW_WORD(lx, x); + + if (ix < 0x408633CE || + (ix == 0x408633ce && lx <= (uint32_t)0x8fb9f87dU)) { + w = exp(half * fabs(x)); + t = half * w; + return t * w; + } + + /* |x| > overflowthresold, cosh(x) overflow */ + return __raise_overflow(1.0); +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double coshl(long double x) +{ + return (long double) cosh((double) x); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/erfcd.c b/libm/libmcs/libm/mathd/erfcd.c new file mode 100644 index 00000000..f201af1f --- /dev/null +++ b/libm/libmcs/libm/mathd/erfcd.c @@ -0,0 +1,253 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +/** + * + * This family of functions implements the complementary error function of + * :math:`x` and is equal to :math:`1 -` erf(:math:`x`). + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float erfcf(float x); + * double erfc(double x); + * long double erfcl(long double x); + * + * Description + * =========== + * + * ``erfc`` computes the complementary error function of :math:`x`. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * erfc(x) \approx 1 - \frac{2}{\sqrt{\pi}}\int_{0}^{x}e^{-t^2}dt + * + * Returns + * ======= + * + * ``erfc`` returns the complementary error function of :math:`x`, in the range + * :math:`[+0.0, 2.0]`. + * + * Exceptions + * ========== + * + * Does not raise overflow, division by zero, and invalid exceptions. + * + * .. May raise ``underflow`` exception. + * + * Output map + * ========== + * + * +---------------------+--------------+------------------------------------------------------+--------------+--------------+------------------------------------------------------+--------------+--------------+ + * | **x** | :math:`-Inf` | :math:`<0` | :math:`-0` | :math:`+0` | :math:`>0` | :math:`+Inf` | :math:`NaN` | + * +=====================+==============+======================================================+==============+==============+======================================================+==============+==============+ + * | **erfc(x)** | :math:`+2` | :math:`1-\frac{2}{\sqrt{\pi}}\int_{0}^{x}e^{-t^2}dt` | :math:`+1` | :math:`1-\frac{2}{\sqrt{\pi}}\int_{0}^{x}e^{-t^2}dt` | :math:`+0` | :math:`qNaN` | + * +---------------------+--------------+------------------------------------------------------+--------------+--------------+------------------------------------------------------+--------------+--------------+ + * + */ + +/* 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 "../common/tools.h" +#include "internal/errorfunctiond.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +static const double +half = 5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */ +two = 2.00000000000000000000e+00, /* 0x40000000, 0x00000000 */ +erx = 8.45062911510467529297e-01; /* 0x3FEB0AC1, 0x60000000 */ + +double erfc(double x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + int32_t hx, ix; + double R, S, P, Q, s, y, z, r; + GET_HIGH_WORD(hx, x); + ix = hx & 0x7fffffff; + + if (ix >= 0x7ff00000) { + if (isnan(x)) { /* erfc(nan) = nan */ + return x + x; + } else if (hx > 0) { /* erfc(+inf) = 0 */ + return 0.0; + } else { /* erfc(-inf) = 2 */ + return two; + } + } + + if (ix < 0x3feb0000) { /* |x|<0.84375 */ + if (ix < 0x3c700000) { /* |x|<2**-56 */ + return __raise_inexact(one); + } + + y = __erf_y(x); + + 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 = __erf_P(s); + Q = __erf_Q(s); + + 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 = __erf_Ra(s); + S = __erf_Sa(s); + } else { /* |x| >= 1/.35 ~ 2.857143 */ + if (hx < 0 && ix >= 0x40180000) { + return __raise_inexact(two); /* x < -6 */ + } + + R = __erf_Rb(s); + S = __erf_Sb(s); + } + + z = x; + SET_LOW_WORD(z, 0); + r = exp(-z * z - 0.5625) * exp((z - x) * (z + x) + R / S); + + if (hx > 0) { + return r / x; + } else { + return two - r / x; + } + } else { + if (hx > 0) { + return __raise_underflow(0.0); + } else { + return __raise_inexact(two); + } + } +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double erfcl(long double x) +{ + return (long double) erfc((double) x); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/erfd.c b/libm/libmcs/libm/mathd/erfd.c new file mode 100644 index 00000000..7b5ff4aa --- /dev/null +++ b/libm/libmcs/libm/mathd/erfd.c @@ -0,0 +1,242 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +/** + * + * This family of functions implements the error function of :math:`x`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float erff(float x); + * double erf(double x); + * long double erfl(long double x); + * + * Description + * =========== + * + * ``erf`` computes the error function of :math:`x`. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * erf(x) \approx \frac{2}{\sqrt{\pi}}\int_{0}^{x}e^{-t^2}dt + * + * Returns + * ======= + * + * ``erf`` returns the error function of :math:`x`, in the range + * :math:`[-1.0, +1.0]`. + * + * Exceptions + * ========== + * + * Does not raise overflow, division by zero, and invalid exceptions. + * + * .. May raise ``underflow`` exception. + * + * Output map + * ========== + * + * +---------------------+--------------+-----------------------------------------------------+--------------+--------------+-----------------------------------------------------+--------------+--------------+ + * | **x** | :math:`-Inf` | :math:`<0` | :math:`-0` | :math:`+0` | :math:`>0` | :math:`+Inf` | :math:`NaN` | + * +=====================+==============+=====================================================+==============+==============+=====================================================+==============+==============+ + * | **erf(x)** | :math:`-Inf` | :math:`\frac{2}{\sqrt{\pi}}\int_{0}^{x}e^{-t^2}dt` | :math:`x` | :math:`\frac{2}{\sqrt{\pi}}\int_{0}^{x}e^{-t^2}dt` | :math:`+Inf` | :math:`qNaN` | + * +---------------------+--------------+-----------------------------------------------------+--------------+--------------+-----------------------------------------------------+--------------+--------------+ + * + */ + +/* 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 "../common/tools.h" +#include "internal/errorfunctiond.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +static const double +erx = 8.45062911510467529297e-01, /* 0x3FEB0AC1, 0x60000000 */ +efx = 1.28379167095512586316e-01, /* 0x3FC06EBA, 0x8214DB69 */ +efx8 = 1.02703333676410069053e+00; /* 0x3FF06EBA, 0x8214DB69 */ + +double erf(double x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + int32_t hx, ix; + double R, S, P, Q, s, z, r; + GET_HIGH_WORD(hx, x); + ix = hx & 0x7fffffff; + + if (ix >= 0x7ff00000) { + if (isnan(x)) { /* erf(nan) = nan */ + return x + x; + } else if (hx > 0) { /* erf(+inf) = +1 */ + return 1.0; + } else { /* erf(-inf) = -1 */ + return -1.0; + } + } + + 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; + } + + return x + x * __erf_y(x); + } + + if (ix < 0x3ff40000) { /* 0.84375 <= |x| < 1.25 */ + s = fabs(x) - one; + P = __erf_P(s); + Q = __erf_Q(s); + + if (hx >= 0) { + return erx + P / Q; + } else { + return -erx - P / Q; + } + } + + if (ix >= 0x40180000) { /* inf>|x|>=6 */ + if (hx >= 0) { + return __raise_inexact(one); + } else { + return -__raise_inexact(one); + } + } + + x = fabs(x); + s = one / (x * x); + + if (ix < 0x4006DB6E) { /* |x| < 1/0.35 */ + R = __erf_Ra(s); + S = __erf_Sa(s); + } else { /* |x| >= 1/0.35 */ + R = __erf_Rb(s); + S = __erf_Sb(s); + } + + z = x; + SET_LOW_WORD(z, 0); + r = exp(-z * z - 0.5625) * exp((z - x) * (z + x) + R / S); + + if (hx >= 0) { + return one - r / x; + } else { + return r / x - one; + } +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double erfl(long double x) +{ + return (long double) erf((double) x); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/exp2d.c b/libm/libmcs/libm/mathd/exp2d.c new file mode 100644 index 00000000..dbe51eee --- /dev/null +++ b/libm/libmcs/libm/mathd/exp2d.c @@ -0,0 +1,76 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +/** + * + * This family of functions implements :math:`2` powered by :math:`x`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float exp2f(float x); + * double exp2(double x); + * long double exp2l(long double x); + * + * Description + * =========== + * + * ``exp2`` computes :math:`2` powered by the input value. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * exp2(x) \approx 2^x + * + * Returns + * ======= + * + * ``exp2`` returns :math:`2` powered by :math:`x`, in the range + * :math:`\mathbb{F}^{+}_0`. + * + * Exceptions + * ========== + * + * Raise ``overflow`` exception when the magnitude of the input value is too + * large. + * + * .. May raise ``underflow`` exception. + * + * Output map + * ========== + * + * +---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ + * | **x** | :math:`-Inf` | :math:`<0` | :math:`-0` | :math:`+0` | :math:`>0` | :math:`+Inf` | :math:`NaN` | + * +=====================+==============+==============+==============+==============+==============+==============+==============+ + * | **exp2(x)** | :math:`+0` | :math:`2^x` | :math:`+1` | :math:`2^x` | :math:`+Inf` | :math:`qNaN` | + * +---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ + * + */ + +#include + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +double exp2(double x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + return pow(2.0, x); +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double exp2l(long double x) +{ + return (long double) exp2((double) x); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/expd.c b/libm/libmcs/libm/mathd/expd.c new file mode 100644 index 00000000..e7af6ae1 --- /dev/null +++ b/libm/libmcs/libm/mathd/expd.c @@ -0,0 +1,177 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +/** + * + * This family of functions implements the exponential function, that is + * :math:`e` powered by :math:`x`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float expf(float x); + * double exp(double x); + * long double expl(long double x); + * + * Description + * =========== + * + * ``exp`` computes :math:`e` powered by the input value. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * exp(x) \approx e^x + * + * Returns + * ======= + * + * ``exp`` returns :math:`e` powered by :math:`x`, in the range + * :math:`\mathbb{F}^{+}_0`. + * + * Exceptions + * ========== + * + * Raise ``overflow`` exception when the magnitude of the input value is too + * large. + * + * .. May raise ``underflow`` exception. + * + * Output map + * ========== + * + * +---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ + * | **x** | :math:`-Inf` | :math:`<0` | :math:`-0` | :math:`+0` | :math:`>0` | :math:`+Inf` | :math:`NaN` | + * +=====================+==============+==============+==============+==============+==============+==============+==============+ + * | **exp(x)** | :math:`+0` | :math:`e^x` | :math:`+1` | :math:`e^x` | :math:`+Inf` | :math:`qNaN` | + * +---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ + * + */ + +#include +#include "../common/tools.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +static const double +one = 1.0, +zero = 0.0, +halF[2] = {0.5, -0.5,}, +twom1000 = 9.33263618503218878990e-302, /* 2**-1000=0x01700000,0*/ +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 */ + +double exp(double x) /* default IEEE double exp */ +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + double y, c, t; + double hi = 0.0; + double lo = 0.0; + int32_t k = 0; + int32_t xsb; + uint32_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) { + uint32_t lx; + GET_LOW_WORD(lx, x); + + if (((hx & 0xfffff) | lx) != 0) { + return x + x; /* NaN */ + } else { /* exp(+-inf)={inf,0} */ + return (xsb == 0) ? x : zero; + } + } + + if (x > o_threshold) { + return __raise_overflow(one); /* overflow */ + } + + if (x < u_threshold) { + return __raise_underflow(zero); /* underflow */ + } + } + + /* 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 = invln2 * x + halF[xsb]; + t = k; + hi = x - t * ln2HI[0]; /* t*ln2HI is exact here */ + lo = t * ln2LO[0]; + } + + x = hi - lo; + } else if (hx < 0x3df00000) { /* when |x|<2**-32 */ + if (x == 0.0) { /* return 1 inexact except 0 */ + return one; + } else { + return __raise_inexact(one + x); + } + } else { + /* No action required */ + } + + /* x is now in primary range */ + t = x * x; + 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) { + uint32_t hy; + GET_HIGH_WORD(hy, y); + SET_HIGH_WORD(y, hy + (((uint32_t)k) << 20)); /* add k to y's exponent */ + return y; + } else { + uint32_t hy; + GET_HIGH_WORD(hy, y); + SET_HIGH_WORD(y, hy + (((uint32_t)k + 1000U) << 20)); /* add k to y's exponent */ + return y * twom1000; + } +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double expl(long double x) +{ + return (long double) exp((double) x); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/expm1d.c b/libm/libmcs/libm/mathd/expm1d.c new file mode 100644 index 00000000..afade950 --- /dev/null +++ b/libm/libmcs/libm/mathd/expm1d.c @@ -0,0 +1,305 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +/** + * + * This family of functions implements the exponential function minus + * :math:`1`, that is :math:`e` powered by :math:`x` before subtracting + * :math:`1`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float expm1f(float x); + * double expm1(double x); + * long double expm1l(long double x); + * + * Description + * =========== + * + * ``expm1`` computes :math:`e` powered by the input value subtracted by + * :math:`1`. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * expm1(x) \approx e^x - 1 + * + * Returns + * ======= + * + * ``expm1`` returns :math:`e` powered by :math:`x` subtracted by :math:`1`, in + * the range :math:`\mathbb{F}_{>=-1}`. + * + * Exceptions + * ========== + * + * Raise ``overflow`` exception when the magnitude of the input value is too + * large. + * + * .. May raise ``underflow`` exception. + * + * Output map + * ========== + * + * +---------------------+---------------+---------------+---------------+---------------+---------------+---------------+---------------+ + * | **x** | :math:`-Inf` | :math:`<0` | :math:`-0` | :math:`+0` | :math:`>0` | :math:`+Inf` | :math:`NaN` | + * +=====================+===============+===============+===============+===============+===============+===============+===============+ + * | **expm1(x)** | :math:`-1` | :math:`e^x-1` | :math:`+0` | :math:`e^x-1` | :math:`+Inf` | :math:`qNaN` | + * +---------------------+---------------+---------------+---------------+---------------+---------------+---------------+---------------+ + * + */ + +/* 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 Remez 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; + * (where z=r*r, and the values of Q1 to Q5 are listed below) + * 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 "../common/tools.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +static const double +one = 1.0, +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 coefficients related to expm1 */ +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 */ + +double expm1(double x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + double y, hi, lo, c, t, e, hxs, hfx, r1; + int32_t k, xsb; + uint32_t hx; + + c = NAN; /* initial value of c is never actually used */ + + GET_HIGH_WORD(hx, x); + xsb = hx & 0x80000000U; /* 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) { + uint32_t low; + GET_LOW_WORD(low, x); + + if (((hx & 0xfffff) | low) != 0) { + return x + x; /* NaN */ + } else { /* exp(+-inf)={inf,-1} */ + return (xsb == 0) ? x : -1.0; + } + } + + if (x > o_threshold) { + return __raise_overflow(one); /* overflow */ + } + } + + if (xsb != 0) { /* x < -56*ln2, return -1.0 with inexact */ + return -__raise_inexact(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; + } + + x = hi - lo; + c = (hi - x) - lo; + } else if (hx < 0x3c900000) { /* when |x|<2**-54, return x */ + if (x == 0.0) { + return x; + } else { /* return x with inexact flags when x!=0 */ + return __raise_inexact(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 { + 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 */ + uint32_t high; + y = one - (e - x); + GET_HIGH_WORD(high, y); + SET_HIGH_WORD(y, high + (((uint32_t)k) << 20)); /* add k to y's exponent */ + return y - one; + } + + t = one; + + if (k < 20) { + uint32_t high; + SET_HIGH_WORD(t, 0x3ff00000 - (0x200000 >> k)); /* t=1-2^-k */ + y = t - (e - x); + GET_HIGH_WORD(high, y); + SET_HIGH_WORD(y, high + (k << 20)); /* add k to y's exponent */ + } else { + uint32_t high; + SET_HIGH_WORD(t, ((0x3ff - k) << 20)); /* 2^-k */ + y = x - (e + t); + y += one; + GET_HIGH_WORD(high, y); + SET_HIGH_WORD(y, high + (k << 20)); /* add k to y's exponent */ + } + } + + return y; +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double expm1l(long double x) +{ + return (long double) expm1((double) x); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/fabsd.c b/libm/libmcs/libm/mathd/fabsd.c new file mode 100644 index 00000000..b6d6740d --- /dev/null +++ b/libm/libmcs/libm/mathd/fabsd.c @@ -0,0 +1,77 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +/** + * + * This family of functions implements the absolute value of :math:`x`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float fabsf(float x); + * double fabs(double x); + * long double fabsl(long double x); + * + * Description + * =========== + * + * ``fabs`` computes the absolute value of the input value. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * fabs(x) = |x| + * + * Returns + * ======= + * + * ``fabs`` returns the absolute value of the input value. + * + * ``fabs`` does not differentiate between different types of ``NaN``, as such + * if the input is ``sNaN`` so will the output, only the sign bit may change. + * + * Exceptions + * ========== + * + * Does not raise exceptions. + * + * Does not raise ``invalid operation`` exception on ``sNaN`` input. + * + * Output map + * ========== + * + * +---------------------+--------------+---------------------+--------------+--------------+---------------------+--------------+--------------+--------------+ + * | **x** | :math:`-Inf` | :math:`<0` | :math:`-0` | :math:`+0` | :math:`>0` | :math:`+Inf` | :math:`qNaN` | :math:`sNaN` | + * +=====================+==============+=====================+==============+==============+=====================+==============+==============+==============+ + * | **fabs(x)** | :math:`+Inf` | :math:`-x` | :math:`+0` | :math:`x` | :math:`+Inf` | :math:`qNaN` | :math:`sNaN` | + * +---------------------+--------------+---------------------+--------------+--------------+---------------------+--------------+--------------+--------------+ + * + */ + +#include +#include "../common/tools.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +double fabs(double x) +{ + uint32_t high; + GET_HIGH_WORD(high, x); + SET_HIGH_WORD(x, high & 0x7fffffff); + return x; +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double fabsl(long double x) +{ + return (long double) fabs((double) x); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/fdimd.c b/libm/libmcs/libm/mathd/fdimd.c new file mode 100644 index 00000000..2ddd1b44 --- /dev/null +++ b/libm/libmcs/libm/mathd/fdimd.c @@ -0,0 +1,96 @@ +/* SPDX-License-Identifier: RedHat */ +/* Copyright (C) 2002 by Red Hat, Incorporated. All rights reserved. */ + +/** + * + * This family of functions implements the positive difference value of + * :math:`x` subtracted by :math:`y`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float fdimf(float x, float y); + * double fdim(double x, double y); + * long double fdiml(long double x, long double y); + * + * Description + * =========== + * + * ``fdim`` computes the positive difference value of :math:`x` subtracted by + * :math:`y`. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * fdim(x, y) \approx \left\{\begin{array}{ll} x - y, & x > y \\ 0, & otherwise \end{array}\right. + * + * Returns + * ======= + * + * ``fdim`` returns the positive difference value of :math:`x` subtracted by + * :math:`y`. + * + * Exceptions + * ========== + * + * Raise ``overflow`` exception when the result overflows. + * + * .. May raise ``underflow`` exception. + * + * Output map + * ========== + * + * +--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+ + * | fdim(x,y) | x | + * +--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+ + * | y | :math:`-Inf` | :math:`<0` | :math:`-0` | :math:`+0` | :math:`>0` | :math:`+Inf` | :math:`NaN` | + * +==========================+==========================+==========================+==========================+==========================+==========================+==========================+==========================+ + * | :math:`-Inf` | :math:`+0` | :math:`+Inf` | :math:`qNaN` | + * +--------------------------+ +--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+ + * | :math:`<0` | | :math:`fdim(x, y)` | :math:`x - y` | :math:`x - y` | :math:`+Inf` | | + * +--------------------------+ +--------------------------+--------------------------+--------------------------+ + + + + * | :math:`-0` | | :math:`+0` | :math:`+0` | | | | + * +--------------------------+ + + + + + + + * | :math:`+0` | | | | | | | + * +--------------------------+ + + +--------------------------+ + + + * | :math:`>0` | | | | :math:`fdim(x, y)` | | | + * +--------------------------+ +--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+ + + * | :math:`+Inf` | | :math:`+0` | | + * +--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+ + + * | :math:`NaN` | :math:`qNaN` | | + * +--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+ + * + */ + +#include + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +double fdim(double x, double y) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_one; + y *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + if (isnan(x) || isnan(y)) { + return x * y; + } + + return x > y ? x - y : 0.0; +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double fdiml(long double x, long double y) +{ + return (long double) fdim((double) x, (double) y); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/floord.c b/libm/libmcs/libm/mathd/floord.c new file mode 100644 index 00000000..c09662ba --- /dev/null +++ b/libm/libmcs/libm/mathd/floord.c @@ -0,0 +1,142 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +/** + * + * This family of functions implements rounding towards negative infinity of + * :math:`x`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float floorf(float x); + * double floor(double x); + * long double floorl(long double x); + * + * Description + * =========== + * + * ``floor`` computes the input value rounded towards negative infinity. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * floor(x) = \lfloor x \rfloor + * + * Returns + * ======= + * + * ``floor`` returns the input value rounded towards negative infinity. + * + * Exceptions + * ========== + * + * Does not raise exceptions. + * + * Output map + * ========== + * + * +---------------------+--------------+---------------------------+--------------+--------------+---------------------------+--------------+--------------+ + * | **x** | :math:`-Inf` | :math:`<0` | :math:`-0` | :math:`+0` | :math:`>0` | :math:`+Inf` | :math:`NaN` | + * +=====================+==============+===========================+==============+==============+===========================+==============+==============+ + * | **floor(x)** | :math:`-Inf` | :math:`\lfloor x \rfloor` | :math:`x` | :math:`\lfloor x \rfloor` | :math:`+Inf` | :math:`qNaN` | + * +---------------------+--------------+---------------------------+--------------+--------------+---------------------------+--------------+--------------+ + * + */ + +#include +#include "../common/tools.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +double floor(double x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + int32_t _i0, _i1, _j0; + uint32_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 (((_i0 & 0x7fffffff) | _i1) == 0) { + return x; + } + + (void) __raise_inexact(x); + + if (_i0 >= 0) { + _i0 = _i1 = 0; + } else { + _i0 = (int32_t)0xbff00000U; + _i1 = 0; + } + } else { + i = (0x000fffff) >> _j0; + + if (((_i0 & i) | _i1) == 0) { + return x; /* x is integral */ + } + + (void) __raise_inexact(x); + + 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 = ((uint32_t)0xffffffffU) >> (_j0 - 20); + + if ((_i1 & i) == 0) { + return x; /* x is integral */ + } + + (void) __raise_inexact(x); + + if (_i0 < 0) { + if (_j0 == 20) { + _i0 += 1; + } else { + j = _i1 + (1 << (52 - _j0)); + + if (j < (uint32_t)_i1) { + _i0 += 1 ; /* got a carry */ + } + + _i1 = j; + } + } + + _i1 &= (~i); + } + + INSERT_WORDS(x, _i0, _i1); + return x; +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double floorl(long double x) +{ + return (long double) floor((double) x); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/fmad.c b/libm/libmcs/libm/mathd/fmad.c new file mode 100644 index 00000000..07ce138b --- /dev/null +++ b/libm/libmcs/libm/mathd/fmad.c @@ -0,0 +1,118 @@ +/* SPDX-License-Identifier: GTDGmbH */ +/* Copyright 2020-2025 by GTD GmbH. */ + +/** + * + * This family of functions fuses the multiplication of :math:`x` and :math:`y` + * with the addition of :math:`z`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float fmaf(float x, float y, float z); + * double fma(double x, double y, double z); + * long double fmal(long double x, long double y, long double z); + * + * Description + * =========== + * + * ``fma`` computes the multiplication of :math:`x` and :math:`y` with the + * addition of :math:`z`. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * fma(x, y, z) = x \cdot y + z + * + * Returns + * ======= + * + * ``fma`` returns the multiplication of :math:`x` and :math:`y` with the + * addition of :math:`z`. + * + * Exceptions + * ========== + * + * Raise ``invalid operation`` exception when either :math:`x` or :math:`y` is + * zero and the other is infinity (regardless of the value in :math:`z`), or + * when :math:`x \cdot y` is infinity and :math:`z` is infinity with the + * opposite sign. + * + * Raise ``overflow`` exception if the result overflows. + * + * .. May raise ``underflow`` exception. + * + * Output map + * ========== + * + * +--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+ + * | :math:`x \cdot y` | x | + * +--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+ + * | y | :math:`-Inf` | :math:`<0` | :math:`-0` | :math:`+0` | :math:`>0` | :math:`+Inf` | :math:`NaN` | + * +==========================+==========================+==========================+==========================+==========================+==========================+==========================+==========================+ + * | :math:`-Inf` | :math:`+Inf` | :math:`+Inf` | :math:`qNaN` | :math:`+Inf` | :math:`+Inf` | :math:`qNaN` | + * +--------------------------+ +--------------------------+--------------------------+--------------------------+--------------------------+ + + + * | :math:`<0` | | :math:`x \cdot y` | :math:`+0` | :math:`-0` | :math:`x \cdot y` | | | + * +--------------------------+--------------------------+--------------------------+ + +--------------------------+--------------------------+ + + * | :math:`-0` | :math:`qNaN` | :math:`+0` | | | :math:`-0` | :math:`qNaN` | | + * +--------------------------+ +--------------------------+--------------------------+--------------------------+--------------------------+ + + + * | :math:`+0` | | :math:`-0` | :math:`-0` | :math:`+0` | :math:`+0` | | | + * +--------------------------+--------------------------+--------------------------+ + +--------------------------+--------------------------+ + + * | :math:`>0` | | :math:`x \cdot y` | | | :math:`x \cdot y` | | | + * +--------------------------+ +--------------------------+--------------------------+--------------------------+--------------------------+ + + + * | :math:`+Inf` | :math:`-Inf` | :math:`-Inf` | :math:`qNaN` | :math:`-Inf` | :math:`-Inf` | | + * +--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+ + + * | :math:`NaN` | :math:`qNaN` | | + * +--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+ + * + * +--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+ + * | fma(x,y,z) | z | + * +--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+ + * | :math:`x \cdot y` | :math:`-Inf` | :math:`<0` | :math:`-0` | :math:`+0` | :math:`>0` | :math:`+Inf` | :math:`NaN` | + * +==========================+==========================+==========================+==========================+==========================+==========================+==========================+==========================+ + * | :math:`-Inf` | :math:`-Inf` | :math:`-Inf` | :math:`qNaN` | :math:`qNaN` | + * +--------------------------+ +--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+ + + * | :math:`<0` | | :math:`x \cdot y + z` | :math:`x \cdot y` | :math:`x \cdot y + z` | :math:`+Inf` | | + * +--------------------------+ +--------------------------+--------------------------+--------------------------+--------------------------+ + + + * | :math:`-0` | | :math:`z` | :math:`-0` | :math:`+0` | :math:`z` | | | + * +--------------------------+ + +--------------------------+--------------------------+ + + + + * | :math:`+0` | | | :math:`+0` | :math:`+0` | | | | + * +--------------------------+ +--------------------------+--------------------------+--------------------------+--------------------------+ + + + * | :math:`>0` | | :math:`x \cdot y + z` | :math:`x \cdot y` | :math:`x \cdot y + z` | | | + * +--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+ + + + * | :math:`+Inf` | :math:`qNaN` | :math:`+Inf` | | | + * +--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+ + * | :math:`NaN` | :math:`qNaN` | + * +--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+ + * + */ + +#include + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +double fma(double x, double y, double z) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_one; + y *= __volatile_one; + z *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + return x * y + z; +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double fmal(long double x, long double y, long double z) +{ + return (long double) fma((double) x, (double) y, (double) z); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/fmaxd.c b/libm/libmcs/libm/mathd/fmaxd.c new file mode 100644 index 00000000..85cc08eb --- /dev/null +++ b/libm/libmcs/libm/mathd/fmaxd.c @@ -0,0 +1,110 @@ +/* SPDX-License-Identifier: RedHat */ +/* Copyright (C) 2002 by Red Hat, Incorporated. All rights reserved. */ + +/** + * + * This family of functions determines the maximum numerical value of :math:`x` and :math:`y`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float fmaxf(float x, float y); + * double fmax(double x, double y); + * long double fmaxl(long double x, long double y); + * + * Description + * =========== + * + * ``fmax`` computes the maximum numerical value of :math:`x` and :math:`y`. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * fmax(x, y) = \left\{\begin{array}{ll} x, & x > y \\ y, & otherwise \end{array}\right. + * + * Returns + * ======= + * + * ``fmax`` returns the maximum numerical value of :math:`x` and :math:`y`. + * + * Exceptions + * ========== + * + * Does raise invalid exception in case one of the parameters is :math:`sNaN`. + * + * Output map + * ========== + * + * +--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+ + * | fmax(x,y) | x | + * +--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+ + * | y | :math:`-Inf` | :math:`<0` | :math:`-0` | :math:`+0` | :math:`>0` | :math:`+Inf` | :math:`qNaN` | :math:`sNaN` | + * +==========================+==========================+==========================+==========================+==========================+==========================+==========================+==========================+==========================+ + * | :math:`-Inf` | :math:`y` | :math:`x` | :math:`x` | :math:`x` | :math:`x` | :math:`y` | :math:`qNaN` | + * +--------------------------+ +--------------------------+ + + + + + + * | :math:`<0` | | :math:`fmax(x, y)` | | | | | | + * +--------------------------+ +--------------------------+--------------------------+--------------------------+ + + + + + * | :math:`-0` | | :math:`y` | | | | | + * +--------------------------+ + + + + + + + * | :math:`+0` | | | | | | | + * +--------------------------+ + +--------------------------+ + + + + * | :math:`>0` | | | :math:`fmax(x, y)` | | | | + * +--------------------------+ + +--------------------------+--------------------------+ + + + * | :math:`+Inf` | | | :math:`y` | | | + * +--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+ + + + * | :math:`qNaN` | :math:`x` | | | + * +--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+ + + * | :math:`sNaN` | :math:`qNaN` | | + * +--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+ + * + */ + +#include +#include "../common/tools.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +double fmax(double x, double y) +{ + if (isnan(x)) { + if (__issignaling(x) != 0 || __issignaling(y) != 0) { + return x * y; + } +#ifdef __LIBMCS_FPU_DAZ + y *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + return y; + } + + if (isnan(y)) { + if (__issignaling(y) != 0) { + return x * y; + } +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + return x; + } + +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_one; + y *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + return x > y ? x : y; +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double fmaxl(long double x, long double y) +{ + return (long double) fmax((double) x, (double) y); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/fmind.c b/libm/libmcs/libm/mathd/fmind.c new file mode 100644 index 00000000..4c446cee --- /dev/null +++ b/libm/libmcs/libm/mathd/fmind.c @@ -0,0 +1,110 @@ +/* SPDX-License-Identifier: RedHat */ +/* Copyright (C) 2002 by Red Hat, Incorporated. All rights reserved. */ + +/** + * + * This family of functions determines the minimum numerical value of :math:`x` and :math:`y`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float fminf(float x, float y); + * double fmin(double x, double y); + * long double fminl(long double x, long double y); + * + * Description + * =========== + * + * ``fmin`` computes the minimum numerical value of :math:`x` and :math:`y`. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * fmin(x, y) = \left\{\begin{array}{ll} x, & x < y \\ y, & otherwise \end{array}\right. + * + * Returns + * ======= + * + * ``fmin`` returns the minimum numerical value of :math:`x` and :math:`y`. + * + * Exceptions + * ========== + * + * Does raise invalid exception in case one of the parameters is :math:`sNaN`. + * + * Output map + * ========== + * + * +--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+ + * | fmin(x,y) | x | + * +--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+ + * | y | :math:`-Inf` | :math:`<0` | :math:`-0` | :math:`+0` | :math:`>0` | :math:`+Inf` | :math:`qNaN` | :math:`sNaN` | + * +==========================+==========================+==========================+==========================+==========================+==========================+==========================+==========================+==========================+ + * | :math:`-Inf` | :math:`y` | :math:`y` | :math:`y` | :math:`y` | :math:`qNaN` | + * +--------------------------+--------------------------+--------------------------+ + + + + + * | :math:`<0` | :math:`x` | :math:`fmin(x, y)` | | | | | + * +--------------------------+ +--------------------------+ + + + + + * | :math:`-0` | | :math:`x` | | | | | + * +--------------------------+ + + + + + + + * | :math:`+0` | | | | | | | + * +--------------------------+ + +--------------------------+--------------------------+--------------------------+ + + + + * | :math:`>0` | | | :math:`x` | :math:`fmin(x, y)` | | | | + * +--------------------------+ + + +--------------------------+ + + + + * | :math:`+Inf` | | | | :math:`x` | | | | + * +--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+ + + + * | :math:`qNaN` | :math:`x` | | | + * +--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+ + + * | :math:`sNaN` | :math:`qNaN` | | + * +--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+ + * + */ + +#include +#include "../common/tools.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +double fmin(double x, double y) +{ + if (isnan(x)) { + if (__issignaling(x) != 0 || __issignaling(y) != 0) { + return x * y; + } +#ifdef __LIBMCS_FPU_DAZ + y *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + return y; + } + + if (isnan(y)) { + if (__issignaling(y) != 0) { + return x * y; + } +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + return x; + } + +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_one; + y *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + return x < y ? x : y; +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double fminl(long double x, long double y) +{ + return (long double) fmin((double) x, (double) y); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/fmodd.c b/libm/libmcs/libm/mathd/fmodd.c new file mode 100644 index 00000000..9ea0e5f2 --- /dev/null +++ b/libm/libmcs/libm/mathd/fmodd.c @@ -0,0 +1,282 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +/** + * + * This family of functions implements the floating-point remainder of + * :math:`x` divided by :math:`y`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float fmodf(float x, float y); + * double fmod(double x, double y); + * long double fmodl(long double x, long double y); + * + * Description + * =========== + * + * ``fmod`` computes the floating-point remainder of :math:`x` divided by + * :math:`y`. + * + * The ``fmod`` and ``remainder`` procedures are rather similar, but not the + * same, see examples: + * + * +----------------+----------------+----------------+----------------+ + * | x | y | fmod | remainder | + * +================+================+================+================+ + * | :math:`+2.456` | :math:`+2.0` | :math:`+0.456` | :math:`+0.456` | + * +----------------+----------------+----------------+----------------+ + * | :math:`+3.456` | :math:`+2.0` | :math:`+1.456` | :math:`-0.544` | + * +----------------+----------------+----------------+----------------+ + * | :math:`-2.456` | :math:`+2.0` | :math:`-0.456` | :math:`-0.456` | + * +----------------+----------------+----------------+----------------+ + * | :math:`-3.456` | :math:`+2.0` | :math:`-1.456` | :math:`+0.544` | + * +----------------+----------------+----------------+----------------+ + * | :math:`+2.456` | :math:`-2.0` | :math:`+0.456` | :math:`+0.456` | + * +----------------+----------------+----------------+----------------+ + * | :math:`+3.456` | :math:`-2.0` | :math:`+1.456` | :math:`-0.544` | + * +----------------+----------------+----------------+----------------+ + * | :math:`-2.456` | :math:`-2.0` | :math:`-0.456` | :math:`-0.456` | + * +----------------+----------------+----------------+----------------+ + * | :math:`-3.456` | :math:`-2.0` | :math:`-1.456` | :math:`+0.544` | + * +----------------+----------------+----------------+----------------+ + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * fmod(x, y) = x - n \cdot y \wedge n \in \mathbb{Z} \wedge |fmod(x, y)| < |y| \wedge \frac{f(x, y)}{|f(x, y)|} = \frac{x}{|x|} + * + * Returns + * ======= + * + * ``fmod`` returns the floating-point remainder of :math:`x` divided by :math:`y`. + * + * Exceptions + * ========== + * + * Raise ``invalid operation`` exception when :math:`x` is infinite or + * :math:`y` is zero. + * + * .. May raise ``underflow`` exception. + * + * Output map + * ========== + * + * +--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+ + * | fmod(x,y) | x | + * +--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+ + * | y | :math:`-Inf` | :math:`<0` | :math:`-0` | :math:`+0` | :math:`>0` | :math:`+Inf` | :math:`NaN` | + * +==========================+==========================+==========================+==========================+==========================+==========================+==========================+==========================+ + * | :math:`-Inf` | :math:`qNaN` | :math:`x` | :math:`qNaN` | :math:`qNaN` | + * +--------------------------+ +--------------------------+--------------------------+--------------------------+--------------------------+ + + + * | :math:`<0` | | :math:`fmod(x, y)` | :math:`x` | :math:`fmod(x, y)` | | | + * +--------------------------+ +--------------------------+--------------------------+--------------------------+--------------------------+ + + + * | :math:`-0` | | :math:`qNaN` | | | + * +--------------------------+ + + + + + * | :math:`+0` | | | | | + * +--------------------------+ +--------------------------+--------------------------+--------------------------+--------------------------+ + + + * | :math:`>0` | | :math:`fmod(x, y)` | :math:`x` | :math:`fmod(x, y)` | | | + * +--------------------------+ +--------------------------+--------------------------+--------------------------+--------------------------+ + + + * | :math:`+Inf` | | :math:`x` | | | + * +--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+ + + * | :math:`NaN` | :math:`qNaN` | | + * +--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+ + * + */ + +#include +#include "../common/tools.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +static const double Zero[] = {0.0, -0.0,}; + +double fmod(double x, double y) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_one; + y *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + int32_t n, hx, hy, hz, ix, iy, sx, i; + uint32_t lx, ly, lz; + + EXTRACT_WORDS(hx, lx, x); + EXTRACT_WORDS(hy, ly, y); + sx = hx & 0x80000000U; /* sign of x */ + hx ^= sx; /* |x| */ + hy &= 0x7fffffff; /* |y| */ + + /* purge off exception values */ + if (hx >= 0x7ff00000 || hy >= 0x7ff00000) { /* x or y is +-Inf/NaN */ + if (hx == 0x7ff00000 && lx == 0) { /* x is +-Inf */ + return __raise_invalid(); + } else if (isnan(x) || isnan(y)) { /* x or y is NaN */ + return x + y; + } else { + /* No action required */ + } + } else if ((hy | ly) == 0) { /* y is +-0 */ + return __raise_invalid(); + } else { + /* No action required */ + } + + if (hx <= hy) { + if ((hx < hy) || (lx < ly)) { + return x; /* |x|<|y| return x */ + } + + if (lx == ly) { + return Zero[(uint32_t)sx >> 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 << n) | (lx >> (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 << n) | (ly >> (32 - n)); + ly <<= n; + } else { + hy = ly << (n - 32); + ly = 0; + } + } + + /* fix point fmod */ + n = ix - iy; + + while (n-- > 0) { + hz = hx - hy; + lz = lx - ly; + + if (lx < ly) { + hz -= 1; + } + + if (hz < 0) { + hx = hx + hx + (lx >> 31); + lx = lx + lx; + } else { + if ((hz | lz) == 0) { /* return sign(x)*0 */ + return Zero[(uint32_t)sx >> 31]; + } + + hx = hz + hz + (lz >> 31); + lx = lz + lz; + } + } + + hz = hx - hy; + lz = lx - ly; + + if (lx < ly) { + hz -= 1; + } + + if (hz >= 0) { + hx = hz; + lx = lz; + } + + /* convert back to floating value and restore the sign */ + if ((hx | lx) == 0) { /* return sign(x)*0 */ + return Zero[(uint32_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) | ((uint32_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); +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + } + + return x; /* exact output */ +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double fmodl(long double x, long double y) +{ + return (long double) fmod((double) x, (double) y); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/frexpd.c b/libm/libmcs/libm/mathd/frexpd.c new file mode 100644 index 00000000..40dada40 --- /dev/null +++ b/libm/libmcs/libm/mathd/frexpd.c @@ -0,0 +1,118 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +/** + * + * This family of functions splits the input value into mantissa and exponent. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float frexpf(float x, int *eptr); + * double frexp(double x, int *eptr); + * long double frexpl(long double x, int *eptr); + * + * Description + * =========== + * + * ``frexp`` splits the input value into the normalized fraction of :math:`x` + * and its integral power of :math:`2`. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * frexp(x) = \frac{x}{2^{eptr}} \wedge frexp(x) \in [0.5,1[ + * + * Returns + * ======= + * + * ``frexp`` returns the normalized fraction of :math:`x` in the range + * :math:`[0.5,1[` and puts the integral power of :math:`2` into the output + * pointer :math:`*eptr`. + * + * Exceptions + * ========== + * + * Does not raise exceptions. + * + * Output map + * ========== + * + * +---------------------+--------------+----------------------------------+--------------+--------------+----------------------------------+--------------+--------------+ + * | **x** | :math:`-Inf` | :math:`<0` | :math:`-0` | :math:`+0` | :math:`>0` | :math:`+Inf` | :math:`NaN` | + * +=====================+==============+==================================+==============+==============+==================================+==============+==============+ + * | **frexp(x)** | :math:`qNaN` | :math:`\frac{x}{2^{eptr}}` | :math:`x` | :math:`\frac{x}{2^{eptr}}` | :math:`qNaN` | :math:`qNaN` | + * +---------------------+--------------+----------------------------------+--------------+--------------+----------------------------------+--------------+--------------+ + * | :math:`*eptr` | :math:`0` | :math:`log_2 \frac{x}{frexp(x)}` | :math:`0` | :math:`log_2 \frac{x}{frexp(x)}` | :math:`0` | :math:`0` | + * +---------------------+--------------+----------------------------------+--------------+--------------+----------------------------------+--------------+--------------+ + * + */ + +/* + * 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 "../common/tools.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +static const double +two54 = 1.80143985094819840000e+16; /* 0x43500000, 0x00000000 */ + +double frexp(double x, int *eptr) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + int _xexp = 0; + int32_t hx, ix, lx; + + assert(eptr != (void*)0); + if(eptr == (void*)0) { + eptr = &_xexp; + } + + EXTRACT_WORDS(hx, lx, x); + ix = 0x7fffffff & hx; + *eptr = 0; + + if (ix >= 0x7ff00000 || ((ix | lx) == 0)) { + return x + 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 & 0x800fffffU) | 0x3fe00000U; + SET_HIGH_WORD(x, hx); + return x; +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double frexpl(long double x, int *eptr) +{ + return (long double) frexp((double) x, eptr); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/hypotd.c b/libm/libmcs/libm/mathd/hypotd.c new file mode 100644 index 00000000..d676a9bc --- /dev/null +++ b/libm/libmcs/libm/mathd/hypotd.c @@ -0,0 +1,193 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +/** + * + * This family of functions implements the hypotenuse of a right-angled triangle. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float hypotf(float x, float y); + * double hypot(double x, double y); + * long double hypotl(long double x, long double y); + * + * Description + * =========== + * + * ``hypot`` computes the length of the hypotenuse of a right-angled triangle + * where the legs have the lengths :math:`x` and :math:`y`. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * hypot(x, y) \approx \sqrt{x^2 + y^2} + * + * Returns + * ======= + * + * ``hypot`` returns the length of the hypotenuse of a right-angled triangle. + * + * Exceptions + * ========== + * + * Raise ``overflow`` exception when the magnitude of the input values is too + * large. + * + * .. May raise ``underflow`` exception. + * + * Output map + * ========== + * + * +--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+ + * | hypot(x,y) | x | + * +--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+ + * | y | :math:`-Inf` | :math:`\in \mathbb{F}` | :math:`+Inf` | :math:`NaN` | + * +==========================+==========================+==========================+==========================+==========================+ + * | :math:`-Inf` | :math:`+Inf` | :math:`+Inf` | :math:`+Inf` | :math:`+Inf` | + * +--------------------------+ +--------------------------+ +--------------------------+ + * | :math:`\in \mathbb{F}` | | :math:`\sqrt{x^2 + y^2}` | | :math:`qNaN` | + * +--------------------------+ +--------------------------+ +--------------------------+ + * | :math:`+Inf` | | :math:`+Inf` | | :math:`+Inf` | + * +--------------------------+ +--------------------------+ +--------------------------+ + * | :math:`NaN` | | :math:`qNaN` | | :math:`qNaN` | + * +--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+ + * + */ + +#include +#include "../common/tools.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +double hypot(double x, double y) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_one; + y *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + double a = x; + double b = y; + double t1, t2; + double _y1, _y2; + double 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; + } + + SET_HIGH_WORD(a, ha); /* a <- |a| */ + SET_HIGH_WORD(b, hb); /* b <- |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 */ + uint32_t low; + w = a + b; /* for sNaN */ + 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 */ + uint32_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) { + t1 = 0.0; + SET_HIGH_WORD(t1, (0x3FF + k) << 20); + return t1 * w; + } else { + return w; + } +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double hypotl(long double x, long double y) +{ + return (long double) hypot((double) x, (double) y); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/ilogbd.c b/libm/libmcs/libm/mathd/ilogbd.c new file mode 100644 index 00000000..e19bd7f9 --- /dev/null +++ b/libm/libmcs/libm/mathd/ilogbd.c @@ -0,0 +1,127 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +/** + * + * This family of functions computes the binary exponent of the input value as + * a signed integer. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * int ilogbf(float x); + * int ilogb(double x); + * int ilogbl(long double x); + * + * Description + * =========== + * + * ``ilogb`` computes the binary exponent of the input value as a signed integer. + * + * ``ilogb`` and :ref:`logb` have the same functionality, but ``ilogb`` returns + * the binary exponent as a signed integer while :ref:`logb` returns a + * floating-point value. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * ilogb(x) \approx \lfloor {\log_2 |x|} \rfloor + * + * Returns + * ======= + * + * ``ilogb`` returns the binary exponent of the input value, in the range + * :math:`\mathbb{I}`. + * + * Exceptions + * ========== + * + * Raise ``invalid operation`` exception when the correct result is not + * representable as an integer. This is the case when the input value is zero, + * infinite or :math:`NaN`, or the magnitude of the result is too large to be + * represented as an integer. + * + * Output map + * ========== + * + * +---------------------+------------------------+----------------------------------------------------------------------------------------------------------+------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------+--------------+--------------+ + * | **x** | :math:`-Inf` | :math:`<0 \wedge \lfloor {\log_2 |x|} \rfloor \notin \mathbb{I} \wedge \lfloor {\log_2 |x|} \rfloor > 0` | :math:`<0 \wedge \lfloor {\log_2 |x|} \rfloor \in \mathbb{I}` | :math:`<0 \wedge \lfloor {\log_2 |x|} \rfloor \notin \mathbb{I} \wedge \lfloor {\log_2 |x|} \rfloor < 0` | :math:`-0` | :math:`+0` | + * +=====================+========================+==========================================================================================================+==================================================================+==========================================================================================================+==============+==============+ + * | **ilogb(x)** | max :math:`\mathbb{I}` | max :math:`\mathbb{I}` | :math:`\lfloor {\log_2 |x|} \rfloor` | min :math:`\mathbb{I}` | min :math:`\mathbb{I}` | + * +---------------------+------------------------+----------------------------------------------------------------------------------------------------------+------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------+--------------+--------------+ + * + * +---------------------+----------------------------------------------------------------------------------------------------------+------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------+--------------+--------------+ + * | **x** | :math:`>0 \wedge \lfloor {\log_2 |x|} \rfloor \notin \mathbb{I} \wedge \lfloor {\log_2 |x|} \rfloor < 0` | :math:`<0 \wedge \lfloor {\log_2 |x|} \rfloor \in \mathbb{I}` | :math:`>0 \wedge \lfloor {\log_2 |x|} \rfloor \notin \mathbb{I} \wedge \lfloor {\log_2 |x|} \rfloor > 0` | :math:`+Inf` | :math:`NaN` | + * +=====================+==========================================================================================================+==================================================================+==========================================================================================================+==============+==============+ + * | **ilogb(x)** | min :math:`\mathbb{I}` | :math:`\lfloor {\log_2 |x|} \rfloor` | max :math:`\mathbb{I}` | max :math:`\mathbb{I}` | + * +---------------------+----------------------------------------------------------------------------------------------------------+------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------+--------------+--------------+ + * + * .. raw:: html + * + * + * + */ + +#include +#include "../common/tools.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +int ilogb(double x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + int32_t hx, lx, ix; + + EXTRACT_WORDS(hx, lx, x); + hx &= 0x7fffffff; + + if (hx < 0x00100000) { + if ((hx | lx) == 0) { + (void) __raise_invalid(); + return FP_ILOGB0; /* ilogb(0) = special case error */ + } 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) { + (void) __raise_invalid(); + return FP_ILOGBNAN; /* NAN */ + } else { + (void) __raise_invalid(); + return INT_MAX; /* infinite */ + } +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +int ilogbl(long double x) +{ + return ilogb((double) x); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/internal/besseld.h b/libm/libmcs/libm/mathd/internal/besseld.h new file mode 100644 index 00000000..4e74b771 --- /dev/null +++ b/libm/libmcs/libm/mathd/internal/besseld.h @@ -0,0 +1,444 @@ +/* SPDX-License-Identifier: GTDGmbH */ +/* Copyright 2020-2025 by GTD GmbH. */ + +#ifndef LIBMCS_BESSELD_H +#define LIBMCS_BESSELD_H + +#include +#include "../../common/tools.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +static const double one = 1.0, zero = 0.0, two = 2.0; + +static const double +invsqrtpi = 5.64189583547756279280e-01, /* 0x3FE20DD7, 0x50429B6D */ +tpi = 6.36619772367581382433e-01; /* 0x3FE45F30, 0x6DC9C883 */ + +/* The asymptotic expansions of __j0_p is + * 1 - 9/128 s^2 + 11025/98304 s^4 - ..., where s = 1/x. + * For x >= 2, We approximate __j0_p by + * __j0_p(x) = 1 + (R/S) + * where R = __j0_pr0 + __j0_pr1*s^2 + __j0_pr2*s^4 + ... + __j0_pr5*s^10 + * S = 1 + __j0_ps0*s^2 + ... + __j0_ps4*s^10 + * and + * | __j0_p(x)-1-R/S | <= 2 ** ( -60.26) + */ +static const double __j0_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 __j0_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 __j0_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 __j0_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 __j0_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 __j0_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 __j0_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 __j0_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 */ +}; + +static inline double __j0_p(double x) +{ + const double *p, *q; + double z, r, s; + int32_t ix; + GET_HIGH_WORD(ix, x); + ix &= 0x7fffffff; + + if (ix >= 0x41b00000) { + return one; + } else if (ix >= 0x40200000) { + p = __j0_pr8; + q = __j0_ps8; + } else if (ix >= 0x40122E8B) { + p = __j0_pr5; + q = __j0_ps5; + } else if (ix >= 0x4006DB6D) { + p = __j0_pr3; + q = __j0_ps3; + } else { + p = __j0_pr2; + q = __j0_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 __j0_q is + * -1/8 s + 75/1024 s^3 - ..., where s = 1/x. + * We approximate __j0_q by + * __j0_q(x) = s*(-1.25 + (R/S)) + * where R = __j0_qr0 + __j0_qr1*s^2 + __j0_qr2*s^4 + ... + __j0_qr5*s^10 + * S = 1 + __j0_qs0*s^2 + ... + __j0_qs5*s^12 + * and + * | __j0_q(x)/s +1.25-R/S | <= 2 ** ( -61.22) + */ +static const double __j0_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 __j0_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 __j0_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 __j0_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 __j0_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 __j0_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 __j0_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 __j0_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 */ +}; + +static inline double __j0_q(double x) +{ + const double *p, *q; + double s, r, z; + int32_t ix; + GET_HIGH_WORD(ix, x); + ix &= 0x7fffffff; + + if (ix >= 0x41b00000) { + return -.125 / x; + } else if (ix >= 0x40200000) { + p = __j0_qr8; + q = __j0_qs8; + } else if (ix >= 0x40122E8B) { + p = __j0_qr5; + q = __j0_qs5; + } else if (ix >= 0x4006DB6D) { + p = __j0_qr3; + q = __j0_qs3; + } else { + p = __j0_qr2; + q = __j0_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; +} + +/* For x >= 8, the asymptotic expansions of __j1_p is + * 1 + 15/128 s^2 - 4725/2^15 s^4 - ..., where s = 1/x. + * We approximate __j1_p by + * __j1_p(x) = 1 + (R/S) + * where R = __j1_pr0 + __j1_pr1*s^2 + __j1_pr2*s^4 + ... + __j1_pr5*s^10 + * S = 1 + __j1_ps0*s^2 + ... + __j1_ps4*s^10 + * and + * | __j1_p(x)-1-R/S | <= 2 ** ( -60.06) + */ + +static const double __j1_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 __j1_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 __j1_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 __j1_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 __j1_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 __j1_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 __j1_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 __j1_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 */ +}; + +static inline double __j1_p(double x) +{ + const double *p, *q; + double z, r, s; + int32_t ix; + GET_HIGH_WORD(ix, x); + ix &= 0x7fffffff; + + if (ix >= 0x41b00000) { + return one; + } else if (ix >= 0x40200000) { + p = __j1_pr8; + q = __j1_ps8; + } else if (ix >= 0x40122E8B) { + p = __j1_pr5; + q = __j1_ps5; + } else if (ix >= 0x4006DB6D) { + p = __j1_pr3; + q = __j1_ps3; + } else { + p = __j1_pr2; + q = __j1_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 __j1_q is + * 3/8 s - 105/1024 s^3 - ..., where s = 1/x. + * We approximate __j1_q by + * __j1_q(x) = s*(0.375 + (R/S)) + * where R = __j1_qr1*s^2 + __j1_qr2*s^4 + ... + __j1_qr5*s^10 + * S = 1 + __j1_qs1*s^2 + ... + __j1_qs6*s^12 + * and + * | __j1_q(x)/s -0.375-R/S | <= 2 ** ( -61.13) + */ + +static const double __j1_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 __j1_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 __j1_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 __j1_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 __j1_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 __j1_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 __j1_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 __j1_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 */ +}; + +static inline double __j1_q(double x) +{ + const double *p, *q; + double s, r, z; + int32_t ix; + GET_HIGH_WORD(ix, x); + ix &= 0x7fffffff; + + if (ix >= 0x41b00000) { + return .375 / x; + } else if (ix >= 0x40200000) { + p = __j1_qr8; + q = __j1_qs8; + } else if (ix >= 0x40122E8B) { + p = __j1_qr5; + q = __j1_qs5; + } else if (ix >= 0x4006DB6D) { + p = __j1_qr3; + q = __j1_qs3; + } else { + p = __j1_qr2; + q = __j1_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; +} + +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ + +#endif /* !LIBMCS_BESSELD_H */ diff --git a/libm/libmcs/libm/mathd/internal/errorfunctiond.h b/libm/libmcs/libm/mathd/internal/errorfunctiond.h new file mode 100644 index 00000000..a2180147 --- /dev/null +++ b/libm/libmcs/libm/mathd/internal/errorfunctiond.h @@ -0,0 +1,121 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +#ifndef LIBMCS_ERRORFUNCTIOND_H +#define LIBMCS_ERRORFUNCTIOND_H + +#include +#include "../../common/tools.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +static const double +one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */ +/* + * Coefficients for approximation to erf on [0,0.84375] + */ +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 */ + +static inline double __erf_y(double x) +{ + double s, z, r; + 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)))); + return r / s; +} + +static inline double __erf_P(double s) +{ + return pa0 + s * (pa1 + s * (pa2 + s * (pa3 + s * (pa4 + s * (pa5 + s * pa6))))); +} + +static inline double __erf_Q(double s) +{ + return one + s * (qa1 + s * (qa2 + s * (qa3 + s * (qa4 + s * (qa5 + s * qa6))))); +} + +static inline double __erf_Ra(double s) +{ + return ra0 + s * (ra1 + s * (ra2 + s * (ra3 + s * (ra4 + s * (ra5 + s * (ra6 + s * ra7)))))); +} + +static inline double __erf_Sa(double s) +{ + return one + s * (sa1 + s * (sa2 + s * (sa3 + s * (sa4 + s * (sa5 + s * (sa6 + s * (sa7 + s * sa8))))))); +} + +static inline double __erf_Rb(double s) +{ + return rb0 + s * (rb1 + s * (rb2 + s * (rb3 + s * (rb4 + s * (rb5 + s * rb6))))); +} + +static inline double __erf_Sb(double s) +{ + return one + s * (sb1 + s * (sb2 + s * (sb3 + s * (sb4 + s * (sb5 + s * (sb6 + s * sb7)))))); +} + +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ + +#endif /* !LIBMCS_ERRORFUNCTIOND_H */ diff --git a/libm/libmcs/libm/mathd/internal/fpclassifyd.c b/libm/libmcs/libm/mathd/internal/fpclassifyd.c new file mode 100644 index 00000000..0540368f --- /dev/null +++ b/libm/libmcs/libm/mathd/internal/fpclassifyd.c @@ -0,0 +1,77 @@ +/* SPDX-License-Identifier: RedHat */ +/* Copyright (C) 2002,2007 by Red Hat, Incorporated. All rights reserved. */ + +/** + * + * This macro is used to classify :math:`x`. It can be called with ``float``, + * ``double`` or ``long double`` input. This macro is implemented in + * ``math.h``. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * int fpclassify(x); + * + * Description + * =========== + * + * ``fpclassify`` returns different constants depending on whether the input is + * subnormal, normal, zero, infinite or :math:`NaN`. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * fpclassify(x) = \left\{\begin{array}{ll} FP\_ZERO, & x = \pm 0.0 \\ + * FP\_SUBNORMAL, & x \in \mathbb{S} \\ + * FP\_INFINITE, & x = \pm Inf \\ + * FP\_NAN, & x = NaN \\ + * FP\_NORMAL, & otherwise \end{array}\right. + * + * Returns + * ======= + * + * ``fpclassify`` returns constant values, see ``math.h`` for their specific values. + * + * Exceptions + * ========== + * + * Does not raise exceptions. + * + * Output map + * ========== + * + * +---------------------+-----------------+------------------------------+------------------------------+-------------+------------------------------+------------------------------+-----------------+-------------+ + * | **x** | :math:`-Inf` | :math:`<0 \notin \mathbb{S}` | :math:`<0 \in \mathbb{S}` | :math:`±0` | :math:`>0 \in \mathbb{S}` | :math:`>0 \notin \mathbb{S}` | :math:`+Inf` | :math:`NaN` | + * +=====================+=================+==============================+==============================+=============+==============================+==============================+=================+=============+ + * | **fpclassify(x)** | ``FP_INFINITE`` | ``FP_NORMAL`` | ``FP_SUBNORMAL`` | ``FP_ZERO`` | ``FP_SUBNORMAL`` | ``FP_NORMAL`` | ``FP_INFINITE`` | ``FP_NAN`` | + * +---------------------+-----------------+------------------------------+------------------------------+-------------+------------------------------+------------------------------+-----------------+-------------+ + * + */ + +#include +#include "../../common/tools.h" + +int __fpclassifyd(double x) +{ + uint32_t msw, lsw; + + EXTRACT_WORDS(msw, lsw, x); + msw &= 0x7fffffffU; + + if (msw == 0x00000000U && lsw == 0x00000000U) { + return FP_ZERO; + } else if (msw >= 0x00100000U && msw <= 0x7fefffffU) { + return FP_NORMAL; + } else if (msw <= 0x000fffffU) { /* zero is already handled above */ + return FP_SUBNORMAL; + } else if (msw == 0x7ff00000U && lsw == 0x00000000U) { + return FP_INFINITE; + } else { + return FP_NAN; + } +} diff --git a/libm/libmcs/libm/mathd/internal/gammad.c b/libm/libmcs/libm/mathd/internal/gammad.c new file mode 100644 index 00000000..7022e1ea --- /dev/null +++ b/libm/libmcs/libm/mathd/internal/gammad.c @@ -0,0 +1,428 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +/** + * + * This family of functions is a set of functions used by the gamma function + * procedures as internal functions. Only ``__lgamma`` is accessible via + * ``gammad.h`` (``gammaf.h``), but should not be accessed directly by a user. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float __sin_pif(float x) + * double __sin_pi(double x) + * float __lgammaf(float x, int *signgamp) + * double __lgamma(double x, int *signgamp) + * + * Description + * =========== + * + * ``__lgamma`` computes the natural logarithm of the gamma function of + * :math:`x` and places the sign of the gamma function in the out-pointer + * :math:`signgamp`. + * + * ``__sin_pi`` computes the sine of the input value after it was multiplied by + * :math:`\pi`. The procedure is only called in the range + * :math:`[-2^{52},-2^{-70}]`, calling it outside of this range may result in + * unexpected results. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * \_\_sin\_pi(x) &\approx sin(\pi \cdot x) \\ + * \_\_lgamma(x) &\approx \ln{|\Gamma(x)|} = \ln{\left|\int_{0}^{\infty}e^{-t}t^{x-1}dt\right|} \\ + * \_\_lgamma\_signgamp(x) &= \left\{\begin{array}{ll} +1, & +0 \leq \Gamma(x) \\ -1, & -0 \geq \Gamma(x) \end{array}\right. + * + * Returns + * ======= + * + * ``__lgamma`` returns the natural logarithm of the gamma function of + * :math:`x` and places the sign of the gamma function in the out-pointer + * :math:`signgamp`. + * + * ``__sin_pi`` returns the sine of :math:`\pi \cdot x`. + * + * Exceptions + * ========== + * + * Do not raise useful exceptions. + * + * .. May raise ``underflow`` exception. + * + * Output map + * ========== + * + * The output maps are in the respective external functions :ref:`lgamma` and + * :ref:`tgamma`. + * + */ + +/* __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 + * minimum 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(inf) = inf + * lgamma(-integer) = +-inf + * + */ + +#include +#include "../../common/tools.h" +#include "gammad.h" +#include "trigd.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +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; + int32_t n, ix; + + GET_HIGH_WORD(ix, x); + ix &= 0x7fffffff; + + if (ix < 0x3fd00000) { + return __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 = (int32_t)(y * 4.0); + } else { + z = y + two52; /* exact */ + + GET_LOW_WORD(n, z); + n &= 1; + y = n; + n <<= 2; + } + + switch (n) { + case 0: + y = __sin(pi * y, zero, 0); + break; + + case 1: /* FALLTHRU */ + case 2: + y = __cos(pi * (0.5 - y), zero); + break; + + case 3: /* FALLTHRU */ + case 4: + y = __sin(pi * (one - y), zero, 0); + break; + + case 5: /* FALLTHRU */ + case 6: + y = -__cos(pi * (y - 1.5), zero); + break; + + default: + y = __sin(pi * (y - 2.0), zero, 0); + break; + } + + return -y; +} + +double __lgamma(double x, int *signgamp) +{ + double t, y, z, nadj = 0.0, p, p1, p2, p3, q, r, w; + int32_t i, hx, lx, ix; + + EXTRACT_WORDS(hx, lx, x); + + /* purge off +-inf, NaN, +-0, and negative arguments */ + *signgamp = 1; + ix = hx & 0x7fffffff; + + if (ix >= 0x7ff00000) { + return x * x; + } + + if ((ix | lx) == 0) { + if(hx < 0) { + *signgamp = -1; + } + return __raise_div_by_zero(zero); + } + + if (ix < 0x3b900000) { /* |x|<2**-70, return -log(|x|) */ + if (hx < 0) { + *signgamp = -1; + return -log(-x); + } else { + return -log(x); + } + } + + if (hx < 0) { + if (ix >= 0x43300000) { /* |x|>=2**52, must be -integer */ + return __raise_div_by_zero(zero); + } + + t = __sin_pi(x); + + if (t == zero) { /* -integer */ + return __raise_div_by_zero(zero); + } + + nadj = log(pi / fabs(t * x)); + + if (t < zero) { + *signgamp = -1; + } + + x = -x; + } + + /* purge off 1 and 2 */ + if ((((ix - 0x3ff00000) | lx) == 0) || (((ix - 0x40000000) | lx) == 0)) { + r = 0; + } + /* for x < 2.0 */ + else if (ix < 0x40000000) { + if (ix <= 0x3feccccc) { /* lgamma(x) = lgamma(x+1)-log(x) */ + r = -log(x); + + if (ix >= 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; /* [1.7316,2] */ + i = 0; + } else if (ix >= 0x3FF3B4C4) { + y = x - tc; /* [1.23,1.73] */ + i = 1; + } else { + y = x - one; + i = 2; + } + } + + switch (i) { + default: /* FALLTHRU */ + 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); + break; + } + } else if (ix < 0x40200000) { /* x < 8.0 */ + i = (int32_t)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 */ + + default: + r += log(z); + break; + } + + } else if (ix < 0x43900000) { /* 8.0 <= x < 2**58 */ + t = 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 * (log(x) - one); + } + + if (hx < 0) { + r = nadj - r; + } + + return r; +} + +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/internal/gammad.h b/libm/libmcs/libm/mathd/internal/gammad.h new file mode 100644 index 00000000..dbaa229c --- /dev/null +++ b/libm/libmcs/libm/mathd/internal/gammad.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GTDGmbH */ +/* Copyright 2020-2025 by GTD GmbH. */ + +#ifndef LIBMCS_GAMMAD_H +#define LIBMCS_GAMMAD_H + +extern double __lgamma(double x, int *signgamp); + +#endif /* !LIBMCS_GAMMAD_H */ diff --git a/libm/libmcs/libm/mathd/internal/log1pmfd.h b/libm/libmcs/libm/mathd/internal/log1pmfd.h new file mode 100644 index 00000000..89d14d3b --- /dev/null +++ b/libm/libmcs/libm/mathd/internal/log1pmfd.h @@ -0,0 +1,43 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +/* + * __log1pmf(f): + * Return log(1+f) - f for 1+f in ~[sqrt(2)/2, sqrt(2)]. + */ + +#ifndef LIBMCS_LOG1PMFD_H +#define LIBMCS_LOG1PMFD_H + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +static const double +Lg1 = 6.666666666666735130e-01, /* 0x3FE5555555555593 */ +Lg2 = 3.999999999940941908e-01, /* 0x3FD999999997FA04 */ +Lg3 = 2.857142874366239149e-01, /* 0x3FD2492494229359 */ +Lg4 = 2.222219843214978396e-01, /* 0x3FCC71C51D8E78AF */ +Lg5 = 1.818357216161805012e-01, /* 0x3FC7466496CB03DE */ +Lg6 = 1.531383769920937332e-01, /* 0x3FC39A09D078C69F */ +Lg7 = 1.479819860511658591e-01; /* 0x3FC2F112DF3E5244 */ + +/* + * We always inline __log1pmf(), since doing so produces a substantial + * performance improvement (~40% on amd64). + */ +static inline double __log1pmf(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); +} + +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ + +#endif /* !LIBMCS_LOG1PMFD_H */ diff --git a/libm/libmcs/libm/mathd/internal/signbitd.c b/libm/libmcs/libm/mathd/internal/signbitd.c new file mode 100644 index 00000000..b8e5cb03 --- /dev/null +++ b/libm/libmcs/libm/mathd/internal/signbitd.c @@ -0,0 +1,63 @@ +/* SPDX-License-Identifier: RedHat */ +/* Copyright (C) 2002 by Red Hat, Incorporated. All rights reserved. */ + +/** + * + * This macro returns a non-zero value if the sign bit of :math:`x` is set. It + * can be called with ``float``, ``double`` or ``long double`` input. This + * macro is implemented in ``math.h``. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * int signbit(x); + * + * Description + * =========== + * + * ``signbit`` returns a non-zero value if the sign bit of :math:`x` is set. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * signbit(x) = \left\{\begin{array}{ll} 1, & x \in \mathbb{F}^{-} \\ + * 0, & otherwise \end{array}\right. + * + * Returns + * ======= + * + * ``signbit`` returns :math:`1` if the sign bit of :math:`x` is set, otherwise + * :math:`0`. + * + * Exceptions + * ========== + * + * Does not raise exceptions. + * + * Output map + * ========== + * + * +---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ + * | **x** | :math:`-NaN` | :math:`-Inf` | :math:`<0` | :math:`-0` | :math:`+0` | :math:`>0` | :math:`+Inf` | :math:`+NaN` | + * +=====================+==============+==============+==============+==============+==============+==============+==============+==============+ + * | **signbit(x)** | :math:`1` | :math:`0` | + * +---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ + * + */ + +#include +#include "../../common/tools.h" + +int __signbitd(double x) +{ + uint32_t msw; + + GET_HIGH_WORD(msw, x); + + return (msw & 0x80000000U) != 0; +} diff --git a/libm/libmcs/libm/mathd/internal/trigd.c b/libm/libmcs/libm/mathd/internal/trigd.c new file mode 100644 index 00000000..62dcc951 --- /dev/null +++ b/libm/libmcs/libm/mathd/internal/trigd.c @@ -0,0 +1,627 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +/** + * + * This family of functions is a set of functions used by multiple + * trigonometric procedures as internal functions. Except for the internal + * range reduction the other functions are accessible via ``trigd.h`` + * (``trigf.h``), but should not be accessed directly by a user. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * float __cosf(float x, float y) + * double __cos(double x, double y) + * float __sinf(float x, float y, int iy) + * double __sin(double x, double y, int iy) + * int32_t __rem_pio2f(float x, float *y) + * int32_t __rem_pio2(double x, double *y) + * int __rem_pio2_internalf(float *x, float *y, int e0, int nx) + * int __rem_pio2_internal(double *x, double *y, int e0, int nx) + * + * Description + * =========== + * + * ``__cos`` computes the cosine of the input value. The sum of both input + * parameters :math:`x` and :math:`y` is bounded to [:math:`-\frac{\pi}{4}`, + * :math:`\frac{\pi}{4}`]. The first parameter :math:`x` is the requested value + * in raw precision while the second parameter :math:`y` contains a tail for + * higher precision. + * + * ``__sin`` computes the sine of the input value. The sum of both input + * parameters :math:`x` and :math:`y` is bounded to [:math:`-\frac{\pi}{4}`, + * :math:`\frac{\pi}{4}`]. The first parameter :math:`x` is the requested value + * in raw precision while the second parameter :math:`y` contains a tail for + * higher precision. The third parameter :math:`iy` signals if the parameter + * :math:`y` is :math:`0`. + * + * ``__rem_pio2`` returns the quadrant the input angle lies in, and place the + * remainder of :math:`x` divided by :math:`\frac{\pi}{4}` in the output array + * :math:`*y` (which consists of two values, the remainder and its tail, + * hereafter called :math:`y_0` and :math:`y_1`). The return value can be + * converted to the angle quadrant by taking just its last two bits. If the + * last two bits are :math:`00`, the input value is represented in + * [:math:`-45^{\circ}`, :math:`45^{\circ}`], if they are :math:`01`, it is in + * [:math:`45^{\circ}`, :math:`135^{\circ}`], if they are :math:`10`, it is in + * [:math:`135^{\circ}`, :math:`225^{\circ}`], and if they are :math:`11`, it + * is in [:math:`225^{\circ}`, :math:`315^{\circ}`]. The last two bits of the + * return value are the only relevant part. In some cases the return value also + * equals the number of reductions (by :math:`\frac{\pi}{2}`) necessary to + * reduce the value - this is not always the case, as the return value would + * often overflow due to the limited size of ``int32_t``. + * + * ``__rem_pio2_internal`` returns the quadrant the input angle lies in (see + * ``__rem_pio2`` on how to convert the return value into the quadrant), and + * place the remainder of :math:`x` (scaled :math:`x` which consists of up to + * three values, hereafter called :math:`x_0`, :math:`x_1` and :math:`x_2`, + * original :math:`x = x_0 \cdot 2^{e0} + x_1 \cdot 2^{e0-24} + x_2 \cdot + * 2^{e0-48}`) divided by :math:`\frac{\pi}{4}` in the output array (which + * consists of two values, the remainder and its tail, :math:`y_0` and + * :math:`y_1`). The variable :math:`nx` needs to be provided with the size of + * the array for :math:`x`. + * + * Although ``__rem_pio2`` and ``__rem_pio2_internal`` seem to do the same, + * they work on different ranges. ``__rem_pio2`` first checks if the input is + * rather close to the target interval, if it isn't it calls + * ``__rem_pio2_internal``. + * + * *Note:* The variables ``prec`` and ``*ipio2`` are to be removed during the + * rework and are therefore not part of the description. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * \_\_cos(x) &\approx cos(x) \\ + * \_\_sin(x) &\approx sin(x) \\ + * \_\_rem\_pio2_y(x) &\approx x - n \cdot \frac{\pi}{2} \wedge n \in \mathbb{Z} \wedge \_\_rem\_pio2_y(x) \in \left[-\frac{\pi}{4},\frac{\pi}{4}\right] \\ + * \_\_rem\_pio2(x) &= n + * + * Returns + * ======= + * + * ``__cos`` returns the cosine of :math:`x + y`. + * + * ``__sin`` returns the sine of :math:`x + y`. + * + * ``__rem_pio2`` returns the quadrant the input angle lies in, and place the + * remainder of :math:`x` divided by :math:`\frac{\pi}{4}` in the output array + * :math:`*y`. See description above. + * + * ``__rem_pio2_internal`` returns the quadrant the input angle lies in, and + * place the remainder of :math:`x` divided by :math:`\frac{\pi}{4}` in the + * output array :math:`*y`. See description above. + * + * Exceptions + * ========== + * + * Do not raise useful exceptions. + * + * .. May raise ``underflow`` exception. + * + * Output map + * ========== + * + * The output maps are in the respective external functions :ref:`cos` and :ref:`sin`. + * + */ + +#include +#include "../../common/tools.h" +#include "trigd.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +/* + * 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. + */ + +/* + * Double precision array, obtained by cutting pi/2 + * into 24 bits chunks. + */ +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 */ +}; + +/* + * Table of constants for 2/pi, 396 Hex digits (476 decimal) of 2/pi + * + * The 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)). + */ +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, +}; + +static const double zero = 0.0; +static const double one = 1.0; +static const double two24 = 0x1p+24; /* 1.6777216000000000000e+07 0x41700000, 0x00000000 */ +static const double twon24 = 0x1p-24; /* 5.9604644775390625000e-08 0x3E700000, 0x00000000 */ + +static inline int __rem_pio2_internal(double *x, double *y, int e0, int nx) +{ + int32_t jk = 4; /* precision setting: + 2 for up to 32 bits single precision + 3 for up to 64 bits double precision + 4 for up to 80 bits extended precision + 6 for up to 128 bit quad precision + + jk+1 is the initial number of terms of ipio2[] needed in the computation. */ + int32_t jp = jk; /* stores the initial value of jk until the final result computation */ + + int32_t k; /* number of additional ipio2 terms needed for recomputation */ + int32_t i, j, m; /* general purpose indices and variables */ + int32_t jz, jx, jv; /* other specific indices */ + int32_t carry; /* indicates whether there is a contribution of q when computing the complementary angle */ + int32_t ih; /* variable that indicates the position of the angle within the resulting quadrant. + If ih is positive then q[] is >= 0.5, hence it acts as the "signbit" of the result, + which will be positive for negative angles within the quadrant. */ + + + double q[20] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, /* value of q = x/(pi/2) = x*(2/pi) */ + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; + int32_t q0; /* the corresponding exponent of q[0]. Note that the exponent for q[i] would be q0-24*i */ + + int32_t n; /* indicates the octant where the angle falls into; it is used to get the quadrant */ + double z; /* high order fractional part of q, down to the q0 bit */ + int32_t iq[20] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* lower order 24 bit chunks of fractional part of q in inverted order. */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; /* iq starts after the q0 bits which are in z */ + + /* For an example angle of x = 900000.0 we would have that q = x/(pi/2) = x*(2/pi) = 572957.79513082320876798154814105170332405472466564321549160243861 + q = 1.00010111110000111011100101110001101101100011001000110111001001001001011001101001100000110011101110000100110100110000100001011101111001001000000000 + The q[] array will represent q = 153802180800000*2^−28 + 104097542400000*2^−52 + 19972857600000*2^-76 + 37128744000000*2^-100 + 231405883200000*2^-124 + where q0 = -28. + This value of q will be split in (after removing the integer part 572957 and storing 572957 mod 8 = 5 in n): + n = 5 (101) -> quadrant 1 + z = 0.7951308228075504 (0.1100101110001101101100011001) + q = 1100101110001101101100011001 000110111001001001001011 001101101101110010110110 011010110101000001100001 011101111001001000000000 + z iq[3] iq[2] iq[1] iq[0] + (Note that z contains 28 bits, because of q0 = -28) + To obtain the end result, the complementary to 1 of z and iq are computed, as the result will be a negative angle within the quadrant 2. + x = 900000.0 radians is equivalent to 2.81978... radians which will result in an angle of -0.321807... radians in quadrant 2 [3*pi/4, 5*pi/4]. + */ + + double fw; /* temporary variable to compute q, iq, and fq */ + double f[20] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, /* ipio2[] terms taken fro computation in floating point */ + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; + double fq[20] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, /* final product of q*pi/2 in fq[0],..,fq[jk]; */ + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; /* computing the fractional value [0,1] within the quadrant back into radians */ + + + + bool recompute; /* variable used to signalize that a recomputation is needed as the current selection of ipio2[] terms has led to loss of significance. + The recomputation will take more terms of ipio2[]. */ + bool exhausted; /* variable used to signalize that the available ipio2 precision has been exhausted making no further recomputing possible */ + + jp = jk; + + /* determine jx,jv,q0, note that 3>q0 */ + jx = nx - 1; + jv = (e0 - 3) / 24; + + 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; + + do { + recompute = false; + exhausted = false; + + /* distill the lower part of q[] into iq[] reversingly and leave the higher part in z */ + 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, (int32_t)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; + } else { + /* No action required */ + } + + /* for the cases that the angle is in the upper side of the quadrant, the complementary is computed */ + if (ih > 0) { /* q > 0.5 */ + n += 1; + carry = 0; + + for (i = 0; i < jz ; i++) { /* compute 1-q by computing the complementary of iq */ + j = iq[i]; + + if (carry == 0) { + if (j != 0) { + carry = 1; + iq[i] = 0x1000000 - j; + } + } else { + iq[i] = 0xffffff - j; + } + } + + if (q0 > 0) { /* rare case: chance is 1 in 12 */ + switch (q0) { + default: /* FALLTHRU */ + case 1: + iq[jz - 1] &= 0x7fffff; + break; + + case 2: + iq[jz - 1] &= 0x3fffff; + break; + } + } + + if (ih == 2) { /* compute the complementary of z */ + z = one - z; + + /* in case that iq[] does have a contribution, subtract the order of magnitude + of this contribution from the complement of z so that z + iq can be computed. */ + if (carry != 0) { + z -= scalbn(one, (int32_t)q0); + /* Given the following decimal example of: z = 0.7 and iq = 0.01 for the angle z + iq = 0.71 + the complements would be z = 1 - z = 0.3 and iq = 0.1 - iq = 0.09 + now, z needs to be decremented by 0.1; z = z - 0.1 so that z + iq = 0.2 + 0.09 = 0.29 + which is the correct complement of the original angle 0.71 */ + } + } + } + + /* check if recomputation is needed in case of loss of significance in z and iq[] */ + if (z == zero) { + j = 0; + + for (i = jz - 1; i >= jk; i--) { + j |= iq[i]; + } + + if (j == 0) { /* need recomputation */ + for (k = 1; (jk - k >= 0) && (iq[jk - k] == 0); k++) { /* k = no. of terms needed */ + } + + /* add q[jz+1] to q[jz+k] + don't pull more terms of ipio2[] than available + and don't overflow f[] */ + for (i = jz + 1; i <= jz + k; i++) { + if ((jv + i < 66) && + (jx + i < 20)) { + f[jx + i] = (double) ipio2[jv + i]; + } else { + exhausted = true; + } + + for (j = 0, fw = 0.0; j <= jx; j++) { + fw += x[j] * f[jx + i - j]; + } + + q[i] = fw; + } + + jz += k; + recompute = true; + } + } + /* The original authors of the algorithm Payne and Hanek estimate the + amount of needed recomputing to be low. Currently only 2 recomputes + are observed at most */ + } while (recompute && !exhausted); + + /* chop off zero terms */ + if (z == 0.0) { + q0 -= 24; + + for (jz -= 1; jz>=0; --jz) { + if (iq[jz]!=0) { + break; + } + q0 -= 24; + } + } else { /* break z into 24-bit if necessary */ + z = scalbn(z, -(int32_t)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, (int32_t)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[] */ + fw = 0.0; + + for (i = jz; i >= 0; i--) { + fw += fq[i]; + } + + 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; + + return n & 7; +} + +/* __rem_pio2(x,y) + * + * return the remainder of x rem pi/2 in y[0]+y[1] + * use __rem_pio2_internal() + */ + +/* + * 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 +half = 5.00000000000000000000e-01, /* 0x3FE00000, 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 */ + +int32_t __rem_pio2(double x, double *y) +{ + double z = 0.0, w, t, r, fn; + double tx[3]; + int32_t i, j, n, ix, hx; + int32_t e0, nx; + uint32_t low; + + GET_HIGH_WORD(hx, x); /* high word of x */ + ix = hx & 0x7fffffff; + + if (ix <= 0x3fe921fb) { /* |x| ~<= pi/4 , no need for reduction */ + y[0] = x; + y[1] = 0; + return 0; + } + + if (ix < 0x4002d97c) { /* |x| < 3pi/4, special case with n=+-1 */ + if (hx > 0) { + z = x - pio2_1; + + if (ix != 0x3ff921fb) { /* 33+53 bit pi is good enough */ + y[0] = z - pio2_1t; + y[1] = (z - y[0]) - pio2_1t; + } else { /* near pi/2, use 33+33+53 bit pi */ + z -= pio2_2; + y[0] = z - pio2_2t; + y[1] = (z - y[0]) - pio2_2t; + } + + return 1; + } else { /* negative x */ + z = x + pio2_1; + + if (ix != 0x3ff921fb) { /* 33+53 bit pi is good enough */ + y[0] = z + pio2_1t; + y[1] = (z - y[0]) + pio2_1t; + } else { /* near pi/2, use 33+33+53 bit pi */ + z += pio2_2; + y[0] = z + pio2_2t; + y[1] = (z - y[0]) + pio2_2t; + } + + return -1; + } + } + + if (ix <= 0x413921fb) { /* |x| ~<= 2^19*(pi/2), medium size */ + t = fabs(x); + n = (int32_t)(t * invpio2 + half); + fn = (double)n; + r = t - fn * pio2_1; + w = fn * pio2_1t; /* 1st round good to 85 bit */ + + { + uint32_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; + + if (hx < 0) { + y[0] = -y[0]; + y[1] = -y[1]; + return -n; + } else { + return n; + } + } + + /* + * all other (large) arguments + */ + if (ix >= 0x7ff00000) { /* x is inf or NaN */ + if (isnan(x)) { + y[1] = x - x; + y[0] = y[1]; + } else { + y[1] = __raise_invalid(); + y[0] = y[1]; + } + return 0; + } + + /* set z = scalbn(|x|,ilogb(x)-23) */ + GET_LOW_WORD(low, x); + SET_LOW_WORD(z, low); + e0 = (int32_t)((ix >> 20) - 1046); /* e0 = ilogb(z)-23; */ + SET_HIGH_WORD(z, ix - ((int32_t)e0 << 20)); + + for (i = 0; i < 2; i++) { + tx[i] = (double)((int32_t)(z)); + z = (z - tx[i]) * two24; + } + + tx[2] = z; + + for (nx = 3; nx>1; --nx) { /* skip zero term */ + if (tx[nx-1]!=zero) { + break; + } + } + + n = __rem_pio2_internal(tx, y, e0, nx); + + if (hx < 0) { + y[0] = -y[0]; + y[1] = -y[1]; + return -n; + } + + return n; +} + +static const double +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 */ + +double __cos(double x, double y) +{ + double hz, z, r, w; + + z = x * x; + r = z * (C1 + z * (C2 + z * (C3 + z * (C4 + z * (C5 + z * C6))))); + hz = 0.5 * z; + w = one - hz; + return w + (((one - w) - hz) + (z * r - x * y)); +} + +static const double +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 */ + +double __sin(double x, double y, int iy) +{ + double z, r, v; + + z = x * x; + v = z * x; + r = S2 + z * (S3 + z * (S4 + z * (S5 + z * S6))); + + if (iy == 0) { + return x + v * (S1 + z * r); + } else { + return x - ((z * (half * y - v * r) - y) - v * S1); + } +} + +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/internal/trigd.h b/libm/libmcs/libm/mathd/internal/trigd.h new file mode 100644 index 00000000..1ff33be8 --- /dev/null +++ b/libm/libmcs/libm/mathd/internal/trigd.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GTDGmbH */ +/* Copyright 2020-2025 by GTD GmbH. */ + +#ifndef LIBMCS_TRIGD_H +#define LIBMCS_TRIGD_H + +#include "../../common/tools.h" + +extern double __sin(double x, double y, int iy); +extern double __cos(double x, double y); +extern int32_t __rem_pio2(double x, double *y); + +#endif /* !LIBMCS_TRIGD_H */ diff --git a/libm/libmcs/libm/mathd/j0d.c b/libm/libmcs/libm/mathd/j0d.c new file mode 100644 index 00000000..58d263f3 --- /dev/null +++ b/libm/libmcs/libm/mathd/j0d.c @@ -0,0 +1,148 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +/** + * + * This function implements the Bessel function of the first kind of + * order 0. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * double j0(double x); + * + * Description + * =========== + * + * ``j0`` computes the Bessel value of :math:`x` of the first kind of order 0. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * j0(x) = J_{0}(x) + * + * Notice that the mathematical function represented by the procedure ``j0`` is + * not :math:`j_0` (which is the spherical version of the Bessel function) but + * :math:`J_0`. See `WolframAlpha + * `_ for what it looks like + * and `Wikipedia `_ for more + * information. + * + * Returns + * ======= + * + * ``j0`` returns the Bessel value of :math:`x` of the first kind of order 0. + * + * Exceptions + * ========== + * + * Does not raise overflow, division by zero, and invalid exceptions. + * + * .. May raise ``underflow`` exception. + * + * Output map + * ========== + * + * +---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ + * | **x** | :math:`-Inf` | :math:`<0` | :math:`-0` | :math:`+0` | :math:`>0` | :math:`+Inf` | :math:`NaN` | + * +=====================+==============+==============+==============+==============+==============+==============+==============+ + * | **j0(x)** | :math:`+0` | :math:`J_{0}(x)` | :math:`+0` | :math:`qNaN` | + * +---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ + * + */ + +#include +#include "internal/besseld.h" +#include "../common/tools.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +static const double +/* 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 */ + +double j0(double x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + 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) < zero) { + cc = z / ss; + } else { + ss = z / cc; + } + } + + /* + * j0(x) = 1/sqrt(pi) * (P(0,x)*cc - Q(0,x)*ss) / sqrt(x) + * y0(x) = 1/sqrt(pi) * (P(0,x)*ss + Q(0,x)*cc) / sqrt(x) + */ + if (ix > 0x48000000) { + z = (invsqrtpi * cc) / sqrt(x); + } else { + u = __j0_p(x); + v = __j0_q(x); + z = invsqrtpi * (u * cc - v * ss) / sqrt(x); + } + + return z; + } + + if (ix < 0x3f200000) { /* |x| < 2**-13 */ + if (x != 0.0) { + (void)__raise_inexact(x); /* 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)); + } +} + +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/j1d.c b/libm/libmcs/libm/mathd/j1d.c new file mode 100644 index 00000000..321255a9 --- /dev/null +++ b/libm/libmcs/libm/mathd/j1d.c @@ -0,0 +1,144 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +/** + * + * This function implements the Bessel function of the first kind of + * order 1. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * double j1(double x); + * + * Description + * =========== + * + * ``j1`` computes the Bessel value of :math:`x` of the first kind of order 1. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * j1(x) = J_{1}(x) + * + * Notice that the mathematical function represented by the procedure ``j1`` is + * not :math:`j_1` (which is the spherical version of the Bessel function) but + * :math:`J_1`. See `WolframAlpha J1(x) + * `_ for what it looks like + * and `Wikipedia `_ for more + * information. + * + * Returns + * ======= + * + * ``j1`` returns the Bessel value of :math:`x` of the first kind of order 1. + * + * Exceptions + * ========== + * + * Does not raise overflow, division by zero, and invalid exceptions. + * + * .. May raise ``underflow`` exception. + * + * Output map + * ========== + * + * +---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ + * | **x** | :math:`-Inf` | :math:`<0` | :math:`-0` | :math:`+0` | :math:`>0` | :math:`+Inf` | :math:`NaN` | + * +=====================+==============+==============+==============+==============+==============+==============+==============+ + * | **j1(x)** | :math:`+0` | :math:`J_{1}(x)` | :math:`+0` | :math:`qNaN` | + * +---------------------+--------------+--------------+--------------+--------------+--------------+--------------+--------------+ + * + */ + +#include +#include "internal/besseld.h" +#include "../common/tools.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +static const double +/* 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 */ + +double j1(double x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + 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 = __j1_p(y); + v = __j1_q(y); + z = invsqrtpi * (u * cc - v * ss) / sqrt(y); + } + + if (hx < 0) { + return -z; + } else { + return z; + } + } + + if (ix < 0x3e400000) { /* |x|<2**-27 */ + if (x != 0.0) { + (void)__raise_inexact(x); /* raise inexact if x != 0 */ + } + return 0.5 * x; + } + + 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); +} + +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/jnd.c b/libm/libmcs/libm/mathd/jnd.c new file mode 100644 index 00000000..e9b681fa --- /dev/null +++ b/libm/libmcs/libm/mathd/jnd.c @@ -0,0 +1,292 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +/** + * + * This function implements the Bessel function of the first kind of + * order :math:`n`. + * + * .. warning:: + * The implementation contains a potentially unbounded while loop. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * double jn(int n, double x); + * + * Description + * =========== + * + * ``jn`` computes the Bessel value of :math:`x` of the first kind of order + * :math:`n`. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * jn(n, x) = J_{n}(x) + * + * Notice that the mathematical function represented by the procedure ``jn`` is + * not :math:`j_n` (which is the spherical version of the Bessel function) but + * :math:`J_n`. See `WolframAlpha Jn(x) + * `_ for what it looks like + * (it shows the different :math:`n` quite nicely in a 3D plot) and `Wikipedia + * `_ for more information. + * + * Returns + * ======= + * + * ``jn`` returns the Bessel value of :math:`x` of the first kind of order + * :math:`n`. + * + * Exceptions + * ========== + * + * Does not raise overflow, division by zero, and invalid exceptions. + * + * .. May raise ``underflow`` exception. + * + * Output map + * ========== + * + * +--------------------------+--------------------------+--------------------------+ + * | jn(n,x) | n | + * +--------------------------+--------------------------+--------------------------+ + * | x | :math:`<0` | :math:`>0` | + * +==========================+==========================+==========================+ + * | :math:`-Inf` | :math:`+0` | + * +--------------------------+--------------------------+--------------------------+ + * | :math:`<0` | :math:`J_{-n}(-x)` | :math:`J_{n}(x)` | + * +--------------------------+ + + + * | :math:`-0` | | | + * +--------------------------+ + + + * | :math:`+0` | | | + * +--------------------------+ + + + * | :math:`>0` | | | + * +--------------------------+--------------------------+--------------------------+ + * | :math:`+Inf` | :math:`+0` | + * +--------------------------+--------------------------+--------------------------+ + * | :math:`NaN` | :math:`qNaN` | + * +--------------------------+--------------------------+--------------------------+ + * + */ + +#include +#include "internal/besseld.h" +#include "../common/tools.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +double jn(int n, double x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + 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 | ((uint32_t)(lx | -lx)) >> 31) > 0x7ff00000) { + return x + x; + } + + if (n < 0) { + n = -n; + x = -x; + hx ^= 0x80000000U; + } + + if (n == 0) { + return (j0(x)); + } + + if (n == 1) { + return (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) { + default: /* FALLTHRU */ + 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 = j0(x); + b = j1(x); + + for (i = 1; i < n; i++) { + temp = b; + b = b * ((double)(i + i) / x) - a; /* avoid underflow */ + a = temp; + } + } + } else { + if (ix < 0x3e100000) { /* x < 2**-29 */ + /* x is tiny, return the first Taylor expansion of J(n,x) + * J(n,x) = 1/n!*(x/2)^n - ... + */ + if (n > 33) { /* 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 * 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; + } + } + } + + b = (t * j0(x) / b); + } + } + + if (sgn != 0) { + return -b; + } else { + return b; + } +} + +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/ldexpd.c b/libm/libmcs/libm/mathd/ldexpd.c new file mode 100644 index 00000000..046d68f7 --- /dev/null +++ b/libm/libmcs/libm/mathd/ldexpd.c @@ -0,0 +1,98 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +/** + * + * This family of functions multiplies the input value :math:`x` by an integral + * power of :math:`2`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float ldexpf(float x, int exp); + * double ldexp(double x, int exp); + * long double ldexpl(long double x, int exp); + * + * Description + * =========== + * + * ``ldexp`` multiplies the input value :math:`x` by an integral power of :math:`2`. + * + * ``ldexp`` and :ref:`scalbn` have the same functionality. In theory their + * definition could be different, but this only applies to architectures which + * do not use a binary system, which by now are assumed to be an obscurity. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * ldexp(x, exp) \approx x \cdot 2^{exp} + * + * Returns + * ======= + * + * ``ldexp`` returns the input value :math:`x` multiplied by :math:`2` powered + * by the input value :math:`exp`. + * + * Exceptions + * ========== + * + * Raise ``overflow`` exception if the result overflows. + * + * .. May raise ``underflow`` exception. + * + * Output map + * ========== + * + * +---------------------+-------------------------+-------------------------+-------------------------+ + * | ldexp(x,exp) | exp | + * +---------------------+-------------------------+-------------------------+-------------------------+ + * | x | :math:`<0` | :math:`0` | :math:`>0` | + * +=====================+=========================+=========================+=========================+ + * | :math:`-Inf` | :math:`x` | :math:`x` | :math:`x` | + * +---------------------+-------------------------+ +-------------------------+ + * | :math:`<0` | :math:`x \cdot 2^{exp}` | | :math:`x \cdot 2^{exp}` | + * +---------------------+-------------------------+ +-------------------------+ + * | :math:`-0` | :math:`x` | | :math:`x` | + * +---------------------+ + + + + * | :math:`+0` | | | | + * +---------------------+-------------------------+ +-------------------------+ + * | :math:`>0` | :math:`x \cdot 2^{exp}` | | :math:`x \cdot 2^{exp}` | + * +---------------------+-------------------------+ +-------------------------+ + * | :math:`+Inf` | :math:`x` | | :math:`x` | + * +---------------------+-------------------------+-------------------------+-------------------------+ + * | :math:`NaN` | :math:`qNaN` | + * +---------------------+-------------------------+-------------------------+-------------------------+ + * + */ + +#include + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +double ldexp(double x, int exp) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + if ((isfinite(x) == 0) || (x == 0.0)) { + return x + x; + } + + return scalbn(x, exp); +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double ldexpl(long double x, int exp) +{ + return (long double) ldexp((double) x, exp); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/lgammad.c b/libm/libmcs/libm/mathd/lgammad.c new file mode 100644 index 00000000..c5a63618 --- /dev/null +++ b/libm/libmcs/libm/mathd/lgammad.c @@ -0,0 +1,78 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +/** + * + * This family of functions implements the natural logarithm of the gamma + * function of :math:`x`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float lgammaf(float x); + * double lgamma(double x); + * long double lgammal(long double x); + * + * Description + * =========== + * + * ``lgamma`` computes the natural logarithm of the gamma function of :math:`x`. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * lgamma(x) \approx \ln{|\Gamma(x)|} = \ln{\left|\int_{0}^{\infty}e^{-t}t^{x-1}dt\right|} + * + * Returns + * ======= + * + * ``lgamma`` returns the natural logarithm of the gamma function of :math:`x`. + * + * Exceptions + * ========== + * + * Raise ``divide by zero`` exception when the input value is a negative + * integer or zero. + * + * Raise ``overflow`` exception when the magnitude of the input value is too + * large. + * + * Output map + * ========== + * + * +---------------------+--------------+---------------------------------------+-----------------------------+--------------+--------------+--------------------------+--------------+--------------------------+--------------+--------------------------+--------------+--------------+ + * | **x** | :math:`-Inf` | :math:`<0\ \wedge\ \notin \mathbb{Z}` | :math:`\in \mathbb{Z}_{<0}` | :math:`-0` | :math:`+0` | :math:`]0,1[` | :math:`+1` | :math:`]1,2[` | :math:`+2` | :math:`>2` | :math:`+Inf` | :math:`NaN` | + * +=====================+==============+=======================================+=============================+==============+==============+==========================+==============+==========================+==============+==========================+==============+==============+ + * | **lgamma(x)** | :math:`+Inf` | :math:`\ln{|\Gamma(x)|}` | :math:`+Inf` | :math:`+Inf` | :math:`\ln{|\Gamma(x)|}` | :math:`+0` | :math:`\ln{|\Gamma(x)|}` | :math:`+0` | :math:`\ln{|\Gamma(x)|}` | :math:`+Inf` | :math:`qNaN` | + * +---------------------+--------------+---------------------------------------+-----------------------------+--------------+--------------+--------------------------+--------------+--------------------------+--------------+--------------------------+--------------+--------------+ + * + */ + +#include +#include "internal/gammad.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +double lgamma(double x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + return __lgamma(x, &__signgam); +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double lgammal(long double x) +{ + return (long double) lgamma((double) x); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/llrintd.c b/libm/libmcs/libm/mathd/llrintd.c new file mode 100644 index 00000000..d756ecc1 --- /dev/null +++ b/libm/libmcs/libm/mathd/llrintd.c @@ -0,0 +1,155 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ +/* lrint adapted to be llrint for Newlib, 2009 by Craig Howland. */ + +/** + * + * This family of functions implements the nearest integer value to :math:`x`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * long long int llrintf(float x); + * long long int llrint(double x); + * long long int llrintl(long double x); + * + * Description + * =========== + * + * ``llrint`` computes the nearest integer value to :math:`x`. Functionally the + * same procedure as :ref:`lrint` but returns ``long long int`` instead of + * ``long int``. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * llrint(x) = \lfloor x \rceil + * + * Returns + * ======= + * + * ``llrint`` returns the nearest integer value to :math:`x`. + * + * Exceptions + * ========== + * + * Raise ``invalid operation`` exception when the correct result is not + * representable as the output type. This is the case when the input value is + * infinite or :math:`NaN`, or the magnitude of the result is too large to be + * represented. + * + * Output map + * ========== + * + * +---------------------+--------------------------+---------------------------------------+--------------------------+--------------+--------------+--------------------------+---------------------------------------+--------------------------+--------------------------+ + * | **x** | :math:`-Inf` | :math:`<` min :math:`\mathbb{I}_{ll}` | :math:`<0` | :math:`-0` | :math:`+0` | :math:`>0` | :math:`>` max :math:`\mathbb{I}_{ll}` | :math:`+Inf` | :math:`NaN` | + * +=====================+==========================+=======================================+==========================+==============+==============+==========================+=======================================+==========================+==========================+ + * | **llrint(x)** | min :math:`\mathbb{I}_{ll}` | :math:`\lfloor x \rceil` | :math:`x` | :math:`\lfloor x \rceil` | max :math:`\mathbb{I}_{ll}` | :math:`llrint(±Inf)` | + * +---------------------+--------------------------+---------------------------------------+--------------------------+--------------+--------------+--------------------------+---------------------------------------+--------------------------+--------------------------+ + * + */ + +#include +#include "../common/tools.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +/* Adding a double, x, to 2^52 will cause the result to be rounded based on + the fractional part of x, according to the implementation's current rounding + mode. 2^52 is the smallest double that can be represented using all 52 significant + digits. */ +static const double TWO52[2] = { + 4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */ + -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */ +}; + +long long int llrint(double x) +{ + int32_t _i0, _j0, sx; + uint32_t _i1; + double t; + volatile double w; + long long int result; + + EXTRACT_WORDS(_i0, _i1, x); + + /* Extract sign bit. */ + sx = (_i0 >> 31) & 1; + + /* Extract exponent field. */ + _j0 = ((_i0 & 0x7ff00000) >> 20) - 1023; + /* _j0 in [-1023,1024] */ + + if (_j0 < 20) { + /* _j0 in [-1023,19] */ + if (_j0 < -1) { + return 0; + } else { + /* _j0 in [0,19] */ + /* shift amt in [0,19] */ + w = TWO52[sx] + x; + t = w - TWO52[sx]; + GET_HIGH_WORD(_i0, t); + + /* Detect the all-zeros representation of plus and + minus zero, which fails the calculation below. */ + if ((_i0 & ~((int32_t)1 << 31)) == 0) { + return 0; + } + + /* After round: _j0 in [0,20] */ + _j0 = ((_i0 & 0x7ff00000) >> 20) - 1023; + _i0 &= 0x000fffff; + _i0 |= 0x00100000; + /* shift amt in [20,0] */ + result = _i0 >> (20 - _j0); + } + } else if ((uint32_t)_j0 < (8 * sizeof(long long int)) - 1) { + /* 64bit return: _j0 in [20,62] */ + if (_j0 >= 52) { + /* 64bit return: _j0 in [52,62] */ + /* 64bit return: left shift amt in [32,42] */ + result = ((long long int)((_i0 & 0x000fffff) | 0x00100000) << (_j0 - 20)) | + /* 64bit return: right shift amt in [0,10] */ + ((long long int) _i1 << (_j0 - 52)); + } else { + /* 64bit return: _j0 in [20,51] */ + w = TWO52[sx] + x; + t = w - TWO52[sx]; + EXTRACT_WORDS(_i0, _i1, t); + _j0 = ((_i0 & 0x7ff00000) >> 20) - 1023; + _i0 &= 0x000fffff; + _i0 |= 0x00100000; + /* After round: + * 64bit return: _j0 in [20,52] */ + /* 64bit return: left shift amt in [0,32] */ + /* ***64bit return: right shift amt in [32,0] */ + result = ((long long int) _i0 << (_j0 - 20)) | SAFE_RIGHT_SHIFT(_i1, (uint32_t)(52 - _j0)); + } + } else { + (void) __raise_invalid(); + if (sx != 0) { + return __MIN_LONG_LONG; + } + else { + return __MAX_LONG_LONG; + } + } + + return (sx != 0) ? -result : result; +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long long int llrintl(long double x) +{ + return llrint((double) x); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/llroundd.c b/libm/libmcs/libm/mathd/llroundd.c new file mode 100644 index 00000000..ec106a18 --- /dev/null +++ b/libm/libmcs/libm/mathd/llroundd.c @@ -0,0 +1,137 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ +/* lround adapted to be llround for Newlib, 2009 by Craig Howland. */ + +/** + * + * This family of functions implements the nearest integer value to :math:`x`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * long long int llroundf(float x); + * long long int llround(double x); + * long long int llroundl(long double x); + * + * Description + * =========== + * + * ``llround`` computes the nearest integer value to :math:`x`. Functionally + * the same procedure as :ref:`lround` but returns ``long long int`` instead of + * ``long int``. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * llround(x) = \lfloor x \rceil + * + * Returns + * ======= + * + * ``llround`` returns the nearest integer value to :math:`x`. + * + * Exceptions + * ========== + * + * Raise ``invalid operation`` exception when the correct result is not + * representable as the output type. This is the case when the input value is + * infinite or :math:`NaN`, or the magnitude of the result is too large to be + * represented. + * + * Output map + * ========== + * + * +---------------------+--------------------------+---------------------------------------+--------------------------+--------------+--------------+--------------------------+---------------------------------------+--------------------------+--------------------------+ + * | **x** | :math:`-Inf` | :math:`<` min :math:`\mathbb{I}_{ll}` | :math:`<0` | :math:`-0` | :math:`+0` | :math:`>0` | :math:`>` max :math:`\mathbb{I}_{ll}` | :math:`+Inf` | :math:`NaN` | + * +=====================+==========================+=======================================+==========================+==============+==============+==========================+=======================================+==========================+==========================+ + * | **llround(x)** | min :math:`\mathbb{I}_{ll}` | :math:`\lfloor x \rceil` | :math:`x` | :math:`\lfloor x \rceil` | max :math:`\mathbb{I}_{ll}` | :math:`llround(±Inf)` | + * +---------------------+--------------------------+---------------------------------------+--------------------------+--------------+--------------+--------------------------+---------------------------------------+--------------------------+--------------------------+ + * + */ + +#include +#include "../common/tools.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +long long int llround(double x) +{ + int32_t sign, exponent_less_1023; + /* Most significant word, least significant word. */ + uint32_t msw, lsw; + long long int result; + + EXTRACT_WORDS(msw, lsw, x); + + /* Extract sign. */ + sign = ((msw & 0x80000000U) ? -1 : 1); + /* Extract exponent field. */ + exponent_less_1023 = ((msw & 0x7ff00000) >> 20) - 1023; + msw &= 0x000fffff; + msw |= 0x00100000; + + /* exponent_less_1023 in [-1023,1024] */ + if (exponent_less_1023 < 20) { + /* exponent_less_1023 in [-1023,19] */ + if (exponent_less_1023 < 0) { + if (exponent_less_1023 < -1) { + return 0; + } else { + return sign; + } + } else { + /* exponent_less_1023 in [0,19] */ + /* shift amt in [0,19] */ + msw += 0x80000 >> exponent_less_1023; + /* shift amt in [20,1] */ + result = msw >> (20 - exponent_less_1023); + } + } else if ((uint32_t)exponent_less_1023 < (8 * sizeof(long long int)) - 1) { + /* 64bit longlong: exponent_less_1023 in [20,62] */ + if (exponent_less_1023 >= 52) { + /* 64bit longlong: exponent_less_1023 in [52,62] */ + /* 64bit longlong: shift amt in [32,42] */ + result = ((long long int) msw << (exponent_less_1023 - 20)) + /* 64bit longlong: shift amt in [0,10] */ + | ((long long int) lsw << (exponent_less_1023 - 52)); + } else { + /* 64bit longlong: exponent_less_1023 in [20,51] */ + /* 64bit longlong: shift amt in [0,31] */ + uint32_t tmp = lsw + (0x80000000U >> (exponent_less_1023 - 20)); + + if (tmp < lsw) { + ++msw; + } + + /* 64bit longlong: shift amt in [0,31] */ + result = ((long long int) msw << (exponent_less_1023 - 20)) + /* ***64bit longlong: shift amt in [32,1] */ + | SAFE_RIGHT_SHIFT(tmp, (uint32_t)(52 - exponent_less_1023)); + } + } else { /* Result is too large to be represented by a long long int. */ + (void) __raise_invalid(); + if (sign == -1) { + return __MIN_LONG_LONG; + } + else { + return __MAX_LONG_LONG; + } + } + + return sign * result; +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long long int llroundl(long double x) +{ + return llround((double) x); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/log10d.c b/libm/libmcs/libm/mathd/log10d.c new file mode 100644 index 00000000..572ab37b --- /dev/null +++ b/libm/libmcs/libm/mathd/log10d.c @@ -0,0 +1,146 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +/** + * + * This family of functions implements the base :math:`10` logarithm. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float log10f(float x); + * double log10(double x); + * long double logl(long double x); + * + * Description + * =========== + * + * ``log10`` computes the base :math:`10` logarithm of the input value. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * log10(x) \approx log_{10}(x) + * + * Returns + * ======= + * + * ``log10`` returns the base :math:`10` logarithm of :math:`x`. + * + * Exceptions + * ========== + * + * Raise ``invalid operation`` exception when the input value is negative. + * + * Raise ``divide by zero`` exception when the input value is zero. + * + * Output map + * ========== + * + * +---------------------+---------------+---------------+---------------+---------------+---------------------+---------------+---------------------+---------------+---------------+ + * | **x** | :math:`-Inf` | :math:`<0` | :math:`-0` | :math:`+0` | :math:`]0,1[` | :math:`1` | :math:`>1` | :math:`+Inf` | :math:`NaN` | + * +=====================+===============+===============+===============+===============+=====================+===============+=====================+===============+===============+ + * | **log10(x)** | :math:`qNaN` | :math:`qNaN` | :math:`-Inf` | :math:`log_{10}(x)` | :math:`+0` | :math:`log_{10}(x)` | :math:`+Inf` | :math:`qNaN` | + * +---------------------+---------------+---------------+---------------+---------------+---------------------+---------------+---------------------+---------------+---------------+ + * + */ + +#include +#include "../common/tools.h" +#include "internal/log1pmfd.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +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; + +double log10(double x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + double f, hfsq, hi, lo, r, val_hi, val_lo, w, y, y2; + int32_t i, k, hx; + uint32_t lx; + + EXTRACT_WORDS(hx, lx, x); + + k = 0; + + if (hx < 0x00100000) { /* x < 2**-1022 */ + if (((hx & 0x7fffffff) | lx) == 0) { + return __raise_div_by_zero(-1.0); /* log(+-0)=-inf */ + } + + if (hx < 0) { + if (isnan(x)) { + return x + x; + } else { + return __raise_invalid(); /* log(-#) = NaN */ + } + } + + k -= 54; + x *= two54; /* subnormal number, scale up x */ + GET_HIGH_WORD(hx, x); + } + + if (hx >= 0x7ff00000) { /* x = NaN/+-Inf */ + return x + x; + } + + if (hx == 0x3ff00000 && lx == 0) { /* log(1) = +0 */ + return zero; + } + + 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 = __log1pmf(f); + + 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; +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double log10l(long double x) +{ + return (long double) log10((double) x); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/log1pd.c b/libm/libmcs/libm/mathd/log1pd.c new file mode 100644 index 00000000..5bd3e331 --- /dev/null +++ b/libm/libmcs/libm/mathd/log1pd.c @@ -0,0 +1,235 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +/** + * + * This family of functions implements the natural logarithm of :math:`1 + x`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float log1pf(float x); + * double log1p(double x); + * long double logl(long double x); + * + * Description + * =========== + * + * ``log1p`` computes the natural logarithm of :math:`1 + x`. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * log1p(x) \approx ln(1 + x) + * + * Returns + * ======= + * + * ``log1p`` returns the natural logarithm of :math:`1 + x`. + * + * Exceptions + * ========== + * + * Raise ``invalid operation`` exception when the input value is less than :math:`-1`. + * + * Raise ``divide by zero`` exception when the input value is :math:`-1`. + * + * .. May raise ``underflow`` exception. + * + * Output map + * ========== + * + * +---------------------+---------------+---------------+---------------+-------------------+---------------+---------------+-------------------+---------------+---------------+ + * | **x** | :math:`-Inf` | :math:`<-1` | :math:`-1` | :math:`]-1,0[` | :math:`-0` | :math:`+0` | :math:`>0` | :math:`+Inf` | :math:`NaN` | + * +=====================+===============+===============+===============+===================+===============+===============+===================+===============+===============+ + * | **log1p(x)** | :math:`qNaN` | :math:`qNaN` | :math:`-Inf` | :math:`ln(1 + x)` | :math:`x` | :math:`ln(1 + x)` | :math:`+Inf` | :math:`qNaN` | + * +---------------------+---------------+---------------+---------------+-------------------+---------------+---------------+-------------------+---------------+---------------+ + * + */ + +/* 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 Remez 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 "../common/tools.h" +#include "internal/log1pmfd.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +static const double +ln2_hi = 6.93147180369123816490e-01, /* 3fe62e42 fee00000 */ +ln2_lo = 1.90821492927058770002e-10; /* 3dea39ef 35793c76 */ + +static const double zero = 0.0; + +double log1p(double x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + double hfsq, f, c, R, u; + int32_t k, hx, hu, ax; + + c = NAN; /* initial value of c is never actually used */ + f = NAN; /* initial value of f is never actually used */ + hu = INT_MAX; /* initial value of hu is never actually used */ + + GET_HIGH_WORD(hx, x); + ax = hx & 0x7fffffff; + + k = 1; + + if (hx >= 0x7ff00000) { /* x = NaN/+-Inf */ + return x + x; + } + + if (hx < 0x3FDA827A) { /* x < 0.41422 */ + if (ax >= 0x3ff00000) { /* x <= -1.0 */ + if (isnan(x)) { + return x + x; + } else if (x == -1.0) { + return __raise_div_by_zero(-1.0); /* log1p(-1)=-inf */ + } else { + return __raise_invalid(); /* log1p(x<-1)=NaN */ + } + } + + if (ax < 0x3e200000) { /* |x| < 2**-29 */ + if (ax < 0x3c900000) { /* |x| < 2**-54 */ + return __raise_inexact(x); + } else { + return __raise_inexact(x - x * x * 0.5); + } + } + + if (hx > 0 || hx <= ((int32_t)0xbfd2bec3U)) { + k = 0; + f = x; + hu = 1; + } /* -0.2929> 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; + + if (hu < 0x6a09e) { + 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) { + c += k * ln2_lo; + return k * ln2_hi + c; + } + + R = hfsq * (1.0 - 0.66666666666666666 * f); + + return k * ln2_hi - ((R - (k * ln2_lo + c)) - f); + } + + if (k == 0) { + return f - (hfsq - __log1pmf(f)); + } else { + return k * ln2_hi - ((hfsq - (__log1pmf(f) + (k * ln2_lo + c))) - f); + } +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double log1pl(long double x) +{ + return (long double) log1p((double) x); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/log2d.c b/libm/libmcs/libm/mathd/log2d.c new file mode 100644 index 00000000..a9741149 --- /dev/null +++ b/libm/libmcs/libm/mathd/log2d.c @@ -0,0 +1,167 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +/** + * + * This family of functions implements the base :math:`2` logarithm. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float log2f(float x); + * double log2(double x); + * long double logl(long double x); + * + * Description + * =========== + * + * ``log2`` computes the base :math:`2` logarithm of the input value. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * log2(x) \approx log_{2}(x) + * + * Returns + * ======= + * + * ``log2`` returns the base :math:`2` logarithm of :math:`x`. + * + * Exceptions + * ========== + * + * Raise ``invalid operation`` exception when the input value is negative. + * + * Raise ``divide by zero`` exception when the input value is zero. + * + * Output map + * ========== + * + * +---------------------+---------------+---------------+---------------+---------------+---------------------+---------------+---------------------+---------------+---------------+ + * | **x** | :math:`-Inf` | :math:`<0` | :math:`-0` | :math:`+0` | :math:`]0,1[` | :math:`1` | :math:`>1` | :math:`+Inf` | :math:`NaN` | + * +=====================+===============+===============+===============+===============+=====================+===============+=====================+===============+===============+ + * | **log2(x)** | :math:`qNaN` | :math:`qNaN` | :math:`-Inf` | :math:`log_{2}(x)` | :math:`+0` | :math:`log_{2}(x)` | :math:`+Inf` | :math:`qNaN` | + * +---------------------+---------------+---------------+---------------+---------------+---------------------+---------------+---------------------+---------------+---------------+ + * + */ + +#include +#include "../common/tools.h" +#include "internal/log1pmfd.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +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; + +double log2(double x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + double f, hfsq, hi, lo, r, val_hi, val_lo, w, y; + int32_t i, k, hx; + uint32_t lx; + + EXTRACT_WORDS(hx, lx, x); + + k = 0; + + if (hx < 0x00100000) { /* x < 2**-1022 */ + if (((hx & 0x7fffffff) | lx) == 0) { + return __raise_div_by_zero(-1.0); /* log(+-0)=-inf */ + } + + if (hx < 0) { + if (isnan(x)) { + return x + x; + } else { + return __raise_invalid(); /* log(-#) = NaN */ + } + } + + k -= 54; + x *= two54; /* subnormal number, scale up x */ + GET_HIGH_WORD(hx, x); + } + + if (hx >= 0x7ff00000) { /* x = NaN/+-Inf */ + return x + x; + } + + if (hx == 0x3ff00000 && lx == 0) { /* log(1) = +0 */ + return zero; + } + + 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 = __log1pmf(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; + + w = y + val_hi; + val_lo += (y - w) + val_hi; + val_hi = w; + + return val_lo + val_hi; +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double log2l(long double x) +{ + return (long double) log2((double) x); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/logbd.c b/libm/libmcs/libm/mathd/logbd.c new file mode 100644 index 00000000..92cc1cae --- /dev/null +++ b/libm/libmcs/libm/mathd/logbd.c @@ -0,0 +1,102 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +/** + * + * This family of functions computes the binary exponent of the input value. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float logbf(float x); + * double logb(double x); + * long double logbl(long double x); + * + * Description + * =========== + * + * ``logb`` computes the binary exponent of the input value. + * + * ``logb`` and :ref:`ilogb` have the same functionality, but ``logb`` returns + * the binary exponent as a floating-point value while :ref:`ilogb` returns a + * signed integer. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * logb(x) \approx \lfloor {\log_2 |x|} \rfloor + * + * Returns + * ======= + * + * ``logb`` returns the binary exponent of the input value. + * + * Exceptions + * ========== + * + * Raise ``divide by zero`` exception when the input value is zero. + * + * Output map + * ========== + * + * +---------------------+--------------+--------------------------------------+--------------+--------------+--------------------------------------+--------------+--------------+ + * | **x** | :math:`-Inf` | :math:`<0` | :math:`-0` | :math:`+0` | :math:`>0` | :math:`+Inf` | :math:`NaN` | + * +=====================+==============+======================================+==============+==============+======================================+==============+==============+ + * | **logb(x)** | :math:`+Inf` | :math:`\lfloor {\log_2 |x|} \rfloor` | :math:`-Inf` | :math:`\lfloor {\log_2 |x|} \rfloor` | :math:`+Inf` | :math:`qNaN` | + * +---------------------+--------------+--------------------------------------+--------------+--------------+--------------------------------------+--------------+--------------+ + * + */ + +#include +#include "../common/tools.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +double logb(double x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + int32_t hx, lx, ix; + + EXTRACT_WORDS(hx, lx, x); + hx &= 0x7fffffff; /* high |x| */ + + if (hx < 0x00100000) { /* 0 or subnormal */ + if ((hx | lx) == 0) { + return __raise_div_by_zero(-1.0); /* logb(0) = -inf */ + } 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 (double) ix; + } else if (hx < 0x7ff00000) { + return (hx >> 20) - 1023; /* normal # */ + } else { + return x * x; /* x = NaN/+-Inf */ + } +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double logbl(long double x) +{ + return (long double) logb((double) x); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/logd.c b/libm/libmcs/libm/mathd/logd.c new file mode 100644 index 00000000..0ceb571e --- /dev/null +++ b/libm/libmcs/libm/mathd/logd.c @@ -0,0 +1,171 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +/** + * + * This family of functions implements the natural logarithm. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float logf(float x); + * double log(double x); + * long double logl(long double x); + * + * Description + * =========== + * + * ``log`` computes the natural logarithm of the input value. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * log(x) \approx ln(x) + * + * Returns + * ======= + * + * ``log`` returns the natural logarithm of :math:`x`. + * + * Exceptions + * ========== + * + * Raise ``invalid operation`` exception when the input value is negative. + * + * Raise ``divide by zero`` exception when the input value is zero. + * + * Output map + * ========== + * + * +---------------------+---------------+---------------+---------------+---------------+---------------+---------------+---------------+---------------+---------------+ + * | **x** | :math:`-Inf` | :math:`<0` | :math:`-0` | :math:`+0` | :math:`]0,1[` | :math:`1` | :math:`>1` | :math:`+Inf` | :math:`NaN` | + * +=====================+===============+===============+===============+===============+===============+===============+===============+===============+===============+ + * | **log(x)** | :math:`qNaN` | :math:`qNaN` | :math:`-Inf` | :math:`ln(x)` | :math:`+0` | :math:`ln(x)` | :math:`+Inf` | :math:`qNaN` | + * +---------------------+---------------+---------------+---------------+---------------+---------------+---------------+---------------+---------------+---------------+ + * + */ + +#include +#include "../common/tools.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +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; + +double log(double x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + double hfsq, f, s, z, R, w, t1, t2, dk; + int32_t k, hx, i, j; + uint32_t lx; + + EXTRACT_WORDS(hx, lx, x); + + k = 0; + + if (hx < 0x00100000) { /* x < 2**-1022 */ + if (((hx & 0x7fffffff) | lx) == 0) { + return __raise_div_by_zero(-1.0); /* log(+-0)=-inf */ + } + + if (hx < 0) { + if (isnan(x)) { + return x + x; + } else { + return __raise_invalid(); /* log(-#) = NaN */ + } + } + + k -= 54; + x *= two54; /* subnormal number, scale up x */ + GET_HIGH_WORD(hx, x); + } + + if (hx >= 0x7ff00000) { /* x = NaN/+-Inf */ + 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) { /* |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); + } + } +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double logl(long double x) +{ + return (long double) log((double) x); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/lrintd.c b/libm/libmcs/libm/mathd/lrintd.c new file mode 100644 index 00000000..c65a715a --- /dev/null +++ b/libm/libmcs/libm/mathd/lrintd.c @@ -0,0 +1,159 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +/** + * + * This family of functions implements the nearest integer value to :math:`x`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * long int lrintf(float x); + * long int lrint(double x); + * long int lrintl(long double x); + * + * Description + * =========== + * + * ``lrint`` computes the nearest integer value to :math:`x`. Functionally the + * same procedure as :ref:`rint` but returns ``long int`` instead of a floating + * point value. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * lrint(x) = \lfloor x \rceil + * + * Returns + * ======= + * + * ``lrint`` returns the nearest integer value to :math:`x`. + * + * Exceptions + * ========== + * + * Raise ``invalid operation`` exception when the correct result is not + * representable as the output type. This is the case when the input value is + * infinite or :math:`NaN`, or the magnitude of the result is too large to be + * represented. + * + * Output map + * ========== + * + * +---------------------+--------------------------+------------------------------------+--------------------------+--------------+--------------+--------------------------+------------------------------------+--------------------------+--------------------------+ + * | **x** | :math:`-Inf` | :math:`<` min :math:`\mathbb{I}_l` | :math:`<0` | :math:`-0` | :math:`+0` | :math:`>0` | :math:`>` max :math:`\mathbb{I}_l` | :math:`+Inf` | :math:`NaN` | + * +=====================+==========================+====================================+==========================+==============+==============+==========================+====================================+==========================+==========================+ + * | **lrint(x)** | min :math:`\mathbb{I}_l` | :math:`\lfloor x \rceil` | :math:`x` | :math:`\lfloor x \rceil` | max :math:`\mathbb{I}_l` | :math:`lrint(±Inf)` | + * +---------------------+--------------------------+------------------------------------+--------------------------+--------------+--------------+--------------------------+------------------------------------+--------------------------+--------------------------+ + * + */ + +#include +#include "../common/tools.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +/* Adding a double, x, to 2^52 will cause the result to be rounded based on + the fractional part of x, according to the implementation's current rounding + mode. 2^52 is the smallest double that can be represented using all 52 significant + digits. */ +static const double TWO52[2] = { + 4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */ + -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */ +}; + +long int lrint(double x) +{ + int32_t _i0, _j0, sx; + uint32_t i1; + double t; + volatile double w; + long int result; + + EXTRACT_WORDS(_i0, i1, x); + + /* Extract sign bit. */ + sx = (_i0 >> 31) & 1; + + /* Extract exponent field. */ + _j0 = ((_i0 & 0x7ff00000) >> 20) - 1023; + /* _j0 in [-1023,1024] */ + + if (_j0 < 20) { + /* _j0 in [-1023,19] */ + if (_j0 < -1) { + return 0; + } else { + /* _j0 in [0,19] */ + /* shift amt in [0,19] */ + w = TWO52[sx] + x; + t = w - TWO52[sx]; + GET_HIGH_WORD(_i0, t); + + /* Detect the all-zeros representation of plus and + minus zero, which fails the calculation below. */ + if ((_i0 & ~(1U << 31)) == 0) { + return 0; + } + + /* After round: _j0 in [0,20] */ + _j0 = ((_i0 & 0x7ff00000) >> 20) - 1023; + _i0 &= 0x000fffff; + _i0 |= 0x00100000; + /* shift amt in [20,0] */ + result = _i0 >> (20 - _j0); + } + } else if ((uint32_t)_j0 < (8 * sizeof(long int)) - 1) { + /* 32bit return: _j0 in [20,30] */ + /* 64bit return: _j0 in [20,62] */ + if (_j0 >= 52) { + /* 64bit return: _j0 in [52,62] */ + /* 64bit return: left shift amt in [32,42] */ + result = ((long int)((_i0 & 0x000fffff) | 0x00100000) << (_j0 - 20)) | + /* 64bit return: right shift amt in [0,10] */ + ((long int) i1 << (_j0 - 52)); + } else { + /* 32bit return: _j0 in [20,30] */ + /* 64bit return: _j0 in [20,51] */ + w = TWO52[sx] + x; + t = w - TWO52[sx]; + EXTRACT_WORDS(_i0, i1, t); + _j0 = ((_i0 & 0x7ff00000) >> 20) - 1023; + _i0 &= 0x000fffff; + _i0 |= 0x00100000; + /* After round: + * 32bit return: _j0 in [20,31]; + * 64bit return: _j0 in [20,52] */ + /* 32bit return: left shift amt in [0,11] */ + /* 64bit return: left shift amt in [0,32] */ + /* ***32bit return: right shift amt in [32,21] */ + /* ***64bit return: right shift amt in [32,0] */ + result = ((long int) _i0 << (_j0 - 20)) | SAFE_RIGHT_SHIFT(i1, (uint32_t)(52 - _j0)); + } + } else { + (void) __raise_invalid(); + if (sx != 0) { + return __MIN_LONG; + } + else { + return __MAX_LONG; + } + } + + return (sx != 0) ? -result : result; +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long int lrintl(long double x) +{ + return lrint((double) x); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/lroundd.c b/libm/libmcs/libm/mathd/lroundd.c new file mode 100644 index 00000000..a0eecff0 --- /dev/null +++ b/libm/libmcs/libm/mathd/lroundd.c @@ -0,0 +1,141 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +/** + * + * This family of functions implements the nearest integer value to :math:`x`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * long int lroundf(float x); + * long int lround(double x); + * long int lroundl(long double x); + * + * Description + * =========== + * + * ``lround`` computes the nearest integer value to :math:`x`. Functionally the + * same procedure as :ref:`round` but returns ``long int`` instead of a + * floating point value. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * lround(x) = \lfloor x \rceil + * + * Returns + * ======= + * + * ``lround`` returns the nearest integer value to :math:`x`. + * + * Exceptions + * ========== + * + * Raise ``invalid operation`` exception when the correct result is not + * representable as the output type. This is the case when the input value is + * infinite or :math:`NaN`, or the magnitude of the result is too large to be + * represented. + * + * Output map + * ========== + * + * +---------------------+--------------------------+------------------------------------+--------------------------+--------------+--------------+--------------------------+------------------------------------+--------------------------+--------------------------+ + * | **x** | :math:`-Inf` | :math:`<` min :math:`\mathbb{I}_l` | :math:`<0` | :math:`-0` | :math:`+0` | :math:`>0` | :math:`>` max :math:`\mathbb{I}_l` | :math:`+Inf` | :math:`NaN` | + * +=====================+==========================+====================================+==========================+==============+==============+==========================+====================================+==========================+==========================+ + * | **lround(x)** | min :math:`\mathbb{I}_l` | :math:`\lfloor x \rceil` | :math:`x` | :math:`\lfloor x \rceil` | max :math:`\mathbb{I}_l` | :math:`lround(±Inf)` | + * +---------------------+--------------------------+------------------------------------+--------------------------+--------------+--------------+--------------------------+------------------------------------+--------------------------+--------------------------+ + * + */ + +#include +#include "../common/tools.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +long int lround(double x) +{ + int32_t sign, exponent_less_1023; + /* Most significant word, least significant word. */ + uint32_t msw, lsw; + long int result; + + EXTRACT_WORDS(msw, lsw, x); + + /* Extract sign. */ + sign = ((msw & 0x80000000U) != 0) ? -1 : 1; + /* Extract exponent field. */ + exponent_less_1023 = ((msw & 0x7ff00000) >> 20) - 1023; + msw &= 0x000fffff; + msw |= 0x00100000; + + /* exponent_less_1023 in [-1023,1024] */ + if (exponent_less_1023 < 20) { + /* exponent_less_1023 in [-1023,19] */ + if (exponent_less_1023 < 0) { + if (exponent_less_1023 < -1) { + return 0; + } else { + return sign; + } + } else { + /* exponent_less_1023 in [0,19] */ + /* shift amt in [0,19] */ + msw += 0x80000 >> exponent_less_1023; + /* shift amt in [20,1] */ + result = msw >> (20 - exponent_less_1023); + } + } else if ((uint32_t)exponent_less_1023 < (8 * sizeof(long int)) - 1) { + /* 32bit long: exponent_less_1023 in [20,30] */ + /* 64bit long: exponent_less_1023 in [20,62] */ + if (exponent_less_1023 >= 52) { + /* 64bit long: exponent_less_1023 in [52,62] */ + /* 64bit long: shift amt in [32,42] */ + result = ((long int) msw << (exponent_less_1023 - 20)) + /* 64bit long: shift amt in [0,10] */ + | ((long int) lsw << (exponent_less_1023 - 52)); + } else { + /* 32bit long: exponent_less_1023 in [20,30] */ + /* 64bit long: exponent_less_1023 in [20,51] */ + /* 32bit long: shift amt in [0,10] */ + /* 64bit long: shift amt in [0,31] */ + uint32_t tmp = lsw + (0x80000000U >> (exponent_less_1023 - 20)); + + if (tmp < lsw) { + ++msw; + } + + /* 32bit long: shift amt in [0,10] */ + /* 64bit long: shift amt in [0,31] */ + result = ((long int) msw << (exponent_less_1023 - 20)) + /* ***32bit long: shift amt in [32,22] */ + /* ***64bit long: shift amt in [32,1] */ + | SAFE_RIGHT_SHIFT(tmp, (uint32_t)(52 - exponent_less_1023)); + } + } else { /* Result is too large to be represented by a long int. */ + (void) __raise_invalid(); + if (sign == -1) { + return __MIN_LONG; + } + else { + return __MAX_LONG; + } + } + + return sign * result; +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long int lroundl(long double x) +{ + return lround((double) x); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/modfd.c b/libm/libmcs/libm/mathd/modfd.c new file mode 100644 index 00000000..cb94c9c8 --- /dev/null +++ b/libm/libmcs/libm/mathd/modfd.c @@ -0,0 +1,128 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +/** + * + * This family of functions splits the input value into integral and fractional + * part. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float modff(float x, float *iptr); + * double modf(double x, double *iptr); + * long double modfl(long double x, long double *iptr); + * + * Description + * =========== + * + * ``modf`` splits the input value into integral and fractional part, each of + * which have the same sign. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * modf(x) = x - iptr \wedge \left\{\begin{array}{ll} iptr = \lfloor x \rfloor, & x \geq 0 \\ iptr = \lceil x \rceil, & otherwise \end{array}\right. + * + * Returns + * ======= + * + * ``modf`` returns the fractional part of :math:`x` in the range + * :math:`]-1.0,1.0[` and puts the integral part into the output pointer + * :math:`*iptr`. + * + * Exceptions + * ========== + * + * Does not raise exceptions. + * + * Output map + * ========== + * + * +---------------------+--------------+----------------------------------+--------------+--------------+----------------------------------+--------------+--------------+ + * | **x** | :math:`-Inf` | :math:`<0` | :math:`-0` | :math:`+0` | :math:`>0` | :math:`+Inf` | :math:`NaN` | + * +=====================+==============+==================================+==============+==============+==================================+==============+==============+ + * | **modf(x)** | :math:`-0` | :math:`x - \lceil x \rceil` | :math:`x` | :math:`x - \lfloor x \rfloor` | :math:`+0` | :math:`qNaN` | + * +---------------------+--------------+----------------------------------+--------------+--------------+----------------------------------+--------------+ + + * | :math:`*iptr` | :math:`-Inf` | :math:`\lceil x \rceil` | :math:`x` | :math:`\lfloor x \rfloor` | :math:`+Inf` | | + * +---------------------+--------------+----------------------------------+--------------+--------------+----------------------------------+--------------+--------------+ + * + */ + +#include +#include +#include "../common/tools.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +double modf(double x, double *iptr) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + double _xi = 0.0; + int32_t _i0, _i1, _j0; + uint32_t i; + + assert(iptr != (void*)0); + if(iptr == (void*)0) { + iptr = &_xi; + } + + 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 & 0x80000000U, 0U); /* *iptr = +-0 */ + return x; + } else { + i = (0x000fffff) >> _j0; + + if (((_i0 & i) | _i1) == 0) { /* x is integral */ + *iptr = x; + INSERT_WORDS(x, _i0 & 0x80000000U, 0U); /* return +-0 */ + return x; + } else { + INSERT_WORDS(*iptr, _i0 & (~i), 0); + return x - *iptr; + } + } + } else if (_j0 > 51) { /* no fraction part */ + *iptr = x; + + if (isnan(x)) { + return *iptr = x + x; /* x is NaN, return NaN */ + } + + INSERT_WORDS(x, _i0 & 0x80000000U, 0U); /* return +-0 */ + return x; + } else { /* fraction part in low x */ + i = ((uint32_t)(0xffffffffU)) >> (_j0 - 20); + + if ((_i1 & i) == 0) { /* x is integral */ + *iptr = x; + INSERT_WORDS(x, _i0 & 0x80000000U, 0U); /* return +-0 */ + return x; + } else { + INSERT_WORDS(*iptr, _i0, _i1 & (~i)); + return x - *iptr; + } + } +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double modfl(long double x, long double *iptr) +{ + return (long double) modf((double) x, (double *) iptr); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/nand.c b/libm/libmcs/libm/mathd/nand.c new file mode 100644 index 00000000..f08fe216 --- /dev/null +++ b/libm/libmcs/libm/mathd/nand.c @@ -0,0 +1,64 @@ +/* SPDX-License-Identifier: GTDGmbH */ +/* Copyright 2020-2025 by GTD GmbH. */ + +/** + * + * This family of functions returns a predefined ``NaN``. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float nanf(const char *payload); + * double nan(const char *payload); + * long double nanl(const char *payload); + * + * Description + * =========== + * + * ``nan`` produces a fixed ``qNaN`` regardless of input. + * + * The return ``qNaN`` is ``0x7FF80000000D067D`` as ``double`` (float: ``0x7FCF067D``). + * + * This procedure is not C standard compliant as the payload parameter is + * ignored. If your platform/toolchain provides ``strtod`` as a workaround the + * call ``strtod("NAN(char-sequence)", NULL);`` can be used as a replacement if + * that functionality is wanted (same with ``strtof`` and ``strtold``). + * + * Returns + * ======= + * + * ``nan`` returns a ``qNaN``. + * + * Exceptions + * ========== + * + * Does not raise exceptions. + * + */ + +#include +#include "../common/tools.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +double nan(const char *payload) +{ + (void)payload; + + double x; + INSERT_WORDS(x,0x7FF80000,0x000D067D); + return x; +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double nanl(const char *payload) +{ + return (long double) nan(payload); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/nearbyintd.c b/libm/libmcs/libm/mathd/nearbyintd.c new file mode 100644 index 00000000..91c9a137 --- /dev/null +++ b/libm/libmcs/libm/mathd/nearbyintd.c @@ -0,0 +1,68 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +/** + * + * This family of functions implements the nearest integer value to :math:`x`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float nearbyintf(float x); + * double nearbyint(double x); + * long double nearbyintl(long double x); + * + * Description + * =========== + * + * ``nearbyint`` computes the nearest integer value to :math:`x`. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * nearbyint(x) = \lfloor x \rceil + * + * Returns + * ======= + * + * ``nearbyint`` returns the nearest integer value to :math:`x`. + * + * Exceptions + * ========== + * + * Does not raise exceptions. + * + * Output map + * ========== + * + * +---------------------+--------------+--------------------------+--------------+--------------+--------------------------+--------------+--------------+ + * | **x** | :math:`-Inf` | :math:`<0` | :math:`-0` | :math:`+0` | :math:`>0` | :math:`+Inf` | :math:`NaN` | + * +=====================+==============+==========================+==============+==============+==========================+==============+==============+ + * | **nearbyint(x)** | :math:`-Inf` | :math:`\lfloor x \rceil` | :math:`x` | :math:`\lfloor x \rceil` | :math:`+Inf` | :math:`qNaN` | + * +---------------------+--------------+--------------------------+--------------+--------------+--------------------------+--------------+--------------+ + * + */ + +#include + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +double nearbyint(double x) +{ + return rint(x); +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double nearbyintl(long double x) +{ + return (long double) nearbyint((double) x); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/nextafterd.c b/libm/libmcs/libm/mathd/nextafterd.c new file mode 100644 index 00000000..c6bea51c --- /dev/null +++ b/libm/libmcs/libm/mathd/nextafterd.c @@ -0,0 +1,162 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +/** + * + * This family of functions computes the next floating-point value after + * :math:`x` in direction of :math:`y`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float nextafterf(float x, float y); + * double nextafter(double x, double y); + * long double nextafterl(long double x, long double y); + * + * Description + * =========== + * + * ``nextafter`` computes the next floating-point value after :math:`x` in direction of :math:`y`. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * nextafter(x, y) = \left\{\begin{array}{ll} y, & x = y \\ \text{min} \{z | z \in \mathbb{F} \wedge z > x\}, & x < y \\ \text{max} \{z | z \in \mathbb{F} \wedge z < x\}, & otherwise \end{array}\right. + * + * Returns + * ======= + * + * ``nextafter`` returns the the next floating-point value after :math:`x` in + * direction of :math:`y`. + * + * Exceptions + * ========== + * + * Raise ``overflow`` exception when the magnitude of :math:`x` is the largest + * finite value representable in the type and :math:`y` is infinite with the + * same sign as :math:`x`. + * + * .. May raise ``underflow`` exception. + * + * Output map + * ========== + * + * +--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+ + * | nextafter(x,y) | x | + * +--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+ + * | y | :math:`-Inf` | :math:`<0` | :math:`-0` | :math:`+0` | :math:`>0` | :math:`+Inf` | :math:`NaN` | + * +==========================+==========================+==========================+==========================+==========================+==========================+==========================+==========================+ + * | :math:`-Inf` | :math:`-Inf` | :math:`nextafter(x, y)` | max :math:`\mathbb{S}^{-}` | :math:`nextafter(x, y)` | :math:`nextafter(x, y)` | :math:`qNaN` | + * +--------------------------+--------------------------+ + + + + + + * | :math:`<0` | :math:`nextafter(x, y)` | | | | | | + * +--------------------------+ + +--------------------------+--------------------------+ + + + + * | :math:`-0` | | | :math:`y` | | | | + * +--------------------------+ + + + + + + + * | :math:`+0` | | | | | | | + * +--------------------------+ + +--------------------------+--------------------------+ + + + + * | :math:`>0` | | | min :math:`\mathbb{S}^{+}` | | | | + * +--------------------------+ + + + +--------------------------+ + + * | :math:`+Inf` | | | | | :math:`+Inf` | | + * +--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+ + + * | :math:`NaN` | :math:`qNaN` | | + * +--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+ + * + */ + +#include +#include "../common/tools.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +double nextafter(double x, double y) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_one; + y *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + int32_t hx, hy, ix; + uint32_t lx, ly; + + EXTRACT_WORDS(hx, lx, x); + EXTRACT_WORDS(hy, ly, y); + ix = hx & 0x7fffffff; /* |x| */ + + if (isnan(x) || isnan(y)) { /* x or y is nan */ + return x + y; + } else if (hx == hy && lx == ly) { + return y; /* x == y, return y */ + } else if ((ix | lx) == 0) { /* x == 0 */ + if (ix == (hy & 0x7fffffff) && ly == 0U) { + return y; /* x == y, return y */ + } +#ifdef __LIBMCS_FPU_DAZ + INSERT_WORDS(x, (hy & 0x80000000U) | 0x00100000U, 0U); /* return +-minnormal */ +#else + INSERT_WORDS(x, hy & 0x80000000U, 1U); /* return +-minsubnormal */ + (void) __raise_underflow(x); +#endif /* defined(__LIBMCS_FPU_DAZ) */ + return x; + } else 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 __raise_overflow(x); /* overflow if x is finite */ + } + + if (hy < 0x00100000) { /* underflow */ +#ifdef __LIBMCS_FPU_DAZ + INSERT_WORDS(x, hx & 0x80000000U, 0U); /* return +-0.0 */ + return x; +#else + (void) __raise_underflow(x); +#endif /* defined(__LIBMCS_FPU_DAZ) */ + } + + INSERT_WORDS(x, hx, lx); + return x; +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double nextafterl(long double x, long double y) +{ + return (long double) nextafter((double) x, (double) y); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/nexttowardd.c b/libm/libmcs/libm/mathd/nexttowardd.c new file mode 100644 index 00000000..d6913aa3 --- /dev/null +++ b/libm/libmcs/libm/mathd/nexttowardd.c @@ -0,0 +1,98 @@ +/* SPDX-License-Identifier: GTDGmbH */ +/* Copyright 2020-2025 by GTD GmbH. */ + +/** + * + * This family of functions computes the next floating-point value after + * :math:`x` in direction of :math:`y`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float nexttowardf(float x, long double y); + * double nexttoward(double x, long double y); + * long double nexttowardl(long double x, long double y); + * + * Description + * =========== + * + * ``nexttoward`` computes the next floating-point value after :math:`x` in + * direction of :math:`y`. + * + * ``nexttoward`` is functionally equivalent to :ref:`nextafter` but uses + * ``long double`` for the :math:`y` input. As the library only supports 64bit + * ``long double`` the procedure ``nexttoward`` is just calling + * :ref:`nextafter` as the types are the same, but for ``nexttowardf`` there is + * an actual difference as :math:`y` can be chosen to be so close to :math:`x` + * that it would be the same value in ``float`` but isn't in (effectively) + * ``double``. This results in ``nexttowardf`` having it's own implementation + * while ``nexttoward`` does not. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * nexttoward(x, y) = \left\{\begin{array}{ll} y, & x = y \\ \text{min} \{z | z \in \mathbb{F} \wedge z > x\}, & x < y \\ \text{max} \{z | z \in \mathbb{F} \wedge z < x\}, & otherwise \end{array}\right. + * + * Returns + * ======= + * + * ``nexttoward`` returns the the next floating-point value after :math:`x` in + * direction of :math:`y`. + * + * Exceptions + * ========== + * + * Raise ``overflow`` exception when the magnitude of :math:`x` is the largest + * finite value representable in the type and :math:`y` is infinite with the + * same sign as :math:`x`. + * + * .. May raise ``underflow`` exception. + * + * Output map + * ========== + * + * +--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+ + * | nexttoward(x,y) | x | + * +--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+ + * | y | :math:`-Inf` | :math:`<0` | :math:`-0` | :math:`+0` | :math:`>0` | :math:`+Inf` | :math:`NaN` | + * +==========================+==========================+==========================+==========================+==========================+==========================+==========================+==========================+ + * | :math:`-Inf` | :math:`-Inf` | :math:`nexttoward(x, y)` | max :math:`\mathbb{S}^{-}` | :math:`nexttoward(x, y)` | :math:`nexttoward(x, y)` | :math:`qNaN` | + * +--------------------------+--------------------------+ + + + + + + * | :math:`<0` | :math:`nexttoward(x, y)` | | | | | | + * +--------------------------+ + +--------------------------+--------------------------+ + + + + * | :math:`-0` | | | :math:`y` | | | | + * +--------------------------+ + + + + + + + * | :math:`+0` | | | | | | | + * +--------------------------+ + +--------------------------+--------------------------+ + + + + * | :math:`>0` | | | min :math:`\mathbb{S}^{+}` | | | | + * +--------------------------+ + + + +--------------------------+ + + * | :math:`+Inf` | | | | | :math:`+Inf` | | + * +--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+ + + * | :math:`NaN` | :math:`qNaN` | | + * +--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+ + * + */ + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +#include + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +double nexttoward(double x, long double y) +{ + return nextafter(x, (double) y); +} + +long double nexttowardl(long double x, long double y) +{ + return (long double) nexttoward((double) x, y); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/powd.c b/libm/libmcs/libm/mathd/powd.c new file mode 100644 index 00000000..a0dc7312 --- /dev/null +++ b/libm/libmcs/libm/mathd/powd.c @@ -0,0 +1,443 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +/** + * + * This family of functions implements the value of :math:`x` raised to the + * power of :math:`y`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float powf(float x, float y); + * double pow(double x, double y); + * long double powl(long double x, long double y); + * + * Description + * =========== + * + * ``pow`` computes the value of :math:`x` raised to the power of :math:`y`. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * pow(x, y) \approx x^y + * + * Returns + * ======= + * + * ``pow`` returns the value of :math:`x` raised to the power of :math:`y`. + * + * Exceptions + * ========== + * + * Raise ``invalid operation`` exception when :math:`x` is finite and negative + * and :math:`y` is finite and not an integer value. + * + * Raise ``divide by zero`` exception when :math:`x` is zero and :math:`y` is a + * negative odd integer value. + * + * Raise ``overflow`` exception when the magnitude of the result is too large. + * + * .. May raise ``underflow`` exception. + * + * Output map + * ========== + * + * +--------------------------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+ + * | pow(x,y) | x | + * +--------------------------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+ + * | y | :math:`-Inf` | :math:`< -1` | :math:`-1` | :math:`]-1,-0[` | :math:`-0` | :math:`+0` | :math:`]+0,+1[` | :math:`+1` | :math:`> +1` | :math:`+Inf` | :math:`qNaN` | :math:`sNaN` | + * +============================================+==========================+==========================+==========================+==========================+==========================+==========================+==========================+==========================+==========================+==========================+==========================+==========================+ + * | :math:`-Inf` | :math:`+0` | :math:`+1` | :math:`+Inf` | :math:`+1` | :math:`+0` | :math:`qNaN` | :math:`qNaN` | + * +--------------------------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+ +--------------------------+--------------------------+ + + + * | :math:`\{2k + 1 : k \in \mathbb{Z}_{<0}\}` | :math:`-0` | :math:`x^y` | :math:`-Inf` | :math:`+Inf` | :math:`x^y` | | :math:`x^y` | :math:`+0` | | | + * +--------------------------------------------+--------------------------+ +--------------------------+--------------------------+ + + + + + + + * | :math:`\{2k : k \in \mathbb{Z}_{<0}\}` | :math:`+0` | | :math:`+Inf` | | | | | | | + * +--------------------------------------------+ +--------------------------+--------------------------+--------------------------+ + + + + + + + + * | :math:`< 0\ \wedge \notin \mathbb{Z}` | | :math:`qNaN` | | | | | | | | + * +--------------------------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+ + + * | :math:`-0` | :math:`+1` | | + * +--------------------------------------------+ + + + * | :math:`+0` | | | + * +--------------------------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+ + + * | :math:`> 0\ \wedge \notin \mathbb{Z}` | :math:`+Inf` | :math:`qNaN` | :math:`+0` | :math:`x^y` | :math:`+1` | :math:`x^y` | :math:`+Inf` | :math:`qNaN` | | + * +--------------------------------------------+ +--------------------------+--------------------------+--------------------------+ + + + + + + + + * | :math:`\{2k : k \in \mathbb{Z}_{>0}\}` | | :math:`x^y` | | | | | | | | + * +--------------------------------------------+--------------------------+ +--------------------------+--------------------------+ + + + + + + + * | :math:`\{2k - 1 : k \in \mathbb{Z}_{>0}\}` | :math:`-Inf` | | :math:`-0` | :math:`+0` | | | | | | | + * +--------------------------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+ +--------------------------+--------------------------+ + + + * | :math:`+Inf` | :math:`+Inf` | :math:`+1` | :math:`+0` | | :math:`+Inf` | | | + * +--------------------------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+ +--------------------------+--------------------------+--------------------------+ + + * | :math:`qNaN` | :math:`qNaN` | | :math:`qNaN` | | + * +--------------------------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+ + * | :math:`sNaN` | :math:`qNaN` | + * +--------------------------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+ + * + */ + +#include +#include "../common/tools.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +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 */ +/* 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*/ + +double pow(double x, double y) +{ + double z, ax, z_h, z_l, p_h, p_l; + double _y1, t1, t2, r, s, sign, t, u, v, w; + int32_t i, j, k, yisint, n; + int32_t hx, hy, ix, iy; + uint32_t lx, ly; + + EXTRACT_WORDS(hx, lx, x); + EXTRACT_WORDS(hy, ly, y); + ix = hx & 0x7fffffff; + iy = hy & 0x7fffffff; + + /* y==zero: x**0 = 1 unless x is snan */ +#ifdef __LIBMCS_FPU_DAZ + if (iy < 0x00100000) { +#else + if ((iy | ly) == 0) { +#endif /* defined(__LIBMCS_FPU_DAZ) */ + if (__issignaling(x) != 0) { + return x + y; + } + + return one; + } + + /* x|y==NaN return NaN unless x==1 then return 1 */ /* For performance: don't use isnan */ + if (ix > 0x7ff00000 || ((ix == 0x7ff00000) && (lx != 0)) || + iy > 0x7ff00000 || ((iy == 0x7ff00000) && (ly != 0))) { + if (((hx - 0x3ff00000) | lx) == 0 && __issignaling(y) == 0) { + return one; + } else { + return x + y; + } + } + +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_one; + y *= __volatile_one; + + EXTRACT_WORDS(hx, lx, x); + EXTRACT_WORDS(hy, ly, y); + ix = hx & 0x7fffffff; + iy = hy & 0x7fffffff; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + /* 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 (((uint32_t)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); + } + } else { + /* No action required */ + } + } else { + /* No action required */ + } + } + + /* special value of y */ + if (ly == 0) { + if (iy == 0x7ff00000) { /* y is +-inf */ + if (((ix - 0x3ff00000) | lx) == 0) { + return one; /* +-1**+-inf = 1 */ + } 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 == 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 = (1/|x|) */ + if (ix == 0x7ff00000) { + z = zero; + } else if (ix == 0) { + z = __raise_div_by_zero(z); + } else { + /* No action required */ + } + } + + if (hx < 0) { + if (((ix - 0x3ff00000) | yisint) == 0) { + z = __raise_invalid(); /* (-1)**non-int is NaN */ + } else if (yisint == 1) { + z = -z; /* (x<0)**odd = -(|x|**odd) */ + } else { + /* No action required */ + } + } + + return z; + } + } + + n = ((uint32_t)hx >> 31U) - 1U; + + /* (x<0)**(non-int) is NaN */ + if ((n | yisint) == 0) { + return __raise_invalid(); + } + + sign = one; /* (sign of result -ve**odd) = -1 else = 1 */ + if ((n | (yisint - 1)) == 0) { + sign = -one; /* (-ve)**(odd int) */ + } + + /* |y| is huge */ + if (iy > 0x42000000) { /* if |y| > ~2**33 (does not regard mantissa) */ + if (iy > 0x43f00000) { /* if |y| > ~2**64, must o/uflow and y is an even integer */ + if (ix <= 0x3fefffff) { /* |x| < 1 */ + return (hy < 0) ? __raise_overflow(one) : __raise_underflow(one); + } else { /* |x| > 1 */ + return (hy > 0) ? __raise_overflow(one) : __raise_underflow(one); + } + } + + /* over/underflow if x is not close to one */ + if (ix < 0x3fefffff) { + return (hy < 0) ? __raise_overflow(sign) : __raise_underflow(sign); + } + + if (ix > 0x3ff00000) { + return (hy > 0) ? __raise_overflow(sign) : __raise_underflow(sign); + } + + /* 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) * (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 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 = 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.0 + s2 + r; + SET_LOW_WORD(t_h, 0); + t_l = r - ((t_h - 3.0) - 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; + 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) = (s+..)*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 __raise_overflow(sign); + } else { + if (p_l + ovt > z - p_h) { + return __raise_overflow(sign); + } + } + } else if ((j & 0x7fffffff) >= 0x4090cc00) { /* z <= -1075 */ + if (((j - 0xc090cc00U) | i) != 0) { /* z < -1075 */ + return __raise_underflow(sign); + } else { + if (p_l <= z - p_h) { + return __raise_underflow(sign); + } + } + } else { + /* No action required */ + } + + /* + * 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, (int32_t)n); /* subnormal output */ + } else { + SET_HIGH_WORD(z, j); + } + + return sign * z; +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double powl(long double x, long double y) +{ + return (long double) pow((double) x, (double) y); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/remainderd.c b/libm/libmcs/libm/mathd/remainderd.c new file mode 100644 index 00000000..cb96fa04 --- /dev/null +++ b/libm/libmcs/libm/mathd/remainderd.c @@ -0,0 +1,176 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +/** + * + * This family of functions implements the floating-point remainder :math:`x\ REM\ y`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float remainderf(float x, float y); + * double remainder(double x, double y); + * long double remainderl(long double x, long double y); + * + * Description + * =========== + * + * ``remainder`` computes the floating-point remainder :math:`r = x\ REM\ y = x + * - n \cdot y` of their arguments :math:`x` and :math:`y`, where :math:`n` is + * the integral value nearest to :math:`\frac{x}{y}`. + * + * The ``fmod`` and ``remainder`` procedures are rather similar, but not the + * same, see examples: + * + * +----------------+----------------+----------------+----------------+ + * | x | y | fmod | remainder | + * +================+================+================+================+ + * | :math:`+2.456` | :math:`+2.0` | :math:`+0.456` | :math:`+0.456` | + * +----------------+----------------+----------------+----------------+ + * | :math:`+3.456` | :math:`+2.0` | :math:`+1.456` | :math:`-0.544` | + * +----------------+----------------+----------------+----------------+ + * | :math:`-2.456` | :math:`+2.0` | :math:`-0.456` | :math:`-0.456` | + * +----------------+----------------+----------------+----------------+ + * | :math:`-3.456` | :math:`+2.0` | :math:`-1.456` | :math:`+0.544` | + * +----------------+----------------+----------------+----------------+ + * | :math:`+2.456` | :math:`-2.0` | :math:`+0.456` | :math:`+0.456` | + * +----------------+----------------+----------------+----------------+ + * | :math:`+3.456` | :math:`-2.0` | :math:`+1.456` | :math:`-0.544` | + * +----------------+----------------+----------------+----------------+ + * | :math:`-2.456` | :math:`-2.0` | :math:`-0.456` | :math:`-0.456` | + * +----------------+----------------+----------------+----------------+ + * | :math:`-3.456` | :math:`-2.0` | :math:`-1.456` | :math:`+0.544` | + * +----------------+----------------+----------------+----------------+ + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * remainder(x, y) = x - n \cdot y \wedge n \in \mathbb{Z} \wedge remainder(x, y) \in \left [-\left | \frac{y}{2} \right |,\left | \frac{y}{2} \right | \right ] + * + * Returns + * ======= + * + * ``remainder`` returns the floating-point remainder :math:`x\ REM\ y`. + * + * Exceptions + * ========== + * + * Raise ``invalid operation`` exception when :math:`x` is infinite or + * :math:`y` is zero. + * + * .. May raise ``underflow`` exception. + * + * Output map + * ========== + * + * +--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+ + * | remainder(x,y) | x | + * +--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+ + * | y | :math:`-Inf` | :math:`<0` | :math:`-0` | :math:`+0` | :math:`>0` | :math:`+Inf` | :math:`NaN` | + * +==========================+==========================+==========================+==========================+==========================+==========================+==========================+==========================+ + * | :math:`-Inf` | :math:`qNaN` | :math:`x` | :math:`qNaN` | :math:`qNaN` | + * +--------------------------+ +--------------------------+--------------------------+--------------------------+--------------------------+ + + + * | :math:`<0` | | :math:`x\ REM\ y` | :math:`x` | :math:`x\ REM\ y` | | | + * +--------------------------+ +--------------------------+--------------------------+--------------------------+--------------------------+ + + + * | :math:`-0` | | :math:`qNaN` | | | + * +--------------------------+ + + + + + * | :math:`+0` | | | | | + * +--------------------------+ +--------------------------+--------------------------+--------------------------+--------------------------+ + + + * | :math:`>0` | | :math:`x\ REM\ y` | :math:`x` | :math:`x\ REM\ y` | | | + * +--------------------------+ +--------------------------+--------------------------+--------------------------+--------------------------+ + + + * | :math:`+Inf` | | :math:`x` | | | + * +--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+ + + * | :math:`NaN` | :math:`qNaN` | | + * +--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+ + * + */ + +#include +#include "../common/tools.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +static const double zero = 0.0; + +double remainder(double x, double y) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_one; + y *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + int32_t hx, hy; + uint32_t sx, lx, ly; + double y_half; + + EXTRACT_WORDS(hx, lx, x); + EXTRACT_WORDS(hy, ly, y); + sx = hx & 0x80000000U; + hy &= 0x7fffffff; + hx &= 0x7fffffff; + + /* purge off exception values */ + if ((hx >= 0x7ff00000) || (hy >= 0x7ff00000)) { /* x or y not finite */ + if (isnan(x) || isnan(y)) { /* x or y is NaN */ + return x + y; + } else if (hx == 0x7ff00000) { /* x is infinite */ + return __raise_invalid(); + } else { + /* No action required */ + } + } else if ((hy | ly) == 0) { /* y = 0 */ + return __raise_invalid(); + } else { + /* No action required */ + } + + if (hy <= 0x7fdfffff) { + x = fmod(x, 2 * y); /* now x < 2y */ + } + + if (((hx - hy) | (lx - ly)) == 0) { /* x equals y */ + return zero * x; + } + + x = fabs(x); + y = fabs(y); + + if (hy < 0x00200000) { + if (x + x > y) { + x -= y; + + if (x + x >= y) { + x -= y; + } + } + } else { + y_half = 0.5 * y; + + if (x > y_half) { + x -= y; + + if (x >= y_half) { + x -= y; + } + } + } + + GET_HIGH_WORD(hx, x); + SET_HIGH_WORD(x, hx ^ sx); + return x; +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double remainderl(long double x, long double y) +{ + return (long double) remainder((double) x, (double) y); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/remquod.c b/libm/libmcs/libm/mathd/remquod.c new file mode 100644 index 00000000..212089d1 --- /dev/null +++ b/libm/libmcs/libm/mathd/remquod.c @@ -0,0 +1,210 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +/** + * + * This family of functions implements the floating-point remainder :math:`x\ + * REM\ y` and puts the quotient (or rather its sign and 3 least significant + * bits) into the out pointer. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float remquof(float x, float y, int *quo); + * double remquo(double x, double y, int *quo); + * long double remquol(long double x, long double y, int *quo); + * + * Description + * =========== + * + * ``remquo`` computes the floating-point remainder :math:`r = x\ REM\ y = x - + * n \cdot y` of their arguments :math:`x` and :math:`y`, where :math:`n` is + * the integral value nearest to :math:`\frac{x}{y}`. + * + * The 3 least significant bits of :math:`n` and its sign are then put into the + * output pointer :math:`*quo`. + * + * ``remquo`` and ``remainder`` are functionally equivalent concerning the + * return value, ``remquo`` only adds an additional output. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * remquo(x, y) = x - n \cdot y \wedge n \in \mathbb{Z} \wedge remquo(x, y) \in \left [-\left | \frac{y}{2} \right |,\left | \frac{y}{2} \right | \right ] \wedge quo = n + * + * Returns + * ======= + * + * ``remquo`` returns the floating-point remainder :math:`x\ REM\ y`. The sign + * and 3 least significant bits of quotient :math:`n` is put into :math:`*quo`. + * + * Exceptions + * ========== + * + * Raise ``invalid operation`` exception when :math:`x` is infinite or + * :math:`y` is zero. + * + * .. May raise ``underflow`` exception. + * + * Output map + * ========== + * + * +--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+ + * | remquo(x,y) | x | + * +--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+ + * | y | :math:`-Inf` | :math:`<0` | :math:`-0` | :math:`+0` | :math:`>0` | :math:`+Inf` | :math:`NaN` | + * +==========================+==========================+==========================+==========================+==========================+==========================+==========================+==========================+ + * | :math:`-Inf` | :math:`qNaN` | :math:`x` | :math:`qNaN` | :math:`qNaN` | + * +--------------------------+ +--------------------------+--------------------------+--------------------------+--------------------------+ + + + * | :math:`<0` | | :math:`x\ REM\ y` | :math:`x` | :math:`x\ REM\ y` | | | + * +--------------------------+ +--------------------------+--------------------------+--------------------------+--------------------------+ + + + * | :math:`-0` | | :math:`qNaN` | | | + * +--------------------------+ + + + + + * | :math:`+0` | | | | | + * +--------------------------+ +--------------------------+--------------------------+--------------------------+--------------------------+ + + + * | :math:`>0` | | :math:`x\ REM\ y` | :math:`x` | :math:`x\ REM\ y` | | | + * +--------------------------+ +--------------------------+--------------------------+--------------------------+--------------------------+ + + + * | :math:`+Inf` | | :math:`x` | | | + * +--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+ + + * | :math:`NaN` | :math:`qNaN` | | + * +--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+ + * + * +--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+ + * | :math:`*quo` | x | + * +--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+ + * | y | :math:`-Inf` | :math:`<0` | :math:`-0` | :math:`+0` | :math:`>0` | :math:`+Inf` | :math:`NaN` | + * +==========================+==========================+==========================+==========================+==========================+==========================+==========================+==========================+ + * | :math:`-Inf` | :math:`0` | :math:`0` | :math:`0` | :math:`0` | + * +--------------------------+ +--------------------------+--------------------------+--------------------------+--------------------------+ + + + * | :math:`<0` | | :math:`n` | :math:`0` | :math:`n` | | | + * +--------------------------+ +--------------------------+--------------------------+--------------------------+--------------------------+ + + + * | :math:`-0` | | :math:`0` | | | + * +--------------------------+ + + + + + * | :math:`+0` | | | | | + * +--------------------------+ +--------------------------+--------------------------+--------------------------+--------------------------+ + + + * | :math:`>0` | | :math:`n` | :math:`0` | :math:`n` | | | + * +--------------------------+ +--------------------------+--------------------------+--------------------------+--------------------------+ + + + * | :math:`+Inf` | | :math:`0` | | | + * +--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+ + + * | :math:`NaN` | :math:`0` | | + * +--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+--------------------------+ + * + */ + +#include +#include +#include "../common/tools.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +static const double zero = 0.0; + +double remquo(double x, double y, int *quo) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_one; + y *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + int _quo = 0; + int32_t hx, hy; + uint32_t sx, sq, lx, ly; + double y_half; + + assert(quo != (void*)0); + if(quo == (void*)0) { + quo = &_quo; + } + *quo = 0; + + EXTRACT_WORDS(hx, lx, x); + EXTRACT_WORDS(hy, ly, y); + sx = hx & 0x80000000U; + sq = sx ^ (hy & 0x80000000U); + hy &= 0x7fffffff; + hx &= 0x7fffffff; + + /* purge off exception values */ + if ((hx >= 0x7ff00000) || (hy >= 0x7ff00000)) { /* x or y not finite */ + if (isnan(x) || isnan(y)) { /* x or y is NaN */ + return x + y; + } else if (hx == 0x7ff00000) { /* x is infinite */ + return __raise_invalid(); + } else { + /* No action required */ + } + } else if ((hy | ly) == 0) { /* y = 0 */ + return __raise_invalid(); + } else { + /* No action required */ + } + + if (hy <= 0x7fbfffff) { + x = fmod(x, 8 * y); /* now x < 8y */ + } + + if (((hx - hy) | (lx - ly)) == 0) { /* x equals y */ + *quo = sq ? -1 : 1; + return zero * x; + } + + x = fabs(x); + y = fabs(y); + _quo = 0; + + if (x >= 4 * y) { + x -= 4 * y; + _quo += 4; + } + if (x >= 2 * y) { + x -= 2 * y; + _quo += 2; + } + + if (hy < 0x00200000) { + if (x + x > y) { + x -= y; + _quo++; + + if (x + x >= y) { + x -= y; + _quo++; + } + } + } else { + y_half = 0.5 * y; + + if (x > y_half) { + x -= y; + _quo++; + + if (x >= y_half) { + x -= y; + _quo++; + } + } + } + + _quo &= 0x7; + + *quo = sq ? -_quo : _quo; + + GET_HIGH_WORD(hx, x); + SET_HIGH_WORD(x, hx ^ sx); + return x; +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double remquol(long double x, long double y, int *quo) +{ + return (long double) remquo((double) x, (double) y, quo); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/rintd.c b/libm/libmcs/libm/mathd/rintd.c new file mode 100644 index 00000000..39bdef05 --- /dev/null +++ b/libm/libmcs/libm/mathd/rintd.c @@ -0,0 +1,143 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +/** + * + * This family of functions implements the nearest integer value to :math:`x`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float rintf(float x); + * double rint(double x); + * long double rintl(long double x); + * + * Description + * =========== + * + * ``rint`` computes the nearest integer value to :math:`x`. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * rint(x) = \lfloor x \rceil + * + * Returns + * ======= + * + * ``rint`` returns the nearest integer value to :math:`x`. + * + * Exceptions + * ========== + * + * Does not raise exceptions. + * + * Output map + * ========== + * + * +---------------------+--------------+--------------------------+--------------+--------------+--------------------------+--------------+--------------+ + * | **x** | :math:`-Inf` | :math:`<0` | :math:`-0` | :math:`+0` | :math:`>0` | :math:`+Inf` | :math:`NaN` | + * +=====================+==============+==========================+==============+==============+==========================+==============+==============+ + * | **rint(x)** | :math:`-Inf` | :math:`\lfloor x \rceil` | :math:`x` | :math:`\lfloor x \rceil` | :math:`+Inf` | :math:`qNaN` | + * +---------------------+--------------+--------------------------+--------------+--------------+--------------------------+--------------+--------------+ + * + */ + +#include +#include "../common/tools.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +static const double TWO52[2] = { + 4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */ + -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */ +}; + +double rint(double x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + int32_t _i0, _j0, sx; + uint32_t i, _i1; + double t; + volatile double w; + EXTRACT_WORDS(_i0, _i1, x); + sx = (_i0 >> 31) & 1; /* sign */ + _j0 = ((_i0 >> 20) & 0x7ff) - 0x3ff; /* exponent */ + + if (_j0 < 20) { /* no integral bits in LS part */ + if (_j0 < 0) { /* x is fractional or 0 */ + if (((_i0 & 0x7fffffff) | _i1) == 0) { + return x; /* x == 0 */ + } + + _i1 |= (_i0 & 0x0fffff); + _i0 &= 0xfffe0000U; + _i0 |= ((_i1 | -_i1) >> 12) & 0x80000; + SET_HIGH_WORD(x, _i0); + w = TWO52[sx] + x; + t = w - TWO52[sx]; + GET_HIGH_WORD(_i0, t); + SET_HIGH_WORD(t, (_i0 & 0x7fffffff) | (sx << 31)); + return t; + } else { /* x has integer and maybe fraction */ + i = (0x000fffff) >> _j0; + + if (((_i0 & i) | _i1) == 0) { + return x; /* x is integral */ + } + + i >>= 1; + + if (((_i0 & i) | _i1) != 0) { + /* 2nd or any later bit after radix is set */ + if (_j0 == 19) { + _i1 = 0x80000000U; + } else { + _i1 = 0; + } + + _i0 = (_i0 & (~i)) | ((0x40000) >> _j0); + } + } + } else if (_j0 > 51) { + if (_j0 == 0x400) { + return x + x; /* inf or NaN */ + } else { + return x; /* x is integral */ + } + } else { + i = ((uint32_t)0xffffffffU) >> (_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); + w = TWO52[sx] + x; + return w - TWO52[sx]; +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double rintl(long double x) +{ + return (long double) rint((double) x); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/roundd.c b/libm/libmcs/libm/mathd/roundd.c new file mode 100644 index 00000000..4b41221c --- /dev/null +++ b/libm/libmcs/libm/mathd/roundd.c @@ -0,0 +1,131 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +/** + * + * This family of functions implements the nearest integer value to :math:`x`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float roundf(float x); + * double round(double x); + * long double roundl(long double x); + * + * Description + * =========== + * + * ``round`` computes the nearest integer value to :math:`x`. Half-way cases + * are rounded away from zero (which is the only difference to + * :ref:`nearbyint`, :ref:`rint`). + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * round(x) = \lfloor x \rceil + * + * Returns + * ======= + * + * ``round`` returns the nearest integer value to :math:`x`. + * + * Exceptions + * ========== + * + * Does not raise exceptions. + * + * Output map + * ========== + * + * +---------------------+--------------+--------------------------+--------------+--------------+--------------------------+--------------+--------------+ + * | **x** | :math:`-Inf` | :math:`<0` | :math:`-0` | :math:`+0` | :math:`>0` | :math:`+Inf` | :math:`NaN` | + * +=====================+==============+==========================+==============+==============+==========================+==============+==============+ + * | **round(x)** | :math:`-Inf` | :math:`\lfloor x \rceil` | :math:`x` | :math:`\lfloor x \rceil` | :math:`+Inf` | :math:`qNaN` | + * +---------------------+--------------+--------------------------+--------------+--------------+--------------------------+--------------+--------------+ + * + */ + +#include +#include "../common/tools.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +double round(double x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + /* Most significant word, least significant word. */ + int32_t msw, exponent_less_1023; + uint32_t lsw; + + EXTRACT_WORDS(msw, lsw, x); + + /* Extract exponent field. */ + exponent_less_1023 = ((msw & 0x7ff00000) >> 20) - 1023; + + if (exponent_less_1023 < 20) { + if (exponent_less_1023 < 0) { + msw &= 0x80000000U; + + if (exponent_less_1023 == -1) { /* Result is +1.0 or -1.0. */ + msw |= ((int32_t)1023 << 20); + } + + lsw = 0; + } else { + uint32_t exponent_mask = 0x000fffff >> exponent_less_1023; + + if ((msw & exponent_mask) == 0 && lsw == 0) { /* x in an integral value. */ + return x; + } + + msw += 0x00080000 >> exponent_less_1023; + msw &= ~exponent_mask; + lsw = 0; + } + } else if (exponent_less_1023 > 51) { + if (exponent_less_1023 == 1024) { /* x is NaN or infinite. */ + return x + x; + } else { + return x; + } + } else { + uint32_t exponent_mask = 0xffffffffU >> (exponent_less_1023 - 20); + uint32_t tmp; + + if ((lsw & exponent_mask) == 0) { /* x is an integral value. */ + return x; + } + + tmp = lsw + (1 << (51 - exponent_less_1023)); + + if (tmp < lsw) { + msw += 1; + } + + lsw = tmp; + + lsw &= ~exponent_mask; + } + + INSERT_WORDS(x, msw, lsw); + + return x; +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double roundl(long double x) +{ + return (long double) round((double) x); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/scalblnd.c b/libm/libmcs/libm/mathd/scalblnd.c new file mode 100644 index 00000000..9517c999 --- /dev/null +++ b/libm/libmcs/libm/mathd/scalblnd.c @@ -0,0 +1,142 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +/** + * + * This family of functions multiplies the input value :math:`x` by an integral + * power of :math:`2`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float scalblnf(float x, int n); + * double scalbln(double x, int n); + * long double scalblnl(long double x, int n); + * + * Description + * =========== + * + * ``scalbln`` multiplies the input value :math:`x` by an integral power of + * :math:`2`. + * + * ``scalbln`` and :ref:`scalbn` have the same functionality. The difference is + * that :ref:`scalbn` uses an ``int`` for :math:`n`. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * scalbln(x, n) \approx x \cdot 2^{n} + * + * Returns + * ======= + * + * ``scalbln`` returns the input value :math:`x` multiplied by :math:`2` + * powered by the input value :math:`n`. + * + * Exceptions + * ========== + * + * Raise ``overflow`` exception if the result overflows. + * + * .. May raise ``underflow`` exception. + * + * Output map + * ========== + * + * +---------------------+-------------------------+-------------------------+-------------------------+ + * | scalbln(x,n) | n | + * +---------------------+-------------------------+-------------------------+-------------------------+ + * | x | :math:`<0` | :math:`0` | :math:`>0` | + * +=====================+=========================+=========================+=========================+ + * | :math:`-Inf` | :math:`x` | :math:`x` | :math:`x` | + * +---------------------+-------------------------+ +-------------------------+ + * | :math:`<0` | :math:`x \cdot 2^{n}` | | :math:`x \cdot 2^{n}` | + * +---------------------+-------------------------+ +-------------------------+ + * | :math:`-0` | :math:`x` | | :math:`x` | + * +---------------------+ + + + + * | :math:`+0` | | | | + * +---------------------+-------------------------+ +-------------------------+ + * | :math:`>0` | :math:`x \cdot 2^{n}` | | :math:`x \cdot 2^{n}` | + * +---------------------+-------------------------+ +-------------------------+ + * | :math:`+Inf` | :math:`x` | | :math:`x` | + * +---------------------+-------------------------+-------------------------+-------------------------+ + * | :math:`NaN` | :math:`qNaN` | + * +---------------------+-------------------------+-------------------------+-------------------------+ + * + */ + +#include +#include "../common/tools.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +static const double +two54 = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */ +twom54 = 5.55111512312578270212e-17; /* 0x3C900000, 0x00000000 */ + +double scalbln(double x, long int n) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + 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 (k == 0x7ff) { + return x + x; /* NaN or Inf */ + } + + if (n > 50000) { + return __raise_overflow(x); /*overflow*/ + } + + k = k + n; + + if (k > 0x7fe) { + return __raise_overflow(x); /*overflow*/ + } + + if (n < -50000) { + return __raise_underflow(x); /*underflow*/ + } + + if (k > 0) { /* normal result */ + SET_HIGH_WORD(x, (hx & 0x800fffffU) | (k << 20U)); + return x; + } + + if (k <= -54) { + return __raise_underflow(x); /*underflow*/ + } + + k += 54; /* subnormal result */ + SET_HIGH_WORD(x, (hx & 0x800fffffU) | (k << 20U)); + return x * twom54; +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double scalblnl(long double x, long int n) +{ + return (long double) scalbln((double) x, n); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/scalbnd.c b/libm/libmcs/libm/mathd/scalbnd.c new file mode 100644 index 00000000..8415567d --- /dev/null +++ b/libm/libmcs/libm/mathd/scalbnd.c @@ -0,0 +1,146 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +/** + * + * This family of functions multiplies the input value :math:`x` by an integral + * power of :math:`2`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float scalbnf(float x, int n); + * double scalbn(double x, int n); + * long double scalbnl(long double x, int n); + * + * Description + * =========== + * + * ``scalbn`` multiplies the input value :math:`x` by an integral power of + * :math:`2`. + * + * ``scalbn`` and :ref:`ldexp` have the same functionality. In theory their + * definition could be different, but this only applies to architectures which + * do not use a binary system, which by now are assumed to be an obscurity. + * + * ``scalbn`` and :ref:`scalbln` have the same functionality. The difference is + * that :ref:`scalbln` uses a ``long int`` for :math:`n`. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * scalbn(x, n) \approx x \cdot 2^{n} + * + * Returns + * ======= + * + * ``scalbn`` returns the input value :math:`x` multiplied by :math:`2` powered + * by the input value :math:`n`. + * + * Exceptions + * ========== + * + * Raise ``overflow`` exception if the result overflows. + * + * .. May raise ``underflow`` exception. + * + * Output map + * ========== + * + * +---------------------+-------------------------+-------------------------+-------------------------+ + * | scalbn(x,n) | n | + * +---------------------+-------------------------+-------------------------+-------------------------+ + * | x | :math:`<0` | :math:`0` | :math:`>0` | + * +=====================+=========================+=========================+=========================+ + * | :math:`-Inf` | :math:`x` | :math:`x` | :math:`x` | + * +---------------------+-------------------------+ +-------------------------+ + * | :math:`<0` | :math:`x \cdot 2^{n}` | | :math:`x \cdot 2^{n}` | + * +---------------------+-------------------------+ +-------------------------+ + * | :math:`-0` | :math:`x` | | :math:`x` | + * +---------------------+ + + + + * | :math:`+0` | | | | + * +---------------------+-------------------------+ +-------------------------+ + * | :math:`>0` | :math:`x \cdot 2^{n}` | | :math:`x \cdot 2^{n}` | + * +---------------------+-------------------------+ +-------------------------+ + * | :math:`+Inf` | :math:`x` | | :math:`x` | + * +---------------------+-------------------------+-------------------------+-------------------------+ + * | :math:`NaN` | :math:`qNaN` | + * +---------------------+-------------------------+-------------------------+-------------------------+ + * + */ + +#include +#include "../common/tools.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +static const double +two54 = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */ +twom54 = 5.55111512312578270212e-17; /* 0x3C900000, 0x00000000 */ + +double scalbn(double x, int n) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + 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 __raise_underflow(x); /*underflow*/ + } + } + + if (k == 0x7ff) { + return x + x; /* NaN or Inf */ + } + + if (n > 50000) { + return __raise_overflow(x); /*overflow */ + } + + k = k + n; + + if (k > 0x7fe) { + return __raise_overflow(x); /*overflow */ + } + + if (k > 0) { /* normal result */ + SET_HIGH_WORD(x, (hx & 0x800fffffU) | (k << 20U)); + return x; + } + + if (k <= -54) { + return __raise_underflow(x); /*underflow*/ + } + + k += 54; /* subnormal result */ + SET_HIGH_WORD(x, (hx & 0x800fffffU) | (k << 20U)); + return x * twom54; +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double scalbnl(long double x, int n) +{ + return (long double) scalbn((double) x, n); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/sind.c b/libm/libmcs/libm/mathd/sind.c new file mode 100644 index 00000000..952f18ed --- /dev/null +++ b/libm/libmcs/libm/mathd/sind.c @@ -0,0 +1,123 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +/** + * + * This family of functions implements the sine of :math:`x`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float sinf(float x); + * double sin(double x); + * long double sinl(long double x); + * + * Description + * =========== + * + * ``sin`` computes the sine of the input value. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * sin(x) \approx sin(x) + * + * Returns + * ======= + * + * ``sin`` returns the sine of the input value, in the range :math:`[-1, 1]`. + * + * Exceptions + * ========== + * + * Raise ``invalid operation`` exception when the input value is infinite. + * + * .. May raise ``underflow`` exception. + * + * Output map + * ========== + * + * +---------------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+ + * | **x** | :math:`-Inf` | :math:`<0` | :math:`-0` | :math:`+0` | :math:`>0` | :math:`+Inf` | :math:`NaN` | + * +=====================+================+================+================+================+================+================+================+ + * | **sin(x)** | :math:`qNaN` | :math:`sin(x)` | :math:`x` | :math:`sin(x)` | :math:`qNaN` | :math:`qNaN` | + * +---------------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+ + * + */ + +#include +#include "../common/tools.h" +#include "internal/trigd.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +double sin(double x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + 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 (x == 0.0) { /* return x inexact except 0 */ + return x; + } else { + return __raise_inexact(x); + } + } + + return __sin(x, z, 0); + } + + /* sin(Inf or NaN) is NaN */ + else if (ix >= 0x7ff00000) { + if (isnan(x)) { + return x + x; + } else { + return __raise_invalid(); + } + } + + /* argument reduction needed */ + else { + n = __rem_pio2(x, y); + + switch (n & 3) { + case 0: + return __sin(y[0], y[1], 1); + + case 1: + return __cos(y[0], y[1]); + + case 2: + return -__sin(y[0], y[1], 1); + + default: + return -__cos(y[0], y[1]); + } + } +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double sinl(long double x) +{ + return (long double) sin((double) x); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/sinhd.c b/libm/libmcs/libm/mathd/sinhd.c new file mode 100644 index 00000000..ae4342d6 --- /dev/null +++ b/libm/libmcs/libm/mathd/sinhd.c @@ -0,0 +1,131 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +/** + * + * This family of functions implements the hyperbolic sine of :math:`x`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float sinhf(float x); + * double sinh(double x); + * long double sinhl(long double x); + * + * Description + * =========== + * + * ``sinh`` computes the hyperbolic sine of the input value. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * sinh(x) \approx sinh(x) = \frac{e^x-e^{-x}}{2} + * + * Returns + * ======= + * + * ``sinh`` returns the hyperbolic sine. + * + * Exceptions + * ========== + * + * Raise ``overflow`` exception when the magnitude of the input value is too + * large. + * + * .. May raise ``underflow`` exception. + * + * Output map + * ========== + * + * +---------------------+--------------+-----------------+--------------+--------------+-----------------+--------------+--------------+ + * | **x** | :math:`-Inf` | :math:`<0` | :math:`-0` | :math:`+0` | :math:`>0` | :math:`+Inf` | :math:`NaN` | + * +=====================+==============+=================+==============+==============+=================+==============+==============+ + * | **sinh(x)** | :math:`-Inf` | :math:`sinh(x)` | :math:`x` | :math:`sinh(x)` | :math:`+Inf` | :math:`qNaN` | + * +---------------------+--------------+-----------------+--------------+--------------+-----------------+--------------+--------------+ + * + */ + +#include +#include "../common/tools.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +static const double one = 1.0; + +double sinh(double x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + double t, w, h; + int32_t ix, jx; + uint32_t lx; + + /* 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 (x == 0.0) { /* return x inexact except 0 */ + return x; + } else { + return __raise_inexact(x); + } + } + + 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 * exp(fabs(x)); + } + + /* |x| in [log(maxdouble), overflowthresold] */ + GET_LOW_WORD(lx, x); + + if (ix < 0x408633CE || (ix == 0x408633ce && lx <= (uint32_t)0x8fb9f87dU)) { + w = exp(0.5 * fabs(x)); + t = h * w; + return t * w; + } + + /* |x| > overflowthresold, sinh(x) overflow */ + return __raise_overflow(x); +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double sinhl(long double x) +{ + return (long double) sinh((double) x); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/sqrtd.c b/libm/libmcs/libm/mathd/sqrtd.c new file mode 100644 index 00000000..843598bf --- /dev/null +++ b/libm/libmcs/libm/mathd/sqrtd.c @@ -0,0 +1,199 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +/** + * + * This family of functions implements the square root of :math:`x`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float sqrtf(float x); + * double sqrt(double x); + * long double sqrtl(long double x); + * + * Description + * =========== + * + * ``sqrt`` computes the square root of the input value. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * sqrt(x) \approx \sqrt{x} + * + * Returns + * ======= + * + * ``sqrt`` returns the square root of the input value. + * + * Exceptions + * ========== + * + * Raise ``invalid operation`` exception when :math:`x` is negative. + * + * Output map + * ========== + * + * +---------------------+--------------+------------------+--------------+--------------+------------------+--------------+--------------+ + * | **x** | :math:`-Inf` | :math:`<0` | :math:`-0` | :math:`+0` | :math:`>0` | :math:`+Inf` | :math:`NaN` | + * +=====================+==============+==================+==============+==============+==================+==============+==============+ + * | **sqrt(x)** | :math:`qNaN` | :math:`qNaN` | :math:`x` | :math:`\sqrt{x}` | :math:`+Inf` | :math:`qNaN` | + * +---------------------+--------------+------------------+--------------+--------------+------------------+--------------+--------------+ + * + */ + +#include +#include "../common/tools.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +double sqrt(double x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + double z; + int32_t sign = 0x80000000U; + uint32_t r, t1, s1, ix1, q1; + int32_t ix0, s0, q, m, t, i; + + EXTRACT_WORDS(ix0, ix1, x); + + /* take care of Inf and NaN */ + if ((ix0 & 0x7ff00000) == 0x7ff00000) { + if (isnan(x)) { /* sqrt(NaN)=NaN */ + return x + x; + } else if (ix0 > 0) { /* sqrt(+inf)=+inf */ + return x; + } else { /* sqrt(-inf)=sNaN */ + return __raise_invalid(); + } + } + + /* take care of zero and negative values */ + if (ix0 <= 0) { + if (((ix0 & (~sign)) | ix1) == 0) { + return x; /* sqrt(+-0) = +-0 */ + } else if (ix0 < 0) { + return __raise_invalid(); /* sqrt(-ve) = sNaN */ + } else { + /* No action required */ + } + } + + /* 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 (0 < (m & 1)) { /* odd m, double x to make it even */ + ix0 += ix0 + (int32_t)((ix1 & (uint32_t)sign) >> 31U); + ix1 += ix1; + } + + m >>= 1; /* m = [m/2] */ + + /* generate sqrt(x) bit by bit */ + ix0 += ix0 + (int32_t)((ix1 & (uint32_t)sign) >> 31U); + 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 + (int32_t)((ix1 & (uint32_t)sign) >> 31U); + ix1 += ix1; + r >>= 1; + } + + r = sign; + + while (r != 0) { + t1 = s1 + r; + t = s0; + + if ((t < ix0) || ((t == ix0) && (t1 <= ix1))) { + s1 = t1 + r; + + if ((((int32_t)t1 & sign) == sign) && ((int32_t)s1 & sign) == 0) { + s0 += 1; + } + + ix0 -= t; + + if (ix1 < t1) { + ix0 -= 1; + } + + ix1 -= t1; + q1 += r; + } + + ix0 += ix0 + (int32_t)((ix1 & (uint32_t)sign) >> 31U); + ix1 += ix1; + r >>= 1; + } + + /* use floating add to find out rounding direction */ + if ((ix0 | ix1) != 0) { + (void) __raise_inexact(x); + if (q1 == (uint32_t)0xffffffffU) { + q1 = 0; + q += 1; + } else { + q1 += (q1 & 1); + } + } + + ix0 = (q >> 1) + 0x3fe00000; + ix1 = q1 >> 1; + + if ((q & 1) != 0) { + ix1 |= sign; + } + + ix0 += (m << 20); + INSERT_WORDS(z, ix0, ix1); + return z; +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double sqrtl(long double x) +{ + return (long double) sqrt((double) x); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/tand.c b/libm/libmcs/libm/mathd/tand.c new file mode 100644 index 00000000..404360c0 --- /dev/null +++ b/libm/libmcs/libm/mathd/tand.c @@ -0,0 +1,195 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +/** + * + * This family of functions implements the tangent of :math:`x`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float tanf(float x); + * double tan(double x); + * long double tanl(long double x); + * float __tanf(float x, float y, int k); + * double __tan(double x, double y, int k); + * + * Description + * =========== + * + * ``tan`` computes the tangent of the input value. + * + * ``__tan`` is an internal function that computes the tangent of the input + * values. The sum of both input parameters :math:`x` and :math:`y` is bounded + * to [:math:`-\frac{\pi}{4}`, :math:`\frac{\pi}{4}`]. The first parameter + * :math:`x` is the requested value in raw precision while the second parameter + * :math:`y` contains a tail for higher precision. If the additional input + * variable :math:`k` is :math:`-1`, the function shall return the negative + * inverse tangent of :math:`x`, if :math:`k` is :math:`1` return the tangent. + * As ``__tan`` is an internal function, it should not be called by a user. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * tan(x) \approx tan(x) + * + * Returns + * ======= + * + * ``tan`` returns the tangent of the input value. + * + * ``__tan`` returns the tangent of the input value. + * + * Exceptions + * ========== + * + * Raise ``invalid operation`` exception when the input value is infinite. + * + * .. May raise ``underflow`` exception. + * + * Output map + * ========== + * + * +---------------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+ + * | **x** | :math:`-Inf` | :math:`<0` | :math:`-0` | :math:`+0` | :math:`>0` | :math:`+Inf` | :math:`NaN` | + * +=====================+================+================+================+================+================+================+================+ + * | **tan(x)** | :math:`qNaN` | :math:`tan(x)` | :math:`x` | :math:`tan(x)` | :math:`qNaN` | :math:`qNaN` | + * +---------------------+----------------+----------------+----------------+----------------+----------------+----------------+----------------+ + * + */ + +#include +#include "../common/tools.h" +#include "internal/trigd.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +static const double +pio4 = 7.85398163397448278999e-01, /* 0x3FE921FB, 0x54442D18 */ +pio4lo = 3.06161699786838301793e-17, /* 0x3C81A626, 0x33145C07 */ +T[] = { + 3.33333333333334091986e-01, /* 0x3FD55555, 0x55555563 */ + 1.33333333333201242699e-01, /* 0x3FC11111, 0x1110FE7A */ + 5.39682539762260521377e-02, /* 0x3FABA1BA, 0x1BB341FE */ + 2.18694882948595424599e-02, /* 0x3F9664F4, 0x8406D637 */ + 8.86323982359930005737e-03, /* 0x3F8226E3, 0xE96E8493 */ + 3.59207910759131235356e-03, /* 0x3F6D6D22, 0xC9560328 */ + 1.45620945432529025516e-03, /* 0x3F57DBC8, 0xFEE08315 */ + 5.88041240820264096874e-04, /* 0x3F4344D8, 0xF2F26501 */ + 2.46463134818469906812e-04, /* 0x3F3026F7, 0x1A8D1068 */ + 7.81794442939557092300e-05, /* 0x3F147E88, 0xA03792A6 */ + 7.14072491382608190305e-05, /* 0x3F12B80F, 0x32F0A7E9 */ + -1.85586374855275456654e-05, /* 0xBEF375CB, 0xDB605373 */ + 2.59073051863633712884e-05, /* 0x3EFB2A70, 0x74BF7AD4 */ +}; + +static inline double __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); + } +} + +double tan(double x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + 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 (x == 0.0) { /* return x inexact except 0 */ + return x; + } else { + return __raise_inexact(x); + } + } + + return __tan(x, z, 1); + } + + /* tan(Inf or NaN) is NaN */ + else if (ix >= 0x7ff00000) { + if (isnan(x)) { + return x + x; + } else { + return __raise_invalid(); + } + } + + /* argument reduction needed */ + else { + n = __rem_pio2(x, y); + return __tan(y[0], y[1], 1 - ((n & 1) << 1)); /* 1 -- n even, -1 -- n odd */ + } +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double tanl(long double x) +{ + return (long double) tan((double) x); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/tanhd.c b/libm/libmcs/libm/mathd/tanhd.c new file mode 100644 index 00000000..df11ab4f --- /dev/null +++ b/libm/libmcs/libm/mathd/tanhd.c @@ -0,0 +1,118 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +/** + * + * This family of functions implements the hyperbolic tangent of :math:`x`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float tanhf(float x); + * double tanh(double x); + * long double tanhl(long double x); + * + * Description + * =========== + * + * ``tanh`` computes the hyperbolic tangent of the input value. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * tanh(x) \approx tanh(x) = \frac{e^x-e^{-x}}{e^x+e^{-x}} + * + * Returns + * ======= + * + * ``tanh`` returns the hyperbolic tangent, in the range :math:`[-1, 1]`. + * + * Exceptions + * ========== + * + * Does not raise overflow, division by zero, and invalid exceptions. + * + * .. May raise ``underflow`` exception. + * + * Output map + * ========== + * + * +---------------------+--------------+-----------------+--------------+--------------+-----------------+--------------+--------------+ + * | **x** | :math:`-Inf` | :math:`<0` | :math:`-0` | :math:`+0` | :math:`>0` | :math:`+Inf` | :math:`NaN` | + * +=====================+==============+=================+==============+==============+=================+==============+==============+ + * | **tanh(x)** | :math:`-1` | :math:`tanh(x)` | :math:`x` | :math:`tanh(x)` | :math:`+1` | :math:`qNaN` | + * +---------------------+--------------+-----------------+--------------+--------------+-----------------+--------------+--------------+ + * + */ + +#include +#include "../common/tools.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +static const double one = 1.0, two = 2.0; + +double tanh(double x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + double t, z; + int32_t jx, ix; + + /* High word of |x|. */ + GET_HIGH_WORD(jx, x); + ix = jx & 0x7fffffff; + + /* x is INF or NaN */ + if (ix >= 0x7ff00000) { + if (isnan(x)) { /* tanh(NaN) = NaN */ + return x + x; + } else if (jx >= 0) { + return one; /* tanh(+inf)=+1 */ + } else { + return -one; /* tanh(-inf)=-1 */ + } + } + + /* |x| < 22 */ + if (ix < 0x40360000) { /* |x|<22 */ + if (ix < 0x3c800000) { /* |x|<2**-55 */ + if (x == 0.0) { /* return x inexact except 0 */ + return x; + } else { + return __raise_inexact(x); + } + } + + 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 = __raise_inexact(one); /* raised inexact flag */ + } + + return (jx >= 0) ? z : -z; +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double tanhl(long double x) +{ + return (long double) tanh((double) x); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/tgammad.c b/libm/libmcs/libm/mathd/tgammad.c new file mode 100644 index 00000000..2ad0285b --- /dev/null +++ b/libm/libmcs/libm/mathd/tgammad.c @@ -0,0 +1,99 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +/** + * + * This family of functions implements the gamma function of :math:`x`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float tgammaf(float x); + * double tgamma(double x); + * long double tgammal(long double x); + * + * Description + * =========== + * + * ``tgamma`` computes the gamma function of :math:`x`. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * tgamma(x) \approx \Gamma(x) = \int_{0}^{\infty}e^{-t}t^{x-1}dt + * + * Returns + * ======= + * + * ``tgamma`` returns the gamma function of :math:`x`. + * + * Exceptions + * ========== + * + * Raise ``invalid operation`` exception when the input value is a negative + * integer or negative infinity. + * + * Raise ``divide by zero`` exception when the input value is zero. + * + * Raise ``overflow`` exception when the magnitude of the input value is too + * large or too small. + * + * Output map + * ========== + * + * +---------------------+--------------+---------------------------------------+-----------------------------+--------------+--------------+-------------------+--------------+--------------+ + * | **x** | :math:`-Inf` | :math:`<0\ \wedge\ \notin \mathbb{Z}` | :math:`\in \mathbb{Z}_{<0}` | :math:`-0` | :math:`+0` | :math:`>0` | :math:`+Inf` | :math:`NaN` | + * +=====================+==============+=======================================+=============================+==============+==============+===================+==============+==============+ + * | **tgamma(x)** | :math:`qNaN` | :math:`\Gamma(x)` | :math:`qNaN` | :math:`-Inf` | :math:`+Inf` | :math:`\Gamma(x)` | :math:`+Inf` | :math:`qNaN` | + * +---------------------+--------------+---------------------------------------+-----------------------------+--------------+--------------+-------------------+--------------+--------------+ + * + */ + +#include +#include "../common/tools.h" +#include "internal/gammad.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +double tgamma(double x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + int signgam_local = 0; + double y = 0.0; + + if (isnan(x) != 0) { /* tgamma(NaN) = NaN */ + return x + x; + } else if (x == 0.0) { /* tgamma(+-0) = +-Inf */ + return __raise_div_by_zero(x); + } else if (floor(x) == x && x < 0.0) { /* tgamma(negative integer, -Inf) = NaN */ + return __raise_invalid(); + } else { + /* No action required */ + } + + y = exp(__lgamma(x, &signgam_local)); + + if (signgam_local < 0) { + y = -y; + } + + return y; +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double tgammal(long double x) +{ + return (long double) tgamma((double) x); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/truncd.c b/libm/libmcs/libm/mathd/truncd.c new file mode 100644 index 00000000..726216d7 --- /dev/null +++ b/libm/libmcs/libm/mathd/truncd.c @@ -0,0 +1,109 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +/** + * + * This family of functions implements the nearest integer value towards zero + * from :math:`x`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * float truncf(float x); + * double trunc(double x); + * long double truncl(long double x); + * + * Description + * =========== + * + * ``trunc`` computes the nearest integer value towards zero from :math:`x`. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * trunc(x) = \left\{\begin{array}{ll} \lfloor x \rfloor, & x \in \mathbb{F}^{+} \\ \lceil x \rceil, & otherwise \end{array}\right. + * + * Returns + * ======= + * + * ``trunc`` returns the nearest integer value towards zero from :math:`x`. + * + * Exceptions + * ========== + * + * Does not raise exceptions. + * + * Output map + * ========== + * + * +---------------------+--------------+---------------------------+--------------+--------------+---------------------------+--------------+--------------+ + * | **x** | :math:`-Inf` | :math:`<0` | :math:`-0` | :math:`+0` | :math:`>0` | :math:`+Inf` | :math:`NaN` | + * +=====================+==============+===========================+==============+==============+===========================+==============+==============+ + * | **trunc(x)** | :math:`-Inf` | :math:`\lceil x \rceil` | :math:`x` | :math:`\lfloor x \rfloor` | :math:`+Inf` | :math:`qNaN` | + * +---------------------+--------------+---------------------------+--------------+--------------+---------------------------+--------------+--------------+ + * + */ + +#include +#include "../common/tools.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +double trunc(double x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + uint32_t sb; + /* Most significant word, least significant word. */ + uint32_t msw; + uint32_t lsw; + int32_t exponent_less_1023; + + EXTRACT_WORDS(msw, lsw, x); + + /* Extract sign bit. */ + sb = msw & 0x80000000U; + + /* Extract exponent field. */ + exponent_less_1023 = ((msw & 0x7ff00000) >> 20) - 1023; + + if (exponent_less_1023 < 20) { + /* All significant digits are in msw. */ + if (exponent_less_1023 < 0) { + /* -1 < x < 1, so result is +0 or -0. */ + INSERT_WORDS(x, sb, 0); + } else { + /* All relevant fraction bits are in msw, so lsw of the result is 0. */ + INSERT_WORDS(x, sb | (msw & ~(0x000fffff >> exponent_less_1023)), 0); + } + } else if (exponent_less_1023 > 51) { + if (exponent_less_1023 == 1024) { + /* x is infinite, or not a number, so trigger an exception. */ + return x + x; + } + + /* All bits in the fraction fields of the msw and lsw are needed in the result. */ + } else { + /* All fraction bits in msw are relevant. Truncate irrelevant bits from lsw. */ + INSERT_WORDS(x, msw, lsw & ~(0xffffffffU >> (exponent_less_1023 - 20))); + } + + return x; +} + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +long double truncl(long double x) +{ + return (long double) trunc((double) x); +} + +#endif /* #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS */ +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/y0d.c b/libm/libmcs/libm/mathd/y0d.c new file mode 100644 index 00000000..a75a1133 --- /dev/null +++ b/libm/libmcs/libm/mathd/y0d.c @@ -0,0 +1,162 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +/** + * + * This family of functions implements the Bessel function of the second kind + * of order 0. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * double y0(double x); + * + * Description + * =========== + * + * ``y0`` computes the Bessel value of :math:`x` of the second kind of order 0. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * y0(x) = Y_{0}(x) + * + * Notice that the mathematical function represented by the procedure ``y0`` is + * not :math:`y_0` (which is the spherical version of the Bessel function) but + * :math:`Y_0`. See `WolframAlpha Y_0(x) + * `_ for what it looks like + * and `Wikipedia `_ for more + * information. + * + * Returns + * ======= + * + * ``y0`` returns the Bessel value of :math:`x` of the second kind of order 0. + * + * Exceptions + * ========== + * + * Raise ``invalid operation`` exception when the input value is negative. + * + * Raise ``divide by zero`` exception when the input value is zero. + * + * .. May raise ``underflow`` exception. + * + * Output map + * ========== + * + * +---------------------+--------------+------------------+--------------+--------------+------------------+--------------+--------------+ + * | **x** | :math:`-Inf` | :math:`<0` | :math:`-0` | :math:`+0` | :math:`>0` | :math:`+Inf` | :math:`NaN` | + * +=====================+==============+==================+==============+==============+==================+==============+==============+ + * | **y0(x)** | :math:`qNaN` | :math:`-Inf` | :math:`Y_{0}(x)` | :math:`+0` | :math:`qNaN` | + * +---------------------+--------------+------------------+--------------+--------------+------------------+--------------+--------------+ + * + */ + +#include +#include "internal/besseld.h" +#include "../common/tools.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +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 */ + +double y0(double x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + double z, s, c, ss, cc, u, v; + int32_t hx, ix, lx; + + EXTRACT_WORDS(hx, lx, x); + ix = 0x7fffffff & hx; + + if (ix >= 0x7ff00000) { + if (isnan(x)) { /* y0(NaN) = NaN */ + return x + x; + } else if (hx > 0) { /* y0(+Inf) = +0.0 */ + return zero; + } else { + /* No action required */ + } + } + + if ((ix | lx) == 0) { /* y0(+-0) = +Inf */ + return __raise_div_by_zero(-1.0); + } + + if (hx < 0) { /* y0(<0) = NaN, y0(-Inf) = NaN */ + return __raise_invalid(); + } + + 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) < zero) { + cc = z / ss; + } else { + ss = z / cc; + } + } + + if (ix > 0x48000000) { + z = (invsqrtpi * ss) / sqrt(x); + } else { + u = __j0_p(x); + v = __j0_q(x); + z = invsqrtpi * (u * ss + v * cc) / sqrt(x); + } + + return z; + } + + if (ix <= 0x3e400000) { /* x < 2**-27 */ + return (u00 + tpi * 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 * (j0(x) * log(x))); +} + +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/y1d.c b/libm/libmcs/libm/mathd/y1d.c new file mode 100644 index 00000000..4d95a063 --- /dev/null +++ b/libm/libmcs/libm/mathd/y1d.c @@ -0,0 +1,160 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +/** + * + * This family of functions implements the Bessel function of the second kind + * of order 1. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * double y1(double x); + * + * Description + * =========== + * + * ``y1`` computes the Bessel value of :math:`x` of the second kind of order 1. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * y1(x) = Y_{1}(x) + * + * Notice that the mathematical function represented by the procedure ``y1`` is + * not :math:`y_1` (which is the spherical version of the Bessel function) but + * :math:`Y_1`. See `WolframAlpha Y_1(x) + * `_ for what it looks like + * and `Wikipedia `_ for more + * information. + * + * Returns + * ======= + * + * ``y1`` returns the Bessel value of :math:`x` of the second kind of order 1. + * + * Exceptions + * ========== + * + * Raise ``invalid operation`` exception when the input value is negative. + * + * Raise ``divide by zero`` exception when the input value is zero. + * + * .. May raise ``underflow`` exception. + * + * Output map + * ========== + * + * +---------------------+--------------+------------------+--------------+--------------+------------------+--------------+--------------+ + * | **x** | :math:`-Inf` | :math:`<0` | :math:`-0` | :math:`+0` | :math:`>0` | :math:`+Inf` | :math:`NaN` | + * +=====================+==============+==================+==============+==============+==================+==============+==============+ + * | **y1(x)** | :math:`qNaN` | :math:`-Inf` | :math:`Y_{1}(x)` | :math:`+0` | :math:`qNaN` | + * +---------------------+--------------+------------------+--------------+--------------+------------------+--------------+--------------+ + * + */ + +#include +#include "internal/besseld.h" +#include "../common/tools.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +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 */ +}; + +double y1(double x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + double z, s, c, ss, cc, u, v; + int32_t hx, ix, lx; + + EXTRACT_WORDS(hx, lx, x); + ix = 0x7fffffff & hx; + + if (ix >= 0x7ff00000) { + if (isnan(x)) { /* y1(NaN) = NaN */ + return x + x; + } else if (hx > 0) { /* y1(+Inf) = +0.0 */ + return zero; + } else { + /* No action required */ + } + } + + if ((ix | lx) == 0) { /* y1(+-0) = -Inf */ + return __raise_div_by_zero(-1.0); + } + + if (hx < 0) { /* y1(<0) = NaN, y1(-Inf) = NaN */ + return __raise_invalid(); + } + + 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 = __j1_p(x); + v = __j1_q(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 * (j1(x) * log(x) - one / x)); +} + +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathd/ynd.c b/libm/libmcs/libm/mathd/ynd.c new file mode 100644 index 00000000..1de96656 --- /dev/null +++ b/libm/libmcs/libm/mathd/ynd.c @@ -0,0 +1,182 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +/** + * + * This family of functions implements the Bessel function of the second kind + * of order :math:`n`. + * + * Synopsis + * ======== + * + * .. code-block:: c + * + * #include + * double yn(int n, double x); + * + * Description + * =========== + * + * ``yn`` computes the Bessel value of :math:`x` of the second kind of order + * :math:`n`. + * + * Mathematical Function + * ===================== + * + * .. math:: + * + * yn(n, x) = Y_{n}(x) + * + * Notice that the mathematical function represented by the procedure ``yn`` is + * not :math:`y_n` (which is the spherical version of the Bessel function) but + * :math:`Y_n`. See `Wikipedia + * `_ for more information. + * + * Returns + * ======= + * + * ``yn`` returns the Bessel value of :math:`x` of the second kind of order + * :math:`n`. + * + * Exceptions + * ========== + * + * Raise ``invalid operation`` exception when :math:`x` is negative. + * + * Raise ``divide by zero`` exception when :math:`x` is zero. + * + * .. May raise ``underflow`` exception. + * + * Output map + * ========== + * + * +--------------------------+-------------------------------+-------------------------------+ + * | yn(n,x) | n | + * +--------------------------+-------------------------------+-------------------------------+ + * | x | :math:`<0` | :math:`>0` | + * +==========================+===============================+===============================+ + * | :math:`-Inf` | :math:`qNaN` | + * +--------------------------+ + + * | :math:`<0` | | + * +--------------------------+-------------------------------+-------------------------------+ + * | :math:`-0` | :math:`-Inf` | + * +--------------------------+ + + * | :math:`+0` | | + * +--------------------------+-------------------------------+-------------------------------+ + * | :math:`>0` | :math:`(-1)^n \cdot Y_{n}(x)` | :math:`Y_{n}(x)` | + * +--------------------------+-------------------------------+-------------------------------+ + * | :math:`+Inf` | :math:`+0` | + * +--------------------------+-------------------------------+-------------------------------+ + * | :math:`NaN` | :math:`qNaN` | + * +--------------------------+-------------------------------+-------------------------------+ + * + */ + +#include +#include "internal/besseld.h" +#include "../common/tools.h" + +#ifndef __LIBMCS_DOUBLE_IS_32BITS + +double yn(int n, double x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + 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 (isnan(x)) { /* yn(n,NaN) = NaN */ + return x + x; + } + + if ((ix | lx) == 0) { /* yn(n,+-0) = +Inf */ + return __raise_div_by_zero(-1.0); + } + + if (hx < 0) { /* yn(n,<0) = NaN, y1(n,-Inf) = NaN */ + return __raise_invalid(); + } + + sign = 1; + + if (n < 0) { + n = -n; + sign = 1 - ((n & 1) << 1); + } + + if (n == 0) { + return (y0(x)); + } + + if (n == 1) { + return (sign * y1(x)); + } + + if (ix == 0x7ff00000) { /* yn(n,+Inf) = +0.0 */ + 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) { + default: /* FALLTHRU */ + 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 { + uint32_t high; + a = y0(x); + b = y1(x); + /* quit if b is -inf */ + GET_HIGH_WORD(high, b); + + for (i = 1; i < n && high != 0xfff00000U; i++) { + temp = b; + b = ((double)(i + i) / x) * b - a; + GET_HIGH_WORD(high, b); + a = temp; + } + } + + if (sign > 0) { + return b; + } else { + return -b; + } +} + +#endif /* #ifndef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathf/acosf.c b/libm/libmcs/libm/mathf/acosf.c new file mode 100644 index 00000000..23f61271 --- /dev/null +++ b/libm/libmcs/libm/mathf/acosf.c @@ -0,0 +1,92 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ +/* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ + +#include +#include "../common/tools.h" + +static const float +one = 1.0000000000e+00f, /* 0x3F800000 */ +pi = 3.1415925026e+00f, /* 0x40490fda */ +pio2_hi = 1.5707962513e+00f, /* 0x3fc90fda */ +pio2_lo = 7.5497894159e-08f, /* 0x33a22168 */ +pS0 = 1.6666667163e-01f, /* 0x3e2aaaab */ +pS1 = -3.2556581497e-01f, /* 0xbea6b090 */ +pS2 = 2.0121252537e-01f, /* 0x3e4e0aa8 */ +pS3 = -4.0055535734e-02f, /* 0xbd241146 */ +pS4 = 7.9153501429e-04f, /* 0x3a4f7f04 */ +pS5 = 3.4793309169e-05f, /* 0x3811ef08 */ +qS1 = -2.4033949375e+00f, /* 0xc019d139 */ +qS2 = 2.0209457874e+00f, /* 0x4001572d */ +qS3 = -6.8828397989e-01f, /* 0xbf303361 */ +qS4 = 7.7038154006e-02f; /* 0x3d9dc62e */ + +float acosf(float x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + 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 (hx > 0) { + return 0.0f; /* acos(1) = 0 */ + } else { + return pi + 2.0f * pio2_lo; /* acos(-1)= pi */ + } + } else if (ix > 0x3f800000) { /* |x| >= 1 */ + if (isnan(x)) { + return x + x; + } + + return __raise_invalidf(); /* acos(|x|>1) is NaN */ + } else { + /* No action required */ + } + + if (ix < 0x3f000000) { /* |x| < 0.5 */ + if (ix <= 0x23000000) { + 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.5f; + p = z * (pS0 + z * (pS1 + z * (pS2 + z * (pS3 + z * (pS4 + z * pS5))))); + q = one + z * (qS1 + z * (qS2 + z * (qS3 + z * qS4))); + s = sqrtf(z); + r = p / q; + w = r * s - pio2_lo; + return pi - 2.0f * (s + w); + } else { /* x > 0.5 */ + int32_t idf; + z = (one - x) * 0.5f; + s = sqrtf(z); + df = s; + GET_FLOAT_WORD(idf, df); + SET_FLOAT_WORD(df, idf & 0xfffff000U); + 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.0f * (df + w); + } +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double acos(double x) +{ + return (double) acosf((float) x); +} + +#endif /* #ifdef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathf/acoshf.c b/libm/libmcs/libm/mathf/acoshf.c new file mode 100644 index 00000000..d9b50c40 --- /dev/null +++ b/libm/libmcs/libm/mathf/acoshf.c @@ -0,0 +1,52 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ +/* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ + +#include +#include "../common/tools.h" + +static const float +one = 1.0f, +ln2 = 6.9314718246e-01f; /* 0x3f317218 */ + +float acoshf(float x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + float t; + int32_t hx; + GET_FLOAT_WORD(hx, x); + + if (hx < 0x3f800000) { /* x < 1 */ + if (isnan(x)) { + return x + x; + } else { + return __raise_invalidf(); + } + } else if (hx >= 0x4d800000) { /* x > 2**28 */ + if (!FLT_UWORD_IS_FINITE(hx)) { /* x is +inf or NaN */ + return x + x; + } else { + return logf(x) + ln2; /* acosh(huge)=log(2x) */ + } + } else if (hx == 0x3f800000) { + return 0.0f; /* acosh(1) = 0 */ + } else if (hx > 0x40000000) { /* 2**28 > x > 2 */ + t = x * x; + return logf(2.0f * x - one / (x + sqrtf(t - one))); + } else { /* 1 +#include "../common/tools.h" + +static const float +one = 1.0000000000e+00f, /* 0x3F800000 */ +pio2_hi = 1.57079637050628662109375f, +pio2_lo = -4.37113900018624283e-8f, +pio4_hi = 0.785398185253143310546875f, +/* coefficient for R(x^2) */ +pS0 = 1.6666667163e-01f, /* 0x3e2aaaab */ +pS1 = -3.2556581497e-01f, /* 0xbea6b090 */ +pS2 = 2.0121252537e-01f, /* 0x3e4e0aa8 */ +pS3 = -4.0055535734e-02f, /* 0xbd241146 */ +pS4 = 7.9153501429e-04f, /* 0x3a4f7f04 */ +pS5 = 3.4793309169e-05f, /* 0x3811ef08 */ +qS1 = -2.4033949375e+00f, /* 0xc019d139 */ +qS2 = 2.0209457874e+00f, /* 0x4001572d */ +qS3 = -6.8828397989e-01f, /* 0xbf303361 */ +qS4 = 7.7038154006e-02f; /* 0x3d9dc62e */ + +float asinf(float x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + float t, w, p, q, c, r, s; + int32_t hx, ix; + GET_FLOAT_WORD(hx, x); + ix = hx & 0x7fffffff; + + if (ix == 0x3f800000) { /* asin(1)=+-pi/2 with inexact */ + return x * pio2_hi + x * pio2_lo; + } else if (ix > 0x3f800000) { /* |x|>= 1 */ + if (isnan(x)) { + return x + x; + } + + return __raise_invalidf(); /* asin(|x|>1) is NaN */ + } else if (ix < 0x3f000000) { /* |x|<0.5 */ + if (ix < 0x32000000) { /* if |x| < 2**-27 */ + if (FLT_UWORD_IS_ZERO(ix)) { /* return x inexact except 0 */ + return x; + } else { + return __raise_inexactf(x); + } + } else { + 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; + } + } else { + /* No action required */ + } + + /* 1> |x|>= 0.5 */ + w = one - fabsf(x); + t = w * 0.5f; + p = t * (pS0 + t * (pS1 + t * (pS2 + t * (pS3 + t * (pS4 + t * pS5))))); + q = one + t * (qS1 + t * (qS2 + t * (qS3 + t * qS4))); + s = sqrtf(t); + + if (ix >= 0x3F79999A) { /* if |x| > 0.975 */ + w = p / q; + t = pio2_hi - (2.0f * (s + s * w) - pio2_lo); + } else { + int32_t iw; + w = s; + GET_FLOAT_WORD(iw, w); + SET_FLOAT_WORD(w, iw & 0xfffff000U); + c = (t - w * w) / (s + w); + r = p / q; + p = 2.0f * s * r - (pio2_lo - 2.0f * c); + q = pio4_hi - 2.0f * w; + t = pio4_hi - (p - q); + } + + if (hx > 0) { + return t; + } else { + return -t; + } +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double asin(double x) +{ + return (double) asinf((float) x); +} + +#endif /* #ifdef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathf/asinhf.c b/libm/libmcs/libm/mathf/asinhf.c new file mode 100644 index 00000000..98f18d8f --- /dev/null +++ b/libm/libmcs/libm/mathf/asinhf.c @@ -0,0 +1,59 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ +/* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ + +#include +#include "../common/tools.h" + +static const float +one = 1.0000000000e+00f, /* 0x3F800000 */ +ln2 = 6.9314718246e-01f; /* 0x3f317218 */ + +float asinhf(float x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + float t, w; + int32_t hx, ix; + GET_FLOAT_WORD(hx, x); + ix = hx & 0x7fffffff; + + if (!FLT_UWORD_IS_FINITE(ix)) { + return x + x; /* x is inf or NaN */ + } + + if (ix < 0x31800000) { /* |x|<2**-28 */ + if (FLT_UWORD_IS_ZERO(ix)) { /* return x inexact except 0 */ + return x; + } else { + return __raise_inexactf(x); + } + } + + if (ix > 0x4d800000) { /* |x| > 2**28 */ + w = logf(fabsf(x)) + ln2; + } else if (ix > 0x40000000) { /* 2**28 > |x| > 2.0 */ + t = fabsf(x); + w = logf(2.0f * t + one / (sqrtf(x * x + one) + t)); + } else { /* 2.0 > |x| > 2**-28 */ + t = x * x; + w = log1pf(fabsf(x) + t / (one + sqrtf(one + t))); + } + + if (hx > 0) { + return w; + } else { + return -w; + } +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double asinh(double x) +{ + return (double) asinhf((float) x); +} + +#endif /* #ifdef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathf/atan2f.c b/libm/libmcs/libm/mathf/atan2f.c new file mode 100644 index 00000000..7ef6c7f8 --- /dev/null +++ b/libm/libmcs/libm/mathf/atan2f.c @@ -0,0 +1,136 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ +/* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ + +#include +#include "../common/tools.h" + +static const float +zero = 0.0f, +pi_o_4 = 7.8539818525e-01f, /* 0x3f490fdb */ +pi_o_2 = 1.5707963705e+00f, /* 0x3fc90fdb */ +pi = 3.1415927410e+00f, /* 0x40490fdb */ +pi_lo = -8.7422776573e-08f; /* 0xb3bbbd2e */ + +float atan2f(float y, float x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_onef; + y *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + 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 (FLT_UWORD_IS_NAN(ix) || + FLT_UWORD_IS_NAN(iy)) { /* 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 (FLT_UWORD_IS_ZERO(iy)) { + switch (m) { + default: /* FALLTHRU */ + case 0: /* FALLTHRU */ + case 1: + return y; /* atan(+-0,+anything)=+-0 */ + + case 2: + return __raise_inexactf(pi); /* atan(+0,-anything) = pi */ + + case 3: + return -__raise_inexactf(pi); /* atan(-0,-anything) =-pi */ + } + } + + /* when x = 0 */ + if (FLT_UWORD_IS_ZERO(ix)) { + return (hy < 0) ? -__raise_inexactf(pi_o_2) : __raise_inexactf(pi_o_2); + } + + /* when x is INF */ + if (FLT_UWORD_IS_INFINITE(ix)) { + if (FLT_UWORD_IS_INFINITE(iy)) { + switch (m) { + default: /* FALLTHRU */ + case 0: + return __raise_inexactf(pi_o_4); /* atan(+INF,+INF) */ + + case 1: + return -__raise_inexactf(pi_o_4); /* atan(-INF,+INF) */ + + case 2: + return __raise_inexactf(3.0f * pi_o_4); /*atan(+INF,-INF)*/ + + case 3: + return -__raise_inexactf(3.0f * pi_o_4); /*atan(-INF,-INF)*/ + } + } else { + switch (m) { + default: /* FALLTHRU */ + case 0: + return zero; /* atan(+...,+INF) */ + + case 1: + return -zero; /* atan(-...,+INF) */ + + case 2: + return __raise_inexactf(pi); /* atan(+...,-INF) */ + + case 3: + return -__raise_inexactf(pi); /* atan(-...,-INF) */ + } + } + } + + /* when y is INF */ + if (FLT_UWORD_IS_INFINITE(iy)) { + return (hy < 0) ? -__raise_inexactf(pi_o_2) : __raise_inexactf(pi_o_2); + } + + /* compute y/x */ + k = (iy - ix) >> 23; + + if (k > 26) { + z = __raise_inexactf(pi_o_2); /* |y/x| > 2**26 */ + m &= 1; + } else if (hx < 0 && k < -26) { + z = 0.0f; /* 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(-,-) */ + } +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double atan2(double y, double x) +{ + return (double) atan2f((float) y, (float) x); +} + +#endif /* #ifdef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathf/atanf.c b/libm/libmcs/libm/mathf/atanf.c new file mode 100644 index 00000000..79491127 --- /dev/null +++ b/libm/libmcs/libm/mathf/atanf.c @@ -0,0 +1,116 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ +/* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ + +#include +#include "../common/tools.h" + +static const float atanhi[] = { + 4.6364760399e-01f, /* atan(0.5)hi 0x3eed6338 */ + 7.8539812565e-01f, /* atan(1.0)hi 0x3f490fda */ + 9.8279368877e-01f, /* atan(1.5)hi 0x3f7b985e */ + 1.5707962513e+00f, /* atan(inf)hi 0x3fc90fda */ +}; + +static const float atanlo[] = { + 5.0121582440e-09f, /* atan(0.5)lo 0x31ac3769 */ + 3.7748947079e-08f, /* atan(1.0)lo 0x33222168 */ + 3.4473217170e-08f, /* atan(1.5)lo 0x33140fb4 */ + 7.5497894159e-08f, /* atan(inf)lo 0x33a22168 */ +}; + +static const float aT[] = { + 3.3333334327e-01f, /* 0x3eaaaaaa */ + -2.0000000298e-01f, /* 0xbe4ccccd */ + 1.4285714924e-01f, /* 0x3e124925 */ + -1.1111110449e-01f, /* 0xbde38e38 */ + 9.0908870101e-02f, /* 0x3dba2e6e */ + -7.6918758452e-02f, /* 0xbd9d8795 */ + 6.6610731184e-02f, /* 0x3d886b35 */ + -5.8335702866e-02f, /* 0xbd6ef16b */ + 4.9768779427e-02f, /* 0x3d4bda59 */ + -3.6531571299e-02f, /* 0xbd15a221 */ + 1.6285819933e-02f, /* 0x3c8569d7 */ +}; + +static const float one = 1.0f; + +float atanf(float x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + float w, s1, s2, z; + int32_t ix, hx, id; + + GET_FLOAT_WORD(hx, x); + ix = hx & 0x7fffffff; + + if (ix >= 0x50800000) { /* if |x| >= 2^34 */ + if (FLT_UWORD_IS_NAN(ix)) { + return x + x; /* NaN */ + } + + if (hx > 0) { + return atanhi[3] + atanlo[3]; + } else { + return -atanhi[3] - atanlo[3]; + } + } + + if (ix < 0x3ee00000) { /* |x| < 0.4375 */ + if (ix < 0x31000000) { /* |x| < 2^-29 */ + if (FLT_UWORD_IS_ZERO(ix)) { /* return x inexact except 0 */ + return x; + } else { + return __raise_inexactf(x); + } + } + + id = -1; + } else { + x = fabsf(x); + + if (ix < 0x3f980000) { /* |x| < 1.1875 */ + if (ix < 0x3f300000) { /* 7/16 <=|x|<11/16 */ + id = 0; + x = (2.0f * x - one) / (2.0f + 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 - 1.5f) / (one + 1.5f * x); + } else { /* 2.4375 <= |x| < 2^66 */ + id = 3; + x = -1.0f / 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; + } +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double atan(double x) +{ + return (double) atanf((float) x); +} + +#endif /* #ifdef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathf/atanhf.c b/libm/libmcs/libm/mathf/atanhf.c new file mode 100644 index 00000000..0777d012 --- /dev/null +++ b/libm/libmcs/libm/mathf/atanhf.c @@ -0,0 +1,64 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ +/* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ + +#include +#include "../common/tools.h" + +static const float one = 1.0f; + +float atanhf(float x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + float t; + int32_t hx, ix; + GET_FLOAT_WORD(hx, x); + ix = hx & 0x7fffffff; + + if (ix > 0x3f800000) { /* |x|>1 */ + if (isnan(x)) { + return x + x; + } else { + return __raise_invalidf(); + } + } + + if (ix == 0x3f800000) { + return __raise_div_by_zerof(x); + } + + if (ix < 0x31800000) { /* x<2**-28 */ + if (FLT_UWORD_IS_ZERO(ix)) { /* return x inexact except 0 */ + return x; + } else { + return __raise_inexactf(x); + } + } + + SET_FLOAT_WORD(x, ix); + + if (ix < 0x3f000000) { /* x < 0.5 */ + t = x + x; + t = 0.5f * log1pf(t + t * x / (one - x)); + } else { + t = 0.5f * log1pf((x + x) / (one - x)); + } + + if (hx >= 0) { + return t; + } else { + return -t; + } +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double atanh(double x) +{ + return (double) atanhf((float) x); +} + +#endif /* #ifdef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathf/cbrtf.c b/libm/libmcs/libm/mathf/cbrtf.c new file mode 100644 index 00000000..c6874eb4 --- /dev/null +++ b/libm/libmcs/libm/mathf/cbrtf.c @@ -0,0 +1,76 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ +/* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ + +#include +#include "../common/tools.h" + +/* cbrtf(x) + * Return cube root of x + */ +static const uint32_t +B1 = 709958130, /* B1 = (84+2/3-0.03306235651)*2**23 */ +B2 = 642849266; /* B2 = (76+2/3-0.03306235651)*2**23 */ + +static const float +C = 5.4285717010e-01f, /* 19/35 = 0x3f0af8b0 */ +D = -7.0530611277e-01f, /* -864/1225 = 0xbf348ef1 */ +E = 1.4142856598e+00f, /* 99/70 = 0x3fb50750 */ +F = 1.6071428061e+00f, /* 45/28 = 0x3fcdb6db */ +G = 3.5714286566e-01f; /* 5/14 = 0x3eb6db6e */ + +float cbrtf(float x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + int32_t hx; + float r, s, t; + uint32_t sign; + uint32_t high; + + GET_FLOAT_WORD(hx, x); + sign = hx & 0x80000000U; /* sign= sign(x) */ + hx ^= sign; + + if (!FLT_UWORD_IS_FINITE(hx)) { + return (x + x); /* cbrt(NaN,INF) is itself */ + } + + if (FLT_UWORD_IS_ZERO(hx)) { + return (x); /* cbrt(0) is itself */ + } + + SET_FLOAT_WORD(x, hx); /* x <- |x| */ + + /* rough cbrt to 5 bits */ + if (FLT_UWORD_IS_SUBNORMAL(hx)) { /* subnormal number */ + SET_FLOAT_WORD(t, 0x4b800000); /* set t= 2**24 */ + t *= x; + GET_FLOAT_WORD(high, t); + SET_FLOAT_WORD(t, high / 3 + B2); + } else { + SET_FLOAT_WORD(t, hx / 3 + B1); + } + + + /* new cbrt to 23 bits */ + r = t * t / x; + s = C + r * t; + t *= G + F / (s + E + D / s); + + /* restore the sign bit */ + GET_FLOAT_WORD(high, t); + SET_FLOAT_WORD(t, high | sign); + return (t); +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double cbrt(double x) +{ + return (double) cbrtf((float) x); +} + +#endif /* #ifdef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathf/ceilf.c b/libm/libmcs/libm/mathf/ceilf.c new file mode 100644 index 00000000..998a20e1 --- /dev/null +++ b/libm/libmcs/libm/mathf/ceilf.c @@ -0,0 +1,67 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ +/* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ + +#include +#include "../common/tools.h" + +float ceilf(float x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + int32_t _i0, _j0; + uint32_t i, ix; + GET_FLOAT_WORD(_i0, x); + ix = (_i0 & 0x7fffffff); + _j0 = (ix >> 23) - 0x7f; + + if (_j0 < 23) { + if (_j0 < 0) { /* raise inexact if x != 0 */ + if (FLT_UWORD_IS_ZERO(ix)) { + return x; + } + + (void) __raise_inexactf(x); /* raise inexact flag */ + + if (_i0 < 0) { + _i0 = (int32_t)0x80000000U; + } else { + _i0 = 0x3f800000; + } + } else { + i = (0x007fffff) >> _j0; + + if ((_i0 & i) == 0) { + return x; /* x is integral */ + } + + (void) __raise_inexactf(x); /* raise inexact flag */ + + if (_i0 > 0) { + _i0 += (0x00800000) >> _j0; + } + + _i0 &= (~i); + } + } else { + if (!FLT_UWORD_IS_FINITE(ix)) { + return x + x; /* inf or NaN */ + } else { + return x; /* x is integral */ + } + } + + SET_FLOAT_WORD(x, _i0); + return x; +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double ceil(double x) +{ + return (double) ceilf((float) x); +} + +#endif /* #ifdef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathf/copysignf.c b/libm/libmcs/libm/mathf/copysignf.c new file mode 100644 index 00000000..5f81e35a --- /dev/null +++ b/libm/libmcs/libm/mathf/copysignf.c @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ +/* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ + +/* + * copysignf(float x, float y) + * copysignf(x,y) returns a value with the magnitude of x and + * with the sign bit of y. + */ + +#include +#include "../common/tools.h" + +float copysignf(float x, float y) +{ + uint32_t ix, iy; + GET_FLOAT_WORD(ix, x); + GET_FLOAT_WORD(iy, y); + SET_FLOAT_WORD(x, (ix & 0x7fffffffU) | (iy & 0x80000000U)); + return x; +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double copysign(double x, double y) +{ + return (double) copysignf((float) x, (float) y); +} + +#endif /* #ifdef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathf/cosf.c b/libm/libmcs/libm/mathf/cosf.c new file mode 100644 index 00000000..49b295ed --- /dev/null +++ b/libm/libmcs/libm/mathf/cosf.c @@ -0,0 +1,70 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ +/* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ + +#include +#include "../common/tools.h" +#include "internal/trigf.h" + +float cosf(float x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + float y[2], z = 0.0f; + int32_t n, ix; + + GET_FLOAT_WORD(ix, x); + + /* |x| ~< pi/4 */ + ix &= 0x7fffffff; + + if (ix <= 0x3f490fd8) { + if(ix < 0x39800000) { /* if x < 2**-12 */ + if (x == 0.0f) { /* return 1 inexact except 0 */ + return 1.0f; + } else { + return __raise_inexactf(1.0f); + } + } + return __cosf(x, z); + } + + /* cos(Inf or NaN) is NaN */ + else if (!FLT_UWORD_IS_FINITE(ix)) { + if (isnan(x)) { + return x + x; + } else { + return __raise_invalidf(); + } + } + + /* argument reduction needed */ + else { + n = __rem_pio2f(x, y); + + switch (n & 3) { + case 0: + return __cosf(y[0], y[1]); + + case 1: + return -__sinf(y[0], y[1], 1); + + case 2: + return -__cosf(y[0], y[1]); + + default: + return __sinf(y[0], y[1], 1); + } + } +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double cos(double x) +{ + return (double) cosf((float) x); +} + +#endif /* #ifdef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathf/coshf.c b/libm/libmcs/libm/mathf/coshf.c new file mode 100644 index 00000000..4bafb9c9 --- /dev/null +++ b/libm/libmcs/libm/mathf/coshf.c @@ -0,0 +1,68 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ +/* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ + +#include +#include "../common/tools.h" + +static const float one = 1.0f, half = 0.5f; + +float coshf(float x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + float t, w; + int32_t ix; + + GET_FLOAT_WORD(ix, x); + ix &= 0x7fffffff; + + /* x is INF or NaN */ + if (!FLT_UWORD_IS_FINITE(ix)) { + 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 < 0x24000000) { + 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 < 0x41b00000) { + t = expf(fabsf(x)); + return half * t + half / t; + } + + /* |x| in [22, log(maxfloat)] return half*exp(|x|) */ + if (ix <= FLT_UWORD_LOG_MAX) { + return half * expf(fabsf(x)); + } + + /* |x| in [log(maxfloat), overflowthresold] */ + if (ix <= FLT_UWORD_LOG_2MAX) { + w = expf(half * fabsf(x)); + t = half * w; + return t * w; + } + + /* |x| > overflowthresold, cosh(x) overflow */ + return __raise_overflowf(1.0f); +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double cosh(double x) +{ + return (double) coshf((float) x); +} + +#endif /* #ifdef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathf/erfcf.c b/libm/libmcs/libm/mathf/erfcf.c new file mode 100644 index 00000000..f791ac11 --- /dev/null +++ b/libm/libmcs/libm/mathf/erfcf.c @@ -0,0 +1,106 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ +/* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ + +#include +#include "../common/tools.h" +#include "internal/errorfunctionf.h" + +static const float +half = 5.0000000000e-01f, /* 0x3F000000 */ +two = 2.0000000000e+00f, /* 0x40000000 */ +erx = 8.42697144e-01f; /* 0x3f57bb00 */ + +float erfcf(float x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + int32_t hx, ix; + float R, S, P, Q, s, y, z, r; + GET_FLOAT_WORD(hx, x); + ix = hx & 0x7fffffff; + + if (!FLT_UWORD_IS_FINITE(ix)) { + if (isnan(x)) { /* erfc(nan) = nan */ + return x + x; + } else if (hx > 0) { /* erfc(+inf) = 0 */ + return 0.0f; + } else { /* erfc(-inf) = 2 */ + return two; + } + } + + if (ix < 0x3f580000) { /* |x|<0.84375 */ + if (ix < 0x33800000) { /* |x|<2**-24 */ + return __raise_inexactf(one); + } + + y = __erff_y(x); + + 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 = __erff_P(s); + Q = __erff_Q(s); + + if (hx >= 0) { + z = one - erx; + return z - P / Q; + } else { + z = erx + P / Q; + return one + z; + } + } + + if (ix < 0x41220000) { /* |x|<10.125 */ + x = fabsf(x); + s = one / (x * x); + + if (ix < 0x4036DB6D) { /* |x| < 1/.35 ~ 2.857143*/ + R = __erff_Ra(s); + S = __erff_Sa(s); + } else { /* |x| >= 1/.35 ~ 2.857143 */ + if (hx < 0 && ix >= 0x40c00000) { + return __raise_inexactf(two); /* x < -6 */ + } + + R = __erff_Rb(s); + S = __erff_Sb(s); + } + + GET_FLOAT_WORD(ix, x); + SET_FLOAT_WORD(z, ix & 0xffffc000U); + 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 __raise_underflowf(0.0f); + } else { + return __raise_inexactf(two); + } + } +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double erfc(double x) +{ + return (double) erfcf((float) x); +} + +#endif /* #ifdef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathf/erff.c b/libm/libmcs/libm/mathf/erff.c new file mode 100644 index 00000000..283e34e6 --- /dev/null +++ b/libm/libmcs/libm/mathf/erff.c @@ -0,0 +1,103 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ +/* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ + +#include +#include "../common/tools.h" +#include "internal/errorfunctionf.h" + +static const float +erx = 8.42697144e-01f, /* 0x3f57bb00 */ +/* + * In the domain [0, 2**-14], only the first term in the power series + * expansion of erf(x) is used. The magnitude of the first neglected + * terms is less than 2**-42. + */ +efx = 1.2837916613e-01f, /* 0x3e0375d4 */ +efx8 = 1.0270333290e+00f; /* 0x3f8375d4 */ + +float erff(float x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + int32_t hx, ix; + float R, S, P, Q, s, z, r; + GET_FLOAT_WORD(hx, x); + ix = hx & 0x7fffffff; + + if (!FLT_UWORD_IS_FINITE(ix)) { + if (isnan(x)) { /* erf(nan) = nan */ + return x + x; + } else if (hx > 0) { /* erf(+inf) = +1 */ + return 1.0f; + } else { /* erf(-inf) = -1 */ + return -1.0f; + } + } + + if (ix < 0x3f580000) { /* |x|<0.84375 */ + if (ix < 0x38800000) { /* |x|<2**-14 */ + if (ix < 0x04000000) + /*avoid underflow */ + { + return 0.125f * (8.0f * x + efx8 * x); + } + + return x + efx * x; + } + + return x + x * __erff_y(x); + } + + if (ix < 0x3fa00000) { /* 0.84375 <= |x| < 1.25 */ + s = fabsf(x) - one; + P = __erff_P(s); + Q = __erff_Q(s); + + if (hx >= 0) { + return erx + P / Q; + } else { + return -erx - P / Q; + } + } + + if (ix >= 0x40800000) { /* inf>|x|>=4 */ + if (hx >= 0) { + return __raise_inexactf(one); + } else { + return -__raise_inexactf(one); + } + } + + x = fabsf(x); + s = one / (x * x); + + if (ix < 0x4036DB8C) { /* |x| < 1/0.35 */ + R = __erff_Ra(s); + S = __erff_Sa(s); + } else { /* |x| >= 1/0.35 */ + R = __erff_Rb(s); + S = __erff_Sb(s); + } + + GET_FLOAT_WORD(ix, x); + SET_FLOAT_WORD(z, ix & 0xffffc000U); + 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; + } +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double erf(double x) +{ + return (double) erff((float) x); +} + +#endif /* #ifdef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathf/exp2f.c b/libm/libmcs/libm/mathf/exp2f.c new file mode 100644 index 00000000..a9d77f26 --- /dev/null +++ b/libm/libmcs/libm/mathf/exp2f.c @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ +/* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ + +#include + +float exp2f(float x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + return powf(2.0f, x); +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double exp2(double x) +{ + return (double) exp2f((float) x); +} + +#endif /* #ifdef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathf/expf.c b/libm/libmcs/libm/mathf/expf.c new file mode 100644 index 00000000..419d5757 --- /dev/null +++ b/libm/libmcs/libm/mathf/expf.c @@ -0,0 +1,114 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ +/* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ + +#include +#include "../common/tools.h" + +static const float +one = 1.0f, +zero = 0.0f, +halF[2] = { 0.5f, -0.5f}, +twom100 = 7.8886090522e-31f, /* 2**-100=0x0d800000 */ +ln2HI[2] = { 6.9314575195e-01f, /* 0x3f317200 */ + -6.9314575195e-01f, /* 0xbf317200 */ +}, +ln2LO[2] = { 1.4286067653e-06f, /* 0x35bfbe8e */ + -1.4286067653e-06f, /* 0xb5bfbe8e */ +}, +invln2 = 1.4426950216e+00f, /* 0x3fb8aa3b */ +P1 = 1.6666667163e-01f, /* 0x3e2aaaab */ +P2 = -2.7777778450e-03f, /* 0xbb360b61 */ +P3 = 6.6137559770e-05f, /* 0x388ab355 */ +P4 = -1.6533901999e-06f, /* 0xb5ddea0e */ +P5 = 4.1381369442e-08f; /* 0x3331bb4c */ + +float expf(float x) /* default IEEE float exp */ +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + float y, c, t; + float hi = 0.0; + float lo = 0.0; + int32_t k = 0; + int32_t xsb, sx; + uint32_t hx; + + GET_FLOAT_WORD(sx, x); + xsb = (sx >> 31) & 1; /* sign bit of x */ + hx = sx & 0x7fffffff; /* high word of |x| */ + + /* filter out non-finite argument */ + if (FLT_UWORD_IS_NAN(hx)) { + return x + x; /* NaN */ + } + + if (FLT_UWORD_IS_INFINITE(hx)) { + return (xsb == 0) ? x : zero; + } /* exp(+-inf)={inf,0} */ + + if (sx > FLT_UWORD_LOG_MAX) { + return __raise_overflowf(one); /* overflow */ + } + + if (sx < 0 && hx > FLT_UWORD_LOG_MIN) { + return __raise_underflowf(zero); /* 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]; + } + + x = hi - lo; + } else if (hx < 0x34000000) { /* when |x|<2**-23 */ + if (x == 0.0f) { /* return 1 inexact except 0 */ + return one; + } else { + return __raise_inexactf(one + x); + } + } else { + /* No action required */ + } + + /* x is now in primary range */ + t = x * x; + c = x - t * (P1 + t * (P2 + t * (P3 + t * (P4 + t * P5)))); + + if (k == 0) { + return one - ((x * c) / (c - 2.0f) - x); + } else { + y = one - ((lo - (x * c) / (2.0f - c)) - hi); + } + + if (k >= -125) { + uint32_t hy; + GET_FLOAT_WORD(hy, y); + SET_FLOAT_WORD(y, hy + (((uint32_t)k) << 23)); /* add k to y's exponent */ + return y; + } else { + uint32_t hy; + GET_FLOAT_WORD(hy, y); + SET_FLOAT_WORD(y, hy + (((uint32_t)k + 100U) << 23)); /* add k to y's exponent */ + return y * twom100; + } +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double exp(double x) +{ + return (double) expf((float) x); +} + +#endif /* #ifdef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathf/expm1f.c b/libm/libmcs/libm/mathf/expm1f.c new file mode 100644 index 00000000..3fb9d40f --- /dev/null +++ b/libm/libmcs/libm/mathf/expm1f.c @@ -0,0 +1,148 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ +/* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ + +#include +#include "../common/tools.h" + +static const float +one = 1.0f, +ln2_hi = 6.9313812256e-01f, /* 0x3f317180 */ +ln2_lo = 9.0580006145e-06f, /* 0x3717f7d1 */ +invln2 = 1.4426950216e+00f, /* 0x3fb8aa3b */ +/* scaled coefficients related to expm1 */ +Q1 = -3.3333335072e-02f, /* 0xbd088889 */ +Q2 = 1.5873016091e-03f, /* 0x3ad00d01 */ +Q3 = -7.9365076090e-05f, /* 0xb8a670cd */ +Q4 = 4.0082177293e-06f, /* 0x36867e54 */ +Q5 = -2.0109921195e-07f; /* 0xb457edbb */ + +float expm1f(float x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + float y, hi, lo, c, t, e, hxs, hfx, r1; + int32_t k, xsb; + uint32_t hx; + + c = NAN; /* initial value of c is never actually used */ + + GET_FLOAT_WORD(hx, x); + xsb = hx & 0x80000000U; /* sign bit of x */ + + hx &= 0x7fffffffU; /* high word of |x| */ + + /* filter out huge and non-finite argument */ + if (hx >= 0x4195b844) { /* if |x|>=27*ln2 */ + if (FLT_UWORD_IS_NAN(hx)) { + return x + x; + } + + if (FLT_UWORD_IS_INFINITE(hx)) { + return (xsb == 0) ? x : -one; + }/* exp(+-inf)={inf,-1} */ + + if (xsb == 0 && hx > FLT_UWORD_LOG_MAX) { /* if x>=o_threshold */ + return __raise_overflowf(one); /* overflow */ + } + + if (xsb != 0) { /* x < -27*ln2, return -1.0 with inexact */ + return -__raise_inexactf(one); + } + } + + /* 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) ? 0.5f : -0.5f); + t = k; + hi = x - t * ln2_hi; /* t*ln2_hi is exact here */ + lo = t * ln2_lo; + } + + x = hi - lo; + c = (hi - x) - lo; + } else if (hx < 0x33000000) { /* when |x|<2**-25, return x */ + if (x == 0.0f) { + return x; + } else { /* return x with inexact flags when x!=0 */ + return __raise_inexactf(x); + } + } else { + k = 0; + } + + /* x is now in primary range */ + hfx = 0.5f * x; + hxs = x * hfx; + r1 = one + hxs * (Q1 + hxs * (Q2 + hxs * (Q3 + hxs * (Q4 + hxs * Q5)))); + t = 3.0f - r1 * hfx; + e = hxs * ((r1 - t) / (6.0f - x * t)); + + if (k == 0) { + return x - (x * e - hxs); /* c is 0 */ + } else { + e = (x * (e - c) - c); + e -= hxs; + + if (k == -1) { + return 0.5f * (x - e) - 0.5f; + } + + if (k == 1) { + if (x < -0.25f) { + return -2.0f * (e - (x + 0.5f)); + } else { + return one + 2.0f * (x - e); + } + } + + if (k <= -2 || k > 56) { /* suffice to return exp(x)-1 */ + int32_t i; + y = one - (e - x); + GET_FLOAT_WORD(i, y); + SET_FLOAT_WORD(y, i + (((uint32_t)k) << 23)); /* add k to y's exponent */ + return y - one; + } + + t = one; + + if (k < 23) { + int32_t i; + SET_FLOAT_WORD(t, 0x3f800000 - (0x1000000 >> k)); /* t=1-2^-k */ + y = t - (e - x); + GET_FLOAT_WORD(i, y); + SET_FLOAT_WORD(y, i + (k << 23)); /* add k to y's exponent */ + } else { + int32_t i; + SET_FLOAT_WORD(t, ((0x7f - k) << 23)); /* 2^-k */ + y = x - (e + t); + y += one; + GET_FLOAT_WORD(i, y); + SET_FLOAT_WORD(y, i + (k << 23)); /* add k to y's exponent */ + } + } + + return y; +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double expm1(double x) +{ + return (double) expm1f((float) x); +} + +#endif /* #ifdef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathf/fabsf.c b/libm/libmcs/libm/mathf/fabsf.c new file mode 100644 index 00000000..f60522dd --- /dev/null +++ b/libm/libmcs/libm/mathf/fabsf.c @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ +/* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ + +/* + * fabsf(x) returns the absolute value of x. + */ + +#include +#include "../common/tools.h" + +float fabsf(float x) +{ + uint32_t ix; + GET_FLOAT_WORD(ix, x); + SET_FLOAT_WORD(x, ix & 0x7fffffff); + return x; +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double fabs(double x) +{ + return (double) fabsf((float) x); +} + +#endif /* #ifdef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathf/fdimf.c b/libm/libmcs/libm/mathf/fdimf.c new file mode 100644 index 00000000..04ed1db9 --- /dev/null +++ b/libm/libmcs/libm/mathf/fdimf.c @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: RedHat */ +/* Copyright (C) 2002 by Red Hat, Incorporated. All rights reserved. */ + +#include + +float fdimf(float x, float y) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_onef; + y *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + if (isnan(x) || isnan(y)) { + return x * y; + } + + return x > y ? x - y : 0.0f; +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double fdim(double x, double y) +{ + return (double) fdimf((float) x, (float) y); +} + +#endif /* #ifdef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathf/floorf.c b/libm/libmcs/libm/mathf/floorf.c new file mode 100644 index 00000000..4d5b504f --- /dev/null +++ b/libm/libmcs/libm/mathf/floorf.c @@ -0,0 +1,76 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ +/* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ + +/* + * floorf(x) + * Return x rounded toward -inf to integral value + * Method: + * Bit twiddling. + * Exception: + * Inexact flag raised if x not equal to floorf(x). + */ + +#include +#include "../common/tools.h" + +float floorf(float x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + int32_t _i0, _j0; + uint32_t i, ix; + GET_FLOAT_WORD(_i0, x); + ix = (_i0 & 0x7fffffff); + _j0 = (ix >> 23) - 0x7f; + + if (_j0 < 23) { + if (_j0 < 0) { /* raise inexact if x != 0 */ + if (FLT_UWORD_IS_ZERO(ix)) { + return x; + } + + (void) __raise_inexactf(x); + + if (_i0 >= 0) { + _i0 = 0; + } else { + _i0 = (int32_t)0xbf800000U; + } + } else { + i = (0x007fffff) >> _j0; + + if ((_i0 & i) == 0) { /* x is integral */ + return x; + } + + (void) __raise_inexactf(x); + + if (_i0 < 0) { + _i0 += (0x00800000) >> _j0; + } + + _i0 &= (~i); + } + } else { + if (!FLT_UWORD_IS_FINITE(ix)) { + return x + x; /* inf or NaN */ + } else { + return x; /* x is integral */ + } + } + + SET_FLOAT_WORD(x, _i0); + return x; +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double floor(double x) +{ + return (double) floorf((float) x); +} + +#endif /* #ifdef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathf/fmaf.c b/libm/libmcs/libm/mathf/fmaf.c new file mode 100644 index 00000000..c03bd315 --- /dev/null +++ b/libm/libmcs/libm/mathf/fmaf.c @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GTDGmbH */ +/* Copyright 2020-2025 by GTD GmbH. */ + +#include + +float fmaf(float x, float y, float z) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_onef; + y *= __volatile_onef; + z *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + return x * y + z; +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double fma(double x, double y, double z) +{ + return (double) fmaf((float) x, (float) y, (float) z); +} + +#endif /* #ifdef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathf/fmaxf.c b/libm/libmcs/libm/mathf/fmaxf.c new file mode 100644 index 00000000..73facf17 --- /dev/null +++ b/libm/libmcs/libm/mathf/fmaxf.c @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: RedHat */ +/* Copyright (C) 2002 by Red Hat, Incorporated. All rights reserved. */ + +#include +#include "../common/tools.h" + +float fmaxf(float x, float y) +{ + if (isnan(x)) { + if (__issignalingf(x) != 0 || __issignalingf(y) != 0) { + return x * y; + } +#ifdef __LIBMCS_FPU_DAZ + y *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + return y; + } + + if (isnan(y)) { + if (__issignalingf(y) != 0) { + return x * y; + } +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + return x; + } + +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_onef; + y *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + return x > y ? x : y; +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double fmax(double x, double y) +{ + return (double) fmaxf((float) x, (float) y); +} + +#endif /* #ifdef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathf/fminf.c b/libm/libmcs/libm/mathf/fminf.c new file mode 100644 index 00000000..98aa5b2f --- /dev/null +++ b/libm/libmcs/libm/mathf/fminf.c @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: RedHat */ +/* Copyright (C) 2002 by Red Hat, Incorporated. All rights reserved. */ + +#include +#include "../common/tools.h" + +float fminf(float x, float y) +{ + if (isnan(x)) { + if (__issignalingf(x) != 0 || __issignalingf(y) != 0) { + return x * y; + } +#ifdef __LIBMCS_FPU_DAZ + y *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + return y; + } + + if (isnan(y)) { + if (__issignalingf(y) != 0) { + return x * y; + } +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + return x; + } + +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_onef; + y *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + return x < y ? x : y; +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double fmin(double x, double y) +{ + return (double) fminf((float) x, (float) y); +} + +#endif /* #ifdef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathf/fmodf.c b/libm/libmcs/libm/mathf/fmodf.c new file mode 100644 index 00000000..22ba3bd1 --- /dev/null +++ b/libm/libmcs/libm/mathf/fmodf.c @@ -0,0 +1,144 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ +/* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ + +/* + * fmodf(x,y) + * Return x mod y in exact arithmetic + * Method: shift and subtract + */ + +#include +#include "../common/tools.h" + +static const float Zero[] = {0.0f, -0.0f,}; + +float fmodf(float x, float y) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_onef; + y *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + int32_t n, hx, hy, hz, ix, iy, sx, i; + + GET_FLOAT_WORD(hx, x); + GET_FLOAT_WORD(hy, y); + sx = hx & 0x80000000U; /* sign of x */ + hx ^= sx; /* |x| */ + hy &= 0x7fffffff; /* |y| */ + + /* purge off exception values */ + if (!FLT_UWORD_IS_FINITE(hx) || !FLT_UWORD_IS_FINITE(hy)) { /* x or y is +-Inf/NaN */ + if (FLT_UWORD_IS_INFINITE(hx)) { /* x is +-Inf */ + return __raise_invalidf(); + } else if (FLT_UWORD_IS_NAN(hx) || FLT_UWORD_IS_NAN(hy)) { /* x or y is NaN */ + return x + y; + } else { + /* No action required */ + } + } else if (FLT_UWORD_IS_ZERO(hy)) { /* y is +-0 */ + return __raise_invalidf(); + } else { + /* No action required */ + } + + if (hx < hy) { + return x; /* |x|<|y| return x */ + } + + if (hx == hy) { + return Zero[(uint32_t)sx >> 31]; /* |x|=|y| return x*0*/ + } + + /* Note: y cannot be zero if we reach here. */ + + /* determine ix = ilogb(x) */ + if (FLT_UWORD_IS_SUBNORMAL(hx)) { /* subnormal x */ + for (ix = -126, i = (hx << 8); i > 0; i <<= 1) { + ix -= 1; + } + } else { + ix = (hx >> 23) - 127; + } + + /* determine iy = ilogb(y) */ + if (FLT_UWORD_IS_SUBNORMAL(hy)) { /* 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 << n; + } + + if (iy >= -126) { + hy = 0x00800000 | (0x007fffff & hy); + } else { /* subnormal y, shift y to normal */ + n = -126 - iy; + hy = hy << n; + } + + /* fix point fmod */ + n = ix - iy; + + while (n-- > 0) { + hz = hx - hy; + + if (hz < 0) { + hx = hx + hx; + } else { + if (hz == 0) { /* return sign(x)*0 */ + return Zero[(uint32_t)sx >> 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[(uint32_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); +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + } + + return x; /* exact output */ +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double fmod(double x, double y) +{ + return (double) fmodf((float) x, (float) y); +} + +#endif /* #ifdef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathf/frexpf.c b/libm/libmcs/libm/mathf/frexpf.c new file mode 100644 index 00000000..bfec0dea --- /dev/null +++ b/libm/libmcs/libm/mathf/frexpf.c @@ -0,0 +1,54 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ +/* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ + +#include +#include +#include "../common/tools.h" + +static const float +two25 = 3.3554432000e+07f; /* 0x4c000000 */ + +float frexpf(float x, int *eptr) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + int _xexp = 0; + int32_t hx, ix; + + assert(eptr != (void*)0); + if(eptr == (void*)0) { + eptr = &_xexp; + } + + GET_FLOAT_WORD(hx, x); + ix = 0x7fffffff & hx; + *eptr = 0; + + if (!FLT_UWORD_IS_FINITE(ix) || FLT_UWORD_IS_ZERO(ix)) { + return x + x; /* 0,inf,nan */ + } + + if (FLT_UWORD_IS_SUBNORMAL(ix)) { /* subnormal */ + x *= two25; + GET_FLOAT_WORD(hx, x); + ix = hx & 0x7fffffff; + *eptr = -25; + } + + *eptr += (ix >> 23) - 126; + hx = (hx & 0x807fffffU) | 0x3f000000U; + SET_FLOAT_WORD(x, hx); + return x; +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double frexp(double x, int *eptr) +{ + return (double) frexpf((float) x, eptr); +} + +#endif /* #ifdef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathf/hypotf.c b/libm/libmcs/libm/mathf/hypotf.c new file mode 100644 index 00000000..91f0c351 --- /dev/null +++ b/libm/libmcs/libm/mathf/hypotf.c @@ -0,0 +1,113 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ +/* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ + +#include +#include "../common/tools.h" + +float hypotf(float x, float y) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_onef; + y *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + float a = x; + float b = y; + float t1, t2; + float _y1, _y2; + float w; + int32_t j, k, ha, hb; + + GET_FLOAT_WORD(ha, x); + ha &= 0x7fffffff; + GET_FLOAT_WORD(hb, y); + hb &= 0x7fffffff; + + if (hb > ha) { + j = ha; + ha = hb; + hb = j; + } + + SET_FLOAT_WORD(a, ha); /* a <- |a| */ + SET_FLOAT_WORD(b, hb); /* b <- |b| */ + + if ((ha - hb) > 0xf000000) { + return a + b; /* x/y > 2**30 */ + } + + k = 0; + + if (ha > 0x58800000) { /* a>2**50 */ + if (!FLT_UWORD_IS_FINITE(ha)) { /* Inf or NaN */ + w = a + b; /* for sNaN */ + + if (FLT_UWORD_IS_INFINITE(ha)) { + w = a; + } + + if (FLT_UWORD_IS_INFINITE(hb)) { + 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 (FLT_UWORD_IS_ZERO(hb)) { + return a; + } else if (FLT_UWORD_IS_SUBNORMAL(hb)) { + SET_FLOAT_WORD(t1, 0x7e800000); /* t1=2^126 */ + b *= t1; + a *= t1; + k -= 126; + } else { /* scale a and b by 2^80 */ + ha += 0x28000000; /* a *= 2^80 */ + hb += 0x28000000; /* b *= 2^80 */ + k -= 80; + 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 & 0xfffff000U); + t2 = a - t1; + w = sqrtf(t1 * t1 - (b * (-b) - t2 * (a + t1))); + } else { + a = a + a; + SET_FLOAT_WORD(_y1, hb & 0xfffff000U); + _y2 = b - _y1; + SET_FLOAT_WORD(t1, (ha + 0x00800000) & 0xfffff000U); + t2 = a - t1; + w = sqrtf(t1 * _y1 - (w * (-w) - (t1 * _y2 + t2 * b))); + } + + if (k != 0) { + SET_FLOAT_WORD(t1, (0x7F + k) << 23); + return t1 * w; + } else { + return w; + } +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double hypot(double x, double y) +{ + return (double) hypotf((float) x, (float) y); +} + +#endif /* #ifdef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathf/ilogbf.c b/libm/libmcs/libm/mathf/ilogbf.c new file mode 100644 index 00000000..23ad7b76 --- /dev/null +++ b/libm/libmcs/libm/mathf/ilogbf.c @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ +/* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ + +#include +#include "../common/tools.h" + +int ilogbf(float x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + int32_t hx, ix; + + GET_FLOAT_WORD(hx, x); + hx &= 0x7fffffff; + + if (FLT_UWORD_IS_ZERO(hx)) { + (void) __raise_invalidf(); + return FP_ILOGB0; /* ilogb(0) = special case error */ + } else if (FLT_UWORD_IS_SUBNORMAL(hx)) { + for (ix = -126, hx <<= 8; hx > 0; hx <<= 1) { + ix -= 1; + } + + return ix; + } else if (FLT_UWORD_IS_FINITE(hx)) { + return (hx >> 23) - 127; + } else if (FLT_UWORD_IS_NAN(hx)) { + (void) __raise_invalidf(); + return FP_ILOGBNAN; /* NAN */ + } else { + (void) __raise_invalidf(); + return INT_MAX; /* infinite */ + } +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +int ilogb(double x) +{ + return ilogbf((float) x); +} + +#endif /* #ifdef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathf/internal/errorfunctionf.h b/libm/libmcs/libm/mathf/internal/errorfunctionf.h new file mode 100644 index 00000000..98a2d5fe --- /dev/null +++ b/libm/libmcs/libm/mathf/internal/errorfunctionf.h @@ -0,0 +1,95 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ +/* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ + +#ifndef LIBMCS_ERRORFUNCTIONF_H +#define LIBMCS_ERRORFUNCTIONF_H + +#include +#include "../../common/tools.h" + +static const float +one = 1.00000000e+00f, /* 0x3F800000 */ +/* + * Domain [0, 0.84375], range ~[-5.4419e-10, 5.5179e-10]: + * |(erf(x) - x)/x - pp(x)/qq(x)| < 2**-31 + */ +pp0 = 1.28379166e-01f, /* 0x3e0375d4 */ +pp1 = -3.36030394e-01f, /* 0xbeac0c2d */ +pp2 = -1.86261395e-03f, /* 0xbaf422f4 */ +qq1 = 3.12324315e-01f, /* 0x3e9fe8f9 */ +qq2 = 2.16070414e-02f, /* 0x3cb10140 */ +qq3 = -1.98859372e-03f, /* 0xbb025311 */ +/* + * Domain [0.84375, 1.25], range ~[-1.023e-9, 1.023e-9]: + * |(erf(x) - erx) - pa(x)/qa(x)| < 2**-31 + */ +pa0 = 3.65041046e-06f, /* 0x3674f993 */ +pa1 = 4.15109307e-01f, /* 0x3ed48935 */ +pa2 = -2.09395722e-01f, /* 0xbe566bd5 */ +pa3 = 8.67677554e-02f, /* 0x3db1b34b */ +qa1 = 4.95560974e-01f, /* 0x3efdba2b */ +qa2 = 3.71248513e-01f, /* 0x3ebe1449 */ +qa3 = 3.92478965e-02f, /* 0x3d20c267 */ +/* + * Domain [1.25,1/0.35], range ~[-4.821e-9, 4.927e-9]: + * |log(x*erfc(x)) + x**2 + 0.5625 - ra(x)/sa(x)| < 2**-28 + */ +ra0 = -9.88156721e-03f, /* 0xbc21e64c */ +ra1 = -5.43658376e-01f, /* 0xbf0b2d32 */ +ra2 = -1.66828310e+00f, /* 0xbfd58a4d */ +ra3 = -6.91554189e-01f, /* 0xbf3109b2 */ +sa1 = 4.48581553e+00f, /* 0x408f8bcd */ +sa2 = 4.10799170e+00f, /* 0x408374ab */ +sa3 = 5.53855181e-01f, /* 0x3f0dc974 */ +/* + * Domain [2.85715, 11], range ~[-1.484e-9, 1.505e-9]: + * |log(x*erfc(x)) + x**2 + 0.5625 - rb(x)/sb(x)| < 2**-30 + */ +rb0 = -9.86496918e-03f, /* 0xbc21a0ae */ +rb1 = -5.48049808e-01f, /* 0xbf0c4cfe */ +rb2 = -1.84115684e+00f, /* 0xbfebab07 */ +sb1 = 4.87132740e+00f, /* 0x409be1ea */ +sb2 = 3.04982710e+00f, /* 0x4043305e */ +sb3 = -7.61900663e-01f; /* 0xbf430bec */ + +static inline float __erff_y(float x) +{ + float s, z, r; + z = x * x; + r = pp0 + z * (pp1 + z * pp2); + s = one + z * (qq1 + z * (qq2 + z * qq3)); + return r / s; +} + +static inline float __erff_P(float s) +{ + return pa0 + s * (pa1 + s * (pa2 + s * pa3)); +} + +static inline float __erff_Q(float s) +{ + return one + s * (qa1 + s * (qa2 + s * qa3)); +} + +static inline float __erff_Ra(float s) +{ + return ra0 + s * (ra1 + s * (ra2 + s * ra3)); +} + +static inline float __erff_Sa(float s) +{ + return one + s * (sa1 + s * (sa2 + s * sa3)); +} + +static inline float __erff_Rb(float s) +{ + return rb0 + s * (rb1 + s * rb2); +} + +static inline float __erff_Sb(float s) +{ + return one + s * (sb1 + s * (sb2 + s * sb3)); +} + +#endif /* !LIBMCS_ERRORFUNCTIONF_H */ diff --git a/libm/libmcs/libm/mathf/internal/fpclassifyf.c b/libm/libmcs/libm/mathf/internal/fpclassifyf.c new file mode 100644 index 00000000..cfa4d285 --- /dev/null +++ b/libm/libmcs/libm/mathf/internal/fpclassifyf.c @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: RedHat */ +/* Copyright (C) 2002,2007 by Red Hat, Incorporated. All rights reserved. */ + +#include +#include "../../common/tools.h" + +int __fpclassifyf(float x) +{ + uint32_t w; + + GET_FLOAT_WORD(w, x); + w &= 0x7fffffffU; + + if (w == 0x00000000U) { + return FP_ZERO; + } else if (w >= 0x00800000U && w <= 0x7f7fffffU) { + return FP_NORMAL; + } else if (w <= 0x007fffffU) { + return FP_SUBNORMAL; + } else if (w == 0x7f800000U) { + return FP_INFINITE; + } else { + return FP_NAN; + } +} + diff --git a/libm/libmcs/libm/mathf/internal/gammaf.c b/libm/libmcs/libm/mathf/internal/gammaf.c new file mode 100644 index 00000000..b84b02f3 --- /dev/null +++ b/libm/libmcs/libm/mathf/internal/gammaf.c @@ -0,0 +1,298 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ +/* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ + +#include "../../common/tools.h" +#include "gammaf.h" +#include "trigf.h" + +static const float +two23 = 8.3886080000e+06f, /* 0x4b000000 */ +half = 5.0000000000e-01f, /* 0x3f000000 */ +one = 1.0000000000e+00f, /* 0x3f800000 */ +pi = 3.1415927410e+00f, /* 0x40490fdb */ +a0 = 7.7215664089e-02f, /* 0x3d9e233f */ +a1 = 3.2246702909e-01f, /* 0x3ea51a66 */ +a2 = 6.7352302372e-02f, /* 0x3d89f001 */ +a3 = 2.0580807701e-02f, /* 0x3ca89915 */ +a4 = 7.3855509982e-03f, /* 0x3bf2027e */ +a5 = 2.8905137442e-03f, /* 0x3b3d6ec6 */ +a6 = 1.1927076848e-03f, /* 0x3a9c54a1 */ +a7 = 5.1006977446e-04f, /* 0x3a05b634 */ +a8 = 2.2086278477e-04f, /* 0x39679767 */ +a9 = 1.0801156895e-04f, /* 0x38e28445 */ +a10 = 2.5214456400e-05f, /* 0x37d383a2 */ +a11 = 4.4864096708e-05f, /* 0x383c2c75 */ +tc = 1.4616321325e+00f, /* 0x3fbb16c3 */ +tf = -1.2148628384e-01f, /* 0xbdf8cdcd */ +/* tt = -(tail of tf) */ +tt = 6.6971006518e-09f, /* 0x31e61c52 */ +t0 = 4.8383611441e-01f, /* 0x3ef7b95e */ +t1 = -1.4758771658e-01f, /* 0xbe17213c */ +t2 = 6.4624942839e-02f, /* 0x3d845a15 */ +t3 = -3.2788541168e-02f, /* 0xbd064d47 */ +t4 = 1.7970675603e-02f, /* 0x3c93373d */ +t5 = -1.0314224288e-02f, /* 0xbc28fcfe */ +t6 = 6.1005386524e-03f, /* 0x3bc7e707 */ +t7 = -3.6845202558e-03f, /* 0xbb7177fe */ +t8 = 2.2596477065e-03f, /* 0x3b141699 */ +t9 = -1.4034647029e-03f, /* 0xbab7f476 */ +t10 = 8.8108185446e-04f, /* 0x3a66f867 */ +t11 = -5.3859531181e-04f, /* 0xba0d3085 */ +t12 = 3.1563205994e-04f, /* 0x39a57b6b */ +t13 = -3.1275415677e-04f, /* 0xb9a3f927 */ +t14 = 3.3552918467e-04f, /* 0x39afe9f7 */ +u0 = -7.7215664089e-02f, /* 0xbd9e233f */ +u1 = 6.3282704353e-01f, /* 0x3f2200f4 */ +u2 = 1.4549225569e+00f, /* 0x3fba3ae7 */ +u3 = 9.7771751881e-01f, /* 0x3f7a4bb2 */ +u4 = 2.2896373272e-01f, /* 0x3e6a7578 */ +u5 = 1.3381091878e-02f, /* 0x3c5b3c5e */ +v1 = 2.4559779167e+00f, /* 0x401d2ebe */ +v2 = 2.1284897327e+00f, /* 0x4008392d */ +v3 = 7.6928514242e-01f, /* 0x3f44efdf */ +v4 = 1.0422264785e-01f, /* 0x3dd572af */ +v5 = 3.2170924824e-03f, /* 0x3b52d5db */ +s0 = -7.7215664089e-02f, /* 0xbd9e233f */ +s1 = 2.1498242021e-01f, /* 0x3e5c245a */ +s2 = 3.2577878237e-01f, /* 0x3ea6cc7a */ +s3 = 1.4635047317e-01f, /* 0x3e15dce6 */ +s4 = 2.6642270386e-02f, /* 0x3cda40e4 */ +s5 = 1.8402845599e-03f, /* 0x3af135b4 */ +s6 = 3.1947532989e-05f, /* 0x3805ff67 */ +r1 = 1.3920053244e+00f, /* 0x3fb22d3b */ +r2 = 7.2193557024e-01f, /* 0x3f38d0c5 */ +r3 = 1.7193385959e-01f, /* 0x3e300f6e */ +r4 = 1.8645919859e-02f, /* 0x3c98bf54 */ +r5 = 7.7794247773e-04f, /* 0x3a4beed6 */ +r6 = 7.3266842264e-06f, /* 0x36f5d7bd */ +w0 = 4.1893854737e-01f, /* 0x3ed67f1d */ +w1 = 8.3333335817e-02f, /* 0x3daaaaab */ +w2 = -2.7777778450e-03f, /* 0xbb360b61 */ +w3 = 7.9365057172e-04f, /* 0x3a500cfd */ +w4 = -5.9518753551e-04f, /* 0xba1c065c */ +w5 = 8.3633989561e-04f, /* 0x3a5b3dd2 */ +w6 = -1.6309292987e-03f; /* 0xbad5c4e8 */ + +static const float zero = 0.0000000000e+00f; + +static float __sin_pif(float x) +{ + float y, z; + int32_t n, ix; + + GET_FLOAT_WORD(ix, x); + ix &= 0x7fffffff; + + if (ix < 0x3e800000) { + return __sinf(pi * x, zero, 0); + } + + 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 *= 0.5f; + y = 2.0f * (y - floorf(y)); /* y = |x| mod 2.0 */ + n = (int32_t)(y * 4.0f); + } else { + z = y + two23; /* exact */ + + GET_FLOAT_WORD(n, z); + n &= 1; + y = n; + n <<= 2; + } + + switch (n) { + case 0: + y = __sinf(pi * y, zero, 0); + break; + + case 1: /* FALLTHRU */ + case 2: + y = __cosf(pi * (0.5f - y), zero); + break; + + case 3: /* FALLTHRU */ + case 4: + y = __sinf(pi * (one - y), zero, 0); + break; + + case 5: /* FALLTHRU */ + case 6: + y = -__cosf(pi * (y - 1.5f), zero); + break; + + default: + y = __sinf(pi * (y - 2.0f), zero, 0); + break; + } + + return -y; +} + +float __lgammaf(float x, int *signgamp) +{ + float t, y, z, nadj = 0.0f, p, p1, p2, p3, q, r, w; + int32_t i, hx, ix; + + GET_FLOAT_WORD(hx, x); + + /* purge off +-inf, NaN, +-0, and negative arguments */ + *signgamp = 1; + ix = hx & 0x7fffffff; + + if (ix >= 0x7f800000) { + return x * x; + } + + if (ix == 0) { + if(hx < 0) { + *signgamp = -1; + } + return __raise_div_by_zerof(zero); + } + + if (ix < 0x30800000) { /* |x|<2**-30, return -log(|x|) */ + if (hx < 0) { + *signgamp = -1; + return -logf(-x); + } else { + return -logf(x); + } + } + + if (hx < 0) { + if (ix >= 0x4b000000) { /* |x|>=2**23, must be -integer */ + return __raise_div_by_zerof(zero); + } + + t = __sin_pif(x); + + if (t == zero) { + return __raise_div_by_zerof(zero); /* -integer */ + } + + nadj = logf(pi / fabsf(t * x)); + + if (t < zero) { + *signgamp = -1; + } + + x = -x; + } + + /* purge off 1 and 2 */ + if (ix == 0x3f800000 || ix == 0x40000000) { + r = 0; + } + /* for x < 2.0 */ + else if (ix < 0x40000000) { + if (ix <= 0x3f666666) { /* lgamma(x) = lgamma(x+1)-log(x) */ + r = -logf(x); + + if (ix >= 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 = 2.0f - x; /* [1.7316,2] */ + i = 0; + } else if (ix >= 0x3F9da620) { + y = x - tc; /* [1.23,1.73] */ + i = 1; + } else { + y = x - one; + i = 2; + } + } + + switch (i) { + default: /* FALLTHRU */ + 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.5f * 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.5f * y + p1 / p2); + break; + } + } else if (ix < 0x41000000) { /* x < 8.0 */ + i = (int32_t)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 + 6.0f); /* FALLTHRU */ + + case 6: + z *= (y + 5.0f); /* FALLTHRU */ + + case 5: + z *= (y + 4.0f); /* FALLTHRU */ + + case 4: + z *= (y + 3.0f); /* FALLTHRU */ + + case 3: + z *= (y + 2.0f); /* FALLTHRU */ + + default: + r += logf(z); + break; + } + + /* 8.0 <= x < 2**58 */ + } else if (ix < 0x5c800000) { + t = 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 * (logf(x) - one); + } + + if (hx < 0) { + r = nadj - r; + } + + return r; +} diff --git a/libm/libmcs/libm/mathf/internal/gammaf.h b/libm/libmcs/libm/mathf/internal/gammaf.h new file mode 100644 index 00000000..46d624fc --- /dev/null +++ b/libm/libmcs/libm/mathf/internal/gammaf.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GTDGmbH */ +/* Copyright 2020-2025 by GTD GmbH. */ + +#ifndef LIBMCS_GAMMAF_H +#define LIBMCS_GAMMAF_H + +extern float __lgammaf(float x, int *signgamp); + +#endif /* !LIBMCS_GAMMAF_H */ diff --git a/libm/libmcs/libm/mathf/internal/log1pmff.h b/libm/libmcs/libm/mathf/internal/log1pmff.h new file mode 100644 index 00000000..4a40a488 --- /dev/null +++ b/libm/libmcs/libm/mathf/internal/log1pmff.h @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +#ifndef LIBMCS_LOG1PMFF_H +#define LIBMCS_LOG1PMFF_H + +static const float +/* |(log(1+s)-log(1-s))/s - Lg(s)| < 2**-34.24 (~[-4.95e-11, 4.97e-11]). */ +Lg1 = 0xaaaaaa.0p-24f, /* 0.66666662693, 0x3F2AAAAA */ +Lg2 = 0xccce13.0p-25f, /* 0.40000972152, 0x3ECCCE13 */ +Lg3 = 0x91e9ee.0p-25f, /* 0.28498786688, 0x3E91E9EE */ +Lg4 = 0xf89e26.0p-26f; /* 0.24279078841, 0x3E789E26 */ + +static inline float __log1pmff(float f) +{ + float hfsq, s, z, R, w, t1, t2; + + s = f / (2.0f + f); + z = s * s; + w = z * z; + t1 = w * (Lg2 + w * Lg4); + t2 = z * (Lg1 + w * Lg3); + R = t2 + t1; + hfsq = 0.5f * f * f; + return s * (hfsq + R); +} + +#endif /* !LIBMCS_LOG1PMFF_H */ diff --git a/libm/libmcs/libm/mathf/internal/signbitf.c b/libm/libmcs/libm/mathf/internal/signbitf.c new file mode 100644 index 00000000..7e98236d --- /dev/null +++ b/libm/libmcs/libm/mathf/internal/signbitf.c @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: RedHat */ +/* Copyright (C) 2002 by Red Hat, Incorporated. All rights reserved. */ + +/* +FUNCTION +<>---Does floating-point number have negative sign? + +INDEX + signbit + +SYNOPSIS + #include + int signbit(real-floating <[x]>); + +DESCRIPTION +The <> macro determines whether the sign of its argument value is +negative. The macro reports the sign of all values, including infinities, +zeros, and NaNs. If zero is unsigned, it is treated as positive. As shown in +the synopsis, the argument is "real-floating," meaning that any of the real +floating-point types (float, double, etc.) may be given to it. + +Note that because of the possibilities of signed 0 and NaNs, the expression +"<[x]> < 0.0" does not give the same result as <> in all cases. + +RETURNS +The <> macro returns a nonzero value if and only if the sign of its +argument value is negative. + +PORTABILITY +C99, POSIX. + +*/ + +#include +#include "../../common/tools.h" + +int __signbitf(float x) +{ + uint32_t w; + + GET_FLOAT_WORD(w, x); + + return (w & 0x80000000U) != 0; +} diff --git a/libm/libmcs/libm/mathf/internal/trigf.c b/libm/libmcs/libm/mathf/internal/trigf.c new file mode 100644 index 00000000..ad8fdca0 --- /dev/null +++ b/libm/libmcs/libm/mathf/internal/trigf.c @@ -0,0 +1,502 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ +/* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ + +#include +#include "../../common/tools.h" +#include "trigf.h" + +/* In the float version, the input parameter x contains 8 bit + integers, not 24 bit integers. 113 bit precision is not supported. */ + +/* + * 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. + */ + +/* + * Single precision array, obtained by cutting pi/2 + * into 8 bits chunks. + */ +static const float PIo2[] = { + 1.5703125000e+00f, /* 0x3fc90000 */ + 4.5776367188e-04f, /* 0x39f00000 */ + 2.5987625122e-05f, /* 0x37da0000 */ + 7.5437128544e-08f, /* 0x33a20000 */ + 6.0026650317e-11f, /* 0x2e840000 */ + 7.3896444519e-13f, /* 0x2b500000 */ + 5.3845816694e-15f, /* 0x27c20000 */ + 5.6378512969e-18f, /* 0x22d00000 */ + 8.3009228831e-20f, /* 0x1fc40000 */ + 3.2756352257e-22f, /* 0x1bc60000 */ + 6.3331015649e-25f, /* 0x17440000 */ +}; + +/* + * Table of constants for 2/pi, 396 Hex digits (476 decimal) of 2/pi + * + * The integer array contains the (8*i)-th to (8*i+7)-th + * bit of 2/pi after binary point. The corresponding + * floating value is + * + * ipio2[i] * 2^(-8(i+1)). + */ +static const int32_t ipio2[] = { + 0xA2, 0xF9, 0x83, 0x6E, 0x4E, 0x44, 0x15, 0x29, 0xFC, + 0x27, 0x57, 0xD1, 0xF5, 0x34, 0xDD, 0xC0, 0xDB, 0x62, + 0x95, 0x99, 0x3C, 0x43, 0x90, 0x41, 0xFE, 0x51, 0x63, + 0xAB, 0xDE, 0xBB, 0xC5, 0x61, 0xB7, 0x24, 0x6E, 0x3A, + 0x42, 0x4D, 0xD2, 0xE0, 0x06, 0x49, 0x2E, 0xEA, 0x09, + 0xD1, 0x92, 0x1C, 0xFE, 0x1D, 0xEB, 0x1C, 0xB1, 0x29, + 0xA7, 0x3E, 0xE8, 0x82, 0x35, 0xF5, 0x2E, 0xBB, 0x44, + 0x84, 0xE9, 0x9C, 0x70, 0x26, 0xB4, 0x5F, 0x7E, 0x41, + 0x39, 0x91, 0xD6, 0x39, 0x83, 0x53, 0x39, 0xF4, 0x9C, + 0x84, 0x5F, 0x8B, 0xBD, 0xF9, 0x28, 0x3B, 0x1F, 0xF8, + 0x97, 0xFF, 0xDE, 0x05, 0x98, 0x0F, 0xEF, 0x2F, 0x11, + 0x8B, 0x5A, 0x0A, 0x6D, 0x1F, 0x6D, 0x36, 0x7E, 0xCF, + 0x27, 0xCB, 0x09, 0xB7, 0x4F, 0x46, 0x3F, 0x66, 0x9E, + 0x5F, 0xEA, 0x2D, 0x75, 0x27, 0xBA, 0xC7, 0xEB, 0xE5, + 0xF1, 0x7B, 0x3D, 0x07, 0x39, 0xF7, 0x8A, 0x52, 0x92, + 0xEA, 0x6B, 0xFB, 0x5F, 0xB1, 0x1F, 0x8D, 0x5D, 0x08, + 0x56, 0x03, 0x30, 0x46, 0xFC, 0x7B, 0x6B, 0xAB, 0xF0, + 0xCF, 0xBC, 0x20, 0x9A, 0xF4, 0x36, 0x1D, 0xA9, 0xE3, + 0x91, 0x61, 0x5E, 0xE6, 0x1B, 0x08, 0x65, 0x99, 0x85, + 0x5F, 0x14, 0xA0, 0x68, 0x40, 0x8D, 0xFF, 0xD8, 0x80, + 0x4D, 0x73, 0x27, 0x31, 0x06, 0x06, 0x15, 0x56, 0xCA, + 0x73, 0xA8, 0xC9, 0x60, 0xE2, 0x7B, 0xC0, 0x8C, 0x6B, +}; + +static const float zero = 0.0f; +static const float one = 1.0f; +static const float two8 = 0x1p+08; /* 2.5600000000e+02f 0x43800000 */ +static const float twon8 = 0x1p-08; /* 3.9062500000e-03f 0x3b800000 */ + +static inline int __rem_pio2f_internal(float *x, float *y, int e0, int nx) +{ + int32_t jk = 7; /* precision setting + jk+1 is the initial number of terms of ipio2[] needed in the computation. */ + int32_t jp = jk; /* stores the initial value of jk until the final result computation */ + + int32_t k; /* number of additional ipio2 terms needed for recomputation */ + int32_t i, j, m; /* general purpose indices and variables */ + int32_t jz, jx, jv; /* other specific indices */ + int32_t carry; /* indicates whether there is a contribution of q when computing the complementary angle */ + int32_t ih; /* variable that indicates the position of the angle within the resulting quadrant. + If ih is positive then q[] is >= 0.5, hence it acts as the "signbit" of the result, + which will be positive for negative angles within the quadrant. */ + + + float q[20] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, /* value of q = x/(pi/2) = x*(2/pi) */ + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; + int32_t q0; /* the corresponding exponent of q[0]. Note that the exponent for q[i] would be q0-8*i */ + + int32_t n; /* indicates the octant where the angle falls into; it is used to get the quadrant */ + float z; /* high order fractional part of q, down to the q0 bit */ + int32_t iq[20] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* lower order 8 bit chunks of fractional part of q in inverted order. */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; /* iq starts after the q0 bits which are in z */ + + float fw; /* temporary variable to compute q, iq, and fq */ + float f[20] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, /* ipio2[] terms taken fro computation in floating point */ + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; + float fq[20] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, /* final product of q*pi/2 in fq[0],..,fq[jk]; */ + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; /* computing the fractional value [0,1] within the quadrant back into radians */ + + + + bool recompute; /* variable used to signalize that a recomputation is needed as the current selection of ipio2[] terms has led to loss of significance. + The recomputation will take more terms of ipio2[]. */ + bool exhausted; /* variable used to signalize that the available ipio2 precision has been exhausted making no further recomputing possible */ + + jp = jk; + + /* determine jx,jv,q0, note that 3>q0 */ + jx = nx - 1; + jv = (e0 - 3) / 8; + + q0 = e0 - 8 * (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 : (float) ipio2[j]; + } + + /* compute q[0],q[1],...q[jk] */ + for (i = 0; i <= jk; i++) { + for (j = 0, fw = 0.0f; j <= jx; j++) { + fw += x[j] * f[jx + i - j]; + } + + q[i] = fw; + } + + jz = jk; + do { + recompute = false; + exhausted = false; + + /* distill the lower part of q[] into iq[] reversingly and leave the higher part in z */ + for (i = 0, j = jz, z = q[jz]; j > 0; i++, j--) { + fw = (float)((int32_t)(twon8 * z)); + iq[i] = (int32_t)(z - two8 * fw); + z = q[j - 1] + fw; + } + + /* compute n */ + z = scalbnf(z, (int32_t)q0); /* actual value of z */ + z -= 8.0f * floorf(z * 0.125f); /* trim off integer >= 8 */ + n = (int32_t) z; + z -= (float)n; + ih = 0; + + if (q0 > 0) { /* need iq[jz-1] to determine n */ + i = (iq[jz - 1] >> (8 - q0)); + n += i; + iq[jz - 1] -= i << (8 - q0); + ih = iq[jz - 1] >> (7 - q0); + } else if (q0 == 0) { + ih = iq[jz - 1] >> 7; + } else if (z >= 0.5f) { + ih = 2; + } else { + /* No action required */ + } + + /* for the cases that the angle is in the upper side of the quadrant, the complementary is computed */ + if (ih > 0) { /* q > 0.5 */ + n += 1; + carry = 0; + + for (i = 0; i < jz ; i++) { /* compute 1-q by computing the complementary of iq */ + j = iq[i]; + + if (carry == 0) { + if (j != 0) { + carry = 1; + iq[i] = 0x100 - j; + } + } else { + iq[i] = 0xff - j; + } + } + + if (q0 > 0) { /* rare case: chance is 1 in 12 */ + switch (q0) { + default: /* FALLTHRU */ + case 1: + iq[jz - 1] &= 0x7f; + break; + + case 2: + iq[jz - 1] &= 0x3f; + break; + } + } + + if (ih == 2) { /* compute the complementary of z */ + z = one - z; + + /* in case that iq[] does have a contribution, subtract the order of magnitude + of this contribution from the complement of z so that z + iq can be computed. */ + if (carry != 0) { + z -= scalbnf(one, (int32_t)q0); + /* Given the following decimal example of: z = 0.7 and iq = 0.01 for the angle z + iq = 0.71 + the complements would be z = 1 - z = 0.3 and iq = 0.1 - iq = 0.09 + now, z needs to be decremented by 0.1; z = z - 0.1 so that z + iq = 0.2 + 0.09 = 0.29 + which is the correct complement of the original angle 0.71 */ + } + } + } + + /* check if recomputation is needed in case of loss of significance in z and iq[] */ + if (z == zero) { + j = 0; + + for (i = jz - 1; i >= jk; i--) { + j |= iq[i]; + } + + if (j == 0) { /* need recomputation */ + for (k = 1; (jk - k >= 0) && (iq[jk - k] == 0); k++) { /* k = no. of terms needed */ + } + + /* add q[jz+1] to q[jz+k] + don't pull more terms of ipio2[] than available + and don't overflow f[] */ + for (i = jz + 1; i <= jz + k; i++) { + if ((jv + i < 66) && + (jx + i < 20)) { + f[jx + i] = (float) ipio2[jv + i]; + } else{ + exhausted = true; + } + + for (j = 0, fw = 0.0f; j <= jx; j++) { + fw += x[j] * f[jx + i - j]; + } + + q[i] = fw; + } + + jz += k; + recompute = true; + } + } + /* The original authors of the algorithm Payne and Hanek estimate the + amount of needed recomputing to be low. Currently only 2 recomputes + are observed at most */ + } while (recompute && !exhausted); + + /* chop off zero terms */ + if (z == 0.0f) { + q0 -= 8; + + for (jz -= 1; jz>=0; --jz) { + if (iq[jz]!=0) { + break; + } + q0 -= 8; + } + } else { /* break z into 8-bit if necessary */ + z = scalbnf(z, -(int32_t)q0); + + iq[jz] = (int32_t) z ; + } + + /* convert integer "bit" chunk to floating-point value */ + fw = scalbnf(one, (int32_t)q0); + + for (i = jz; i >= 0; i--) { + q[i] = fw * (float)iq[i]; + fw *= twon8; + } + + /* compute PIo2[0,...,jp]*q[jz,...,0] */ + for (i = jz; i >= 0; i--) { + for (fw = 0.0f, k = 0; k <= jp && k <= jz - i; k++) { + fw += PIo2[k] * q[i + k]; + } + + fq[jz - i] = fw; + } + + /* compress fq[] into y[] */ + fw = 0.0f; + + for (i = jz; i >= 0; i--) { + fw += fq[i]; + } + + 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; + + return n & 7; +} + +/* __rem_pio2f(x,y) + * + * return the remainder of x rem pi/2 in y[0]+y[1] + * use __rem_pio2f_internal() + */ + +/* + * invpio2: 24 bits of 2/pi + * pio2_1: first 17 bit of pi/2 + * pio2_1t: pi/2 - pio2_1 + * pio2_2: second 17 bit of pi/2 + * pio2_2t: pi/2 - (pio2_1+pio2_2) + * pio2_3: third 17 bit of pi/2 + * pio2_3t: pi/2 - (pio2_1+pio2_2+pio2_3) + */ + +static const float +half = 5.0000000000e-01f, /* 0x3f000000 */ +invpio2 = 6.3661980629e-01f, /* 0x3f22f984 */ +pio2_1 = 1.5707855225e+00f, /* 0x3fc90f80 */ +pio2_1t = 1.0804334124e-05f, /* 0x37354443 */ +pio2_2 = 1.0804273188e-05f, /* 0x37354400 */ +pio2_2t = 6.0770999344e-11f, /* 0x2e85a308 */ +pio2_3 = 6.0770943833e-11f, /* 0x2e85a300 */ +pio2_3t = 6.1232342629e-17f; /* 0x248d3132 */ + +int32_t __rem_pio2f(float x, float *y) +{ + float z, w, t, r, fn; + float tx[3]; + int32_t i, j, n, ix, hx; + int32_t e0, nx; + + GET_FLOAT_WORD(hx, x); + ix = hx & 0x7fffffff; + + if (ix <= 0x3f490fd8) { /* |x| ~<= pi/4 , no need for reduction */ + y[0] = x; + y[1] = 0; + return 0; + } + + if (ix < 0x4016cbe4) { /* |x| < 3pi/4, special case with n=+-1 */ + /* 17+17+24 bit pi has sufficient precision and best efficiency */ + if (hx > 0) { + z = x - pio2_1; + + if ((ix & 0xfffe0000U) != 0x3fc80000) { /* 17+24 bit pi OK */ + y[0] = z - pio2_1t; + y[1] = (z - y[0]) - pio2_1t; + } else { /* near pi/2, use 17+17+24 bit pi */ + z -= pio2_2; + y[0] = z - pio2_2t; + y[1] = (z - y[0]) - pio2_2t; + } + + return 1; + } else { /* negative x */ + z = x + pio2_1; + + if ((ix & 0xfffe0000U) != 0x3fc80000) { /* 17+24 bit pi OK */ + y[0] = z + pio2_1t; + y[1] = (z - y[0]) + pio2_1t; + } else { /* near pi/2, use 17+17+24 bit pi */ + z += pio2_2; + y[0] = z + pio2_2t; + y[1] = (z - y[0]) + pio2_2t; + } + + return -1; + } + } + + if (ix <= 0x43490f80) { /* |x| ~<= 2^7*(pi/2), medium size */ + t = fabsf(x); + n = (int32_t)(t * invpio2 + half); + fn = (float)n; + r = t - fn * pio2_1; + w = fn * pio2_1t; /* 1st round good to 40 bit */ + + { + uint32_t high; + j = ix >> 23; + y[0] = r - w; + GET_FLOAT_WORD(high, y[0]); + i = j - ((high >> 23) & 0xff); + + if (i > 8) { /* 2nd iteration needed, good to 57 */ + t = r; + w = fn * pio2_2; + r = t - w; + w = fn * pio2_2t - ((t - r) - w); + y[0] = r - w; + GET_FLOAT_WORD(high, y[0]); + i = j - ((high >> 23) & 0xff); + + if (i > 25) { /* 3rd iteration need, 74 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; + + if (hx < 0) { + y[0] = -y[0]; + y[1] = -y[1]; + return -n; + } else { + return n; + } + } + + /* + * all other (large) arguments + */ + if (!FLT_UWORD_IS_FINITE(ix)) { + if (isnan(x)) { + y[1] = x - x; + y[0] = y[1]; + } else { + y[1] = __raise_invalidf(); + y[0] = y[1]; + } + return 0; + } + + /* set z = scalbn(|x|,ilogb(x)-7) */ + e0 = (int32_t)((ix >> 23) - 134); /* e0 = ilogb(z)-7; */ + SET_FLOAT_WORD(z, ix - ((int32_t)e0 << 23)); + + for (i = 0; i < 2; i++) { + tx[i] = (float)((int32_t)(z)); + z = (z - tx[i]) * two8; + } + + tx[2] = z; + + for (nx = 3; nx>1; --nx) { /* skip zero term */ + if (tx[nx-1]!=zero) { + break; + } + } + + n = __rem_pio2f_internal(tx, y, e0, nx); + + if (hx < 0) { + y[0] = -y[0]; + y[1] = -y[1]; + return -n; + } + + return n; +} + +static const float +C1 = 0xaaaaa5.0p-28f, /* 0.04166664555668830871582031250, 0x3D2AAAA5 */ +C2 = -0xb60615.0p-33f, /* -0.001388731063343584537506103516, 0xBAB60615 */ +C3 = 0xccf47d.0p-39f; /* 0.00002443254288664320483803749084, 0x37CCF47C */ + +float __cosf(float x, float y) +{ + float hz, z, r, w; + + z = x * x; + r = z * (C1 + z * (C2 + z * C3)); + + hz = 0.5f * z; + w = one - hz; + return w + (((one - w) - hz) + (z * r - x * y)); +} + +static const float +S1 = -0xaaaaab.0p-26f, /* -0.16666667163, 0xBE2AAAAB */ +S2 = 0x8888bb.0p-30f, /* 0.0083333803341, 0x3C0888BB */ +S3 = -0xd02de1.0p-36f, /* -0.00019853517006, 0xB9502DE1 */ +S4 = 0xbe6dbe.0p-42f; /* 0.0000028376084629, 0x363E6DBE */ + +float __sinf(float x, float y, int iy) +{ + float z, r, v; + + z = x * x; + v = z * x; + r = S2 + z * (S3 + z * S4); + + if (iy == 0) { + return x + v * (S1 + z * r); + } else { + return x - ((z * (half * y - v * r) - y) - v * S1); + } +} diff --git a/libm/libmcs/libm/mathf/internal/trigf.h b/libm/libmcs/libm/mathf/internal/trigf.h new file mode 100644 index 00000000..8a1e5ef8 --- /dev/null +++ b/libm/libmcs/libm/mathf/internal/trigf.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GTDGmbH */ +/* Copyright 2020-2025 by GTD GmbH. */ + +#ifndef LIBMCS_TRIGF_H +#define LIBMCS_TRIGF_H + +#include "../../common/tools.h" + +extern float __sinf(float x, float y, int iy); +extern float __cosf(float x, float y); +extern int32_t __rem_pio2f(float x, float *y); + +#endif /* !LIBMCS_TRIGF_H */ diff --git a/libm/libmcs/libm/mathf/ldexpf.c b/libm/libmcs/libm/mathf/ldexpf.c new file mode 100644 index 00000000..0b9187ec --- /dev/null +++ b/libm/libmcs/libm/mathf/ldexpf.c @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ +/* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ + +#include + +float ldexpf(float x, int exp) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + if ((isfinite(x) == 0) || x == 0.0f) { + return x + x; + } + + return scalbnf(x, exp); +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double ldexp(double x, int exp) +{ + return (double) ldexpf((float) x, exp); +} + +#endif /* #ifdef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathf/lgammaf.c b/libm/libmcs/libm/mathf/lgammaf.c new file mode 100644 index 00000000..128b216c --- /dev/null +++ b/libm/libmcs/libm/mathf/lgammaf.c @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ +/* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ + +#include +#include "internal/gammaf.h" + +float lgammaf(float x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + return __lgammaf(x, &__signgam); +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double lgamma(double x) +{ + return (double) lgammaf((float) x); +} + +#endif /* #ifdef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathf/llrintf.c b/libm/libmcs/libm/mathf/llrintf.c new file mode 100644 index 00000000..e3e936fd --- /dev/null +++ b/libm/libmcs/libm/mathf/llrintf.c @@ -0,0 +1,85 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ +/* lrint adapted to be llrint for Newlib, 2009 by Craig Howland. */ + +/* + * llrintf(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 llrintf(x). + */ + +#include +#include "../common/tools.h" + +static const float +/* Adding a float, x, to 2^23 will cause the result to be rounded based on + the fractional part of x, according to the implementation's current rounding + mode. 2^23 is the smallest float that can be represented using all 23 significant + digits. */ +TWO23[2] = { + 8.3886080000e+06f, /* 0x4b000000 */ + -8.3886080000e+06f, /* 0xcb000000 */ +}; + +long long int llrintf(float x) +{ + int32_t _j0, sx; + uint32_t _i0; + float t; + volatile float w; + long long int result; + + GET_FLOAT_WORD(_i0, x); + + /* Extract sign bit. */ + sx = (_i0 >> 31); + + /* Extract exponent field. */ + _j0 = ((_i0 & 0x7f800000) >> 23) - 127; + + if (_j0 < (int32_t)(sizeof(long long int) * 8) - 1) { + if (_j0 < -1) { + return 0; + } else if (_j0 >= 23) { + result = (long long int)((_i0 & 0x7fffff) | 0x800000) << (_j0 - 23); + } else { + w = TWO23[sx] + x; + t = w - TWO23[sx]; + GET_FLOAT_WORD(_i0, t); + + /* Detect the all-zeros representation of plus and + minus zero, which fails the calculation below. */ + if ((_i0 & ~((uint32_t)1 << 31)) == 0) { + return 0; + } + + _j0 = ((_i0 >> 23) & 0xff) - 0x7f; + _i0 &= 0x7fffff; + _i0 |= 0x800000; + result = _i0 >> (23 - _j0); + } + } else { + (void) __raise_invalidf(); + if (sx != 0) { + return __MIN_LONG_LONG; + } + else { + return __MAX_LONG_LONG; + } + } + + return (sx != 0) ? -result : result; +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +long long int llrint(double x) +{ + return llrintf((float) x); +} + +#endif /* #ifdef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathf/llroundf.c b/libm/libmcs/libm/mathf/llroundf.c new file mode 100644 index 00000000..9de17e1a --- /dev/null +++ b/libm/libmcs/libm/mathf/llroundf.c @@ -0,0 +1,50 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ +/* lrint adapted to be llrint for Newlib, 2009 by Craig Howland. */ + +#include +#include "../common/tools.h" + +long long int llroundf(float x) +{ + int32_t exponent_less_127; + uint32_t w; + long long int result; + int32_t sign; + + GET_FLOAT_WORD(w, x); + exponent_less_127 = ((w & 0x7f800000) >> 23) - 127; + sign = (w & 0x80000000U) != 0 ? -1 : 1; + w &= 0x7fffff; + w |= 0x800000; + + if (exponent_less_127 < (int32_t)((8 * sizeof(long long int)) - 1)) { + if (exponent_less_127 < 0) { + return exponent_less_127 < -1 ? 0 : sign; + } else if (exponent_less_127 >= 23) { + result = (long long int) w << (exponent_less_127 - 23); + } else { + w += 0x400000 >> exponent_less_127; + result = w >> (23 - exponent_less_127); + } + } else { + (void) __raise_invalidf(); + if (sign == -1) { + return __MIN_LONG_LONG; + } + else { + return __MAX_LONG_LONG; + } + } + + return sign * result; +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +long long int llround(double x) +{ + return llroundf((float) x); +} + +#endif /* #ifdef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathf/log10f.c b/libm/libmcs/libm/mathf/log10f.c new file mode 100644 index 00000000..f50ce390 --- /dev/null +++ b/libm/libmcs/libm/mathf/log10f.c @@ -0,0 +1,80 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ +/* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ + +#include +#include "../common/tools.h" +#include "internal/log1pmff.h" + +static const float +two25 = 3.3554432000e+07f, /* 0x4c000000 */ +ivln10hi = 4.3432617188e-01f, /* 0x3ede6000 */ +ivln10lo = -3.1689971365e-05f, /* 0xb804ead9 */ +log10_2hi = 3.0102920532e-01f, /* 0x3e9a2080 */ +log10_2lo = 7.9034151668e-07f; /* 0x355427db */ + +static const float zero = 0.0f; + +float log10f(float x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + float f, hfsq, hi, lo, r, y; + int32_t i, k, hx; + + GET_FLOAT_WORD(hx, x); + + k = 0; + + if (FLT_UWORD_IS_ZERO(hx & 0x7fffffff)) { + return __raise_div_by_zerof(-1.0f); /* log(+-0)=-inf */ + } + + if (FLT_UWORD_IS_NAN(hx & 0x7fffffff)) { /* x = NaN */ + return x + x; + } + + if (hx < 0) { + return __raise_invalidf(); /* log(-#) = NaN */ + } + + if (FLT_UWORD_IS_INFINITE(hx)) { /* x = +Inf */ + return x + x; + } + + if (FLT_UWORD_IS_SUBNORMAL(hx)) { + k -= 25; + x *= two25; /* subnormal number, scale up x */ + GET_FLOAT_WORD(hx, x); + } + + if (hx == 0x3f800000) { /* log(1) = +0 */ + return zero; + } + + 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 - 1.0f; + hfsq = 0.5f * f * f; + r = __log1pmff(f); + hi = f - hfsq; + GET_FLOAT_WORD(hx, hi); + SET_FLOAT_WORD(hi, hx & 0xfffff000U); + lo = (f - hi) - hfsq + r; + return y * log10_2lo + (lo + hi) * ivln10lo + lo * ivln10hi + hi * ivln10hi + y * log10_2hi; +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double log10(double x) +{ + return (double) log10f((float) x); +} + +#endif /* #ifdef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathf/log1pf.c b/libm/libmcs/libm/mathf/log1pf.c new file mode 100644 index 00000000..c0d6f113 --- /dev/null +++ b/libm/libmcs/libm/mathf/log1pf.c @@ -0,0 +1,118 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ +/* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ + +#include +#include "../common/tools.h" +#include "internal/log1pmff.h" + +static const float +ln2_hi = 6.9313812256e-01f, /* 0x3f317180 */ +ln2_lo = 9.0580006145e-06f; /* 0x3717f7d1 */ + +static const float zero = 0.0f; + +float log1pf(float x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + float hfsq, f, c, R, u; + int32_t k, hx, hu, ax; + + c = NAN; /* initial value of c is never actually used */ + f = NAN; /* initial value of f is never actually used */ + hu = INT_MAX; /* initial value of hu is never actually used */ + + GET_FLOAT_WORD(hx, x); + ax = hx & 0x7fffffff; + + k = 1; + + if (!FLT_UWORD_IS_FINITE(hx)) { /* x = NaN/+Inf */ + return x + x; + } + + if (hx < 0x3ed413d7) { /* x < 0.41422 */ + if (ax >= 0x3f800000) { /* x <= -1.0 */ + if (FLT_UWORD_IS_NAN(ax)) { /* x = NaN */ + return x + x; + } else if (x == -1.0f) { + return __raise_div_by_zerof(-1.0f); /* log1p(-1)=-inf */ + } else { + return __raise_invalidf(); /* log1p(x<-1)=NaN */ + } + } + + if (ax < 0x31000000) { /* |x| < 2**-29 */ + if (ax < 0x24800000) { /* |x| < 2**-54 */ + return __raise_inexactf(x); + } else { + return __raise_inexactf(x - x * x * 0.5f); + } + } + + if (hx > 0 || hx <= ((int32_t)0xbe95f61fU)) { + k = 0; + f = x; + hu = 1; + } /* -0.2929> 23) - 127; + /* correction term */ + c = (k > 0) ? 1.0f - (u - x) : x - (u - 1.0f); + c /= u; + } else { + u = x; + GET_FLOAT_WORD(hu, u); + k = (hu >> 23) - 127; + c = 0; + } + + hu &= 0x007fffff; + + if (hu < 0x3504f7) { + 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 - 1.0f; + } + + hfsq = 0.5f * f * f; + + if (hu == 0) { /* |f| < 2**-20 */ + if (f == zero) { + c += k * ln2_lo; + return k * ln2_hi + c; + } + + R = hfsq * (1.0f - 0.66666666666666666f * f); + + return k * ln2_hi - ((R - (k * ln2_lo + c)) - f); + } + + if (k == 0) { + return f - (hfsq - __log1pmff(f)); + } else { + return k * ln2_hi - ((hfsq - (__log1pmff(f) + (k * ln2_lo + c))) - f); + } +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double log1p(double x) +{ + return (double) log1pf((float) x); +} + +#endif /* #ifdef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathf/log2f.c b/libm/libmcs/libm/mathf/log2f.c new file mode 100644 index 00000000..0336d0b5 --- /dev/null +++ b/libm/libmcs/libm/mathf/log2f.c @@ -0,0 +1,78 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ +/* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ + +#include +#include "../common/tools.h" +#include "internal/log1pmff.h" + +static const float +two25 = 3.3554432000e+07f, /* 0x4c000000 */ +ivln2hi = 1.4428710938e+00f, /* 0x3fb8b000 */ +ivln2lo = -1.7605285393e-04f; /* 0xb9389ad4 */ + +static const float zero = 0.0f; + +float log2f(float x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + float f, hfsq, hi, lo, r, y; + int32_t i, k, hx; + + GET_FLOAT_WORD(hx, x); + + k = 0; + + if (FLT_UWORD_IS_ZERO(hx & 0x7fffffff)) { + return __raise_div_by_zerof(-1.0f); /* log(+-0)=-inf */ + } + + if (FLT_UWORD_IS_NAN(hx & 0x7fffffff)) { /* x = NaN */ + return x + x; + } + + if (hx < 0) { + return __raise_invalidf(); /* log(-#) = NaN */ + } + + if (FLT_UWORD_IS_INFINITE(hx)) { /* x = +Inf */ + return x + x; + } + + if (FLT_UWORD_IS_SUBNORMAL(hx)) { + k -= 25; + x *= two25; /* subnormal number, scale up x */ + GET_FLOAT_WORD(hx, x); + } + + if (hx == 0x3f800000) { /* log(1) = +0 */ + return zero; + } + + 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 - 1.0f; + hfsq = 0.5f * f * f; + r = __log1pmff(f); + hi = f - hfsq; + GET_FLOAT_WORD(hx, hi); + SET_FLOAT_WORD(hi, hx & 0xfffff000U); + lo = (f - hi) - hfsq + r; + return (lo + hi) * ivln2lo + lo * ivln2hi + hi * ivln2hi + y; +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double log2(double x) +{ + return (double) log2f((float) x); +} + +#endif /* #ifdef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathf/logbf.c b/libm/libmcs/libm/mathf/logbf.c new file mode 100644 index 00000000..25fe2ac2 --- /dev/null +++ b/libm/libmcs/libm/mathf/logbf.c @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ +/* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ + +/* float logb(float x) + * return the binary exponent of non-zero x + * logbf(0) = -inf, raise divide-by-zero floating point exception + * logbf(+inf|-inf) = +inf (no signal is raised) + * logbf(NaN) = NaN (no signal is raised) + * Per C99 recommendation, a NaN argument is returned unchanged. + */ + +#include +#include "../common/tools.h" + +float logbf(float x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + int32_t hx, ix; + + GET_FLOAT_WORD(hx, x); + hx &= 0x7fffffff; + + if (FLT_UWORD_IS_ZERO(hx)) { + return __raise_div_by_zerof(-1.0f); /* logbf(0) = -inf */ + } + + if (FLT_UWORD_IS_SUBNORMAL(hx)) { + for (ix = -126, hx <<= 8; hx > 0; hx <<= 1) { + ix -= 1; + } + + return (float) ix; + } else if (!FLT_UWORD_IS_FINITE(hx)) { /* x = NaN/+-Inf */ + return x * x; + } else { + return (float)((hx >> 23) - 127); + } +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double logb(double x) +{ + return (double) logbf((float) x); +} + +#endif /* #ifdef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathf/logf.c b/libm/libmcs/libm/mathf/logf.c new file mode 100644 index 00000000..51e33131 --- /dev/null +++ b/libm/libmcs/libm/mathf/logf.c @@ -0,0 +1,119 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ +/* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ + +#include +#include "../common/tools.h" + +static const float +ln2_hi = 6.9313812256e-01f, /* 0x3f317180 */ +ln2_lo = 9.0580006145e-06f, /* 0x3717f7d1 */ +two25 = 3.355443200e+07f, /* 0x4c000000 */ +Lg1 = 6.6666668653e-01f, /* 0x3F2AAAAB */ +Lg2 = 4.0000000596e-01f, /* 0x3ECCCCCD */ +Lg3 = 2.8571429849e-01f, /* 0x3E924925 */ +Lg4 = 2.2222198546e-01f, /* 0x3E638E29 */ +Lg5 = 1.8183572590e-01f, /* 0x3E3A3325 */ +Lg6 = 1.5313838422e-01f, /* 0x3E1CD04F */ +Lg7 = 1.4798198640e-01f; /* 0x3E178897 */ + +static const float zero = 0.0f; + +float logf(float x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + float hfsq, f, s, z, R, w, t1, t2, dk; + int32_t k, ix, i, j; + + GET_FLOAT_WORD(ix, x); + + k = 0; + + if (FLT_UWORD_IS_ZERO(ix & 0x7fffffff)) { + return __raise_div_by_zerof(-1.0f); /* log(+-0)=-inf */ + } + + if (FLT_UWORD_IS_NAN(ix & 0x7fffffff)) { /* x = NaN */ + return x + x; + } + + if (ix < 0) { + return __raise_invalidf(); /* log(-#) = NaN */ + } + + if (FLT_UWORD_IS_INFINITE(ix)) { /* x = +Inf */ + return x + x; + } + + if (FLT_UWORD_IS_SUBNORMAL(ix)) { + k -= 25; + x *= two25; /* subnormal number, scale up x */ + GET_FLOAT_WORD(ix, 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 - 1.0f; + + if ((0x007fffff & (15 + ix)) < 16) { /* |f| < 2**-20 */ + if (f == zero) { + if (k == 0) { + return zero; + } else { + dk = (float)k; + return dk * ln2_hi + dk * ln2_lo; + } + } + + R = f * f * (0.5f - 0.33333333333333333f * f); + + if (k == 0) { + return f - R; + } else { + dk = (float)k; + return dk * ln2_hi - ((R - dk * ln2_lo) - f); + } + } + + s = f / (2.0f + f); + dk = (float)k; + z = s * s; + i = ix - (0x6147a << 3); + w = z * z; + j = (0x6b851 << 3) - ix; + 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.5f * 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); + } + } +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double log(double x) +{ + return (double) logf((float) x); +} + +#endif /* #ifdef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathf/lrintf.c b/libm/libmcs/libm/mathf/lrintf.c new file mode 100644 index 00000000..f04abe43 --- /dev/null +++ b/libm/libmcs/libm/mathf/lrintf.c @@ -0,0 +1,84 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +/* + * lrintf(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 lrintf(x). + */ + +#include +#include "../common/tools.h" + +static const float +/* Adding a float, x, to 2^23 will cause the result to be rounded based on + the fractional part of x, according to the implementation's current rounding + mode. 2^23 is the smallest float that can be represented using all 23 significant + digits. */ +TWO23[2] = { + 8.3886080000e+06f, /* 0x4b000000 */ + -8.3886080000e+06f, /* 0xcb000000 */ +}; + +long int lrintf(float x) +{ + int32_t _j0, sx; + uint32_t _i0; + float t; + volatile float w; + long int result; + + GET_FLOAT_WORD(_i0, x); + + /* Extract sign bit. */ + sx = (_i0 >> 31); + + /* Extract exponent field. */ + _j0 = ((_i0 & 0x7f800000) >> 23) - 127; + + if (_j0 < (int32_t)(sizeof(long int) * 8) - 1) { + if (_j0 < -1) { + return 0; + } else if (_j0 >= 23) { + result = (long int)((_i0 & 0x7fffff) | 0x800000) << (_j0 - 23); + } else { + w = TWO23[sx] + x; + t = w - TWO23[sx]; + GET_FLOAT_WORD(_i0, t); + + /* Detect the all-zeros representation of plus and + minus zero, which fails the calculation below. */ + if ((_i0 & ~(1U << 31)) == 0) { + return 0; + } + + _j0 = ((_i0 >> 23) & 0xff) - 0x7f; + _i0 &= 0x7fffff; + _i0 |= 0x800000; + result = _i0 >> (23 - _j0); + } + } else { + (void) __raise_invalidf(); + if (sx != 0) { + return __MIN_LONG; + } + else { + return __MAX_LONG; + } + } + + return (sx != 0) ? -result : result; +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +long int lrint(double x) +{ + return lrintf((float) x); +} + +#endif /* #ifdef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathf/lroundf.c b/libm/libmcs/libm/mathf/lroundf.c new file mode 100644 index 00000000..f674a8cb --- /dev/null +++ b/libm/libmcs/libm/mathf/lroundf.c @@ -0,0 +1,48 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +#include +#include "../common/tools.h" + +long int lroundf(float x) +{ + int32_t exponent_less_127; + uint32_t w; + long int result; + int32_t sign; + + GET_FLOAT_WORD(w, x); + exponent_less_127 = ((w & 0x7f800000) >> 23) - 127; + sign = (w & 0x80000000U) != 0 ? -1 : 1; + w &= 0x7fffff; + w |= 0x800000; + + if (exponent_less_127 < (int32_t)((8 * sizeof(long int)) - 1)) { + if (exponent_less_127 < 0) { + return exponent_less_127 < -1 ? 0 : sign; + } else if (exponent_less_127 >= 23) { + result = (long int) w << (exponent_less_127 - 23); + } else { + w += 0x400000 >> exponent_less_127; + result = w >> (23 - exponent_less_127); + } + } else { + (void) __raise_invalidf(); + if (sign == -1) { + return __MIN_LONG; + } else { + return __MAX_LONG; + } + } + + return sign * result; +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +long int lround(double x) +{ + return lroundf((float) x); +} + +#endif /* #ifdef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathf/modff.c b/libm/libmcs/libm/mathf/modff.c new file mode 100644 index 00000000..b270a863 --- /dev/null +++ b/libm/libmcs/libm/mathf/modff.c @@ -0,0 +1,62 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ +/* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ + +#include +#include +#include "../common/tools.h" + +float modff(float x, float *iptr) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + float _xi = 0.0f; + int32_t _i0, _j0; + uint32_t i; + + assert(iptr != (void*)0); + if(iptr == (void*)0) { + iptr = &_xi; + } + + 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 & 0x80000000U); /* *iptr = +-0 */ + return x; + } else { + i = (0x007fffff) >> _j0; + + if ((_i0 & i) == 0) { /* x is integral */ + *iptr = x; + SET_FLOAT_WORD(x, _i0 & 0x80000000U); /* return +-0 */ + return x; + } else { + SET_FLOAT_WORD(*iptr, _i0 & (~i)); + return x - *iptr; + } + } + } else { /* no fraction part */ + *iptr = x; + + if (isnan(x)) { + return *iptr = x + x; /* x is NaN, return NaN */ + } + + SET_FLOAT_WORD(x, _i0 & 0x80000000U); /* return +-0 */ + return x; + } +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double modf(double x, double *iptr) +{ + return (double) modff((float) x, (float *) iptr); +} + +#endif /* #ifdef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathf/nanf.c b/libm/libmcs/libm/mathf/nanf.c new file mode 100644 index 00000000..0814bc19 --- /dev/null +++ b/libm/libmcs/libm/mathf/nanf.c @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GTDGmbH */ +/* Copyright 2020-2025 by GTD GmbH. */ + +#include +#include "../common/tools.h" + +float nanf(const char *payload) +{ + (void)payload; + + float x; + SET_FLOAT_WORD(x,0x7FCF067D); + return x; +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double nan(const char *payload) +{ + return (double) nanf(payload); +} + +#endif /* #ifdef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathf/nearbyintf.c b/libm/libmcs/libm/mathf/nearbyintf.c new file mode 100644 index 00000000..c6c26ad3 --- /dev/null +++ b/libm/libmcs/libm/mathf/nearbyintf.c @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +#include + +float nearbyintf(float x) +{ + return rintf(x); +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double nearbyint(double x) +{ + return (double) nearbyintf((float) x); +} + +#endif /* #ifdef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathf/nextafterf.c b/libm/libmcs/libm/mathf/nextafterf.c new file mode 100644 index 00000000..b72d7289 --- /dev/null +++ b/libm/libmcs/libm/mathf/nextafterf.c @@ -0,0 +1,77 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ +/* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ + +#include +#include "../common/tools.h" + +float nextafterf(float x, float y) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_onef; + y *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + 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 (FLT_UWORD_IS_NAN(ix) || FLT_UWORD_IS_NAN(iy)) { + return x + y; + } else if (hx == hy) { + return y; /* x == y, return y */ + } else if (ix == 0) { /* x == 0 */ + if (ix == iy) { + return y; /* x == y, return y */ + } +#ifdef __LIBMCS_FPU_DAZ + SET_FLOAT_WORD(x, (hy & 0x80000000U) | 0x00800000U); /* return +-minnormal */ +#else + SET_FLOAT_WORD(x, (hy & 0x80000000U) | 1U); /* return +-minsubnormal */ + (void) __raise_underflowf(x); +#endif /* defined(__LIBMCS_FPU_DAZ) */ + return x; + } else 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 > FLT_UWORD_MAX) { + return __raise_overflowf(x); /* overflow if x is finite */ + } + + if (hy < 0x00800000) { /* underflow */ +#ifdef __LIBMCS_FPU_DAZ + SET_FLOAT_WORD(x, hx & 0x80000000U); /* return +-0.0 */ + return x; +#else + (void) __raise_underflowf(x); +#endif /* defined(__LIBMCS_FPU_DAZ) */ + } + + SET_FLOAT_WORD(x, hx); + return x; +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double nextafter(double x, double y) +{ + return (double) nextafterf((float) x, (float) y); +} + +#endif /* #ifdef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathf/nexttowardf.c b/libm/libmcs/libm/mathf/nexttowardf.c new file mode 100644 index 00000000..ad4bcecd --- /dev/null +++ b/libm/libmcs/libm/mathf/nexttowardf.c @@ -0,0 +1,90 @@ +/* SPDX-License-Identifier: RichFelker */ +/* Copyright © 2005-2014 Rich Felker, et al. */ + +#include +#include "../common/tools.h" + +#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS + +union fshape { + float value; + uint32_t bits; +}; + +float nexttowardf(float x, long double y) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_onef; + y *= (long double)__volatile_one; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + union fshape ux; + uint32_t e; + + if (isnan(x) || isnan(y)) { + return x + y; + } + + if (x == y) { + return y; + } + + ux.value = x; + + if (x == 0) { +#ifdef __LIBMCS_FPU_DAZ + ux.bits = 0x00800000U; /* return +-minnormal */ +#else + ux.bits = 1U; /* return +-minsubnormal */ +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + if (signbit(y) != 0) { + ux.bits |= 0x80000000U; + } + } else if (x < y) { + if (signbit(x) != 0) { + ux.bits--; + } else { + ux.bits++; + } + } else { + if (signbit(x) != 0) { + ux.bits++; + } else { + ux.bits--; + } + } + + e = ux.bits & 0x7f800000; + + /* raise overflow if ux.value is infinite and x is finite */ + if (e == 0x7f800000) { + return __raise_overflowf(x); + } + + /* raise underflow if ux.value is subnormal or zero */ + if (e == 0) { +#ifdef __LIBMCS_FPU_DAZ + ux.bits = 0U; /* return +-0.0 */ + + if (signbit(x) != 0) { + ux.bits |= 0x80000000U; + } +#else + (void) __raise_underflowf(x); +#endif /* defined(__LIBMCS_FPU_DAZ) */ + } + + return ux.value; +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double nexttoward(double x, long double y) +{ + return (double) nexttowardf((float) x, y); +} + +#endif /* #ifdef __LIBMCS_DOUBLE_IS_32BITS */ + +#endif /* __LIBMCS_LONG_DOUBLE_IS_64BITS */ diff --git a/libm/libmcs/libm/mathf/powf.c b/libm/libmcs/libm/mathf/powf.c new file mode 100644 index 00000000..45831ef7 --- /dev/null +++ b/libm/libmcs/libm/mathf/powf.c @@ -0,0 +1,339 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ +/* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ + +#include +#include "../common/tools.h" + +static const float +bp[] = { 1.0f, 1.5f}, +dp_h[] = { 0.0f, 5.84960938e-01f}, /* 0x3f15c000 */ +dp_l[] = { 0.0f, 1.56322085e-06f}, /* 0x35d1cfdc */ +zero = 0.0f, +one = 1.0f, +two = 2.0f, +two24 = 16777216.0f, /* 0x4b800000 */ +/* poly coefs for (3/2)*(log(x)-2s-2/3*s**3 */ +L1 = 6.0000002384e-01f, /* 0x3f19999a */ +L2 = 4.2857143283e-01f, /* 0x3edb6db7 */ +L3 = 3.3333334327e-01f, /* 0x3eaaaaab */ +L4 = 2.7272811532e-01f, /* 0x3e8ba305 */ +L5 = 2.3066075146e-01f, /* 0x3e6c3255 */ +L6 = 2.0697501302e-01f, /* 0x3e53f142 */ +P1 = 1.6666667163e-01f, /* 0x3e2aaaab */ +P2 = -2.7777778450e-03f, /* 0xbb360b61 */ +P3 = 6.6137559770e-05f, /* 0x388ab355 */ +P4 = -1.6533901999e-06f, /* 0xb5ddea0e */ +P5 = 4.1381369442e-08f, /* 0x3331bb4c */ +lg2 = 6.9314718246e-01f, /* 0x3f317218 */ +lg2_h = 6.93145752e-01f, /* 0x3f317200 */ +lg2_l = 1.42860654e-06f, /* 0x35bfbe8c */ +ovt = 4.2995665694e-08f, /* -(128-log2(ovfl+.5ulp)) */ +cp = 9.6179670095e-01f, /* 0x3f76384f =2/(3ln2) */ +cp_h = 9.6191406250e-01f, /* 0x3f764000 =12b of cp */ +cp_l = -1.1736857402e-04f, /* 0xb8f623c6 =tail of cp_h */ +ivln2 = 1.4426950216e+00f, /* 0x3fb8aa3b =1/ln2 */ +ivln2_h = 1.4426879883e+00f, /* 0x3fb8aa00 =16b 1/ln2*/ +ivln2_l = 7.0526075433e-06f; /* 0x36eca570 =1/ln2 tail*/ + +float powf(float x, float y) +{ + float z, ax, z_h, z_l, p_h, p_l; + float _y1, t1, t2, r, s, 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 (FLT_UWORD_IS_ZERO(iy)) { + if (__issignalingf(x) != 0) { + return x + y; + } + + return one; + } + + /* x|y==NaN return NaN unless x==1 then return 1 */ + if (FLT_UWORD_IS_NAN(ix) || FLT_UWORD_IS_NAN(iy)) { + if (hx == 0x3f800000 && __issignalingf(y) == 0) { + return one; + } else { + return x + y; + } + } + +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_onef; + y *= __volatile_onef; + + GET_FLOAT_WORD(hx, x); + GET_FLOAT_WORD(hy, y); + ix = hx & 0x7fffffff; + iy = hy & 0x7fffffff; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + /* 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); + } + } else { + /* No action required */ + } + } + + /* special value of y */ + if (FLT_UWORD_IS_INFINITE(iy)) { /* y is +-inf */ + if (ix == 0x3f800000) { + return one; /* +-1**+-inf = 1 */ + } 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 sqrtf(x); + } + } + + ax = fabsf(x); + + /* special value of x */ + if (FLT_UWORD_IS_INFINITE(ix) || FLT_UWORD_IS_ZERO(ix) || ix == 0x3f800000) { + z = ax; /*x is +-0,+-inf,+-1*/ + + if (hy < 0) { /* z = (1/|x|) */ + if (FLT_UWORD_IS_INFINITE(ix)) { + z = zero; + } else if (FLT_UWORD_IS_ZERO(ix)) { + z = __raise_div_by_zerof(z); + } else { + /* No action required */ + } + } + + if (hx < 0) { + if (((ix - 0x3f800000) | yisint) == 0) { + z = __raise_invalidf(); /* (-1)**non-int is NaN */ + } else if (yisint == 1) { + z = -z; /* (x<0)**odd = -(|x|**odd) */ + } else { + /* No action required */ + } + } + + return z; + } + + /* (x<0)**(non-int) is NaN */ + if (((((uint32_t)hx >> 31U) - 1U) | (uint32_t)yisint) == 0) { + return __raise_invalidf(); + } + + /* |y| is huge */ + if (iy > 0x4d000000) { /* if |y| > 2**27 */ + /* over/underflow if x is not close to one */ + /* Contrary to the double procedure we don't need the sign for these over/underflows as |y| > 2**27 means that y is an even integer (should the border ever be lowered to 2**23 or lower, the sign plays a role). */ + if (ix < 0x3f7ffff4) { + return (hy < 0) ? __raise_overflowf(one) : __raise_underflowf(one); + } + + if (ix > 0x3f800007) { + return (hy > 0) ? __raise_overflowf(one) : __raise_underflowf(one); + } + + /* 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) * (0.5f - t * (0.333333333333f - t * 0.25f)); + 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 & 0xfffff000U); + t2 = v - (t1 - u); + } else { + float s2, s_h, s_l, t_h, t_l; + n = 0; + + /* take care subnormal number */ + if (FLT_UWORD_IS_SUBNORMAL(ix)) { + 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) & 0xfffff000U) | 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.0f + s2 + r; + GET_FLOAT_WORD(is, t_h); + SET_FLOAT_WORD(t_h, is & 0xfffff000U); + t_l = r - ((t_h - 3.0f) - 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 & 0xfffff000U); + 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 = (float)n; + t1 = (((z_h + z_l) + dp_h[k]) + t); + GET_FLOAT_WORD(is, t1); + SET_FLOAT_WORD(t1, is & 0xfffff000U); + t2 = z_l - (((t1 - t) - dp_h[k]) - z_h); + } + + s = one; /* s (sign of result -ve**odd) = -1 else = 1 */ + + if (((((uint32_t)hx >> 31U) - 1U) | (uint32_t)(yisint - 1)) == 0) { + s = -one; /* (-ve)**(odd int) */ + } + + /* split up y into _y1+y2 and compute (_y1+y2)*(t1+t2) */ + GET_FLOAT_WORD(is, y); + SET_FLOAT_WORD(_y1, is & 0xfffff000U); + p_l = (y - _y1) * t1 + y * t2; + p_h = _y1 * t1; + z = p_l + p_h; + GET_FLOAT_WORD(j, z); + i = j & 0x7fffffff; + + if (j > 0) { + if (i > FLT_UWORD_EXP_MAX) { + return __raise_overflowf(s); /* overflow */ + } else if (i == FLT_UWORD_EXP_MAX) { + if (p_l + ovt > z - p_h) { + return __raise_overflowf(s); /* overflow */ + } + } else { + /* No action required */ + } + } else { + if (i > FLT_UWORD_EXP_MIN) { + return __raise_underflowf(s); /* underflow */ + } else if (i == FLT_UWORD_EXP_MIN) { + if (p_l <= z - p_h) { + return __raise_underflowf(s); /* underflow */ + } + } else { + /* No action required */ + } + } + + /* + * compute 2**(p_h+p_l) + */ + 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 & 0xffff8000U); + 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, (int32_t)n); /* subnormal output */ + } else { + SET_FLOAT_WORD(z, j); + } + + return s * z; +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double pow(double x, double y) +{ + return (double) powf((float) x, (float) y); +} + +#endif /* #ifdef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathf/remainderf.c b/libm/libmcs/libm/mathf/remainderf.c new file mode 100644 index 00000000..6d149b0a --- /dev/null +++ b/libm/libmcs/libm/mathf/remainderf.c @@ -0,0 +1,79 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ +/* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ + +#include +#include "../common/tools.h" + +static const float zero = 0.0f; + +float remainderf(float x, float y) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_onef; + y *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + int32_t hx, hy; + uint32_t sx; + float y_half; + + GET_FLOAT_WORD(hx, x); + GET_FLOAT_WORD(hy, y); + sx = hx & 0x80000000U; + hy &= 0x7fffffff; + hx &= 0x7fffffff; + + /* purge off exception values */ + if (FLT_UWORD_IS_NAN(hx) || FLT_UWORD_IS_NAN(hy)) { /* x or y is NaN */ + return x + y; + } else if (FLT_UWORD_IS_ZERO(hy) || FLT_UWORD_IS_INFINITE(hx)) { /* y is 0 or x is inf */ + return __raise_invalidf(); + } else { + /* No action required */ + } + + if (hy <= FLT_UWORD_HALF_MAX) { + x = fmodf(x, 2 * y); /* now x < 2y */ + } + + if ((hx - hy) == 0) { + return zero * x; + } + + x = fabsf(x); + y = fabsf(y); + + if (hy < 0x01000000) { + if (x + x > y) { + x -= y; + + if (x + x >= y) { + x -= y; + } + } + } else { + y_half = 0.5f * y; + + if (x > y_half) { + x -= y; + + if (x >= y_half) { + x -= y; + } + } + } + + GET_FLOAT_WORD(hx, x); + SET_FLOAT_WORD(x, hx ^ sx); + return x; +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double remainder(double x, double y) +{ + return (double) remainderf((float) x, (float) y); +} + +#endif /* #ifdef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathf/remquof.c b/libm/libmcs/libm/mathf/remquof.c new file mode 100644 index 00000000..85b46772 --- /dev/null +++ b/libm/libmcs/libm/mathf/remquof.c @@ -0,0 +1,97 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +#include +#include +#include "../common/tools.h" + +static const float zero = 0.0f; + +float remquof(float x, float y, int *quo) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_onef; + y *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + int _quo = 0; + int32_t hx, hy; + uint32_t sx, sq; + float y_half; + + assert(quo != (void*)0); + if(quo == (void*)0) { + quo = &_quo; + } + *quo = 0; + + GET_FLOAT_WORD(hx, x); + GET_FLOAT_WORD(hy, y); + sx = hx & 0x80000000U; + sq = sx ^ (hy & 0x80000000U); + hy &= 0x7fffffff; + hx &= 0x7fffffff; + + /* purge off exception values */ + if (FLT_UWORD_IS_NAN(hx) || FLT_UWORD_IS_NAN(hy)) { /* x or y is NaN */ + return x + y; + } else if (FLT_UWORD_IS_ZERO(hy) || FLT_UWORD_IS_INFINITE(hx)) { /* y is 0 or x is inf */ + return __raise_invalidf(); + } else { + /* No action required */ + } + + if (hy <= 0x7dffffff) { + x = fmodf(x, 8 * y); /* now x < 8y */ + } + + if ((hx - hy) == 0) { + *quo = sq ? -1 : 1; + return zero * x; + } + + x = fabsf(x); + y = fabsf(y); + _quo = 0; + + if (x >= 4 * y) { + x -= 4 * y; + _quo += 4; + } + if (x >= 2 * y) { + x -= 2 * y; + _quo += 2; + } + + if (hy < 0x01000000) { + if (x + x > y) { + x -= y; + _quo++; + + if (x + x >= y) { + x -= y; + _quo++; + } + } + } else { + y_half = 0.5f * y; + + if (x > y_half) { + x -= y; + _quo++; + + if (x >= y_half) { + x -= y; + _quo++; + } + } + } + + _quo &= 0x7; + + *quo = sq ? -_quo : _quo; + + GET_FLOAT_WORD(hx, x); + SET_FLOAT_WORD(x, hx ^ sx); + return x; +} diff --git a/libm/libmcs/libm/mathf/rintf.c b/libm/libmcs/libm/mathf/rintf.c new file mode 100644 index 00000000..d804f9ef --- /dev/null +++ b/libm/libmcs/libm/mathf/rintf.c @@ -0,0 +1,77 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +#include +#include "../common/tools.h" + +static const float +TWO23[2] = { + 8.3886080000e+06f, /* 0x4b000000 */ + -8.3886080000e+06f, /* 0xcb000000 */ +}; + +float rintf(float x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + int32_t _i0, _j0, sx; + uint32_t i, _i1, ix; + float t; + volatile float w; + + GET_FLOAT_WORD(_i0, x); + sx = (_i0 >> 31) & 1; + ix = (_i0 & 0x7fffffff); + _j0 = (ix >> 23) - 0x7f; + + if (_j0 < 23) { + if (FLT_UWORD_IS_ZERO(ix)) { + return x; + } + + if (_j0 < 0) { + _i1 = (_i0 & 0x07fffff); + _i0 &= 0xfff00000U; + _i0 |= ((_i1 | -_i1) >> 9) & 0x400000; + SET_FLOAT_WORD(x, _i0); + w = TWO23[sx] + x; + t = w - TWO23[sx]; + GET_FLOAT_WORD(_i0, t); + SET_FLOAT_WORD(t, (_i0 & 0x7fffffff) | (sx << 31)); + return t; + } else { + i = (0x007fffff) >> _j0; + + if ((_i0 & i) == 0) { + return x; /* x is integral */ + } + + i >>= 1; + + if ((_i0 & i) != 0) { + _i0 = (_i0 & (~i)) | ((0x200000) >> _j0); + } + } + } else { + if (!FLT_UWORD_IS_FINITE(ix)) { + return x + x; /* inf or NaN */ + } else { + return x; /* x is integral */ + } + } + + SET_FLOAT_WORD(x, _i0); + w = TWO23[sx] + x; + return w - TWO23[sx]; +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double rint(double x) +{ + return (double) rintf((float) x); +} + +#endif /* #ifdef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathf/roundf.c b/libm/libmcs/libm/mathf/roundf.c new file mode 100644 index 00000000..d1ba9db4 --- /dev/null +++ b/libm/libmcs/libm/mathf/roundf.c @@ -0,0 +1,64 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +#include +#include "../common/tools.h" + +float roundf(float x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + uint32_t w; + /* Most significant word, least significant word. */ + int32_t exponent_less_127; + + GET_FLOAT_WORD(w, x); + + /* Extract exponent field. */ + exponent_less_127 = (int32_t)((w & 0x7f800000) >> 23) - 127; + + if (exponent_less_127 < 23) { + if (exponent_less_127 < 0) { + w &= 0x80000000U; + + if (exponent_less_127 == -1) { + /* Result is +1.0 or -1.0. */ + + w |= ((uint32_t)127 << 23); + } + } else { + uint32_t exponent_mask = 0x007fffff >> exponent_less_127; + + if ((w & exponent_mask) == 0) { + /* x has an integral value. */ + + return x; + } + + w += 0x00400000 >> exponent_less_127; + w &= ~exponent_mask; + } + } else { + if (exponent_less_127 == 128) { + /* x is NaN or infinite. */ + + return x + x; + } else { + return x; + } + } + + SET_FLOAT_WORD(x, w); + return x; +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double round(double x) +{ + return (double) roundf((float) x); +} + +#endif /* #ifdef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathf/scalblnf.c b/libm/libmcs/libm/mathf/scalblnf.c new file mode 100644 index 00000000..a02634ef --- /dev/null +++ b/libm/libmcs/libm/mathf/scalblnf.c @@ -0,0 +1,71 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ +/* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ + +#include +#include "../common/tools.h" + +static const float +two25 = 3.355443200e+07f, /* 0x4c000000 */ +twom25 = 2.9802322388e-08f; /* 0x33000000 */ + +float scalblnf(float x, long int n) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + 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 (k == 0xff) { + return x + x; /* NaN or Inf */ + } + + if (n > 50000) { + return __raise_overflowf(x); /*overflow*/ + } + + k = k + n; + + if (k > 0xfe) { + return __raise_overflowf(x); /*overflow*/ + } + + if (n < -50000) { + return __raise_underflowf(x); /*underflow*/ + } + + if (k > 0) { /* normal result */ + SET_FLOAT_WORD(x, (ix & 0x807fffffU) | (k << 23U)); + return x; + } + + if (k <= -25) { + return __raise_underflowf(x); /*underflow*/ + } + + k += 25; /* subnormal result */ + SET_FLOAT_WORD(x, (ix & 0x807fffffU) | (k << 23U)); + return x * twom25; +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double scalbln(double x, long int n) +{ + return (double) scalblnf((float) x, n); +} + +#endif /* #ifdef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathf/scalbnf.c b/libm/libmcs/libm/mathf/scalbnf.c new file mode 100644 index 00000000..8331f1fd --- /dev/null +++ b/libm/libmcs/libm/mathf/scalbnf.c @@ -0,0 +1,80 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ +/* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ + +#include +#include "../common/tools.h" + +#if INT_MAX > 50000 + #define OVERFLOW_INT 50000 +#else + #define OVERFLOW_INT 30000 +#endif + +static const float +two25 = 3.355443200e+07f, /* 0x4c000000 */ +twom25 = 2.9802322388e-08f; /* 0x33000000 */ + +float scalbnf(float x, int n) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + int32_t k, ix; + uint32_t hx; + + GET_FLOAT_WORD(ix, x); + hx = ix & 0x7fffffff; + k = hx >> 23; /* extract exponent */ + + if (FLT_UWORD_IS_ZERO(hx)) { + return x; + } + + if (!FLT_UWORD_IS_FINITE(hx)) { + return x + x; /* NaN or Inf */ + } + + if (FLT_UWORD_IS_SUBNORMAL(hx)) { + x *= two25; + GET_FLOAT_WORD(ix, x); + k = ((ix & 0x7f800000) >> 23) - 25; + + if (n < -50000) { + return __raise_underflowf(x); /*underflow*/ + } + } + + if (n > OVERFLOW_INT) { + return __raise_overflowf(x); /*overflow */ + } + + k = k + n; + + if (k > FLT_LARGEST_EXP) { + return __raise_overflowf(x); /*overflow */ + } + + if (k > 0) { /* normal result */ + SET_FLOAT_WORD(x, (ix & 0x807fffffU) | (k << 23U)); + return x; + } + + if (k < FLT_SMALLEST_EXP) { + return __raise_underflowf(x); /*underflow*/ + } + + k += 25; /* subnormal result */ + SET_FLOAT_WORD(x, (ix & 0x807fffffU) | (k << 23U)); + return x * twom25; +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double scalbn(double x, int n) +{ + return (double) scalbnf((float) x, n); +} + +#endif /* #ifdef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathf/sinf.c b/libm/libmcs/libm/mathf/sinf.c new file mode 100644 index 00000000..be6cc23a --- /dev/null +++ b/libm/libmcs/libm/mathf/sinf.c @@ -0,0 +1,70 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ +/* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ + +#include +#include "../common/tools.h" +#include "internal/trigf.h" + +float sinf(float x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + float y[2], z = 0.0f; + int32_t n, ix; + + GET_FLOAT_WORD(ix, x); + + /* |x| ~< pi/4 */ + ix &= 0x7fffffff; + + if (ix <= 0x3f490fd8) { + if(ix < 0x39800000) { /* if x < 2**-12 */ + if (FLT_UWORD_IS_ZERO(ix)) { /* return x inexact except 0 */ + return x; + } else { + return __raise_inexactf(x); + } + } + return __sinf(x, z, 0); + } + + /* sin(Inf or NaN) is NaN */ + else if (!FLT_UWORD_IS_FINITE(ix)) { + if (isnan(x)) { + return x + x; + } else { + return __raise_invalidf(); + } + } + + /* argument reduction needed */ + else { + n = __rem_pio2f(x, y); + + switch (n & 3) { + case 0: + return __sinf(y[0], y[1], 1); + + case 1: + return __cosf(y[0], y[1]); + + case 2: + return -__sinf(y[0], y[1], 1); + + default: + return -__cosf(y[0], y[1]); + } + } +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double sin(double x) +{ + return (double) sinf((float) x); +} + +#endif /* #ifdef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathf/sinhf.c b/libm/libmcs/libm/mathf/sinhf.c new file mode 100644 index 00000000..8193ab2c --- /dev/null +++ b/libm/libmcs/libm/mathf/sinhf.c @@ -0,0 +1,75 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ +/* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ + +#include +#include "../common/tools.h" + +static const float one = 1.0f; + +float sinhf(float x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + float t, w, h; + int32_t ix, jx; + + GET_FLOAT_WORD(jx, x); + ix = jx & 0x7fffffff; + + /* x is INF or NaN */ + if (!FLT_UWORD_IS_FINITE(ix)) { + return x + x; + } + + h = 0.5f; + + if (jx < 0) { + h = -h; + } + + /* |x| in [0,22], return sign(x)*0.5*(E+E/(E+1))) */ + if (ix < 0x41b00000) { /* |x|<22 */ + if (ix < 0x31800000) { /* |x|<2**-28 */ + if (FLT_UWORD_IS_ZERO(ix)) { /* return x inexact except 0 */ + return x; + } else { + return __raise_inexactf(x); + } + } + + t = expm1f(fabsf(x)); + + if (ix < 0x3f800000) { + return h * (2.0f * t - t * t / (t + one)); + } + + return h * (t + t / (t + one)); + } + + /* |x| in [22, log(maxfloat)] return 0.5*exp(|x|) */ + if (ix <= FLT_UWORD_LOG_MAX) { + return h * expf(fabsf(x)); + } + + /* |x| in [log(maxfloat), overflowthresold] */ + if (ix <= FLT_UWORD_LOG_2MAX) { + w = expf(0.5f * fabsf(x)); + t = h * w; + return t * w; + } + + /* |x| > overflowthresold, sinh(x) overflow */ + return __raise_overflowf(x); +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double sinh(double x) +{ + return (double) sinhf((float) x); +} + +#endif /* #ifdef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathf/sqrtf.c b/libm/libmcs/libm/mathf/sqrtf.c new file mode 100644 index 00000000..ea638e40 --- /dev/null +++ b/libm/libmcs/libm/mathf/sqrtf.c @@ -0,0 +1,97 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ +/* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ + +#include +#include "../common/tools.h" + +float sqrtf(float x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + float z; + uint32_t r, hx; + int32_t ix, s, q, m, t, i; + + GET_FLOAT_WORD(ix, x); + hx = ix & 0x7fffffff; + + /* take care of Inf and NaN */ + if (!FLT_UWORD_IS_FINITE(hx)) { + if (FLT_UWORD_IS_NAN(hx)) { /* sqrt(NaN)=NaN */ + return x + x; + } else if (ix > 0) { /* sqrt(+inf)=+inf */ + return x; + } else { /* sqrt(-inf)=sNaN */ + return __raise_invalidf(); + } + } + + /* take care of zero and -ves */ + if (FLT_UWORD_IS_ZERO(hx)) { + return x; /* sqrt(+-0) = +-0 */ + } + + if (ix < 0) { + return __raise_invalidf(); /* sqrt(-ve) = sNaN */ + } + + /* normalize x */ + m = (ix >> 23); + + if (FLT_UWORD_IS_SUBNORMAL(hx)) { /* subnormal x */ + for (i = 0; (ix & 0x00800000) == 0; i++) { + ix <<= 1; + } + + m -= i - 1; + } + + m -= 127; /* unbias exponent */ + ix = (ix & 0x007fffff) | 0x00800000; + + if (0 < (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; + } + + if (ix != 0) { + (void) __raise_inexactf(x); + q += (q & 1); + } + + ix = (q >> 1) + 0x3f000000; + ix += (m << 23); + SET_FLOAT_WORD(z, ix); + return z; +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double sqrt(double x) +{ + return (double) sqrtf((float) x); +} + +#endif /* #ifdef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathf/tanf.c b/libm/libmcs/libm/mathf/tanf.c new file mode 100644 index 00000000..b91e188a --- /dev/null +++ b/libm/libmcs/libm/mathf/tanf.c @@ -0,0 +1,133 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ +/* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ + +#include +#include "../common/tools.h" +#include "internal/trigf.h" + +static const float +pio4 = 7.8539812565e-01f, /* 0x3f490fda */ +pio4lo = 3.7748947079e-08f, /* 0x33222168 */ +T[] = { + 3.3333334327e-01f, /* 0x3eaaaaab */ + 1.3333334029e-01f, /* 0x3e088889 */ + 5.3968254477e-02f, /* 0x3d5d0dd1 */ + 2.1869488060e-02f, /* 0x3cb327a4 */ + 8.8632395491e-03f, /* 0x3c11371f */ + 3.5920790397e-03f, /* 0x3b6b6916 */ + 1.4562094584e-03f, /* 0x3abede48 */ + 5.8804126456e-04f, /* 0x3a1a26c8 */ + 2.4646313977e-04f, /* 0x398137b9 */ + 7.8179444245e-05f, /* 0x38a3f445 */ + 7.1407252108e-05f, /* 0x3895c07a */ + -1.8558637748e-05f, /* 0xb79bae5f */ + 2.5907305826e-05f, /* 0x37d95384 */ +}; + +static inline float __tanf(float x, float y, int iy) +{ + float z, r, v, w, s; + int32_t ix, hx; + + GET_FLOAT_WORD(hx, x); + ix = hx & 0x7fffffff; /* high word of |x| */ + + if (ix >= 0x3f2ca140) { /* |x|>=0.6744 */ + if (hx < 0) { + x = -x; + y = -y; + } + + z = pio4 - x; + w = pio4lo - y; + x = z + w; + y = 0.0f; + } + + 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 >= 0x3f2ca140) { + v = (float)iy; + return (float)(1 - ((hx >> 30) & 2)) * (v - 2.0f * (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 */ + float a, t; + int32_t i; + z = w; + GET_FLOAT_WORD(i, z); + SET_FLOAT_WORD(z, i & 0xfffff000U); + v = r - (z - x); /* z+v = r+x */ + t = a = -1.0f / w; /* a = -1.0/w */ + GET_FLOAT_WORD(i, t); + SET_FLOAT_WORD(t, i & 0xfffff000U); + s = 1.0f + t * z; + return t + a * (s + t * v); + } +} + +float tanf(float x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + float y[2], z = 0.0; + int32_t n, ix; + + GET_FLOAT_WORD(ix, x); + + /* |x| ~< pi/4 */ + ix &= 0x7fffffff; + + if (ix <= 0x3f490fda) { + if(ix < 0x39800000) { /* |x| < 2**-12 */ + if (FLT_UWORD_IS_ZERO(ix)) { /* return x inexact except 0 */ + return x; + } else { + return __raise_inexactf(x); + } + } + return __tanf(x, z, 1); + } + + /* tan(Inf or NaN) is NaN */ + else if (!FLT_UWORD_IS_FINITE(ix)) { + if (isnan(x)) { + return x + x; + } else { + return __raise_invalidf(); + } + } + + /* argument reduction needed */ + else { + n = __rem_pio2f(x, y); + return __tanf(y[0], y[1], 1 - ((n & 1) << 1)); /* 1 -- n even, -1 -- n odd */ + } +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double tan(double x) +{ + return (double) tanf((float) x); +} + +#endif /* #ifdef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathf/tanhf.c b/libm/libmcs/libm/mathf/tanhf.c new file mode 100644 index 00000000..dca784b2 --- /dev/null +++ b/libm/libmcs/libm/mathf/tanhf.c @@ -0,0 +1,66 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ +/* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ + +#include +#include "../common/tools.h" + +static const float one = 1.0f, two = 2.0f; + +float tanhf(float x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + float t, z; + int32_t jx, ix; + + GET_FLOAT_WORD(jx, x); + ix = jx & 0x7fffffff; + + /* x is INF or NaN */ + if (!FLT_UWORD_IS_FINITE(ix)) { + if (isnan(x)) { /* tanh(NaN) = NaN */ + return x + x; + } else if (jx >= 0) { + return one; /* tanh(+inf)=+1 */ + } else { + return -one; /* tanh(-inf)=-1 */ + } + } + + /* |x| < 22 */ + if (ix < 0x41b00000) { /* |x|<22 */ + if (ix < 0x24000000) { /* |x|<2**-55 */ + if (FLT_UWORD_IS_ZERO(ix)) { /* return x inexact except 0 */ + return x; + } else { + return __raise_inexactf(x); + } + } + + 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| > 22, return +-1 */ + } else { + z = __raise_inexactf(one); /* raised inexact flag */ + } + + return (jx >= 0) ? z : -z; +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double tanh(double x) +{ + return (double) tanhf((float) x); +} + +#endif /* #ifdef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathf/tgammaf.c b/libm/libmcs/libm/mathf/tgammaf.c new file mode 100644 index 00000000..dd95ab31 --- /dev/null +++ b/libm/libmcs/libm/mathf/tgammaf.c @@ -0,0 +1,50 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ +/* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ + +/* __tgammaf(x) + * Float version the Gamma function. Returns gamma(x) + * + * Method: See __lgammaf + */ + +#include +#include "../common/tools.h" +#include "internal/gammaf.h" + +float tgammaf(float x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + int signgam_local = 0; + float y = 0.0f; + + if (isnan(x) != 0) { /* tgamma(NaN) = NaN */ + return x + x; + } else if (x == 0.0f) { /* tgamma(+-0) = +-Inf */ + return __raise_div_by_zerof(x); + } else if (floorf(x) == x && x < 0.0f) { /* tgamma(negative integer, -Inf) = NaN */ + return __raise_invalidf(); + } else { + /* No action required */ + } + + y = expf(__lgammaf(x, &signgam_local)); + + if (signgam_local < 0) { + y = -y; + } + + return y; +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double tgamma(double x) +{ + return (double) tgammaf((float) x); +} + +#endif /* #ifdef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathf/truncf.c b/libm/libmcs/libm/mathf/truncf.c new file mode 100644 index 00000000..20c43bd5 --- /dev/null +++ b/libm/libmcs/libm/mathf/truncf.c @@ -0,0 +1,52 @@ +/* SPDX-License-Identifier: SunMicrosystems */ +/* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. */ + +#include +#include "../common/tools.h" + +float truncf(float x) +{ +#ifdef __LIBMCS_FPU_DAZ + x *= __volatile_onef; +#endif /* defined(__LIBMCS_FPU_DAZ) */ + + int32_t sb; + int32_t w; + int32_t exponent_less_127; + + GET_FLOAT_WORD(w, x); + + /* Extract sign bit. */ + sb = w & 0x80000000U; + + /* Extract exponent field. */ + exponent_less_127 = ((w & 0x7f800000) >> 23) - 127; + + if (exponent_less_127 < 23) { + if (exponent_less_127 < 0) { + /* -1 < x < 1, so result is +0 or -0. */ + SET_FLOAT_WORD(x, sb); + } else { + SET_FLOAT_WORD(x, sb | (w & ~(0x007fffff >> exponent_less_127))); + } + } else { + if (exponent_less_127 == 128) + /* x is NaN or infinite. */ + { + return x + x; + } + + /* All bits in the fraction field are relevant. */ + } + + return x; +} + +#ifdef __LIBMCS_DOUBLE_IS_32BITS + +double trunc(double x) +{ + return (double) truncf((float) x); +} + +#endif /* #ifdef __LIBMCS_DOUBLE_IS_32BITS */ diff --git a/libm/libmcs/libm/mathfe/internal/.gitkeep b/libm/libmcs/libm/mathfe/internal/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/libm/libmcs/libm/mathl/internal/.gitkeep b/libm/libmcs/libm/mathl/internal/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/libm/libmcs/poetry.lock b/libm/libmcs/poetry.lock new file mode 100644 index 00000000..65c97577 --- /dev/null +++ b/libm/libmcs/poetry.lock @@ -0,0 +1,1118 @@ +# This file is automatically @generated by Poetry 1.8.4 and should not be changed by hand. + +[[package]] +name = "alabaster" +version = "1.0.0" +description = "A light, configurable Sphinx theme" +optional = false +python-versions = ">=3.10" +files = [ + {file = "alabaster-1.0.0-py3-none-any.whl", hash = "sha256:fc6786402dc3fcb2de3cabd5fe455a2db534b371124f1f21de8731783dec828b"}, + {file = "alabaster-1.0.0.tar.gz", hash = "sha256:c00dca57bca26fa62a6d7d0a9fcce65f3e026e9bfe33e9c538fd3fbb2144fd9e"}, +] + +[[package]] +name = "babel" +version = "2.16.0" +description = "Internationalization utilities" +optional = false +python-versions = ">=3.8" +files = [ + {file = "babel-2.16.0-py3-none-any.whl", hash = "sha256:368b5b98b37c06b7daf6696391c3240c938b37767d4584413e8438c5c435fa8b"}, + {file = "babel-2.16.0.tar.gz", hash = "sha256:d1f3554ca26605fe173f3de0c65f750f5a42f924499bf134de6423582298e316"}, +] + +[package.extras] +dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"] + +[[package]] +name = "certifi" +version = "2024.8.30" +description = "Python package for providing Mozilla's CA Bundle." +optional = false +python-versions = ">=3.6" +files = [ + {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, + {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, +] + +[[package]] +name = "charset-normalizer" +version = "3.4.0" +description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, + {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, + {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, +] + +[[package]] +name = "clang" +version = "14.0.6" +description = "libclang python bindings" +optional = false +python-versions = "*" +files = [ + {file = "clang-14.0.6-py3-none-any.whl", hash = "sha256:1bb534a031473d6250fb6af7a2a7d545ca6d3e72781b4c688ee5c0782ce2e851"}, + {file = "clang-14.0.6.tar.gz", hash = "sha256:5ffb10e52328b6117c93b7b86fa5bf1df2d0bdfdd8011b208bda66209feee32a"}, +] + +[[package]] +name = "colorama" +version = "0.4.6" +description = "Cross-platform colored terminal text." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +files = [ + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] + +[[package]] +name = "contourpy" +version = "1.3.0" +description = "Python library for calculating contours of 2D quadrilateral grids" +optional = false +python-versions = ">=3.9" +files = [ + {file = "contourpy-1.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:880ea32e5c774634f9fcd46504bf9f080a41ad855f4fef54f5380f5133d343c7"}, + {file = "contourpy-1.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:76c905ef940a4474a6289c71d53122a4f77766eef23c03cd57016ce19d0f7b42"}, + {file = "contourpy-1.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:92f8557cbb07415a4d6fa191f20fd9d2d9eb9c0b61d1b2f52a8926e43c6e9af7"}, + {file = "contourpy-1.3.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:36f965570cff02b874773c49bfe85562b47030805d7d8360748f3eca570f4cab"}, + {file = "contourpy-1.3.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cacd81e2d4b6f89c9f8a5b69b86490152ff39afc58a95af002a398273e5ce589"}, + {file = "contourpy-1.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69375194457ad0fad3a839b9e29aa0b0ed53bb54db1bfb6c3ae43d111c31ce41"}, + {file = "contourpy-1.3.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:7a52040312b1a858b5e31ef28c2e865376a386c60c0e248370bbea2d3f3b760d"}, + {file = "contourpy-1.3.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3faeb2998e4fcb256542e8a926d08da08977f7f5e62cf733f3c211c2a5586223"}, + {file = "contourpy-1.3.0-cp310-cp310-win32.whl", hash = "sha256:36e0cff201bcb17a0a8ecc7f454fe078437fa6bda730e695a92f2d9932bd507f"}, + {file = "contourpy-1.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:87ddffef1dbe5e669b5c2440b643d3fdd8622a348fe1983fad7a0f0ccb1cd67b"}, + {file = "contourpy-1.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0fa4c02abe6c446ba70d96ece336e621efa4aecae43eaa9b030ae5fb92b309ad"}, + {file = "contourpy-1.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:834e0cfe17ba12f79963861e0f908556b2cedd52e1f75e6578801febcc6a9f49"}, + {file = "contourpy-1.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dbc4c3217eee163fa3984fd1567632b48d6dfd29216da3ded3d7b844a8014a66"}, + {file = "contourpy-1.3.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4865cd1d419e0c7a7bf6de1777b185eebdc51470800a9f42b9e9decf17762081"}, + {file = "contourpy-1.3.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:303c252947ab4b14c08afeb52375b26781ccd6a5ccd81abcdfc1fafd14cf93c1"}, + {file = "contourpy-1.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:637f674226be46f6ba372fd29d9523dd977a291f66ab2a74fbeb5530bb3f445d"}, + {file = "contourpy-1.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:76a896b2f195b57db25d6b44e7e03f221d32fe318d03ede41f8b4d9ba1bff53c"}, + {file = "contourpy-1.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e1fd23e9d01591bab45546c089ae89d926917a66dceb3abcf01f6105d927e2cb"}, + {file = "contourpy-1.3.0-cp311-cp311-win32.whl", hash = "sha256:d402880b84df3bec6eab53cd0cf802cae6a2ef9537e70cf75e91618a3801c20c"}, + {file = "contourpy-1.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:6cb6cc968059db9c62cb35fbf70248f40994dfcd7aa10444bbf8b3faeb7c2d67"}, + {file = "contourpy-1.3.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:570ef7cf892f0afbe5b2ee410c507ce12e15a5fa91017a0009f79f7d93a1268f"}, + {file = "contourpy-1.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:da84c537cb8b97d153e9fb208c221c45605f73147bd4cadd23bdae915042aad6"}, + {file = "contourpy-1.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0be4d8425bfa755e0fd76ee1e019636ccc7c29f77a7c86b4328a9eb6a26d0639"}, + {file = "contourpy-1.3.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9c0da700bf58f6e0b65312d0a5e695179a71d0163957fa381bb3c1f72972537c"}, + {file = "contourpy-1.3.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eb8b141bb00fa977d9122636b16aa67d37fd40a3d8b52dd837e536d64b9a4d06"}, + {file = "contourpy-1.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3634b5385c6716c258d0419c46d05c8aa7dc8cb70326c9a4fb66b69ad2b52e09"}, + {file = "contourpy-1.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0dce35502151b6bd35027ac39ba6e5a44be13a68f55735c3612c568cac3805fd"}, + {file = "contourpy-1.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:aea348f053c645100612b333adc5983d87be69acdc6d77d3169c090d3b01dc35"}, + {file = "contourpy-1.3.0-cp312-cp312-win32.whl", hash = "sha256:90f73a5116ad1ba7174341ef3ea5c3150ddf20b024b98fb0c3b29034752c8aeb"}, + {file = "contourpy-1.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:b11b39aea6be6764f84360fce6c82211a9db32a7c7de8fa6dd5397cf1d079c3b"}, + {file = "contourpy-1.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:3e1c7fa44aaae40a2247e2e8e0627f4bea3dd257014764aa644f319a5f8600e3"}, + {file = "contourpy-1.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:364174c2a76057feef647c802652f00953b575723062560498dc7930fc9b1cb7"}, + {file = "contourpy-1.3.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:32b238b3b3b649e09ce9aaf51f0c261d38644bdfa35cbaf7b263457850957a84"}, + {file = "contourpy-1.3.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d51fca85f9f7ad0b65b4b9fe800406d0d77017d7270d31ec3fb1cc07358fdea0"}, + {file = "contourpy-1.3.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:732896af21716b29ab3e988d4ce14bc5133733b85956316fb0c56355f398099b"}, + {file = "contourpy-1.3.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d73f659398a0904e125280836ae6f88ba9b178b2fed6884f3b1f95b989d2c8da"}, + {file = "contourpy-1.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c6c7c2408b7048082932cf4e641fa3b8ca848259212f51c8c59c45aa7ac18f14"}, + {file = "contourpy-1.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f317576606de89da6b7e0861cf6061f6146ead3528acabff9236458a6ba467f8"}, + {file = "contourpy-1.3.0-cp313-cp313-win32.whl", hash = "sha256:31cd3a85dbdf1fc002280c65caa7e2b5f65e4a973fcdf70dd2fdcb9868069294"}, + {file = "contourpy-1.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:4553c421929ec95fb07b3aaca0fae668b2eb5a5203d1217ca7c34c063c53d087"}, + {file = "contourpy-1.3.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:345af746d7766821d05d72cb8f3845dfd08dd137101a2cb9b24de277d716def8"}, + {file = "contourpy-1.3.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3bb3808858a9dc68f6f03d319acd5f1b8a337e6cdda197f02f4b8ff67ad2057b"}, + {file = "contourpy-1.3.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:420d39daa61aab1221567b42eecb01112908b2cab7f1b4106a52caaec8d36973"}, + {file = "contourpy-1.3.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4d63ee447261e963af02642ffcb864e5a2ee4cbfd78080657a9880b8b1868e18"}, + {file = "contourpy-1.3.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:167d6c890815e1dac9536dca00828b445d5d0df4d6a8c6adb4a7ec3166812fa8"}, + {file = "contourpy-1.3.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:710a26b3dc80c0e4febf04555de66f5fd17e9cf7170a7b08000601a10570bda6"}, + {file = "contourpy-1.3.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:75ee7cb1a14c617f34a51d11fa7524173e56551646828353c4af859c56b766e2"}, + {file = "contourpy-1.3.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:33c92cdae89ec5135d036e7218e69b0bb2851206077251f04a6c4e0e21f03927"}, + {file = "contourpy-1.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a11077e395f67ffc2c44ec2418cfebed032cd6da3022a94fc227b6faf8e2acb8"}, + {file = "contourpy-1.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e8134301d7e204c88ed7ab50028ba06c683000040ede1d617298611f9dc6240c"}, + {file = "contourpy-1.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e12968fdfd5bb45ffdf6192a590bd8ddd3ba9e58360b29683c6bb71a7b41edca"}, + {file = "contourpy-1.3.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fd2a0fc506eccaaa7595b7e1418951f213cf8255be2600f1ea1b61e46a60c55f"}, + {file = "contourpy-1.3.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4cfb5c62ce023dfc410d6059c936dcf96442ba40814aefbfa575425a3a7f19dc"}, + {file = "contourpy-1.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:68a32389b06b82c2fdd68276148d7b9275b5f5cf13e5417e4252f6d1a34f72a2"}, + {file = "contourpy-1.3.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:94e848a6b83da10898cbf1311a815f770acc9b6a3f2d646f330d57eb4e87592e"}, + {file = "contourpy-1.3.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:d78ab28a03c854a873787a0a42254a0ccb3cb133c672f645c9f9c8f3ae9d0800"}, + {file = "contourpy-1.3.0-cp39-cp39-win32.whl", hash = "sha256:81cb5ed4952aae6014bc9d0421dec7c5835c9c8c31cdf51910b708f548cf58e5"}, + {file = "contourpy-1.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:14e262f67bd7e6eb6880bc564dcda30b15e351a594657e55b7eec94b6ef72843"}, + {file = "contourpy-1.3.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:fe41b41505a5a33aeaed2a613dccaeaa74e0e3ead6dd6fd3a118fb471644fd6c"}, + {file = "contourpy-1.3.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eca7e17a65f72a5133bdbec9ecf22401c62bcf4821361ef7811faee695799779"}, + {file = "contourpy-1.3.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:1ec4dc6bf570f5b22ed0d7efba0dfa9c5b9e0431aeea7581aa217542d9e809a4"}, + {file = "contourpy-1.3.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:00ccd0dbaad6d804ab259820fa7cb0b8036bda0686ef844d24125d8287178ce0"}, + {file = "contourpy-1.3.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8ca947601224119117f7c19c9cdf6b3ab54c5726ef1d906aa4a69dfb6dd58102"}, + {file = "contourpy-1.3.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:c6ec93afeb848a0845a18989da3beca3eec2c0f852322efe21af1931147d12cb"}, + {file = "contourpy-1.3.0.tar.gz", hash = "sha256:7ffa0db17717a8ffb127efd0c95a4362d996b892c2904db72428d5b52e1938a4"}, +] + +[package.dependencies] +numpy = ">=1.23" + +[package.extras] +bokeh = ["bokeh", "selenium"] +docs = ["furo", "sphinx (>=7.2)", "sphinx-copybutton"] +mypy = ["contourpy[bokeh,docs]", "docutils-stubs", "mypy (==1.11.1)", "types-Pillow"] +test = ["Pillow", "contourpy[test-no-images]", "matplotlib"] +test-no-images = ["pytest", "pytest-cov", "pytest-rerunfailures", "pytest-xdist", "wurlitzer"] + +[[package]] +name = "cycler" +version = "0.12.1" +description = "Composable style cycles" +optional = false +python-versions = ">=3.8" +files = [ + {file = "cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30"}, + {file = "cycler-0.12.1.tar.gz", hash = "sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c"}, +] + +[package.extras] +docs = ["ipython", "matplotlib", "numpydoc", "sphinx"] +tests = ["pytest", "pytest-cov", "pytest-xdist"] + +[[package]] +name = "docutils" +version = "0.21.2" +description = "Docutils -- Python Documentation Utilities" +optional = false +python-versions = ">=3.9" +files = [ + {file = "docutils-0.21.2-py3-none-any.whl", hash = "sha256:dafca5b9e384f0e419294eb4d2ff9fa826435bf15f15b7bd45723e8ad76811b2"}, + {file = "docutils-0.21.2.tar.gz", hash = "sha256:3a6b18732edf182daa3cd12775bbb338cf5691468f91eeeb109deff6ebfa986f"}, +] + +[[package]] +name = "fonttools" +version = "4.54.1" +description = "Tools to manipulate font files" +optional = false +python-versions = ">=3.8" +files = [ + {file = "fonttools-4.54.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7ed7ee041ff7b34cc62f07545e55e1468808691dddfd315d51dd82a6b37ddef2"}, + {file = "fonttools-4.54.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:41bb0b250c8132b2fcac148e2e9198e62ff06f3cc472065dff839327945c5882"}, + {file = "fonttools-4.54.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7965af9b67dd546e52afcf2e38641b5be956d68c425bef2158e95af11d229f10"}, + {file = "fonttools-4.54.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:278913a168f90d53378c20c23b80f4e599dca62fbffae4cc620c8eed476b723e"}, + {file = "fonttools-4.54.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:0e88e3018ac809b9662615072dcd6b84dca4c2d991c6d66e1970a112503bba7e"}, + {file = "fonttools-4.54.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:4aa4817f0031206e637d1e685251ac61be64d1adef111060df84fdcbc6ab6c44"}, + {file = "fonttools-4.54.1-cp310-cp310-win32.whl", hash = "sha256:7e3b7d44e18c085fd8c16dcc6f1ad6c61b71ff463636fcb13df7b1b818bd0c02"}, + {file = "fonttools-4.54.1-cp310-cp310-win_amd64.whl", hash = "sha256:dd9cc95b8d6e27d01e1e1f1fae8559ef3c02c76317da650a19047f249acd519d"}, + {file = "fonttools-4.54.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5419771b64248484299fa77689d4f3aeed643ea6630b2ea750eeab219588ba20"}, + {file = "fonttools-4.54.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:301540e89cf4ce89d462eb23a89464fef50915255ece765d10eee8b2bf9d75b2"}, + {file = "fonttools-4.54.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76ae5091547e74e7efecc3cbf8e75200bc92daaeb88e5433c5e3e95ea8ce5aa7"}, + {file = "fonttools-4.54.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82834962b3d7c5ca98cb56001c33cf20eb110ecf442725dc5fdf36d16ed1ab07"}, + {file = "fonttools-4.54.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d26732ae002cc3d2ecab04897bb02ae3f11f06dd7575d1df46acd2f7c012a8d8"}, + {file = "fonttools-4.54.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:58974b4987b2a71ee08ade1e7f47f410c367cdfc5a94fabd599c88165f56213a"}, + {file = "fonttools-4.54.1-cp311-cp311-win32.whl", hash = "sha256:ab774fa225238986218a463f3fe151e04d8c25d7de09df7f0f5fce27b1243dbc"}, + {file = "fonttools-4.54.1-cp311-cp311-win_amd64.whl", hash = "sha256:07e005dc454eee1cc60105d6a29593459a06321c21897f769a281ff2d08939f6"}, + {file = "fonttools-4.54.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:54471032f7cb5fca694b5f1a0aaeba4af6e10ae989df408e0216f7fd6cdc405d"}, + {file = "fonttools-4.54.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8fa92cb248e573daab8d032919623cc309c005086d743afb014c836636166f08"}, + {file = "fonttools-4.54.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a911591200114969befa7f2cb74ac148bce5a91df5645443371aba6d222e263"}, + {file = "fonttools-4.54.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:93d458c8a6a354dc8b48fc78d66d2a8a90b941f7fec30e94c7ad9982b1fa6bab"}, + {file = "fonttools-4.54.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5eb2474a7c5be8a5331146758debb2669bf5635c021aee00fd7c353558fc659d"}, + {file = "fonttools-4.54.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c9c563351ddc230725c4bdf7d9e1e92cbe6ae8553942bd1fb2b2ff0884e8b714"}, + {file = "fonttools-4.54.1-cp312-cp312-win32.whl", hash = "sha256:fdb062893fd6d47b527d39346e0c5578b7957dcea6d6a3b6794569370013d9ac"}, + {file = "fonttools-4.54.1-cp312-cp312-win_amd64.whl", hash = "sha256:e4564cf40cebcb53f3dc825e85910bf54835e8a8b6880d59e5159f0f325e637e"}, + {file = "fonttools-4.54.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:6e37561751b017cf5c40fce0d90fd9e8274716de327ec4ffb0df957160be3bff"}, + {file = "fonttools-4.54.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:357cacb988a18aace66e5e55fe1247f2ee706e01debc4b1a20d77400354cddeb"}, + {file = "fonttools-4.54.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8e953cc0bddc2beaf3a3c3b5dd9ab7554677da72dfaf46951e193c9653e515a"}, + {file = "fonttools-4.54.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:58d29b9a294573d8319f16f2f79e42428ba9b6480442fa1836e4eb89c4d9d61c"}, + {file = "fonttools-4.54.1-cp313-cp313-win32.whl", hash = "sha256:9ef1b167e22709b46bf8168368b7b5d3efeaaa746c6d39661c1b4405b6352e58"}, + {file = "fonttools-4.54.1-cp313-cp313-win_amd64.whl", hash = "sha256:262705b1663f18c04250bd1242b0515d3bbae177bee7752be67c979b7d47f43d"}, + {file = "fonttools-4.54.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ed2f80ca07025551636c555dec2b755dd005e2ea8fbeb99fc5cdff319b70b23b"}, + {file = "fonttools-4.54.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9dc080e5a1c3b2656caff2ac2633d009b3a9ff7b5e93d0452f40cd76d3da3b3c"}, + {file = "fonttools-4.54.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d152d1be65652fc65e695e5619e0aa0982295a95a9b29b52b85775243c06556"}, + {file = "fonttools-4.54.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8583e563df41fdecef31b793b4dd3af8a9caa03397be648945ad32717a92885b"}, + {file = "fonttools-4.54.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:0d1d353ef198c422515a3e974a1e8d5b304cd54a4c2eebcae708e37cd9eeffb1"}, + {file = "fonttools-4.54.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:fda582236fee135d4daeca056c8c88ec5f6f6d88a004a79b84a02547c8f57386"}, + {file = "fonttools-4.54.1-cp38-cp38-win32.whl", hash = "sha256:e7d82b9e56716ed32574ee106cabca80992e6bbdcf25a88d97d21f73a0aae664"}, + {file = "fonttools-4.54.1-cp38-cp38-win_amd64.whl", hash = "sha256:ada215fd079e23e060157aab12eba0d66704316547f334eee9ff26f8c0d7b8ab"}, + {file = "fonttools-4.54.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:f5b8a096e649768c2f4233f947cf9737f8dbf8728b90e2771e2497c6e3d21d13"}, + {file = "fonttools-4.54.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4e10d2e0a12e18f4e2dd031e1bf7c3d7017be5c8dbe524d07706179f355c5dac"}, + {file = "fonttools-4.54.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:31c32d7d4b0958600eac75eaf524b7b7cb68d3a8c196635252b7a2c30d80e986"}, + {file = "fonttools-4.54.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c39287f5c8f4a0c5a55daf9eaf9ccd223ea59eed3f6d467133cc727d7b943a55"}, + {file = "fonttools-4.54.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:a7a310c6e0471602fe3bf8efaf193d396ea561486aeaa7adc1f132e02d30c4b9"}, + {file = "fonttools-4.54.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:d3b659d1029946f4ff9b6183984578041b520ce0f8fb7078bb37ec7445806b33"}, + {file = "fonttools-4.54.1-cp39-cp39-win32.whl", hash = "sha256:e96bc94c8cda58f577277d4a71f51c8e2129b8b36fd05adece6320dd3d57de8a"}, + {file = "fonttools-4.54.1-cp39-cp39-win_amd64.whl", hash = "sha256:e8a4b261c1ef91e7188a30571be6ad98d1c6d9fa2427244c545e2fa0a2494dd7"}, + {file = "fonttools-4.54.1-py3-none-any.whl", hash = "sha256:37cddd62d83dc4f72f7c3f3c2bcf2697e89a30efb152079896544a93907733bd"}, + {file = "fonttools-4.54.1.tar.gz", hash = "sha256:957f669d4922f92c171ba01bef7f29410668db09f6c02111e22b2bce446f3285"}, +] + +[package.extras] +all = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "fs (>=2.2.0,<3)", "lxml (>=4.0)", "lz4 (>=1.7.4.2)", "matplotlib", "munkres", "pycairo", "scipy", "skia-pathops (>=0.5.0)", "sympy", "uharfbuzz (>=0.23.0)", "unicodedata2 (>=15.1.0)", "xattr", "zopfli (>=0.1.4)"] +graphite = ["lz4 (>=1.7.4.2)"] +interpolatable = ["munkres", "pycairo", "scipy"] +lxml = ["lxml (>=4.0)"] +pathops = ["skia-pathops (>=0.5.0)"] +plot = ["matplotlib"] +repacker = ["uharfbuzz (>=0.23.0)"] +symfont = ["sympy"] +type1 = ["xattr"] +ufo = ["fs (>=2.2.0,<3)"] +unicode = ["unicodedata2 (>=15.1.0)"] +woff = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "zopfli (>=0.1.4)"] + +[[package]] +name = "hawkmoth" +version = "0.19.0" +description = "Hawkmoth - Sphinx Autodoc for C" +optional = false +python-versions = "~=3.9" +files = [ + {file = "hawkmoth-0.19.0-py3-none-any.whl", hash = "sha256:7eb42a235274ea5ed383af9c2ea4b4a53466152ec8c3af90f145b731d493814f"}, + {file = "hawkmoth-0.19.0.tar.gz", hash = "sha256:3718d2520fd9ce7b80288b736dcfec2276466d0c492d7cb41cbc822f12caf32a"}, +] + +[package.dependencies] +sphinx = ">=3" + +[package.extras] +dev = ["flake8", "mypy", "pytest", "pytest-cov", "pytest-xdist", "restructuredtext-lint", "strictyaml", "types-docutils"] + +[[package]] +name = "idna" +version = "3.10" +description = "Internationalized Domain Names in Applications (IDNA)" +optional = false +python-versions = ">=3.6" +files = [ + {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, + {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, +] + +[package.extras] +all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] + +[[package]] +name = "imagesize" +version = "1.4.1" +description = "Getting image size from png/jpeg/jpeg2000/gif file" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b"}, + {file = "imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a"}, +] + +[[package]] +name = "jinja2" +version = "3.1.4" +description = "A very fast and expressive template engine." +optional = false +python-versions = ">=3.7" +files = [ + {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, + {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, +] + +[package.dependencies] +MarkupSafe = ">=2.0" + +[package.extras] +i18n = ["Babel (>=2.7)"] + +[[package]] +name = "kiwisolver" +version = "1.4.7" +description = "A fast implementation of the Cassowary constraint solver" +optional = false +python-versions = ">=3.8" +files = [ + {file = "kiwisolver-1.4.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8a9c83f75223d5e48b0bc9cb1bf2776cf01563e00ade8775ffe13b0b6e1af3a6"}, + {file = "kiwisolver-1.4.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:58370b1ffbd35407444d57057b57da5d6549d2d854fa30249771775c63b5fe17"}, + {file = "kiwisolver-1.4.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:aa0abdf853e09aff551db11fce173e2177d00786c688203f52c87ad7fcd91ef9"}, + {file = "kiwisolver-1.4.7-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:8d53103597a252fb3ab8b5845af04c7a26d5e7ea8122303dd7a021176a87e8b9"}, + {file = "kiwisolver-1.4.7-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:88f17c5ffa8e9462fb79f62746428dd57b46eb931698e42e990ad63103f35e6c"}, + {file = "kiwisolver-1.4.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88a9ca9c710d598fd75ee5de59d5bda2684d9db36a9f50b6125eaea3969c2599"}, + {file = "kiwisolver-1.4.7-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f4d742cb7af1c28303a51b7a27aaee540e71bb8e24f68c736f6f2ffc82f2bf05"}, + {file = "kiwisolver-1.4.7-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e28c7fea2196bf4c2f8d46a0415c77a1c480cc0724722f23d7410ffe9842c407"}, + {file = "kiwisolver-1.4.7-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e968b84db54f9d42046cf154e02911e39c0435c9801681e3fc9ce8a3c4130278"}, + {file = "kiwisolver-1.4.7-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0c18ec74c0472de033e1bebb2911c3c310eef5649133dd0bedf2a169a1b269e5"}, + {file = "kiwisolver-1.4.7-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:8f0ea6da6d393d8b2e187e6a5e3fb81f5862010a40c3945e2c6d12ae45cfb2ad"}, + {file = "kiwisolver-1.4.7-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:f106407dda69ae456dd1227966bf445b157ccc80ba0dff3802bb63f30b74e895"}, + {file = "kiwisolver-1.4.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:84ec80df401cfee1457063732d90022f93951944b5b58975d34ab56bb150dfb3"}, + {file = "kiwisolver-1.4.7-cp310-cp310-win32.whl", hash = "sha256:71bb308552200fb2c195e35ef05de12f0c878c07fc91c270eb3d6e41698c3bcc"}, + {file = "kiwisolver-1.4.7-cp310-cp310-win_amd64.whl", hash = "sha256:44756f9fd339de0fb6ee4f8c1696cfd19b2422e0d70b4cefc1cc7f1f64045a8c"}, + {file = "kiwisolver-1.4.7-cp310-cp310-win_arm64.whl", hash = "sha256:78a42513018c41c2ffd262eb676442315cbfe3c44eed82385c2ed043bc63210a"}, + {file = "kiwisolver-1.4.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:d2b0e12a42fb4e72d509fc994713d099cbb15ebf1103545e8a45f14da2dfca54"}, + {file = "kiwisolver-1.4.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2a8781ac3edc42ea4b90bc23e7d37b665d89423818e26eb6df90698aa2287c95"}, + {file = "kiwisolver-1.4.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:46707a10836894b559e04b0fd143e343945c97fd170d69a2d26d640b4e297935"}, + {file = "kiwisolver-1.4.7-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ef97b8df011141c9b0f6caf23b29379f87dd13183c978a30a3c546d2c47314cb"}, + {file = "kiwisolver-1.4.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ab58c12a2cd0fc769089e6d38466c46d7f76aced0a1f54c77652446733d2d02"}, + {file = "kiwisolver-1.4.7-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:803b8e1459341c1bb56d1c5c010406d5edec8a0713a0945851290a7930679b51"}, + {file = "kiwisolver-1.4.7-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f9a9e8a507420fe35992ee9ecb302dab68550dedc0da9e2880dd88071c5fb052"}, + {file = "kiwisolver-1.4.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18077b53dc3bb490e330669a99920c5e6a496889ae8c63b58fbc57c3d7f33a18"}, + {file = "kiwisolver-1.4.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6af936f79086a89b3680a280c47ea90b4df7047b5bdf3aa5c524bbedddb9e545"}, + {file = "kiwisolver-1.4.7-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:3abc5b19d24af4b77d1598a585b8a719beb8569a71568b66f4ebe1fb0449460b"}, + {file = "kiwisolver-1.4.7-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:933d4de052939d90afbe6e9d5273ae05fb836cc86c15b686edd4b3560cc0ee36"}, + {file = "kiwisolver-1.4.7-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:65e720d2ab2b53f1f72fb5da5fb477455905ce2c88aaa671ff0a447c2c80e8e3"}, + {file = "kiwisolver-1.4.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3bf1ed55088f214ba6427484c59553123fdd9b218a42bbc8c6496d6754b1e523"}, + {file = "kiwisolver-1.4.7-cp311-cp311-win32.whl", hash = "sha256:4c00336b9dd5ad96d0a558fd18a8b6f711b7449acce4c157e7343ba92dd0cf3d"}, + {file = "kiwisolver-1.4.7-cp311-cp311-win_amd64.whl", hash = "sha256:929e294c1ac1e9f615c62a4e4313ca1823ba37326c164ec720a803287c4c499b"}, + {file = "kiwisolver-1.4.7-cp311-cp311-win_arm64.whl", hash = "sha256:e33e8fbd440c917106b237ef1a2f1449dfbb9b6f6e1ce17c94cd6a1e0d438376"}, + {file = "kiwisolver-1.4.7-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:5360cc32706dab3931f738d3079652d20982511f7c0ac5711483e6eab08efff2"}, + {file = "kiwisolver-1.4.7-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:942216596dc64ddb25adb215c3c783215b23626f8d84e8eff8d6d45c3f29f75a"}, + {file = "kiwisolver-1.4.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:48b571ecd8bae15702e4f22d3ff6a0f13e54d3d00cd25216d5e7f658242065ee"}, + {file = "kiwisolver-1.4.7-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ad42ba922c67c5f219097b28fae965e10045ddf145d2928bfac2eb2e17673640"}, + {file = "kiwisolver-1.4.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:612a10bdae23404a72941a0fc8fa2660c6ea1217c4ce0dbcab8a8f6543ea9e7f"}, + {file = "kiwisolver-1.4.7-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9e838bba3a3bac0fe06d849d29772eb1afb9745a59710762e4ba3f4cb8424483"}, + {file = "kiwisolver-1.4.7-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:22f499f6157236c19f4bbbd472fa55b063db77a16cd74d49afe28992dff8c258"}, + {file = "kiwisolver-1.4.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:693902d433cf585133699972b6d7c42a8b9f8f826ebcaf0132ff55200afc599e"}, + {file = "kiwisolver-1.4.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4e77f2126c3e0b0d055f44513ed349038ac180371ed9b52fe96a32aa071a5107"}, + {file = "kiwisolver-1.4.7-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:657a05857bda581c3656bfc3b20e353c232e9193eb167766ad2dc58b56504948"}, + {file = "kiwisolver-1.4.7-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:4bfa75a048c056a411f9705856abfc872558e33c055d80af6a380e3658766038"}, + {file = "kiwisolver-1.4.7-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:34ea1de54beef1c104422d210c47c7d2a4999bdecf42c7b5718fbe59a4cac383"}, + {file = "kiwisolver-1.4.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:90da3b5f694b85231cf93586dad5e90e2d71b9428f9aad96952c99055582f520"}, + {file = "kiwisolver-1.4.7-cp312-cp312-win32.whl", hash = "sha256:18e0cca3e008e17fe9b164b55735a325140a5a35faad8de92dd80265cd5eb80b"}, + {file = "kiwisolver-1.4.7-cp312-cp312-win_amd64.whl", hash = "sha256:58cb20602b18f86f83a5c87d3ee1c766a79c0d452f8def86d925e6c60fbf7bfb"}, + {file = "kiwisolver-1.4.7-cp312-cp312-win_arm64.whl", hash = "sha256:f5a8b53bdc0b3961f8b6125e198617c40aeed638b387913bf1ce78afb1b0be2a"}, + {file = "kiwisolver-1.4.7-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:2e6039dcbe79a8e0f044f1c39db1986a1b8071051efba3ee4d74f5b365f5226e"}, + {file = "kiwisolver-1.4.7-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a1ecf0ac1c518487d9d23b1cd7139a6a65bc460cd101ab01f1be82ecf09794b6"}, + {file = "kiwisolver-1.4.7-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7ab9ccab2b5bd5702ab0803676a580fffa2aa178c2badc5557a84cc943fcf750"}, + {file = "kiwisolver-1.4.7-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f816dd2277f8d63d79f9c8473a79fe54047bc0467754962840782c575522224d"}, + {file = "kiwisolver-1.4.7-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cf8bcc23ceb5a1b624572a1623b9f79d2c3b337c8c455405ef231933a10da379"}, + {file = "kiwisolver-1.4.7-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dea0bf229319828467d7fca8c7c189780aa9ff679c94539eed7532ebe33ed37c"}, + {file = "kiwisolver-1.4.7-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c06a4c7cf15ec739ce0e5971b26c93638730090add60e183530d70848ebdd34"}, + {file = "kiwisolver-1.4.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:913983ad2deb14e66d83c28b632fd35ba2b825031f2fa4ca29675e665dfecbe1"}, + {file = "kiwisolver-1.4.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5337ec7809bcd0f424c6b705ecf97941c46279cf5ed92311782c7c9c2026f07f"}, + {file = "kiwisolver-1.4.7-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:4c26ed10c4f6fa6ddb329a5120ba3b6db349ca192ae211e882970bfc9d91420b"}, + {file = "kiwisolver-1.4.7-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c619b101e6de2222c1fcb0531e1b17bbffbe54294bfba43ea0d411d428618c27"}, + {file = "kiwisolver-1.4.7-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:073a36c8273647592ea332e816e75ef8da5c303236ec0167196793eb1e34657a"}, + {file = "kiwisolver-1.4.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:3ce6b2b0231bda412463e152fc18335ba32faf4e8c23a754ad50ffa70e4091ee"}, + {file = "kiwisolver-1.4.7-cp313-cp313-win32.whl", hash = "sha256:f4c9aee212bc89d4e13f58be11a56cc8036cabad119259d12ace14b34476fd07"}, + {file = "kiwisolver-1.4.7-cp313-cp313-win_amd64.whl", hash = "sha256:8a3ec5aa8e38fc4c8af308917ce12c536f1c88452ce554027e55b22cbbfbff76"}, + {file = "kiwisolver-1.4.7-cp313-cp313-win_arm64.whl", hash = "sha256:76c8094ac20ec259471ac53e774623eb62e6e1f56cd8690c67ce6ce4fcb05650"}, + {file = "kiwisolver-1.4.7-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5d5abf8f8ec1f4e22882273c423e16cae834c36856cac348cfbfa68e01c40f3a"}, + {file = "kiwisolver-1.4.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:aeb3531b196ef6f11776c21674dba836aeea9d5bd1cf630f869e3d90b16cfade"}, + {file = "kiwisolver-1.4.7-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b7d755065e4e866a8086c9bdada157133ff466476a2ad7861828e17b6026e22c"}, + {file = "kiwisolver-1.4.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:08471d4d86cbaec61f86b217dd938a83d85e03785f51121e791a6e6689a3be95"}, + {file = "kiwisolver-1.4.7-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7bbfcb7165ce3d54a3dfbe731e470f65739c4c1f85bb1018ee912bae139e263b"}, + {file = "kiwisolver-1.4.7-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5d34eb8494bea691a1a450141ebb5385e4b69d38bb8403b5146ad279f4b30fa3"}, + {file = "kiwisolver-1.4.7-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9242795d174daa40105c1d86aba618e8eab7bf96ba8c3ee614da8302a9f95503"}, + {file = "kiwisolver-1.4.7-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:a0f64a48bb81af7450e641e3fe0b0394d7381e342805479178b3d335d60ca7cf"}, + {file = "kiwisolver-1.4.7-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8e045731a5416357638d1700927529e2b8ab304811671f665b225f8bf8d8f933"}, + {file = "kiwisolver-1.4.7-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:4322872d5772cae7369f8351da1edf255a604ea7087fe295411397d0cfd9655e"}, + {file = "kiwisolver-1.4.7-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:e1631290ee9271dffe3062d2634c3ecac02c83890ada077d225e081aca8aab89"}, + {file = "kiwisolver-1.4.7-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:edcfc407e4eb17e037bca59be0e85a2031a2ac87e4fed26d3e9df88b4165f92d"}, + {file = "kiwisolver-1.4.7-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:4d05d81ecb47d11e7f8932bd8b61b720bf0b41199358f3f5e36d38e28f0532c5"}, + {file = "kiwisolver-1.4.7-cp38-cp38-win32.whl", hash = "sha256:b38ac83d5f04b15e515fd86f312479d950d05ce2368d5413d46c088dda7de90a"}, + {file = "kiwisolver-1.4.7-cp38-cp38-win_amd64.whl", hash = "sha256:d83db7cde68459fc803052a55ace60bea2bae361fc3b7a6d5da07e11954e4b09"}, + {file = "kiwisolver-1.4.7-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:3f9362ecfca44c863569d3d3c033dbe8ba452ff8eed6f6b5806382741a1334bd"}, + {file = "kiwisolver-1.4.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e8df2eb9b2bac43ef8b082e06f750350fbbaf2887534a5be97f6cf07b19d9583"}, + {file = "kiwisolver-1.4.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f32d6edbc638cde7652bd690c3e728b25332acbadd7cad670cc4a02558d9c417"}, + {file = "kiwisolver-1.4.7-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:e2e6c39bd7b9372b0be21456caab138e8e69cc0fc1190a9dfa92bd45a1e6e904"}, + {file = "kiwisolver-1.4.7-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:dda56c24d869b1193fcc763f1284b9126550eaf84b88bbc7256e15028f19188a"}, + {file = "kiwisolver-1.4.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79849239c39b5e1fd906556c474d9b0439ea6792b637511f3fe3a41158d89ca8"}, + {file = "kiwisolver-1.4.7-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5e3bc157fed2a4c02ec468de4ecd12a6e22818d4f09cde2c31ee3226ffbefab2"}, + {file = "kiwisolver-1.4.7-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3da53da805b71e41053dc670f9a820d1157aae77b6b944e08024d17bcd51ef88"}, + {file = "kiwisolver-1.4.7-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:8705f17dfeb43139a692298cb6637ee2e59c0194538153e83e9ee0c75c2eddde"}, + {file = "kiwisolver-1.4.7-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:82a5c2f4b87c26bb1a0ef3d16b5c4753434633b83d365cc0ddf2770c93829e3c"}, + {file = "kiwisolver-1.4.7-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ce8be0466f4c0d585cdb6c1e2ed07232221df101a4c6f28821d2aa754ca2d9e2"}, + {file = "kiwisolver-1.4.7-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:409afdfe1e2e90e6ee7fc896f3df9a7fec8e793e58bfa0d052c8a82f99c37abb"}, + {file = "kiwisolver-1.4.7-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:5b9c3f4ee0b9a439d2415012bd1b1cc2df59e4d6a9939f4d669241d30b414327"}, + {file = "kiwisolver-1.4.7-cp39-cp39-win32.whl", hash = "sha256:a79ae34384df2b615eefca647a2873842ac3b596418032bef9a7283675962644"}, + {file = "kiwisolver-1.4.7-cp39-cp39-win_amd64.whl", hash = "sha256:cf0438b42121a66a3a667de17e779330fc0f20b0d97d59d2f2121e182b0505e4"}, + {file = "kiwisolver-1.4.7-cp39-cp39-win_arm64.whl", hash = "sha256:764202cc7e70f767dab49e8df52c7455e8de0df5d858fa801a11aa0d882ccf3f"}, + {file = "kiwisolver-1.4.7-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:94252291e3fe68001b1dd747b4c0b3be12582839b95ad4d1b641924d68fd4643"}, + {file = "kiwisolver-1.4.7-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:5b7dfa3b546da08a9f622bb6becdb14b3e24aaa30adba66749d38f3cc7ea9706"}, + {file = "kiwisolver-1.4.7-pp310-pypy310_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bd3de6481f4ed8b734da5df134cd5a6a64fe32124fe83dde1e5b5f29fe30b1e6"}, + {file = "kiwisolver-1.4.7-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a91b5f9f1205845d488c928e8570dcb62b893372f63b8b6e98b863ebd2368ff2"}, + {file = "kiwisolver-1.4.7-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40fa14dbd66b8b8f470d5fc79c089a66185619d31645f9b0773b88b19f7223c4"}, + {file = "kiwisolver-1.4.7-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:eb542fe7933aa09d8d8f9d9097ef37532a7df6497819d16efe4359890a2f417a"}, + {file = "kiwisolver-1.4.7-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:bfa1acfa0c54932d5607e19a2c24646fb4c1ae2694437789129cf099789a3b00"}, + {file = "kiwisolver-1.4.7-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:eee3ea935c3d227d49b4eb85660ff631556841f6e567f0f7bda972df6c2c9935"}, + {file = "kiwisolver-1.4.7-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:f3160309af4396e0ed04db259c3ccbfdc3621b5559b5453075e5de555e1f3a1b"}, + {file = "kiwisolver-1.4.7-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a17f6a29cf8935e587cc8a4dbfc8368c55edc645283db0ce9801016f83526c2d"}, + {file = "kiwisolver-1.4.7-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:10849fb2c1ecbfae45a693c070e0320a91b35dd4bcf58172c023b994283a124d"}, + {file = "kiwisolver-1.4.7-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:ac542bf38a8a4be2dc6b15248d36315ccc65f0743f7b1a76688ffb6b5129a5c2"}, + {file = "kiwisolver-1.4.7-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:8b01aac285f91ca889c800042c35ad3b239e704b150cfd3382adfc9dcc780e39"}, + {file = "kiwisolver-1.4.7-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:48be928f59a1f5c8207154f935334d374e79f2b5d212826307d072595ad76a2e"}, + {file = "kiwisolver-1.4.7-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f37cfe618a117e50d8c240555331160d73d0411422b59b5ee217843d7b693608"}, + {file = "kiwisolver-1.4.7-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:599b5c873c63a1f6ed7eead644a8a380cfbdf5db91dcb6f85707aaab213b1674"}, + {file = "kiwisolver-1.4.7-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:801fa7802e5cfabe3ab0c81a34c323a319b097dfb5004be950482d882f3d7225"}, + {file = "kiwisolver-1.4.7-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:0c6c43471bc764fad4bc99c5c2d6d16a676b1abf844ca7c8702bdae92df01ee0"}, + {file = "kiwisolver-1.4.7.tar.gz", hash = "sha256:9893ff81bd7107f7b685d3017cc6583daadb4fc26e4a888350df530e41980a60"}, +] + +[[package]] +name = "markupsafe" +version = "3.0.2" +description = "Safely add untrusted strings to HTML/XML markup." +optional = false +python-versions = ">=3.9" +files = [ + {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-win32.whl", hash = "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-win32.whl", hash = "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-win32.whl", hash = "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a"}, + {file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"}, +] + +[[package]] +name = "matplotlib" +version = "3.9.2" +description = "Python plotting package" +optional = false +python-versions = ">=3.9" +files = [ + {file = "matplotlib-3.9.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:9d78bbc0cbc891ad55b4f39a48c22182e9bdaea7fc0e5dbd364f49f729ca1bbb"}, + {file = "matplotlib-3.9.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c375cc72229614632c87355366bdf2570c2dac01ac66b8ad048d2dabadf2d0d4"}, + {file = "matplotlib-3.9.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d94ff717eb2bd0b58fe66380bd8b14ac35f48a98e7c6765117fe67fb7684e64"}, + {file = "matplotlib-3.9.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ab68d50c06938ef28681073327795c5db99bb4666214d2d5f880ed11aeaded66"}, + {file = "matplotlib-3.9.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:65aacf95b62272d568044531e41de26285d54aec8cb859031f511f84bd8b495a"}, + {file = "matplotlib-3.9.2-cp310-cp310-win_amd64.whl", hash = "sha256:3fd595f34aa8a55b7fc8bf9ebea8aa665a84c82d275190a61118d33fbc82ccae"}, + {file = "matplotlib-3.9.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:d8dd059447824eec055e829258ab092b56bb0579fc3164fa09c64f3acd478772"}, + {file = "matplotlib-3.9.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c797dac8bb9c7a3fd3382b16fe8f215b4cf0f22adccea36f1545a6d7be310b41"}, + {file = "matplotlib-3.9.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d719465db13267bcef19ea8954a971db03b9f48b4647e3860e4bc8e6ed86610f"}, + {file = "matplotlib-3.9.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8912ef7c2362f7193b5819d17dae8629b34a95c58603d781329712ada83f9447"}, + {file = "matplotlib-3.9.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7741f26a58a240f43bee74965c4882b6c93df3e7eb3de160126d8c8f53a6ae6e"}, + {file = "matplotlib-3.9.2-cp311-cp311-win_amd64.whl", hash = "sha256:ae82a14dab96fbfad7965403c643cafe6515e386de723e498cf3eeb1e0b70cc7"}, + {file = "matplotlib-3.9.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:ac43031375a65c3196bee99f6001e7fa5bdfb00ddf43379d3c0609bdca042df9"}, + {file = "matplotlib-3.9.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:be0fc24a5e4531ae4d8e858a1a548c1fe33b176bb13eff7f9d0d38ce5112a27d"}, + {file = "matplotlib-3.9.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf81de2926c2db243c9b2cbc3917619a0fc85796c6ba4e58f541df814bbf83c7"}, + {file = "matplotlib-3.9.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6ee45bc4245533111ced13f1f2cace1e7f89d1c793390392a80c139d6cf0e6c"}, + {file = "matplotlib-3.9.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:306c8dfc73239f0e72ac50e5a9cf19cc4e8e331dd0c54f5e69ca8758550f1e1e"}, + {file = "matplotlib-3.9.2-cp312-cp312-win_amd64.whl", hash = "sha256:5413401594cfaff0052f9d8b1aafc6d305b4bd7c4331dccd18f561ff7e1d3bd3"}, + {file = "matplotlib-3.9.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:18128cc08f0d3cfff10b76baa2f296fc28c4607368a8402de61bb3f2eb33c7d9"}, + {file = "matplotlib-3.9.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4876d7d40219e8ae8bb70f9263bcbe5714415acfdf781086601211335e24f8aa"}, + {file = "matplotlib-3.9.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6d9f07a80deab4bb0b82858a9e9ad53d1382fd122be8cde11080f4e7dfedb38b"}, + {file = "matplotlib-3.9.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f7c0410f181a531ec4e93bbc27692f2c71a15c2da16766f5ba9761e7ae518413"}, + {file = "matplotlib-3.9.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:909645cce2dc28b735674ce0931a4ac94e12f5b13f6bb0b5a5e65e7cea2c192b"}, + {file = "matplotlib-3.9.2-cp313-cp313-win_amd64.whl", hash = "sha256:f32c7410c7f246838a77d6d1eff0c0f87f3cb0e7c4247aebea71a6d5a68cab49"}, + {file = "matplotlib-3.9.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:37e51dd1c2db16ede9cfd7b5cabdfc818b2c6397c83f8b10e0e797501c963a03"}, + {file = "matplotlib-3.9.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:b82c5045cebcecd8496a4d694d43f9cc84aeeb49fe2133e036b207abe73f4d30"}, + {file = "matplotlib-3.9.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f053c40f94bc51bc03832a41b4f153d83f2062d88c72b5e79997072594e97e51"}, + {file = "matplotlib-3.9.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbe196377a8248972f5cede786d4c5508ed5f5ca4a1e09b44bda889958b33f8c"}, + {file = "matplotlib-3.9.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:5816b1e1fe8c192cbc013f8f3e3368ac56fbecf02fb41b8f8559303f24c5015e"}, + {file = "matplotlib-3.9.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:cef2a73d06601437be399908cf13aee74e86932a5ccc6ccdf173408ebc5f6bb2"}, + {file = "matplotlib-3.9.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e0830e188029c14e891fadd99702fd90d317df294c3298aad682739c5533721a"}, + {file = "matplotlib-3.9.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:03ba9c1299c920964e8d3857ba27173b4dbb51ca4bab47ffc2c2ba0eb5e2cbc5"}, + {file = "matplotlib-3.9.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1cd93b91ab47a3616b4d3c42b52f8363b88ca021e340804c6ab2536344fad9ca"}, + {file = "matplotlib-3.9.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:6d1ce5ed2aefcdce11904fc5bbea7d9c21fff3d5f543841edf3dea84451a09ea"}, + {file = "matplotlib-3.9.2-cp39-cp39-win_amd64.whl", hash = "sha256:b2696efdc08648536efd4e1601b5fd491fd47f4db97a5fbfd175549a7365c1b2"}, + {file = "matplotlib-3.9.2-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:d52a3b618cb1cbb769ce2ee1dcdb333c3ab6e823944e9a2d36e37253815f9556"}, + {file = "matplotlib-3.9.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:039082812cacd6c6bec8e17a9c1e6baca230d4116d522e81e1f63a74d01d2e21"}, + {file = "matplotlib-3.9.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6758baae2ed64f2331d4fd19be38b7b4eae3ecec210049a26b6a4f3ae1c85dcc"}, + {file = "matplotlib-3.9.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:050598c2b29e0b9832cde72bcf97627bf00262adbc4a54e2b856426bb2ef0697"}, + {file = "matplotlib-3.9.2.tar.gz", hash = "sha256:96ab43906269ca64a6366934106fa01534454a69e471b7bf3d79083981aaab92"}, +] + +[package.dependencies] +contourpy = ">=1.0.1" +cycler = ">=0.10" +fonttools = ">=4.22.0" +kiwisolver = ">=1.3.1" +numpy = ">=1.23" +packaging = ">=20.0" +pillow = ">=8" +pyparsing = ">=2.3.1" +python-dateutil = ">=2.7" + +[package.extras] +dev = ["meson-python (>=0.13.1)", "numpy (>=1.25)", "pybind11 (>=2.6)", "setuptools (>=64)", "setuptools_scm (>=7)"] + +[[package]] +name = "numpy" +version = "2.1.3" +description = "Fundamental package for array computing in Python" +optional = false +python-versions = ">=3.10" +files = [ + {file = "numpy-2.1.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c894b4305373b9c5576d7a12b473702afdf48ce5369c074ba304cc5ad8730dff"}, + {file = "numpy-2.1.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b47fbb433d3260adcd51eb54f92a2ffbc90a4595f8970ee00e064c644ac788f5"}, + {file = "numpy-2.1.3-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:825656d0743699c529c5943554d223c021ff0494ff1442152ce887ef4f7561a1"}, + {file = "numpy-2.1.3-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:6a4825252fcc430a182ac4dee5a505053d262c807f8a924603d411f6718b88fd"}, + {file = "numpy-2.1.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e711e02f49e176a01d0349d82cb5f05ba4db7d5e7e0defd026328e5cfb3226d3"}, + {file = "numpy-2.1.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78574ac2d1a4a02421f25da9559850d59457bac82f2b8d7a44fe83a64f770098"}, + {file = "numpy-2.1.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c7662f0e3673fe4e832fe07b65c50342ea27d989f92c80355658c7f888fcc83c"}, + {file = "numpy-2.1.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:fa2d1337dc61c8dc417fbccf20f6d1e139896a30721b7f1e832b2bb6ef4eb6c4"}, + {file = "numpy-2.1.3-cp310-cp310-win32.whl", hash = "sha256:72dcc4a35a8515d83e76b58fdf8113a5c969ccd505c8a946759b24e3182d1f23"}, + {file = "numpy-2.1.3-cp310-cp310-win_amd64.whl", hash = "sha256:ecc76a9ba2911d8d37ac01de72834d8849e55473457558e12995f4cd53e778e0"}, + {file = "numpy-2.1.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4d1167c53b93f1f5d8a139a742b3c6f4d429b54e74e6b57d0eff40045187b15d"}, + {file = "numpy-2.1.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c80e4a09b3d95b4e1cac08643f1152fa71a0a821a2d4277334c88d54b2219a41"}, + {file = "numpy-2.1.3-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:576a1c1d25e9e02ed7fa5477f30a127fe56debd53b8d2c89d5578f9857d03ca9"}, + {file = "numpy-2.1.3-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:973faafebaae4c0aaa1a1ca1ce02434554d67e628b8d805e61f874b84e136b09"}, + {file = "numpy-2.1.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:762479be47a4863e261a840e8e01608d124ee1361e48b96916f38b119cfda04a"}, + {file = "numpy-2.1.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc6f24b3d1ecc1eebfbf5d6051faa49af40b03be1aaa781ebdadcbc090b4539b"}, + {file = "numpy-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:17ee83a1f4fef3c94d16dc1802b998668b5419362c8a4f4e8a491de1b41cc3ee"}, + {file = "numpy-2.1.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:15cb89f39fa6d0bdfb600ea24b250e5f1a3df23f901f51c8debaa6a5d122b2f0"}, + {file = "numpy-2.1.3-cp311-cp311-win32.whl", hash = "sha256:d9beb777a78c331580705326d2367488d5bc473b49a9bc3036c154832520aca9"}, + {file = "numpy-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:d89dd2b6da69c4fff5e39c28a382199ddedc3a5be5390115608345dec660b9e2"}, + {file = "numpy-2.1.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f55ba01150f52b1027829b50d70ef1dafd9821ea82905b63936668403c3b471e"}, + {file = "numpy-2.1.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:13138eadd4f4da03074851a698ffa7e405f41a0845a6b1ad135b81596e4e9958"}, + {file = "numpy-2.1.3-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:a6b46587b14b888e95e4a24d7b13ae91fa22386c199ee7b418f449032b2fa3b8"}, + {file = "numpy-2.1.3-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:0fa14563cc46422e99daef53d725d0c326e99e468a9320a240affffe87852564"}, + {file = "numpy-2.1.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8637dcd2caa676e475503d1f8fdb327bc495554e10838019651b76d17b98e512"}, + {file = "numpy-2.1.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2312b2aa89e1f43ecea6da6ea9a810d06aae08321609d8dc0d0eda6d946a541b"}, + {file = "numpy-2.1.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a38c19106902bb19351b83802531fea19dee18e5b37b36454f27f11ff956f7fc"}, + {file = "numpy-2.1.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:02135ade8b8a84011cbb67dc44e07c58f28575cf9ecf8ab304e51c05528c19f0"}, + {file = "numpy-2.1.3-cp312-cp312-win32.whl", hash = "sha256:e6988e90fcf617da2b5c78902fe8e668361b43b4fe26dbf2d7b0f8034d4cafb9"}, + {file = "numpy-2.1.3-cp312-cp312-win_amd64.whl", hash = "sha256:0d30c543f02e84e92c4b1f415b7c6b5326cbe45ee7882b6b77db7195fb971e3a"}, + {file = "numpy-2.1.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:96fe52fcdb9345b7cd82ecd34547fca4321f7656d500eca497eb7ea5a926692f"}, + {file = "numpy-2.1.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f653490b33e9c3a4c1c01d41bc2aef08f9475af51146e4a7710c450cf9761598"}, + {file = "numpy-2.1.3-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:dc258a761a16daa791081d026f0ed4399b582712e6fc887a95af09df10c5ca57"}, + {file = "numpy-2.1.3-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:016d0f6f5e77b0f0d45d77387ffa4bb89816b57c835580c3ce8e099ef830befe"}, + {file = "numpy-2.1.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c181ba05ce8299c7aa3125c27b9c2167bca4a4445b7ce73d5febc411ca692e43"}, + {file = "numpy-2.1.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5641516794ca9e5f8a4d17bb45446998c6554704d888f86df9b200e66bdcce56"}, + {file = "numpy-2.1.3-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ea4dedd6e394a9c180b33c2c872b92f7ce0f8e7ad93e9585312b0c5a04777a4a"}, + {file = "numpy-2.1.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b0df3635b9c8ef48bd3be5f862cf71b0a4716fa0e702155c45067c6b711ddcef"}, + {file = "numpy-2.1.3-cp313-cp313-win32.whl", hash = "sha256:50ca6aba6e163363f132b5c101ba078b8cbd3fa92c7865fd7d4d62d9779ac29f"}, + {file = "numpy-2.1.3-cp313-cp313-win_amd64.whl", hash = "sha256:747641635d3d44bcb380d950679462fae44f54b131be347d5ec2bce47d3df9ed"}, + {file = "numpy-2.1.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:996bb9399059c5b82f76b53ff8bb686069c05acc94656bb259b1d63d04a9506f"}, + {file = "numpy-2.1.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:45966d859916ad02b779706bb43b954281db43e185015df6eb3323120188f9e4"}, + {file = "numpy-2.1.3-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:baed7e8d7481bfe0874b566850cb0b85243e982388b7b23348c6db2ee2b2ae8e"}, + {file = "numpy-2.1.3-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:a9f7f672a3388133335589cfca93ed468509cb7b93ba3105fce780d04a6576a0"}, + {file = "numpy-2.1.3-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7aac50327da5d208db2eec22eb11e491e3fe13d22653dce51b0f4109101b408"}, + {file = "numpy-2.1.3-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4394bc0dbd074b7f9b52024832d16e019decebf86caf909d94f6b3f77a8ee3b6"}, + {file = "numpy-2.1.3-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:50d18c4358a0a8a53f12a8ba9d772ab2d460321e6a93d6064fc22443d189853f"}, + {file = "numpy-2.1.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:14e253bd43fc6b37af4921b10f6add6925878a42a0c5fe83daee390bca80bc17"}, + {file = "numpy-2.1.3-cp313-cp313t-win32.whl", hash = "sha256:08788d27a5fd867a663f6fc753fd7c3ad7e92747efc73c53bca2f19f8bc06f48"}, + {file = "numpy-2.1.3-cp313-cp313t-win_amd64.whl", hash = "sha256:2564fbdf2b99b3f815f2107c1bbc93e2de8ee655a69c261363a1172a79a257d4"}, + {file = "numpy-2.1.3-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:4f2015dfe437dfebbfce7c85c7b53d81ba49e71ba7eadbf1df40c915af75979f"}, + {file = "numpy-2.1.3-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:3522b0dfe983a575e6a9ab3a4a4dfe156c3e428468ff08ce582b9bb6bd1d71d4"}, + {file = "numpy-2.1.3-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c006b607a865b07cd981ccb218a04fc86b600411d83d6fc261357f1c0966755d"}, + {file = "numpy-2.1.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:e14e26956e6f1696070788252dcdff11b4aca4c3e8bd166e0df1bb8f315a67cb"}, + {file = "numpy-2.1.3.tar.gz", hash = "sha256:aa08e04e08aaf974d4458def539dece0d28146d866a39da5639596f4921fd761"}, +] + +[[package]] +name = "packaging" +version = "24.1" +description = "Core utilities for Python packages" +optional = false +python-versions = ">=3.8" +files = [ + {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, + {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, +] + +[[package]] +name = "pillow" +version = "11.0.0" +description = "Python Imaging Library (Fork)" +optional = false +python-versions = ">=3.9" +files = [ + {file = "pillow-11.0.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:6619654954dc4936fcff82db8eb6401d3159ec6be81e33c6000dfd76ae189947"}, + {file = "pillow-11.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b3c5ac4bed7519088103d9450a1107f76308ecf91d6dabc8a33a2fcfb18d0fba"}, + {file = "pillow-11.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a65149d8ada1055029fcb665452b2814fe7d7082fcb0c5bed6db851cb69b2086"}, + {file = "pillow-11.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88a58d8ac0cc0e7f3a014509f0455248a76629ca9b604eca7dc5927cc593c5e9"}, + {file = "pillow-11.0.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:c26845094b1af3c91852745ae78e3ea47abf3dbcd1cf962f16b9a5fbe3ee8488"}, + {file = "pillow-11.0.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:1a61b54f87ab5786b8479f81c4b11f4d61702830354520837f8cc791ebba0f5f"}, + {file = "pillow-11.0.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:674629ff60030d144b7bca2b8330225a9b11c482ed408813924619c6f302fdbb"}, + {file = "pillow-11.0.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:598b4e238f13276e0008299bd2482003f48158e2b11826862b1eb2ad7c768b97"}, + {file = "pillow-11.0.0-cp310-cp310-win32.whl", hash = "sha256:9a0f748eaa434a41fccf8e1ee7a3eed68af1b690e75328fd7a60af123c193b50"}, + {file = "pillow-11.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:a5629742881bcbc1f42e840af185fd4d83a5edeb96475a575f4da50d6ede337c"}, + {file = "pillow-11.0.0-cp310-cp310-win_arm64.whl", hash = "sha256:ee217c198f2e41f184f3869f3e485557296d505b5195c513b2bfe0062dc537f1"}, + {file = "pillow-11.0.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:1c1d72714f429a521d8d2d018badc42414c3077eb187a59579f28e4270b4b0fc"}, + {file = "pillow-11.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:499c3a1b0d6fc8213519e193796eb1a86a1be4b1877d678b30f83fd979811d1a"}, + {file = "pillow-11.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c8b2351c85d855293a299038e1f89db92a2f35e8d2f783489c6f0b2b5f3fe8a3"}, + {file = "pillow-11.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f4dba50cfa56f910241eb7f883c20f1e7b1d8f7d91c750cd0b318bad443f4d5"}, + {file = "pillow-11.0.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:5ddbfd761ee00c12ee1be86c9c0683ecf5bb14c9772ddbd782085779a63dd55b"}, + {file = "pillow-11.0.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:45c566eb10b8967d71bf1ab8e4a525e5a93519e29ea071459ce517f6b903d7fa"}, + {file = "pillow-11.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b4fd7bd29610a83a8c9b564d457cf5bd92b4e11e79a4ee4716a63c959699b306"}, + {file = "pillow-11.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:cb929ca942d0ec4fac404cbf520ee6cac37bf35be479b970c4ffadf2b6a1cad9"}, + {file = "pillow-11.0.0-cp311-cp311-win32.whl", hash = "sha256:006bcdd307cc47ba43e924099a038cbf9591062e6c50e570819743f5607404f5"}, + {file = "pillow-11.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:52a2d8323a465f84faaba5236567d212c3668f2ab53e1c74c15583cf507a0291"}, + {file = "pillow-11.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:16095692a253047fe3ec028e951fa4221a1f3ed3d80c397e83541a3037ff67c9"}, + {file = "pillow-11.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d2c0a187a92a1cb5ef2c8ed5412dd8d4334272617f532d4ad4de31e0495bd923"}, + {file = "pillow-11.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:084a07ef0821cfe4858fe86652fffac8e187b6ae677e9906e192aafcc1b69903"}, + {file = "pillow-11.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8069c5179902dcdce0be9bfc8235347fdbac249d23bd90514b7a47a72d9fecf4"}, + {file = "pillow-11.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f02541ef64077f22bf4924f225c0fd1248c168f86e4b7abdedd87d6ebaceab0f"}, + {file = "pillow-11.0.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:fcb4621042ac4b7865c179bb972ed0da0218a076dc1820ffc48b1d74c1e37fe9"}, + {file = "pillow-11.0.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:00177a63030d612148e659b55ba99527803288cea7c75fb05766ab7981a8c1b7"}, + {file = "pillow-11.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8853a3bf12afddfdf15f57c4b02d7ded92c7a75a5d7331d19f4f9572a89c17e6"}, + {file = "pillow-11.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3107c66e43bda25359d5ef446f59c497de2b5ed4c7fdba0894f8d6cf3822dafc"}, + {file = "pillow-11.0.0-cp312-cp312-win32.whl", hash = "sha256:86510e3f5eca0ab87429dd77fafc04693195eec7fd6a137c389c3eeb4cfb77c6"}, + {file = "pillow-11.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:8ec4a89295cd6cd4d1058a5e6aec6bf51e0eaaf9714774e1bfac7cfc9051db47"}, + {file = "pillow-11.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:27a7860107500d813fcd203b4ea19b04babe79448268403172782754870dac25"}, + {file = "pillow-11.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:bcd1fb5bb7b07f64c15618c89efcc2cfa3e95f0e3bcdbaf4642509de1942a699"}, + {file = "pillow-11.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0e038b0745997c7dcaae350d35859c9715c71e92ffb7e0f4a8e8a16732150f38"}, + {file = "pillow-11.0.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ae08bd8ffc41aebf578c2af2f9d8749d91f448b3bfd41d7d9ff573d74f2a6b2"}, + {file = "pillow-11.0.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d69bfd8ec3219ae71bcde1f942b728903cad25fafe3100ba2258b973bd2bc1b2"}, + {file = "pillow-11.0.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:61b887f9ddba63ddf62fd02a3ba7add935d053b6dd7d58998c630e6dbade8527"}, + {file = "pillow-11.0.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:c6a660307ca9d4867caa8d9ca2c2658ab685de83792d1876274991adec7b93fa"}, + {file = "pillow-11.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:73e3a0200cdda995c7e43dd47436c1548f87a30bb27fb871f352a22ab8dcf45f"}, + {file = "pillow-11.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fba162b8872d30fea8c52b258a542c5dfd7b235fb5cb352240c8d63b414013eb"}, + {file = "pillow-11.0.0-cp313-cp313-win32.whl", hash = "sha256:f1b82c27e89fffc6da125d5eb0ca6e68017faf5efc078128cfaa42cf5cb38798"}, + {file = "pillow-11.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:8ba470552b48e5835f1d23ecb936bb7f71d206f9dfeee64245f30c3270b994de"}, + {file = "pillow-11.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:846e193e103b41e984ac921b335df59195356ce3f71dcfd155aa79c603873b84"}, + {file = "pillow-11.0.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:4ad70c4214f67d7466bea6a08061eba35c01b1b89eaa098040a35272a8efb22b"}, + {file = "pillow-11.0.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:6ec0d5af64f2e3d64a165f490d96368bb5dea8b8f9ad04487f9ab60dc4bb6003"}, + {file = "pillow-11.0.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c809a70e43c7977c4a42aefd62f0131823ebf7dd73556fa5d5950f5b354087e2"}, + {file = "pillow-11.0.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:4b60c9520f7207aaf2e1d94de026682fc227806c6e1f55bba7606d1c94dd623a"}, + {file = "pillow-11.0.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:1e2688958a840c822279fda0086fec1fdab2f95bf2b717b66871c4ad9859d7e8"}, + {file = "pillow-11.0.0-cp313-cp313t-win32.whl", hash = "sha256:607bbe123c74e272e381a8d1957083a9463401f7bd01287f50521ecb05a313f8"}, + {file = "pillow-11.0.0-cp313-cp313t-win_amd64.whl", hash = "sha256:5c39ed17edea3bc69c743a8dd3e9853b7509625c2462532e62baa0732163a904"}, + {file = "pillow-11.0.0-cp313-cp313t-win_arm64.whl", hash = "sha256:75acbbeb05b86bc53cbe7b7e6fe00fbcf82ad7c684b3ad82e3d711da9ba287d3"}, + {file = "pillow-11.0.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:2e46773dc9f35a1dd28bd6981332fd7f27bec001a918a72a79b4133cf5291dba"}, + {file = "pillow-11.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2679d2258b7f1192b378e2893a8a0a0ca472234d4c2c0e6bdd3380e8dfa21b6a"}, + {file = "pillow-11.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eda2616eb2313cbb3eebbe51f19362eb434b18e3bb599466a1ffa76a033fb916"}, + {file = "pillow-11.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20ec184af98a121fb2da42642dea8a29ec80fc3efbaefb86d8fdd2606619045d"}, + {file = "pillow-11.0.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:8594f42df584e5b4bb9281799698403f7af489fba84c34d53d1c4bfb71b7c4e7"}, + {file = "pillow-11.0.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:c12b5ae868897c7338519c03049a806af85b9b8c237b7d675b8c5e089e4a618e"}, + {file = "pillow-11.0.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:70fbbdacd1d271b77b7721fe3cdd2d537bbbd75d29e6300c672ec6bb38d9672f"}, + {file = "pillow-11.0.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:5178952973e588b3f1360868847334e9e3bf49d19e169bbbdfaf8398002419ae"}, + {file = "pillow-11.0.0-cp39-cp39-win32.whl", hash = "sha256:8c676b587da5673d3c75bd67dd2a8cdfeb282ca38a30f37950511766b26858c4"}, + {file = "pillow-11.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:94f3e1780abb45062287b4614a5bc0874519c86a777d4a7ad34978e86428b8dd"}, + {file = "pillow-11.0.0-cp39-cp39-win_arm64.whl", hash = "sha256:290f2cc809f9da7d6d622550bbf4c1e57518212da51b6a30fe8e0a270a5b78bd"}, + {file = "pillow-11.0.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:1187739620f2b365de756ce086fdb3604573337cc28a0d3ac4a01ab6b2d2a6d2"}, + {file = "pillow-11.0.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:fbbcb7b57dc9c794843e3d1258c0fbf0f48656d46ffe9e09b63bbd6e8cd5d0a2"}, + {file = "pillow-11.0.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d203af30149ae339ad1b4f710d9844ed8796e97fda23ffbc4cc472968a47d0b"}, + {file = "pillow-11.0.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21a0d3b115009ebb8ac3d2ebec5c2982cc693da935f4ab7bb5c8ebe2f47d36f2"}, + {file = "pillow-11.0.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:73853108f56df97baf2bb8b522f3578221e56f646ba345a372c78326710d3830"}, + {file = "pillow-11.0.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:e58876c91f97b0952eb766123bfef372792ab3f4e3e1f1a2267834c2ab131734"}, + {file = "pillow-11.0.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:224aaa38177597bb179f3ec87eeefcce8e4f85e608025e9cfac60de237ba6316"}, + {file = "pillow-11.0.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:5bd2d3bdb846d757055910f0a59792d33b555800813c3b39ada1829c372ccb06"}, + {file = "pillow-11.0.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:375b8dd15a1f5d2feafff536d47e22f69625c1aa92f12b339ec0b2ca40263273"}, + {file = "pillow-11.0.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:daffdf51ee5db69a82dd127eabecce20729e21f7a3680cf7cbb23f0829189790"}, + {file = "pillow-11.0.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7326a1787e3c7b0429659e0a944725e1b03eeaa10edd945a86dead1913383944"}, + {file = "pillow-11.0.0.tar.gz", hash = "sha256:72bacbaf24ac003fea9bff9837d1eedb6088758d41e100c1552930151f677739"}, +] + +[package.extras] +docs = ["furo", "olefile", "sphinx (>=8.1)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinxext-opengraph"] +fpx = ["olefile"] +mic = ["olefile"] +tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"] +typing = ["typing-extensions"] +xmp = ["defusedxml"] + +[[package]] +name = "pygments" +version = "2.18.0" +description = "Pygments is a syntax highlighting package written in Python." +optional = false +python-versions = ">=3.8" +files = [ + {file = "pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a"}, + {file = "pygments-2.18.0.tar.gz", hash = "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199"}, +] + +[package.extras] +windows-terminal = ["colorama (>=0.4.6)"] + +[[package]] +name = "pyparsing" +version = "3.2.0" +description = "pyparsing module - Classes and methods to define and execute parsing grammars" +optional = false +python-versions = ">=3.9" +files = [ + {file = "pyparsing-3.2.0-py3-none-any.whl", hash = "sha256:93d9577b88da0bbea8cc8334ee8b918ed014968fd2ec383e868fb8afb1ccef84"}, + {file = "pyparsing-3.2.0.tar.gz", hash = "sha256:cbf74e27246d595d9a74b186b810f6fbb86726dbf3b9532efb343f6d7294fe9c"}, +] + +[package.extras] +diagrams = ["jinja2", "railroad-diagrams"] + +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +description = "Extensions to the standard Python datetime module" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +files = [ + {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, + {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, +] + +[package.dependencies] +six = ">=1.5" + +[[package]] +name = "requests" +version = "2.32.3" +description = "Python HTTP for Humans." +optional = false +python-versions = ">=3.8" +files = [ + {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, + {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, +] + +[package.dependencies] +certifi = ">=2017.4.17" +charset-normalizer = ">=2,<4" +idna = ">=2.5,<4" +urllib3 = ">=1.21.1,<3" + +[package.extras] +socks = ["PySocks (>=1.5.6,!=1.5.7)"] +use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] + +[[package]] +name = "six" +version = "1.16.0" +description = "Python 2 and 3 compatibility utilities" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, + {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, +] + +[[package]] +name = "snowballstemmer" +version = "2.2.0" +description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms." +optional = false +python-versions = "*" +files = [ + {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"}, + {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"}, +] + +[[package]] +name = "sphinx" +version = "8.1.3" +description = "Python documentation generator" +optional = false +python-versions = ">=3.10" +files = [ + {file = "sphinx-8.1.3-py3-none-any.whl", hash = "sha256:09719015511837b76bf6e03e42eb7595ac8c2e41eeb9c29c5b755c6b677992a2"}, + {file = "sphinx-8.1.3.tar.gz", hash = "sha256:43c1911eecb0d3e161ad78611bc905d1ad0e523e4ddc202a58a821773dc4c927"}, +] + +[package.dependencies] +alabaster = ">=0.7.14" +babel = ">=2.13" +colorama = {version = ">=0.4.6", markers = "sys_platform == \"win32\""} +docutils = ">=0.20,<0.22" +imagesize = ">=1.3" +Jinja2 = ">=3.1" +packaging = ">=23.0" +Pygments = ">=2.17" +requests = ">=2.30.0" +snowballstemmer = ">=2.2" +sphinxcontrib-applehelp = ">=1.0.7" +sphinxcontrib-devhelp = ">=1.0.6" +sphinxcontrib-htmlhelp = ">=2.0.6" +sphinxcontrib-jsmath = ">=1.0.1" +sphinxcontrib-qthelp = ">=1.0.6" +sphinxcontrib-serializinghtml = ">=1.1.9" + +[package.extras] +docs = ["sphinxcontrib-websupport"] +lint = ["flake8 (>=6.0)", "mypy (==1.11.1)", "pyright (==1.1.384)", "pytest (>=6.0)", "ruff (==0.6.9)", "sphinx-lint (>=0.9)", "tomli (>=2)", "types-Pillow (==10.2.0.20240822)", "types-Pygments (==2.18.0.20240506)", "types-colorama (==0.4.15.20240311)", "types-defusedxml (==0.7.0.20240218)", "types-docutils (==0.21.0.20241005)", "types-requests (==2.32.0.20240914)", "types-urllib3 (==1.26.25.14)"] +test = ["cython (>=3.0)", "defusedxml (>=0.7.1)", "pytest (>=8.0)", "setuptools (>=70.0)", "typing_extensions (>=4.9)"] + +[[package]] +name = "sphinx-mathjax-offline" +version = "0.0.2" +description = "MathJax offline support for Sphinx" +optional = false +python-versions = "*" +files = [ + {file = "sphinx-mathjax-offline-0.0.2.tar.gz", hash = "sha256:7dfbcbd6dc60efd8d8f1aac0718f0ee5913a5cea03cb0e03ffa77ff0dfbfe5bd"}, + {file = "sphinx_mathjax_offline-0.0.2-py3-none-any.whl", hash = "sha256:206418155b2ff2f57496fb8501fdccae3da978e53031ff296c73729ba16062c4"}, +] + +[package.dependencies] +sphinx = "*" + +[[package]] +name = "sphinx-rtd-theme" +version = "3.0.1" +description = "Read the Docs theme for Sphinx" +optional = false +python-versions = ">=3.8" +files = [ + {file = "sphinx_rtd_theme-3.0.1-py2.py3-none-any.whl", hash = "sha256:921c0ece75e90633ee876bd7b148cfaad136b481907ad154ac3669b6fc957916"}, + {file = "sphinx_rtd_theme-3.0.1.tar.gz", hash = "sha256:a4c5745d1b06dfcb80b7704fe532eb765b44065a8fad9851e4258c8804140703"}, +] + +[package.dependencies] +docutils = ">0.18,<0.22" +sphinx = ">=6,<9" +sphinxcontrib-jquery = ">=4,<5" + +[package.extras] +dev = ["bump2version", "transifex-client", "twine", "wheel"] + +[[package]] +name = "sphinxcontrib-applehelp" +version = "2.0.0" +description = "sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books" +optional = false +python-versions = ">=3.9" +files = [ + {file = "sphinxcontrib_applehelp-2.0.0-py3-none-any.whl", hash = "sha256:4cd3f0ec4ac5dd9c17ec65e9ab272c9b867ea77425228e68ecf08d6b28ddbdb5"}, + {file = "sphinxcontrib_applehelp-2.0.0.tar.gz", hash = "sha256:2f29ef331735ce958efa4734873f084941970894c6090408b079c61b2e1c06d1"}, +] + +[package.extras] +lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] +standalone = ["Sphinx (>=5)"] +test = ["pytest"] + +[[package]] +name = "sphinxcontrib-devhelp" +version = "2.0.0" +description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp documents" +optional = false +python-versions = ">=3.9" +files = [ + {file = "sphinxcontrib_devhelp-2.0.0-py3-none-any.whl", hash = "sha256:aefb8b83854e4b0998877524d1029fd3e6879210422ee3780459e28a1f03a8a2"}, + {file = "sphinxcontrib_devhelp-2.0.0.tar.gz", hash = "sha256:411f5d96d445d1d73bb5d52133377b4248ec79db5c793ce7dbe59e074b4dd1ad"}, +] + +[package.extras] +lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] +standalone = ["Sphinx (>=5)"] +test = ["pytest"] + +[[package]] +name = "sphinxcontrib-htmlhelp" +version = "2.1.0" +description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files" +optional = false +python-versions = ">=3.9" +files = [ + {file = "sphinxcontrib_htmlhelp-2.1.0-py3-none-any.whl", hash = "sha256:166759820b47002d22914d64a075ce08f4c46818e17cfc9470a9786b759b19f8"}, + {file = "sphinxcontrib_htmlhelp-2.1.0.tar.gz", hash = "sha256:c9e2916ace8aad64cc13a0d233ee22317f2b9025b9cf3295249fa985cc7082e9"}, +] + +[package.extras] +lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] +standalone = ["Sphinx (>=5)"] +test = ["html5lib", "pytest"] + +[[package]] +name = "sphinxcontrib-jquery" +version = "4.1" +description = "Extension to include jQuery on newer Sphinx releases" +optional = false +python-versions = ">=2.7" +files = [ + {file = "sphinxcontrib-jquery-4.1.tar.gz", hash = "sha256:1620739f04e36a2c779f1a131a2dfd49b2fd07351bf1968ced074365933abc7a"}, + {file = "sphinxcontrib_jquery-4.1-py2.py3-none-any.whl", hash = "sha256:f936030d7d0147dd026a4f2b5a57343d233f1fc7b363f68b3d4f1cb0993878ae"}, +] + +[package.dependencies] +Sphinx = ">=1.8" + +[[package]] +name = "sphinxcontrib-jsmath" +version = "1.0.1" +description = "A sphinx extension which renders display math in HTML via JavaScript" +optional = false +python-versions = ">=3.5" +files = [ + {file = "sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8"}, + {file = "sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178"}, +] + +[package.extras] +test = ["flake8", "mypy", "pytest"] + +[[package]] +name = "sphinxcontrib-qthelp" +version = "2.0.0" +description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp documents" +optional = false +python-versions = ">=3.9" +files = [ + {file = "sphinxcontrib_qthelp-2.0.0-py3-none-any.whl", hash = "sha256:b18a828cdba941ccd6ee8445dbe72ffa3ef8cbe7505d8cd1fa0d42d3f2d5f3eb"}, + {file = "sphinxcontrib_qthelp-2.0.0.tar.gz", hash = "sha256:4fe7d0ac8fc171045be623aba3e2a8f613f8682731f9153bb2e40ece16b9bbab"}, +] + +[package.extras] +lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] +standalone = ["Sphinx (>=5)"] +test = ["defusedxml (>=0.7.1)", "pytest"] + +[[package]] +name = "sphinxcontrib-serializinghtml" +version = "2.0.0" +description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)" +optional = false +python-versions = ">=3.9" +files = [ + {file = "sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl", hash = "sha256:6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331"}, + {file = "sphinxcontrib_serializinghtml-2.0.0.tar.gz", hash = "sha256:e9d912827f872c029017a53f0ef2180b327c3f7fd23c87229f7a8e8b70031d4d"}, +] + +[package.extras] +lint = ["mypy", "ruff (==0.5.5)", "types-docutils"] +standalone = ["Sphinx (>=5)"] +test = ["pytest"] + +[[package]] +name = "urllib3" +version = "2.2.3" +description = "HTTP library with thread-safe connection pooling, file post, and more." +optional = false +python-versions = ">=3.8" +files = [ + {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, + {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, +] + +[package.extras] +brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] +h2 = ["h2 (>=4,<5)"] +socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] +zstd = ["zstandard (>=0.18.0)"] + +[metadata] +lock-version = "2.0" +python-versions = "^3.11" +content-hash = "d69e16533f4f5745ba226d3781ce00bc4a0db82bdbaf24690e6605bcb22e37b8" diff --git a/libm/libmcs/pyproject.toml b/libm/libmcs/pyproject.toml new file mode 100644 index 00000000..727cb78a --- /dev/null +++ b/libm/libmcs/pyproject.toml @@ -0,0 +1,21 @@ +[tool.poetry] +name = "libmcs" +version = "1.3.0" +description = "Qualified Mathematical Library for Critical Systems, based on Newlib" +authors = ["GTD GmbH "] +license = "BSD" +readme = "README.md" +package-mode = false + +[tool.poetry.dependencies] +python = "^3.11" +sphinx-rtd-theme = "^3.0.1" +sphinx-mathjax-offline = "^0.0.2" +hawkmoth = "^0.19.0" +clang = "^14.0.0" +matplotlib = "^3.9.2" + + +[build-system] +requires = ["poetry-core"] +build-backend = "poetry.core.masonry.api" diff --git a/libm/libmcs/sw-quality/au-misra3.lnt b/libm/libmcs/sw-quality/au-misra3.lnt new file mode 100644 index 00000000..b5b66921 --- /dev/null +++ b/libm/libmcs/sw-quality/au-misra3.lnt @@ -0,0 +1,2173 @@ +/* Date Stamp */ -d"_lint_au_misra3_lnt=au-misra3.lnt modified 12-Jun-2014" +/* To document usage use: -message( "Using " _lint_au_misra3_lnt ) */ + +// --------------------------------------------------------------------- +// This file is provided by Gimpel Software (www.gimpel.com) for use with +// its products PC-lint and FlexeLint. +// +// Redistribution and use of this file, with or without modification, is +// permitted provided that any such redistribution retains this notice. +// --------------------------------------------------------------------- + +// au-misra3.lnt -- Author options - MISRA C 2012 + +/* + This options file can be used to explicitly activate those + checks advocated by the Motor Industry Software Reliability + Association. + + You can use this file directly when linting your programs as in: + + lin au-misra3 files + + Gimpel Software relies on the document, "MISRA-C:2012 + Guidelines for the use of the C language in critical systems", + copyright 2012 by MIRA Limited, as the primary source for this + file. Gimpel Software makes no warranty as to the completeness + or applicability of this options file and reserves the right to + amend or alter the official contents of such at any time. + + "MISRA" is a registered trademark of MIRA Limited, held on + behalf of the MISRA Consortium. + + */ + -misra(3) // Activate MISRA Essential Type model + +/**** Dir 1.1 (Req) ************/ + + /* not statically checkable */ + +/**** Dir 2.1 (Req) ************/ + + -A(C99) /* strict ISO C99 */ + /* Note: if you code to the C90 standard instead, you may + want to comment out the above option and uncomment the + following option. You will also want to do likewise for + other uses of the '-A(C99)' option throughout this file. */ + // -A(C90) /* strict ANSI */ + +e950 /* flag non-standard word or construct */ + +elib(950) + -append(950,[MISRA 2012 Directive 2.1, required]) + +/**** Dir 3.1 (Req) ************/ + + /* not statically checkable */ + +/**** Dir 4.1 (Req) ************/ + + /* not statically checkable */ + +/**** Dir 4.2 (Adv) ************/ + + /* not statically checkable */ + +/**** Dir 4.3 (Req) ************/ + + +e586 /* to activate the deprecation message */ + +elib(586) + -deprecate(keyword,asm,[MISRA 2012 4.3, required]) + +/**** Dir 4.4 (Adv) ************/ + + /* This requirement (that there be no commented-out code) is, in + principle, not statically checkable. The reason given for the + requirement is that comments do not nest. Thus a commented + out section of code that happens to use slash-star commenting + could inadvertently introduce unwanted code. Rule 3.1, however, + addresses the nested comment issue and hence the major concern + that this requirement seeks to address is indeed checkable. + */ + -fnc /* flag nested comments */ + +e602 /* comment within comment */ + +elib(602) + -append(602,[MISRA 2012 Directive 4.4, advisory]) + +/**** Dir 4.5 (Adv) ************/ + + // While Lint can enforce this directive with the following four + // options, doing so can increase the run time of Lint depending + // upon the number of identifiers in your program. If you want + // this checking, uncomment each of the following four options. + // + // +fta + // +e9046 /* typographical ambiguity */ + // +elib(9046) + // -append(9046,[MISRA 2012 Directive 4.5, advisory]) + +/**** Dir 4.6 (Adv) ************/ + + +e970 /* flag modifiers used outside of typedefs */ + +elib(970) + -append(970,[MISRA 2012 Directive 4.6, advisory]) + // For the duration, we are presuming MISRA does not want + // diagnostics for the bool type. + -esym(970,bool) + -esym(970,char) + +/**** Dir 4.7 (Req) ************/ + + +e534 /* ignoring return value of function */ + +elib(534) + -append(534,[MISRA 2012 Directive 4.7, required]) + +/**** Dir 4.8 (Adv) ************/ + + +e9045 /* non-hidden definition of type */ + +elib(9045) + -append(9045,[MISRA 2012 Directive 4.8, advisory]) + +/**** Dir 4.9 (Adv) ************/ + + +e9026 /* function-like macro defined */ + +elib(9026) + -append(9026,[MISRA 2012 Directive 4.9, advisory]) + +/**** Dir 4.10 (Req) ************/ + + +e451 /* Header repeatedly included without guard */ + +elib(451) + -append(451,[MISRA 2012 Directive 4.10, required]) + +/**** Dir 4.11 (Req) ************/ + + /* The arguments to over 100 calls to standard library functions + are monitored; users can specify additional constraints for + other functions. + */ + +/**** Dir 4.12 (Req) ************/ + + +e586 /* Symbol is deprecated */ + +elib(586) + -deprecate(function,calloc,[MISRA 2012 Directive 4.12, required]) + -deprecate(function,malloc,[MISRA 2012 Directive 4.12, required]) + -deprecate(function,realloc,[MISRA 2012 Directive 4.12, required]) + -deprecate(function,free,[MISRA 2012 Directive 4.12, required]) + +/**** Dir 4.13 (Adv) ************/ + + /* supported by uncommenting the next six options and use of the + -function_pair() option */ + // +e480 + // +elib(480) + // -append(480,[MISRA 2012 Directive 4.13, advisory]) + // +e481 + // +elib(481) + // -append(481,[MISRA 2012 Directive 4.13, advisory]) + +/**** Rule 1.1 (Req) ************/ + + /* While MISRA has declared this rule to be "undecidable", Gimpel + * Software provides the following options to assist: + */ + -A(C99) /* strict ISO C99 */ + /* Note: if you code to the C90 standard instead, you may + want to comment out the above option and uncomment the + following option. You will also want to do likewise for + other uses of the '-A(C99)' option throughout this file. */ + // -A(C90) /* strict ANSI */ + +e950 /* flag non-standard word or construct */ + +elib(950) + -append(950,[MISRA 2012 Rule 1.1, required]) + +/**** Rule 1.2 (Adv) ************/ + + /* While MISRA has declared this rule to be "undecidable", Gimpel + * Software provides the following options to assist: + */ + -A(C99) /* strict ISO C99 */ + /* Note: if you code to the C90 standard instead, you may + want to comment out the above option and uncomment the + following option. You will also want to do likewise for + other uses of the '-A(C99)' option throughout this file. */ + // -A(C90) /* strict ANSI */ + +e950 /* flag non-ANSI word or construct */ + +elib(950) + -append(950,[MISRA 2012 Rule 1.2, advisory]) + +/**** Rule 1.3 (Req) ************/ + + /* While MISRA has declared this rule to be "undecidable", Gimpel + * Software provides the following options to assist: + */ + + /* Avoid the use of undefined or unspecified behavior as described + in ISO C, Appendix A.6.1 and Appendix A.6.2 */ + + /* Source file not ending in a new-line character, ending in + new-line character immediately preceded by a backslash + character, or ending in a partial preprocessing token or + comment (ISO C, Appendix A.6.2, point 1). + */ + +e406 /* unclosed comment */ + +elib(406) + -append(406,[MISRA 2012 Rule 1.3, required]) + + /* Non-standard character usage (ISO C, Appendix A.6.2, point 2). + */ + +e27 /* illegal character */ + +elib(27) + -append(27,[MISRA 2012 Rule 1.3, required]) + + /* Unclosed quotes (ISO C, Appendix A.6.2, point 4). + */ + +e2 /* unclosed quote */ + +elib(2) + -append(2,[MISRA 2012 Rule 1.3, required]) + + /* Repeated label within a function (ISO C, Appendix A.6.2, point + 5). + */ + +e31 /* symbol redefinition */ + +elib(31) + -append(31,[MISRA 2012 Rule 1.3, required]) + + /* Non-visible identifier used (ISO C, Appendix A.6.2, point 6). + */ + +e40 /* undeclared identifier */ + +elib(40) + -append(40,[MISRA 2012 Rule 1.3, required]) + + /* Identifiers for the same entity differ beyond the minimal + significant characters (ISO C, Appendix A.6.2, point 7). + See Rules 5.1, 5.2, 5.4, and 5.5. + */ + + /* The same identifier has both internal and external linkage in + the same translation unit (ISO C, Appendix A.6.2, point 8). + */ + +e401 /* symbol not previously declared static */ + +elib(401) + -append(401,[MISRA 2012 Rule 1.3, required]) + + /* Multiple definitions for the same externally linked identifier + (ISO C, Appendix A.6.2, point 9). + */ + +e31 /* symbol redefinition */ + +elib(31) + + /* Using automatic storage data via a pointer after the data's + lifetime (ISO C, Appendix A.6.2, point 10). + */ + +e604 /* returning address of auto variable */ + +elib(604) + -append(604,[MISRA 2012 Rule 1.3, required]) + +e934 /* taking address of near auto variable */ + +elib(934) + -append(934,[MISRA 2012 Rule 1.3, required]) + + /* Incompatible redeclarations (ISO C, Appendix A.6.2, point 11). + See Rule 8.3 + */ + + /* Non-standard escape sequence (ISO C, Appendix A.6.2, point 12). + */ + +e606 /* non-ANSI escape sequence */ + +elib(606) + -append(606,[MISRA 2012 Rule 1.3, required]) + + /* Non-standard character in header name (ISO C, Appendix A.6.2, + point 15). + See Rule 20.2 + */ + +e9020 /* header name with non-standard character */ + +elib(9020) + -append(9020,[MISRA 2012 Rule 1.3, required]) + + /* No complete type available (ISO C, Appendix A.6.2, point 16). + */ + +e86 /* structure has no data elements */ + +elib(86) + -append(86,[MISRA 2012 Rule 1.3, required]) + + /* Using or converting a void expression (ISO C, Appendix A.6.2, + point 17). + */ + +e64 /* type mismatch */ + +elib(64) + -append(64,[MISRA 2012 Rule 1.3, required]) + +e67 /* cannot cast between types */ + +elib(67) + -append(67,[MISRA 2012 Rule 1.3, required]) + +e144 /* non-existent return value */ + +elib(144) + -append(144,[MISRA 2012 Rule 1.3, required]) + + /* Modifying an object more than once or modifying and accessing + between two sequence points (ISO C, Appendix A.6.2, point 18). + See Rule 13.2 + */ + +e564 /* variable depends on order of evaluation */ + +elib(564) + -append(564,[MISRA 2012 Rule 1.3, required]) + + /* Invalid arithmetic operations or unrepresentable results + (ISO C, Appendix A.6.2, point 19). + */ + +e54 /* division by 0 */ + +elib(54) + -append(54,[MISRA 2012 Rule 1.3, required]) + +e414 /* possible division by 0 */ + +elib(414) + -append(414,[MISRA 2012 Rule 1.3, required]) + +e795 /* conceivable division by 0 */ + +elib(795) + -append(795,[MISRA 2012 Rule 1.3, required]) + /* Also, see Rule 12.4 */ + + /* Passing a void argument to a function (ISO C, Appendix A.6.2, + point 20). + */ + +e64 /* type mismatch */ + +elib(64) + + /* Incompatible function redeclaration (ISO C, Appendix A.6.2, + point 22). + See Rule 8.3 + */ + + /* An invalid array reference, null pointer reference, or + reference to an object declared with automatic storage duration in + a terminated block occurs (ISO C, Appendix A.6.2, point 24). + */ + +e64 /* type mismatch */ + +elib(64) + +e413 /* likely use of null pointer */ + +elib(413) + -append(413,[MISRA 2012 Rule 1.3, required]) + +e415 /* out-of-bounds pointer */ + +elib(415) + -append(415,[MISRA 2012 Rule 1.3, required]) + +e416 /* out-of-bounds pointer */ + +elib(416) + -append(416,[MISRA 2012 Rule 1.3, required]) + +e428 /* negative subscript */ + +elib(428) + -append(428,[MISRA 2012 Rule 1.3, required]) + /* Also, see Rule 17.6 */ + + /* A pointer to a function is converted to a pointer to an object + or a pointer to an object is converted to a pointer to a function + (ISO C, Appendix A.6.2, point 26). + */ + +e64 /* type mismatch */ + +elib(64) + +e740 /* unusual pointer cast */ + +elib(740) + -append(740,[MISRA 2012 Rule 1.3, required]) + /* Also, see Rule 11.1 and 11.2 */ + + /* A pointer is converted to other than an integral or pointer + type (ISO C, Appendix A.6.2, point 27). + */ + +e64 /* type mismatch */ + +elib(64) + +e71 /* cannot cast */ + +elib(71) + + /* An expression is shifted by a negative number or by an amount + greater than or equal to the width in bits of the expression being + shifted (ISO C, Appendix A.6.2, point 30). + */ + +e504 /* unusual shift */ + +elib(504) + -append(504,[MISRA 2012 Rule 1.3, required]) + + /* An identifier for an object is declared with no linkage and the + type of the object is incomplete after its declarator, or after its + init-declarator if it has an initializer (ISO C, Appendix + A.6.2, point 33). + */ + +e86 /* structure has no data elements */ + +elib(86) + + /* Declaring a function at block scope with a storage-class + specifier other than extern (ISO C, Appendix A.6.2, point 34). + */ + +e629 /* static class for function */ + +elib(629) + -append(629,[MISRA 2012 Rule 1.3, required]) + + /* A bit-field is declared with a type other than int, signed int, + or unsigned int (ISO C, Appendix A.6.2, point 35). + See Rule 6.1. + */ + + /* Attempting to modify an object with const-qualified type by + means of an lvalue with non-const-qualified type (ISO C, + Appendix A.6.2, point 36). + */ + +e158 /* assignment increases capability */ + +elib(158) + -append(158,[MISRA 2012 Rule 1.3, required]) + + /* Attempting to refer to an object with volatile-qualified type + by means of an lvalue with non-volatile-qualified type (ISO C, + Appendix A.6.2, point 37). + */ + +e158 /* assignment increases capability */ + +elib(158) + + /* Using the value of uninitialized automatic object (ISO C, + Appendix A.6.2, point 38). + See Rule 9.1 + */ + + /* An object with aggregate or union type with static storage + duration has a non-brace-enclosed initializer, or an object + with aggregate or union type with automatic storage duration + has either a single expression initializer with a type other + than that of the object or a non-brace-enclosed initializer + (ISO C, Appendix A.6.2, point 39). + Also, see Rule 9.2 + */ + +e64 /* type mismatch */ + +elib(64) + + /* The value of a function is used, but no value was returned + (ISO C, Appendix A.6.2, point 40). + See Rule 17.4. + */ + + /* A function that accepts a variable number of arguments is + defined without a parameter type list that ends with the + ellipsis notation (ISO C, Appendix A.6.2, point 41). + */ + + /* An identifier for an object with internal linkage and an + incomplete type is declared with a tentative definition (ISO C, + Appendix A.6.2, point 42). + */ + +e86 /* structure has no data elements */ + +elib(86) + + /* Non-standard #include preprocessing directive (ISO C, Appendix + A.6.2, point 44). + See Rule 20.3. + */ + + /* Non-standard #line directive (ISO C, Appendix A.6.2, point 49). + */ + +"estring(10,a numeric constant)" /* expecting a numeric constant */ + + /* #defining or #undefing any of: defined, __LINE__, __FILE__, + __DATE__, __TIME__, or __STDC__ (ISO C, Appendix A.6.2, point 50). + */ + +e136 /* illegal macro name */ + +elib(136) + -append(136,[MISRA 2012 Rule 1.3, required]) + + /* Format-argument mismatch in an fprintf or fscanf type of + function (ISO C, Appendix A.6.2, point 75). + */ + +e558 /* too few arguments */ + +elib(558) + -append(558,[MISRA 2012 Rule 1.3, required]) + +e719 /* too many arguments */ + +elib(719) + -append(719,[MISRA 2012 Rule 1.3, required]) + + /* A %% conversion specification for the fprintf or fscanf + function contains characters between the pair of % characters + (ISO C, Appendix A.6.2, point 77). + */ + +e557 /* unrecognized format */ + +elib(557) + -append(557,[MISRA 2012 Rule 1.3, required]) + + /* An aggregate or union, or a pointer to an aggregate or union is + an argument to the fprintf function, except for the conversion + specifiers %s (for an array of character type) or %p (for a pointer + to void) (ISO C, Appendix A.6.2, point 81). + */ + +e437 /* passing struct to ellipsis */ + +elib(437) + -append(437,[MISRA 2012 Rule 1.3, required]) + + /* Referring to deallocated space (ISO C, Appendix A.6.2, point + 87). + */ + +e449 /* previously deallocated pointer */ + +elib(449) + -append(449,[MISRA 2012 Rule 1.3, required]) + + /* Misuse of free or realloc (ISO C, Appendix A.6.2, point 88). + */ + +esym(424,free) /* inappropriate deallocation */ + -append(424,[MISRA 2012 Rule 1.3, required]) + + /* An array written to by a copying or concatenation function is + too small (ISO C, Appendix A.6.2, point 91). + */ + +e419 /* data overrun */ + +elib(419) + -append(419,[MISRA 2012 Rule 1.3, required]) + + /* Order of evaluation (ISO C, Appendix A.6.1, point 7). + */ + +e564 /* variable depends on order of evaluation */ + +elib(564) + -append(564,[MISRA 2012 Rule 1.3, required]) + + /* Side effects order (ISO C, Appendix A.6.1, point 8). + */ + +e931 /* both sides of an expression have side-effects */ + +elib(931) + -append(931,[MISRA 2012 Rule 1.3, required]) + + /* Function argument evaluation (ISO C, Appendix A.6.1, point 9). + */ + +e564 /* variable depends on order of evaluation */ + +elib(564) + + /* The order in which # and ## operations are evaluated during + macro substitution (ISO C, Appendix A.6.1, point 12). + */ + +e9023 /* multiple '#/##' operators in macro definition */ + +elib(9023) + -append(9023,[MISRA 2012 Rule 1.3, required]) + + /* Whether setjmp is a macro or an external identifier (ISO C, + Appendix A.6.1, point 14). + See Rule 21.2. + */ + +/**** Rule 2.1 (Req) ************/ + + /* While MISRA has declared this rule to be "undecidable", Gimpel + * Software provides the following options to assist: + */ + +e506 /* constant value boolean */ + +elib(506) + -append(506,[MISRA 2012 Rule 2.1, required]) + +e527 /* unreachable */ + +elib(527) + -append(527,[MISRA 2012 Rule 2.1, required]) + +e681 /* loop not entered */ + +elib(681) + -append(681,[MISRA 2012 Rule 2.1, required]) + +e827 /* loop not reachable */ + +elib(827) + -append(827,[MISRA 2012 Rule 2.1, required]) + +/**** Rule 2.2 (Req) ************/ + + /* While MISRA has declared this rule to be "undecidable", Gimpel + * Software provides the following options to assist: + */ + +e438 /* value not used */ + +elib(438) + -append(438,[MISRA 2012 Rule 2.2, required]) + +e505 /* redundant argument to comma */ + +elib(505) + -append(505,[MISRA 2012 Rule 2.2, required]) + +e520 /* highest operator has no side effects */ + +elib(520) + -append(520,[MISRA 2012 Rule 2.2, required]) + +e521 /* highest operator has no side effects */ + +elib(521) + -append(521,[MISRA 2012 Rule 2.2, required]) + +e522 /* highest operator has no side effects */ + +elib(522) + -append(522,[MISRA 2012 Rule 2.2, required]) + +/**** Rule 2.3 (Adv) ************/ + + +e751 /* local typedef not referenced */ + +elib(751) + -append(751,[MISRA 2012 Rule 2.3, advisory]) + +e756 /* global not referenced */ + +elib(756) + -append(756,[MISRA 2012 Rule 2.3, advisory]) + +/**** Rule 2.4 (Adv) ************/ + + +e753 /* local tag not referenced */ + +elib(753) + -append(753,[MISRA 2012 Rule 2.4, advisory]) + +e9058 + +elibsym(9058) + -append(9058,[MISRA 2012 Rule 2.4, advisory]) + +/**** Rule 2.5 (Adv) ************/ + + +e750 /* local macro not referenced */ + +elib(750) + -append(750,[MISRA 2012 Rule 2.5, advisory]) + +e755 /* global macro not referenced */ + +elib(755) + -append(755,[MISRA 2012 Rule 2.5, advisory]) + +/**** Rule 2.6 (Adv) ************/ + + +e563 /* label not referenced */ + +elib(563) + -append(563,[MISRA 2012 Rule 2.6, advisory]) + +/**** Rule 2.7 (Adv) ************/ + + +e715 /* not referenced */ + +elib(715) + -append(715,[MISRA 2012 Rule 2.7, advisory]) + +/**** Rule 3.1 (Req) ************/ + + -fnc /* flag nested comments */ + +e602 /* comment within comment */ + +elib(602) + -append(602,[MISRA 2012 Rule 3.1, required]) + +e9059 + +elib(9059) + -append(9059,[MISRA 2012 Rule 3.1, required]) + +e9066 + +elib(9066) + -append(9066,[MISRA 2012 Rule 3.1, required]) + +/**** Rule 3.2 (Req) ************/ + + +e427 /* C++ comment ends in \\ */ + +elib(427) + -append(427,[MISRA 2012 Rule 3.2, required]) + +/**** Rule 4.1 (Req) ************/ + + +e9039 /* prohibited escape sequence */ + +elib(9039) + -append(9039,[MISRA 2012 Rule 4.1, required]) + +/**** Rule 4.2 (Adv) ************/ + + -ftg /* inhibit use of trigraphs */ + +e584 /* activate trigraph detected message */ + +elib(584) + -append(584,[MISRA 2012 Rule 4.2, advisory]) + +e739 /* activate trigraph in string message */ + +elib(739) + -append(739,[MISRA 2012 Rule 4.2, advisory]) + +e9060 /* trigraph in comment */ + +elib(9060) + -append(9060,[MISRA 2012 Rule 4.2, advisory]) + +/**** Rule 5.1 (Req) ************/ + + -idlen(31) /* flag names identical in the first 31 characters */ + +e621 /* Identifier clash - length set by -idlen */ + +elib(621) + -append(621,[MISRA 2012 Rule 5.1, required]) + +/**** Rule 5.2 (Req) ************/ + + -idlen(31) /* flag names identical in the first 31 characters */ + +e621 /* Identifier clash - length set by -idlen */ + +elib(621) + -append(621,[MISRA 2012 Rule 5.2, required]) + +/**** Rule 5.3 (Req) ************/ + + +e578 /* enable reports of name hiding */ + +elib(578) + -append(578,[MISRA 2012 Rule 5.3, required]) + +/**** Rule 5.4 (Req) ************/ + + -idlen(31) /* flag names identical in the first 31 characters */ + +e621 /* Identifier clash - length set by -idlen */ + +elib(621) + -append(621,[MISRA 2012 Rule 5.4, required]) + +/**** Rule 5.5 (Req) ************/ + + +e123 /* macro defined with arguments */ + +elib(123) + -append(123,[MISRA 2012 Rule 5.5, required]) + -idlen(31) /* flag names identical in the first 31 characters */ + +e621 /* Identifier clash - length set by -idlen */ + +elib(621) + -append(621,[MISRA 2012 Rule 5.5, required]) + +e9061 /* non-distinct identifier */ + +elib(9061) + -append(9061,[MISRA 2012 Rule 5.5, required]) + +/**** Rule 5.6 (Req) ************/ + + +e578 /* enable reports of name hiding */ + +elib(578) + -append(578,[MISRA 2012 Rule 5.6, required]) + +e623 /* redefining the storage class of symbol */ + +elib(623) + -append(623,[MISRA 2012 Rule 5.6, required]) + +estring(9062,typedef) /* non-unique typedef */ + +elib(9062) + -append(9062(typedef),[MISRA 2012 Rule 5.6, required]) + +/**** Rule 5.7 (Req) ************/ + + +e407 /* Inconsistent use of tag */ + +elib(407) + -append(407,[MISRA 2012 Rule 5.7, required]) + +e578 /* Declaration of Symbol hides Symbol */ + +elib(578) + -append(578,[MISRA 2012 Rule 5.7, required]) + +e14 /* Symbol previously defined */ + +elib(14) + -append(14,[MISRA 2012 Rule 5.7, required]) + +e15 /* Symbol redeclared */ + +elib(15) + -append(15,[MISRA 2012 Rule 5.7, required]) + +e631 /* Tag defined differently */ + +elib(631) + -append(631,[MISRA 2012 Rule 5.7, required]) + +e9062 /* non-unique tag */ + +elib(9062) + -append(9062(tag),[MISRA 2012 Rule 5.7, required]) + +/**** Rule 5.8 (Req) ************/ + + +e401 /* Symbol not previously declared static */ + +elib(401) + -append(401,[MISRA 2012 Rule 5.8, required]) + +e578 /* Declaration of Symbol hides Symbol */ + +elib(578) + -append(578,[MISRA 2012 Rule 5.8, required]) + +e580 /* enable reports of name hiding */ + +elib(580) + -append(580,[MISRA 2012 Rule 5.8, required]) + +/**** Rule 5.9 (Adv) ************/ + + +e578 /* enable reports of name hiding */ + +elib(578) + -append(578,[MISRA 2012 Rule 5.9, advisory]) + +e580 /* enable reports of name hiding */ + +elib(580) + -append(580,[MISRA 2012 Rule 5.9, advisory]) + +/**** Rule 6.1 (Req) ************/ + + +e46 /* field type should be int */ + +elib(46) + -append(46,[MISRA 2012 Rule 6.1, required]) + +e806 /* small bit field is signed rather than unsigned */ + +elib(806) + -append(806,[MISRA 2012 Rule 6.1, required]) + +/**** Rule 6.2 (Req) ************/ + + +e9088 /* named signed single-bit bit-field */ + +elib(9088) + -append(9088,[MISRA 2012 Rule 6.2, required]) + +/**** Rule 7.1 (Req) ************/ + + +e9001 /* Octal constant used */ + +elib(9001) + -append(9001,[MISRA 2012 Rule 7.1, required]) + +/**** Rule 7.2 (Req) ************/ + + +e9048 /* unsigned literal without 'U' suffix */ + +elib(9048) + -append(9048,[MISRA 2012 Rule 7.2, required]) + +/**** Rule 7.3 (Req) ************/ + + +e620 /* suspicious constant */ + +elib(620) + -append(620,[MISRA 2012 Rule 7.3, required]) + +e9057 /* "l" after "u" in literal suffix */ + +elib(9057) + -append(9057,[MISRA 2012 Rule 7.3, required]) + +/**** Rule 7.4 (Req) ************/ + + +fsc + +e489 /* attempting to modify a string literal */ + +elib(489) + -append(489,[MISRA 2012 Rule 7.4, required]) + +e1776 /* string literal not const safe */ + +elib(1776) + -append(1776,[MISRA 2012 Rule 7.4, required]) + +e1778 /* assignment of string literal not const safe */ + +elib(1778) + -append(1778,[MISRA 2012 Rule 7.4, required]) + +/**** Rule 8.1 (Req) ************/ + + +e601 /* no explicit type */ + +elib(601) + -append(601,[MISRA 2012 Rule 8.1, required]) + +e745 /* function has no explicit type */ + +elib(745) + -append(745,[MISRA 2012 Rule 8.1, required]) + +e808 /* no explicit type */ + +elib(808) + -append(808,[MISRA 2012 Rule 8.1, required]) + +e832 /* parameter has no explicit type */ + +elib(832) + -append(832,[MISRA 2012 Rule 8.1, required]) + +e939 /* return type defaults to int */ + +elib(939) + -append(939,[MISRA 2012 Rule 8.1, required]) + +/**** Rule 8.2 (Req) ************/ + + +e937 /* old-style function declaration */ + +elib(937) + -append(937,[MISRA 2012 Rule 8.2, required]) + +e745 /* function has no explicit type */ + +elib(745) + -append(745,[MISRA 2012 Rule 8.2, required]) + +e939 /* return type defaults to int */ + +elib(939) + -append(939,[MISRA 2012 Rule 8.2, required]) + -fvr /* varying return mode not allowed */ + -strong() /* enable strong typing for + declarations */ + +e18 /* symbol redeclared */ + +elib(18) + -append(18,[MISRA 2012 Rule 8.2, required]) + + +e936 /* old-style function definition */ + +elib(936) + -append(936,[MISRA 2012 Rule 8.2, required]) + + +e955 /* param name missing from prototype */ + +elib(955) + -append(955,[MISRA 2012 Rule 8.2, required]) + +/**** Rule 8.3 (Req) ************/ + + -fvr /* varying return mode not allowed */ + -strong() /* enable strong typing for declarations */ + +e18 /* symbol redeclared */ + +elib(18) + -append(18,[MISRA 2012 Rule 8.3, required]) + +e516 /* argument type conflict */ + +elib(516) + -append(516,[MISRA 2012 Rule 8.3, required]) + +e532 /* return mode of symbol inconsistent */ + +elib(532) + -append(532,[MISRA 2012 Rule 8.3, required]) + +e9072 /* parameter list differs */ + +elib(9072) + -append(9072,[MISRA 2012 Rule 8.3, required]) + +/**** Rule 8.4 (Req) ************/ + + +e15 /* symbol redeclared */ + +elib(15) + -append(15,[MISRA 2012 Rule 8.4, required]) + +e64 /* flag type mismatch */ + +elib(64) + -append(64,[MISRA 2012 Rule 8.4, required]) + +e516 /* argument type mismatch */ + +elib(516) + -append(516,[MISRA 2012 Rule 8.4, required]) + +e9075 /* extern defined without prior declaration */ + +elib(9075) + -append(9075,[MISRA 2012 Rule 8.4, required]) + +/**** Rule 8.5 (Req) ************/ + + +e9004 /* object/function previously declared */ + +elib(9004) + -append(9004,[MISRA 2012 Rule 8.5, required]) + +/**** Rule 8.6 (Req) ************/ + + --fmd /* diallow multiple definitions */ + +e14 /* Symbol previously defined */ + +elib(14) + -append(14,[MISRA 2012 Rule 8.6, required]) + +/**** Rule 8.7 (Adv) ************/ + + +e765 /* could be made static */ + +elib(765) + -append(765,[MISRA 2012 Rule 8.7, advisory]) + +/**** Rule 8.8 (Req) ************/ + + +e839 /* storage class assumed static */ + +elib(839) + -append(839,[MISRA 2012 Rule 8.8, required]) + +/**** Rule 8.9 (Adv) ************/ + + +e9003 /* could define variable at block scope */ + +elib(9003) + -append(9003,[MISRA 2012 Rule 8.9, advisory]) + +/**** Rule 8.10 (Req) ************/ + + +e695 /* inline function without storage-class specifier */ + +elib(695) + -append(695,[MISRA 2012 Rule 8.10, required]) + +estring(9056,extern) /* inline function defined with extern */ + -append(9056,[MISRA 2012 Rule 8.10, required]) + +/**** Rule 8.11 (Adv) ************/ + + +e9067 /* array has no dimension or initializer */ + +elib(9067) + -append(9067,[MISRA 2012 Rule 8.11, advisory]) + +/**** Rule 8.12 (Req) ************/ + + +e488 /* duplicate enumerator values */ + +elib(488) + -append(488,[MISRA 2012 Rule 8.12, required]) + +/**** Rule 8.13 (Adv) ************/ + + /* While MISRA has declared this rule to be "undecidable", Gimpel + * Software provides the following options to assist: + */ + +e818 /* pointer could be declared pointing to const */ + +elib(818) + -append(818,[MISRA 2012 Rule 8.13, advisory]) + +e844 /* pointer could be declared pointing to const */ + +elib(844) + -append(844,[MISRA 2012 Rule 8.13, advisory]) + +e954 /* pointer could be declared pointing to const */ + +elib(954) + -append(954,[MISRA 2012 Rule 8.13, advisory]) + +/**** Rule 8.14 (Req) ************/ + + +e586 /* Symbol is deprecated */ + +elib(586) + -deprecate(keyword,restrict,[MISRA 2012 Rule 8.14, required]) + +/**** Rule 9.1 (Mand) ************/ + + /* While MISRA has declared this rule to be "undecidable", Gimpel + * Software provides the following options to assist: + */ + +e644 /* Symbol may not have been initialized */ + +elib(644) + -append(644,[MISRA 2012 Rule 9.1, mandatory]) + +e771 /* Symbol conceivably not initialized */ + +elib(771) + -append(771,[MISRA 2012 Rule 9.1, mandatory]) + +e530 /* Symbol not initialized */ + +elib(530) + -append(530,[MISRA 2012 Rule 9.1, mandatory]) + -specific(+e644 +e771 +e530,) + +/**** Rule 9.2 (Req) ************/ + + +e9069 /* omitted braces within an initializer */ + +elib(9069) + -append(9069,[MISRA 2012 Rule 9.2, required]) + +/**** Rule 9.3 (Req) ************/ + + +e9068 /* too few initializers */ + +elib(9068) + -append(9068,[MISRA 2012 Rule 9.3, required]) + +/**** Rule 9.4 (Req) ************/ + + +e485 /* duplicate initialization */ + +elib(485) + -append(485,[MISRA 2012 Rule 9.4, required]) + +/**** Rule 9.5 (Req) ************/ + + +e9054 /* designated initializer and dimensionless array */ + +elib(9054) + -append(9054,[MISRA 2012 Rule 9.5, required]) + +/**** Rule 10.1 (Req) ************/ + + +e48 /* bad type */ + +elib(48) + -append(48,[MISRA 2012 Rule 10.1, required]) + +e9027 /* unpermitted operand */ + +elib(9027) + -append(9027,[MISRA 2012 Rule 10.1, required]) + +/**** Rule 10.2 (Req) ************/ + + +e9028 /* unpermitted arithmetic */ + +elib(9028) + -append(9028,[MISRA 2012 Rule 10.2, required]) + +/**** Rule 10.3 (Req) ************/ + + +e9034 /* expression assigned to narrower or different essential type */ + +elib(9034) + // Note: the following -d options for true and false don't apply + // to C90 and should be commented out if not using C99 + +"dtrue=/*lint -save -e921 */(_Bool) 1/*lint -restore */" // exception + +"dfalse=/*lint -save -e921 */(_Bool) 0/*lint -restore */" // exception + -append(9034,[MISRA 2012 Rule 10.3, required]) + +/**** Rule 10.4 (Req) ************/ + + +e9029 /* mismatched essential type */ + +elib(9029) + -append(9029,[MISRA 2012 Rule 10.4, required]) + +/**** Rule 10.5 (Adv) ************/ + + +e9030 /* impermissible cast */ + +elib(9030) + -append(9030,[MISRA 2012 Rule 10.5, advisory]) + +/**** Rule 10.6 (Req) ************/ + + +e9031 /* composite expression assigned to wider essential type */ + +elib(9031) + -append(9031,[MISRA 2012 Rule 10.6, required]) + +/**** Rule 10.7 (Req) ************/ + + +e9032 /* composite expression with smaller essential type than other operand*/ + +elib(9032) + -append(9032,[MISRA 2012 Rule 10.7, required]) + +/**** Rule 10.8 (Req) ************/ + + +e9033 /* impermissible cast of composite expression */ + +elib(9033) + -append(9033,[MISRA 2012 Rule 10.8, required]) + +/**** Rule 11.1 (Req) ************/ + + +e9074 /* conversion between a pointer to function and another type */ + +elib(9074) + --emacro((9074),NULL) /* explicit exception */ + -append(9074,[MISRA 2012 Rule 11.1, required]) + +/**** Rule 11.2 (Req) ************/ + + +e9076 /* conversion between a pointer to incomplete type and another type */ + +elib(9076) + --emacro((9076),NULL) /* explicit exception */ + -append(9076,[MISRA 2012 Rule 11.2, required]) + +/**** Rule 11.3 (Req) ************/ + + +e9087 /* cast from pointer to pointer */ + +elib(9087) + -append(9087,[MISRA 2012 Rule 11.3, required]) + +/**** Rule 11.4 (Adv) ************/ + + +e9078 /* cast pointer/integer */ + +elib(9078) + -append(9078,[MISRA 2012 Rule 11.4, advisory]) + +/**** Rule 11.5 (Adv) ************/ + + +e9079 /* cast from pointer to pointer */ + +elib(9079) + -append(9079,[MISRA 2012 Rule 11.5, advisory]) + +/**** Rule 11.6 (Req) ************/ + + +e923 /* cast pointer/non-pointer */ + +elib(923) + -append(923,[MISRA 2012 Rule 11.6, required]) + +/**** Rule 11.7 (Req) ************/ + + +e68 /* cast pointer/float */ + +elib(68) + -append(68,[MISRA 2012 Rule 11.7, required]) + +e70 /* cast pointer/float */ + +elib(70) + -append(70,[MISRA 2012 Rule 11.7, required]) + +/**** Rule 11.8 (Req) ************/ + + +e9005 /* attempt to cast away const/volatile from pointer or reference */ + +elib(9005) + -append(9005,[MISRA 2012 Rule 11.8, required]) + +/**** Rule 11.9 (Req) ************/ + + +e910 /* conversion from 0 to pointer */ + +elib(910) + --emacro((910),NULL) /* explicit exception */ + -append(910,[MISRA 2012 Rule 11.9, required]) + +e9080 /* integer null pointer constant */ + +elib(9080) + -append(9080,[MISRA 2012 Rule 11.9, required]) + +/**** Rule 12.1 (Adv) ************/ + + +e9050 /* dependence placed on precedence */ + +elib(9050) + -append(9050,[MISRA 2012 Rule 12.1, advisory]) + +/**** Rule 12.2 (Req) ************/ + + /* While MISRA has declared this rule to be "undecidable", Gimpel + * Software provides the following options to assist: + */ + +e598 /* excessive left shift */ + +elib(598) + -append(598,[MISRA 2012 Rule 12.2, required]) + +e9053 /* shift value exceeds size of LHS */ + +elib(9053) + -append(9053,[MISRA 2012 Rule 12.2, required]) + +/**** Rule 12.3 (Adv) ************/ + + +e9008 /* comma operator used */ + +elib(9008) + -append(9008,[MISRA 2012 Rule 12.3, advisory]) + +/**** Rule 12.4 (Adv) ************/ + + +elib(648) /* Overflow in computing constant */ + +estring(648,unsigned addition) + +estring(648,unsigned multiplication) + +estring(648,unsigned sub.) + +estring(648,unsigned shift left) + +estring(648,unsigned shift right) + -append(648,[MISRA 2012 Rule 12.4, advisory]) + +/**** Rule 13.1 (Req) ************/ + + /* While MISRA has declared this rule to be "undecidable", Gimpel + * Software provides the following options to assist: + */ + +e446 /* side effect in initializer */ + +elib(446) + -append(446,[MISRA 2012 Rule 13.1, required]) + +/**** Rule 13.2 (Req) ************/ + + /* While MISRA has declared this rule to be "undecidable", Gimpel + * Software provides the following options to assist: + */ + +e564 /* variable depends on order of evaluation */ + +elib(564) + -append(564,[MISRA 2012 Rule 13.2, required]) + +e864 /* variable possibly depends on order of evaluation */ + +elib(864) + -append(864,[MISRA 2012 Rule 13.2, required]) + +e931 /* both sides have side effects */ + +elib(931) + -append(931,[MISRA 2012 Rule 13.2, required]) + +/**** Rule 13.3 (Adv) ************/ + + +e9049 /* increment/decrement combined with other operations */ + +elib(9049) + -append(9049,[MISRA 2012 Rule 13.3, advisory]) + +/**** Rule 13.4 (Adv) ************/ + + +e720 /* Boolean test of assignment */ + +elib(720) + -append(720,[MISRA 2012 Rule 13.4, advisory]) + +e820 /* Boolean test of parenthesized assignment */ + +elib(820) + -append(820,[MISRA 2012 Rule 13.4, advisory]) + +e9084 /* assignment used inside larger + expression */ + +elib(9084) + -append(9084,[MISRA 2012 Rule 13.4, advisory]) + +/**** Rule 13.5 (Req) ************/ + + /* While MISRA has declared this rule to be "undecidable", Gimpel + * Software provides the following options to assist: + */ + +e9007 /* side effects on right hand side of logical operator */ + +elib(9007) + -append(9007,[MISRA 2012 Rule 13.5, required]) + +/**** Rule 13.6 (Mand) ************/ + + +e9006 /* sizeof used with expression with side effect */ + +elib(9006) + -append(9006,[MISRA 2012 Rule 13.6, mandatory]) + +e9089 /* potential side-effect in argument to sizeof */ + +elib(9089) + -append(9089,[MISRA 2012 Rule 13.6, mandatory]) + +/**** Rule 14.1 (Req) ************/ + + /* While MISRA has declared this rule to be "undecidable", Gimpel + * Software provides the following options to assist: + */ + +e9009 /* floating point variable used as loop counter */ + +elib(9009) + -append(9009,[MISRA 2012 Rule 14.1, required]) + +/**** Rule 14.2 (Req) ************/ + + /* While MISRA has declared this rule to be "undecidable", Gimpel + * Software provides the following options to assist: + */ + +e850 /* index variable modified in body of for loop */ + +elib(850) + -append(850,[MISRA 2012 Rule 14.2, required]) + +/**** Rule 14.3 (Req) ************/ + + /* While MISRA has declared this rule to be "undecidable", Gimpel + * Software provides the following options to assist: + */ + +e685 /* relational always evaluates to true/false */ + +elib(685) + -append(685,[MISRA 2012 Rule 14.3, required]) + +e774 /* boolean always evaluates to true/false */ + +elib(774) + -append(774,[MISRA 2012 Rule 14.3, required]) + +e650 /* constant out of range for operator */ + +elib(650) + -append(650,[MISRA 2012 Rule 14.3, required]) + +/**** Rule 14.4 (Req) ************/ + + +e9036 /* condition should have essentially Boolean type */ + +elib(9036) + -append(9036,[MISRA 2012 Rule 14.4, required]) + +/**** Rule 15.1 (Adv) ************/ + + +e801 /* use of 'goto' is deprecated */ + +elib(801) + -append(801,[MISRA 2012 Rule 15.1, advisory]) + +/**** Rule 15.2 (Req) ************/ + + +e9064 /* goto references earlier label */ + +elib(9064) + -append(9064,[MISRA 2012 Rule 15.2, required]) + +/**** Rule 15.3 (Req) ************/ + + +e9041 /* goto not nested in the same block as label */ + +elib(9041) + -append(9041,[MISRA 2012 Rule 15.3, required]) + +/**** Rule 15.4 (Adv) ************/ + + +e9011 /* more than one 'break' terminates loop */ + +elib(9011) + -append(9011,[MISRA 2012 Rule 15.4, advisory]) + +/**** Rule 15.5 (Adv) ************/ + + +e904 /* return before function end */ + +elib(904) + -append(904,[MISRA 2012 Rule 15.5, advisory]) + +/**** Rule 15.6 (Req) ************/ + + +e9012 /* sub-statement should be a compound statement */ + +elib(9012) + -append(9012,[MISRA 2012 Rule 15.6, required]) + +/**** Rule 15.7 (Req) ************/ + + +e9013 /* no 'else' at end of 'if ... else if' chain */ + +elib(9013) + -append(9013,[MISRA 2012 Rule 15.7, required]) + +e9063 /* no comment or action in else-branch */ + +elib(9063) + -append(9063,[MISRA 2012 Rule 15.7, required]) + +/**** Rule 16.1 (Req) ************/ + + +e616 /* control flows into case/default */ + +elib(616) + -append(616,[MISRA 2012 Rule 16.1, required]) + +e744 /* switch statement has no default */ + +elib(744) + -append(744,[MISRA 2012 Rule 16.1, required]) + +e764 /* switch does not have a case */ + +elib(764) + -append(764,[MISRA 2012 Rule 16.1, required]) + +e825 /* control flows into case/default without -fallthrough comment */ + +elib(825) + -append(825,[MISRA 2012 Rule 16.1, required]) + +e9014 /* default missing from switch */ + +elib(9014) + -append(9014,[MISRA 2012 Rule 16.1, required]) + +e9042 /* departure from MISRA switch syntax */ + +elib(9042) + -append(9042,[MISRA 2012 Rule 16.1, required]) + +e9077 /* missing unconditional break */ + +elib(9077) + -append(9077,[MISRA 2012 Rule 16.1, required]) + +e9081 /* too few independent cases for switch */ + +elib(9081) + -append(9081,[MISRA 2012 Rule 16.1, required]) + +e9082 /* switch statement should either begin or end with default label */ + +elib(9082) + -append(9082,[MISRA 2012 Rule 16.1, required]) + +e9085 /* statement or comment should appear in default case */ + +elib(9085) + -append(9085,[MISRA 2012 Rule 16.1, required]) + +/**** Rule 16.2 (Req) ************/ + + +e44 /* Need a switch */ + +elib(44) + -append(44,[MISRA 2012 Rule 16.2, required]) + +e9055 /* enclosing statement is not a switch */ + +elib(9055) + -append(9055,[MISRA 2012 Rule 16.2, required]) + +/**** Rule 16.3 (Req) ************/ + + +e616 /* control flows into case/default */ + +elib(616) + -append(616,[MISRA 2012 Rule 16.3, required]) + +e825 /* control flows into case/default without -fallthrough comment */ + +elib(825) + -append(825,[MISRA 2012 Rule 16.3, required]) + +e9077 /* missing unconditional break */ + +elib(9077) + -append(9077,[MISRA 2012 Rule 16.3, required]) + +e9090 /* missing unconditional break */ + +elib(9090) + -append(9090,[MISRA 2012 Rule 16.3, required]) + +/**** Rule 16.4 (Req) ************/ + + +e744 /* switch statement has no default */ + +elib(744) + -append(744,[MISRA 2012 Rule 16.4, required]) + +e9014 /* switch statement has no default */ + +elib(9014) + -append(9014,[MISRA 2012 Rule 16.4, required]) + +e9085 /* default case has no statement nor comment */ + +elib(9085) + -append(9085,[MISRA 2012 Rule 16.4, required]) + +/**** Rule 16.5 (Req) ************/ + + +e9082 /* default should be first or last */ + +elib(9082) + -append(9082,[MISRA 2012 Rule 16.5, required]) + +/**** Rule 16.6 (Req) ************/ + + +e764 /* switch does not have a case */ + +elib(764) + -append(764,[MISRA 2012 Rule 16.6, required]) + +e9081 /* too few cases */ + +elib(9081) + -append(9081,[MISRA 2012 Rule 16.6, required]) + +/**** Rule 16.7 (Req) ************/ + + +e483 /* boolean value in switch expression */ + +elib(483) + -append(483,[MISRA 2012 Rule 16.7, required]) + +/**** Rule 17.1 (Req) ************/ + + +e829 /* warn on header usage */ + +elib(829) + +headerwarn(stdarg.h) + -append(829(stdarg.h),[MISRA 2012 Rule 17.1, required]) + -deprecate(macro,va_arg,[MISRA 2012 Rule 17.1, required]) + -deprecate(macro,va_start,[MISRA 2012 Rule 17.1, required]) + -deprecate(macro,va_end,[MISRA 2012 Rule 17.1, required]) + -deprecate(macro,va_copy,[MISRA 2012 Rule 17.1, required]) + +/**** Rule 17.2 (Req) ************/ + + /* While MISRA has declared this rule to be "undecidable", Gimpel + * Software provides the following options to assist: + */ + +e9070 + -append(9070,[MISRA 2012 Rule 17.2, required]) + +/**** Rule 17.3 (Mand) ************/ + + +e718 /* symbol undeclared, assumed to return int */ + +elib(718) + -append(718,[MISRA 2012 Rule 17.3, mandatory]) + +/**** Rule 17.4 (Mand) ************/ + + +e533 /* function should return a value */ + +elib(533) + -append(533,[MISRA 2012 Rule 17.4, mandatory]) + +/**** Rule 17.5 (Adv) ************/ + + /* MISRA has declared this rule to be "undecidable". */ + +/**** Rule 17.6 (Mand) ************/ + + +e9043 /* static between brackets of array declaration */ + +elib(9043) + -append(9043,[MISRA 2012 Rule 17.6, mandatory]) + +/**** Rule 17.7 (Req) ************/ + + +e534 /* ignoring return value of function */ + +elib(534) + -append(534,[MISRA 2012 Rule 17.7, required]) + +/**** Rule 17.8 (Adv) ************/ + + /* While MISRA has declared this rule to be "undecidable", Gimpel + * Software provides the following options to assist: + */ + +e9044 /* function parameter modified */ + +elib(9044) + -append(9044,[MISRA 2012 Rule 17.8, advisory]) + +/**** Rule 18.1 (Req) ************/ + + /* While MISRA has declared this rule to be "undecidable", Gimpel + * Software provides the following options to assist: + */ + +e415 /* out-of-bounds pointer */ + +elib(415) + -append(415,[MISRA 2012 Rule 18.1, required]) + +e416 /* out-of-bounds pointer */ + +elib(416) + -append(416,[MISRA 2012 Rule 18.1, required]) + +e428 /* out-of-bounds pointer */ + +elib(428) + -append(428,[MISRA 2012 Rule 18.1, required]) + +e661 /* out-of-bounds pointer */ + +elib(661) + -append(661,[MISRA 2012 Rule 18.1, required]) + +e662 /* out-of-bounds pointer */ + +elib(662) + -append(662,[MISRA 2012 Rule 18.1, required]) + +e676 /* out-of-bounds pointer */ + +elib(676) + -append(676,[MISRA 2012 Rule 18.1, required]) + +e796 /* out-of-bounds pointer */ + +elib(796) + -append(796,[MISRA 2012 Rule 18.1, required]) + +e797 /* out-of-bounds pointer */ + +elib(797) + -append(797,[MISRA 2012 Rule 18.1, required]) + +e817 /* out-of-bounds pointer */ + +elib(817) + -append(817,[MISRA 2012 Rule 18.1, required]) + +/**** Rule 18.2 (Req) ************/ + + /* While MISRA has declared this rule to be "undecidable", Gimpel + * Software provides the following options to assist: + */ + +e946 /* relational or subtract operator applied to pointers */ + +elib(946) + -append(946,[MISRA 2012 Rule 18.2, required]) + +e947 /* relational or subtract operator applied to pointers */ + +elib(947) + -append(947,[MISRA 2012 Rule 18.2, required]) + +/**** Rule 18.3 (Req) ************/ + + /* While MISRA has declared this rule to be "undecidable", Gimpel + * Software provides the following options to assist: + */ + +e946 /* relational or subtract operator applied to pointers */ + +elib(946) + -append(946,[MISRA 2012 Rule 18.3, required]) + +e947 /* relational or subtract operator applied to pointers */ + +elib(947) + -append(947,[MISRA 2012 Rule 18.3, required]) + +/**** Rule 18.4 (Adv) ************/ + + +e9016 /* pointer arithmetic other than array indexing used */ + +elib(9016) + -append(9016,[MISRA 2012 Rule 18.4, advisory]) + +/**** Rule 18.5 (Adv) ************/ + + +e9025 /* more than two pointer indirection levels used */ + +elib(9025) + -append(9025,[MISRA 2012 Rule 18.5, advisory]) + +/**** Rule 18.6 (Req) ************/ + + /* While MISRA has declared this rule to be "undecidable", Gimpel + * Software provides the following options to assist: + */ + +e733 /* assigning address of auto to outer scope symbol */ + +elib(733) + -append(733,[MISRA 2012 Rule 18.6, required]) + +e789 /* assigning address of auto to static */ + +elib(789) + -append(789,[MISRA 2012 Rule 18.6, required]) + +e604 /* returning address of auto variable */ + +elib(604) + -append(604,[MISRA 2012 Rule 18.6, required]) + +/**** Rule 18.7 (Req) ************/ + + +e9038 /* flexible array member declared */ + +elib(9038) + -append(9038,[MISRA 2012 Rule 18.7, required]) + +/**** Rule 18.8 (Req) ************/ + + +e9035 /* variable length array declared */ + +elib(9035) + -append(9035,[MISRA 2012 Rule 18.8, required]) + +/**** Rule 19.1 (Mand) ************/ + + /* MISRA has declared this rule to be "undecidable". */ + +/**** Rule 19.2 (Adv) ************/ + + +e9018 /* union type/object declared */ + +elib(9018) + -append(9018,[MISRA 2012 Rule 19.2, advisory]) + +/**** Rule 20.1 (Adv) ************/ + + +e9019 /* declaration before #include */ + +elib(9019) + -append(9019,[MISRA 2012 Rule 20.1, advisory]) + +/**** Rule 20.2 (Req) ************/ + + +e9020 /* header file name with non-standard character */ + +elib(9020) + -append(9020,[MISRA 2012 Rule 20.2, required]) + /* Note: If your system requires the '\' be used as a directory + separator, uncomment the following option. + */ + // -estring(9020,\) + +/**** Rule 20.3 (Req) ************/ + + +e12 /* Need < or " after #include */ + +elib(12) + -append(12,[MISRA 2012 Rule 20.3, required]) + +e9086 /* multiple arguments after #include */ + +elib(9086) + -append(9086,[MISRA 2012 Rule 20.3, required]) + +/**** Rule 20.4 (Req) ************/ + + +e9051 /* macro with same name as a keyword */ + +elib(9051) + -append(9051,[MISRA 2012 Rule 20.4, required]) + +/**** Rule 20.5 (Adv) ************/ + + +e9021 /* use of '#undef' is discouraged */ + +elib(9021) + -append(9021,[MISRA 2012 Rule 20.5, advisory]) + +/**** Rule 20.6 (Req) ************/ + + +e436 /* preprocessor directive in invocation of macro */ + +elib(436) + -append(436,[MISRA 2012 Rule 20.6, required]) + +/**** Rule 20.7 (Req) ************/ + + +e665 /* expression passed to unparenthesized macro */ + +elib(665) + -append(665,[MISRA 2012 Rule 20.7, required]) + +/**** Rule 20.8 (Req) ************/ + + +e9037 /* conditional of #if/#elif does not evaluate to 0 or 1 */ + +elib(9037) + -append(9037,[MISRA 2012 Rule 20.8, required]) + +/**** Rule 20.9 (Req) ************/ + + +e553 /* Undefined preprocessor variable, assumed 0 */ + +elib(553) + -append(553,[MISRA 2012 Rule 20.9, required]) + +/**** Rule 20.10 (Adv) ************/ + + +e9024 /* '#/##' operators used */ + +elib(9024) + -append(9024,[MISRA 2012 Rule 20.10, advisory]) + +/**** Rule 20.11 (Req) ************/ + + +e484 /* stringize operator followed by macro parameter followed by pasting operator */ + +elib(484) + -append(484,[MISRA 2012 Rule 20.11, required]) + +/**** Rule 20.12 (Req) ************/ + + +e9015 /* macro argument is used both with and without '#/##' and is subject to further replacement */ + +elib(9015) + -append(9015,[MISRA 2012 Rule 20.12, required]) + +/**** Rule 20.13 (Req) ************/ + + +e544 /* endif or else not followed by EOL */ + +elib(544) + -append(544,[MISRA 2012 Rule 20.13, required]) + +e16 /* # directive not followed by recognizable word */ + +elib(16) + -append(16,[MISRA 2012 Rule 20.13, required]) + /* other parts of this rule such as a syntax check of the disabled + portions of the code do not seem to be statically checkable + */ + +/**** Rule 20.14 (Req) ************/ + + +e405 /* #if/#ifdef/#ifndef not closed off */ + +elib(405) + -append(405,[MISRA 2012 Rule 20.14, required]) + +/**** Rule 21.1 (Req) ************/ + + +e136 /* Illegal macro name */ + +elib(136) + -append(136,[MISRA 2012 Rule 21.1, required]) + /* Undefining standard library macros is covered by rule 20.5. */ + /* Defining/redefining reserved/standard identifiers is covered + by rules 20.4 and 21.2. + */ + +e9071 /* defined macro reserved to the compiler */ + +elib(9071) + -append(9071,[MISRA 2012 Rule 21.1, required]) + // explicit exemptions + -estring(9071,* because *) + -estring(9071,cerf) + -estring(9071,cerfc) + -estring(9071,cexp2) + -estring(9071,cexpm1) + -estring(9071,clog10) + -estring(9071,clog1p) + -estring(9071,clog2) + -estring(9071,clgamma) + -estring(9071,ctgamma) + -estring(9071,cerff) + -estring(9071,cerfcf) + -estring(9071,cexp2f) + -estring(9071,cexpm1f) + -estring(9071,clog10f) + -estring(9071,clog1pf) + -estring(9071,clog2f) + -estring(9071,clgammaf) + -estring(9071,ctgammaf) + -estring(9071,cerfl) + -estring(9071,cerfcl) + -estring(9071,cexp2l) + -estring(9071,cexpm1l) + -estring(9071,clog10l) + -estring(9071,clog1pl) + -estring(9071,clog2l) + -estring(9071,clgammal) + -estring(9071,ctgammal) + -estring(9071,E0*) + -estring(9071,E1*) + -estring(9071,E2*) + -estring(9071,E3*) + -estring(9071,E4*) + -estring(9071,E5*) + -estring(9071,E6*) + -estring(9071,E7*) + -estring(9071,E8*) + -estring(9071,E9*) + -estring(9071,NDEBUG) + -estring(9071,PRIa*) + -estring(9071,PRIb*) + -estring(9071,PRIc*) + -estring(9071,PRId*) + -estring(9071,PRIe*) + -estring(9071,PRIf*) + -estring(9071,PRIg*) + -estring(9071,PRIh*) + -estring(9071,PRIi*) + -estring(9071,PRIj*) + -estring(9071,PRIk*) + -estring(9071,PRIl*) + -estring(9071,PRIm*) + -estring(9071,PRIn*) + -estring(9071,PRIo*) + -estring(9071,PRIp*) + -estring(9071,PRIq*) + -estring(9071,PRIr*) + -estring(9071,PRIs*) + -estring(9071,PRIt*) + -estring(9071,PRIu*) + -estring(9071,PRIv*) + -estring(9071,PRIw*) + -estring(9071,PRIx*) + -estring(9071,PRIy*) + -estring(9071,PRIz*) + -estring(9071,PRIX*) + -estring(9071,SCNa*) + -estring(9071,SCNb*) + -estring(9071,SCNc*) + -estring(9071,SCNd*) + -estring(9071,SCNe*) + -estring(9071,SCNf*) + -estring(9071,SCNg*) + -estring(9071,SCNh*) + -estring(9071,SCNi*) + -estring(9071,SCNj*) + -estring(9071,SCNk*) + -estring(9071,SCNl*) + -estring(9071,SCNm*) + -estring(9071,SCNn*) + -estring(9071,SCNo*) + -estring(9071,SCNp*) + -estring(9071,SCNq*) + -estring(9071,SCNr*) + -estring(9071,SCNs*) + -estring(9071,SCNt*) + -estring(9071,SCNu*) + -estring(9071,SCNv*) + -estring(9071,SCNw*) + -estring(9071,SCNx*) + -estring(9071,SCNy*) + -estring(9071,SCNz*) + -estring(9071,SCNX*) + +e9083 /* undefined macro reserved to the compiler */ + +elib(9083) + -append(9083,[MISRA 2012 Rule 21.1, required]) + // explicit exemptions + -estring(9083,* because *) + -estring(9083,cerf) + -estring(9083,cerfc) + -estring(9083,cexp2) + -estring(9083,cexpm1) + -estring(9083,clog10) + -estring(9083,clog1p) + -estring(9083,clog2) + -estring(9083,clgamma) + -estring(9083,ctgamma) + -estring(9083,cerff) + -estring(9083,cerfcf) + -estring(9083,cexp2f) + -estring(9083,cexpm1f) + -estring(9083,clog10f) + -estring(9083,clog1pf) + -estring(9083,clog2f) + -estring(9083,clgammaf) + -estring(9083,ctgammaf) + -estring(9083,cerfl) + -estring(9083,cerfcl) + -estring(9083,cexp2l) + -estring(9083,cexpm1l) + -estring(9083,clog10l) + -estring(9083,clog1pl) + -estring(9083,clog2l) + -estring(9083,clgammal) + -estring(9083,ctgammal) + -estring(9083,E0*) + -estring(9083,E1*) + -estring(9083,E2*) + -estring(9083,E3*) + -estring(9083,E4*) + -estring(9083,E5*) + -estring(9083,E6*) + -estring(9083,E7*) + -estring(9083,E8*) + -estring(9083,E9*) + -estring(9083,NDEBUG) + -estring(9083,PRIa*) + -estring(9083,PRIb*) + -estring(9083,PRIc*) + -estring(9083,PRId*) + -estring(9083,PRIe*) + -estring(9083,PRIf*) + -estring(9083,PRIg*) + -estring(9083,PRIh*) + -estring(9083,PRIi*) + -estring(9083,PRIj*) + -estring(9083,PRIk*) + -estring(9083,PRIl*) + -estring(9083,PRIm*) + -estring(9083,PRIn*) + -estring(9083,PRIo*) + -estring(9083,PRIp*) + -estring(9083,PRIq*) + -estring(9083,PRIr*) + -estring(9083,PRIs*) + -estring(9083,PRIt*) + -estring(9083,PRIu*) + -estring(9083,PRIv*) + -estring(9083,PRIw*) + -estring(9083,PRIx*) + -estring(9083,PRIy*) + -estring(9083,PRIz*) + -estring(9083,PRIX*) + -estring(9083,SCNa*) + -estring(9083,SCNb*) + -estring(9083,SCNc*) + -estring(9083,SCNd*) + -estring(9083,SCNe*) + -estring(9083,SCNf*) + -estring(9083,SCNg*) + -estring(9083,SCNh*) + -estring(9083,SCNi*) + -estring(9083,SCNj*) + -estring(9083,SCNk*) + -estring(9083,SCNl*) + -estring(9083,SCNm*) + -estring(9083,SCNn*) + -estring(9083,SCNo*) + -estring(9083,SCNp*) + -estring(9083,SCNq*) + -estring(9083,SCNr*) + -estring(9083,SCNs*) + -estring(9083,SCNt*) + -estring(9083,SCNu*) + -estring(9083,SCNv*) + -estring(9083,SCNw*) + -estring(9083,SCNx*) + -estring(9083,SCNy*) + -estring(9083,SCNz*) + -estring(9083,SCNX*) + +/**** Rule 21.2 (Req) ************/ + + +e683 /* complain about #define standard functions */ + +elib(683) + -append(683,[MISRA 2012 Rule 21.2, required]) + /* Undefining standard library macros is covered by rule 20.5. */ + /* Defining/redefining reserved/standard identifiers is covered + by rule 20.4 and 21.2. + */ + +/**** Rule 21.3 (Req) ************/ + + +e586 /* Symbol is deprecated */ + +elib(586) + -deprecate(function,calloc,[MISRA 2012 Rule 21.3, required]) + -deprecate(macro,calloc,[MISRA 2012 Rule 21.3, required]) + -deprecate(function,malloc,[MISRA 2012 Rule 21.3, required]) + -deprecate(macro,malloc,[MISRA 2012 Rule 21.3, required]) + -deprecate(function,realloc,[MISRA 2012 Rule 21.3, required]) + -deprecate(macro,realloc,[MISRA 2012 Rule 21.3, required]) + -deprecate(function,free,[MISRA 2012 Rule 21.3, required]) + -deprecate(macro,free,[MISRA 2012 Rule 21.3, required]) + +/**** Rule 21.4 (Req) ************/ + + +e829 /* warn on header usage */ + +elib(829) + +headerwarn(setjmp.h) + -append(829(setjmp.h),[MISRA 2012 Rule 21.4, required]) + -deprecate(function,setjmp,[MISRA 2012 Rule 21.4, required]) + -deprecate(function,longjmp,[MISRA 2012 Rule 21.4, required]) + -deprecate(macro,setjmp,[MISRA 2012 Rule 21.4, required]) + -deprecate(macro,longjmp,[MISRA 2012 Rule 21.4, required]) + +/**** Rule 21.5 (Req) ************/ + + +e586 /* Symbol is deprecated */ + +elib(586) + -deprecate(function,signal,[MISRA 2012 Rule 21.5, required]) + -deprecate(function,raise,[MISRA 2012 Rule 21.5, required]) + -deprecate(macro,SIGABRT,[MISRA 2012 Rule 21.5, required]) + -deprecate(macro,SIGFPE,[MISRA 2012 Rule 21.5, required]) + -deprecate(macro,SIGILL,[MISRA 2012 Rule 21.5, required]) + -deprecate(macro,SIGINT,[MISRA 2012 Rule 21.5, required]) + -deprecate(macro,SIGSEGV,[MISRA 2012 Rule 21.5, required]) + -deprecate(macro,SIGTERM,[MISRA 2012 Rule 21.5, required]) + -deprecate(macro,SIG_DFL,[MISRA 2012 Rule 21.5, required]) + -deprecate(macro,SIG_ERR,[MISRA 2012 Rule 21.5, required]) + -deprecate(macro,SIG_IGN,[MISRA 2012 Rule 21.5, required]) + +e829 /* warn on header usage */ + +elib(829) + +headerwarn(signal.h) + -append(829(signal.h),[MISRA 2012 Rule 21.5, required]) + +/**** Rule 21.6 (Req) ************/ + + +e586 /* Symbol is deprecated */ + +elib(586) + -deprecate(function,clearerr,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,fclose,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,feof,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,ferror,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,fflush,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,fgetc,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,fgetpos,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,fgets,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,fgetwc,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,fgetws,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,fopen,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,fprintf,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,fputc,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,fputs,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,fputwc,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,fputws,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,fread,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,fscanf,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,fseek,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,fsetpos,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,freopen,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,ftell,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,fwide,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,fwprintf,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,fwrite,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,fwscanf,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,getc,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,getchar,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,gets,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,getwc,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,getwchar,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,perror,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,printf,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,putc,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,putchar,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,puts,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,putwc,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,putwchar,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,remove,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,rename,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,rewind,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,scanf,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,setbuf,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,setvbuf,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,snprintf,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,sprintf,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,sscanf,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,swprintf,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,swscanf,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,tmpfile,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,tmpnam,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,ungetc,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,ungetwc,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,vfprintf,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,vfscanf,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,vfwprintf,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,vfwscanf,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,vprintf,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,vscanf,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,vsnprintf,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,vsprintf,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,vsscanf,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,vswprintf,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,vswscanf,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,vwprintf,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,vwscanf,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,wprintf,[MISRA 2012 Rule 21.6, required]) + -deprecate(function,wscanf,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,clearerr,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,fclose,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,feof,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,ferror,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,fflush,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,fgetc,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,fgets,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,fgetpos,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,fgetwc,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,fgetws,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,fopen,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,fprintf,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,fputc,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,fputs,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,fputwc,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,fputws,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,fread,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,fscanf,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,fseek,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,fsetpos,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,freopen,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,ftell,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,fwide,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,fwprintf,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,fwrite,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,fwscanf,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,getc,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,getchar,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,gets,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,getwc,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,getwchar,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,perror,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,printf,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,putc,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,putchar,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,puts,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,putwc,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,putwchar,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,remove,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,rename,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,rewind,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,scanf,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,setbuf,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,setvbuf,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,snprintf,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,sprintf,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,sscanf,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,swprintf,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,swscanf,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,tmpfile,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,tmpnam,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,ungetc,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,ungetwc,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,vfprintf,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,vfscanf,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,vfwprintf,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,vfwscanf,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,vprintf,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,vscanf,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,vsnprintf,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,vsprintf,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,vsscanf,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,vswprintf,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,vswscanf,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,vwprintf,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,vwscanf,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,wprintf,[MISRA 2012 Rule 21.6, required]) + -deprecate(macro,wscanf,[MISRA 2012 Rule 21.6, required]) + +/**** Rule 21.7 (Req) ************/ + + +e586 /* Symbol is deprecated */ + +elib(586) + -deprecate(function,atof,[MISRA 2012 Rule 21.7, required]) + -deprecate(function,atoi,[MISRA 2012 Rule 21.7, required]) + -deprecate(function,atol,[MISRA 2012 Rule 21.7, required]) + -deprecate(function,atoll,[MISRA 2012 Rule 21.7, required]) + -deprecate(macro,atof,[MISRA 2012 Rule 21.7, required]) + -deprecate(macro,atoi,[MISRA 2012 Rule 21.7, required]) + -deprecate(macro,atol,[MISRA 2012 Rule 21.7, required]) + -deprecate(macro,atoll,[MISRA 2012 Rule 21.7, required]) + +/**** Rule 21.8 (Req) ************/ + + +e586 /* Symbol is deprecated */ + +elib(586) + -deprecate(function,abort,[MISRA 2012 Rule 21.8, required]) + -deprecate(function,exit,[MISRA 2012 Rule 21.8, required]) + -deprecate(function,getenv,[MISRA 2012 Rule 21.8, required]) + -deprecate(function,system,[MISRA 2012 Rule 21.8, required]) + -deprecate(macro,abort,[MISRA 2012 Rule 21.8, required]) + -deprecate(macro,exit,[MISRA 2012 Rule 21.8, required]) + -deprecate(macro,getenv,[MISRA 2012 Rule 21.8, required]) + -deprecate(macro,system,[MISRA 2012 Rule 21.8, required]) + +/**** Rule 21.9 (Req) ************/ + + +e586 /* Symbol is deprecated */ + +elib(586) + -deprecate(function,bsearch,[MISRA 2012 Rule 21.9, required]) + -deprecate(function,qsort,[MISRA 2012 Rule 21.9, required]) + -deprecate(macro,bsearch,[MISRA 2012 Rule 21.9, required]) + -deprecate(macro,qsort,[MISRA 2012 Rule 21.9, required]) + +/**** Rule 21.10 (Req) ************/ + + +e586 /* Symbol is deprecated */ + +elib(586) + -deprecate(macro,wcsftime,[MISRA 2012 Rule 21.10, required]) + -deprecate(function,wcsftime,[MISRA 2012 Rule 21.10, required]) + -deprecate(macro,clock,[MISRA 2012 Rule 21.10, required]) + -deprecate(function,clock,[MISRA 2012 Rule 21.10, required]) + -deprecate(macro,difftime,[MISRA 2012 Rule 21.10, required]) + -deprecate(function,difftime,[MISRA 2012 Rule 21.10, required]) + -deprecate(macro,mktime,[MISRA 2012 Rule 21.10, required]) + -deprecate(function,mktime,[MISRA 2012 Rule 21.10, required]) + -deprecate(macro,time,[MISRA 2012 Rule 21.10, required]) + -deprecate(function,time,[MISRA 2012 Rule 21.10, required]) + -deprecate(macro,asctime,[MISRA 2012 Rule 21.10, required]) + -deprecate(function,asctime,[MISRA 2012 Rule 21.10, required]) + -deprecate(macro,ctime,[MISRA 2012 Rule 21.10, required]) + -deprecate(function,ctime,[MISRA 2012 Rule 21.10, required]) + -deprecate(macro,gmtime,[MISRA 2012 Rule 21.10, required]) + -deprecate(function,gmtime,[MISRA 2012 Rule 21.10, required]) + -deprecate(macro,localtime,[MISRA 2012 Rule 21.10, required]) + -deprecate(function,localtime,[MISRA 2012 Rule 21.10, required]) + -deprecate(macro,strftime,[MISRA 2012 Rule 21.10, required]) + -deprecate(function,strftime,[MISRA 2012 Rule 21.10, required]) + -deprecate(macro,CLOCKS_PER_SEC,[MISRA 2012 Rule 21.10, required]) + +e829 /* warn on header usage */ + +elib(829) + +headerwarn(time.h) + -append(829(time.h),[MISRA 2012 Rule 21.10, required]) + +/**** Rule 21.11 (Req) ************/ + + +e829 /* warn on header usage */ + +elib(829) + +headerwarn(tgmath.h) + -append(829(tgmath.h),[MISRA 2012 Rule 21.11, required]) + +/**** Rule 21.12 (Adv) ************/ + + +e586 /* Symbol is deprecated */ + +elib(586) + -deprecate(function,feclearexcept,[MISRA 2012 Rule 21.12, advisory]) + -deprecate(macro,feclearexcept,[MISRA 2012 Rule 21.12, advisory]) + -deprecate(function,fegetexceptflag,[MISRA 2012 Rule 21.12, advisory]) + -deprecate(macro,fegetexceptflag,[MISRA 2012 Rule 21.12, advisory]) + -deprecate(function,feraiseexcept,[MISRA 2012 Rule 21.12, advisory]) + -deprecate(macro,feraiseexcept,[MISRA 2012 Rule 21.12, advisory]) + -deprecate(function,fesetexceptflag,[MISRA 2012 Rule 21.12, advisory]) + -deprecate(macro,fesetexceptflag,[MISRA 2012 Rule 21.12, advisory]) + -deprecate(function,fetestexcept,[MISRA 2012 Rule 21.12, advisory]) + -deprecate(macro,fetestexcept,[MISRA 2012 Rule 21.12, advisory]) + -deprecate(macro,FE_INEXACT,[MISRA 2012 Rule 21.12, advisory]) + -deprecate(macro,FE_DIVBYZERO,[MISRA 2012 Rule 21.12, advisory]) + -deprecate(macro,FE_UNDERFLOW,[MISRA 2012 Rule 21.12, advisory]) + -deprecate(macro,FE_OVERFLOW,[MISRA 2012 Rule 21.12, advisory]) + -deprecate(macro,FE_INVALID,[MISRA 2012 Rule 21.12, advisory]) + -deprecate(macro,FE_ALL_EXCEPT,[MISRA 2012 Rule 21.12, advisory]) + +/**** Rule 22.1 (Req) ************/ + + /* While MISRA has declared this rule to be "undecidable", Gimpel + * Software provides the following options to assist: + */ + +e429 /* custodial pointer neither free'd nor returned */ + +elib(429) + -append(429,[MISRA 2012 Rule 22.1, required]) + -function_pair(fopen,fclose) + +e480 /* no balancing call */ + +elib(480) + -append(480,[MISRA 2012 Rule 22.1, required]) + +e481 /* different balance call states */ + +elib(481) + -append(481,[MISRA 2012 Rule 22.1, required]) + +/**** Rule 22.2 (Mand) ************/ + + /* While MISRA has declared this rule to be "undecidable", Gimpel + * Software provides the following options to assist: + */ + +e424 /* inappropriate deallocation */ + +elib(424) + -append(424,[MISRA 2012 Rule 22.2, mandatory]) + +e449 /* pointer previously deallocated */ + +elib(449) + -append(449,[MISRA 2012 Rule 22.2, mandatory]) + +/**** Rule 22.3 (Req) ************/ + + /* MISRA has declared this rule to be "undecidable". */ + +/**** Rule 22.4 (Mand) ************/ + + /* MISRA has declared this rule to be "undecidable". */ + +/**** Rule 22.5 (Mand) ************/ + + /* While MISRA has declared this rule to be "undecidable", Gimpel + Software provides the following message to assist: + */ + +e9047 /* FILE pointer dereferenced */ + +elib(9047) + -append(9047,[MISRA 2012 Rule 22.5, mandatory]) + + +/**** Rule 22.6 (Mand) ************/ + + /* While MISRA has declared this rule to be "undecidable", Gimpel + * Software provides the following options to assist: + */ + +e449 /* previously deallocated pointer */ + +elib(449) + -append(449,[MISRA 2012 Rule 22.6, mandatory]) diff --git a/libm/libmcs/sw-quality/co-gcc.h b/libm/libmcs/sw-quality/co-gcc.h new file mode 100644 index 00000000..92f9f995 --- /dev/null +++ b/libm/libmcs/sw-quality/co-gcc.h @@ -0,0 +1,129 @@ +// --------------------------------------------------------------------- +// This file is provided by Gimpel Software (www.gimpel.com) for use with +// its products PC-lint and FlexeLint. +// +// Redistribution and use of this file, with or without modification, is +// permitted provided that any such redistribution retains this notice. +// --------------------------------------------------------------------- + +#ifndef CO_GCC_H_ +#define CO_GCC_H_ +/*lint -save -w1 */ + +#ifdef _lint /* Make sure no compiler comes this way */ +#ifdef __cplusplus +extern "C" { +#endif + +/* Standard library headers typically define the assert macro so that it + expands to a complicated conditional expression that uses special + funtions that Lint does not know about by default. For linting + purposes, we can simplify things a bit by forcing assert() to expand to + a call to a special function that has the appropriate 'assert' + semantics. + */ +//lint -function( __assert, __lint_assert ) +void __lint_assert( int ); +//lint ++d"assert(e)=__lint_assert(!!(e))" +//(++d makes this definition permanently immutable for the Lint run.) +//Now that we've made our own 'assert', we need to keep people from being +//punished when the marco in 'assert.h' appears not to be used: +//lint -efile(766,*assert.h) + +typedef char *__builtin_va_list; + +/*lint -e{171} */ +__builtin_va_list __lint_init_va(...); + +void __builtin_va_end( __builtin_va_list ); + /*lint +++d"__builtin_va_start(ap,parmN)=((ap)=__lint_init_va(parmN))" +++d"__builtin_va_arg(a,b)=(*( ((b) *) ( (((a) += sizeof(b)) - sizeof(b) )))" + */ + + +/* + The headers included below must be generated; For C++, generate + with: + + g++ [usual build options] -E -dM t.cpp >lint_cppmac.h + + For C, generate with: + + gcc [usual build options] -E -dM t.c >lint_cmac.h + + ...where "t.cpp" and "t.c" are empty source files. + + It's important to use the same compiler options used when compiling + project code because they can affect the existence and precise + definitions of certain predefined macros. See gcc-readme.txt for + details and a tutorial. + */ +#if defined(__cplusplus) +# include "lint_cppmac.h" // DO NOT COMMENT THIS OUT. DO NOT SUPPRESS ERROR 322. (If you see an error here, your Lint configuration is broken; check -i options and ensure that you have generated lint_cppmac.h as documented in gcc-readme.txt. Otherwise Gimpel Software cannot support your configuration.) +#else +# include "lint_cmac.h" // DO NOT COMMENT THIS OUT. DO NOT SUPPRESS ERROR 322. (If you see an error here, your Lint configuration is broken; check -i options and ensure that you have generated lint_cmac.h as documented in gcc-readme.txt. Otherwise Gimpel Software cannot support your configuration.) +#endif + +/* If the macro set given by the generated macro files must be adjusted in + order for Lint to cope, then you can make those adjustments here. + */ + +#define LINT_CO_GCC_H_GCC_VERSION ( __GNUC__ * 10000 + \ + __GNUC_MINOR__ * 100 + \ + __GNUC_PATCHLEVEL__ ) + +/* The following is a workaround for versions of GCC with bug 25717, in + which the preprocessor does not dump a #define directive for __STDC__ + when -dM is given: + http://gcc.gnu.org/bugzilla/show_bug.cgi?id=25717 + + We know the unconditional definition of __STDC__ was introduced no + later than version 3.0; the preprocessor bug was fixed no later than + version 4.1.0. + */ +#if ( LINT_CO_GCC_H_GCC_VERSION >= 30000 && \ + LINT_CO_GCC_H_GCC_VERSION < 40100 ) +# define __STDC__ 1 +#endif + +#if !__cplusplus && !__STRICT_ANSI__ && __STDC_VERSION__ < 199901L +/* apparently, the code is compiled with -std=gnu89 (as opposed to -std=c89), + so: */ +/*lint -rw_asgn(inline,__inline) */ +#endif + +#if LINT_CO_GCC_H_GCC_VERSION >= 40300 +# define __COUNTER__ __lint__COUNTER__ +//lint +rw( *type_traits ) // Enable type traits support +#endif + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#if _lint >= 909 // For 9.00i and later: + //// __attribute__ is GCC's __attribute__: + // + //lint -rw_asgn(__attribute__,__gcc_attribute__) + //lint -rw_asgn(__attribute, __gcc_attribute__) + // + //// Prevent "__attribute__" from being defined as a macro: + // + //lint --u"__attribute__" + //lint --u"__attribute" + // + //// Because an attribute-specifier is a form of + //// declaration-modifier, and because it can appear at the + //// beginning of a decl-specifier-seq, we must enable "Early + //// Modifiers": + // + //lint +fem +#else // for 9.00h and earlier: + //lint -d__attribute__()= + //lint -d__attribute()= +#endif + +#endif /* _lint */ +/*lint -restore */ +#endif /* CO_GCC_H_ */ diff --git a/libm/libmcs/sw-quality/co-gcc.lnt b/libm/libmcs/sw-quality/co-gcc.lnt new file mode 100644 index 00000000..13187da2 --- /dev/null +++ b/libm/libmcs/sw-quality/co-gcc.lnt @@ -0,0 +1,211 @@ +/* Date Stamp */ -d"_lint_co_gcc_lnt=co-gcc.lnt modified 12-Jun-2014" +/* To document usage use: -message( "Using " _lint_co_gcc_lnt ) */ +// --------------------------------------------------------------------- +// This file is provided by Gimpel Software (www.gimpel.com) for use with +// its products PC-lint and FlexeLint. +// +// Redistribution and use of this file, with or without modification, is +// permitted provided that any such redistribution retains this notice. +// --------------------------------------------------------------------- +/* co-gcc.lnt: This is the seed file for configuring Lint for use with + GCC versions 2.95.3 and later. + + Like all compiler options files this file is intended to be used + as follows: + + lint co-gcc.lnt source-files-to-be-linted + + Some of the information that co-gcc.lnt requires needs to be furnished + with the help of the gcc system itself. The easiest way to generate + this information is to use the makefile co-gcc.mak (supplied with the + Lint distribution) in an invocation of GNU Make; for details, see the + commentary at the top of co-gcc.mak. +*/ + +-cgnu // Notifies FlexeLint that gcc is being used. + +// =========================== +// Preprocessor Configuration: ++fdi // GCC starts its #include search in the directory of the including + // file. + +++fln // Allow: + // # digit-sequence " [s-char-sequence] " new-line + // as a synonym for: + // # line digit-sequence " [s-char-sequence] " new-line + // GCC additionally allows flag values to follow the + // s-char-sequence, but currently Lint ignores them. + +-header(sw-quality/co-gcc.h) // Includes headers generated by GCC (bringing in + // predefined macros). ++libh(sw-quality/co-gcc.h) // Marks that header as library code. + +sw-quality/gcc-include-path.lnt // This .lnt file should contain --i options + // and should be generated by invoking gcc with its '-v' option. + // (GCC's implicit #include search path is presented in the output.) + // This happens automatically when 'make -f co-gcc.mak' is invoked. + +// Assertion directives (a feature of GCC's preprocessor) have been +// considered obsolete in GCC's documentation since version 3.0, so we do +// not use them here. If support for #assert is needed in the form of a +// lint option, one may use '-a#' like so: +// -a#machine(i386) // #assert's machine(i386) (SVR4 facility). + +// File extensions: +// From the GCC man page: +// +// file.cc +// file.cp +// file.cxx +// file.cpp +// file.CPP +// file.c++ +// file.C +// C++ source code that must be preprocessed. Note that in .cxx, the +// last two letters must both be literally x. Likewise, .C refers to +// a literal capital C. +// +// We emulate this with: + + +cpp(.cc) + +cpp(.cp) + +cpp(.cxx) + +cpp(.cpp) + +cpp(.c++) + // Note the exceptions: + // +cpp(.CPP) + // +cpp(.C) + // These are commented out for the default config because they seem to + // cause trouble more often than not. For starters, it is problematic + // with filesystems that are case-insensitive (which has become common + // even on some POSIX systems). + +// ============= +// Size Options: +// +fwc // wchar_t might be builtin; if so, uncomment this option. (NOTE: +// // this option needs to be set before a size option is given for +// // wchar_t; see the documentation for -sw# in the Lint manual.) + +sw-quality/size-options.lnt // This .lnt file should be generated (preferrably + // by a program created by invoking GCC with the compile options that + // are used in the compilation of the project to be linted). This + // happens automatically when 'make -f co-gcc.mak' is invoked. + + +// =========================================== +// +rw and -d options to cope with GNU syntax: ++ppw(ident) // Tolerate #ident ++ppw(warning) + +// GCC provides alternative spellings of certain keywords: ++rw(__inline) +-rw_asgn(__inline__,__inline) +-rw_asgn(__header_always_inline,__inline) +-rw_asgn(__header_inline,__inline) + +-rw_asgn(__signed__,signed) +-rw_asgn(__signed,signed) +-rw_asgn( __volatile__, volatile ) +-rw_asgn( __volatile, volatile ) ++rw(restrict) +-rw_asgn(__restrict,restrict) +-rw_asgn(__restrict__,restrict) +++d"__const=const" // gconv.h uses __const rather than const +++d"const=const" // ensure const expands to const. + +-rw_asgn( asm, _up_to_brackets ) +-rw_asgn( __asm, _up_to_brackets ) +-rw_asgn( __asm__, _up_to_brackets ) +// This re-definition of the various spellings of the asm keyword enables +// Lint to pass gracefully over expression-statements like: +// __asm __volatile ("fsqrt" : "=t" (__result) : "0" (__x)); +// But it may be necessary to suppress certain error messages that are +// triggered by tokens that are part of an assembly declaration or +// statement. For example: + + -d"__asm__(p...)=/*lint -e{19}*/ __asm__(p)" + +// ...causes Lint to be quiet about the semicolon that follows an +// __asm__() declaration. Note, the -e{N} form of suppression takes +// effect only for the forward-declaration, definition or +// [possibly-compound] statement that immediately follows. Because a +// semicolon is seen as a declaration-terminator, Error 19 will be +// re-enabled immediately after the semicolon in '__asm__(...);'. +// (The elipsis after the macro parameter p allows zero or more commas to +// appear in the operand.) +// +// If you encounter other diagnostics that appear to need suppression in +// or near assembly regions, please let us know! +// +-esym(123,__asm__) + +-rw_asgn(__alignof__,__alignof) + +// "__extension__" is GCC's way of allowing the use of non-standard +// constructs in a strict Standard-conforming mode. We don't currently +// have explicit support for it, but we can use local suppressions. For +// example, we can use -e(160) so that we will not see any Errors about +// GNU statement-expressions wrapped in __extension__(). +++d"__extension__=/*lint -e(160) */" + +++d"I=1.0f" + +++d"__null=0" ++rw(_to_semi) // needed for the two macros above. ++rw(__typeof__) // activate __typeof__ keyword +-d"__typeof=__typeof__" // an alternative to using __typeof__ + +-rw(__except) // This MS reserved word is used as an identifier ++rw( __complex__, __real__, __imag__, _Complex ) // reserved words that can be ignored. +++d"__builtin_strchr=(char*)" // permits the inline definition ... +++d"__builtin_strpbrk=(char*)" // of these functions to be linted ... +++d"__builtin_strrchr=(char*)" // without drawing a complaint +++d"__builtin_strstr=(char*)" // about the use of a non-standard name +++d"__PRETTY_FUNCTION__=___function___" // lint defines ___function___ internally +++d"__FUNCTION__=___function___" // lint defines ___function___ internally +++d"__func__=___function___" // Some C++ modes suport the implicit __func__ + // identifier. +-ident($) + +// ========================================================= +// Other options supporting GNU C/C++ syntax: ++fld // enables the processing of _L_abel _D_esignators E.g.: + // union { double d; int i; } u = { d: 3.141 }; + +// ========================================================= +// Generally useful suppressions: +-wlib(1) // sets the warning level within library headers to 1 + // (no warnings, just syntax errors). Comment out if you + // are actually linting library headers. +-elib(123) // 123 is really a warning, but it's in the "Error" range. +-elib(93) // allow newlines within quoted string arguments to macros +-elib(46) // allow bit fields to have integral types other than + // '_Bool' and 'int'. +-elibsym(628) // Suppress 628 for __builtin symbols. + +-esym(528,__huge_val,__nan,__qnan,__qnanf,__snan,__snanf) + // We don't care if we don't reference some GNU functions +-esym(528,__gnu_malloc,__gnu_calloc) + +// The following functions exhibit variable return modes. +// That is, they may equally-usefully be called for a value +// as called just for their effects. Accordingly we inhibit +// Warning 534 for these functions. +// Feel free to add to or subtract from this list. + +-esym(534,close,creat,fclose,fprintf,fputc) +-esym(534,fputs,fscanf,fseek,fwrite,lseek,memcpy,memmove,memset) +-esym(534,printf,puts,scanf,sprintf,sscanf,strcat,strcpy) +-esym(534,strncat,strncpy,unlink,write) + +// For non-ANSI compilers we suppress messages 515 and 516 +// for functions known to have variable argument lists. +// For ANSI compilers, header files should take care of this. + +-esym(515,fprintf,printf,sprintf,fscanf,scanf,sscanf) +-esym(516,fprintf,printf,sprintf,fscanf,scanf,sscanf) +-esym(1702,*operator<<,*operator>>) +-esym(534,*operator<<,*operator>>) +-esym(1055,*__builtin*) +-esym(718,*__builtin*) // The compiler does not need these ... +-esym(746,*__builtin*) // declared and it knows their prototypes. diff --git a/libm/libmcs/sw-quality/co-gcc.mak b/libm/libmcs/sw-quality/co-gcc.mak new file mode 100644 index 00000000..c82c5faf --- /dev/null +++ b/libm/libmcs/sw-quality/co-gcc.mak @@ -0,0 +1,173 @@ +# This Makefile enables the automatic generation of macro definition +# headers, --i options and size options for Lint based on command-line +# switches passed to GCC. +# +# Usage: +# +# make -f co-gcc.mak \ +# GCC_BIN='name of the gcc binary' \ +# GXX_BIN='name of the g++ binary' \ +# CFLAGS='[usual C compile switches here]' \ +# CXXFLAGS='[usual C++ compile switches here]' \ +# CPPFLAGS='[usual common preprocessor switches here]' \ +# COMMON_FLAGS='[usual C & C++ compile switches here]' \ +# +# ... where 'make' is the name of the GNU Make program on your system. +# That invocation should generate the following files: +# +# lint_cmac.h +# lint_cppmac.h +# gcc-include-path.lnt +# size-options.lnt +# +# Note, if you do not supply the options that you actually compile with, +# you may see undesired results. Examples: +# +# 1) If you usually compile with -m64 but do not pass this in the +# COMMON_FLAGS variable when you run `make -f co-gcc.mak` then Lint may +# see the wrong size options (so it may think e.g. that sizeof(void*) is +# 4, which of course is inappropriate if you compile your code in 64-bit +# mode). +# +# 2) The set of compile switches (even non-preprocessor switches like -O3) +# can affect the configuration of GCC's preprocessor, which means it can +# affect how the preprocessor views the contents of system headers (and +# hence the token sequence it generates). So if we don't see the right +# set of compile switches here then the program you Lint might not be the +# program you compile (even though the same .c and .cpp files are +# involved). +# +# See also the file gcc-readme.txt (supplied with the Lint distribution). + +COMMON_GCC_OPTS:= $(COMMON_FLAGS) $(CPPFLAGS) -Wno-long-long +# We want to enable 'long long' for the purpose of extracting the value of +# 'sizeof(long long)'; see the 'size-options.lnt' target below. + +C_OPTS:= $(CFLAGS) $(COMMON_GCC_OPTS) +CXX_OPTS:=$(CXXFLAGS) $(COMMON_GCC_OPTS) +# Note, we're not *yet* able to handle some of the header contents when +# -std=c++0x is given. + +GCC_BIN:=sparc-rtems-gcc +GXX_BIN:=sparc-rtems-g++ + +GCC:=$(GCC_BIN) $(C_OPTS) +GXX:=$(GXX_BIN) $(CXX_OPTS) + +TEMP_FILE_PREFIX:=co-gcc.mak.temp + +E:=$(TEMP_FILE_PREFIX)-empty +SIZE_GEN:=$(TEMP_FILE_PREFIX)-generate-size-options + +ECHO:=echo +TOUCH:=touch +AWK:=awk + +.PHONY: config +config: preprocessor size-options.lnt + +.PHONY: preprocessor +preprocessor: lint_cmac.h lint_cppmac.h gcc-include-path.lnt + +.PHONY: dumpConfig +dumpConfig: + echo GCC_BIN=$(GCC_BIN) + echo GXX_BIN=$(GXX_BIN) + echo CFLAGS=$(CFLAGS) + echo CXXFLAGS=$(CXXFLAGS) + echo CPPFLAGS=$(CPPFLAGS) + echo COMMON_FLAGS=$(COMMON_FLAGS) + +lint_cmac.h: + set -e ; $(TOUCH) $(E)$$$$.c ; $(GCC) -E -dM $(E)$$$$.c -o $@ ; $(RM) $(E)$$$$.c + +lint_cppmac.h: + set -e ; $(TOUCH) $(E)$$$$.cpp ; $(GXX) -E -dM $(E)$$$$.cpp -o $@ ; $(RM) $(E)$$$$.cpp + +gcc-include-path.lnt: + @# Here we make options for the #include search path. + @# Note, frameworks (a feature of Apple's GCC) are not supported + @# yet so for now we filter them out. Each remaining search + @# directory 'foo' is transformed into '--i"foo"' after + @# superfluous directory separators are removed (as well as each + @# CR character appearing immediately before a newline): + $(TOUCH) $(E)$$$$.cpp ; \ + $(GXX) -v -c $(E)$$$$.cpp >$(E)$$$$.tmp 2>&1 ; \ + <$(E)$$$$.tmp $(AWK) ' \ + BEGIN {S=0} \ + /search starts here:/ {S=1;next;} \ + S && /Library\/Frameworks/ {next;} \ + S && /^ / { \ + sub("^ ",""); \ + gsub("//*","/"); \ + sub("\xd$$",""); \ + sub("/$$",""); \ + printf("--i\"%s\"\n", $$0); \ + next; \ + } \ + S {exit;} \ + ' >gcc-include-path.lnt ; \ + $(RM) $(E)$$$$.cpp $(E)$$$$.tmp $(E)$$$$.o + @# Note, we deliberately use '--i' instead of '-i' here; the effect + @# is that the directories named with the double-dash form are + @# searched after directories named with the single-dash form. + @# (See also the entry for '--i' in section 5.7 of the Lint + @# manual.) + @# + @# We typically use '--i' when we want to name a system include + @# directory, which GCC searches only after it searches all + @# directories named in a '-I' option. The upshot is that the + @# correct search order (i.e., project includes before system + @# includes) is preserved even when double-dash-i options are given + @# before single-dash-i options. + @# + @# Also note, no harm is done if '-I' options are passed to GCC + @# here: directories named with '-I' will appear before the + @# sys-include-dirs in GCC's output, so even though Lint might then + @# see a project-include directory named with a '--i' option, that + @# directory will still be searched before the sys-includes because + @# of the ordering of '--i' options. (Just make sure you don't use + @# the double-dash form with project include dirs outside of this + @# limited & generated sub-sequence of options because this is the + @# only place where we are certain that project directories always + @# come before system directories.) + + +size-options.lnt: + @# 'echo' seems to vary in behavior with respect to its handling + @# of '\n'. (Is it a newline, or a literal backslash followed by + @# a literal 'n'? It seems to depend on your platform.) So we + @# deliberately avoid the use of explicit newline characters here. + @$(ECHO) '\ +extern "C" int printf(const char*, ...);\ +int main() {\ +printf( "-ss%zu ", sizeof(short) );\ +printf( "-si%zu ", sizeof(int) );\ +printf( "-sl%zu ", sizeof(long) );\ +printf( "-sll%zu ", sizeof(long long) );\ +printf( "-sf%zu ", sizeof(float) );\ +printf( "-sd%zu ", sizeof(double) );\ +printf( "-sld%zu ", sizeof(long double) );\ +printf( "-sp%zu ", sizeof(void*) );\ +printf( "-sw%zu ", sizeof(wchar_t) );\ +}' >$(SIZE_GEN).cc + $(GXX) $(SIZE_GEN).cc -o $(SIZE_GEN) + ./$(SIZE_GEN) >size-options.lnt + @# ... and make it newline-terminated: + @$(ECHO) "" >>size-options.lnt + $(RM) $(SIZE_GEN)* + +.PHONY: clean_temps +clean_temps: + $(RM) $(TEMP_FILE_PREFIX)* + +.PHONY: clean +clean: clean_temps + $(RM) \ + lint_cppmac.h \ + lint_cmac.h \ + gcc-include-path.lnt \ + size-options.lnt + +# vim:ts=8 + diff --git a/libm/libmcs/sw-quality/dummy_includes/config.h b/libm/libmcs/sw-quality/dummy_includes/config.h new file mode 100644 index 00000000..3ccf0998 --- /dev/null +++ b/libm/libmcs/sw-quality/dummy_includes/config.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GTDGmbH */ +/* Copyright 2020-2022 by GTD GmbH. */ + +#ifndef LIBMCS_CONFIG_H +#define LIBMCS_CONFIG_H + +#ifdef LIBMCS_FPU_DAZ + #undef LIBMCS_FPU_DAZ +#endif /* LIBMCS_FPU_DAZ */ +#ifndef LIBMCS_LONG_DOUBLE_IS_64BITS + #define LIBMCS_LONG_DOUBLE_IS_64BITS +#endif /* !LIBMCS_LONG_DOUBLE_IS_64BITS */ +#ifndef LIBMCS_WANT_COMPLEX + #define LIBMCS_WANT_COMPLEX +#endif /* !LIBMCS_WANT_COMPLEX */ + +#endif /* !LIBMCS_CONFIG_H */ diff --git a/libm/libmcs/sw-quality/gcc-include-path.lnt b/libm/libmcs/sw-quality/gcc-include-path.lnt new file mode 100644 index 00000000..3be358e7 --- /dev/null +++ b/libm/libmcs/sw-quality/gcc-include-path.lnt @@ -0,0 +1,4 @@ +--i"../gcc/gcc/ginclude/" +--i"libm/include" +--i"libm/common" +--i"sw-quality/dummy_includes" diff --git a/libm/libmcs/sw-quality/lint.sh b/libm/libmcs/sw-quality/lint.sh new file mode 100755 index 00000000..f4a41b68 --- /dev/null +++ b/libm/libmcs/sw-quality/lint.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +set -xe + +mkdir -p sw-quality/misra-c +find libm/common libm/complex* libm/math* -name "*.c" | grep -v "fenv.c" > sw-quality/misra-c/files.lnt +wine ~/lint-nt.exe sw-quality/std.lnt sw-quality/misra-c/files.lnt | sed 's#\\#/#g' > sw-quality/misra-c/lint.txt || true +python3 -m sqarg -c sw-quality/sqarg-config.toml diff --git a/libm/libmcs/sw-quality/lint_cmac.h b/libm/libmcs/sw-quality/lint_cmac.h new file mode 100644 index 00000000..61923dee --- /dev/null +++ b/libm/libmcs/sw-quality/lint_cmac.h @@ -0,0 +1,116 @@ +#define __DBL_MIN_EXP__ (-1021) +#define __FLT_MIN__ 1.17549435e-38F +#define __CHAR_BIT__ 8 +#define __WCHAR_MAX__ 2147483647 +#define __DBL_DENORM_MIN__ 4.9406564584124654e-324 +#define __FLT_EVAL_METHOD__ 0 +#define __DBL_MIN_10_EXP__ (-307) +#define __FINITE_MATH_ONLY__ 0 +#define __GNUC_PATCHLEVEL__ 6 +#define __DEC64_MAX_EXP__ 385 +#define sparc 1 +#define __SHRT_MAX__ 32767 +#define __LDBL_MAX__ 1.7976931348623157e+308L +#define __UINTMAX_TYPE__ long long unsigned int +#define __DEC32_EPSILON__ 1E-6DF +#define __LDBL_MAX_EXP__ 1024 +#define __SCHAR_MAX__ 127 +#define __DBL_DIG__ 15 +#define __SIZEOF_INT__ 4 +#define __SIZEOF_POINTER__ 4 +#define __USER_LABEL_PREFIX__ +#define __STDC_HOSTED__ 1 +#define __LDBL_HAS_INFINITY__ 1 +#define __FLT_EPSILON__ 1.19209290e-7F +#define __LDBL_MIN__ 2.2250738585072014e-308L +#define __DEC32_MAX__ 9.999999E96DF +#define __SIZEOF_LONG__ 4 +#define __DECIMAL_DIG__ 17 +#define __LDBL_HAS_QUIET_NAN__ 1 +#define __GNUC__ 4 +#define __FLT_HAS_DENORM__ 1 +#define __SIZEOF_LONG_DOUBLE__ 8 +#define __BIGGEST_ALIGNMENT__ 8 +#define __DBL_MAX__ 1.7976931348623157e+308 +#define __DBL_HAS_INFINITY__ 1 +#define __DEC32_MIN_EXP__ (-94) +#define __LDBL_HAS_DENORM__ 1 +#define __DEC128_MAX__ 9.999999999999999999999999999999999E6144DL +#define __DEC32_MIN__ 1E-95DF +#define __DBL_MAX_EXP__ 1024 +#define __DEC128_EPSILON__ 1E-33DL +#define __LONG_LONG_MAX__ 9223372036854775807LL +#define __SIZEOF_SIZE_T__ 4 +#define __sparc__ 1 +#define __SIZEOF_WINT_T__ 4 +#define __GXX_ABI_VERSION 1002 +#define __FLT_MIN_EXP__ (-125) +#define __DBL_MIN__ 2.2250738585072014e-308 +#define __USE_INIT_FINI__ 1 +#define __DEC128_MIN__ 1E-6143DL +#define __REGISTER_PREFIX__ +#define __DBL_HAS_DENORM__ 1 +#define __NO_INLINE__ 1 +#define __FLT_MANT_DIG__ 24 +#define __VERSION__ "4.4.6" +#define __sparc 1 +#define __DEC64_EPSILON__ 1E-15DD +#define __DEC128_MIN_EXP__ (-6142) +#define __SIZE_TYPE__ unsigned int +#define __ELF__ 1 +#define __rtems__ 1 +#define __FLT_RADIX__ 2 +#define __LDBL_EPSILON__ 2.2204460492503131e-16L +#define __SIZEOF_PTRDIFF_T__ 4 +#define __DEC32_SUBNORMAL_MIN__ 0.000001E-95DF +#define __FLT_HAS_QUIET_NAN__ 1 +#define __FLT_MAX_10_EXP__ 38 +#define __LONG_MAX__ 2147483647L +#define __DEC128_SUBNORMAL_MIN__ 0.000000000000000000000000000000001E-6143DL +#define __FLT_HAS_INFINITY__ 1 +#define __DEC64_MAX__ 9.999999999999999E384DD +#define __CHAR16_TYPE__ short unsigned int +#define __DEC64_MANT_DIG__ 16 +#define __DEC32_MAX_EXP__ 97 +#define __LDBL_MANT_DIG__ 53 +#define __DBL_HAS_QUIET_NAN__ 1 +#define __WCHAR_TYPE__ int +#define __SIZEOF_FLOAT__ 4 +#define __DEC64_MIN_EXP__ (-382) +#define __FLT_DIG__ 6 +#define __INT_MAX__ 2147483647 +#define __FLT_MAX_EXP__ 128 +#define __DBL_MANT_DIG__ 53 +#define __DEC64_MIN__ 1E-383DD +#define __WINT_TYPE__ unsigned int +#define __SIZEOF_SHORT__ 2 +#define __LDBL_MIN_EXP__ (-1021) +#define __LDBL_MAX_10_EXP__ 308 +#define __DBL_EPSILON__ 2.2204460492503131e-16 +#define __SIZEOF_WCHAR_T__ 4 +#define __DEC_EVAL_METHOD__ 2 +#define __INTMAX_MAX__ 9223372036854775807LL +#define __FLT_DENORM_MIN__ 1.40129846e-45F +#define __CHAR32_TYPE__ unsigned int +#define __FLT_MAX__ 3.40282347e+38F +#define __SIZEOF_DOUBLE__ 8 +#define __FLT_MIN_10_EXP__ (-37) +#define __INTMAX_TYPE__ long long int +#define __DEC128_MAX_EXP__ 6145 +#define __GNUC_MINOR__ 4 +#define __DEC32_MANT_DIG__ 7 +#define __DBL_MAX_10_EXP__ 308 +#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324L +#define __STDC__ 1 +#define __PTRDIFF_TYPE__ int +#define __DEC64_SUBNORMAL_MIN__ 0.000000000000001E-383DD +#define __DEC128_MANT_DIG__ 34 +#define __LDBL_MIN_10_EXP__ (-307) +#define __SIZEOF_LONG_LONG__ 8 +#define __LDBL_DIG__ 15 +#define __GNUC_GNU_INLINE__ 1 +#define _GCC_LIMITS_H_ +#define _MATH_CONFIG_H +#define _LDBL_EQ_DBL +#define __ORDER_BIG_ENDIAN__ 1 +#define __BYTE_ORDER__ 1 \ No newline at end of file diff --git a/libm/libmcs/sw-quality/lint_cppmac.h b/libm/libmcs/sw-quality/lint_cppmac.h new file mode 100644 index 00000000..e22054a5 --- /dev/null +++ b/libm/libmcs/sw-quality/lint_cppmac.h @@ -0,0 +1,118 @@ +#define __DBL_MIN_EXP__ (-1021) +#define __FLT_MIN__ 1.17549435e-38F +#define __CHAR_BIT__ 8 +#define __WCHAR_MAX__ 2147483647 +#define __DBL_DENORM_MIN__ 4.9406564584124654e-324 +#define __FLT_EVAL_METHOD__ 0 +#define __DBL_MIN_10_EXP__ (-307) +#define __FINITE_MATH_ONLY__ 0 +#define __GNUC_PATCHLEVEL__ 6 +#define __DEC64_MAX_EXP__ 385 +#define sparc 1 +#define __SHRT_MAX__ 32767 +#define __LDBL_MAX__ 1.7976931348623157e+308L +#define __UINTMAX_TYPE__ long long unsigned int +#define __DEC32_EPSILON__ 1E-6DF +#define __LDBL_MAX_EXP__ 1024 +#define __SCHAR_MAX__ 127 +#define __DBL_DIG__ 15 +#define __SIZEOF_INT__ 4 +#define __SIZEOF_POINTER__ 4 +#define __USER_LABEL_PREFIX__ +#define __STDC_HOSTED__ 1 +#define __LDBL_HAS_INFINITY__ 1 +#define __FLT_EPSILON__ 1.19209290e-7F +#define __GXX_WEAK__ 1 +#define __LDBL_MIN__ 2.2250738585072014e-308L +#define __DEC32_MAX__ 9.999999E96DF +#define __SIZEOF_LONG__ 4 +#define __DECIMAL_DIG__ 17 +#define __LDBL_HAS_QUIET_NAN__ 1 +#define __GNUC__ 4 +#define __GXX_RTTI 1 +#define __FLT_HAS_DENORM__ 1 +#define __SIZEOF_LONG_DOUBLE__ 8 +#define __BIGGEST_ALIGNMENT__ 8 +#define __DBL_MAX__ 1.7976931348623157e+308 +#define __DBL_HAS_INFINITY__ 1 +#define __DEC32_MIN_EXP__ (-94) +#define __LDBL_HAS_DENORM__ 1 +#define __cplusplus 1 +#define __DEC128_MAX__ 9.999999999999999999999999999999999E6144DL +#define __DEC32_MIN__ 1E-95DF +#define __DEPRECATED 1 +#define __DBL_MAX_EXP__ 1024 +#define __DEC128_EPSILON__ 1E-33DL +#define __GNUG__ 4 +#define __LONG_LONG_MAX__ 9223372036854775807LL +#define __SIZEOF_SIZE_T__ 4 +#define __sparc__ 1 +#define __SIZEOF_WINT_T__ 4 +#define __GCC_HAVE_DWARF2_CFI_ASM 1 +#define __GXX_ABI_VERSION 1002 +#define __FLT_MIN_EXP__ (-125) +#define __DBL_MIN__ 2.2250738585072014e-308 +#define __FLT_MIN_10_EXP__ (-37) +#define __USE_INIT_FINI__ 1 +#define __DEC128_MIN__ 1E-6143DL +#define __REGISTER_PREFIX__ +#define __DBL_HAS_DENORM__ 1 +#define __NO_INLINE__ 1 +#define __FLT_MANT_DIG__ 24 +#define __VERSION__ "4.4.6" +#define __sparc 1 +#define __DEC64_EPSILON__ 1E-15DD +#define __DEC128_MIN_EXP__ (-6142) +#define __SIZE_TYPE__ unsigned int +#define __ELF__ 1 +#define __FLT_RADIX__ 2 +#define __LDBL_EPSILON__ 2.2204460492503131e-16L +#define __SIZEOF_PTRDIFF_T__ 4 +#define __DEC32_SUBNORMAL_MIN__ 0.000001E-95DF +#define __FLT_HAS_QUIET_NAN__ 1 +#define __FLT_MAX_10_EXP__ 38 +#define __LONG_MAX__ 2147483647L +#define __DEC128_SUBNORMAL_MIN__ 0.000000000000000000000000000000001E-6143DL +#define __FLT_HAS_INFINITY__ 1 +#define __DEC64_MAX__ 9.999999999999999E384DD +#define __CHAR16_TYPE__ short unsigned int +#define __DEC64_MANT_DIG__ 16 +#define __DEC32_MAX_EXP__ 97 +#define __EXCEPTIONS 1 +#define __LDBL_MANT_DIG__ 53 +#define __DBL_HAS_QUIET_NAN__ 1 +#define __WCHAR_TYPE__ int +#define __SIZEOF_FLOAT__ 4 +#define __DEC64_MIN_EXP__ (-382) +#define __FLT_DIG__ 6 +#define __INT_MAX__ 2147483647 +#define __FLT_MAX_EXP__ 128 +#define __DBL_MANT_DIG__ 53 +#define __DEC64_MIN__ 1E-383DD +#define __WINT_TYPE__ unsigned int +#define __SIZEOF_SHORT__ 2 +#define __LDBL_MIN_EXP__ (-1021) +#define __LDBL_MAX_10_EXP__ 308 +#define __DBL_EPSILON__ 2.2204460492503131e-16 +#define __rtems__ 1 +#define __SIZEOF_WCHAR_T__ 4 +#define __DEC_EVAL_METHOD__ 2 +#define __INTMAX_MAX__ 9223372036854775807LL +#define __FLT_DENORM_MIN__ 1.40129846e-45F +#define __CHAR32_TYPE__ unsigned int +#define __FLT_MAX__ 3.40282347e+38F +#define __SIZEOF_DOUBLE__ 8 +#define __INTMAX_TYPE__ long long int +#define __DEC128_MAX_EXP__ 6145 +#define __GNUC_MINOR__ 4 +#define __DEC32_MANT_DIG__ 7 +#define __DBL_MAX_10_EXP__ 308 +#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324L +#define __STDC__ 1 +#define __PTRDIFF_TYPE__ int +#define __DEC64_SUBNORMAL_MIN__ 0.000000000000001E-383DD +#define __DEC128_MANT_DIG__ 34 +#define __LDBL_MIN_10_EXP__ (-307) +#define __SIZEOF_LONG_LONG__ 8 +#define __LDBL_DIG__ 15 +#define __GNUC_GNU_INLINE__ 1 diff --git a/libm/libmcs/sw-quality/options.lnt b/libm/libmcs/sw-quality/options.lnt new file mode 100644 index 00000000..d043df94 --- /dev/null +++ b/libm/libmcs/sw-quality/options.lnt @@ -0,0 +1,13 @@ +-rw(*ms) // Disable microsoft keywords huge, far, near etc +-estring(9051,__asm__) // co-gcc.lnt defines various __asm__ spellings which makes misra complain +-e830 // Disable additonal location hints for various error messages to reduce logspam + +// Output format +// ------------- +// Vim Quickfix format +//-"format= %f%(:%l%)%(:%c:%) %t %n: %m\n\n" + +// Single line format +-width(0) // don't insert line breaks (unlimited output width). +-"format= %t %n$ %f%($%l%)%($%c$%) %m" +-h1 diff --git a/libm/libmcs/sw-quality/size-options.lnt b/libm/libmcs/sw-quality/size-options.lnt new file mode 100644 index 00000000..7947166e --- /dev/null +++ b/libm/libmcs/sw-quality/size-options.lnt @@ -0,0 +1 @@ +-ss2 -si4 -sl4 -sll8 -sf4 -sd8 -sld8 -sp4 -sw4 diff --git a/libm/libmcs/sw-quality/sqarg-config.toml b/libm/libmcs/sw-quality/sqarg-config.toml new file mode 100644 index 00000000..c54245b7 --- /dev/null +++ b/libm/libmcs/sw-quality/sqarg-config.toml @@ -0,0 +1,27 @@ +# SPDX-License-Identifier: GTDGmbH +# Copyright 2024 by GTD GmbH. + +# Section PcLint +[pc-lint] +# Path to lint file +lint-file = "sw-quality/misra-c/lint.txt" + +# Separation character in lint file +lint-file-separator = "$" + +# Path bend from current working dir to pc lint working dir +# (lint path files are relative to working dir in lint.exe) +lint-dir = "." + + +# Export directory and the required type +export-path = "sw-quality/misra-c" +export-type = ".md" + +# The String merger is a algorithm who try to squeeze list of strings into less +# by compare and add padding character into different spaces +[string-merge] +min-match = 4 # Minimum matching character +padding-char = '$' # Padding character, $ is not used in PcLint output strings +ratio-threshold = 0.7 # difflib.SequenceMatcher ratio threshold +iteration = 3 # How often is iterated over the result list to find new merges diff --git a/libm/libmcs/sw-quality/std.lnt b/libm/libmcs/sw-quality/std.lnt new file mode 100644 index 00000000..64fc2b40 --- /dev/null +++ b/libm/libmcs/sw-quality/std.lnt @@ -0,0 +1,6 @@ +// Gnu C/C++ (version 2.95.3 or later), -si4 -sp4, +// Standard lint options + +sw-quality/au-misra3.lnt +sw-quality/co-gcc.lnt +sw-quality/options.lnt From 4b75e9b3c2da0a7e4fe307f5c2f50e4b6164f9cd Mon Sep 17 00:00:00 2001 From: Mikolaj Matalowski Date: Tue, 30 Sep 2025 12:55:29 +0200 Subject: [PATCH 2/3] Libmcs: add Makefile and cleanup JIRA: RTOS-1132 --- libm/Makefile | 87 ++ libm/README.md | 21 + libm/libmcs/doc/_static/css/custom.css | 66 -- libm/libmcs/doc/figure/libmcs-complex.png | Bin 18554 -> 0 bytes .../doc/figure/libmcs-include-common.png | Bin 10299 -> 0 bytes libm/libmcs/doc/figure/libmcs-real.png | Bin 18050 -> 0 bytes .../doc/figure/libmcs-static-architecture.png | Bin 16401 -> 0 bytes libm/libmcs/doc/index.html | 117 --- libm/libmcs/doc/logo/libmcs-favicon.ico | Bin 12862 -> 0 bytes libm/libmcs/doc/logo/libmcs-logo.png | Bin 28336 -> 0 bytes libm/libmcs/doc/sdd/1_Introduction.rst | 15 - .../2_Applicable_and_Reference_Documents.rst | 46 -- libm/libmcs/doc/sdd/3_Abbreviations.rst | 52 -- .../doc/sdd/4_Software_Design_Overview.rst | 124 --- .../5_Software_Design/0_Software_Design.rst | 11 - .../doc/sdd/5_Software_Design/1_General.rst | 21 - .../2_Overall_Architecture.rst | 387 --------- .../3_Software_Component_Design_General.rst | 112 --- ...onent_Design_Aspects_Of_Each_Component.rst | 315 -------- .../0010_fpclassify.rst | 54 -- .../0020_isfinite.rst | 34 - .../0030_isinf.rst | 34 - .../0040_isnan.rst | 34 - .../0050_isnormal.rst | 33 - .../0060_signbit.rst | 34 - .../0100_acos.rst | 118 --- .../0110_asin.rst | 136 ---- .../0120_atan.rst | 145 ---- .../0130_atan2.rst | 139 ---- .../0140_cos.rst | 85 -- .../0150_sin.rst | 83 -- .../0160_tan.rst | 162 ---- .../0170_trig.rst | 191 ----- .../0200_acosh.rst | 53 -- .../0210_asinh.rst | 52 -- .../0220_atanh.rst | 52 -- .../0230_cosh.rst | 56 -- .../0240_sinh.rst | 55 -- .../0250_tanh.rst | 45 -- .../0300_exp.rst | 100 --- .../0310_exp2.rst | 47 -- .../0320_expm1.rst | 49 -- .../0330_frexp.rst | 42 - .../0340_ilogb.rst | 45 -- .../0350_ldexp.rst | 49 -- .../0360_log.rst | 138 ---- .../0370_log10.rst | 87 -- .../0380_log1p.rst | 53 -- .../0390_log2.rst | 50 -- .../0400_logb.rst | 44 - .../0410_modf.rst | 68 -- .../0420_scalbn.rst | 81 -- .../0430_scalbln.rst | 44 - .../0440_log_internal.rst | 76 -- .../0500_cbrt.rst | 42 - .../0510_fabs.rst | 66 -- .../0520_hypot.rst | 74 -- .../0530_pow.rst | 345 -------- .../0540_sqrt.rst | 124 --- .../0600_erf.rst | 51 -- .../0610_erfc.rst | 51 -- .../0620_lgamma.rst | 52 -- .../0630_tgamma.rst | 50 -- .../0640_gamma_internal.rst | 42 - .../0650_signgam.rst | 25 - .../0700_ceil.rst | 76 -- .../0710_floor.rst | 76 -- .../0720_nearbyint.rst | 43 - .../0730_rint.rst | 45 -- .../0740_lrint.rst | 51 -- .../0750_llrint.rst | 47 -- .../0760_round.rst | 77 -- .../0770_lround.rst | 51 -- .../0780_llround.rst | 47 -- .../0790_trunc.rst | 65 -- .../0900_fmod.rst | 66 -- .../0910_remainder.rst | 46 -- .../0920_remquo.rst | 47 -- .../1000_copysign.rst | 36 - .../1010_nan.rst | 26 - .../1020_nextafter.rst | 56 -- .../1030_nexttoward.rst | 51 -- .../1100_fdim.rst | 49 -- .../1110_fmax.rst | 51 -- .../1120_fmin.rst | 51 -- .../1200_fma.rst | 48 -- .../1300_isgreater.rst | 38 - .../1310_isgreaterequal.rst | 38 - .../1320_isless.rst | 38 - .../1330_islessequal.rst | 38 - .../1340_islessgreater.rst | 38 - .../1350_isunordered.rst | 35 - .../1400_j0.rst | 48 -- .../1410_j1.rst | 48 -- .../1420_jn.rst | 49 -- .../1430_y0.rst | 60 -- .../1440_y1.rst | 61 -- .../1450_yn.rst | 55 -- .../1500_cacos.rst | 32 - .../1510_casin.rst | 35 - .../1520_catan.rst | 39 - .../1530_ccos.rst | 37 - .../1540_csin.rst | 41 - .../1550_ctan.rst | 36 - .../1600_cacosh.rst | 29 - .../1610_casinh.rst | 31 - .../1620_catanh.rst | 31 - .../1630_ccosh.rst | 38 - .../1640_csinh.rst | 34 - .../1650_ctanh.rst | 39 - .../1700_cexp.rst | 33 - .../1710_clog.rst | 35 - .../1800_cabs.rst | 33 - .../1810_cpow.rst | 38 - .../1820_csqrt.rst | 35 - .../1900_carg.rst | 31 - .../1910_cimag.rst | 30 - .../1920_cmplx.rst | 27 - .../1930_conj.rst | 26 - .../1940_cproj.rst | 30 - .../1950_creal.rst | 30 - .../2000_misc_internal.rst | 40 - .../3000_configure.rst | 56 -- .../3100_makefile.rst | 48 -- .../5_Internal_Interface_Design.rst | 20 - ...ents_to_Design_Components_Traceability.rst | 761 ------------------ libm/libmcs/doc/sdd/conf.py | 84 -- libm/libmcs/doc/sdd/index.rst | 18 - libm/libmcs/doc/sum/10_Bindings.rst | 179 ---- libm/libmcs/doc/sum/1_Abbreviations.rst | 112 --- libm/libmcs/doc/sum/2_Conventions.rst | 39 - .../doc/sum/3_Purpose_of_the_Software.rst | 318 -------- libm/libmcs/doc/sum/4_General_Behaviour.rst | 395 --------- .../sum/5_External_View_of_the_Software.rst | 177 ---- .../doc/sum/6_Operations_Environment.rst | 77 -- libm/libmcs/doc/sum/7_Operations_Manual.rst | 95 --- libm/libmcs/doc/sum/8_Reference_Manual.rst | 556 ------------- libm/libmcs/doc/sum/9_Tutorial.rst | 265 ------ libm/libmcs/doc/sum/conf.py | 84 -- libm/libmcs/doc/sum/index.rst | 26 - libm/libmcs/libm/include/complex.h | 1 - libm/libmcs/libm/include/config.h | 17 - libm/libmcs/libm/include/math.h | 1 - libm/phoenix/compatibility.c | 49 ++ 144 files changed, 157 insertions(+), 10546 deletions(-) create mode 100644 libm/Makefile create mode 100644 libm/README.md delete mode 100644 libm/libmcs/doc/_static/css/custom.css delete mode 100644 libm/libmcs/doc/figure/libmcs-complex.png delete mode 100644 libm/libmcs/doc/figure/libmcs-include-common.png delete mode 100644 libm/libmcs/doc/figure/libmcs-real.png delete mode 100644 libm/libmcs/doc/figure/libmcs-static-architecture.png delete mode 100644 libm/libmcs/doc/index.html delete mode 100644 libm/libmcs/doc/logo/libmcs-favicon.ico delete mode 100644 libm/libmcs/doc/logo/libmcs-logo.png delete mode 100644 libm/libmcs/doc/sdd/1_Introduction.rst delete mode 100644 libm/libmcs/doc/sdd/2_Applicable_and_Reference_Documents.rst delete mode 100644 libm/libmcs/doc/sdd/3_Abbreviations.rst delete mode 100644 libm/libmcs/doc/sdd/4_Software_Design_Overview.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/0_Software_Design.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/1_General.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/2_Overall_Architecture.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/3_Software_Component_Design_General.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0000_Software_Component_Design_Aspects_Of_Each_Component.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0010_fpclassify.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0020_isfinite.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0030_isinf.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0040_isnan.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0050_isnormal.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0060_signbit.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0100_acos.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0110_asin.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0120_atan.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0130_atan2.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0140_cos.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0150_sin.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0160_tan.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0170_trig.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0200_acosh.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0210_asinh.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0220_atanh.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0230_cosh.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0240_sinh.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0250_tanh.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0300_exp.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0310_exp2.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0320_expm1.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0330_frexp.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0340_ilogb.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0350_ldexp.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0360_log.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0370_log10.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0380_log1p.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0390_log2.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0400_logb.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0410_modf.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0420_scalbn.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0430_scalbln.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0440_log_internal.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0500_cbrt.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0510_fabs.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0520_hypot.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0530_pow.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0540_sqrt.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0600_erf.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0610_erfc.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0620_lgamma.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0630_tgamma.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0640_gamma_internal.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0650_signgam.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0700_ceil.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0710_floor.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0720_nearbyint.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0730_rint.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0740_lrint.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0750_llrint.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0760_round.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0770_lround.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0780_llround.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0790_trunc.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0900_fmod.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0910_remainder.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0920_remquo.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1000_copysign.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1010_nan.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1020_nextafter.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1030_nexttoward.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1100_fdim.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1110_fmax.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1120_fmin.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1200_fma.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1300_isgreater.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1310_isgreaterequal.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1320_isless.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1330_islessequal.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1340_islessgreater.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1350_isunordered.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1400_j0.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1410_j1.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1420_jn.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1430_y0.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1440_y1.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1450_yn.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1500_cacos.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1510_casin.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1520_catan.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1530_ccos.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1540_csin.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1550_ctan.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1600_cacosh.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1610_casinh.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1620_catanh.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1630_ccosh.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1640_csinh.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1650_ctanh.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1700_cexp.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1710_clog.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1800_cabs.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1810_cpow.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1820_csqrt.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1900_carg.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1910_cimag.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1920_cmplx.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1930_conj.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1940_cproj.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1950_creal.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/2000_misc_internal.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/3000_configure.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/3100_makefile.rst delete mode 100644 libm/libmcs/doc/sdd/5_Software_Design/5_Internal_Interface_Design.rst delete mode 100644 libm/libmcs/doc/sdd/6_Requirements_to_Design_Components_Traceability.rst delete mode 100644 libm/libmcs/doc/sdd/conf.py delete mode 100644 libm/libmcs/doc/sdd/index.rst delete mode 100644 libm/libmcs/doc/sum/10_Bindings.rst delete mode 100644 libm/libmcs/doc/sum/1_Abbreviations.rst delete mode 100644 libm/libmcs/doc/sum/2_Conventions.rst delete mode 100644 libm/libmcs/doc/sum/3_Purpose_of_the_Software.rst delete mode 100644 libm/libmcs/doc/sum/4_General_Behaviour.rst delete mode 100644 libm/libmcs/doc/sum/5_External_View_of_the_Software.rst delete mode 100644 libm/libmcs/doc/sum/6_Operations_Environment.rst delete mode 100644 libm/libmcs/doc/sum/7_Operations_Manual.rst delete mode 100644 libm/libmcs/doc/sum/8_Reference_Manual.rst delete mode 100644 libm/libmcs/doc/sum/9_Tutorial.rst delete mode 100644 libm/libmcs/doc/sum/conf.py delete mode 100644 libm/libmcs/doc/sum/index.rst delete mode 100644 libm/libmcs/libm/include/config.h create mode 100644 libm/phoenix/compatibility.c diff --git a/libm/Makefile b/libm/Makefile new file mode 100644 index 00000000..4d314515 --- /dev/null +++ b/libm/Makefile @@ -0,0 +1,87 @@ +# +# Makefile for math library +# +# Copyright 2025 Phoenix Systems +# Author: Mikolaj Matalowski +# +# This file is part of Phoenix-RTOS. +# +# %LICENSE% +# +LIBM_USE_LIBMCS ?= n +LIBM_LIBMCS_DAZ ?= n +LIBM_WANT_COMPLEX ?= y + +# Grab builtin definitions from gcc +GET_DEFINITIONS = $(shell $(CC) -dM -E - < /dev/null) +DEFINITIONS = $(filter-out #define, $(GET_DEFINITIONS)) + +# Setting sizes of floating point types +NAME_OF_TYPE_FOR_SIZE_CHECK := __SIZEOF_DOUBLE__ +DOUBLE_SIZE = $(word 2, $(shell echo "$(DEFINITIONS)" | grep -E -o '$(NAME_OF_TYPE_FOR_SIZE_CHECK)\s+(\w+)')) + +ifeq ($(DOUBLE_SIZE), 8) + CPPFLAGS += -DLIBMCS_DOUBLE_IS_64BITS +else + CPPFLAGS += -DLIBMCS_DOUBLE_IS_32BITS +endif + +NAME_OF_TYPE_FOR_SIZE_CHECK := __SIZEOF_LONG_DOUBLE__ +LDOUBLE_SIZE = $(word 2, $(shell echo "$(DEFINITIONS)" | grep -E -o '$(NAME_OF_TYPE_FOR_SIZE_CHECK)\s+(\w+)')) + +ifeq ($(LDOUBLE_SIZE), 10) + CPPFLAGS += -DLIBMCS_LONG_DOUBLE_IS_80BITS +else + CPPFLAGS += -DLIBMCS_LONG_DOUBLE_IS_64BITS +endif + +NAME_OF_TYPE_FOR_SIZE_CHECK := __SIZEOF_LONG__ +LONG_SIZE = $(word 2, $(shell echo "$(DEFINITIONS)" | grep -E -o '$(NAME_OF_TYPE_FOR_SIZE_CHECK)\s+(\w+)')) + +ifeq ($(LONG_SIZE), 8) + CPPFLAGS += -DLIBMCS_LONG_IS_64BITS +else + CPPFLAGS += -DLIBMCS_LONG_IS_32BITS +endif + +# Set options for denormals on the FPU +ifeq ($(LIBMCS_WANT_DAZ), y) + CPPFLAGS += -DLIBMCS_FPU_DAZ +endif + +ifeq ($(LIBM_WANT_COMPLEX), y) + CPPFLAGS += -DLIBMCS_WANT_COMPLEX +endif + +CFLAGS += -Ilibm/libmcs/libm/include + +# TODO: Separate math library implementation from libphoenix + +# Build for libmcs +ifeq ($(USE_LIBMCS), y) + ifeq ($(LIBM_WANT_COMPLEX), y) + CPPFLAGS += -DLIBM_WANT_COMPLEX + OBJS += $(addprefix $(PREFIX_O), $(patsubst %.c,%.o,$(wildcard libm/libmcs/libm/complexd/internal/*.c))) + OBJS += $(addprefix $(PREFIX_O), $(patsubst %.c,%.o,$(wildcard libm/libmcs/libm/complexd/*.c))) + OBJS += $(addprefix $(PREFIX_O), $(patsubst %.c,%.o,$(wildcard libm/libmcs/libm/complexf/internal/*.c))) + OBJS += $(addprefix $(PREFIX_O), $(patsubst %.c,%.o,$(wildcard libm/libmcs/libm/complexf/*.c))) + endif + + # fenv.c implementation is target specific + OBJS += $(addprefix $(PREFIX_O), $(patsubst %.c,%.o, $(filter-out %fenv.c,$(wildcard libm/libmcs/libm/common/*.c)))) + OBJS += $(addprefix $(PREFIX_O), $(patsubst %.c,%.o,$(wildcard libm/libmcs/libm/mathf/*.c))) + OBJS += $(addprefix $(PREFIX_O), $(patsubst %.c,%.o,$(wildcard libm/libmcs/libm/mathf/internal/*.c))) + OBJS += $(addprefix $(PREFIX_O), $(patsubst %.c,%.o,$(wildcard libm/libmcs/libm/mathd/*.c))) + OBJS += $(addprefix $(PREFIX_O), $(patsubst %.c,%.o,$(wildcard libm/libmcs/libm/mathd/internal/*.c))) +else + # Build for phoenix implementation + # OBJS += $(addprefix $(PREFIX_O)libm/, $(patsubst %.c,%.o, math/common.c math/trig.c)) + OBJS += $(addprefix $(PREFIX_O), $(patsubst %.c,%.o, $(patsubst %complex.c,, $(wildcard libm/phoenix/*.c)))) + + ifeq ($(LIBM_WANT_COMPLEX), y) + OBJS += $(addprefix $(PREFIX_O), $(patsubst %.c,%.o, libm/phoenix/complex.c)) + endif + + # This part is needed for libmcs headers compatibility + CFLAGS += -include libm/libmcs/libm/include/internal_config.h +endif \ No newline at end of file diff --git a/libm/README.md b/libm/README.md new file mode 100644 index 00000000..1b65ade2 --- /dev/null +++ b/libm/README.md @@ -0,0 +1,21 @@ +# Phoenix math library implementation +This directory contains implementation of math library. It currently links to libphoenix with intention to be compiled to separate libm.a library. There are two implementation for two following reasons: +- libphoenix implementation is not complete. +- version for critical systems is nice to have :) + +Usage: For each project it is suggested to set following +- ```LIBM_USE_LIBMCS := y/n``` - select implementation of math library for critical systems (if not set will use phoenix implementation) +- ```LIBM_WANT_COMPLEX := y/n``` - select if project wants implementation of complex routines +- ```LIBM_LIBMCS_DAZ := y/n``` - (applicable only for libmcs) select whether denormals are zero. This is especially useful if underlying FPU has limited functionalities implemented. + +## LIBMCS +This is a copy of libmcs math library implementation from https://gitlab.com/gtd-gmbh/libmcs (commit: 79a3235511f01644139c95249487729621667249) + +For documentation please refer to /docs directory present on the main repo linked above. + +## Phoenix +This is implementation of math library developed alongside Pheonix RTOS operating system. Keep in mind that this implementation is not complete, not all functions in C99 standard are implemented. Since headers are shared for both implementations, and libmcs implementation contains complete set of C99 function, there might be some undefined symbols when linking projects that use this implementation in libphoenix. Not present functions will be added if such need arises in the future. + +# Notes +1. This is a temporary state, moving math library to be separate to libphoenix +2. libmcs - has no ARM optimization for ```sqrt``` function \ No newline at end of file diff --git a/libm/libmcs/doc/_static/css/custom.css b/libm/libmcs/doc/_static/css/custom.css deleted file mode 100644 index 63a143b0..00000000 --- a/libm/libmcs/doc/_static/css/custom.css +++ /dev/null @@ -1,66 +0,0 @@ -.wy-nav-content { - max-width: 1200px !important; -} - -.wy-side-nav-search { - background-color: #80a2b4; -} - -.wy-side-nav-search a { - color: #404040; -} - -.wy-side-nav-search a:visited { - color: #404040; -} - -.wy-side-nav-search input[type=text] { - border-color: #536974; -} - -a { - color: #6e8b9a; -} - -a:visited { - color: #b49d80; -} - -a:hover { - color: #536974; -} - -.wy-menu-vertical a:active { - color: #404040 !important; - background-color: #d9d9d9; -} - -.wy-menu-vertical a:hover { - color: #404040 !important; - background-color: #d9d9d9 !important; -} - -.wy-menu-vertical li.toctree-l1 a { - font-weight: bold; -} - -.wy-menu-vertical li.toctree-l1 a:visited { - color: #d9d9d9; -} - -.wy-menu-vertical li.toctree-l1 a:hover { - color: #d9d9d9; -} - -.wy-menu-vertical li.current a:visited { - color: #404040; -} - -.wy-menu-vertical li.current a:hover { - color: #404040; -} - -.rst-content dl:not(.docutils) dt { - color: #536974; - border-top: solid 3px #536974; -} diff --git a/libm/libmcs/doc/figure/libmcs-complex.png b/libm/libmcs/doc/figure/libmcs-complex.png deleted file mode 100644 index 850cab431cb55cc5bfd7fe1d9823a0356f3f0432..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18554 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 {eK`W`EN{qo}tEo1Bj=a87fD5K_JBxf@r)l zU|q_Czm&~i!w21_1vUM_%>w~h2*d<{IYzp=PQ#T4*Y`or$J{~C0xVPVVej7nzQ^vr z_HnNZDbqo@y(z>Dxm_)V0k`PErQ75~knjd7WfyZxXA xxn{-=aSjiMgVq+mHxB$?BZQ#ee$SE*9E2B+wQuKzfiFOmVCwQ&H*P=vzW@*mLizvz diff --git a/libm/libmcs/doc/figure/libmcs-include-common.png b/libm/libmcs/doc/figure/libmcs-include-common.png deleted file mode 100644 index 9798d0c6d2d451a7a7c0dbc62cc2421444d89ada..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10299 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�?fHNJvmS;(G!wc?^r` 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 diff --git a/libm/libmcs/doc/index.html b/libm/libmcs/doc/index.html deleted file mode 100644 index f73d33db..00000000 --- a/libm/libmcs/doc/index.html +++ /dev/null @@ -1,117 +0,0 @@ - - - - - - - LibmCS Documentation Resources - - - - -
- - - -
- - -
- -
- -
- -
- -
- -
- - - - diff --git a/libm/libmcs/doc/logo/libmcs-favicon.ico b/libm/libmcs/doc/logo/libmcs-favicon.ico deleted file mode 100644 index ac9ec21ad0fe141133d3770e4d219af292f4fe7c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12862 zcmeHO`BxJ=6dwNxkH5R|RMwUjE7d+Kt>Ae@3bIIPQJ@qMeRhQ+Z9%kdD2pJV$mYI0 z72hBDK1>OD(@q7NnGVOH>72|>a`WX&<|g+}5rhNySS$jrhlGMMK{zM~LIJ)I2?=~R zd_Xa&|6Xo+8t8sr%{q_{R+Ma@p_;{Fu*7p>)=UqqG1 zEb4J>I$$=Q`Z)#1r^dXrG$Z~G^Mh7%F&S@isDoC{Z^rLUO~I9V3(O7ylM#O+aD{*e z`CncR=NC5Z9aC_&Vsi@cz*3W#j{nnQ^t`!*RJ$Kl3;AReH@oTptgP_JlSDU>%q9DA z3t_0Yfkg*Mt7xTaJDgVfT+i-s)4CB`=d-#1hc6ZPn>2LhFkh1W2c(F}j zJ6M{y$+lHV9^1hVlS%-yFklHm?6sEaYt6q%eV&U;6MwU9)sTdt3k51xAA|s%Jdh zPIn6V_{TnF(*J>T0!^MKE6n~L_)iXbs1lM{cyL`l0l;3PTi6P{;{_z|sym;smYI2x!$N#6P=-pgIZniV(M*t^x z{JkDUEe|^ogf6>UZMmF(5Qtcx4zM~E&ch8P!Gt}W-(EipDQ|Y9_}K$~DOGuq?-IX3 zZT>HbzmXl`msf`k{<~U&pJciNJ|~4;eXbN<6(XE8-5c__8dCc;syS;->IvQw{KH%E zAM8go1j?@DH?v`QC}fN(jQ@aef^8FjJQc$IKmHI2KBHQDV-*hJY-!%}aOw$uTx+WI zSTIjVy)?nc?`S$tD|ENn5zEaxW){HW!vSO2wo`^#5G4v;S9CNw(8RV?LmunFVk)8_ zvt%%?dHLfEyX6GlQ)i1U3v60sHJ4<3qrKZ6x!0c@^HPvmGB~ht@0yE3m~@BTm<2hC z;B_uM9N^NO97>)hy0hcQ%L_!n zn*JLP`C#Otd3o}d-Lm=f5}GP>1vm>S8R5wVKiaNL`W@A&XBlojcISNro{SxDtMNLr qwo0!+R6IwvrJBP*Rx+w71w)f-3}_5!3}_6bGa&VU0h;{xVBkN+N#Q&I diff --git a/libm/libmcs/doc/logo/libmcs-logo.png b/libm/libmcs/doc/logo/libmcs-logo.png deleted file mode 100644 index c431b9a2590b02d9c638e3760b103c3f2e2382ce..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28336 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%0A{*0&7BycSiLj6?s@YIElmFGBAl66A^Ozi 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 Q9$`I`R(zT(Y2g2V0E#qSX#fBK diff --git a/libm/libmcs/doc/sdd/1_Introduction.rst b/libm/libmcs/doc/sdd/1_Introduction.rst deleted file mode 100644 index 4e118c2c..00000000 --- a/libm/libmcs/doc/sdd/1_Introduction.rst +++ /dev/null @@ -1,15 +0,0 @@ -Introduction -============ - -.. raw:: html - - - -This document is the :ref:`SDD ` for the development of a qualified mathematical library for critical systems and is prepared in response to ECSS-E-ST-40C :ref:`[AD01] `, section F.2. - -Its purpose is to describe the software architectural design and the software detailed design, by listing the software components, explaining the purpose of each and documenting the design decisions which led to -the implementation of the software as is. It further includes the internal interfaces design. - -The mathematical library is an :ref:`ECSS ` category B software. diff --git a/libm/libmcs/doc/sdd/2_Applicable_and_Reference_Documents.rst b/libm/libmcs/doc/sdd/2_Applicable_and_Reference_Documents.rst deleted file mode 100644 index be93c1a7..00000000 --- a/libm/libmcs/doc/sdd/2_Applicable_and_Reference_Documents.rst +++ /dev/null @@ -1,46 +0,0 @@ -Applicable and Reference Documents -================================== - -.. raw:: html - - - -In case no issue number is specified for a document, the latest issue shall be applicable. - -.. _AD: - -Applicable Documents --------------------- - -The documents listed below form part of this document. - -.. table:: Applicable Documents - :name: applicable_documents - - ============== ================ ========= ====================================================== - Reference Identification Issue Title - ============== ================ ========= ====================================================== - AD01 ECSS-E-ST-40 C Space Engineering - Software - AD02 ECSS-Q-ST-80 C Rev. 1 Space Product Assurance - Software Product Assurance - ============== ================ ========= ====================================================== - -.. _RD: - -Reference Documents -------------------- - -The documents listed below were used to prepare this document and contain background information on topics discussed in this document. - -.. table:: Reference Documents - :name: reference_documents - - ============== ================ ========= ======================================================== - Reference Identification Issue Title - ============== ================ ========= ======================================================== - RD01 ES-SRS.00-ML \- Software Requirements Specification - RD02 ED-ICD.00-ML \- Interface Control Document - RD03 ISO/IEC 9899 2018 Programming languages - C - RD04 MISRA C:2012 03/2013 Guidelines for the use of C language in critical systems - ============== ================ ========= ======================================================== diff --git a/libm/libmcs/doc/sdd/3_Abbreviations.rst b/libm/libmcs/doc/sdd/3_Abbreviations.rst deleted file mode 100644 index 4c24f2d3..00000000 --- a/libm/libmcs/doc/sdd/3_Abbreviations.rst +++ /dev/null @@ -1,52 +0,0 @@ -.. _ABBR: - -Terms, Definitions and Abbreviated Terms -======================================== - -.. raw:: html - - - -Agency - refers to :ref:`ESA ` - -DAZ - Denormals are Zero - -denormal - See subnormal. - -DRD - Document Requirements Definition - -ECSS - European Cooperation for Space Standardization - -ESA - European Space Agency - -FPU - Floating Point Unit - -ICD - Interface Control Document - -SDD - Software Design Document - -SPDX - Software Package Data Exchange - -SRS - Software Requirements Specification - -subnormal - See IEEE-754 standard for the definition. - -SUM - Software Users Manual - -ULP - Unit in the Last Place diff --git a/libm/libmcs/doc/sdd/4_Software_Design_Overview.rst b/libm/libmcs/doc/sdd/4_Software_Design_Overview.rst deleted file mode 100644 index 3bf38291..00000000 --- a/libm/libmcs/doc/sdd/4_Software_Design_Overview.rst +++ /dev/null @@ -1,124 +0,0 @@ -Software Design Overview -======================== - -Software Static Architecture ----------------------------- - -.. raw:: html - - - -The mathematical library is a software library. The library is a fully passive library and provides solutions for mathematical procedures to the calling software. As such it can be seen as a replacement of the -``libm`` standard library. The procedures the library implements are listed in :ref:`Overall Architecture`. - -The library has no separate operational modes or states, it simply provides the above mentioned procedures. - -Further the library does not store data of any kind. - -Software Dynamic Architecture ------------------------------ - -.. raw:: html - - - -The library has no real-time constraints, all procedures provided calculate a response right away. Each procedure however has a bounded execution time (refer to :ref:`SRS ` :ref:`[RD01] ` §5.3). - -Software Behaviour ------------------- - -As previously noted, the library’s behaviour is that of a passive library. It never executes code of any kind without being explicitly called by another program. - -Interfaces Context ------------------- - -.. raw:: html - - - -No :ref:`ICD ` will be provided for this project and its contents are part of the :ref:`SUM ` and this :ref:`SDD `. All of the :ref:`ICDs ` contents required by :ref:`ECSS ` are part of these two documents without any loss. - -Section :ref:`Software Components Design – Aspects of Each Component` provides information on the function signatures of all library procedures. The library is meant to be included in other software projects. - -The interface provided is that of a C library that can be compiled to an object file to be statically or dynamically linked to the calling software. - -The library and all its components are compliant to the IEEE 754-2019 (Information technology – Microprocessor Systems – Floating-Point arithmetic), IEEE 1003.1-2017 (POSIX) and ISO/IEC 9899 (Programming languages – C) standards. - -Long Lifetime Software ----------------------- - -.. raw:: html - - - -The library does not cause restrictions regarding the longevity of the operating software. It does not depend on a particular operating system or hardware setup. - -Memory and CPU Budget ---------------------- - -.. raw:: html - - - -The library uses 100% of available processing time while executing a procedure and 0% while it doesn’t. This is due to the library not having any tasks that run continuously or periodically. It simply executes one function, returns its result and stops. - -The static memory needed for the library differs depending on the used toolchain and on which procedures are used by the user (due to ``gc-sections`` flags to the compiler). Still the library targets to use -as little static memory as possible while providing its functionality. The library’s allocation of dynamic memory is marginal - each procedure only requires several bytes to save intermediate variables. This however -is only stack memory, no ``malloc`` is used, therefore no memory will be allocated from heap. - -Design Standards, Conventions and Procedures --------------------------------------------- - -.. raw:: html - - - -The main design method of this project is ‘reuse’, therefore the design of the functions highly depends on the already existing implementation, which in turn causes this :ref:`SDD ` to be more of a description of an existing design rather than a design produced before implementation. However the procedures and their designs may be improved during this project, turning the design method into ‘reuse with improvements’. - -Source code documentation is done using the restructured text format for file, procedure and variable documentation, it will then be interpreted by Sphinx to generate HTML/PDF documents. Additionally the software engineer may use further comments within the code to describe parts of their implementation. - -All aspects regarding the design that are not explicitly stated shall remain as they were in newlib’s libm. - -The library will guarantee thread safety and reentrancy for all procedures unless explicitly stated otherwise. The only exception will be the ``lgamma`` procedures due to the requirement to have the global variable ``signgam``, as such the content of the variable is not thread safe when ``lgamma`` procedures are executed in multiple threads at the same time. - -We define the set of all floating-point numbers as :math:`\mathbb{F}` and the set of all subnormal numbers as :math:`\mathbb{S}` to be used in mathematical formulae. The set of floating-point numbers :math:`\mathbb{F}` contains all floating-point numbers, that is normals, subnormals (therefore :math:`\mathbb{S} \subset \mathbb{F}`), zeroes, infinities and ``NaN``, of the type given by the context. If a reduction to a specific type is needed, this will be indicated as follows: :math:`\mathbb{F}_s` for single precision, :math:`\mathbb{F}_d` for double precision, and :math:`\mathbb{F}_{ld}` for long double precision. The same will be done for :math:`\mathbb{S}` with :math:`\mathbb{S}_s`, :math:`\mathbb{S}_d`, and :math:`\mathbb{S}_{ld}` respectively. Furthermore :math:`\mathbb{F}^{+}` symbolizes all floating-point numbers where the sign bit is not set, while :math:`\mathbb{F}^{-}` contains all those where the sign bit is set (this includes :math:`-0.0`, ``-Inf``, and ``NaNs`` where the signbit is set). Using these sets we are able to express floating-point numbers in mathematical formulae, for example the formula :math:`x \in \mathbb{F} \setminus \left \{ \pm \text{Inf}, \text{NaN} \right \}` denotes that `x` is a floating-point number that is neither infinity nor ``NaN``, which leaves `x` to be either zero, a normal or a subnormal number. :math:`\mathbb{F}` cannot be fully represented by conventional number classifications due to the introduction of :math:`\pm 0.0`, explicit infinities and ``NaNs``, however the following is valid: :math:`(\mathbb{F} \setminus \left \{ -0.0, \pm \text{Inf}, \text{NaN} \right \}) \subset \mathbb{Q}`. - -Similarly we define the set of all 32bit integer numbers as :math:`\mathbb{I}`. :math:`\mathbb{I}` is a subset of :math:`\mathbb{Z}` limited by the size of the integer, therefore :math:`\mathbb{I} \subset \mathbb{Z}`. The same concept applies for :math:`\mathbb{I}_{l}` which represents either 32bit or 64bit integer numbers depending on the size of ``long int``, and :math:`\mathbb{I}_{ll}` which represents 64bit integer numbers. - -To denote the similarity, but not always equality, between the mathematical function and its representing procedure we use :math:`\approx` where appropriate. This is not used if a procedure is able to exactly mimic the functionality of the mathematical function. diff --git a/libm/libmcs/doc/sdd/5_Software_Design/0_Software_Design.rst b/libm/libmcs/doc/sdd/5_Software_Design/0_Software_Design.rst deleted file mode 100644 index 6fc8efe2..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/0_Software_Design.rst +++ /dev/null @@ -1,11 +0,0 @@ -Software Design -=============== - -.. toctree:: - :maxdepth: 3 - - 1_General.rst - 2_Overall_Architecture.rst - 3_Software_Component_Design_General.rst - 4_Software_Component_Design_Aspects_Of_Each_Component/0000_Software_Component_Design_Aspects_Of_Each_Component.rst - 5_Internal_Interface_Design.rst diff --git a/libm/libmcs/doc/sdd/5_Software_Design/1_General.rst b/libm/libmcs/doc/sdd/5_Software_Design/1_General.rst deleted file mode 100644 index 4a1eefc2..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/1_General.rst +++ /dev/null @@ -1,21 +0,0 @@ -General -------- - -.. raw:: html - - - -The herein described software is a mathematical library, not designed for independent execution, but for embedding into other software projects. This chapter describes the software design in a top-bottom approach: First in :ref:`Overall Architecture` a common overview over the structure of the software is given. The section afterwards :ref:`Software Components Design - General` identifies each component in the software. All components are described in :ref:`Software Components Design – Aspects of Each Component`. The last section :ref:`Internal Interface Design` gives an overview about the internal usage between the components. - -The library is a reuse of the mathematical library contained in ``newlib`` called ``libm``, specifically we use the ``libm`` contained in ``newlib`` v4.0.0. - -In the process of improving the reused software several design and implementation changes have to be made to the library. - -This document follows in structure and content the :ref:`DRD ` in ECSS-E-ST-40 :ref:`[AD01] `, but because of the type of the reused software some required items have to be redefined for an appropriate design description or are not relevant. The reinterpreting/redefining of items is done at the start of each section. All items not relevant in this context are mentioned at the end of each section to be compliant with :ref:`ECSS `. - -The source code is designed to be compliant to the mandatory and required rules depicted in MISRA C:2012 :ref:`[AD04] `. diff --git a/libm/libmcs/doc/sdd/5_Software_Design/2_Overall_Architecture.rst b/libm/libmcs/doc/sdd/5_Software_Design/2_Overall_Architecture.rst deleted file mode 100644 index 23118b6f..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/2_Overall_Architecture.rst +++ /dev/null @@ -1,387 +0,0 @@ -Overall Architecture --------------------- - -.. raw:: html - - - -One of the project’s goals is having an easy access to all of the library’s procedures. To attain this goal, only the header files ``math.h`` and ``complex.h`` (if complex procedures are wanted by the given project) have to be included to use all the mathematical procedures provided by the library. These header files contain all procedure definitions, while their implementation can be found in separate ``.c`` files. - -A further difference to other projects is the definition of a software component. In most other projects, this library would be considered as one single component, but in the context of describing the library a component/unit is one procedure, e.g. ``sin``, ``sinf``, ``sinl``, ``cos``, ``cosf``, ``cosl``, ``atan2``, &c. Most of the procedures are implemented in one or more separate translation units. The following procedures are accessible (the list contains the names of the double precision procedures, the single precision procedure names are the same but suffixed with an ``f``, the long double precision procedure names are the same but suffixed with an ``l``): - -.. table:: List of all procedures in math.h - :name: List of math procedures - - +--------------------+-----------------------------------------------------------+ - | Procedure | Description | - +====================+===========================================================+ - | ``fpclassify`` | Procedure returning the classification of the argument | - +--------------------+-----------------------------------------------------------+ - | ``isfinite`` | Procedure returning whether the value of the argument is | - | | finite or not (not :math:`±Inf` and not :math:`NaN`) | - +--------------------+-----------------------------------------------------------+ - | ``isinf`` | Procedure returning whether the value of the argument is | - | | positive or negative Infinity or not | - +--------------------+-----------------------------------------------------------+ - | ``isnan`` | Procedure returning whether the argument is a | - | | :math:`NaN` floating-point value or not | - +--------------------+-----------------------------------------------------------+ - | ``isnormal`` | Procedure returning whether the argument is a normal | - | | floating-point value or not | - +--------------------+-----------------------------------------------------------+ - | ``signbit`` | Procedure returning whether the argument is negative or | - | | not | - +--------------------+-----------------------------------------------------------+ - | ``acos`` | Procedure returning the trigonometric arccosine | - +--------------------+-----------------------------------------------------------+ - | ``asin`` | Procedure returning the trigonometric arcsine | - +--------------------+-----------------------------------------------------------+ - | ``atan`` | Procedure returning the trigonometric arctangent | - +--------------------+-----------------------------------------------------------+ - | ``atan2`` | Procedure returning the trigonometric arctangent of | - | | :math:`\frac{y}{x}` | - +--------------------+-----------------------------------------------------------+ - | ``cos`` | Procedure returning the trigonometric cosine | - +--------------------+-----------------------------------------------------------+ - | ``sin`` | Procedure returning the trigonometric sine | - +--------------------+-----------------------------------------------------------+ - | ``tan`` | Procedure returning the trigonometric tangent | - +--------------------+-----------------------------------------------------------+ - | ``acosh`` | Procedure returning the hyperbolic arccosine | - +--------------------+-----------------------------------------------------------+ - | ``asinh`` | Procedure returning the hyperbolic arcsine | - +--------------------+-----------------------------------------------------------+ - | ``atanh`` | Procedure returning the hyperbolic arctangent | - +--------------------+-----------------------------------------------------------+ - | ``cosh`` | Procedure returning the hyperbolic cosine | - +--------------------+-----------------------------------------------------------+ - | ``sinh`` | Procedure returning the hyperbolic sine | - +--------------------+-----------------------------------------------------------+ - | ``tanh`` | Procedure returning the hyperbolic tangent | - +--------------------+-----------------------------------------------------------+ - | ``exp`` | Procedure returning the base :math:`e` exponential of | - | | :math:`x` | - +--------------------+-----------------------------------------------------------+ - | ``exp2`` | Procedure returning the base :math:`2` exponential of | - | | :math:`x` | - +--------------------+-----------------------------------------------------------+ - | ``expm1`` | Procedure returning the base :math:`e` exponential of | - | | :math:`x` minus :math:`1` | - +--------------------+-----------------------------------------------------------+ - | ``frexp`` | Procedure breaking :math:`x` into a normalized fraction | - | | and an integral power of :math:`2` | - +--------------------+-----------------------------------------------------------+ - | ``ilogb`` | Procedure returning the binary exponent of :math:`x` as | - | | integer | - +--------------------+-----------------------------------------------------------+ - | ``ldexp`` | Procedure returning :math:`x` multiplied by an integral | - | | power of :math:`2` | - +--------------------+-----------------------------------------------------------+ - | ``log`` | Procedure returning the natural logarithm | - +--------------------+-----------------------------------------------------------+ - | ``log10`` | Procedure returning the base :math:`10` logarithm | - +--------------------+-----------------------------------------------------------+ - | ``log1p`` | Procedure returning the natural logarithm of | - | | :math:`x + 1` | - +--------------------+-----------------------------------------------------------+ - | ``log2`` | Procedure returning the base :math:`2` logarithm | - +--------------------+-----------------------------------------------------------+ - | ``logb`` | Procedure returning the binary exponent of :math:`x` | - +--------------------+-----------------------------------------------------------+ - | ``modf`` | Procedure breaking :math:`x` in its integral and | - | | fractional part | - +--------------------+-----------------------------------------------------------+ - | ``scalbn`` | Procedure returning :math:`x` multiplied by an integral | - | | power of :math:`2` | - +--------------------+-----------------------------------------------------------+ - | ``scalbln`` | Procedure returning :math:`x` multiplied by an integral | - | | power of :math:`2` | - +--------------------+-----------------------------------------------------------+ - | ``cbrt`` | Procedure returning the cubic root | - +--------------------+-----------------------------------------------------------+ - | ``fabs`` | Procedure returning the absolute value | - +--------------------+-----------------------------------------------------------+ - | ``hypot`` | Procedure returning the square root of :math:`x^2+y^2` | - +--------------------+-----------------------------------------------------------+ - | ``pow`` | Procedure returning :math:`x` raised to the power of | - | | :math:`y` | - +--------------------+-----------------------------------------------------------+ - | ``sqrt`` | Procedure returning the square root | - +--------------------+-----------------------------------------------------------+ - | ``erf`` | Procedure returning the error function | - +--------------------+-----------------------------------------------------------+ - | ``erfc`` | Procedure returning the complementary error function | - | | (``erfc`` = :math:`1 -` ``erf``) | - +--------------------+-----------------------------------------------------------+ - | ``lgamma`` | Procedure returning the natural logarithm of the absolute | - | | value of gamma of :math:`x` | - +--------------------+-----------------------------------------------------------+ - | ``tgamma`` | Procedure returning gamma function of :math:`x` | - +--------------------+-----------------------------------------------------------+ - | ``ceil`` | Procedure for rounding upwards to the nearest integer | - +--------------------+-----------------------------------------------------------+ - | ``floor`` | Procedure for rounding downwards to the nearest integer | - +--------------------+-----------------------------------------------------------+ - | ``nearbyint`` | Procedure for rounding to the nearest integer using the | - | | current rounding direction | - +--------------------+-----------------------------------------------------------+ - | ``rint`` | Procedure for rounding to the nearest integer using the | - | | current rounding direction (raises inexact) | - +--------------------+-----------------------------------------------------------+ - | ``lrint`` | Procedure for rounding to the nearest integer using the | - | | current rounding direction | - +--------------------+-----------------------------------------------------------+ - | ``llrint`` | Procedure for rounding to the nearest integer using the | - | | current rounding direction | - +--------------------+-----------------------------------------------------------+ - | ``round`` | Procedure for rounding to the nearest integer (Halfway | - | | values rounded away from :math:`0`) | - +--------------------+-----------------------------------------------------------+ - | ``lround`` | Procedure for rounding to the nearest integer (Halfway | - | | values rounded away from :math:`0`) | - +--------------------+-----------------------------------------------------------+ - | ``llround`` | Procedure for rounding to the nearest integer (Halfway | - | | values rounded away from :math:`0`) | - +--------------------+-----------------------------------------------------------+ - | ``trunc`` | Procedure for rounding towards :math:`0` to the nearest | - | | integer | - +--------------------+-----------------------------------------------------------+ - | ``fmod`` | Procedure returning the floating-point remainder of | - | | :math:`\frac{y}{x}` (rounded towards zero) | - +--------------------+-----------------------------------------------------------+ - | ``remainder`` | Procedure returning the floating-point remainder of | - | | :math:`\frac{y}{x}` (rounded to nearest integral value) | - +--------------------+-----------------------------------------------------------+ - | ``remquo`` | Procedure returning the same value as ``remainder`` and | - | | puts the quotient in :math:`*quo` | - +--------------------+-----------------------------------------------------------+ - | ``copysign`` | Procedure returning a floating-point number with the | - | | magnitude of :math:`x` and the sign of :math:`y` | - +--------------------+-----------------------------------------------------------+ - | ``nan`` | Procedure returning a :math:`NaN` | - +--------------------+-----------------------------------------------------------+ - | ``nextafter`` | Procedure returning the next floating-point value after | - | | :math:`x` in direction of :math:`y` | - +--------------------+-----------------------------------------------------------+ - | ``nexttoward`` | Procedure returning the next floating-point value after | - | | :math:`x` in direction of :math:`y` | - +--------------------+-----------------------------------------------------------+ - | ``fdim`` | Procedure returning the positive difference between the | - | | arguments | - +--------------------+-----------------------------------------------------------+ - | ``fmax`` | Procedure returning the larger of two values | - +--------------------+-----------------------------------------------------------+ - | ``fmin`` | Procedure returning the smaller of two values | - +--------------------+-----------------------------------------------------------+ - | ``fma`` | Procedure returning the result of :math:`x \cdot y + z` | - +--------------------+-----------------------------------------------------------+ - | ``isgreater`` | Procedure returning whether :math:`x` is greater than | - | | :math:`y` | - +--------------------+-----------------------------------------------------------+ - | ``isgreaterequal`` | Procedure returning whether :math:`x` is greater than or | - | | equal to :math:`y` | - +--------------------+-----------------------------------------------------------+ - | ``isless`` | Procedure returning whether :math:`x` is less than | - | | :math:`y` | - +--------------------+-----------------------------------------------------------+ - | ``islessequal`` | Procedure returning whether :math:`x` is less than or | - | | equal to :math:`y` | - +--------------------+-----------------------------------------------------------+ - | ``islessgreater`` | Procedure returning whether :math:`x` is less or greater | - | | than :math:`y` | - +--------------------+-----------------------------------------------------------+ - | ``isunordered`` | Procedure returning whether the arguments are unordered | - | | (aka at least one is :math:`NaN`) | - +--------------------+-----------------------------------------------------------+ - | ``j0`` | Procedure returning the Bessel value of :math:`x` of the | - | | first kind of order :math:`0` | - +--------------------+-----------------------------------------------------------+ - | ``j1`` | Procedure returning the Bessel value of :math:`x` of the | - | | first kind of order :math:`1` | - +--------------------+-----------------------------------------------------------+ - | ``jn`` | Procedure returning the Bessel value of :math:`x` of the | - | | first kind of order :math:`n` | - +--------------------+-----------------------------------------------------------+ - | ``y0`` | Procedure returning the Bessel value of :math:`x` of the | - | | second kind of order :math:`0` | - +--------------------+-----------------------------------------------------------+ - | ``y1`` | Procedure returning the Bessel value of :math:`x` of the | - | | second kind of order :math:`1` | - +--------------------+-----------------------------------------------------------+ - | ``yn`` | Procedure returning the Bessel value of :math:`x` of the | - | | second kind of order :math:`n` | - +--------------------+-----------------------------------------------------------+ - -.. table:: List of all procedures in complex.h - :name: List of complex procedures - - +--------------------+-----------------------------------------------------------+ - | Procedure | Description | - +====================+===========================================================+ - | ``cacos`` | Procedure returning the complex trigonometric arccosine | - +--------------------+-----------------------------------------------------------+ - | ``casin`` | Procedure returning the complex trigonometric arcsine | - +--------------------+-----------------------------------------------------------+ - | ``catan`` | Procedure returning the complex trigonometric arctangent | - +--------------------+-----------------------------------------------------------+ - | ``ccos`` | Procedure returning the complex trigonometric cosine | - +--------------------+-----------------------------------------------------------+ - | ``csin`` | Procedure returning the complex trigonometric sine | - +--------------------+-----------------------------------------------------------+ - | ``ctan`` | Procedure returning the complex trigonometric tangent | - +--------------------+-----------------------------------------------------------+ - | ``cacosh`` | Procedure returning the complex hyperbolic arccosine | - +--------------------+-----------------------------------------------------------+ - | ``casinh`` | Procedure returning the complex hyperbolic arcsine | - +--------------------+-----------------------------------------------------------+ - | ``catanh`` | Procedure returning the complex hyperbolic arctangent | - +--------------------+-----------------------------------------------------------+ - | ``ccosh`` | Procedure returning the complex hyperbolic cosine | - +--------------------+-----------------------------------------------------------+ - | ``csinh`` | Procedure returning the complex hyperbolic sine | - +--------------------+-----------------------------------------------------------+ - | ``ctanh`` | Procedure returning the complex hyperbolic tangent | - +--------------------+-----------------------------------------------------------+ - | ``cexp`` | Procedure returning the complex base :math:`e` | - | | exponential of :math:`z` | - +--------------------+-----------------------------------------------------------+ - | ``clog`` | Procedure returning the complex natural logarithm | - +--------------------+-----------------------------------------------------------+ - | ``cabs`` | Procedure returning the complex absolute value | - +--------------------+-----------------------------------------------------------+ - | ``cpow`` | Procedure returning the complex value :math:`x` raised to | - | | the power of :math:`y` | - +--------------------+-----------------------------------------------------------+ - | ``csqrt`` | Procedure returning the complex square root | - +--------------------+-----------------------------------------------------------+ - | ``carg`` | Procedure returning the value of :math:`z` in the | - | | interval [:math:`-\pi`, :math:`+\pi`] | - +--------------------+-----------------------------------------------------------+ - | ``cimag`` | Procedure returning the imaginary part of the value of | - | | :math:`z` | - +--------------------+-----------------------------------------------------------+ - | ``CMPLX`` | Procedure returning the complex value with real part | - | | :math:`x` and imaginary part :math:`y` | - +--------------------+-----------------------------------------------------------+ - | ``conj`` | Procedure returning the complex conjugate value of | - | | :math:`z` | - +--------------------+-----------------------------------------------------------+ - | ``cproj`` | Procedure returning the value of the projection onto the | - | | Riemann sphere of :math:`z` | - +--------------------+-----------------------------------------------------------+ - | ``creal`` | Procedure returning the real part of the value of | - | | :math:`z` | - +--------------------+-----------------------------------------------------------+ - -Furthermore the library shall provide a number of constants, as such the following defines are to be added to ``math.h``: - -.. table:: List of all constant defines in math.h - :name: List of math constants - - ================ =============================================== - Name Description - ================ =============================================== - ``M_E`` Value of :math:`e` - ``M_LOG2E`` Value of :math:`log_{2} e` - ``M_LOG10E`` Value of :math:`log_{10} e` - ``M_LN2`` Value of :math:`log_e 2` - ``M_LN10`` Value of :math:`log_e 10` - ``M_PI`` Value of :math:`\pi` - ``M_PI_2`` Value of :math:`\frac{\pi}{2}` - ``M_PI_4`` Value of :math:`\frac{\pi}{4}` - ``M_1_PI`` Value of :math:`\frac{1}{\pi}` - ``M_2_PI`` Value of :math:`\frac{2}{\pi}` - ``M_2_SQRTPI`` Value of :math:`\frac{2}{\sqrt{\pi}}` - ``M_SQRT2`` Value of :math:`\sqrt{2}` - ``M_SQRT1_2`` Value of :math:`\sqrt{\frac{1}{2}}` - ``HUGE_VAL`` Value of :math:`+Inf` (double) - ``HUGE_VALF`` Value of :math:`+Inf` (float) - ``INFINITY`` Value of :math:`+Inf` - ``NAN`` Value of :math:`NaN` - ``MAXFLOAT`` Synonym of ``FLT_MAX`` - ``FP_INFINITE`` :math:`1` - ``FP_NAN`` :math:`0` - ``FP_NORMAL`` :math:`4` - ``FP_SUBNORMAL`` :math:`3` - ``FP_ZERO`` :math:`2` - ``FP_ILOGB0`` Value to return for :ref:`ilogb` (:math:`0`) - ``FP_ILOGBNAN`` Value to return for :ref:`ilogb` (:math:`NaN`) - ================ =============================================== - -*Remark:* Both ``INFINITY`` and ``NAN`` expand to floats or doubles depending on the context. - -Directory Structure and Naming Scheme -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. figure:: ../../figure/libmcs-static-architecture.png - :name: static-architecture - - Folder structure - -The :numref:`Fig. %s ` shows the planned directory and file structure for the ``libm``. As can be seen in the figure the main directory of the ``LibmCS`` will contain eight elements: - -- the library contents are in ``libm``, -- the licenses of all files are in ``LICENSES``, -- the combined license file for the library ``COPYING.md``, -- the credits to the main contributors are in ``CREDITS.md``, -- the explanations on how to contribute to the library are in ``CONTRIBUTING.md``, -- the ``configure`` script to configure the library, -- the ``Makefile`` to build the library, and finally -- there is a ``README.md`` containing general information about the library. - -The ``libm`` directory contains four types of subdirectories: - -- ``include``: This directory contains the header files available to the users. -- ``common``: This directory contains helper functionalities which are used by many library files, for example macros to easily switch between floating-point datums and their integer representation. -- ``math/complex/d/f/l/fe``: These directories contain the implementation files of the mathematical functions. They are named after the header file they cater to and a suffix for the type they contain. Possible suffixes are ``d`` for ``double``-type procedures, ``f`` for ``float``-type procedures, ``fe`` for ``float``-type procedures which use ``double``-type variables/procedures as part of their implementation (thus called ``float-extended``), and ``l`` for ``long double``-type procedures. Some procedures use multiple types for their inputs/outputs but usually have a proper place in this setup; refer to :ref:`Software Components Design – Aspects of Each Component` to see where each file is placed. These directories furthermore each contain an ``internal`` directory which will be used for internal functions which are used by multiple similar functions (e.g., range reduction functions for the trigonometric procedures). Internal functions which are only used by a single function will be placed in their parent function’s file. -- ``machine``: This directory is meant to be used for machine (hardware/toolchain) specific implementations of library functions. In this activity there will only be an example such that the user may include their own implementations for their machine. - -The ``LICENSES`` directory contains a file for each individual license used within the library. All library files contain an :ref:`SPDX `-license-identifier to refer to the licenses within this directory. - -.. figure:: ../../figure/libmcs-include-common.png - :name: include-common - - Folders include and common - -.. figure:: ../../figure/libmcs-real.png - :name: real-procedures - - Real procedures - -.. figure:: ../../figure/libmcs-complex.png - :name: complex-procedures - - Complex procedures - -The C-Functions directly representing a required procedure are named the same as the procedure (e.g., ``asin``, ``asinf``, ``asinl``). The same applies to their filenames with the exception of the ``double``-type versions which have an additional ``d`` suffix (e.g., ``asind.c``), and the ``float-extended``-type which add an ``e`` to the already existing ``f`` suffix. - -Internal procedures shall be named after the procedure they are mainly called by prefixed with a double underscore (e.g., ``__asin``). There is a bit more freedom in the case of multiple internal functions, but all should at least contain the double underscore prefix as well as the procedure name (in some cases it might make sense to use a conglomerate instead of a specific procedure e.g. use ``__trig_rempio2`` for the range reduction function for all trigonometric procedures). The same freedom is given for naming the files containing internal functions: the name should represent the content (e.g., ``trig.c`` contains the internal procedures used by both ``sin`` and ``cos`` as well as the range reduction function used by all three trigonometric functions). - -If the user were to add a separate implementation for a procedure, we suggest to add another suffix using an underscore (e.g., ``expd_table.c`` for a table based implementation of the ``exp`` procedure). Choosing between implementations should be done with changes to the ``Makefile``. diff --git a/libm/libmcs/doc/sdd/5_Software_Design/3_Software_Component_Design_General.rst b/libm/libmcs/doc/sdd/5_Software_Design/3_Software_Component_Design_General.rst deleted file mode 100644 index 93fdb24e..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/3_Software_Component_Design_General.rst +++ /dev/null @@ -1,112 +0,0 @@ -Software Components Design - General ------------------------------------- - -.. raw:: html - - - -fenv.h -~~~~~~ - -Due to requirement REQ-ML-8700: When compiling user software with ``fenv.h`` included the compiler shall throw an error and stop. To achieve this the file shall contain the preprocessing directive ``#error`` before any other statement with an additional message, that if the user removes this error he shall provide his own implementations of these procedures and be aware that they are not part of this qualification effort and need to be qualified separately. - -The library provides an ``fenv.c`` file in the ``libm/common`` directory which contains stub implementations for all ``fenv.h`` procedures which return an error value (:math:`-1`) in line with the ISO C18 standard :ref:`[RD03] `. - -tgmath.h -~~~~~~~~ - -Due to requirement REQ-ML-8800: When compiling user software with ``tgmath.h`` included the compiler shall throw an error and stop. To achieve this the file shall contain the preprocessing directive ``#error`` before any other statement with an additional message, that if the user removes this error he’s left to his own devices and he’s using a not qualified library. - -Long Double -~~~~~~~~~~~ - -The library is limited in that it only offers ``long double`` procedures when ``long double`` has the same size as ``double``. As such there will be no independent implementation of ``long double`` procedures, instead there will only be additional wrappers to call the ``double`` procedures. These wrappers are very simple in that they only have a call to their respective ``double`` version, accompanied by an ``#ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS``-structure, to only include the procedure if the preprocessor macro ``LIBMCS_LONG_DOUBLE_IS_64BITS`` is set. For example for ``acoshl``: - -.. code:: c - - #include - - #ifdef __LIBMCS_LONG_DOUBLE_IS_64BITS - long double acoshl (long double x) - { - return acosh(x); - } - #endif - -As all the ``long double`` procedures look the same there is no need to add them to :ref:`Software Components Design – Aspects of Each Component` individually. - -Handling of Subnormal Numbers -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Each of the procedures defined in ``math.h`` and ``complex.h`` shall enforce the behaviour of the :ref:`FPU ` regarding subnormal numbers if the preprocessor macro ``LIBMCS_FPU_DAZ`` is set (for example during the ``make`` call). This is done by multiplying all floating point input arguments with :math:`1.0` to force the compiler to move the argument into an :ref:`FPU ` register (care needs to be taken that the multiplication can not be thrown out by the compiler, for example by using a volatile variable to contain the :math:`1.0`). Depending on the :ref:`FPU `'s configuration copying a subnormal value into an :ref:`FPU ` register will either - -- set the register to zero (this would be :ref:`DAZ ` behaviour, and can for example be seen when using a GRFPU set to non-standard mode), -- produce an appropriate :ref:`FPU ` exception (for example a GRFPU without being set to the non-standard mode), -- set the register to the input argument in case the :ref:`FPU ` is able to handle subnormal inputs (for example a MEIKO FPU), -- or do whatever else the :ref:`FPU ` does in case of a subnormal input, - -thus enforcing the inherent behaviour of the :ref:`FPU ` to be represented by the library. - -No procedure shall be able to generate subnormal numbers if the preprocessor macro ``LIBMCS_FPU_DAZ`` is set on a platform that can not produce subnormals. When using the preprocessor macro it is up to the user to inhibit their platform if it is inherently able to produce subnormals. - -NaNs -~~~~ - -All procedures accept ``NaNs`` of both varieties, quiet and signaling, as valid inputs. In case the input is a signaling ``NaN``, an invalid operation exception will be raised by the :ref:`FPU ` (except for the procedures ``fabs`` and ``copysign``), and a quiet ``NaN`` will be returned (unless there is a special case that returns a result different to ``NaN``). - -The procedures will never produce a signaling ``NaN`` and only return quiet ``NaNs`` (except for the procedures ``fabs`` and ``copysign``). The procedures use the :ref:`FPU ` to generate :ref:`FPU ` native ``NaNs`` if ``NaNs`` need to be produced artificially. Trying to produce fixed ``NaNs`` would slow down the whole code since there would be a need to check everywhere and produce the *artificial* ``NaNs``. As the overall numerical code will anyways produce :ref:`FPU ` native ``NaNs``, it would also not help the reproducibility objective. - -In case any of the inputs of a procedure is ``NaN`` and the output also is a ``NaN``, the procedure does not necessarily return the (or one of the) input ``NaN`` but may produce a different one. - -The tables within this document will not differentiate between quiet and signaling ``NaNs`` as inputs as the behaviour is always the same. - -In some places of this document there will be ``NaNs`` accompanied by a sign, this is to symbolize that the signbit of the ``NaN`` is set or not to be used by the ``fabs`` and ``copysign`` procedures. - -Exceptions -~~~~~~~~~~ - -The library causes the :ref:`FPU ` to produce exceptions. Those exceptions are ``invalid operation``, ``divide-by-zero``, ``overflow``, ``underflow``, and ``inexact``. This :ref:`SDD ` details where the exceptions are intentionally produced but not when they appear during a mathematical operation within the procedure. A comprehensive list of all exceptions thrown by each procedure can be found in :ref:`Software Components Design – Aspects of Each Component`. - -Errno -~~~~~ - -The library does not set the ``errno`` variable to report errors. It is explicitly ignored and will not be defined or changed as to not interfere with the user using ``errno`` elsewhere in their project. - -Implementation Tricks -~~~~~~~~~~~~~~~~~~~~~ - -The implementation of the library employs a number of tricks to achieve the intended results. For example the following tricks are used: - -- ``if (huge+x>0) return x;`` is used to produce an ``inexact`` exception for ``x`` close to zero (``huge`` is a very large floating point number). Producing the exception is ``huge+x``, as ``huge`` is a lot larger than ``x`` and in turn the result cannot be an exact value, unless ``x`` is zero. This calculation is placed into an if-clause to ensure that the compiler may not remove the calculation during optimization. As this if-clause is always true, it creates an unreachable branch. This downside however is offset by producing the intended results. -- ``if (x is not finite) return x+x;`` is used when ``x`` is either infinite or ``NaN`` to return a same signed infinity or the ``NaN``. The addition is needed to create the ``invalid operation`` exception in the case a signaling ``NaN`` was used as input. -- ``if (x is not finite) return x-x;`` is used when ``x`` is either infinite or ``NaN`` to return ``NaN``. Subtracting two same signed infinity values produces a ``NaN`` as result as well as an ``invalid operation`` exception. -- ``return (x-x)/zero;`` is used to produce a ``NaN`` regardless of the input value. This statement also produces an ``invalid operation`` exception by dividing zero by zero (or in the case of an infinite ``x``, even earlier). -- ``return x/zero;`` is used to produce an infinity with the sign of ``x``. This statement also produces a ``divide-by-zero`` exception. This trick shall not be used when ``x`` is zero. diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0000_Software_Component_Design_Aspects_Of_Each_Component.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0000_Software_Component_Design_Aspects_Of_Each_Component.rst deleted file mode 100644 index 590ac382..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0000_Software_Component_Design_Aspects_Of_Each_Component.rst +++ /dev/null @@ -1,315 +0,0 @@ -Software Components Design – Aspects of Each Component ------------------------------------------------------- - -.. raw:: html - - - -Classification Macros -""""""""""""""""""""" - -.. toctree:: - :maxdepth: 1 - - 0010_fpclassify.rst - 0020_isfinite.rst - 0030_isinf.rst - 0040_isnan.rst - 0050_isnormal.rst - 0060_signbit.rst - -Trigonometric Functions -""""""""""""""""""""""" - -.. toctree:: - :maxdepth: 1 - - 0100_acos.rst - 0110_asin.rst - 0120_atan.rst - 0130_atan2.rst - 0140_cos.rst - 0150_sin.rst - 0160_tan.rst - 0170_trig.rst - -Hyperbolic Functions -"""""""""""""""""""" - -.. toctree:: - :maxdepth: 1 - - 0200_acosh.rst - 0210_asinh.rst - 0220_atanh.rst - 0230_cosh.rst - 0240_sinh.rst - 0250_tanh.rst - -Exponential and Logarithmic Functions -""""""""""""""""""""""""""""""""""""" - -.. toctree:: - :maxdepth: 1 - - 0300_exp.rst - 0310_exp2.rst - 0320_expm1.rst - 0330_frexp.rst - 0340_ilogb.rst - 0350_ldexp.rst - 0360_log.rst - 0370_log10.rst - 0380_log1p.rst - 0390_log2.rst - 0400_logb.rst - 0410_modf.rst - 0420_scalbn.rst - 0430_scalbln.rst - 0440_log_internal.rst - -Power and Absolute-value Functions -"""""""""""""""""""""""""""""""""" - -.. toctree:: - :maxdepth: 1 - - 0500_cbrt.rst - 0510_fabs.rst - 0520_hypot.rst - 0530_pow.rst - 0540_sqrt.rst - -Error and Gamma Functions -""""""""""""""""""""""""" - -.. toctree:: - :maxdepth: 1 - - 0600_erf.rst - 0610_erfc.rst - 0620_lgamma.rst - 0630_tgamma.rst - 0640_gamma_internal.rst - 0650_signgam.rst - -Nearest Integer Functions -""""""""""""""""""""""""" - -.. toctree:: - :maxdepth: 1 - - 0700_ceil.rst - 0710_floor.rst - 0720_nearbyint.rst - 0730_rint.rst - 0740_lrint.rst - 0750_llrint.rst - 0760_round.rst - 0770_lround.rst - 0780_llround.rst - 0790_trunc.rst - -Remainder Functions -""""""""""""""""""" - -.. toctree:: - :maxdepth: 1 - - 0900_fmod.rst - 0910_remainder.rst - 0920_remquo.rst - -Manipulation Functions -"""""""""""""""""""""" - -.. toctree:: - :maxdepth: 1 - - 1000_copysign.rst - 1010_nan.rst - 1020_nextafter.rst - 1030_nexttoward.rst - -Maximum, Minimum and Positive Difference Functions -"""""""""""""""""""""""""""""""""""""""""""""""""" - -.. toctree:: - :maxdepth: 1 - - 1100_fdim.rst - 1110_fmax.rst - 1120_fmin.rst - -Floating Multiply-Add -""""""""""""""""""""" - -.. toctree:: - :maxdepth: 1 - - 1200_fma.rst - -Comparison Macros -""""""""""""""""" - -.. toctree:: - :maxdepth: 1 - - 1300_isgreater.rst - 1310_isgreaterequal.rst - 1320_isless.rst - 1330_islessequal.rst - 1340_islessgreater.rst - 1350_isunordered.rst - -Bessel Functions (POSIX) -"""""""""""""""""""""""" - -.. toctree:: - :maxdepth: 1 - - 1400_j0.rst - 1410_j1.rst - 1420_jn.rst - 1430_y0.rst - 1440_y1.rst - 1450_yn.rst - -Complex Trigonometric Functions -""""""""""""""""""""""""""""""" - -.. toctree:: - :maxdepth: 1 - - 1500_cacos.rst - 1510_casin.rst - 1520_catan.rst - 1530_ccos.rst - 1540_csin.rst - 1550_ctan.rst - -Complex Hyperbolic Functions -"""""""""""""""""""""""""""" - -.. toctree:: - :maxdepth: 1 - - 1600_cacosh.rst - 1610_casinh.rst - 1620_catanh.rst - 1630_ccosh.rst - 1640_csinh.rst - 1650_ctanh.rst - -Complex Exponential and Logarithmic Functions -""""""""""""""""""""""""""""""""""""""""""""" - -.. toctree:: - :maxdepth: 1 - - 1700_cexp.rst - 1710_clog.rst - -Complex Power and Absolute-value Functions -"""""""""""""""""""""""""""""""""""""""""" - -.. toctree:: - :maxdepth: 1 - - 1800_cabs.rst - 1810_cpow.rst - 1820_csqrt.rst - -Complex Manipulation Functions -"""""""""""""""""""""""""""""" - -.. toctree:: - :maxdepth: 1 - - 1900_carg.rst - 1910_cimag.rst - 1920_cmplx.rst - 1930_conj.rst - 1940_cproj.rst - 1950_creal.rst - -Miscellaneous Internal Functions -"""""""""""""""""""""""""""""""" - -.. toctree:: - :maxdepth: 1 - - 2000_misc_internal.rst - -Build and Configuration Files -""""""""""""""""""""""""""""" - -.. toctree:: - :maxdepth: 1 - - 3000_configure.rst - 3100_makefile.rst diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0010_fpclassify.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0010_fpclassify.rst deleted file mode 100644 index b2272a8b..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0010_fpclassify.rst +++ /dev/null @@ -1,54 +0,0 @@ -fpclassify -~~~~~~~~~~ - -.. c:autodoc:: mathd/internal/fpclassifyd.c - -Special cases -^^^^^^^^^^^^^ - -+------------------------------+--------------------------+ -| x | Result | -+==============================+==========================+ -| :math:`±0` | ``FP_ZERO`` | -+------------------------------+--------------------------+ -| :math:`\in \mathbb{S}` | ``FP_SUBNORMAL`` | -+------------------------------+--------------------------+ -| :math:`±Inf` | ``FP_INFINITE`` | -+------------------------------+--------------------------+ -| :math:`NaN` | ``FP_NAN`` | -+------------------------------+--------------------------+ -| all others | ``FP_NORMAL`` | -+------------------------------+--------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -The approach is to call one of two internal procedures named ``__fpclassifyd`` or ``__fpclassifyf`` depending on the type of the input. These procedures follow the following approach: - -#. For :math:`x` is :math:`-0` or :math:`+0`, return ``FP_ZERO``. -#. For :math:`x` is finite and not subnormal, return ``FP_NORMAL``. -#. For :math:`x` is subnormal, return ``FP_SUBNORMAL``. -#. For :math:`x` is infinite (:math:`±Inf`), return ``FP_INFINITE``. -#. For :math:`x` is :math:`NaN`, return ``FP_NAN``. - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-5700 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/internal/fpclassifyd.c -* libm/mathf/internal/fpclassifyf.c - -References -^^^^^^^^^^ - -* :numref:`Tbl. %s ` -* :ref:`isfinite` -* :ref:`isinf` -* :ref:`isnan` -* :ref:`isnormal` -* :ref:`isunordered` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0020_isfinite.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0020_isfinite.rst deleted file mode 100644 index 312f7fd1..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0020_isfinite.rst +++ /dev/null @@ -1,34 +0,0 @@ -isfinite -~~~~~~~~ - -.. c:autodoc:: common/isfinite.c - -Special cases -^^^^^^^^^^^^^ - -This macro does not have special cases. - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -The approach is to call ``fpclassify`` and decide on the return value depending on the result: - -#. Call ``fpclassify`` with input :math:`x`, return :math:`0` if the call returned ``FP_INFINITE`` or ``FP_NAN``. -#. Else return :math:`1`. - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-1300 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/common/isfinite.c - -References -^^^^^^^^^^ - -* :ref:`fpclassify` -* :ref:`ldexp` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0030_isinf.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0030_isinf.rst deleted file mode 100644 index c102d926..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0030_isinf.rst +++ /dev/null @@ -1,34 +0,0 @@ -isinf -~~~~~ - -.. c:autodoc:: common/isinf.c - -Special cases -^^^^^^^^^^^^^ - -This macro does not have special cases. - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -The approach is to call ``fpclassify`` and decide on the return value depending on the result: - -#. Call ``fpclassify`` with input :math:`x`, return :math:`1` if the call returned ``FP_INFINITE``. -#. Else return :math:`0`. - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-1320 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/common/isinf.c - -References -^^^^^^^^^^ - -* :ref:`cproj` -* :ref:`fpclassify` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0040_isnan.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0040_isnan.rst deleted file mode 100644 index e9de3c80..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0040_isnan.rst +++ /dev/null @@ -1,34 +0,0 @@ -isnan -~~~~~ - -.. c:autodoc:: common/isnan.c - -Special cases -^^^^^^^^^^^^^ - -This macro does not have special cases. - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -The approach is to call ``fpclassify`` and decide on the return value depending on the result: - -#. Call ``fpclassify`` with input :math:`x`, return :math:`1` if the call returned ``FP_NAN``. -#. Else return :math:`0`. - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-1340 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/common/isnan.c - -References -^^^^^^^^^^ - -* :ref:`fpclassify` -* :ref:`nexttowardf ` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0050_isnormal.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0050_isnormal.rst deleted file mode 100644 index c8408640..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0050_isnormal.rst +++ /dev/null @@ -1,33 +0,0 @@ -isnormal -~~~~~~~~ - -.. c:autodoc:: common/isnormal.c - -Special cases -^^^^^^^^^^^^^ - -This macro does not have special cases. - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -The approach is to call ``fpclassify`` and decide on the return value depending on the result: - -#. Call ``fpclassify`` with input :math:`x`, return :math:`1` if the call returned ``FP_NORMAL``. -#. Else return :math:`0`. - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-5500 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/common/isnormal.c - -References -^^^^^^^^^^ - -* :ref:`fpclassify` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0060_signbit.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0060_signbit.rst deleted file mode 100644 index 7447c83c..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0060_signbit.rst +++ /dev/null @@ -1,34 +0,0 @@ -signbit -~~~~~~~ - -.. c:autodoc:: mathd/internal/signbitd.c - -Special cases -^^^^^^^^^^^^^ - -This macro does not have special cases. - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -The approach is to call one of two internal procedures named ``__signbitd`` or ``__signbitf`` depending on the type of the input. These procedures follow the following approach: - -#. Use a mask to get the sign bit of the input value. -#. If the sign bit is set, return :math:`1`, else return :math:`0`. - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-1360 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/internal/signbitd.c -* libm/mathf/internal/signbitf.c - -References -^^^^^^^^^^ - -* :ref:`nexttowardf ` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0100_acos.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0100_acos.rst deleted file mode 100644 index 7bb82944..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0100_acos.rst +++ /dev/null @@ -1,118 +0,0 @@ -acos -~~~~ - -.. c:autodoc:: mathd/acosd.c - -Special cases -^^^^^^^^^^^^^ - -+--------------------------+--------------------------+ -| x | Result | -+==========================+==========================+ -| :math:`+1` | :math:`+0` | -+--------------------------+--------------------------+ -| :math:`\notin [-1, 1]` | :math:`qNaN` | -+--------------------------+--------------------------+ -| :math:`±Inf` | :math:`qNaN` | -+--------------------------+--------------------------+ -| :math:`NaN` | :math:`qNaN` | -+--------------------------+--------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -The approach is to first work on special values and then use rational approximation for the calculation. - -The ``acos`` functionality is highly similar to the :ref:`asin` function, therefore it will be heavily referenced here even though it is not called. Assume all mentioned constants that are not expressed here, are taken from :ref:`asin`. - -Use the following constants as calculation/return values: - -* :math:`\pi \approx PI =` ``0x400921FB54442D18 (0x40490FDA)`` - -#. For :math:`x` is ``NaN``, return ``qNaN``. -#. For :math:`|x| > 1`, return ``qNaN``. -#. For :math:`x` is :math:`1`, return :math:`0`. -#. For :math:`x` is :math:`-1`, return :math:`PI`. -#. For :math:`|x| < 2^{-57}`, return :math:`pio2_{hi} + pio2_{lo}`. -#. All the following return values shall have the same sign as the input value. -#. The following identity provides the reason ``acos`` and :ref:`asin` are so closely related: - - .. math:: - :label: formula_acos_1 - - cos^{-1}(x) &= \frac{\pi}{2} - sin^{-1}(x) \\ - \wedge \qquad cos^{-1}(-x) &= \frac{\pi}{2} + sin^{-1}(x) - - #. For :math:`|x| < 0.5`: - - #. Using the identity shown in formula :math:numref:`formula_acos_1` and converting the approximation of :ref:`asin` shown in formula :math:numref:`formula_asin_2` to approximate ``acos`` as: - - .. math:: - :label: formula_acos_2 - - acos(x) = \frac{\pi}{2} - (x + x \cdot x^2 \cdot R(x^2)) - - #. Return [#]_ :math:`pio2_{hi} - (x - (pio2_{lo} - x \cdot R(x^2)))`. - - #. For the following steps use formula :math:numref:`formula_asin_4` to reduce the range. - #. For :math:`x <= -0.5`: - - \item With formula :math:numref:`formula_acos_1` and :math:numref:`formula_acos_2`, as well as applying the range reduction, the approximation of ``acos`` changes to: - - .. math:: - :label: formula_acos_3 - - acos(x) &= \pi - 2 \cdot (s + s \cdot z \cdot R(z)) \\ - &= PI - 2 \cdot (s+s \cdot z \cdot R(z) - pio2_{lo}) - - with - - #. :math:`z = \frac{1-|x|}{2}` - #. :math:`s = \sqrt{z}` - - #. Return the result of the approximation. - - #. Otherwise (:math:`x >= 0.5`): - - #. With formula :math:numref:`formula_acos_1` and :math:numref:`formula_acos_2`, as well as applying the range reduction, the approximation of ``acos`` changes to: - - .. math:: - :label: formula_acos_4 - - acos(x) &= \frac{\pi}{2} - \Big(\frac{\pi}{2} - 2 \cdot \big(s + s \cdot z \cdot R(z)\big)\Big) \\ - &= 2 \cdot (s + s \cdot z \cdot R(z)) \\ - &= 2s + 2s \cdot z \cdot R(z) \\ - &= (2f + 2c) + (2s \cdot z \cdot R(z)) \\ - &= 2 \cdot (f + (c + s \cdot z \cdot R(z))) - - with - - #. :math:`f =` ``highword`` of :math:`s` (float: :math:`f =` integer representation of :math:`s` with the last 12 bits masked to 0) - #. :math:`c = \frac{z-f^2}{s+f}`, which is the correction term for :math:`f` so that :math:`f+c \sim \sqrt{z}` - - #. Return the result of the approximation. - -.. [#] Formula :math:numref:`formula_acos_2` with some accuracy improvements - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-0450 -* REQ-ML-0460 -* REQ-ML-0470 -* REQ-ML-0480 -* REQ-ML-0490 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/mathd/acosd.c -* libm/mathf/mathf/acosf.c - -References -^^^^^^^^^^ - -* :ref:`asin` -* :ref:`cos` -* :ref:`sqrt` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0110_asin.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0110_asin.rst deleted file mode 100644 index fc2b070d..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0110_asin.rst +++ /dev/null @@ -1,136 +0,0 @@ -asin -~~~~ - -.. c:autodoc:: mathd/asind.c - -Special cases -^^^^^^^^^^^^^ - -+--------------------------+--------------------------+ -| x | Result | -+==========================+==========================+ -| :math:`±0` | :math:`x` | -+--------------------------+--------------------------+ -| :math:`\notin [-1, 1]` | :math:`qNaN` | -+--------------------------+--------------------------+ -| :math:`±Inf` | :math:`qNaN` | -+--------------------------+--------------------------+ -| :math:`NaN` | :math:`qNaN` | -+--------------------------+--------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -The approach is to first work on special values and then use rational approximation for the calculation. - -Use the following constants as calculation/return values: - -* :math:`\frac{\pi}{2} \approx pio2_{hi} + pio2_{lo}` -* :math:`pio2_{hi} =` ``0x3FF921FB54442D18 (0x3FC90FDB)`` -* :math:`pio2_{lo} =` ``0x3C91A62633145C07 (0xC08BE05E)`` -* :math:`pio4_{hi} = \frac{pio2_{hi}}{2} =` ``0x3FE921FB54442D18 (0x3F490FDB)`` -* :math:`P0 =` ``0x3FC5555555555555 (0x3E2AAAAB)`` -* :math:`P1 =` ``0xBFD4D61203EB6F7D (0xBEA6B090)`` -* :math:`P2 =` ``0x3FC9C1550E884455 (0x3E4E0AA8)`` -* :math:`P3 =` ``0xBFA48228B5688F3B (0xBD241146)`` -* :math:`P4 =` ``0x3F49EFE07501B288 (0x3A4F7F04)`` -* :math:`P5 =` ``0x3F023DE10DFDF709 (0x3811EF08)`` -* :math:`Q1 =` ``0xC0033A271C8A2D4B (0xC019D139)`` -* :math:`Q2 =` ``0x40002AE59C598AC8 (0x4001572D)`` -* :math:`Q3 =` ``0xBFE6066C1B8D0159 (0xBF303361)`` -* :math:`Q4 =` ``0x3FB3B8C5B12E9282 (0x3D9DC62E)`` - -#. For :math:`x` is ``NaN``, return ``qNaN``. -#. For :math:`|x| > 1`, return ``qNaN``. -#. For :math:`|x|` is :math:`1`, return :math:`x \cdot pio2_{hi} + x \cdot pio2_{lo}`. -#. For :math:`|x| < 2^{-57}`, return :math:`pio2_{hi} + pio2_{lo}`. -#. All the following return values shall have the same sign as the input value. -#. For :math:`|x| < 0.5` [#]_: - - #. Use the identity - - .. math:: - :label: formula_asin_1 - - sin^{-1}(x) &= x + \frac{1}{2} \frac{x^3}{3} + \frac{1 \cdot 3}{2 \cdot 4} \frac{x^5}{5} + ... \\ - &= \sum\limits_{i=0}^{\infty} \frac{\binom{2i}{i} \cdot x^{2i+1}}{4^i \cdot (2i+1)} - - to approximate ``asin`` as: - - .. math:: - :label: formula_asin_2 - - asin(x) &= x + x \cdot x^2 \cdot R(x^2) \nonumber \\ - R(x^2) &= \frac{asin(x)-x}{x^3} - - #. :math:`R(x^2)` can be rationally approximated with [#]_: - - .. math:: - :label: formula_asin_3 - - t &= x^2 \\ - R(t) &\sim \frac{P0 \cdot t + P1 \cdot t^2 + P2 \cdot t^3 + P3 \cdot t^4 + P4 \cdot t^5 + P5 \cdot t^6}{1 + Q1 \cdot t + Q2 \cdot t^2 + Q3 \cdot t^3 + Q4 \cdot t^4} - - The error of this approximation is smaller than :math:`2^{-58.75}`. - #. Return :math:`x + x \cdot R(t)`. - -#. Use the identity (set :math:`x = |x|`, use :ref:`fabs` to calculate the absolute value [#]_) - - .. math:: - :label: formula_asin_4 - - sin^{-1}(x) = \frac{\pi}{2} - 2 \cdot sin^{-1}\bigg(\sqrt{\frac{1-x}{2}}\bigg) - - for range reduction purposes. -#. Let :math:`y = (1-x)`, :math:`z = \frac{y}{2}`, :math:`s = \sqrt{z}`, and split :math:`\frac{\pi}{2}` into :math:`pio2_{hi}` and :math:`pio2_{lo}` for more accuracy, then: - - #. For :math:`|x| >= 0.975` [#]_, return - - .. math:: - :label: formula_asin_5 - - asin(x) &= \frac{\pi}{2} - 2 \cdot (s + s \cdot z \cdot R(z)) \\ - &= pio2_{hi} - (2 \cdot (s + s \cdot z \cdot R(z)) - pio2_{lo}) - - with - - #. :math:`R(z)` approximated as in :math:numref:`formula_asin_3`. - #. Use :ref:`sqrt` to calculate the square root of :math:`z`. - - #. Otherwise, let :math:`pio4_{hi} = \frac{pio2_{hi}}{2}`, :math:`f =` highword of :math:`s` (float: :math:`f =` integer representation of :math:`s` with the last 12 bits masked to 0), :math:`c = \sqrt{z} - f = \frac{z-f^2}{s+f}`, then return - - .. math:: - :label: formula_asin_6 - - asin(x) &= \frac{\pi}{2} - 2 \cdot (s + s \cdot z \cdot R(z)) \\ - &= pio4_{hi} + (pio4_{hi} - 2s) - (2 \cdot s \cdot z \cdot R(z) - pio2_{lo}) \\ - &= pio4_{hi} - \Big(\big(2 \cdot s \cdot z \cdot R(z) - (pio2_{lo}+2c)\big) - (pio4_{hi} - 2f)\Big) - -.. [#] This implementation of ``asin`` is a variation of the algorithm proposed by W. J. Cody, Jr. and W. Waite in *Software Manual for the Elementary Functions*. -.. [#] Use Horner's method for implementation. -.. [#] Remember that the final results still have the same sign as the initial :math:`x`! -.. [#] Use ``highword`` :math:`>=` ``0x3FEF3333`` (float: use integer representation of :math:`x >=` ``0x3F79999A``). - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-0250 -* REQ-ML-0260 -* REQ-ML-0270 -* REQ-ML-0280 -* REQ-ML-0281 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/asind.c -* libm/mathf/asinf.c - -References -^^^^^^^^^^ - -* :ref:`acos` -* :ref:`fabs` -* :ref:`sin` -* :ref:`sqrt` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0120_atan.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0120_atan.rst deleted file mode 100644 index bc43dc71..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0120_atan.rst +++ /dev/null @@ -1,145 +0,0 @@ -atan -~~~~ - -.. c:autodoc:: mathd/atand.c - -Special cases -^^^^^^^^^^^^^ - -+--------------------------+--------------------------+ -| x | Result | -+==========================+==========================+ -| :math:`±0` | :math:`x` | -+--------------------------+--------------------------+ -| :math:`-Inf` | :math:`-\frac{\pi}{2}` | -+--------------------------+--------------------------+ -| :math:`+Inf` | :math:`+\frac{\pi}{2}` | -+--------------------------+--------------------------+ -| :math:`NaN` | :math:`qNaN` | -+--------------------------+--------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -The approach is to first work on special values and then use rational approximation for the calculation. - -Use the following constants as calculation/return values: - -* :math:`tan^{-1}(0.5) \approx atan0.5_{hi} + atan0.5_{lo}` -* :math:`atan0.5_{hi} =` ``0x3FDDAC670561BB4F (0x3EED6338)`` -* :math:`atan0.5_{lo} =` ``0x3C7A2B7F222F65E2 (0x31AC3769)`` -* :math:`tan^{-1}(1) = \frac{\pi}{4} \approx atan1_{hi} + atan1_{lo}` -* :math:`atan1_{hi} =` ``0x3FE921FB54442D18 (0x3F490FDA)`` -* :math:`atan1_{lo} =` ``0x3C81A62633145C07 (0x33222168)`` -* :math:`tan^{-1}(1.5) \approx atan1.5_{hi} + atan1.5_{lo}` -* :math:`atan1.5_{hi} =` ``0x3FEF730BD281F69B (0x3F7B985E)`` -* :math:`atan1.5_{lo} =` ``0x3C7007887AF0CBBD (0x33140FB4)`` -* :math:`\lim\limits_{n \rightarrow \infty}tan^{-1}(n) = \frac{\pi}{2} \approx atanInf_{hi} + atanInf_{lo}` -* :math:`atanInf_{hi} =` ``0x3FF921FB54442D18 (0x3FC90FDA)`` -* :math:`atanInf_{lo} =` ``0x3C91A62633145C07 (0x33A22168)`` -* :math:`A0 =` ``0x3FD555555555550D (0x3EAAAAAA)`` -* :math:`A1 =` ``0xBFC999999998EBC4 (0xBE4CCCCD)`` -* :math:`A2 =` ``0x3FC24924920083FF (0x3E124925)`` -* :math:`A3 =` ``0xBFBC71C6FE231671 (0xBDE38E38)`` -* :math:`A4 =` ``0x3FB745CDC54C206E (0x3DBA2E6E)`` -* :math:`A5 =` ``0xBFB3B0F2AF749A6D (0xBD9D8795)`` -* :math:`A6 =` ``0x3FB10D66A0D03D51 (0x3D886B35)`` -* :math:`A7 =` ``0xBFADDE2D52DEFD9A (0xBD6EF16B)`` -* :math:`A8 =` ``0x3FA97B4B24760DEB (0x3D4BDA59)`` -* :math:`A9 =` ``0xBFA2B4442C6A6C2F (0xBD15A221)`` -* :math:`A10 =` ``0x3F90AD3AE322DA11 (0x3C8569D7)`` - -#. For :math:`x` is ``NaN``, return ``qNaN``. -#. For :math:`|x| > 2^{66}` (float: :math:`|x| > 2^{34}`), return :math:`atanInf_{hi} + atanInf_{lo}` (which represents :math:`\frac{\pi}{2}`) with the sign of :math:`x`. -#. For :math:`|x| < 2^{-27}`, return :math:`x`. -#. Use the identity :math:`tan^{-1}(x) = -tan^{-1}(-x)` to reduce :math:`x` to positive. -#. For :math:`x < \frac{7}{16}` [#]_, use the identity - - .. math:: - :label: formula_atan_1 - - tan^{-1}(x) &= x - \frac{x^3}{3} + \frac{x^5}{5} - \frac{x^7}{7} + ... \\ - &= \sum\limits_{i=0}^{\infty} \frac{(-1)^i \cdot x^{2i+1}}{2i+1} - - to approximate ``atan`` rationally as [#]_: - - .. math:: - :label: formula_atan_2 - - atan(x) = & x - x \cdot R(x) \\ - R(x) = & A0 \cdot x^2 - A1 \cdot x^4 + A2 \cdot x^6 - A3 \cdot x^8 + A4 \cdot x^{10} - A5 \cdot x^{12} \\ - &+ A6 \cdot x^{14} - A7 \cdot x^{16} + A8 \cdot x^{18} - A9 \cdot x^{20} + A10 \cdot x^{22} - -#. If :math:`x < \frac{11}{16}` [#]_, use the identity :math:`tan^{-1}(x) = tan^{-1}(\frac{1}{2}) + tan^{-1}(\frac{x-\frac{1}{2}}{1+\frac{x}{2}})` to modify the approximation of ``atan`` as in formula :math:numref:`formula_atan_2` to: - - .. math:: - :label: formula_atan_3 - - z &= \frac{2x - 1}{2 + x} \\ - atan(x) &= tan^{-1}\Big(\frac{1}{2}\Big) + (z - z \cdot R(z)) \\ - &= atan0.5_{hi} - ((z \cdot R(z) - atan0.5_{lo}) - z) - -#. If :math:`x < \frac{19}{16}` [#]_, use the identity :math:`tan^{-1}(x) = tan^{-1}(1) + tan^{-1}(\frac{x-1}{1+x}) = \frac{\pi}{4} + tan^{-1}(\frac{x-1}{1+x})` to modify the approximation of ``atan`` to: - - .. math:: - :label: formula_atan_4 - - z &= \frac{x - 1}{x + 1} \\ - atan(x) &= \frac{\pi}{4} + (z - z \cdot R(z)) \\ - &= atan1_{hi} - ((z \cdot R(z) - atan1_{lo}) - z) - -#. If :math:`x < \frac{39}{16}` [#]_, use the identity :math:`tan^{-1}(x) = tan^{-1}(\frac{3}{2}) + tan^{-1}(\frac{x-\frac{3}{2}}{1+\frac{3}{2}x})` to modify the approximation of ``atan`` to: - - .. math:: - :label: formula_atan_5 - - z &= \frac{2x-3}{2+3x} \\ - atan(x) &= tan^{-1}\Big(\frac{3}{2}\Big) + (z - z \cdot R(z)) \\ - &= atan1.5_{hi} - ((z \cdot R(z) - atan1.5_{lo}) - z) - -#. Otherwise (:math:`x >= \frac{39}{16}`), use the identity :math:`tan^{-1}(x) = \lim\limits_{n \rightarrow \infty}(tan^{-1}(n)) + tan^{-1}(-\frac{1}{x}) = \frac{\pi}{2} + tan^{-1}(-\frac{1}{x})` to modify the approximation of ``atan`` to: - - .. math:: - :label: formula_atan_6 - - z &= -\frac{1}{x} \\ - atan(x) &= \frac{\pi}{2} + (z - z \cdot R(z)) \\ - &= atanInf_{hi} - ((z \cdot R(z) - atanInf_{lo}) - z) - -#. Return the result of the appropriate approximation, with the sign of the original input value. - -.. raw:: html - - - -.. [#] Test with ``highword`` :math:`<` ``0x3FDC0000``. (float: use integer representation of :math:`x >=` ``0x3EE00000``). -.. [#] Use Horner's method for implementation. -.. [#] Test with ``highword`` :math:`<` ``0x3FE60000``. (float: use integer representation of :math:`x >=` ``0x3F300000``). -.. [#] Test with ``highword`` :math:`<` ``0x3FF30000``. (float: use integer representation of :math:`x >=` ``0x3F980000``). -.. [#] Test with ``highword`` :math:`<` ``0x40038000``. (float: use integer representation of :math:`x >=` ``0x401C0000``). - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-0600 -* REQ-ML-0610 -* REQ-ML-0620 -* REQ-ML-0621 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/atand.c -* libm/mathf/atanf.c - -References -^^^^^^^^^^ - -* :ref:`atan2` -* :ref:`fabs` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0130_atan2.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0130_atan2.rst deleted file mode 100644 index 8fc546c7..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0130_atan2.rst +++ /dev/null @@ -1,139 +0,0 @@ -atan2 -~~~~~ - -.. c:autodoc:: mathd/atan2d.c - -Special cases -^^^^^^^^^^^^^ - -+------------------------+------------------------------+--------------------------+ -| x | y | Result | -+========================+==============================+==========================+ -| :math:`<0` | :math:`-0` | :math:`-\pi` | -+------------------------+------------------------------+--------------------------+ -| :math:`<0` | :math:`+0` | :math:`+\pi` | -+------------------------+------------------------------+--------------------------+ -| :math:`-0` | :math:`-0` | :math:`-\pi` | -+------------------------+------------------------------+--------------------------+ -| :math:`-0` | :math:`+0` | :math:`+\pi` | -+------------------------+------------------------------+--------------------------+ -| :math:`±0` | :math:`<0` | :math:`-\frac{\pi}{2}` | -+------------------------+------------------------------+--------------------------+ -| :math:`±0` | :math:`>0` | :math:`+\frac{\pi}{2}` | -+------------------------+------------------------------+--------------------------+ -| :math:`+0` | :math:`-0` | :math:`-0` | -+------------------------+------------------------------+--------------------------+ -| :math:`+0` | :math:`+0` | :math:`+0` | -+------------------------+------------------------------+--------------------------+ -| :math:`>0` | :math:`-0` | :math:`-0` | -+------------------------+------------------------------+--------------------------+ -| :math:`>0` | :math:`+0` | :math:`+0` | -+------------------------+------------------------------+--------------------------+ -| :math:`-Inf` | :math:`<0 \wedge \neq -Inf` | :math:`-\pi` | -+------------------------+------------------------------+--------------------------+ -| :math:`-Inf` | :math:`>0 \wedge \neq +Inf` | :math:`+\pi` | -+------------------------+------------------------------+--------------------------+ -| :math:`+Inf` | :math:`<0 \wedge \neq -Inf` | :math:`-0` | -+------------------------+------------------------------+--------------------------+ -| :math:`+Inf` | :math:`>0 \wedge \neq +Inf` | :math:`+0` | -+------------------------+------------------------------+--------------------------+ -| :math:`\neq ±Inf` | :math:`-Inf` | :math:`-\frac{\pi}{2}` | -+------------------------+------------------------------+--------------------------+ -| :math:`\neq ±Inf` | :math:`+Inf` | :math:`+\frac{\pi}{2}` | -+------------------------+------------------------------+--------------------------+ -| :math:`-Inf` | :math:`-Inf` | :math:`-\frac{3 \pi}{4}` | -+------------------------+------------------------------+--------------------------+ -| :math:`-Inf` | :math:`+Inf` | :math:`+\frac{3 \pi}{4}` | -+------------------------+------------------------------+--------------------------+ -| :math:`+Inf` | :math:`-Inf` | :math:`-\frac{\pi}{4}` | -+------------------------+------------------------------+--------------------------+ -| :math:`+Inf` | :math:`+Inf` | :math:`+\frac{\pi}{4}` | -+------------------------+------------------------------+--------------------------+ -| :math:`NaN` | :math:`\in \mathbb{F}` | :math:`qNaN` | -+------------------------+------------------------------+--------------------------+ -| :math:`\in \mathbb{F}` | :math:`NaN` | :math:`qNaN` | -+------------------------+------------------------------+--------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -The approach is to first work on special values and then use :ref:`atan` for the calculation. - -Use the following constants as calculation/return values: - -* :math:`\pi \approx PI + PI_{lo}` -* :math:`PI =` ``0x400921FB54442D18 (0x40490FDB)`` -* :math:`PI_{lo} =` ``0x3CA1A62633145C07 (0xB3BBBD2E)`` -* :math:`\frac{\pi}{2} \approx PIo2 =` ``0x3FF921FB54442D18 (0x3FC90FDB)`` -* :math:`\frac{\pi}{4} \approx PIo4 =` ``0x3FE921FB54442D18 (0x3F490FDB)`` - -#. For :math:`x` or :math:`y` is ``NaN``, return ``qNaN``. -#. For :math:`x==1.0`, return :ref:`atan`:math:`(\frac{y}{x})`. -#. Create :math:`m` to contain the sign bits of both input values for later use: :math:`m = 2 \cdot sign_x + sign_y`. :math:`m` can have values from :math:`0` to :math:`3`. -#. For :math:`y` is zero: - - #. For :math:`m<=1`, return :math:`y`. - #. For :math:`m==2`, return :math:`PI`. - #. For :math:`m==3` (which is the only remaining option), return :math:`-PI`. - -#. For :math:`x` is zero, return :math:`PIo2` with sign of :math:`y`. -#. For :math:`x` is infinite: - - #. For :math:`y` is infinite: - - #. For :math:`m==0`, return :math:`PIo4`. - #. For :math:`m==1`, return :math:`-PIo4`. - #. For :math:`m==2`, return :math:`3 \cdot PIo4`. - #. For :math:`m==3`, return :math:`-3 \cdot PIo4`. - - #. For :math:`m==0`, return :math:`+0`. - #. For :math:`m==1`, return :math:`-0`. - #. For :math:`m==2`, return :math:`PI`. - #. For :math:`m==3`, return :math:`-PI`. - -#. For :math:`y` is infinite, return :math:`PIo2` with sign of :math:`y`. -#. For :math:`|\frac{y}{x}|>2^{60}` (float: :math:`|\frac{y}{x}|>2^{26}`), create :math:`z = PIo2 + 0.5 \cdot PI_{lo}` and mask off all but the last bit of :math:`m`. Else: - - #. For :math:`\frac{|y|}{x}<-2^{-60}` (float: :math:`\frac{|y|}{x}<-2^{-26}`), create :math:`z = 0` [#]_. - #. Else create :math:`z = tan^{-1}|\frac{y}{x}|`, using the procedures :ref:`atan` and :ref:`fabs`. - -#. For :math:`m==0`, return :math:`z`. -#. For :math:`m==1`, return :math:`-z`. -#. For :math:`m==2`, return :math:`PI - (z - PI_{lo})`. -#. For :math:`m==3`, return :math:`(z - PI_{lo}) - PI`. - -.. [#] This is an optimization which omits the call to :ref:`atan` and :ref:`fabs` as the result is so much smaller than :math:`PI` that the result has no significance to the final result (as :math:`m` can only be :math:`2` or :math:`3` for negative :math:`x`). - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-0650 -* REQ-ML-0652 -* REQ-ML-0660 -* REQ-ML-0661 -* REQ-ML-0662 -* REQ-ML-0663 -* REQ-ML-0670 -* REQ-ML-0680 -* REQ-ML-0681 -* REQ-ML-0682 -* REQ-ML-0683 -* REQ-ML-0684 -* REQ-ML-0685 -* REQ-ML-0686 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/atan2d.c -* libm/mathf/atan2f.c - -References -^^^^^^^^^^ - -* :ref:`atan` -* :ref:`carg` -* :ref:`catan` -* :ref:`clog` -* :ref:`fabs` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0140_cos.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0140_cos.rst deleted file mode 100644 index 2286e955..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0140_cos.rst +++ /dev/null @@ -1,85 +0,0 @@ -cos -~~~ - -.. c:autodoc:: mathd/cosd.c - -Special cases -^^^^^^^^^^^^^ - -+--------------------------+--------------------------+ -| x | Result | -+==========================+==========================+ -| :math:`±0` | :math:`1` | -+--------------------------+--------------------------+ -| :math:`±Inf` | :math:`qNaN` | -+--------------------------+--------------------------+ -| :math:`NaN` | :math:`qNaN` | -+--------------------------+--------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -The ``cos`` functionality is highly similar to the :ref:`sin` function, therefore both of them use the same :ref:`internal_trig`. - -The approach is to first work on special values, reduce the range of the input value to :math:`\left[-\frac{\pi}{4},\frac{\pi}{4}\right]` and then use :ref:`__cos ` and :ref:`__sin ` for the actual calculation. - -The input value :math:`x` is interpreted in radians. - -#. For :math:`x` is :math:`NaN` or infinite, return :math:`qNaN`. -#. If the input argument is already within the range :math:`\left[-\frac{\pi}{4},\frac{\pi}{4}\right]`: - - #. If the input argument is smaller than :math:`2^{-27}` (float: :math:`2^{-12}`), return :math:`1`. - #. Otherwise use :ref:`__cos `. - -#. The input value :math:`x` is reduced to the range :math:`\left[-\frac{\pi}{4},\frac{\pi}{4}\right]` by using the function :ref:`__rem_pio2 `. -#. The return value is computed according to the last two bits of the return value :math:`n` of :ref:`__rem_pio2 ` (count :math:`n` of reminded :math:`\frac{\pi}{2}`): - -+-----------------------------------------+-----------------------------------------+ -| last two bits of :math:`n` | Return | -+=========================================+=========================================+ -| ``00`` | :ref:`__cos ` | -+-----------------------------------------+-----------------------------------------+ -| ``01`` | :math:`-` :ref:`__sin ` | -+-----------------------------------------+-----------------------------------------+ -| ``10`` | :math:`-` :ref:`__cos ` | -+-----------------------------------------+-----------------------------------------+ -| ``11`` | :ref:`__sin ` | -+-----------------------------------------+-----------------------------------------+ - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-0300 -* REQ-ML-0310 -* REQ-ML-0320 -* REQ-ML-0330 - - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/cosd.c -* libm/mathf/cosf.c - -References -^^^^^^^^^^ - -* :ref:`__cos ` -* :ref:`__rem_pio2 ` -* :ref:`__sin ` -* :ref:`acos` -* :ref:`ccos` -* :ref:`ccosh` -* :ref:`cexp` -* :ref:`cpow` -* :ref:`csinh` -* :ref:`ctan` -* :ref:`ctanh` -* :ref:`j0` -* :ref:`j1` -* :ref:`jn` -* :ref:`sin` -* :ref:`y0` -* :ref:`y1` -* :ref:`yn` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0150_sin.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0150_sin.rst deleted file mode 100644 index 35b57c40..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0150_sin.rst +++ /dev/null @@ -1,83 +0,0 @@ -sin -~~~ - -.. c:autodoc:: mathd/sind.c - -Special cases -^^^^^^^^^^^^^ - -+--------------------------+--------------------------+ -| x | Result | -+==========================+==========================+ -| :math:`±0` | :math:`x` | -+--------------------------+--------------------------+ -| :math:`±Inf` | :math:`qNaN` | -+--------------------------+--------------------------+ -| :math:`NaN` | :math:`qNaN` | -+--------------------------+--------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -The ``sin`` functionality is highly similar to the :ref:`cos` function, therefore both of them use the same :ref:`internal_trig`. - -The approach is to first work on special values, reduce the range of the input value to :math:`\left[-\frac{\pi}{4},\frac{\pi}{4}\right]` and then use :ref:`__cos ` and :ref:`__sin ` for the actual calculation. - -The input value :math:`x` is interpreted in radians. - -#. For :math:`x` is :math:`NaN` or infinite, return :math:`qNaN`. -#. If the input argument is already within the range :math:`\left[-\frac{\pi}{4},\frac{\pi}{4}\right]`: - - #. If the input argument is smaller than :math:`2^{-26}` (float: :math:`2^{-13}`), return :math:`x`. - #. Otherwise use :ref:`__sin `. - -#. The input value :math:`x` is reduced to the range :math:`\left[-\frac{\pi}{4},\frac{\pi}{4}\right]` by using the function :ref:`__rem_pio2 `. -#. The return value is computed according to the last two bits of the return value :math:`n` of :ref:`__rem_pio2 ` (count :math:`n` of reminded :math:`\frac{\pi}{2}`): - -+-----------------------------------------+-----------------------------------------+ -| last two bits of :math:`n` | Return | -+=========================================+=========================================+ -| ``00`` | :ref:`__sin ` | -+-----------------------------------------+-----------------------------------------+ -| ``01`` | :ref:`__cos ` | -+-----------------------------------------+-----------------------------------------+ -| ``10`` | :math:`-` :ref:`__sin ` | -+-----------------------------------------+-----------------------------------------+ -| ``11`` | :math:`-` :ref:`__cos ` | -+-----------------------------------------+-----------------------------------------+ - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-0200 -* REQ-ML-0210 -* REQ-ML-0220 -* REQ-ML-0240 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/sind.c -* libm/mathf/sinf.c - -References -^^^^^^^^^^ - -* :ref:`__cos ` -* :ref:`__rem_pio2 ` -* :ref:`__sin ` -* :ref:`asin` -* :ref:`ccosh` -* :ref:`cexp` -* :ref:`cpow` -* :ref:`cos` -* :ref:`csin` -* :ref:`csinh` -* :ref:`ctan` -* :ref:`j0` -* :ref:`j1` -* :ref:`jn` -* :ref:`y0` -* :ref:`y1` -* :ref:`yn` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0160_tan.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0160_tan.rst deleted file mode 100644 index 81d7e42f..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0160_tan.rst +++ /dev/null @@ -1,162 +0,0 @@ -tan -~~~ - -.. c:autodoc:: mathd/tand.c - -Special cases -^^^^^^^^^^^^^ - -+--------------------------+--------------------------+ -| x | Result | -+==========================+==========================+ -| :math:`±0` | :math:`x` | -+--------------------------+--------------------------+ -| :math:`±Inf` | :math:`qNaN` | -+--------------------------+--------------------------+ -| :math:`NaN` | :math:`qNaN` | -+--------------------------+--------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -``tan``: The ``tan`` functionality is similar to the :ref:`cos` and :ref:`sin` functions in that they use the same range reduction function from :ref:`internal_trig`. - -The approach is to first work on special values, reduce the range of the input value to :math:`\left[-\frac{\pi}{4},\frac{\pi}{4}\right]` and then use ``__tan`` for the actual calculation. - -The input value :math:`x` is interpreted in radians. - -#. If the input argument is already within the range :math:`\left[-\frac{\pi}{4},\frac{\pi}{4}\right]`: - - #. If the input argument is smaller than :math:`2^{-27}` (float: :math:`2^{-12}`), return :math:`x`. - #. Otherwise use ``__tan``. - -#. For :math:`x` is :math:`NaN` or infinite, return :math:`qNaN`. -#. The input value :math:`x` is reduced to the range :math:`\left[-\frac{\pi}{4},\frac{\pi}{4}\right]` by using the function :ref:`__rem_pio2 `. Save the return value as :math:`n`. -#. For :math:`n` is even, return the result of ``__tan`` with the third input set to :math:`1`. -#. Else, return the result of ``__tan`` with the third input set to :math:`-1`. - --------------------------- - -``__tan``: The approach is to use a polynomial approximation for the calculation. - -Use the following constants as calculation/return values: - -* :math:`\frac{\pi}{4} \approx pio4 + pio4_{lo}` -* :math:`pio4 =` ``0x3FE921FB54442D18 (0x3F490FDA)`` -* :math:`pio4_{lo} =` ``0x3C81A62633145C07 (0x33222168)`` -* :math:`T0 =` ``0x3FC5555555555555 (0x3EAAAAAB)`` :math:`\approx \frac{1}{3}` -* :math:`T1 =` ``0x3FC111111110FE7A (0x3E088889)`` :math:`\approx \frac{2}{15}` -* :math:`T2 =` ``0x3FABA1BA1BB341FE (0x3D5D0DD1)`` :math:`\approx \frac{17}{315}` -* :math:`T3 =` ``0x3F9664F48406D637 (0x3CB327A4)`` :math:`\approx ...` -* :math:`T4 =` ``0x3F8226E3E96E8493 (0x3C11371F)`` -* :math:`T5 =` ``0x3F6D6D22C9560328 (0x3B6B6916)`` -* :math:`T6 =` ``0x3F57DBC8FEE08315 (0x3ABEDE48)`` -* :math:`T7 =` ``0x3F4344D8F2F26501 (0x3A1A26C8)`` -* :math:`T8 =` ``0x3F3026F71A8D1068 (0x398137B9)`` -* :math:`T9 =` ``0x3F147E88A03792A6 (0x38A3F445)`` -* :math:`T10 =` ``0x3F12B80F32F0A7E9 (0x3895C07A)`` -* :math:`T11 =` ``0xBEF375CBDB605373 (0xB79BAE5F)`` -* :math:`T12 =` ``0x3EFB2A7074BF7AD4 (0x37D95384)`` - -#. The identity :math:`tan(-x) = -tan(x)` can be used to reduce :math:`x` to positive. -#. The tangent of an argument can be calculated with: - - .. math:: - :label: formula_tan_1 - - tan(x) &= x + \frac{1}{3}x^3 + \frac{2}{15}x^5 + \frac{17}{315}x^7 + ... \\ - &= \sum\limits_{i=1}^{\infty} \frac{(-1)^{i-1} \cdot 2^{2i} \cdot (2^{2i}-1) \cdot B_{2i} \cdot x^{2i-1}}{(2i)!} - - with :math:`B_{n}` being the :math:`n`-th Bernoulli number. -#. If :math:`|x| < 0.67434` [#]_: - - #. Use a polynomial approximation of formula :math:numref:`formula_tan_1` to calculate the tangent [#]_: - - .. math:: - :label: formula_tan_2 - - tan(x) \sim x \cdot (T0 \cdot x + T1 \cdot x^3 + T2 \cdot x^5 + ... + T12 \cdot x^{27}) - - #. To increase the accuracy make use of the identity - - .. math:: - :label: formula_tan_3 - - tan(x+y) &= tan(x) + tan'(x) \cdot y \\ - &\sim tan(x) + (1+ x^2) \cdot y - - to change the approximation to: - - .. math:: - :label: formula_tan_4 - - r(x) &= x^3 \cdot (T1 + x \cdot (T2 + x \cdot (... + x \cdot (T11 + x \cdot T12)))) \\ - R(x) &= T0 \cdot x^3 + (x^2 \cdot (r(x)+y) +y) \\ - tan(x+y) &= x + R(x) - - #. If :math:`k` is :math:`1`, return the result of the approximation. - #. Return :math:`-\frac{1}{tan(x+y)}`, to not loose precision on this arithmetic operation, use this formula to create the return value: - - .. math:: - :label: formula_tan_5 - - -\frac{1}{tan(x+y)} = t + a \cdot (s + t \cdot v) - - with - - #. :math:`z = tan(x+y)` with the ``lowword`` masked to zero (float: last 12 bits of the integer representation masked to zero). - #. :math:`v = R(x) - (z - x)`. - #. :math:`a = -\frac{1}{tan(x+y)}`. - #. :math:`t = a` with the ``lowword`` masked to zero (float: last 12 bits of the integer representation masked to zero). - #. :math:`s = 1 + t \cdot z`. - -#. As the approximation in formula :math:numref:`formula_tan_2` is only reliable for :math:`|x| < 0.67434`, make use of the identity - - .. math:: - :label: formula_tan_6 - - tan(x) &= tan\bigg(\frac{\pi}{4}-f\bigg) \\ - &= \frac{1-tan(f)}{1+tan(f)} \\ - &= 1-2 \cdot \bigg(tan(f) - \frac{tan(f)^2}{1+tan(f)}\bigg) - - with - - #. If :math:`x` is negative, replace :math:`x` with :math:`x = -x`` and :math:`y` with :math:`y = -y`. - #. :math:`f = \frac{\pi}{4} - x`. - - to change the approximation of the tangent. -#. Let :math:`f = \frac{\pi}{4} - x = PIo4 - x + (PIo4_{lo} - y)`. -#. Calculate :math:`tan(f)` as in formula :math:numref:`formula_tan_4`, with :math:`x = f` and :math:`y = 0`. -#. Use formula :math:numref:`formula_tan_6` to calculate :math:`tan(x)`: - - .. math:: - :label: formula_tan_7 - - tan(x) = k - 2 \cdot \bigg(f-\Big(\frac{tan(f)^2}{tan(f)+k}-R(f)\Big)\bigg) - -#. Return :math:`tan(x)` with the sign of the original :math:`x`. - -.. [#] Use ``highword`` :math:`<` ``0x3FE59428`` (float: use integer representation of :math:`x <` ``0x3F2CA140``). -.. [#] The error of this approximation is less than :math:`2^{-59.2}`. - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-0500 -* REQ-ML-0520 -* REQ-ML-0530 -* REQ-ML-0550 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/tand.c -* libm/mathf/tanf.c - -References -^^^^^^^^^^ - -* :ref:`__rem_pio2 ` -* :ref:`cos` -* :ref:`sin` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0170_trig.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0170_trig.rst deleted file mode 100644 index c4258060..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0170_trig.rst +++ /dev/null @@ -1,191 +0,0 @@ -.. _internal_trig: - -Internal Trigonometric Functions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. c:autodoc:: mathd/internal/trigd.c - -Special cases -^^^^^^^^^^^^^ - -The special cases are in the respective external functions :ref:`cos` and :ref:`sin`. - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -``__cos``: The approach is to use a polynomial approximation for the calculation. - -Use the following constants as calculation/return values: - -* :math:`C1 =` ``0x3FA555555555554C (0x3D2AAAA5)`` -* :math:`C2 =` ``0xBF56C16C16C15177 (0xBAB60615)`` -* :math:`C3 =` ``0x3EFA01A019CB1590 (0x37CCF47C)`` -* :math:`C4 =` ``0xBE927E4F809C52AD`` -* :math:`C5 =` ``0x3E21EE9EBDB4B1C4`` -* :math:`C6 =` ``0xBDA8FAE9BE8838D4`` - -The cosine is computed by evaluating the following polynomial: - -.. math:: - - r &= C1 \cdot x^2 + C2 \cdot x^4 + C3 \cdot x^6 + C4 \cdot x^{8} + C5 \cdot x^{10} + C6 \cdot x^{12} \\ - cos(x+y) &= w + (((1 - w) - hz) + (x^2 \cdot r - x \cdot y)) - -with: - -* :math:`hz = 0.5 \cdot x^2` -* :math:`w = 1 - hz` - -For the float version the polynomial can be shortened to: - -.. math:: - - r = C1 \cdot x^2 + C2 \cdot x^4 + C3 \cdot x^6 - --------------------------- - -``__sin``: The approach is to use a polynomial approximation for the calculation. - -Use the following constants as calculation/return values: - -* :math:`S1 =` ``0xBFC5555555555549 (0xBE2AAAAB)`` -* :math:`S2 =` ``0x3F8111111110F8A6 (0x3C0888BB)`` -* :math:`S3 =` ``0xBF2A01A019C161D5 (0xB9502DE1)`` -* :math:`S4 =` ``0x3EC71DE357B1FE7D (0x363E6DBE)`` -* :math:`S5 =` ``0xBE5AE5E68A2B9CEB`` -* :math:`S6 =` ``0x3DE5D93A5ACFD57C`` - -The sine is computed by evaluating the following polynomial: - -.. math:: - - r &= S2 \cdot x^3 + S3 \cdot x^5 + S4 \cdot x^7 + S5 \cdot x^{9} + S6 \cdot x^{11} \\ - sin(x+y) &= x + (S1 \cdot x + ( x \cdot (r - \frac{y}{2}) + y)) - -For the float version the polynomial can be shortened to: - -.. math:: - - r = S2 \cdot x^3 + S3 \cdot x^5 + S4 \cdot x^7 - --------------------------- - -``__rem_pio2``: The approach is to use a polynomial approximation for the calculation. - -Use the following constants as calculation/return values: - -* :math:`invpio2 =` ``0x3FE45F306DC9C883 (0x3F22F984)``, equals the first 53 bit of :math:`\frac{2}{\pi}` -* :math:`pio2_1 =` ``0x3FF921FB54400000 (0x3FC90F80)``, equals the first 33 bit of :math:`\frac{\pi}{2}` -* :math:`pio2_{1t} =` ``0x3DD0B4611A626331 (0x37354443)``, equals :math:`\frac{\pi}{2} - pio2_1` -* :math:`pio2_2 =` ``0x3DD0B4611A600000 (0x37354400)``, equals the second 33 bit of :math:`\frac{\pi}{2}` -* :math:`pio2_{2t} =` ``0x3BA3198A2E037073 (0x2E85A308)``, equals :math:`\frac{\pi}{2} - (pio2_1 + pio2_2)` -* :math:`pio2_3 =` ``0x3BA3198A2E000000 (0x2E85A300)``, equals the second 33 bit of :math:`\frac{\pi}{2}` -* :math:`pio2_{3t} =` ``0x397B839A252049C1 (0x248D3132)``, equals :math:`\frac{\pi}{2} - (pio2_1 + pio2_2 + pio2_3)` - -#. For :math:`|x| < \frac{\pi}{4}`, there is no need for reduction: Set :math:`y_0 = x` and :math:`y_1 = 0`, and return :math:`0`. -#. For :math:`|x| < 3 \cdot \frac{\pi}{4}`, one addition or subtraction of :math:`pio2` is enough: - - #. For :math:`x` is positive: - - #. For ``highword`` of :math:`x` is ``0x3FF921FB`` (this means :math:`x` is close to :math:`\frac{\pi}{2}`) (float: For integer representation of :math:`x`, with the last 17 bit masked off, is ``0x3FC80000``): - - #. Set :math:`y_0 = x - pio2_1 - pio2_2 - pio2_{2t}`. - #. Set :math:`y_1 = (x - pio2_1 - pio2_2 - y_0) - pio2_{2t}`. - - Oherwise a less precise :math:`pio2` is sufficient: - - #. Set :math:`y_0 = x - pio2_1 - pio2_{1t}`. - #. Set :math:`y_1 = (x - pio2_1 - y_0) - pio2_{1t}`. - - #. Return :math:`1`. - - Otherwise for :math:`x` is negative: - - #. For ``highword`` of :math:`x` is ``0x3FF921FB`` (this means :math:`x` is close to :math:`\frac{\pi}{2}`) (float: For integer representation of :math:`x`, with the last 17 bit masked off, is ``0x3FC80000``): - - #. Set :math:`y_0 = x + pio2_1 + pio2_2 + pio2_{2t}`. - #. Set :math:`y_1 = (x + pio2_1 + pio2_2 - y_0) + pio2_{2t}`. - - Oherwise a less precise :math:`pio2` is sufficient: - - #. Set :math:`y_0 = x + pio2_1 + pio2_{1t}`. - #. Set :math:`y_1 = (x + pio2_1 - y_0) + pio2_{1t}`. - - #. Return :math:`-1`. - -#. For :math:`|x| < 2^{19} \cdot \frac{\pi}{2}` (float: :math:`|x| < 2^{7} \cdot \frac{\pi}{2}`), an addition or subtraction of multiple :math:`pio2` is enough: - - #. :math:`n` shall be an integer. Set :math:`n = |x| \cdot invpio2 + 0.5` (use :ref:`fabs` to calculate the absolute value of :math:`x`). - #. Set :math:`r = |x| - n \cdot pio2_1`. - #. Set :math:`w = n \cdot pio2_{1t}`. - #. Set :math:`y_0 = r - w`. - #. Set :math:`i =` exponent bits of :math:`x -` exponent bits of :math:`y_0`. - #. For :math:`i > 16` (float: :math:`i > 8`), a second iteration is necessary: - - #. Set :math:`t = r`. - #. Set :math:`r = r - n \cdot pio2_{2}`. - #. Set :math:`w = n \cdot pio2_{2t} - ((t - r) - n \cdot pio2_{2})`. - #. Set :math:`y_0 = r - w`. - #. Set :math:`i =` exponent bits of :math:`x -` exponent bits of :math:`y_0`. - #. For :math:`i > 49` (float: :math:`i > 25`), a second iteration is necessary: - - #. Set :math:`t = r`. - #. Set :math:`r = r - n \cdot pio2_{3}`. - #. Set :math:`w = n \cdot pio2_{3t} - ((t - r) - n \cdot pio2_{3})`. - #. Set :math:`y_0 = r - w`. - - #. Set :math:`y_1 = (r - y_0) - w`. - #. For :math:`x` is negative, negate :math:`y_0` and :math:`y_1`, and return :math:`-n`. - #. Return :math:`n`. - -#. For :math:`x` is infinite or :math:`NaN`, set both :math:`y_0` and :math:`y_1` to :math:`NaN`, and return :math:`0`. -#. Set :math:`e0 =` (exponent of :math:`|x|`) :math:`- 23` (float: :math:`e0 =` (exponent of :math:`|x|`) :math:`- 7`). -#. Set :math:`z = |x|` with exponent set to :math:`e0`. -#. Create array :math:`tx` for three values. -#. Set :math:`tx[0] =` integer part of :math:`z`. -#. Set :math:`z = (z-tx[0]) \cdot 2^{24}` (float: :math:`z = (z-tx[0]) \cdot 2^{8}`). -#. Set :math:`tx[1] =` integer part of :math:`z`. -#. Set :math:`z = (z-tx[1]) \cdot 2^{24}` (float: :math:`z = (z-tx[1]) \cdot 2^{8}`). -#. Set :math:`tx[2] = z`. -#. Loop over the array :math:`tx` from back to front, break the loop if the element is equal to zero. Set :math:`nx` to the index of the element that caused the break, or :math:`0` if no break was triggered. -#. Call ``__rem_pio2_internal`` with arguments :math:`tx`, :math:`y`, :math:`e0`, and :math:`nx`. Save the return value in :math:`n`. -#. For :math:`x` is negative, negate :math:`y_0` and :math:`y_1`, and return :math:`-n`. -#. Return :math:`n`. - --------------------------- - -``__rem_pio2_internal``: Use Payne and Hanek's method for range reduction as described in the article *Radian reduction for trigonometric functions* [PH]_. The design of the algorithm is further detailed in [NG]_. As the description in the article is quite extensive it will only be outlined here. - -The external range reduction ``__rem_pio2`` will split the angle :math:`x` into an array :math:`x[0]+x[1]+x[2]` where each :math:`x[i]` item contains 24 bits of the original angle, and it will set the unbiased exponent of :math:`x` in :math:`e0`. - -The internal range reduction will compute the integer and fractional parts of the angle :math:`q = x/(\frac{\pi}{2}) = x\cdot(\frac{2}{\pi})`. The constant :math:`\frac{2}{\pi}` is stored in high precision in an array containing 24 bit chunks of the constant. - -The method is to compute the integer (mod 8) and fraction parts of :math:`x\cdot(\frac{2}{\pi})` without doing the full multiplication. In general the part of the product that are known to be a huge integer (more accurately the integer part that is 0 mod 8) are skipped. Thus the number of operations are independent of the exponent of the input. - -.. [PH] *Radian reduction for trigonometric functions* by Mary H. Payne and Robert N. Hanek (https://dl.acm.org/doi/pdf/10.1145/1057600.1057602). -.. [NG] *ARGUMENT REDUCTION FOR HUGE ARGUMENTS: Good to the Last Bit* by K.C. NG and the members of the FP group of SunPro (https://www.csee.umbc.edu/~phatak/645/supl/Ng-ArgReduction.pdf) - -Requirements -^^^^^^^^^^^^ - -Internal functions do not directly implement requirements. - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/internal/trigd.h -* libm/mathd/internal/trigd.c -* libm/mathf/internal/trigf.h -* libm/mathf/internal/trigf.c - -References -^^^^^^^^^^ - -* :ref:`__lgamma ` -* :ref:`cos` -* :ref:`fabs` -* :ref:`floor` -* :ref:`scalbn` -* :ref:`sin` -* :ref:`tan` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0200_acosh.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0200_acosh.rst deleted file mode 100644 index 73d20e7a..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0200_acosh.rst +++ /dev/null @@ -1,53 +0,0 @@ -acosh -~~~~~ - -.. c:autodoc:: mathd/acoshd.c - -Special cases -^^^^^^^^^^^^^ - -+--------------------------+--------------------------+ -| x | Result | -+==========================+==========================+ -| :math:`+1` | :math:`+0` | -+--------------------------+--------------------------+ -| :math:`<+1` | :math:`qNaN` | -+--------------------------+--------------------------+ -| :math:`-Inf` | :math:`qNaN` | -+--------------------------+--------------------------+ -| :math:`+Inf` | :math:`+Inf` | -+--------------------------+--------------------------+ -| :math:`NaN` | :math:`qNaN` | -+--------------------------+--------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -Implement based on :math:`cosh^{-1}(x) = ln(x + \sqrt{x^2-1})` using :ref:`log`, :ref:`log1p`, and :ref:`sqrt`: - -#. For large :math:`x` (:math:`x > 2^{28}`): :math:`acosh(x) = log(x) + log(2)` -#. For :math:`x > 2`: :math:`acosh(x) = log\Big(\frac{2x - 1}{x + \sqrt{x^2 - 1}}\Big)` -#. For smaller :math:`x`: :math:`acosh(x) = log1p(t + \sqrt{2t+t^2}) \wedge t = x - 1` - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-2710 -* REQ-ML-3010 -* REQ-ML-3020 -* REQ-ML-3030 -* REQ-ML-3040 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/acoshd.c -* libm/mathf/acoshf.c - -References -^^^^^^^^^^ - -* :ref:`log` -* :ref:`log1p` -* :ref:`sqrt` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0210_asinh.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0210_asinh.rst deleted file mode 100644 index e9d48ecb..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0210_asinh.rst +++ /dev/null @@ -1,52 +0,0 @@ -asinh -~~~~~ - -.. c:autodoc:: mathd/asinhd.c - -Special cases -^^^^^^^^^^^^^ - -+--------------------------+--------------------------+ -| x | Result | -+==========================+==========================+ -| :math:`±0` | :math:`x` | -+--------------------------+--------------------------+ -| :math:`±Inf` | :math:`x` | -+--------------------------+--------------------------+ -| :math:`NaN` | :math:`qNaN` | -+--------------------------+--------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -Implement based on :math:`sinh^{-1}(x) = sign(x) \cdot ln(|x| + \sqrt{x^2+1})` using :ref:`log`, :ref:`log1p`, and :ref:`sqrt`: - -#. For large :math:`x` (:math:`|x| > 2^{28}`): :math:`asinh(x) = sign(x) \cdot log(|x|) + log(2)` -#. For :math:`x > 2`: :math:`asinh(x) = sign(x) \cdot log\Big(\frac{|2x| + 1}{|x| + \sqrt{x^2 + 1}}\Big)` -#. For smaller :math:`x`: :math:`asinh(x) = sign(x) \cdot log1p(|x| + \frac{x^2}{1 + \sqrt{1+x^2}})` -#. For very small :math:`x` (:math:`|x| < 2^{-28}`): :math:`asinh(x) = x` - -.. Here there be dragons. (TODO) - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-2620 -* REQ-ML-2630 -* REQ-ML-2640 -* REQ-ML-2700 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/asinhd.c -* libm/mathf/asinhf.c - -References -^^^^^^^^^^ - -* :ref:`fabs` -* :ref:`log` -* :ref:`log1p` -* :ref:`sqrt` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0220_atanh.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0220_atanh.rst deleted file mode 100644 index afdd57b1..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0220_atanh.rst +++ /dev/null @@ -1,52 +0,0 @@ -atanh -~~~~~ - -.. c:autodoc:: mathd/atanhd.c - -Special cases -^^^^^^^^^^^^^ - -+--------------------------+--------------------------+ -| x | Result | -+==========================+==========================+ -| :math:`±0` | :math:`x` | -+--------------------------+--------------------------+ -| :math:`\notin [-1, 1]` | :math:`qNaN` | -+--------------------------+--------------------------+ -| :math:`±1` | :math:`±Inf` | -+--------------------------+--------------------------+ -| :math:`±Inf` | :math:`qNaN` | -+--------------------------+--------------------------+ -| :math:`NaN` | :math:`qNaN` | -+--------------------------+--------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -Implement based on :math:`tanh^{-1}(x) = \frac{1}{2} ln \left( \frac{1+x}{1-x} \right)` using :ref:`log1p`: - -#. Reduce to positive as :math:`tanh^{-1}(-x) = -tanh^{-1}(x)` -#. For :math:`x >= \frac{1}{2}`: :math:`atanh(x) = \frac{1}{2} log\Big(1 + \frac{2x}{1 - x}\Big) = \frac{1}{2} log1p\Big(\frac{2x}{1 - x}\Big)` -#. Otherwise: :math:`atanh(x) = \frac{1}{2} log1p\Big(2x + \frac{2x^2}{1-x}\Big)` - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-3100 -* REQ-ML-3110 -* REQ-ML-3120 -* REQ-ML-3121 -* REQ-ML-3140 -* REQ-ML-3141 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/atanhd.c -* libm/mathf/atanhf.c - -References -^^^^^^^^^^ - -* :ref:`log1p` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0230_cosh.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0230_cosh.rst deleted file mode 100644 index 9d84a787..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0230_cosh.rst +++ /dev/null @@ -1,56 +0,0 @@ -cosh -~~~~ - -.. c:autodoc:: mathd/coshd.c - -Special cases -^^^^^^^^^^^^^ - -+--------------------------+--------------------------+ -| x | Result | -+==========================+==========================+ -| :math:`±0` | :math:`1` | -+--------------------------+--------------------------+ -| :math:`±Inf` | :math:`+Inf` | -+--------------------------+--------------------------+ -| :math:`NaN` | :math:`qNaN` | -+--------------------------+--------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -Implement based on :math:`cosh(x) = \frac{e^x+e^{-x}}{2}` using :ref:`exp` and :ref:`expm1`: - -#. Reduce to positive as :math:`cosh(-x) = cosh(x)` -#. For :math:`0 <= x <= \frac{ln(2)}{2}`: :math:`cosh(x) = 1 + \frac{(exp(x) - 1)^2}{2 \cdot exp(x)}` -#. For :math:`\frac{ln(2)}{2} <= x <= 22`: :math:`cosh(x) = \frac{exp(x) + \frac{1}{exp(x)}}{2}` -#. For :math:`22 <= x`: :math:`cosh(x) = \frac{exp(x)}{2}` - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-2200 -* REQ-ML-2210 -* REQ-ML-2220 -* REQ-ML-2240 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/coshd.c -* libm/mathf/coshf.c - -References -^^^^^^^^^^ - -* :ref:`__ccoshsinh ` -* :ref:`ccos` -* :ref:`ccosh` -* :ref:`csin` -* :ref:`csinh` -* :ref:`ctan` -* :ref:`ctanh` -* :ref:`exp` -* :ref:`expm1` -* :ref:`fabs` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0240_sinh.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0240_sinh.rst deleted file mode 100644 index 6ff9543d..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0240_sinh.rst +++ /dev/null @@ -1,55 +0,0 @@ -sinh -~~~~ - -.. c:autodoc:: mathd/sinhd.c - -Special cases -^^^^^^^^^^^^^ - -+--------------------------+--------------------------+ -| x | Result | -+==========================+==========================+ -| :math:`±0` | :math:`x` | -+--------------------------+--------------------------+ -| :math:`±Inf` | :math:`x` | -+--------------------------+--------------------------+ -| :math:`NaN` | :math:`qNaN` | -+--------------------------+--------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -Implement based on :math:`sinh(x) = \frac{e^x-e^{-x}}{2}` using :ref:`exp` and :ref:`expm1`: - -#. Reduce to positive as :math:`sinh(-x) = -sinh(x)` -#. For :math:`0 <= x <= 22`: :math:`sinh(x) = \frac{expm1(x) + \frac{expm1(x)}{exp(x)}}{2}` -#. For :math:`22 <= x`: :math:`sinh(x) = \frac{exp(x)}{2}` - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-2100 -* REQ-ML-2110 -* REQ-ML-2120 -* REQ-ML-2140 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/sinhd.c -* libm/mathf/sinhf.c - -References -^^^^^^^^^^ - -* :ref:`__ccoshsinh ` -* :ref:`ccos` -* :ref:`ccosh` -* :ref:`csin` -* :ref:`csinh` -* :ref:`ctan` -* :ref:`ctanh` -* :ref:`exp` -* :ref:`expm1` -* :ref:`fabs` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0250_tanh.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0250_tanh.rst deleted file mode 100644 index 5061d197..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0250_tanh.rst +++ /dev/null @@ -1,45 +0,0 @@ -tanh -~~~~ - -.. c:autodoc:: mathd/tanhd.c - -Special cases -^^^^^^^^^^^^^ - -+--------------------------+--------------------------+ -| x | Result | -+==========================+==========================+ -| :math:`±0` | :math:`x` | -+--------------------------+--------------------------+ -| :math:`±Inf` | :math:`±1` | -+--------------------------+--------------------------+ -| :math:`NaN` | :math:`qNaN` | -+--------------------------+--------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -Implement based on :math:`tanh(x) = \frac{e^x-e^{-x}}{e^x+e^{-x}}` using :ref:`expm1`: - -#. Reduce to positive as :math:`tanh(-x) = -tanh(x)` -#. For :math:`0 <= x <= 1`: :math:`tanh(x) = -\frac{t}{t + 2} \wedge t = expm1(-2x)` -#. For :math:`1 <= x <= 22`: :math:`tanh(x) = 1 - \frac{2}{t + 2} \wedge t = expm1(2x)` -#. For :math:`22 <= x`: :math:`tanh(x) = 1` - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-2540 -* REQ-ML-2550 -* REQ-ML-2600 -* REQ-ML-2610 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/tanhd.c -* libm/mathf/tanhf.c - -References -^^^^^^^^^^ diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0300_exp.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0300_exp.rst deleted file mode 100644 index 34e4a57f..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0300_exp.rst +++ /dev/null @@ -1,100 +0,0 @@ -exp -~~~ - -.. c:autodoc:: mathd/expd.c - -Special cases -^^^^^^^^^^^^^ - -+--------------------------+--------------------------+ -| x | Result | -+==========================+==========================+ -| :math:`±0` | :math:`1` | -+--------------------------+--------------------------+ -| :math:`-Inf` | :math:`+0` | -+--------------------------+--------------------------+ -| :math:`+Inf` | :math:`+Inf` | -+--------------------------+--------------------------+ -| :math:`NaN` | :math:`qNaN` | -+--------------------------+--------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -The approach is to first work on special values and then use polynomial approximation for the calculation. - -Use the following constants as calculation/return values: - -* :math:`P1 =` ``0x3FC555555555553E (0x3E2AAAAB)`` -* :math:`P2 =` ``0xBF66C16C16BEBD93 (0xBB360B61)`` -* :math:`P3 =` ``0x3F11566AAF25DE2C (0x388AB355)`` -* :math:`P4 =` ``0xBEBBBD41C5D26BF1 (0xB5DDEA0E)`` -* :math:`P5 =` ``0x3E66376972BEA4D0 (0x3331BB4C)`` - -#. For :math:`x` is :math:`NaN`, return :math:`qNaN`. [#]_ -#. For :math:`x` is :math:`+Inf`, return :math:`x`. -#. For :math:`x` is :math:`-Inf`, return :math:`+0`. -#. If :math:`e^x` produces an overflow, return positive infinity [#]_, with ``overflow`` exception. -#. If :math:`e^x` produces an underflow, return :math:`0` [#]_. -#. For :math:`|x| < 2^{-28}`, return :math:`1`. [#]_ -#. For :math:`|x| > 0.5 \cdot ln(2)`, an argument reduction is necessary. Given :math:`x` find :math:`r` and integer :math:`k` such that the formula - - .. math:: - :label: formula_exp_1 - - x = k \cdot ln(2) + r \wedge |r| <= 0.5 \cdot ln(2) - - holds true. To increase accuracy save :math:`r` using two double precision floating point values. -#. If no argument reduction was necessary in step 7, :math:`r` equals :math:`x`. -#. Calculate :math:`e^r` with the following formulae using Horner's method: - - .. math:: - :label: formula_exp_2 - - c = r - P1 \cdot r^2 - P2 \cdot r^4 - P3 \cdot r^6 - P4 \cdot r^8 - P5 \cdot r^{10} \\ - e^r = 1 - \frac{r \cdot c}{c - 2} - r - -#. If no argument reduction was necessary in step 7, return :math:`e^r`. -#. Use the formula - - .. math:: - :label: formula_exp_3 - - e^x = 2^k \cdot e^r - - to scale back from :math:`r` to :math:`x`, and return the calculated value for :math:`e^x`. - -.. [#] For optimization the steps 1 through 5 can be combined in a single if-statement using :math:`|x| >=` the overflow threshold, therefore making the execution time of non-special cases shorter. -.. [#] This is the case when :math:`x` is :math:`>` ``0x40862E42FEFA39EF`` (:math:`7.09782712893383973096 \cdot 10^2`). -.. [#] This is the case when :math:`x` is :math:`<` ``0xC0874910D52D3051`` (:math:`-7.45133219101941108420 \cdot 10^2`). -.. [#] This is faster than the calculation and the result would be indistinguishable from :math:`1` using double precision. - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-0800 -* REQ-ML-0831 -* REQ-ML-0832 -* REQ-ML-0833 -* REQ-ML-0834 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/expd.c -* libm/mathf/expf.c - -References -^^^^^^^^^^ - -* :ref:`__ccoshsinh ` -* :ref:`ccos` -* :ref:`cexp` -* :ref:`cosh` -* :ref:`cpow` -* :ref:`csin` -* :ref:`erf` -* :ref:`erfc` -* :ref:`sinh` -* :ref:`tgamma` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0310_exp2.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0310_exp2.rst deleted file mode 100644 index 388fc3e5..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0310_exp2.rst +++ /dev/null @@ -1,47 +0,0 @@ -exp2 -~~~~ - -.. c:autodoc:: mathd/exp2d.c - -Special cases -^^^^^^^^^^^^^ - -+--------------------------+--------------------------+ -| x | Result | -+==========================+==========================+ -| :math:`±0` | :math:`1` | -+--------------------------+--------------------------+ -| :math:`-Inf` | :math:`+0` | -+--------------------------+--------------------------+ -| :math:`+Inf` | :math:`+Inf` | -+--------------------------+--------------------------+ -| :math:`NaN` | :math:`qNaN` | -+--------------------------+--------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -Implement based on :ref:`pow`. - -.. Here there be dragons. (TODO) - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-3200 -* REQ-ML-3210 -* REQ-ML-3220 -* REQ-ML-3240 -* REQ-ML-3250 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/exp2d.c -* libm/mathf/exp2f.c - -References -^^^^^^^^^^ - -* :ref:`pow` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0320_expm1.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0320_expm1.rst deleted file mode 100644 index 6ad8f107..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0320_expm1.rst +++ /dev/null @@ -1,49 +0,0 @@ -expm1 -~~~~~ - -.. c:autodoc:: mathd/expm1d.c - -Special cases -^^^^^^^^^^^^^ - -+--------------------------+--------------------------+ -| x | Result | -+==========================+==========================+ -| :math:`±0` | :math:`+0` | -+--------------------------+--------------------------+ -| :math:`-Inf` | :math:`-1` | -+--------------------------+--------------------------+ -| :math:`+Inf` | :math:`+Inf` | -+--------------------------+--------------------------+ -| :math:`NaN` | :math:`qNaN` | -+--------------------------+--------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -Implement based on a rational approximation. - -.. Here there be dragons. (TODO) - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-2500 -* REQ-ML-2510 -* REQ-ML-2520 -* REQ-ML-2540 -* REQ-ML-2550 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/expm1d.c -* libm/mathf/expm1f.c - -References -^^^^^^^^^^ - -* :ref:`cosh` -* :ref:`sinh` -* :ref:`tanh` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0330_frexp.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0330_frexp.rst deleted file mode 100644 index a134c40a..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0330_frexp.rst +++ /dev/null @@ -1,42 +0,0 @@ -frexp -~~~~~ - -.. c:autodoc:: mathd/frexpd.c - -Special cases -^^^^^^^^^^^^^ - -+------------------------------+------------------------------+--------------------------+ -| x | :math:`*eptr` | Result | -+==============================+==============================+==========================+ -| :math:`±0` | :math:`0` | :math:`±0` | -+------------------------------+------------------------------+--------------------------+ -| :math:`±Inf` | :math:`0` | :math:`qNaN` | -+------------------------------+------------------------------+--------------------------+ -| :math:`NaN` | :math:`0` | :math:`qNaN` | -+------------------------------+------------------------------+--------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -Implement based on bit-fiddling. - -.. Here there be dragons. (TODO) - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-4000 -* REQ-ML-4010 -* REQ-ML-4020 -* REQ-ML-4040 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/frexpd.c -* libm/mathf/frexpf.c - -References -^^^^^^^^^^ diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0340_ilogb.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0340_ilogb.rst deleted file mode 100644 index 3e800724..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0340_ilogb.rst +++ /dev/null @@ -1,45 +0,0 @@ -ilogb -~~~~~ - -.. c:autodoc:: mathd/ilogbd.c - -Special cases -^^^^^^^^^^^^^ - -+--------------------------+--------------------------+ -| x | Result | -+==========================+==========================+ -| :math:`±0` | min :math:`\mathbb{I}` | -+--------------------------+--------------------------+ -| :math:`±Inf` | max :math:`\mathbb{I}` | -+--------------------------+--------------------------+ -| :math:`NaN` | max :math:`\mathbb{I}` | -+--------------------------+--------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -Implement based on bit-fiddling. - -.. Here there be dragons. (TODO) - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-4300 -* REQ-ML-4310 -* REQ-ML-4320 -* REQ-ML-4340 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/ilogbd.c -* libm/mathf/ilogbf.c - -References -^^^^^^^^^^ - -* :numref:`Tbl. %s ` -* :ref:`logb` \ No newline at end of file diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0350_ldexp.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0350_ldexp.rst deleted file mode 100644 index f95c63f3..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0350_ldexp.rst +++ /dev/null @@ -1,49 +0,0 @@ -ldexp -~~~~~ - -.. c:autodoc:: mathd/ldexpd.c - -Special cases -^^^^^^^^^^^^^ - -+------------------------+------------------------+------------------------+ -| x | exp | Result | -+========================+========================+========================+ -| :math:`±0` | :math:`\in \mathbb{I}` | :math:`x` | -+------------------------+------------------------+------------------------+ -| :math:`\in \mathbb{F}` | :math:`0` | :math:`x` | -+------------------------+------------------------+------------------------+ -| :math:`±Inf` | :math:`\in \mathbb{I}` | :math:`x` | -+------------------------+------------------------+------------------------+ -| :math:`NaN` | :math:`\in \mathbb{I}` | :math:`qNaN` | -+------------------------+------------------------+------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -The approach is to first work on special values and then use :ref:`scalbn`. - -#. For :math:`x` is zero, infinite or ``NaN``, return :math:`x`. -#. Else use :ref:`scalbn` and return its result. - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-4100 -* REQ-ML-4110 -* REQ-ML-4120 -* REQ-ML-4130 -* REQ-ML-4140 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/ldexpd.c -* libm/mathf/ldexpf.c - -References -^^^^^^^^^^ - -* :ref:`isfinite` -* :ref:`scalbn` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0360_log.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0360_log.rst deleted file mode 100644 index ad0f938a..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0360_log.rst +++ /dev/null @@ -1,138 +0,0 @@ -log -~~~ - -.. c:autodoc:: mathd/logd.c - -Special cases -^^^^^^^^^^^^^ - -+--------------------------+--------------------------+ -| x | Result | -+==========================+==========================+ -| :math:`<0` | :math:`qNaN` | -+--------------------------+--------------------------+ -| :math:`±0` | :math:`-Inf` | -+--------------------------+--------------------------+ -| :math:`1` | :math:`+0` | -+--------------------------+--------------------------+ -| :math:`+Inf` | :math:`+Inf` | -+--------------------------+--------------------------+ -| :math:`NaN` | :math:`qNaN` | -+--------------------------+--------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -The approach is to first work on special values and then use polynomial approximation for the calculation. - -Use the following constants as calculation/return values: - -* :math:`L1 =` ``0x3FE5555555555593 (0x3E2AAAAB)`` -* :math:`L2 =` ``0x3FD999999997FA04 (0x3ECCCCCD)`` -* :math:`L3 =` ``0x3FD2492494229359 (0x3E924925)`` -* :math:`L4 =` ``0x3FCC71C51D8E78AF (0x3E638E29)`` -* :math:`L5 =` ``0x3FC7466496CB03DE (0x3E3A3325)`` -* :math:`L6 =` ``0x3FC39A09D078C69F (0x3E1CD04F)`` -* :math:`L7 =` ``0x3FC2F112DF3E5244 (0x3E178897)`` -* :math:`ln(2) \approx Ln2_{hi} + Ln2_{lo}` -* :math:`Ln2_{hi} =` ``0x3FE62E42FEE00000 (0x3F317180)`` -* :math:`Ln2_{lo} =` ``0x3DEA39EF35793C76 (0x3717F7D1)`` - -#. For :math:`x` is :math:`NaN` or positive infinity, return :math:`x+x`. -#. For :math:`x` is a zero, return negative infinity. -#. For :math:`x` is negative, return :math:`NaN`. -#. For :math:`x` is subnormal, scale up by multiplying with :math:`2^{54}` (float: :math:`2^{25}`). -#. Given :math:`x` find :math:`f` and integer :math:`k` such that the formulae [#]_ - - .. math:: - :label: formula_log_1 - - x &= 2^k \cdot (1 + f) \\ - \frac{\sqrt{2}}{2} &< (1 + f) < \sqrt{2} - - hold true [#]_. Decrease :math:`k` by :math:`54` (float: :math:`25`) if :math:`x` was subnormal in the previous step. -#. Approximate :math:`\log{(1+f)}`: - - #. Let :math:`s` be :math:`\frac{f}{2+f}`, based on: - - .. math:: - :label: formula_log_2 - - \log{(1+f)} &= \log{(1+s)} - \log{(1-s)} \\ - &= 2s + s \cdot \sum\limits_{i=1}^{\infty} \bigg(\frac{2}{2i+1} \cdot s^2\bigg) \\ - &= 2s + s \cdot R(z) \wedge z = 2s - - #. Use the following polynomial to approximate :math:`R(z)`: - - .. math:: - :label: formula_log_3 - - R(z) \sim L1 \cdot s^2 + L2 \cdot s^4 + L3 \cdot s^6 + L4 \cdot s^8 + L5 \cdot s^{10} +L6 \cdot s^{12} + L7 \cdot s^{14} - - The error of this approximation is smaller than or equal to :math:`2^{-58.45}`. - #. To ensure that the error of :math:`\log{(1+f)}` is below 1 :ref:`ULP ` use the identity: - - .. math:: - :label: formula_log_4 - - 2s = f - s \cdot f = f - \frac{f^2}{2} + s \cdot \frac{f^2}{2} - - Therefore if :math:`f` is not too large [#]_: - - .. math:: - :label: formula_log_5 - - \log{(1+f)} = f - s \cdot (f - R) - - Otherwise: - - .. math:: - :label: formula_log_6 - - \log{(1+f)} = f - \bigg(\frac{f^2}{2} - s \cdot \Big(\frac{f^2}{2} - R\Big)\bigg) - -#. For :math:`k` is :math:`0`, return :math:`\log{(1+f)}`. -#. Return (split :math:`ln(2)` into :math:`Ln2_{hi}` and :math:`Ln2_{lo}` for more accuracy) - - .. math:: - :label: formula_log_7 - - \log{(x)} &= k \cdot Ln2 + \log{(1+f)} \\ - &= k \cdot Ln2_{hi} + (f - (s \cdot (f - R) + k \cdot Ln2_{lo})) \\ - \vee \qquad &= k \cdot Ln2_{hi} + \Bigg(f - \bigg(\frac{f^2}{2} - s \cdot \Big(\frac{f^2}{2} - R\Big) + k \cdot Ln2_{lo}\bigg)\Bigg) - - Use the first version if formula :math:numref:`formula_log_5` was used earlier, otherwise use the second one. - -.. [#] This implementation of log is a variation of the algorithm proposed by W. J. Cody, JR. and W. Waite in *Software Manual for the Elementary Functions* -.. [#] Use mantissa part of ``highword`` + ``0x95f64`` (float: integer representation + ``0x95f64 << 3``) to find :math:`k`. -.. [#] :math:`f` is too large when ``0x6147A`` :math:`<` mantissa part of ``highword`` of :math:`x <` ``0x6B851`` (float: ``0x6147A << 3`` :math:`<` mantissa part of integer representation of :math:`x <` ``0x6B851 << 3``). - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-0900 -* REQ-ML-0910 -* REQ-ML-0920 -* REQ-ML-0921 -* REQ-ML-0930 -* REQ-ML-0931 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/logd.c -* libm/mathf/logf.c - -References -^^^^^^^^^^ - -* :ref:`__lgamma ` -* :ref:`acosh` -* :ref:`asinh` -* :ref:`catan` -* :ref:`clog` -* :ref:`cpow` -* :ref:`jn` -* :ref:`y0` -* :ref:`y1` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0370_log10.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0370_log10.rst deleted file mode 100644 index ff821f99..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0370_log10.rst +++ /dev/null @@ -1,87 +0,0 @@ -log10 -~~~~~ - -.. c:autodoc:: mathd/log10d.c - -Special cases -^^^^^^^^^^^^^ - -+--------------------------+--------------------------+ -| x | Result | -+==========================+==========================+ -| :math:`<0` | :math:`qNaN` | -+--------------------------+--------------------------+ -| :math:`±0` | :math:`-Inf` | -+--------------------------+--------------------------+ -| :math:`1` | :math:`+0` | -+--------------------------+--------------------------+ -| :math:`+Inf` | :math:`+Inf` | -+--------------------------+--------------------------+ -| :math:`NaN` | :math:`qNaN` | -+--------------------------+--------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -The approach is to first work on special values and then use polynomial approximation for the calculation. - -Use the following constants as calculation/return values: - -* :math:`log_{10}(2) \approx Log_{10}2_{hi} + Log_{10}2_{lo}` -* :math:`Log_{10}2_{hi} =` ``0x3FD34413509F6000 (0x3E9A2080)`` -* :math:`Log_{10}2_{lo} =` ``0x3D59FEF311F12B36 (0x355427DB)`` -* :math:`\frac{1}{ln(10)} \approx invln10_{hi} + invln10_{lo}` -* :math:`invln10_{hi} =` ``0x3FDBCB7B15200000 (0x3EDE6000)`` -* :math:`invln10_{lo} =` ``0x3DBB9438CA9AADD5 (0xB804EAD9)`` - -#. For :math:`x` is :math:`NaN` or positive infinity, return :math:`x+x`. -#. For :math:`x` is a zero, return negative infinity. -#. For :math:`x` is negative, return :math:`NaN`. -#. For :math:`x` is subnormal, scale up by multiplying with :math:`2^{54}` (float: :math:`2^{25}`). -#. Given :math:`x` find :math:`f` and integer :math:`k` such that the formulae [#]_ - - .. math:: - :label: formula_log10_1 - - x &= 2^k \cdot (1 + f) \\ - \frac{\sqrt{2}}{2} &< (1 + f) < \sqrt{2} - - hold true [#]_. -#. Use :ref:`__log1p ` to return the result of: - - .. math:: - :label: formula_log10_2 - - hfsq &= \frac{f^2}{2} \\ - r &= \_\_log1p(f) \\ - hi &= f - hfsq,\ with\ the\ lowword\ masked\ off \\ - lo &= (f - hi) - hfsq + r \\ - z &= k \cdot Log_{10}2_{hi} \\ - w &= z + hi \cdot invln10_{hi} \\ - log_{10}{x} &= \Big(\big(k \cdot Log_{10}2_{lo} + (lo + hi) \cdot invln10_{lo} + lo \cdot invln10_{hi}\big) \\ - &\qquad + (z - w) + hi \cdot invln10_{hi}\Big) + w - -.. [#] This implementation of log is a variation of the algorithm proposed by W. J. Cody, JR. and W. Waite in *Software Manual for the Elementary Functions* -.. [#] Use mantissa part of ``highword`` + ``0x95f64`` (float: integer representation + ``0x95f64 << 3``) to find :math:`k`. - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-0950 -* REQ-ML-0960 -* REQ-ML-0970 -* REQ-ML-0971 -* REQ-ML-0980 -* REQ-ML-0981 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/log10d.c -* libm/mathf/log10f.c - -References -^^^^^^^^^^ - -* :ref:`__log1pmf ` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0380_log1p.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0380_log1p.rst deleted file mode 100644 index 83500d83..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0380_log1p.rst +++ /dev/null @@ -1,53 +0,0 @@ -log1p -~~~~~ - -.. c:autodoc:: mathd/log1pd.c - -Special cases -^^^^^^^^^^^^^ - -+--------------------------+--------------------------+ -| x | Result | -+==========================+==========================+ -| :math:`<-1` | :math:`qNaN` | -+--------------------------+--------------------------+ -| :math:`-1` | :math:`-Inf` | -+--------------------------+--------------------------+ -| :math:`±0` | :math:`x` | -+--------------------------+--------------------------+ -| :math:`+Inf` | :math:`+Inf` | -+--------------------------+--------------------------+ -| :math:`NaN` | :math:`qNaN` | -+--------------------------+--------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -Implement similarly to :ref:`log10` using :ref:`__log1pmf `. - -.. Here there be dragons. (TODO) - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-3400 -* REQ-ML-3410 -* REQ-ML-3420 -* REQ-ML-3430 -* REQ-ML-3440 -* REQ-ML-3450 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/log1pd.c -* libm/mathf/log1pf.c - -References -^^^^^^^^^^ - -* :ref:`__log1pmf ` -* :ref:`acosh` -* :ref:`asinh` -* :ref:`atanh` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0390_log2.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0390_log2.rst deleted file mode 100644 index 98a6aec0..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0390_log2.rst +++ /dev/null @@ -1,50 +0,0 @@ -log2 -~~~~ - -.. c:autodoc:: mathd/log2d.c - -Special cases -^^^^^^^^^^^^^ - -+--------------------------+--------------------------+ -| x | Result | -+==========================+==========================+ -| :math:`<0` | :math:`qNaN` | -+--------------------------+--------------------------+ -| :math:`±0` | :math:`-Inf` | -+--------------------------+--------------------------+ -| :math:`1` | :math:`+0` | -+--------------------------+--------------------------+ -| :math:`+Inf` | :math:`+Inf` | -+--------------------------+--------------------------+ -| :math:`NaN` | :math:`qNaN` | -+--------------------------+--------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -Implement similarly to :ref:`log10` using :ref:`__log1pmf `. - -.. Here there be dragons. (TODO) - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-3300 -* REQ-ML-3310 -* REQ-ML-3320 -* REQ-ML-3330 -* REQ-ML-3340 -* REQ-ML-3350 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/log2d.c -* libm/mathf/log2f.c - -References -^^^^^^^^^^ - -* :ref:`__log1pmf ` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0400_logb.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0400_logb.rst deleted file mode 100644 index 7f8be7a3..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0400_logb.rst +++ /dev/null @@ -1,44 +0,0 @@ -logb -~~~~ - -.. c:autodoc:: mathd/logbd.c - -Special cases -^^^^^^^^^^^^^ - -+--------------------------+--------------------------+ -| x | Result | -+==========================+==========================+ -| :math:`±0` | :math:`-Inf` | -+--------------------------+--------------------------+ -| :math:`±Inf` | :math:`+Inf` | -+--------------------------+--------------------------+ -| :math:`NaN` | :math:`NaN` | -+--------------------------+--------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -Implement based on bit-fiddling. - -.. Here there be dragons. (TODO) - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-3500 -* REQ-ML-3510 -* REQ-ML-3520 -* REQ-ML-3540 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/logbd.c -* libm/mathf/logbf.c - -References -^^^^^^^^^^ - -* :ref:`ilogb` \ No newline at end of file diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0410_modf.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0410_modf.rst deleted file mode 100644 index 55c5af0c..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0410_modf.rst +++ /dev/null @@ -1,68 +0,0 @@ -modf -~~~~ - -.. c:autodoc:: mathd/modfd.c - -Special cases -^^^^^^^^^^^^^ - -+------------------------------+------------------------------+--------------------------+ -| x | :math:`*iptr` | Result | -+==============================+==============================+==========================+ -| :math:`-Inf` | :math:`-Inf` | :math:`-0` | -+------------------------------+------------------------------+--------------------------+ -| :math:`+Inf` | :math:`+Inf` | :math:`+0` | -+------------------------------+------------------------------+--------------------------+ -| :math:`NaN` | :math:`qNaN` | :math:`qNaN` | -+------------------------------+------------------------------+--------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -The approach is to first work on special values and then use bit-fiddling tricks. - -All the following outputs (both return value and out-pointer) shall have the same sign as the input value. - -#. If the argument :math:`*iptr` is a NULL-pointer replace the pointer internally with a valid one. At the end place a NULL-pointer to the out-pointer regardless of what is otherwise stated at that branch. The return value remains unchanged. -#. Return :math:`qNaN` to both outputs if the input value is :math:`NaN`. -#. Return a zero if the input value is infinite, and place the infinity to the out-pointer. -#. If the exponent is :math:`< 20`, the integral part of :math:`x` is in the double's highword: - - #. If the exponent is :math:`< 0`, there is no integral part, return the input and place a zero to the out-pointer. - #. If the input is integral, return a zero and place the input value to the out-pointer. - #. Return the fractional part of the input and place the integral part to the out-pointer. - -#. If the exponent is :math:`> 51`, there is no fractional part, return a zero and place the input value to the out-pointer. -#. If the input is integral, return a zero and place the input value to the out-pointer. -#. Return the fractional part of the input and place the integral part to the out-pointer. - -For the float version: - -#. Same as the first 3 steps as the double version. -#. If the exponent is :math:`< 23`, there may be a fractional part: - - #. If the exponent is :math:`< 0`, there is no integral part, return the input and place a zero to the out-pointer. - #. If the input is integral, return a zero and place the input value to the out-pointer. - #. Return the fractional part of the input and place the integral part to the out-pointer. - -#. Return a zero and place the input value to the out-pointer. - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-1200 -* REQ-ML-1201 -* REQ-ML-1210 -* REQ-ML-1211 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/modfd.c -* libm/mathf/modff.c - -References -^^^^^^^^^^ - -* :ref:`isnan` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0420_scalbn.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0420_scalbn.rst deleted file mode 100644 index 9416dce9..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0420_scalbn.rst +++ /dev/null @@ -1,81 +0,0 @@ -scalbn -~~~~~~ - -.. c:autodoc:: mathd/scalbnd.c - -Special cases -^^^^^^^^^^^^^ - -+------------------------+------------------------+------------------------+ -| x | n | Result | -+========================+========================+========================+ -| :math:`±0` | :math:`\in \mathbb{I}` | :math:`x` | -+------------------------+------------------------+------------------------+ -| :math:`\in \mathbb{F}` | :math:`0` | :math:`x` | -+------------------------+------------------------+------------------------+ -| :math:`±Inf` | :math:`\in \mathbb{I}` | :math:`x` | -+------------------------+------------------------+------------------------+ -| :math:`NaN` | :math:`\in \mathbb{I}` | :math:`qNaN` | -+------------------------+------------------------+------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -The approach is to first work on special values and then use bit-fiddling tricks. - -All the following return values shall have the same sign as the input value, use :ref:`copysign`. - -#. For :math:`x` is zero, infinite or ``NaN``, return :math:`x`. - -#. If the input is subnormal or zero: - - #. If the input is zero, return a zero. - #. Scale up the input by multiplying with :math:`2^{54}`. - #. If :math:`n` is :math:`< -50000` return a zero. - -#. If the exponent of :math:`x` is :math:`1024`, :math:`x` is :math:`NaN` or infinite, return :math:`x+x`. -#. If the exponent of :math:`x` :math:`+ n` is :math:`> 1023`, return an infinity, with overflow. -#. If the exponent of :math:`x` :math:`+ n` is :math:`> 0`, return :math:`x` with the exponent increased by :math:`n`. -#. If the exponent of :math:`x` :math:`+ n` is :math:`> -54`, return :math:`x` with the exponent increased by :math:`n` and then multiplied with :math:`2^{-54}`. -#. If :math:`n` is :math:`> 50000` return an infinity, with overflow. -#. Return a zero. - -For the float version: - -#. If the input is zero, return a zero. -#. If the input is not finite, return :math:`x+x`. -#. If the input is subnormal: - - #. Scale up the input by multiplying with :math:`2^{25}`. - #. If :math:`n` is :math:`< -50000` return a zero. - -#. If the exponent :math:`x` :math:`+ n` is :math:`> 254`, return an infinity, with overflow. -#. If the exponent :math:`x` :math:`+ n` is :math:`> 0`, return :math:`x` with the exponent increased by :math:`n`. -#. If the exponent :math:`x` :math:`+ n` is :math:`>= -22`, return :math:`x` with the exponent increased by :math:`n` and then multiplied with :math:`2^{-25}`. -#. If :math:`n` is :math:`> 50000` return an infinity, with overflow. -#. Return a zero. - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-4200 -* REQ-ML-4210 -* REQ-ML-4220 -* REQ-ML-4230 -* REQ-ML-4240 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/scalbnd.c -* libm/mathf/scalbnf.c - -References -^^^^^^^^^^ - -* :ref:`__rem_pio2_internal ` -* :ref:`copysign` -* :ref:`ldexp` -* :ref:`pow` -* :ref:`scalbln` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0430_scalbln.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0430_scalbln.rst deleted file mode 100644 index 37dde320..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0430_scalbln.rst +++ /dev/null @@ -1,44 +0,0 @@ -scalbln -~~~~~~~ - -.. c:autodoc:: mathd/scalblnd.c - -Special cases -^^^^^^^^^^^^^ - -+------------------------+------------------------+------------------------+ -| x | n | Result | -+========================+========================+========================+ -| :math:`±0` | :math:`\in \mathbb{I}` | :math:`x` | -+------------------------+------------------------+------------------------+ -| :math:`\in \mathbb{F}` | :math:`0` | :math:`x` | -+------------------------+------------------------+------------------------+ -| :math:`±Inf` | :math:`\in \mathbb{I}` | :math:`x` | -+------------------------+------------------------+------------------------+ -| :math:`NaN` | :math:`\in \mathbb{I}` | :math:`qNaN` | -+------------------------+------------------------+------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -Implement similarly to :ref:`scalbn`. - -.. Here there be dragons. (TODO) - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-4250 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/scalblnd.c -* libm/mathf/scalblnf.c - -References -^^^^^^^^^^ - -* :ref:`copysign` -* :ref:`scalbn` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0440_log_internal.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0440_log_internal.rst deleted file mode 100644 index 9126c076..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0440_log_internal.rst +++ /dev/null @@ -1,76 +0,0 @@ -.. _internal_log: - -Internal Logarithm Functions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. c:autodoc:: mathd/internal/log1pmfd.h - -.. raw:: html - - - -Special cases -^^^^^^^^^^^^^ - -The special cases are in the respective external functions :ref:`log2` and :ref:`log10`. - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -``__log1pmf``: The approach is to use a polynomial approximation for the calculation. - -The procedure shall be always inlined. - -This calculation is a simplification of the theory employed and described in :ref:`log10` and omits the considerations regarding extra precision, as this is done by the upper level procedures. - -Use the following constants as calculation/return values: - -* :math:`L1 =` ``0x3FE5555555555593 (0x3F2AAAAA)`` -* :math:`L2 =` ``0x3FD999999997FA04 (0x3ECCCE13)`` -* :math:`L3 =` ``0x3FD2492494229359 (0x3E91E9EE)`` -* :math:`L4 =` ``0x3FCC71C51D8E78AF (0x3E789E26)`` -* :math:`L5 =` ``0x3FC7466496CB03DE`` -* :math:`L6 =` ``0x3FC39A09D078C69F`` -* :math:`L7 =` ``0x3FC2F112DF3E5244`` - -The logarithm is computed by evaluating the following polynomial and return :math:`r`: - -.. math:: - :label: formula_log_internal_1 - - s &= \frac{f}{2+f} \\ - R &= L1 \cdot s^2 + L2 \cdot s^4 + L3 \cdot s^6 + L4 \cdot s^8 + L5 \cdot s^{10} +L6 \cdot s^{12} + L7 \cdot s^{14} \\ - r &= s \cdot \Big(\frac{f^2}{2} + R\Big) - -For the float version the polynomial can be shortened to: - -.. math:: - :label: formula_log_internal_2 - - s &= \frac{f}{2+f} \\ - R &= L1 \cdot s^2 + L2 \cdot s^4 + L3 \cdot s^6 + L4 \cdot s^8 \\ - r &= s \cdot \Big(\frac{f^2}{2} + R\Big) - -Requirements -^^^^^^^^^^^^ - -Internal functions do not directly implement requirements. - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/mathd/internal/log1pmfd.h -* libm/mathf/internal/log1pmff.h -* libm/mathd/internal/log1pmfd.c -* libm/mathf/internal/log1pmff.c - -References -^^^^^^^^^^ - -* :ref:`log10` -* :ref:`log1p` -* :ref:`log2` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0500_cbrt.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0500_cbrt.rst deleted file mode 100644 index cb8cfc14..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0500_cbrt.rst +++ /dev/null @@ -1,42 +0,0 @@ -cbrt -~~~~ - -.. c:autodoc:: mathd/cbrtd.c - -Special cases -^^^^^^^^^^^^^ - -+--------------------------+--------------------------+ -| x | Result | -+==========================+==========================+ -| :math:`±0` | :math:`x` | -+--------------------------+--------------------------+ -| :math:`±Inf` | :math:`x` | -+--------------------------+--------------------------+ -| :math:`NaN` | :math:`qNaN` | -+--------------------------+--------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -Implement based on the Newton-Raphson method. - -.. Here there be dragons. (TODO) - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-2300 -* REQ-ML-2310 -* REQ-ML-2320 -* REQ-ML-2340 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/cbrtd.c -* libm/mathf/cbrtf.c - -References -^^^^^^^^^^ diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0510_fabs.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0510_fabs.rst deleted file mode 100644 index 19ca1835..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0510_fabs.rst +++ /dev/null @@ -1,66 +0,0 @@ -fabs -~~~~ - -.. c:autodoc:: mathd/fabsd.c - -Special cases -^^^^^^^^^^^^^ - -+--------------------------+--------------------------+ -| x | Result | -+==========================+==========================+ -| :math:`±0` | :math:`+0` | -+--------------------------+--------------------------+ -| :math:`±Inf` | :math:`+Inf` | -+--------------------------+--------------------------+ -| :math:`qNaN` | :math:`qNaN` | -+--------------------------+--------------------------+ -| :math:`sNaN` | :math:`sNaN` | -+--------------------------+--------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -The approach is to mask off the signbit of :math:`x` and return :math:`x`. - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-1000 -* REQ-ML-1010 -* REQ-ML-1011 -* REQ-ML-1012 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/fabsd.c -* libm/mathf/fabsf.c - -References -^^^^^^^^^^ - -* :ref:`__ccoshsinh ` -* :ref:`__lgamma ` -* :ref:`__rem_pio2 ` -* :ref:`catan` -* :ref:`ccos` -* :ref:`csqrt` -* :ref:`csin` -* :ref:`ctan` -* :ref:`asin` -* :ref:`asinh` -* :ref:`atan` -* :ref:`atan2` -* :ref:`cosh` -* :ref:`erf` -* :ref:`erfc` -* :ref:`j0` -* :ref:`j1` -* :ref:`jn` -* :ref:`pow` -* :ref:`remainder` -* :ref:`remquo` -* :ref:`sinh` -* :ref:`tanh` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0520_hypot.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0520_hypot.rst deleted file mode 100644 index c715a334..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0520_hypot.rst +++ /dev/null @@ -1,74 +0,0 @@ -hypot -~~~~~ - -.. c:autodoc:: mathd/hypotd.c - -Special cases -^^^^^^^^^^^^^ - -+-----------------------------+-----------------------------+------------------------------+ -| x | y | Result | -+=============================+=============================+==============================+ -| :math:`\in \mathbb{F}` | :math:`±Inf` | :math:`+Inf` | -+-----------------------------+-----------------------------+------------------------------+ -| :math:`±Inf` | :math:`\in \mathbb{F}` | :math:`+Inf` | -+-----------------------------+-----------------------------+------------------------------+ -| :math:`NaN` | :math:`\neq ±Inf` | :math:`qNaN` | -+-----------------------------+-----------------------------+------------------------------+ -| :math:`\neq ±Inf` | :math:`NaN` | :math:`qNaN` | -+-----------------------------+-----------------------------+------------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -The approach is to first work on special values and overflows, then use :ref:`sqrt` for the calculation. - -#. Assume :math:`x > y`, otherwise replace :math:`x` with :math:`y` and :math:`y` with :math:`x`. -#. Set both :math:`x` and :math:`y` to their absolute value. -#. For :math:`\frac{x}{y} > 2^{60}` (float: :math:`2^{30}`), :math:`y` is too small to matter when the result is represented with double (float) precision, return :math:`x`. -#. For :math:`x` or :math:`y` is infinite, return ``+Inf``. -#. For :math:`x` or :math:`y` is ``NaN``, return :math:`x + y`. -#. For :math:`x > 2^{500}` (float: :math:`2^{50}`), scale down :math:`x` and :math:`y` by multiplying them with :math:`2^{-600}` (float: :math:`2^{-68}`), otherwise their combined squares will overflow the double (float) range. -#. For :math:`y < 2^{-500}` (float: :math:`2^{-50}`), scale up :math:`x` and :math:`y` by multiplying them with :math:`2^{600}` (float: :math:`2^{68}`), otherwise their combined squares will underflow the double (float) range. - -#. If :math:`z = x \cdot x + y \cdot y` has an error of less than :math:`\frac{\sqrt{2}}{2}` :ref:`ULPs `, then :math:`\sqrt{z}` has an error of less than 1 :ref:`ULP `. Using this relation calculate :math:`\sqrt{x \cdot x + y \cdot y}` as follows: - - #. If :math:`x > 2y` use the following to replace :math:`x \cdot x + y \cdot y`: - - .. math:: - :label: formula_hypot_1 - - x_1 \cdot x_1 + (y \cdot y + (x_2 \cdot (x+x_1))) - - with :math:`x_1 = x` with the lower 32bits (float: 12bits) cleared and :math:`x_2 = x - x_1`. - #. Otherwise use: - - .. math:: - :label: formula_hypot_2 - - t_1 \cdot y_1 + ((x-y) \cdot (x-y)+(t_1 \cdot y_2 + t_2 \cdot y)) - - with :math:`t_1 = 2x` with the lower 32bits (float: 12bits) cleared and :math:`t_2 = 2x - t_1`, and :math:`y_1 = y` with the lower 32bits (float: 12bits) cleared and :math:`y_2 = y - y_1`. - #. Use :ref:`sqrt` to calculate the square root of the replacement :math:numref:`formula_hypot_1` or :math:numref:`formula_hypot_2`. - -#. Revert the scaling on the resulting square root if any was done in an earlier step. -#. Return the calculated square root. - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-1260 -* REQ-ML-1270 -* REQ-ML-1271 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/hypotd.c -* libm/mathf/hypotf.c - -References -^^^^^^^^^^ - -* :ref:`sqrt` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0530_pow.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0530_pow.rst deleted file mode 100644 index 2ac2c504..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0530_pow.rst +++ /dev/null @@ -1,345 +0,0 @@ -pow -~~~~~ - -.. c:autodoc:: mathd/powd.c - -Special cases -^^^^^^^^^^^^^ - -+-------------------------------------------+---------------------------------------------------------------------+------------------------------+ -| :math:`x` | :math:`y` | Result | -+===========================================+=====================================================================+==============================+ -| :math:`<0\ \wedge \neq -Inf` | :math:`\notin \mathbb{Z}^{*}` | :math:`qNaN` | -+-------------------------------------------+---------------------------------------------------------------------+------------------------------+ -| :math:`-0` | :math:`\{2k + 1 : k \in \mathbb{Z}_{<0}\}` | :math:`-Inf` | -+-------------------------------------------+---------------------------------------------------------------------+------------------------------+ -| :math:`-0` | :math:`\in \mathbb{F}_{<0} \setminus \{2k + 1 : k \in \mathbb{Z}\}` | :math:`+Inf` | -+-------------------------------------------+---------------------------------------------------------------------+------------------------------+ -| :math:`+0` | :math:`<0` | :math:`+Inf` | -+-------------------------------------------+---------------------------------------------------------------------+------------------------------+ -| :math:`±0` | :math:`\{2k - 1 : k \in \mathbb{Z}_{>0}\}` | :math:`x` | -+-------------------------------------------+---------------------------------------------------------------------+------------------------------+ -| :math:`±0` | :math:`\in \mathbb{F}_{>0} \setminus \{2k - 1 : k \in \mathbb{Z}\}` | :math:`+0` | -+-------------------------------------------+---------------------------------------------------------------------+------------------------------+ -| :math:`-1` | :math:`±Inf` | :math:`+1` | -+-------------------------------------------+---------------------------------------------------------------------+------------------------------+ -| :math:`+1` | :math:`\in \mathbb{F} \setminus \{sNaN\}` | :math:`+1` | -+-------------------------------------------+---------------------------------------------------------------------+------------------------------+ -| :math:`\in \mathbb{F} \setminus \{sNaN\}` | :math:`±0` | :math:`+1` | -+-------------------------------------------+---------------------------------------------------------------------+------------------------------+ -| :math:`\in ]-1;1[` | :math:`-Inf` | :math:`+Inf` | -+-------------------------------------------+---------------------------------------------------------------------+------------------------------+ -| :math:`\notin [-1;1]` | :math:`-Inf` | :math:`+0` | -+-------------------------------------------+---------------------------------------------------------------------+------------------------------+ -| :math:`\in ]-1;1[` | :math:`+Inf` | :math:`+0` | -+-------------------------------------------+---------------------------------------------------------------------+------------------------------+ -| :math:`\notin [-1;1]` | :math:`+Inf` | :math:`+Inf` | -+-------------------------------------------+---------------------------------------------------------------------+------------------------------+ -| :math:`-Inf` | :math:`\{2k + 1 : k \in \mathbb{Z}_{<0}\}` | :math:`-0` | -+-------------------------------------------+---------------------------------------------------------------------+------------------------------+ -| :math:`-Inf` | :math:`\in \mathbb{F}_{<0} \setminus \{2k + 1 : k \in \mathbb{Z}\}` | :math:`+0` | -+-------------------------------------------+---------------------------------------------------------------------+------------------------------+ -| :math:`-Inf` | :math:`\{2k - 1 : k \in \mathbb{Z}_{>0}\}` | :math:`-Inf` | -+-------------------------------------------+---------------------------------------------------------------------+------------------------------+ -| :math:`-Inf` | :math:`\in \mathbb{F}_{>0} \setminus \{2k - 1 : k \in \mathbb{Z}\}` | :math:`+Inf` | -+-------------------------------------------+---------------------------------------------------------------------+------------------------------+ -| :math:`+Inf` | :math:`<0` | :math:`+0` | -+-------------------------------------------+---------------------------------------------------------------------+------------------------------+ -| :math:`+Inf` | :math:`>0` | :math:`+Inf` | -+-------------------------------------------+---------------------------------------------------------------------+------------------------------+ -| :math:`NaN` | :math:`\neq ±0` | :math:`qNaN` | -+-------------------------------------------+---------------------------------------------------------------------+------------------------------+ -| :math:`qNaN` | :math:`±0` | :math:`+1` | -+-------------------------------------------+---------------------------------------------------------------------+------------------------------+ -| :math:`sNaN` | :math:`±0` | :math:`qNaN` | -+-------------------------------------------+---------------------------------------------------------------------+------------------------------+ -| :math:`\neq +1` | :math:`NaN` | :math:`qNaN` | -+-------------------------------------------+---------------------------------------------------------------------+------------------------------+ -| :math:`+1` | :math:`qNaN` | :math:`+1` | -+-------------------------------------------+---------------------------------------------------------------------+------------------------------+ -| :math:`+1` | :math:`sNaN` | :math:`qNaN` | -+-------------------------------------------+---------------------------------------------------------------------+------------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -The approach is to first work on special values then use the following approach for the calculation: - -#. Compute :math:`log_2(x)`, with increased accuracy. -#. Find an integral value :math:`n` where :math:`y \cdot log_2(x) = n + m`, and :math:`|m| <= 0.5`. -#. Then :math:`x^y = 2^n \cdot e^{m \cdot log_2(x)}`. - -Use the following constants as calculation values: - -* :math:`ln(2) \approx lg2_h + lg2_l \approx lg2` -* :math:`lg2 =` ``0x3FE62E42FEFA39EF (0x3F317218)`` -* :math:`lg2_h =` ``0x3FE62E4300000000 (0x3F317200)`` -* :math:`lg2_l =` ``0xBE205C610CA86C39 (0x35BFBE8C)`` -* :math:`\frac{1}{ln(2)} \approx invln2_h + invln2_l \approx invln2` -* :math:`invln2 =` ``0x3FF71547652B82FE (0x3FB8AA3B)`` -* :math:`invln2_h =` ``0x3FF7154760000000 (0x3FB8AA00)`` -* :math:`invln2_l =` ``0x3E54AE0BF85DDF44 (0x36ECA570)`` -* :math:`\frac{2}{3 \cdot ln(2)} \approx cp_h + cp_l \approx cp` -* :math:`cp =` ``0x3FEEC709DC3A03FD (0x3F76384F)`` -* :math:`cp_h =` ``0x3FEEC709E0000000 (0x3F764000)`` -* :math:`cp_l =` ``0xBE3E2FE0145B01F5 (0xB8F623C6)`` -* :math:`dp_h =` ``0x3FE2B80340000000 (0x3F15C000)`` -* :math:`dp_l =` ``0x3E4CFDEB43CFD006 (0x35D1CFDC)`` -* :math:`L1 =` ``0x3FE3333333333303 (0x3F19999A)`` -* :math:`L2 =` ``0x3FDB6DB6DB6FABFF (0x3EDB6DB7)`` -* :math:`L3 =` ``0x3FD55555518F264D (0x3EAAAAAB)`` -* :math:`L4 =` ``0x3FD17460A91D4101 (0x3E8BA305)`` -* :math:`L5 =` ``0x3FCD864A93C9DB65 (0x3E6C3255)`` -* :math:`L6 =` ``0x3FCA7E284A454EEF (0x3E53f142)`` -* :math:`P1 =` ``0x3FC555555555553E (0x3E2AAAAB)`` -* :math:`P2 =` ``0xBF66C16C16BEBD93 (0xBB360B61)`` -* :math:`P3 =` ``0x3F11566AAF25DE2C (0x388AB355)`` -* :math:`P4 =` ``0xBEBBBD41C5D26BF1 (0xB5DDEA0E)`` -* :math:`P5 =` ``0x3E66376972BEA4D0 (0x3331BB4C)`` - -#. For :math:`y` is zero, return :math:`1`. -#. For :math:`x` is :math:`+1` and :math:`y` is ``NaN``, return :math:`1`. -#. For :math:`x` or :math:`y` is ``NaN``, return the result of a call to :ref:`nan`. -#. For :math:`x < 0`, determine if :math:`y` is an odd integer as follows (the result shall be saved in the variable :math:`yisint`, it shall be :math:`0` if :math:`y` is not an integer, :math:`1` if it is odd, :math:`2` if it is even): - - #. For ``highword`` of :math:`y >=` ``0x43400000`` (float: integer representation of :math:`y >=` ``0x4B800000``) [#]_, set :math:`yisint` to :math:`2`. - #. For :math:`y >= 1`: - - #. For binary exponent :math:`k` of :math:`y > 20`: - - #. Set :math:`j` to the ``lowword`` of :math:`y` shifted right by :math:`(52 - k)`. [#]_ - #. For :math:`(j` shifted left by :math:`(52 - k))` equals the ``lowword`` of :math:`y` [#]_, set :math:`yisint` to :math:`(2 -` last bit of :math:`j)`. - - #. For the ``lowword`` of :math:`y` is :math:`0`: - - #. Set :math:`j` to the ``highword`` of :math:`y` shifted right by :math:`(20 - k)`. - #. For :math:`(j` shifted left by :math:`(20 - k))` equals the ``highword`` of :math:`y`, set :math:`yisint` to :math:`(2 -` last bit of :math:`j)`. - - #. For the float version of this procedure skip the previous two steps and their substeps and replace them with: - - #. Let :math:`k` be the binary exponent of :math:`y`. - #. Set :math:`j` to the integer representation of :math:`y` shifted right by :math:`(23 - k)`. - #. For :math:`(j` shifted left by :math:`(23 - k))` equals the integer representation of :math:`y`, set :math:`yisint` to :math:`(2 -` last bit of :math:`j)`. - - #. If :math:`yisint` has not yet been set in the earlier steps, set it to :math:`0`. - -#. For ``lowword`` of :math:`y` is :math:`0` (float: omit this if-clause, but use its contents) [#]_: - - #. For :math:`y` is infinite: - - #. For :math:`x` is :math:`1`, return :math:`1`. - #. For :math:`|x| > 1`: - - #. For :math:`y` is positive, return :math:`y`. - #. Return :math:`0`. - - #. Otherwise: - - #. For :math:`y` is positive, return :math:`0`. - #. Return :math:`-y`. - - #. For :math:`y` is :math:`1`, return :math:`x`. - #. For :math:`y` is :math:`-1`, return :math:`\frac{1}{x}`. - #. For :math:`y` is :math:`2`, return :math:`x \cdot x`. - #. For :math:`y` is :math:`0.5` and :math:`x` greater than or equal to positive zero, return :math:`\sqrt{x}`, using :ref:`sqrt` to calculate the square root of :math:`x`. - -#. Let :math:`ax = |x|`, using :ref:`fabs` to calculate the absolute value of :math:`x`. -#. For :math:`x` is infinite, a zero, :math:`-1` or :math:`1`: - - #. For :math:`y < 0`, let :math:`z = \frac{1}{|x|} = \frac{1}{ax}`. - #. For :math:`x < 0`: - - #. For :math:`yisint` is :math:`0` (:math:`y` is not an integer) and :math:`x` is :math:`-1`, let :math:`z =` ``NaN``. - #. For :math:`yisint` is :math:`1` (:math:`y` is an odd integer), let :math:`z = -z`. - - #. Return :math:`z`. - -#. For :math:`yisint` is :math:`0` (:math:`y` is not an integer) and :math:`x < 0`, return ``NaN``. -#. For :math:`yisint` is :math:`1` (:math:`y` is an odd integer) and :math:`x < 0`, set :math:`sn = -1`, otherwise set :math:`sn = +1` (this contains the sign for the final result). -#. For :math:`|y| > 2^{31}` (float: :math:`|y| > 2^{27}`): - - #. For :math:`|y| > 2^{64}`, as for such high :math:`y` either an under- or overflow is guaranteed (float: omit this step and its substeps): - - #. For :math:`|x| < 1`: - - #. For :math:`y < 0`, return infinity with sign of :math:`sn`. - #. Return :math:`0` with sign of :math:`sn`. - - #. Otherwise: - - #. For :math:`y > 0`, return infinity with sign of :math:`sn`. - #. Return :math:`0` with sign of :math:`sn`. - - #. For ``highword`` of :math:`|x| <` ``0x3FEFFFFF`` (float: integer representation of :math:`|x| <` ``0x3F7FFFF4``) [#]_: - - #. For :math:`y < 0`, return positive infinity (float: return infinity with sign of :math:`sn`). - #. Return :math:`0` (float: return :math:`0` with sign of :math:`sn`). - - #. For ``highword`` of :math:`|x| >` ``0x3FF00000`` (float: integer representation of :math:`|x| >` ``0x3F800007``) [#]_: - - #. For :math:`y > 0`, return positive infinity (float: return infinity with sign of :math:`sn`). - #. Return :math:`0` (float: return :math:`0` with sign of :math:`sn`). - - #. Set :math:`t = |x| - 1 = ax - 1`. - #. Set :math:`w = t^2 \cdot (\frac{1}{2} - t \cdot (\frac{1}{3} - t \cdot \frac{1}{4}))` which is an approximation for :math:`log(x)` for :math:`x` close to :math:`1`. - #. Set :math:`t1 = invln2_{h} \cdot t + (t \cdot invln2_{l} - w \cdot invln2)`, with ``lowword`` masked to :math:`0` (float: with the 12 lowest bits masked to :math:`0`). - #. Set :math:`t2 = (t \cdot invln2_{l} - w \cdot invln2) - (t1 - invln2_{h} \cdot t)`. - -#. Otherwise: - - #. For :math:`x` is subnormal, scale :math:`x` and :math:`ax` by multiplying them with :math:`2^{53}` (float: :math:`2^{24}`). - #. Set :math:`n` to the exponent of the original :math:`x` [#]_. - #. Normalize :math:`ix` by setting the exponent to :math:`0` [#]_. - #. For :math:`|x| < \sqrt{\frac{3}{2}}` [#]_, set :math:`k` to :math:`0`. - #. For :math:`|x| < \sqrt{3}` [#]_, set :math:`k` to :math:`1`. - #. If :math:`k` has not been set in the two previous steps, set :math:`k` to :math:`0`, increase :math:`n` by :math:`1`, and decrease the exponent of :math:`ix` by :math:`1`. - #. Set the ``highword`` of :math:`ax` to :math:`ix` (float: Set :math:`ax` to :math:`ix`). - #. Compute :math:`s = \frac{ax-bp}{ax+bp}`, with :math:`bp = 1+\frac{k}{2}`, with increased accuracy by splitting :math:`s` into :math:`s_{h} + s_{l}` by using the following formulae: - - .. math:: - :label: formula_pow_1 - - s &= \frac{ax-bp}{ax+bp} \\ - s_{h} &= highword\ of \bigg(\frac{ax-bp}{ax+bp}\bigg) \\ - s_{l} &= \frac{1}{ax+bp} \cdot (((ax-bp) - s_{h} \cdot t_{h}) - s_{h} \cdot t_{l}) - - with - - #. :math:`t_{h} = ax + bp` with ``lowword`` (float: lowest 12 bits) set to all zeroes. - #. :math:`t_{l} = ax - (t_{h}-bp)`. - - For float replace :math:`s_{h}` in formula :math:numref:`formula_pow_1` with :math:`s_{h} = \bigg(\frac{ax-bp}{ax+bp}\bigg)` with the lowest 12 bits set to all zeroes. - - #. Compute the logarithm of :math:`ax` with the following approximation (the theory behind the approximation is similar (smaller polynomial and in range :math:`[\frac{\sqrt{3}}{2}, \sqrt{3}]`) to the one expressed for :ref:`log` and will not be presented here): - - .. math:: - :label: formula_pow_2 - - R(s) &= s^2 \cdot (L1 + s^2 \cdot (L2 + s^2 \cdot (L3 + s^2 \cdot (L4 + s^2 \cdot (L5 + s^2 \cdot L6))))) \\ - r &= s^2 \cdot R(s) + s_{l} \cdot (s_{h} + s) \\ - t_{h} &= 3 + s_{h}^2 + r \quad \wedge \quad lowword\ of\ t_{h}\ set\ to\ all\ zeroes \\ - t_{l} &= r - ((t_{h} - 3) - s_{h}^2) \\ - p_{h} &= s_{h} \cdot t_{h} + (s_{l} \cdot t_{h} + t_{l} \cdot s) \quad \wedge \quad lowword\ of\ p_{h}\ set\ to\ all\ zeroes \\ - p_{l} &= (s_{l} \cdot t_{h} + t_{l} \cdot s) - (p_{h} - (s_{h} \cdot t_{h})) \\ - z_{h} &= cp_h \cdot p_h \\ - z_{l} &= cp_l \cdot p_h + p_l \cdot cp + dp_l \\ - t1 &= z_h+z_l+dp_h+n \\ - t2 &= z_l-(((t1-n)-dp_h)-z_h) - - with - - #. :math:`dp_h` and :math:`dp_l` are zero if :math:`k` is zero, otherwise they have the values described at the beginning. - - For float replace :math:`t_{h}` in formula :math:numref:`formula_pow_2` with :math:`t_{h} = 3 + s_{h}^2 + r` with the lowest 12 bits set to all zeroes, and replace :math:`p_{h}` with :math:`p_{h} = s_{h} \cdot t_{h} + (s_{l} \cdot t_{h} + t_{l} \cdot s)` with the lowest 12 bits set to all zeroes. - -#. Split :math:`y` into :math:`y1 + y2`: - - #. :math:`y1 = y` with ``lowword`` (float: lowest 12 bits) set to all zeroes. - #. :math:`y2 = y - y1`. - -#. Calculate :math:`y \cdot log_2(x)` as follows: - - .. math:: - :label: formula_pow_3 - - p_{l} &= y2 \cdot t1 + y \cdot t2 \\ - p_{h} &= y1 \cdot t1 \\ - y \cdot log_2(x) &= p_l + p_h - -#. For :math:`y \cdot log_2(x) >= 1024` (float: :math:`y \cdot log_2(x) >= 128`): - - #. For :math:`y \cdot log_2(x) > 1024` (float: :math:`y \cdot log_2(x) > 128`) return infinity with the sign of :math:`s`. - #. For :math:`p_l + ovt > y \cdot log_2(x) - p_h`, with :math:`ovt = 8.0085662595372944372 \cdot 10^{-17}` (float: :math:`ovt = 4.2995665694 \cdot 10^{-8}`) [#]_, return infinity with the sign of :math:`s`. - -#. For :math:`y \cdot log_2(x) <= -1075` (float: :math:`y \cdot log_2(x) <= -150`): - - #. For :math:`y \cdot log_2(x) < -1075` (float: :math:`y \cdot log_2(x) < -150`) return zero with the sign of :math:`s`. - #. For :math:`p_l <= y \cdot log_2(x) - p_h` return zero with the sign of :math:`s`. - -#. Calculate :math:`e^{m \cdot log_2(x)}`: - - #. Set :math:`k =` exponent of :math:`y \cdot log_2(x)`, and :math:`n = 0`. - #. For :math:`|y \cdot log_2(x)| > 0.5`: - - #. Set :math:`n = ` ``highword`` (float: integer representation) of :math:`(y \cdot log_2(x) + 0.5)`. - #. Set :math:`k =` exponent of :math:`n`. - #. Set :math:`t` to a new double (float) with (exponent of :math:`n` including sign) right shifted by :math:`k` as ``highword``, and all zeros as ``lowword`` (float: right shift by :math:`k`). - #. Replace the exponent of :math:`n` with :math:`1`, then right shift :math:`n` by :math:`(20-k)` (float: :math:`(23-k)`). - #. For :math:`y \cdot log_2(x) < 0` set the sign of :math:`n`. - #. Set :math:`p_h = p_h - t`. - - #. Calculate :math:`e^{m \cdot log_2(x)}` with the following approximation (the theory behind the approximation is the one expressed for :ref:`exp` and will not be presented here): - - .. math:: - :label: formula_pow_4 - - t &= p_l + p_h \quad \wedge \quad lowword\ of\ t\ set\ to\ all\ zeroes \\ - z &= (t \cdot lg2_h) + ((p_l-(t-p_h)) \cdot lg2 + t \cdot lg2_l) \\ - w &= ((p_l-(t-p_h)) \cdot lg2 + t \cdot lg2_l) - (z - (t \cdot lg2_h)) \\ - t1 &= z - z^2 \cdot (P1 + z^2 \cdot (P2 + z^2 \cdot (P3 + z^2 \cdot (P4 + z^2 \cdot P5)))) \\ - r &= \frac{z \cdot t1}{t1-2}-(w+z \cdot w) \\ - e^{m \cdot log_2(x)} &= 1 - (r-z) - - For float replace :math:`t` in formula :math:numref:`formula_pow_4` with :math:`t = p_l + p_h` with the lowest 12 bits set to all zeroes. - -#. For (exponent of :math:`e^{m \cdot log_2(x)} + n) <= 0`: - - #. Set :math:`z = e^{m \cdot log_2(x)} \cdot 2^n`, using the :ref:`scalbn` function. - #. Return :math:`z` with sign of :math:`s`. - -#. Set :math:`z = e^{m \cdot log_2(x)}` with exponent set to :math:`n`. -#. Return :math:`z` with sign of :math:`sn`. - -.. [#] This means that :math:`y` can only be even, as the exponent is so high that only integral values that are multiples of :math:`2` are possible. -.. [#] In this case the lowest bit of :math:`j` is the lowest bit that is in the integer part of :math:`y`. -.. [#] In this case the lowest :math:`(52 - k)` bits of :math:`y` are :math:`0`, therefore :math:`y` has no fractional part and is integral. -.. [#] This is used to combine the other special cases for :math:`y`, so that they can be skipped altogether instead of one after another which improves the performance of the 'normal' cases. -.. [#] This means that :math:`(1-x) >= 2^{-20}`. -.. [#] This means that :math:`(1-x) <= -2^{-20}`. -.. [#] This shall be the real binary exponent: subnormals have an exponent :math:`< -1022` (float: :math:`< -128`). -.. [#] Set the three highest bytes of :math:`ix` to ``0x3FF0`` (float: ``0x3F80``). -.. [#] This is when (:math:`ix` with exponent masked) :math:`<` ``0x3988E`` (float: :math:`<` ``0x1CC471``). -.. [#] This is when (:math:`ix` with exponent masked) :math:`<` ``0xBB67A`` (float: :math:`<` ``0x5DB3D7``). -.. [#] Which equals :math:`-(1024-log_2(overflow+0.5\ ULP))` (float: :math:`-(128-log_2(overflow+0.5\ ULP))`). - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-0850 -* REQ-ML-0860 -* REQ-ML-0864 -* REQ-ML-0870 -* REQ-ML-0871 -* REQ-ML-0872 -* REQ-ML-0873 -* REQ-ML-0874 -* REQ-ML-0875 -* REQ-ML-0876 -* REQ-ML-0877 -* REQ-ML-0878 -* REQ-ML-0879 -* REQ-ML-0880 -* REQ-ML-0881 -* REQ-ML-0882 -* REQ-ML-0883 -* REQ-ML-0885 -* REQ-ML-0886 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/powd.c -* libm/mathf/powf.c - -References -^^^^^^^^^^ - -* :ref:`cpow` -* :ref:`exp` -* :ref:`exp2` -* :ref:`fabs` -* :ref:`log` -* :ref:`nan` -* :ref:`scalbn` -* :ref:`sqrt` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0540_sqrt.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0540_sqrt.rst deleted file mode 100644 index e7108816..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0540_sqrt.rst +++ /dev/null @@ -1,124 +0,0 @@ -sqrt -~~~~ - -.. c:autodoc:: mathd/sqrtd.c - -Special cases -^^^^^^^^^^^^^ - -+--------------------------+--------------------------+ -| x | Result | -+==========================+==========================+ -| :math:`<0` | :math:`qNaN` | -+--------------------------+--------------------------+ -| :math:`±0` | :math:`x` | -+--------------------------+--------------------------+ -| :math:`-Inf` | :math:`qNaN` | -+--------------------------+--------------------------+ -| :math:`+Inf` | :math:`+Inf` | -+--------------------------+--------------------------+ -| :math:`NaN` | :math:`qNaN` | -+--------------------------+--------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -The approach is to first work on special values and then use mostly bit-fiddling for the calculation. - -#. For :math:`x` is :math:`NaN`, return :math:`qNaN`. -#. For :math:`x` is positive infinity, return positive infinity. -#. For :math:`x` is negative infinity, return :math:`qNaN`. [#]_ -#. For :math:`x` is a zero, return the zero with the same sign. -#. For :math:`x` is negative, return :math:`qNaN`. -#. Given :math:`x` find :math:`y` and integer :math:`k` such that the formula - - .. math:: - :label: formula_sqrt_1 - - y &= x \cdot 2 ^ {-2k} \\ - \Leftrightarrow \qquad \sqrt{x} &= 2^{k} \cdot \sqrt{y} - - with :math:`y \in [1.0, 4.0)` [#]_ \\ - holds true. [#]_ -#. Compute the square root bit by bit [#]_: - - #. Let :math:`q_i` be :math:`\sqrt{y}` truncated to :math:`i` bit after the binary point (:math:`q_0 = 1`), then - - .. math:: - :label: formula_sqrt_2 - - y_i = 2 ^ {i+1} \cdot (y - q_i^2) - - #. To compute :math:`q_{i+1}` from :math:`q_i`, check whether - - .. math:: - :label: formula_sqrt_3 - - (q_i + 2^{-(i+1)})^2 <= y - - is false, if yes :math:`q_{i+1} = q_i`, else :math:`q_{i+1} = q_i + 2^{-(i+1)}`. - #. With :math:`s_i = 2 q_i` formula :math:numref:`formula_sqrt_3` is equivalent to [#]_ - - .. math:: - :label: formula_sqrt_4 - - s_i + 2^{-(i+1)} <= y_i - - #. With formula :math:numref:`formula_sqrt_4` one can compute :math:`s_i` and :math:`y_i` with the following recurrence formula: - - If formula :math:numref:`formula_sqrt_4` is false: - - .. math:: - :label: formula_sqrt_5 - - s_{i+1} = s_i \wedge y_{i+1} = y_i - - otherwise: - - .. math:: - :label: formula_sqrt_6 - - s_{i+1} = s_i + 2^{-i} \wedge y_{i+1} = y_i - s_i - 2^{-(i+1)} - -#. When done with computing the 53-bit result in the previous step, compute another bit. Use this bit added to the remainder to correctly round the calculated square root. -#. Use formula :math:numref:`formula_sqrt_1` to return :math:`y` to :math:`x`. -#. Return :math:`x`. - -.. [#] The first three steps can be combined by checking that :math:`x` is not finite and returning :math:`x \cdot x + x`, which returns the correct value for all three cases -.. [#] With this trick one can ensure that :math:`\sqrt{y}` truncates to :math:`1`. -.. [#] Take special care with subnormal numbers. -.. [#] As shown in John von Neumann's *First Draft of a Report on the EDVAC* in section 10.1. -.. [#] Since the left hand side of this formula only contains :math:`i+2` bits it is not necessary to do a full (53-bit) comparison. - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-0700 -* REQ-ML-0710 -* REQ-ML-0720 -* REQ-ML-0730 -* REQ-ML-0740 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/sqrtd.c -* libm/mathf/sqrtf.c - -References -^^^^^^^^^^ - -* :ref:`acos` -* :ref:`acosh` -* :ref:`asin` -* :ref:`asinh` -* :ref:`csqrt` -* :ref:`hypot` -* :ref:`j0` -* :ref:`j1` -* :ref:`jn` -* :ref:`pow` -* :ref:`y0` -* :ref:`y1` -* :ref:`yn` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0600_erf.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0600_erf.rst deleted file mode 100644 index 0d300628..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0600_erf.rst +++ /dev/null @@ -1,51 +0,0 @@ -erf -~~~ - -.. c:autodoc:: mathd/erfd.c - -Special cases -^^^^^^^^^^^^^ - -+--------------------------------------+--------------------------------------+ -| x | Result | -+======================================+======================================+ -| :math:`±0` | :math:`x` | -+--------------------------------------+--------------------------------------+ -| :math:`±Inf` | :math:`x` | -+--------------------------------------+--------------------------------------+ -| :math:`\in \mathbb{S}` | :math:`\frac{2}{\sqrt{\pi}} \cdot x` | -+--------------------------------------+--------------------------------------+ -| :math:`NaN` | :math:`qNaN` | -+--------------------------------------+--------------------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -Implement based on a polynomial approximation. - -.. Here there be dragons. (TODO) - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-3600 -* REQ-ML-3610 -* REQ-ML-3620 -* REQ-ML-3630 -* REQ-ML-3640 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/erfd.c -* libm/mathf/erff.c -* libm/mathd/internal/errorfunctiond.h -* libm/mathf/internal/errorfunctionf.h - -References -^^^^^^^^^^ - -* :ref:`erfc` -* :ref:`exp` -* :ref:`fabs` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0610_erfc.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0610_erfc.rst deleted file mode 100644 index e975887c..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0610_erfc.rst +++ /dev/null @@ -1,51 +0,0 @@ -erfc -~~~~ - -.. c:autodoc:: mathd/erfcd.c - -Special cases -^^^^^^^^^^^^^ - -+--------------------------------------+--------------------------------------+ -| x | Result | -+======================================+======================================+ -| :math:`±0` | :math:`+1` | -+--------------------------------------+--------------------------------------+ -| :math:`-Inf` | :math:`+2` | -+--------------------------------------+--------------------------------------+ -| :math:`+Inf` | :math:`+0` | -+--------------------------------------+--------------------------------------+ -| :math:`NaN` | :math:`qNaN` | -+--------------------------------------+--------------------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -Implement based on a polynomial approximation. - -.. Here there be dragons. (TODO) - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-3700 -* REQ-ML-3710 -* REQ-ML-3720 -* REQ-ML-3730 -* REQ-ML-3740 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/erfcd.c -* libm/mathf/erfcf.c -* libm/mathd/internal/errorfunctiond.h -* libm/mathf/internal/errorfunctionf.h - -References -^^^^^^^^^^ - -* :ref:`erf` -* :ref:`exp` -* :ref:`fabs` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0620_lgamma.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0620_lgamma.rst deleted file mode 100644 index 5aecaf6f..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0620_lgamma.rst +++ /dev/null @@ -1,52 +0,0 @@ -lgamma -~~~~~~ - -.. c:autodoc:: mathd/lgammad.c - -Special cases -^^^^^^^^^^^^^ - -+--------------------------------------+--------------------------------------+ -| x | Result | -+======================================+======================================+ -| :math:`\in \mathbb{Z}_{<0}` | :math:`+Inf` | -+--------------------------------------+--------------------------------------+ -| :math:`±0` | :math:`+Inf` | -+--------------------------------------+--------------------------------------+ -| :math:`+1` | :math:`+0` | -+--------------------------------------+--------------------------------------+ -| :math:`+2` | :math:`+0` | -+--------------------------------------+--------------------------------------+ -| :math:`±Inf` | :math:`+Inf` | -+--------------------------------------+--------------------------------------+ -| :math:`NaN` | :math:`qNaN` | -+--------------------------------------+--------------------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -Call :ref:`__lgamma ` with :math:`x` and a pointer to :ref:`signgam`. - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-3800 -* REQ-ML-3810 -* REQ-ML-3820 -* REQ-ML-3830 -* REQ-ML-3840 -* REQ-ML-3850 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/lgammad.c -* libm/mathf/lgammaf.c - -References -^^^^^^^^^^ - -* :ref:`__lgamma ` -* :ref:`signgam` -* :ref:`tgamma` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0630_tgamma.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0630_tgamma.rst deleted file mode 100644 index b3262c9a..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0630_tgamma.rst +++ /dev/null @@ -1,50 +0,0 @@ -tgamma -~~~~~~ - -.. c:autodoc:: mathd/tgammad.c - -Special cases -^^^^^^^^^^^^^ - -+--------------------------------------+--------------------------------------+ -| x | Result | -+======================================+======================================+ -| :math:`-Inf` | :math:`qNaN` | -+--------------------------------------+--------------------------------------+ -| :math:`\in \mathbb{Z}_{<0}` | :math:`qNaN` | -+--------------------------------------+--------------------------------------+ -| :math:`±0` | :math:`±Inf` | -+--------------------------------------+--------------------------------------+ -| :math:`+Inf` | :math:`+Inf` | -+--------------------------------------+--------------------------------------+ -| :math:`NaN` | :math:`qNaN` | -+--------------------------------------+--------------------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -Call :ref:`__lgamma ` with :math:`x` and a local pointer to receive the sign. Use the result of :ref:`__lgamma ` as input for :ref:`exp` and use the local pointer with the sign to decide the sign of the result of the :ref:`exp` call. Return the now correctly signed result. - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-5800 -* REQ-ML-5810 -* REQ-ML-5820 -* REQ-ML-5830 -* REQ-ML-5840 -* REQ-ML-5841 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/tgammad.c -* libm/mathf/tgammaf.c - -References -^^^^^^^^^^ - -* :ref:`__lgamma ` -* :ref:`exp` -* :ref:`lgamma` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0640_gamma_internal.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0640_gamma_internal.rst deleted file mode 100644 index 003052fc..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0640_gamma_internal.rst +++ /dev/null @@ -1,42 +0,0 @@ -.. _internal_gamma: - -Internal Gamma Functions -~~~~~~~~~~~~~~~~~~~~~~~~ - -.. c:autodoc:: mathd/internal/gammad.c - -Special cases -^^^^^^^^^^^^^ - -The special cases are in the external functions :ref:`lgamma` and :ref:`tgamma`. - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -``__lgamma``: Implement based on a rational approximation. - -.. Here there be dragons. (TODO) - -``__sin_pi``: Implement based on :ref:`__cos `, and :ref:`__sin `. - -.. Here there be dragons. (TODO) - -Requirements -^^^^^^^^^^^^ - -Internal functions do not directly implement requirements. - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/mathd/internal/gammad.c -* libm/mathd/internal/gammad.h -* libm/mathf/internal/gammaf.c -* libm/mathf/internal/gammaf.h - -References -^^^^^^^^^^ - -* :ref:`__cos, __sin ` -* :ref:`lgamma` -* :ref:`tgamma` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0650_signgam.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0650_signgam.rst deleted file mode 100644 index a4a0086d..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0650_signgam.rst +++ /dev/null @@ -1,25 +0,0 @@ -signgam -~~~~~~~ - -.. c:autodoc:: common/signgam.c - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -Simply provide a global variable :math:`signgam` by using a macro around an internal variable :math:`\_\_signgam`. - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-3850 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/common/signgam.c - -References -^^^^^^^^^^ - -* :ref:`lgamma` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0700_ceil.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0700_ceil.rst deleted file mode 100644 index 2951846b..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0700_ceil.rst +++ /dev/null @@ -1,76 +0,0 @@ -ceil -~~~~ - -.. c:autodoc:: mathd/ceild.c - -Special cases -^^^^^^^^^^^^^ - -+--------------------------+--------------------------+ -| x | Result | -+==========================+==========================+ -| :math:`±0` | :math:`x` | -+--------------------------+--------------------------+ -| :math:`±Inf` | :math:`x` | -+--------------------------+--------------------------+ -| :math:`NaN` | :math:`NaN` | -+--------------------------+--------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -The approach is to first check whether the input is fractional, then remove the fraction and round in the correct direction. - -#. All the following return values shall have the same sign as the input value. -#. If the exponent is :math:`< 20`, the integral part of :math:`x` is in the double's highword: - - #. If the exponent is :math:`< 0`, there is no integral part: - - #. If the input is :math:`<= 0`, return a zero. - #. Return :math:`1`. - - #. If :math:`x` is integral, return :math:`x`. - #. Return :math:`x` rounded towards positive infinity. - -#. If the exponent is :math:`> 51`, there is no fractional part: - - #. If the exponent is :math:`= 1024`, :math:`x` is :math:`NaN` or infinite, return :math:`x+x`. - #. Return :math:`x`. - -#. If :math:`x` is integral, return :math:`x`. -#. Return :math:`x` rounded towards positive infinity. - -For the float version the approach can be shortened: - -#. All the following return values shall have the same sign as the input value. -#. If the exponent is :math:`< 23`, there may be a fractional part: - - #. If the exponent is :math:`< 0`, there is no integral part: - - #. If the input is :math:`<= 0`, return a zero. - #. Return :math:`1`. - - #. If :math:`x` is integral, return :math:`x`. - #. Return :math:`x` rounded towards positive infinity. - -#. If the input is not finite, return :math:`x+x`. -#. Return :math:`x`. - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-1080 -* REQ-ML-1091 -* REQ-ML-1092 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/ceild.c -* libm/mathf/ceilf.c - -References -^^^^^^^^^^ - -* :ref:`floor` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0710_floor.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0710_floor.rst deleted file mode 100644 index 20dd779b..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0710_floor.rst +++ /dev/null @@ -1,76 +0,0 @@ -floor -~~~~~ - -.. c:autodoc:: mathd/floord.c - -Special cases -^^^^^^^^^^^^^ - -+--------------------------+--------------------------+ -| x | Result | -+==========================+==========================+ -| :math:`±0` | :math:`x` | -+--------------------------+--------------------------+ -| :math:`±Inf` | :math:`x` | -+--------------------------+--------------------------+ -| :math:`NaN` | :math:`NaN` | -+--------------------------+--------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -The approach is to first check whether the input is fractional, then remove the fraction and round in the correct direction. - -#. All the following return values shall have the same sign as the input value. -#. If the exponent is :math:`< 20`, the integral part of :math:`x` is in the double's highword: - - #. If the exponent is :math:`< 0`, there is no integral part: - - #. If the input is :math:`>= 0`, return a zero. - #. Return :math:`-1`. - - #. If :math:`x` is integral, return :math:`x`. - #. Return :math:`x` rounded towards negative infinity. - -#. If the exponent is :math:`> 51`, there is no fractional part: - - #. If the exponent is :math:`= 1024`, :math:`x` is :math:`NaN` or infinite, return :math:`x+x`. - #. Return :math:`x`. - -#. If :math:`x` is integral, return :math:`x`. -#. Return :math:`x` rounded towards negative infinity. - -For the float version the approach can be shortened: - -#. All the following return values shall have the same sign as the input value. -#. If the exponent is :math:`< 23`, there may be a fractional part: - - #. If the exponent is :math:`< 0`, there is no integral part: - - #. If the input is :math:`>= 0`, return a zero. - #. Return :math:`-1`. - - #. If :math:`x` is integral, return :math:`x`. - #. Return :math:`x` rounded towards negative infinity. - -#. If the input is not finite, return :math:`x+x`. -#. Return :math:`x`. - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-1040 -* REQ-ML-1051 -* REQ-ML-1052 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/floord.c -* libm/mathf/floorf.c - -References -^^^^^^^^^^ - -* :ref:`ceil` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0720_nearbyint.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0720_nearbyint.rst deleted file mode 100644 index 17fefc39..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0720_nearbyint.rst +++ /dev/null @@ -1,43 +0,0 @@ -nearbyint -~~~~~~~~~ - -.. c:autodoc:: mathd/nearbyintd.c - -Special cases -^^^^^^^^^^^^^ - -+--------------------------+--------------------------+ -| x | Result | -+==========================+==========================+ -| :math:`±0` | :math:`x` | -+--------------------------+--------------------------+ -| :math:`±Inf` | :math:`x` | -+--------------------------+--------------------------+ -| :math:`NaN` | :math:`NaN` | -+--------------------------+--------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -Call :ref:`rint`. - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-4500 -* REQ-ML-4510 -* REQ-ML-4520 -* REQ-ML-4540 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/nearbyintd.c -* libm/mathf/nearbyintf.c - -References -^^^^^^^^^^ - -* :ref:`rint` -* :ref:`round` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0730_rint.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0730_rint.rst deleted file mode 100644 index 8a662176..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0730_rint.rst +++ /dev/null @@ -1,45 +0,0 @@ -rint -~~~~ - -.. c:autodoc:: mathd/rintd.c - -Special cases -^^^^^^^^^^^^^ - -+--------------------------+--------------------------+ -| x | Result | -+==========================+==========================+ -| :math:`±0` | :math:`x` | -+--------------------------+--------------------------+ -| :math:`±Inf` | :math:`x` | -+--------------------------+--------------------------+ -| :math:`NaN` | :math:`NaN` | -+--------------------------+--------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -Implement based on bit-fiddling. - -.. Here there be dragons. (TODO) - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-4600 -* REQ-ML-4610 -* REQ-ML-4620 -* REQ-ML-4640 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/rintd.c -* libm/mathf/rintf.c - -References -^^^^^^^^^^ - -* :ref:`nearbyint` -* :ref:`round` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0740_lrint.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0740_lrint.rst deleted file mode 100644 index 6cd2a35f..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0740_lrint.rst +++ /dev/null @@ -1,51 +0,0 @@ -lrint -~~~~~ - -.. c:autodoc:: mathd/lrintd.c - -Special cases -^^^^^^^^^^^^^ - -+------------------------------------+------------------------------------+ -| x | Result | -+====================================+====================================+ -| :math:`±0` | :math:`0` | -+------------------------------------+------------------------------------+ -| :math:`-Inf` | min :math:`\mathbb{I}_l` | -+------------------------------------+------------------------------------+ -| :math:`<` min :math:`\mathbb{I}_l` | min :math:`\mathbb{I}_l` | -+------------------------------------+------------------------------------+ -| :math:`>` max :math:`\mathbb{I}_l` | max :math:`\mathbb{I}_l` | -+------------------------------------+------------------------------------+ -| :math:`+Inf` | max :math:`\mathbb{I}_l` | -+------------------------------------+------------------------------------+ -| :math:`NaN` | :math:`lrint(±Inf)` | -+------------------------------------+------------------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -Implement based on bit-fiddling. - -.. Here there be dragons. (TODO) - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-4650 -* REQ-ML-4653 -* REQ-ML-4656 -* REQ-ML-4659 -* REQ-ML-4662 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/lrintd.c -* libm/mathf/lrintff.c - -References -^^^^^^^^^^ - -* :ref:`rint` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0750_llrint.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0750_llrint.rst deleted file mode 100644 index 8710906e..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0750_llrint.rst +++ /dev/null @@ -1,47 +0,0 @@ -llrint -~~~~~~ - -.. c:autodoc:: mathd/llrintd.c - -Special cases -^^^^^^^^^^^^^ - -+---------------------------------------+---------------------------------------+ -| x | Result | -+=======================================+=======================================+ -| :math:`±0` | :math:`0` | -+---------------------------------------+---------------------------------------+ -| :math:`-Inf` | min :math:`\mathbb{I}_{ll}` | -+---------------------------------------+---------------------------------------+ -| :math:`<` min :math:`\mathbb{I}_{ll}` | min :math:`\mathbb{I}_{ll}` | -+---------------------------------------+---------------------------------------+ -| :math:`>` max :math:`\mathbb{I}_{ll}` | max :math:`\mathbb{I}_{ll}` | -+---------------------------------------+---------------------------------------+ -| :math:`+Inf` | max :math:`\mathbb{I}_{ll}` | -+---------------------------------------+---------------------------------------+ -| :math:`NaN` | :math:`llrint(±Inf)` | -+---------------------------------------+---------------------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -Implement based on bit-fiddling. - -.. Here there be dragons. (TODO) - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-4670 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/llrintd.c -* libm/mathf/llrintf.c - -References -^^^^^^^^^^ - -* :ref:`lrint` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0760_round.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0760_round.rst deleted file mode 100644 index a20dcac9..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0760_round.rst +++ /dev/null @@ -1,77 +0,0 @@ -round -~~~~~ - -.. c:autodoc:: mathd/roundd.c - -Special cases -^^^^^^^^^^^^^ - -+--------------------------+--------------------------+ -| x | Result | -+==========================+==========================+ -| :math:`±0` | :math:`x` | -+--------------------------+--------------------------+ -| :math:`±Inf` | :math:`x` | -+--------------------------+--------------------------+ -| :math:`NaN` | :math:`NaN` | -+--------------------------+--------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -The approach is to first check whether the input is fractional, then remove the fraction and round in the correct direction. - -#. All the following return values shall have the same sign as the input value. -#. If the exponent is :math:`< 20`, the integral part of :math:`x` is in the double's highword: - - #. If the exponent is :math:`< 0`, there is no integral part: - - #. If the exponent is :math:`-1`, return a zero. - #. Return a one. - - #. If the input is integral, return :math:`x`. - #. Return :math:`x` rounded to the nearest integer, with halfway cases rounded away from zero, regardless of the current rounding direction. - -#. If the exponent is :math:`> 51`, there is no fractional part: - - #. If the exponent is :math:`= 1024`, :math:`x` is :math:`NaN` or infinite, return :math:`x+x`. - #. Return :math:`x`. - -#. If the input is integral, return :math:`x`. -#. Return :math:`x` rounded to the nearest integer, with halfway cases rounded away from zero, regardless of the current rounding direction. - -For the float version the approach can be shortened: - -#. All the following return values shall have the same sign as the input value. -#. If the exponent is :math:`< 23`, there may be a fractional part: - - #. If the exponent is :math:`< 0`, there is no integral part: - - #. If the exponent is :math:`-1`, return a zero. - #. Return a one. - - #. If the input is integral, return :math:`x`. - #. Return :math:`x` rounded to the nearest integer, with halfway cases rounded away from zero, regardless of the current rounding direction. - -#. If the exponent is :math:`= 128`, :math:`x` is :math:`NaN` or infinite, return :math:`x+x`. -#. Return :math:`x`. - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-1020 -* REQ-ML-1031 -* REQ-ML-1032 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/roundd.c -* libm/mathf/roundf.c - -References -^^^^^^^^^^ - -* :ref:`nearbyint` -* :ref:`rint` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0770_lround.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0770_lround.rst deleted file mode 100644 index 3a0b3a02..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0770_lround.rst +++ /dev/null @@ -1,51 +0,0 @@ -lround -~~~~~~ - -.. c:autodoc:: mathd/lroundd.c - -Special cases -^^^^^^^^^^^^^ - -+------------------------------------+------------------------------------+ -| x | Result | -+====================================+====================================+ -| :math:`±0` | :math:`0` | -+------------------------------------+------------------------------------+ -| :math:`-Inf` | min :math:`\mathbb{I}_l` | -+------------------------------------+------------------------------------+ -| :math:`<` min :math:`\mathbb{I}_l` | min :math:`\mathbb{I}_l` | -+------------------------------------+------------------------------------+ -| :math:`>` max :math:`\mathbb{I}_l` | max :math:`\mathbb{I}_l` | -+------------------------------------+------------------------------------+ -| :math:`+Inf` | max :math:`\mathbb{I}_l` | -+------------------------------------+------------------------------------+ -| :math:`NaN` | :math:`lround(±Inf)` | -+------------------------------------+------------------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -Implement based on bit-fiddling. - -.. Here there be dragons. (TODO) - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-8300 -* REQ-ML-8310 -* REQ-ML-8320 -* REQ-ML-8330 -* REQ-ML-8340 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/lroundd.c -* libm/mathf/lroundf.c - -References -^^^^^^^^^^ - -* :ref:`round` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0780_llround.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0780_llround.rst deleted file mode 100644 index 6f440590..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0780_llround.rst +++ /dev/null @@ -1,47 +0,0 @@ -llround -~~~~~~~ - -.. c:autodoc:: mathd/llroundd.c - -Special cases -^^^^^^^^^^^^^ - -+---------------------------------------+---------------------------------------+ -| x | Result | -+=======================================+=======================================+ -| :math:`±0` | :math:`0` | -+---------------------------------------+---------------------------------------+ -| :math:`-Inf` | min :math:`\mathbb{I}_{ll}` | -+---------------------------------------+---------------------------------------+ -| :math:`<` min :math:`\mathbb{I}_{ll}` | min :math:`\mathbb{I}_{ll}` | -+---------------------------------------+---------------------------------------+ -| :math:`>` max :math:`\mathbb{I}_{ll}` | max :math:`\mathbb{I}_{ll}` | -+---------------------------------------+---------------------------------------+ -| :math:`+Inf` | max :math:`\mathbb{I}_{ll}` | -+---------------------------------------+---------------------------------------+ -| :math:`NaN` | :math:`llround(±Inf)` | -+---------------------------------------+---------------------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -Implement based on bit-fiddling. - -.. Here there be dragons. (TODO) - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-8400 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/llroundd.c -* libm/mathf/llroundf.c - -References -^^^^^^^^^^ - -* :ref:`lround` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0790_trunc.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0790_trunc.rst deleted file mode 100644 index d56a8b6b..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0790_trunc.rst +++ /dev/null @@ -1,65 +0,0 @@ -trunc -~~~~~ - -.. c:autodoc:: mathd/truncd.c - -Special cases -^^^^^^^^^^^^^ - -+--------------------------+--------------------------+ -| x | Result | -+==========================+==========================+ -| :math:`±0` | :math:`x` | -+--------------------------+--------------------------+ -| :math:`±Inf` | :math:`x` | -+--------------------------+--------------------------+ -| :math:`NaN` | :math:`NaN` | -+--------------------------+--------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -The approach is to first check whether the input is fractional, then remove the fraction and round in the correct direction. - -#. All the following return values shall have the same sign as the input value. -#. If the exponent is :math:`< 20`, the integral part of :math:`x` is in the double's highword: - - #. If the exponent is :math:`< 0`, there is no integral part, return a zero. - #. Return :math:`x` rounded to the nearest integer no greater in magnitude than :math:`x`. - -#. If the exponent is :math:`> 51`, there is no fractional part: - - #. If the exponent is :math:`= 1024`, :math:`x` is :math:`NaN` or infinite, return :math:`x+x`. - #. Return :math:`x`. - -#. Return :math:`x` rounded to the nearest integer no greater in magnitude than :math:`x`. - -For the float version the approach can be shortened: - -#. All the following return values shall have the same sign as the input value. -#. If the exponent is :math:`< 23`, there may be a fractional part: - - #. If the exponent is :math:`< 0`, there is no integral part, return a zero. - #. Return :math:`x` rounded to the nearest integer no greater in magnitude than :math:`x`. - -#. If the exponent is :math:`= 128`, :math:`x` is :math:`NaN` or infinite, return :math:`x+x`. -#. Return :math:`x`. - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-1060 -* REQ-ML-1070 -* REQ-ML-1071 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/truncd.c -* libm/mathf/truncf.c - -References -^^^^^^^^^^ - -* :ref:`round` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0900_fmod.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0900_fmod.rst deleted file mode 100644 index fcd41b48..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0900_fmod.rst +++ /dev/null @@ -1,66 +0,0 @@ -fmod -~~~~ - -.. c:autodoc:: mathd/fmodd.c - -Special cases -^^^^^^^^^^^^^ - -+-----------------------------+-----------------------------+-----------------------------+ -| x | y | Result | -+=============================+=============================+=============================+ -| :math:`\in \mathbb{F}` | :math:`±0` | :math:`qNaN` | -+-----------------------------+-----------------------------+-----------------------------+ -| :math:`±Inf` | :math:`\in \mathbb{F}` | :math:`qNaN` | -+-----------------------------+-----------------------------+-----------------------------+ -| :math:`±0` | :math:`\neq ±0` | :math:`x` | -+-----------------------------+-----------------------------+-----------------------------+ -| :math:`\neq ±Inf` | :math:`±Inf` | :math:`x` | -+-----------------------------+-----------------------------+-----------------------------+ -| :math:`NaN` | :math:`\in \mathbb{F}` | :math:`qNaN` | -+-----------------------------+-----------------------------+-----------------------------+ -| :math:`\in \mathbb{F}` | :math:`NaN` | :math:`qNaN` | -+-----------------------------+-----------------------------+-----------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -The approach is to first work on special values and overflows, then use :ref:`sqrt` for the calculation. - -#. All return values mentioned hereafter shall have the same sign as :math:`x` at this point. -#. If :math:`x` is not finite, or :math:`y` is :math:`NaN` or zero, return :math:`NaN`. -#. If :math:`|x| < |y|`, return :math:`x`. -#. If :math:`|x|` equals :math:`|y|`, return a zero. -#. Remove the sign bits from :math:`x` and :math:`y`. -#. Extract the binary exponents of :math:`x` and :math:`y` into :math:`ix` and :math:`iy` respectively.\footnote{Take care with subnormals.} -#. Normalize :math:`x` and :math:`y` by replacing their exponent with :math:`1`.\footnote{Subnormal :math:`x` or :math:`y` instead need to be shifted left until the exponent is :math:`1`.} -#. Loop for :math:`ix - iy` steps, add an additional step if :math:`x` is :math:`> y` at the end: - - #. Set :math:`x` to :math:`x - y`. - #. If :math:`x` is :math:`0`, return a zero. - -#. If the exponent of :math:`x` is :math:`< 1`, normalize :math:`x` by shifting left until the exponent is :math:`1`. While doing so decrease :math:`iy` once for every necessary shifting step. -#. Set :math:`iy` as the new exponent of :math:`x`.\footnote{If :math:`iy` is :math:`<= -1023` (this means the result is subnormal), :math:`x` needs to be shifted right while increasing :math:`iy` for every step until :math:`iy` is :math:`-1022`.} -#. Return :math:`x`. - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-1100 -* REQ-ML-1120 -* REQ-ML-1121 -* REQ-ML-1122 -* REQ-ML-1130 -* REQ-ML-1131 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/fmodd.c -* libm/mathf/fmodf.c - -References -^^^^^^^^^^ - -* :ref:`remainder` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0910_remainder.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0910_remainder.rst deleted file mode 100644 index fd9e3d05..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0910_remainder.rst +++ /dev/null @@ -1,46 +0,0 @@ -remainder -~~~~~~~~~ - -.. c:autodoc:: mathd/remainderd.c - -Special cases -^^^^^^^^^^^^^ - -+-----------------------------+-----------------------------+-----------------------------+ -| x | y | Result | -+=============================+=============================+=============================+ -| :math:`\in \mathbb{F}` | :math:`±0` | :math:`qNaN` | -+-----------------------------+-----------------------------+-----------------------------+ -| :math:`±Inf` | :math:`\in \mathbb{F}` | :math:`qNaN` | -+-----------------------------+-----------------------------+-----------------------------+ -| :math:`NaN` | :math:`\in \mathbb{F}` | :math:`qNaN` | -+-----------------------------+-----------------------------+-----------------------------+ -| :math:`\in \mathbb{F}` | :math:`NaN` | :math:`qNaN` | -+-----------------------------+-----------------------------+-----------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -Implement based on :ref:`fmod`. - -.. Here there be dragons. (TODO) - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-3900 -* REQ-ML-3910 -* REQ-ML-3920 -* REQ-ML-3940 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/remainderd.c -* libm/mathf/remainderf.c - -References -^^^^^^^^^^ - -* :ref:`fmod` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0920_remquo.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0920_remquo.rst deleted file mode 100644 index da17de0b..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/0920_remquo.rst +++ /dev/null @@ -1,47 +0,0 @@ -remquo -~~~~~~ - -.. c:autodoc:: mathd/remquod.c - -Special cases -^^^^^^^^^^^^^ - -+-----------------------------+-----------------------------+-----------------------------+-----------------------------+ -| x | y | Result | :math:`*quo` | -+=============================+=============================+=============================+=============================+ -| :math:`\in \mathbb{F}` | :math:`±0` | :math:`qNaN` | :math:`0` | -+-----------------------------+-----------------------------+-----------------------------+-----------------------------+ -| :math:`±Inf` | :math:`\in \mathbb{F}` | :math:`qNaN` | :math:`0` | -+-----------------------------+-----------------------------+-----------------------------+-----------------------------+ -| :math:`NaN` | :math:`\in \mathbb{F}` | :math:`qNaN` | :math:`0` | -+-----------------------------+-----------------------------+-----------------------------+-----------------------------+ -| :math:`\in \mathbb{F}` | :math:`NaN` | :math:`qNaN` | :math:`0` | -+-----------------------------+-----------------------------+-----------------------------+-----------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -Implement similarly to :ref:`remainder`, and calculate the quotient while at it. - -.. Here there be dragons. (TODO) - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-5600 -* REQ-ML-5601 -* REQ-ML-5620 -* REQ-ML-5620 -* REQ-ML-5640 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/remquod.c -* libm/mathf/remquof.c - -References -^^^^^^^^^^ - -* :ref:`remainder` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1000_copysign.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1000_copysign.rst deleted file mode 100644 index de251142..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1000_copysign.rst +++ /dev/null @@ -1,36 +0,0 @@ -copysign -~~~~~~~~ - -.. c:autodoc:: mathd/copysignd.c - -Special cases -^^^^^^^^^^^^^ - -+-----------------------------+-----------------------------+-----------------------------+ -| x | y | Result | -+=============================+=============================+=============================+ -| :math:`NaN` | :math:`\in \mathbb{F}` | :math:`qNaN` | -+-----------------------------+-----------------------------+-----------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -Return the value with the magnitude of :math:`x` and sign of :math:`y`. - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-1380 -* REQ-ML-1381 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/copysignd.c -* libm/mathf/copysignf.c - -References -^^^^^^^^^^ - -* :ref:`cproj` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1010_nan.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1010_nan.rst deleted file mode 100644 index 70348ecb..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1010_nan.rst +++ /dev/null @@ -1,26 +0,0 @@ -nan -~~~ - -.. c:autodoc:: mathd/nand.c - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -The approach is to return ``0x7FF80000000D067D`` as ``double`` (float: ``0x7FCF067D``). This is a quiet ``NaN`` with the fixed payload ``D067D`` (float: ``F067D``). - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-4400 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/nand.c -* libm/mathf/nanf.c - -References -^^^^^^^^^^ - -* NAN in :numref:`Tbl. %s ` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1020_nextafter.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1020_nextafter.rst deleted file mode 100644 index acc7135b..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1020_nextafter.rst +++ /dev/null @@ -1,56 +0,0 @@ -nextafter -~~~~~~~~~ - -.. c:autodoc:: mathd/nextafterd.c - -Special cases -^^^^^^^^^^^^^ - -+-----------------------------+-----------------------------+--------------------------------------------------------------------+ -| x | y | Result | -+=============================+=============================+====================================================================+ -| :math:`Any` | :math:`x` | :math:`y` | -+-----------------------------+-----------------------------+--------------------------------------------------------------------+ -| :math:`-Inf` | :math:`>-Inf` | min :math:`(\mathbb{F} \setminus \left \{ \pm Inf, NaN \right \})` | -+-----------------------------+-----------------------------+--------------------------------------------------------------------+ -| :math:`±0` | :math:`<0` | max :math:`\mathbb{S}^{-}` | -+-----------------------------+-----------------------------+--------------------------------------------------------------------+ -| :math:`±0` | :math:`±0` | :math:`y` | -+-----------------------------+-----------------------------+--------------------------------------------------------------------+ -| :math:`±0` | :math:`>0` | min :math:`\mathbb{S}^{+}` | -+-----------------------------+-----------------------------+--------------------------------------------------------------------+ -| :math:`+Inf` | :math:`<+Inf` | max :math:`(\mathbb{F} \setminus \left \{ \pm Inf, NaN \right \})` | -+-----------------------------+-----------------------------+--------------------------------------------------------------------+ -| :math:`NaN` | :math:`\in \mathbb{F}` | :math:`qNaN` | -+-----------------------------+-----------------------------+--------------------------------------------------------------------+ -| :math:`\in \mathbb{F}` | :math:`NaN` | :math:`qNaN` | -+-----------------------------+-----------------------------+--------------------------------------------------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -Implement based on bit-fiddling. - -.. Here there be dragons. (TODO) - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-4700 -* REQ-ML-4710 -* REQ-ML-4720 -* REQ-ML-4731 -* REQ-ML-4740 -* REQ-ML-4741 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/nextafterd.c -* libm/mathf/nextafterf.c - -References -^^^^^^^^^^ - -* :ref:`nexttoward` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1030_nexttoward.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1030_nexttoward.rst deleted file mode 100644 index 7444fc0f..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1030_nexttoward.rst +++ /dev/null @@ -1,51 +0,0 @@ -nexttoward -~~~~~~~~~~ - -.. c:autodoc:: mathd/nexttowardd.c - -Special cases -^^^^^^^^^^^^^ - -+-----------------------------+-----------------------------+--------------------------------------------------------------------+ -| x | y | Result | -+=============================+=============================+====================================================================+ -| :math:`Any` | :math:`x` | :math:`y` | -+-----------------------------+-----------------------------+--------------------------------------------------------------------+ -| :math:`-Inf` | :math:`>-Inf` | min :math:`(\mathbb{F} \setminus \left \{ \pm Inf, NaN \right \})` | -+-----------------------------+-----------------------------+--------------------------------------------------------------------+ -| :math:`±0` | :math:`<0` | max :math:`\mathbb{S}^{-}` | -+-----------------------------+-----------------------------+--------------------------------------------------------------------+ -| :math:`±0` | :math:`±0` | :math:`y` | -+-----------------------------+-----------------------------+--------------------------------------------------------------------+ -| :math:`±0` | :math:`>0` | min :math:`\mathbb{S}^{+}` | -+-----------------------------+-----------------------------+--------------------------------------------------------------------+ -| :math:`+Inf` | :math:`<+Inf` | max :math:`(\mathbb{F} \setminus \left \{ \pm Inf, NaN \right \})` | -+-----------------------------+-----------------------------+--------------------------------------------------------------------+ -| :math:`NaN` | :math:`\in \mathbb{F}` | :math:`qNaN` | -+-----------------------------+-----------------------------+--------------------------------------------------------------------+ -| :math:`\in \mathbb{F}` | :math:`NaN` | :math:`qNaN` | -+-----------------------------+-----------------------------+--------------------------------------------------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -The approach is to call :ref:`nextafter`. - -Float: Implement based on bit-fiddling. - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-4750 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/nexttowardd.c -* libm/mathf/nexttowardf.c - -References -^^^^^^^^^^ - -* :ref:`nextafter` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1100_fdim.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1100_fdim.rst deleted file mode 100644 index cde43b02..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1100_fdim.rst +++ /dev/null @@ -1,49 +0,0 @@ -fdim -~~~~ - -.. c:autodoc:: mathd/fdimd.c - -Special cases -^^^^^^^^^^^^^ - -+-----------------------------+-----------------------------+-----------------------------+ -| x | y | Result | -+=============================+=============================+=============================+ -| :math:`-Inf` | :math:`±Inf` | :math:`+0` | -+-----------------------------+-----------------------------+-----------------------------+ -| :math:`±0` | :math:`<0` | :math:`x` | -+-----------------------------+-----------------------------+-----------------------------+ -| :math:`±0` | :math:`>=±0` | :math:`+0` | -+-----------------------------+-----------------------------+-----------------------------+ -| :math:`+Inf` | :math:`-Inf` | :math:`+Inf` | -+-----------------------------+-----------------------------+-----------------------------+ -| :math:`+Inf` | :math:`+Inf` | :math:`+0` | -+-----------------------------+-----------------------------+-----------------------------+ -| :math:`NaN` | :math:`\in \mathbb{F}` | :math:`qNaN` | -+-----------------------------+-----------------------------+-----------------------------+ -| :math:`\in \mathbb{F}` | :math:`NaN` | :math:`qNaN` | -+-----------------------------+-----------------------------+-----------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -If :math:`x` is greater than :math:`y` return :math:`x - y`, otherwise return :math:`0`. - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-2600 -* REQ-ML-2610 -* REQ-ML-2620 -* REQ-ML-2630 -* REQ-ML-2640 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/fdimd.c -* libm/mathf/fdimf.c - -References -^^^^^^^^^^ diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1110_fmax.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1110_fmax.rst deleted file mode 100644 index 8cb72382..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1110_fmax.rst +++ /dev/null @@ -1,51 +0,0 @@ -fmax -~~~~ - -.. c:autodoc:: mathd/fmaxd.c - -Special cases -^^^^^^^^^^^^^ - -+-----------------------------+-----------------------------+-----------------------------+ -| x | y | Result | -+=============================+=============================+=============================+ -| :math:`±0` | :math:`±0` | :math:`y` | -+-----------------------------+-----------------------------+-----------------------------+ -| :math:`NaN` | :math:`\neq NaN` | :math:`y` | -+-----------------------------+-----------------------------+-----------------------------+ -| :math:`\neq NaN` | :math:`NaN` | :math:`x` | -+-----------------------------+-----------------------------+-----------------------------+ -| :math:`sNaN` | :math:`Any` | :math:`qNaN` | -+-----------------------------+-----------------------------+-----------------------------+ -| :math:`Any` | :math:`sNaN` | :math:`qNaN` | -+-----------------------------+-----------------------------+-----------------------------+ -| :math:`NaN` | :math:`NaN` | :math:`qNaN` | -+-----------------------------+-----------------------------+-----------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -The approach is to first check the arguments for any :math:`NaN` values and then compare the inputs to return the maximum: - -#. Return :math:`NaN` if both input values are :math:`NaN`. -#. Return the remaining value if one of the input values is :math:`NaN`. -#. If :math:`x > y` return :math:`x`, else return :math:`y`. - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-1240 -* REQ-ML-1250 -* REQ-ML-1252 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/fmaxd.c -* libm/mathf/fmaxf.c - -References -^^^^^^^^^^ - -* :ref:`fmin` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1120_fmin.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1120_fmin.rst deleted file mode 100644 index e287a465..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1120_fmin.rst +++ /dev/null @@ -1,51 +0,0 @@ -fmin -~~~~ - -.. c:autodoc:: mathd/fmind.c - -Special cases -^^^^^^^^^^^^^ - -+-----------------------------+-----------------------------+-----------------------------+ -| x | y | Result | -+=============================+=============================+=============================+ -| :math:`±0` | :math:`±0` | :math:`y` | -+-----------------------------+-----------------------------+-----------------------------+ -| :math:`NaN` | :math:`\neq NaN` | :math:`y` | -+-----------------------------+-----------------------------+-----------------------------+ -| :math:`\neq NaN` | :math:`NaN` | :math:`x` | -+-----------------------------+-----------------------------+-----------------------------+ -| :math:`sNaN` | :math:`Any` | :math:`qNaN` | -+-----------------------------+-----------------------------+-----------------------------+ -| :math:`Any` | :math:`sNaN` | :math:`qNaN` | -+-----------------------------+-----------------------------+-----------------------------+ -| :math:`NaN` | :math:`NaN` | :math:`qNaN` | -+-----------------------------+-----------------------------+-----------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -The approach is to first check the arguments for any :math:`NaN` values and then compare the inputs to return the minimum: - -#. Return :math:`NaN` if both input values are :math:`NaN`. -#. Return the remaining value if one of the input values is :math:`NaN`. -#. If :math:`x < y` return :math:`x`, else return :math:`y`. - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-1220 -* REQ-ML-1230 -* REQ-ML-1232 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/fmind.c -* libm/mathf/fminf.c - -References -^^^^^^^^^^ - -* :ref:`fmax` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1200_fma.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1200_fma.rst deleted file mode 100644 index 87986ef6..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1200_fma.rst +++ /dev/null @@ -1,48 +0,0 @@ -fma -~~~~ - -.. c:autodoc:: mathd/fmad.c - -Special cases -^^^^^^^^^^^^^ - -+-----------------------------+-----------------------------+-----------------------------+-----------------------------+ -| x | y | z | Result | -+=============================+=============================+=============================+=============================+ -| :math:`±0` | :math:`±Inf` | :math:`\in \mathbb{F}` | :math:`qNaN` | -+-----------------------------+-----------------------------+-----------------------------+-----------------------------+ -| :math:`±Inf` | :math:`±0` | :math:`\in \mathbb{F}` | :math:`qNaN` | -+-----------------------------+-----------------------------+-----------------------------+-----------------------------+ -| :math:`x \cdot y = -Inf` | :math:`+Inf` | :math:`qNaN` | -+-----------------------------+-----------------------------+-----------------------------+-----------------------------+ -| :math:`x \cdot y = +Inf` | :math:`-Inf` | :math:`qNaN` | -+-----------------------------+-----------------------------+-----------------------------+-----------------------------+ -| :math:`NaN` | :math:`\in \mathbb{F}` | :math:`\in \mathbb{F}` | :math:`qNaN` | -+-----------------------------+-----------------------------+-----------------------------+-----------------------------+ -| :math:`\in \mathbb{F}` | :math:`NaN` | :math:`\in \mathbb{F}` | :math:`qNaN` | -+-----------------------------+-----------------------------+-----------------------------+-----------------------------+ -| :math:`\in \mathbb{F}` | :math:`\in \mathbb{F}` | :math:`NaN` | :math:`qNaN` | -+-----------------------------+-----------------------------+-----------------------------+-----------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -The approach is to naively implement :math:`x \cdot y + z`. - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-2700 -* REQ-ML-2500 -* REQ-ML-2510 -* REQ-ML-2520 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/fmad.c -* libm/mathf/fmaf.c - -References -^^^^^^^^^^ diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1300_isgreater.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1300_isgreater.rst deleted file mode 100644 index 617421b2..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1300_isgreater.rst +++ /dev/null @@ -1,38 +0,0 @@ -isgreater -~~~~~~~~~ - -.. c:autodoc:: common/isgreater.c - -Special cases -^^^^^^^^^^^^^ - -+-----------------------------+-----------------------------+-----------------------------+ -| x | y | Result | -+=============================+=============================+=============================+ -| :math:`NaN` | :math:`\in \mathbb{F}` | :math:`0` | -+-----------------------------+-----------------------------+-----------------------------+ -| :math:`\in \mathbb{F}` | :math:`NaN` | :math:`0` | -+-----------------------------+-----------------------------+-----------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -#. Use :ref:`isunordered` to return :math:`0` if either input is :math:`NaN`. -#. If :math:`x > y`, return :math:`1`, otherwise return :math:`0`. - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-5000 -* REQ-ML-5010 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/common/isgreater.c - -References -^^^^^^^^^^ - -* :ref:`isunordered` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1310_isgreaterequal.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1310_isgreaterequal.rst deleted file mode 100644 index b66130b1..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1310_isgreaterequal.rst +++ /dev/null @@ -1,38 +0,0 @@ -isgreaterequal -~~~~~~~~~~~~~~ - -.. c:autodoc:: common/isgreaterequal.c - -Special cases -^^^^^^^^^^^^^ - -+-----------------------------+-----------------------------+-----------------------------+ -| x | y | Result | -+=============================+=============================+=============================+ -| :math:`NaN` | :math:`\in \mathbb{F}` | :math:`0` | -+-----------------------------+-----------------------------+-----------------------------+ -| :math:`\in \mathbb{F}` | :math:`NaN` | :math:`0` | -+-----------------------------+-----------------------------+-----------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -#. Use :ref:`isunordered` to return :math:`0` if either input is :math:`NaN`. -#. If :math:`x >= y`, return :math:`1`, otherwise return :math:`0`. - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-5100 -* REQ-ML-5110 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/common/isgreaterequal.c - -References -^^^^^^^^^^ - -* :ref:`isunordered` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1320_isless.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1320_isless.rst deleted file mode 100644 index 3b17cfd6..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1320_isless.rst +++ /dev/null @@ -1,38 +0,0 @@ -isless -~~~~~~ - -.. c:autodoc:: common/isless.c - -Special cases -^^^^^^^^^^^^^ - -+-----------------------------+-----------------------------+-----------------------------+ -| x | y | Result | -+=============================+=============================+=============================+ -| :math:`NaN` | :math:`\in \mathbb{F}` | :math:`0` | -+-----------------------------+-----------------------------+-----------------------------+ -| :math:`\in \mathbb{F}` | :math:`NaN` | :math:`0` | -+-----------------------------+-----------------------------+-----------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -#. Use :ref:`isunordered` to return :math:`0` if either input is :math:`NaN`. -#. If :math:`x < y`, return :math:`1`, otherwise return :math:`0`. - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-5200 -* REQ-ML-5210 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/common/isless.c - -References -^^^^^^^^^^ - -* :ref:`isunordered` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1330_islessequal.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1330_islessequal.rst deleted file mode 100644 index ffe9ef99..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1330_islessequal.rst +++ /dev/null @@ -1,38 +0,0 @@ -islessequal -~~~~~~~~~~~ - -.. c:autodoc:: common/islessequal.c - -Special cases -^^^^^^^^^^^^^ - -+-----------------------------+-----------------------------+-----------------------------+ -| x | y | Result | -+=============================+=============================+=============================+ -| :math:`NaN` | :math:`\in \mathbb{F}` | :math:`0` | -+-----------------------------+-----------------------------+-----------------------------+ -| :math:`\in \mathbb{F}` | :math:`NaN` | :math:`0` | -+-----------------------------+-----------------------------+-----------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -#. Use :ref:`isunordered` to return :math:`0` if either input is :math:`NaN`. -#. If :math:`x <= y`, return :math:`1`, otherwise return :math:`0`. - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-5300 -* REQ-ML-5310 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/common/islessequal.c - -References -^^^^^^^^^^ - -* :ref:`isunordered` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1340_islessgreater.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1340_islessgreater.rst deleted file mode 100644 index cac66f9f..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1340_islessgreater.rst +++ /dev/null @@ -1,38 +0,0 @@ -islessgreater -~~~~~~~~~~~~~ - -.. c:autodoc:: common/islessgreater.c - -Special cases -^^^^^^^^^^^^^ - -+-----------------------------+-----------------------------+-----------------------------+ -| x | y | Result | -+=============================+=============================+=============================+ -| :math:`NaN` | :math:`\in \mathbb{F}` | :math:`0` | -+-----------------------------+-----------------------------+-----------------------------+ -| :math:`\in \mathbb{F}` | :math:`NaN` | :math:`0` | -+-----------------------------+-----------------------------+-----------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -#. Use :ref:`isunordered` to return :math:`0` if either input is :math:`NaN`. -#. If :math:`x < y` or :math:`x > y`, return :math:`1`, otherwise return :math:`0`. - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-5400 -* REQ-ML-5410 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/common/islessgreater.c - -References -^^^^^^^^^^ - -* :ref:`isunordered` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1350_isunordered.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1350_isunordered.rst deleted file mode 100644 index 1674ae23..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1350_isunordered.rst +++ /dev/null @@ -1,35 +0,0 @@ -isunordered -~~~~~~~~~~~ - -.. c:autodoc:: common/isunordered.c - -Special cases -^^^^^^^^^^^^^ - -This macro does not have special cases. - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -If at least one input is :math:`NaN` return :math:`1`, else return :math:`0`. - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-4900 -* REQ-ML-4910 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/common/isunordered.c - -References -^^^^^^^^^^ - -* :ref:`isgreater` -* :ref:`isgreaterequal` -* :ref:`isless` -* :ref:`islessequal` -* :ref:`islessgreater` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1400_j0.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1400_j0.rst deleted file mode 100644 index 5bd18457..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1400_j0.rst +++ /dev/null @@ -1,48 +0,0 @@ -j0 -~~~ - -.. c:autodoc:: mathd/j0d.c - -Special cases -^^^^^^^^^^^^^ - -+--------------------------------------+--------------------------------------+ -| x | Result | -+======================================+======================================+ -| :math:`±Inf` | :math:`+0` | -+--------------------------------------+--------------------------------------+ -| :math:`NaN` | :math:`qNaN` | -+--------------------------------------+--------------------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -#. Check for special cases and handle them. -#. Reduce :math:`x` to :math:`|x|` using :ref:`fabs` as :math:`j0(x) = j0(-x)`. -#. For small :math:`x` (:math:`x < 2`) use :math:`j0(x) = 1 - \frac{x^2}{4} + \frac{x^4}{64} - \cdots`. -#. For larger :math:`x` use :math:`j0(x) = \sqrt{\frac{2}{\pi x}} \cdot (p0(x) \cdot cos(x0) - q0(x) \cdot sin(x0))`, where :math:`x0 = x - \frac{\pi}{4}`, with :math:`p0` and :math:`q0`. Use asymptotic expansions for :math:`p0` and :math:`q0`. -#. Make use of the existing trigonometric procedures :ref:`sin` and :ref:`cos` as well as :ref:`sqrt`, but use :math:`cos(x0) = cos(x)cos(\frac{\pi}{4}) + sin(x)sin(\frac{\pi}{4}) = \frac{1}{\sqrt{2}} \cdot (cos(x) + sin(x))` and :math:`sin(x0) = sin(x)cos(\frac{\pi}{4}) - cos(x)sin(\frac{\pi}{4}) = \frac{1}{\sqrt{2}} \cdot (sin(x) - cos(x))` to calculate their values for :math:`x0`. To avoid cancellation, use :math:`sin(x) \pm cos(x) = -\frac{cos(2x)}{(sin(x) \mp cos(x)}` to compute the worse one. - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-8500 -* REQ-ML-8510 -* REQ-ML-8520 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/internal/besseld.h -* libm/mathd/j0d.c - -References -^^^^^^^^^^ - -* :ref:`cos` -* :ref:`fabs` -* :ref:`jn` -* :ref:`sin` -* :ref:`sqrt` -* :ref:`y0` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1410_j1.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1410_j1.rst deleted file mode 100644 index 49bfc2b8..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1410_j1.rst +++ /dev/null @@ -1,48 +0,0 @@ -j1 -~~~ - -.. c:autodoc:: mathd/j1d.c - -Special cases -^^^^^^^^^^^^^ - -+--------------------------------------+--------------------------------------+ -| x | Result | -+======================================+======================================+ -| :math:`±Inf` | :math:`+0` | -+--------------------------------------+--------------------------------------+ -| :math:`NaN` | :math:`qNaN` | -+--------------------------------------+--------------------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -#. Check for special cases and handle them. -#. Reduce :math:`x` to :math:`|x|` using :ref:`fabs` as :math:`j1(x) = -j1(-x)`. -#. For small :math:`x` (:math:`x < 2`) use :math:`j1(x) = \frac{x}{2} - \frac{x^3}{16} + \frac{x^5}{384} - \cdots`. -#. For larger :math:`x` use :math:`j1(x) = \sqrt{\frac{2}{\pi x}} \cdot (p1(x) \cdot cos(x1) - q1(x) \cdot sin(x1))`, where :math:`x1 = x - \frac{3\pi}{4}`, with :math:`p1` and :math:`q1`. Use asymptotic expansions for :math:`p1` and :math:`q1`. -#. Make use of the existing trigonometric procedures :ref:`sin` and :ref:`cos` as well as :ref:`sqrt`, but use :math:`cos(x1) = cos(x)cos(\frac{3\pi}{4}) + sin(x)sin(\frac{3\pi}{4}) = \frac{1}{\sqrt{2}} \cdot (sin(x) - cos(x))` and :math:`sin(x1) = sin(x)cos(\frac{3\pi}{4}) - cos(x)sin(\frac{3\pi}{4}) = -\frac{1}{\sqrt{2}} \cdot (sin(x) + cos(x))` to calculate their values for :math:`x1`. To avoid cancellation, use :math:`sin(x) \pm cos(x) = -\frac{cos(2x)}{(sin(x) \mp cos(x)}` to compute the worse one. - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-8530 -* REQ-ML-8540 -* REQ-ML-8550 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/internal/besseld.h -* libm/mathd/j1d.c - -References -^^^^^^^^^^ - -* :ref:`cos` -* :ref:`fabs` -* :ref:`jn` -* :ref:`sin` -* :ref:`sqrt` -* :ref:`y1` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1420_jn.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1420_jn.rst deleted file mode 100644 index 88a94d1a..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1420_jn.rst +++ /dev/null @@ -1,49 +0,0 @@ -jn -~~~ - -.. c:autodoc:: mathd/jnd.c - -Special cases -^^^^^^^^^^^^^ - -+--------------------------------------+--------------------------------------+--------------------------------------+ -| n | x | Result | -+======================================+======================================+======================================+ -| :math:`\in \mathbb{I}` | :math:`±Inf` | :math:`+0` | -+--------------------------------------+--------------------------------------+--------------------------------------+ -| :math:`\in \mathbb{I}` | :math:`NaN` | :math:`qNaN` | -+--------------------------------------+--------------------------------------+--------------------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -#. Check for special cases and handle them. -#. For :math:`n` is zero or one use :ref:`j0` and :ref:`j1`. -#. For :math:`n < x` use forward recursion starting from the values of :math:`j0(x)` and :math:`j1(x)`. -#. For :math:`n > x` use a continued fraction approximation to calculate :math:`\frac{j(n,x)}{j(n-1,x)}` and then use backward recursion starting from a supposed value for :math:`j(n,x)`. The resulting value of :math:`j(0,x)` is compared with the actual value to correct the supposed value of :math:`j(n,x)`. - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-8560 -* REQ-ML-8570 -* REQ-ML-8580 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/internal/besseld.h -* libm/mathd/jnd.c - -References -^^^^^^^^^^ - -* :ref:`cos` -* :ref:`fabs` -* :ref:`j0` -* :ref:`j1` -* :ref:`log` -* :ref:`sin` -* :ref:`sqrt` -* :ref:`yn` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1430_y0.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1430_y0.rst deleted file mode 100644 index 0f954b9f..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1430_y0.rst +++ /dev/null @@ -1,60 +0,0 @@ -y0 -~~~ - -.. c:autodoc:: mathd/y0d.c - -Special cases -^^^^^^^^^^^^^ - -+--------------------------------------+--------------------------------------+ -| x | Result | -+======================================+======================================+ -| :math:`-Inf` | :math:`qNaN` | -+--------------------------------------+--------------------------------------+ -| :math:`<0` | :math:`qNaN` | -+--------------------------------------+--------------------------------------+ -| :math:`±0` | :math:`-Inf` | -+--------------------------------------+--------------------------------------+ -| :math:`+Inf` | :math:`+0` | -+--------------------------------------+--------------------------------------+ -| :math:`NaN` | :math:`qNaN` | -+--------------------------------------+--------------------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -#. Check for special cases and handle them. -#. For small :math:`x` (:math:`x < 2`): - - #. Since :math:`y0(x) = \frac{2}{\pi} \cdot \Big(j0(x) \cdot \Big(ln\Big(\frac{x}{2}\Big) + Euler\Big) + \frac{x^2}{4} - \cdots\Big)` therefore :math:`y0(x) - \frac{2}{\pi} \cdot j0(x) \cdot ln(x)` is an even function. - #. Use :math:`y0(x) = \frac{U(z)}{V(z)} + \frac{2}{\pi} \cdot j0(x) \cdot ln(x) \wedge z = x^2`, and use approximations for :math:`U` and :math:`V`. (For tiny :math:`x` this can be further simplified to :math:`U/V = u0 \wedge j0(x) \approx 1`) - -#. For larger :math:`x` use :math:`y0(x) = \sqrt{\frac{2}{\pi x}} \cdot (p0(x) \cdot cos(x0) + q0(x) \cdot sin(x0))`, where :math:`x0 = x - \frac{\pi}{4}`, with :math:`p0` and :math:`q0`. Use asymptotic expansions for :math:`p0` and :math:`q0`. -#. Make use of the existing trigonometric procedures :ref:`sin` and :ref:`cos` as well as :ref:`sqrt`, but use :math:`cos(x0) = cos(x)cos(\frac{\pi}{4}) + sin(x)sin(\frac{\pi}{4}) = \frac{1}{\sqrt{2}} \cdot (cos(x) + sin(x))` and :math:`sin(x0) = sin(x)cos(\frac{\pi}{4}) - cos(x)sin(\frac{\pi}{4}) = \frac{1}{\sqrt{2}} \cdot (sin(x) - cos(x))` to calculate their values for :math:`x0`. To avoid cancellation, use :math:`sin(x) \pm cos(x) = -\frac{cos(2x)}{(sin(x) \mp cos(x)}` to compute the worse one. - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-8600 -* REQ-ML-8601 -* REQ-ML-8605 -* REQ-ML-8610 -* REQ-ML-8620 -* REQ-ML-8621 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/internal/besseld.h -* libm/mathd/y0d.c - -References -^^^^^^^^^^ - -* :ref:`cos` -* :ref:`j0` -* :ref:`log` -* :ref:`sin` -* :ref:`sqrt` -* :ref:`yn` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1440_y1.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1440_y1.rst deleted file mode 100644 index d0b9687d..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1440_y1.rst +++ /dev/null @@ -1,61 +0,0 @@ -y1 -~~~ - -.. c:autodoc:: mathd/y1d.c - -Special cases -^^^^^^^^^^^^^ - -+--------------------------------------+--------------------------------------+ -| x | Result | -+======================================+======================================+ -| :math:`-Inf` | :math:`qNaN` | -+--------------------------------------+--------------------------------------+ -| :math:`<0` | :math:`qNaN` | -+--------------------------------------+--------------------------------------+ -| :math:`±0` | :math:`-Inf` | -+--------------------------------------+--------------------------------------+ -| :math:`+Inf` | :math:`+0` | -+--------------------------------------+--------------------------------------+ -| :math:`NaN` | :math:`qNaN` | -+--------------------------------------+--------------------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -#. Check for special cases and handle them. -#. If :math:`x` is negative return :math:`NaN`. -#. For small :math:`x` (:math:`x < 2`): - - #. Since :math:`y1(x) = \frac{2}{\pi} \cdot \Big(j1(x) \cdot \Big(ln\Big(\frac{x}{2}\Big) + Euler\Big) - \frac{1}{x} - \frac{x}{2} + \frac{5x^3}{64} - \cdots\Big)` therefore :math:`y1(x) - \frac{2}{\pi} \cdot j1(x) \cdot ln(x) - \frac{1}{x}` is an odd function. - #. Use :math:`y1(x) = x\frac{U(z)}{V(z)} + \frac{2}{\pi} \cdot \Big(j1(x) \cdot ln(x) - \frac{1}{x}\Big) \wedge z = x^2`, and use approximations for :math:`U` and :math:`V`. (For tiny :math:`x` this can be further simplified to :math:`y1(x) = -\frac{2}{\pi x}`) - -#. For larger :math:`x` use :math:`y1(x) = \sqrt{\frac{2}{\pi x}} \cdot (p1(x) \cdot sin(x1) + q1(x) \cdot cos(x1))`, where :math:`x1 = x - \frac{3\pi}{4}`, with :math:`p1` and :math:`q1`. Use asymptotic expansions for :math:`p1` and :math:`q1`. -#. Make use of the existing trigonometric procedures :ref:`sin` and :ref:`cos` as well as :ref:`sqrt`, but use :math:`cos(x1) = cos(x)cos(\frac{3\pi}{4}) + sin(x)sin(\frac{3\pi}{4}) = \frac{1}{\sqrt{2}} \cdot (sin(x) - cos(x))` and :math:`sin(x1) = sin(x)cos(\frac{3\pi}{4}) - cos(x)sin(\frac{3\pi}{4}) = -\frac{1}{\sqrt{2}} \cdot (sin(x) + cos(x))` to calculate their values for :math:`x1`. To avoid cancellation, use :math:`sin(x) \pm cos(x) = -\frac{cos(2x)}{(sin(x) \mp cos(x)}` to compute the worse one. - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-8630 -* REQ-ML-8631 -* REQ-ML-8635 -* REQ-ML-8640 -* REQ-ML-8650 -* REQ-ML-8651 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/internal/besseld.h -* libm/mathd/y1d.c - -References -^^^^^^^^^^ - -* :ref:`cos` -* :ref:`j1` -* :ref:`log` -* :ref:`sin` -* :ref:`sqrt` -* :ref:`yn` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1450_yn.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1450_yn.rst deleted file mode 100644 index 536fd0c9..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1450_yn.rst +++ /dev/null @@ -1,55 +0,0 @@ -yn -~~~ - -.. c:autodoc:: mathd/ynd.c - -Special cases -^^^^^^^^^^^^^ - -+--------------------------------------+--------------------------------------+--------------------------------------+ -| n | x | Result | -+======================================+======================================+======================================+ -| :math:`\in \mathbb{I}` | :math:`-Inf` | :math:`qNaN` | -+--------------------------------------+--------------------------------------+--------------------------------------+ -| :math:`\in \mathbb{I}` | :math:`<0` | :math:`qNaN` | -+--------------------------------------+--------------------------------------+--------------------------------------+ -| :math:`\in \mathbb{I}` | :math:`±0` | :math:`-Inf` | -+--------------------------------------+--------------------------------------+--------------------------------------+ -| :math:`\in \mathbb{I}` | :math:`+Inf` | :math:`+0` | -+--------------------------------------+--------------------------------------+--------------------------------------+ -| :math:`\in \mathbb{I}` | :math:`NaN` | :math:`qNaN` | -+--------------------------------------+--------------------------------------+--------------------------------------+ - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -#. Check for special cases and handle them. -#. For :math:`n` is zero or one use :ref:`y0` and :ref:`y1`. -#. For :math:`n > 1` use forward recursion starting from the values of :math:`y0(x)` and :math:`y1(x)`. - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-8660 -* REQ-ML-8661 -* REQ-ML-8665 -* REQ-ML-8670 -* REQ-ML-8680 -* REQ-ML-8681 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/math.h -* libm/mathd/internal/besseld.h -* libm/mathd/y1n.c - -References -^^^^^^^^^^ - -* :ref:`cos` -* :ref:`jn` -* :ref:`sin` -* :ref:`sqrt` -* :ref:`y0` -* :ref:`y1` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1500_cacos.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1500_cacos.rst deleted file mode 100644 index 765a101e..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1500_cacos.rst +++ /dev/null @@ -1,32 +0,0 @@ -cacos -~~~~~ - -.. c:autodoc:: complexd/cacosd.c - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -Implement based on :ref:`casin`. - -.. Here there be dragons. (TODO) - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-6000 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/complex.h -* libm/complexd/cacosd.c -* libm/complexf/cacosf.c - -References -^^^^^^^^^^ - -* :numref:`Tbl. %s ` -* :ref:`casin` -* :ref:`cimag` -* :ref:`CMPLX` -* :ref:`creal` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1510_casin.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1510_casin.rst deleted file mode 100644 index bca3afbe..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1510_casin.rst +++ /dev/null @@ -1,35 +0,0 @@ -casin -~~~~~ - -.. c:autodoc:: complexd/casind.c - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -Implement based on :ref:`clog` and :ref:`csqrt`. - -.. Here there be dragons. (TODO) - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-6100 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/complex.h -* libm/complexd/casind.c -* libm/complexf/casinf.c - -References -^^^^^^^^^^ - -* :numref:`Tbl. %s ` -* :ref:`cacos` -* :ref:`casinh` -* :ref:`cimag` -* :ref:`clog` -* :ref:`CMPLX` -* :ref:`creal` -* :ref:`csqrt` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1520_catan.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1520_catan.rst deleted file mode 100644 index 79dad9fb..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1520_catan.rst +++ /dev/null @@ -1,39 +0,0 @@ -catan -~~~~~ - -.. c:autodoc:: complexd/catand.c - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -Implement based on :ref:`atan2`. - -.. Here there be dragons. (TODO) - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-6200 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/complex.h -* libm/complexd/catand.c -* libm/complexd/internal/ctrigd.h -* libm/complexd/internal/ctrigd.c -* libm/complexf/catanf.c -* libm/complexf/internal/ctrigf.h -* libm/complexf/internal/ctrigf.c - - -References -^^^^^^^^^^ - -* :numref:`Tbl. %s ` -* :ref:`atan2` -* :ref:`catanh` -* :ref:`cimag` -* :ref:`CMPLX` -* :ref:`creal` -* :ref:`log` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1530_ccos.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1530_ccos.rst deleted file mode 100644 index 5b4f0aba..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1530_ccos.rst +++ /dev/null @@ -1,37 +0,0 @@ -ccos -~~~~ - -.. c:autodoc:: complexd/ccosd.c - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -Implement based on :ref:`cos` and :ref:`sin`. - -.. Here there be dragons. (TODO) - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-6300 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/complex.h -* libm/complexd/ccosd.c -* libm/complexf/ccosf.c - -References -^^^^^^^^^^ - -* :numref:`Tbl. %s ` -* :ref:`cimag` -* :ref:`CMPLX` -* :ref:`cos` -* :ref:`cosh` -* :ref:`creal` -* :ref:`exp` -* :ref:`fabs` -* :ref:`sin` -* :ref:`sinh` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1540_csin.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1540_csin.rst deleted file mode 100644 index 792aae05..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1540_csin.rst +++ /dev/null @@ -1,41 +0,0 @@ -csin -~~~~ - -.. c:autodoc:: complexd/csind.c - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -Implement based on :ref:`cos` and :ref:`sin`. - -.. Here there be dragons. (TODO) - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-6400 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/complex.h -* libm/complexd/csind.c -* libm/complexd/internal/ctrigd.h -* libm/complexd/internal/ctrigd.c -* libm/complexf/csinf.c -* libm/complexf/internal/ctrigf.h -* libm/complexf/internal/ctrigf.c - -References -^^^^^^^^^^ - -* :numref:`Tbl. %s ` -* :ref:`cimag` -* :ref:`CMPLX` -* :ref:`cos` -* :ref:`cosh` -* :ref:`creal` -* :ref:`exp` -* :ref:`fabs` -* :ref:`sin` -* :ref:`sinh` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1550_ctan.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1550_ctan.rst deleted file mode 100644 index 74bf7ec7..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1550_ctan.rst +++ /dev/null @@ -1,36 +0,0 @@ -ctan -~~~~ - -.. c:autodoc:: complexd/ctand.c - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -Implement based on :ref:`cos`, :ref:`sin`, :ref:`cosh`, and :ref:`sinh`. - -.. Here there be dragons. (TODO) - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-6500 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/complex.h -* libm/complexd/ctand.c -* libm/complexf/ctanf.c - -References -^^^^^^^^^^ - -* :numref:`Tbl. %s ` -* :ref:`cimag` -* :ref:`CMPLX` -* :ref:`cos` -* :ref:`cosh` -* :ref:`creal` -* :ref:`fabs` -* :ref:`sin` -* :ref:`sinh` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1600_cacosh.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1600_cacosh.rst deleted file mode 100644 index 048c210f..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1600_cacosh.rst +++ /dev/null @@ -1,29 +0,0 @@ -cacosh -~~~~~~ - -.. c:autodoc:: complexd/cacoshd.c - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -Implement based on :ref:`clog` and :ref:`csqrt`. - -.. Here there be dragons. (TODO) - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-6600 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/complex.h -* libm/complexd/cacoshd.c -* libm/complexf/cacoshf.c - -References -^^^^^^^^^^ - -* :ref:`clog` -* :ref:`csqrt` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1610_casinh.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1610_casinh.rst deleted file mode 100644 index cd7ca786..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1610_casinh.rst +++ /dev/null @@ -1,31 +0,0 @@ -casinh -~~~~~~ - -.. c:autodoc:: complexd/casinhd.c - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -Implement based on :ref:`casin`. - -.. Here there be dragons. (TODO) - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-6700 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/complex.h -* libm/complexd/casinhd.c -* libm/complexf/casinhf.c - -References -^^^^^^^^^^ - -* :ref:`casin` -* :ref:`cimag` -* :ref:`CMPLX` -* :ref:`creal` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1620_catanh.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1620_catanh.rst deleted file mode 100644 index 7d29f1b5..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1620_catanh.rst +++ /dev/null @@ -1,31 +0,0 @@ -catanh -~~~~~~ - -.. c:autodoc:: complexd/catanhd.c - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -Implement based on :ref:`catan`. - -.. Here there be dragons. (TODO) - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-6800 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/complex.h -* libm/complexd/catanhd.c -* libm/complexf/catanhf.c - -References -^^^^^^^^^^ - -* :ref:`catan` -* :ref:`cimag` -* :ref:`CMPLX` -* :ref:`creal` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1630_ccosh.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1630_ccosh.rst deleted file mode 100644 index 75943f2f..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1630_ccosh.rst +++ /dev/null @@ -1,38 +0,0 @@ -ccosh -~~~~~ - -.. c:autodoc:: complexd/ccoshd.c - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -Implement based on :ref:`cos`, :ref:`sin`, :ref:`cosh`, and :ref:`cosh`. - -.. Here there be dragons. (TODO) - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-6900 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/complex.h -* libm/complexd/ccoshd.c -* libm/complexd/internal/ctrigd.h -* libm/complexd/internal/ctrigd.c -* libm/complexf/ccoshf.c -* libm/complexf/internal/ctrigf.h -* libm/complexf/internal/ctrigf.c - -References -^^^^^^^^^^ - -* :ref:`cimag` -* :ref:`CMPLX` -* :ref:`cos` -* :ref:`cosh` -* :ref:`creal` -* :ref:`sin` -* :ref:`sinh` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1640_csinh.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1640_csinh.rst deleted file mode 100644 index 5fd539b8..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1640_csinh.rst +++ /dev/null @@ -1,34 +0,0 @@ -csinh -~~~~~ - -.. c:autodoc:: complexd/csinhd.c - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -Implement based on :ref:`cos`, :ref:`sin`, :ref:`cosh`, and :ref:`cosh`. - -.. Here there be dragons. (TODO) - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-7000 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/complex.h -* libm/complexd/csinhd.c -* libm/complexf/csinhf.c - -References -^^^^^^^^^^ - -* :ref:`cimag` -* :ref:`CMPLX` -* :ref:`cos` -* :ref:`cosh` -* :ref:`creal` -* :ref:`sin` -* :ref:`sinh` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1650_ctanh.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1650_ctanh.rst deleted file mode 100644 index ed9c6b55..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1650_ctanh.rst +++ /dev/null @@ -1,39 +0,0 @@ -ctanh -~~~~~ - -.. c:autodoc:: complexd/ctanhd.c - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -Implement based on :ref:`cos`, :ref:`sin`, :ref:`cosh`, and :ref:`cosh`. - -.. Here there be dragons. (TODO) - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-7100 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/complex.h -* libm/complexd/ctanhd.c -* libm/complexd/internal/ctrigd.h -* libm/complexd/internal/ctrigd.c -* libm/complexf/ctanhf.c -* libm/complexf/internal/ctrigf.h -* libm/complexf/internal/ctrigf.c - - -References -^^^^^^^^^^ - -* :ref:`cimag` -* :ref:`CMPLX` -* :ref:`cos` -* :ref:`cosh` -* :ref:`creal` -* :ref:`sin` -* :ref:`sinh` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1700_cexp.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1700_cexp.rst deleted file mode 100644 index c1427fe5..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1700_cexp.rst +++ /dev/null @@ -1,33 +0,0 @@ -cexp -~~~~ - -.. c:autodoc:: complexd/cexpd.c - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -Implement based on :ref:`cos`, :ref:`sin`, and :ref:`exp`. - -.. Here there be dragons. (TODO) - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-7200 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/complex.h -* libm/complexd/cexpd.c -* libm/complexf/cexpf.c - -References -^^^^^^^^^^ - -* :ref:`cimag` -* :ref:`CMPLX` -* :ref:`cos` -* :ref:`creal` -* :ref:`exp` -* :ref:`sin` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1710_clog.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1710_clog.rst deleted file mode 100644 index a2c128de..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1710_clog.rst +++ /dev/null @@ -1,35 +0,0 @@ -clog -~~~~ - -.. c:autodoc:: complexd/clogd.c - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -Implement based on :ref:`atan2`, and :ref:`log`. - -.. Here there be dragons. (TODO) - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-7300 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/complex.h -* libm/complexd/clogd.c -* libm/complexf/clogf.c - -References -^^^^^^^^^^ - -* :ref:`atan2` -* :ref:`cabs` -* :ref:`cacosh` -* :ref:`casin` -* :ref:`cimag` -* :ref:`CMPLX` -* :ref:`creal` -* :ref:`log` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1800_cabs.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1800_cabs.rst deleted file mode 100644 index f3459df5..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1800_cabs.rst +++ /dev/null @@ -1,33 +0,0 @@ -cabs -~~~~ - -.. c:autodoc:: complexd/cabsd.c - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -Implement based on :ref:`hypot`. - -.. Here there be dragons. (TODO) - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-7400 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/complex.h -* libm/complexd/cabsd.c -* libm/complexf/cabsf.c - -References -^^^^^^^^^^ - -* :ref:`cimag` -* :ref:`clog` -* :ref:`cpow` -* :ref:`creal` -* :ref:`csqrt` -* :ref:`hypot` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1810_cpow.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1810_cpow.rst deleted file mode 100644 index c55fb882..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1810_cpow.rst +++ /dev/null @@ -1,38 +0,0 @@ -cpow -~~~~~ - -.. c:autodoc:: complexd/cpowd.c - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -Implement based on :ref:`cos`, :ref:`sin`, :ref:`log`, :ref:`exp`, :ref:`pow`, and :ref:`carg`. - -.. Here there be dragons. (TODO) - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-7500 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/complex.h -* libm/complexd/cpowd.c -* libm/complexf/cpowf.c - -References -^^^^^^^^^^ - -* :ref:`cabs` -* :ref:`carg` -* :ref:`cimag` -* :ref:`CMPLX` -* :ref:`cos` -* :ref:`creal` -* :ref:`csqrt` -* :ref:`exp` -* :ref:`log` -* :ref:`pow` -* :ref:`sin` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1820_csqrt.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1820_csqrt.rst deleted file mode 100644 index 49cdaf4b..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1820_csqrt.rst +++ /dev/null @@ -1,35 +0,0 @@ -csqrt -~~~~~ - -.. c:autodoc:: complexd/csqrtd.c - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -Implement based on :ref:`sqrt`. - -.. Here there be dragons. (TODO) - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-7600 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/complex.h -* libm/complexd/csqrtd.c -* libm/complexf/csqrtf.c - -References -^^^^^^^^^^ - -* :ref:`cabs` -* :ref:`cacosh` -* :ref:`casin` -* :ref:`cimag` -* :ref:`CMPLX` -* :ref:`creal` -* :ref:`fabs` -* :ref:`sqrt` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1900_carg.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1900_carg.rst deleted file mode 100644 index 54f1f4de..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1900_carg.rst +++ /dev/null @@ -1,31 +0,0 @@ -carg -~~~~ - -.. c:autodoc:: complexd/cargd.c - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -Implement based on :ref:`atan2`. - -.. Here there be dragons. (TODO) - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-7700 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/complex.h -* libm/complexd/cargd.c -* libm/complexf/cargf.c - -References -^^^^^^^^^^ - -* :ref:`atan2` -* :ref:`cimag` -* :ref:`cpow` -* :ref:`creal` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1910_cimag.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1910_cimag.rst deleted file mode 100644 index 8dacbcd5..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1910_cimag.rst +++ /dev/null @@ -1,30 +0,0 @@ -cimag -~~~~~ - -.. c:autodoc:: complexd/cimagd.c - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -Return the imaginary part of the input. - -.. Here there be dragons. (TODO) - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-7800 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/complex.h -* libm/complexd/cimagd.c -* libm/complexf/cimagf.c - -References -^^^^^^^^^^ - -* :ref:`creal` - -Nearly all complex procedures use ``cimag``. diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1920_cmplx.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1920_cmplx.rst deleted file mode 100644 index b8d5bb52..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1920_cmplx.rst +++ /dev/null @@ -1,27 +0,0 @@ -CMPLX -~~~~~~~~~ - -.. c:autodoc:: common/cmplx.c - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -Use inherent procedures in accordance with C standard compliant toolchains. - -.. Here there be dragons. (TODO) - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-7900 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/complex.h -* libm/common/cmplx.c - -References -^^^^^^^^^^ - -Nearly all complex procedures use ``CMPLX``. diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1930_conj.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1930_conj.rst deleted file mode 100644 index 0e945cab..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1930_conj.rst +++ /dev/null @@ -1,26 +0,0 @@ -conj -~~~~~ - -.. c:autodoc:: complexd/conjd.c - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -Inverse the imaginary part of the input. - -.. Here there be dragons. (TODO) - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-8000 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/complex.h -* libm/complexd/conjd.c -* libm/complexf/conjf.c - -References -^^^^^^^^^^ diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1940_cproj.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1940_cproj.rst deleted file mode 100644 index 08ade237..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1940_cproj.rst +++ /dev/null @@ -1,30 +0,0 @@ -cproj -~~~~~ - -.. c:autodoc:: complexd/cprojd.c - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -Implement based on :ref:`copysign`. - -.. Here there be dragons. (TODO) - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-8100 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/complex.h -* libm/complexd/cprojd.c -* libm/complexf/cprojf.c - -References -^^^^^^^^^^ - -* :ref:`cimag` -* :ref:`copysign` -* :ref:`isinf` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1950_creal.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1950_creal.rst deleted file mode 100644 index 0510b24e..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/1950_creal.rst +++ /dev/null @@ -1,30 +0,0 @@ -creal -~~~~~ - -.. c:autodoc:: complexd/creald.c - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -Return the real part of the input. - -.. Here there be dragons. (TODO) - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-8200 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/include/complex.h -* libm/complexd/creald.c -* libm/complexf/crealf.c - -References -^^^^^^^^^^ - -* :ref:`cimag` - -Nearly all complex procedures use ``creal``. diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/2000_misc_internal.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/2000_misc_internal.rst deleted file mode 100644 index 33c2d4f8..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/2000_misc_internal.rst +++ /dev/null @@ -1,40 +0,0 @@ -.. _internal_misc: - -Exception Raising And Floating-Point/Integer Conversion Functions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. c:autodoc:: common/tools.h - -Special cases -^^^^^^^^^^^^^ - -The exception raising procedures are themselves special cases but do not have any. - -The floating-point to integer conversion (and vice-versa) procedures do not have any. - -Mathematical Approach -^^^^^^^^^^^^^^^^^^^^^ - -Implement based on bit-fiddling and tricks for forcing the FPU to do as it should. - -.. Here there be dragons. (TODO) - -Requirements -^^^^^^^^^^^^ - -Internal functions do not directly implement requirements. - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* libm/common/tools.h -* libm/common/tools.c - -References -^^^^^^^^^^ - -Exception raising procedures are used in a lot of other procedures. They are used whenever the `Mathematical Approach` of the procedure explicitly states raising an exception. - -Floating-point to integer conversion (and vice-versa) procedures are used in a lot of other procedures. They are used whenever the `Mathematical Approach` of the procedure makes use of, or manipulates, the hexadecimal representation of floating-point datums, for example for checking/extracting/manipulating the sign/exponent/mantissa. They are used quite liberally. - -``SAFE_RIGHT_SHIFT`` is used by :ref:`lrint`, :ref:`llrint`, :ref:`lround` and :ref:`llround`. diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/3000_configure.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/3000_configure.rst deleted file mode 100644 index 863fb333..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/3000_configure.rst +++ /dev/null @@ -1,56 +0,0 @@ -configure -~~~~~~~~~ - -Description and Use -^^^^^^^^^^^^^^^^^^^ - -The ``configure`` file shall be a script to prepare for running the :ref:`Makefile`. It's intention is to smoothen the process of building and rebuilding the library for multiple platforms, toolchains and configurations. - -For this the user has to be asked multiple questions to configure the library for the project's use-case. - -Alternatively the script should be callable with command line options to enable/disable the flags and input paths. The use should be very similar to ``configure`` scripts created using an ``autoconf/automake`` setup. - -Approach -^^^^^^^^ - -#. Use ``getopt`` to define usable flags. -#. Parse user arguments into variables. -#. Create a user help (flag ``-h`` or on unexpected options). -#. Create a an empty ``user_make`` file which will later be read by the :ref:`Makefile`. -#. Create a minimal C program to check preset defines of the toolchain (e.g., type sizes). -#. Before asking the following questions first check if the user has already provided the answer via flag. -#. If any of the below questions was answered with a faulty value, ask again. -#. Ask for path to toolchain. -#. Ask for additional compilation flags. -#. Ask for DAZ/FTZ mode. -#. Use the previously created C program to check the size of ``long int``, if it is 32bit add ``-DLIBMCS_LONG_IS_32BITS`` to the additional compilation flags. -#. Use the previously created C program to check the size of ``double``, if it is 32bit add ``-DLIBMCS_DOUBLE_IS_32BITS`` to the additional compilation flags. -#. Use the previously created C program to check the size of ``long double``, if it is 64bit ask if ``long double`` procedures shall be compiled into the library, and if so add ``-DLIBMCS_LONG_DOUBLE_IS_64BITS`` to the additional compilation flags. -#. Use the previously created C program to check the endianess of the toolchain/platform/flag-combination, if no endianess is found ask the user whether it is little or big endian, and add the specific flag to the additional compilation flags (either ``-D__BYTE_ORDER__=__ORDER_BIG_ENDIAN__`` or ``-D__BYTE_ORDER__=__ORDER_LITTLE_ENDIAN__``). -#. Add the path to the toolchain and the accumulated additional compilation flags to the ``user_make``. -#. Ask if ``complex`` procedures shall be compiled into the library, and if so add a variable to the ``user_make``. -#. Finish of the ``user_make`` with a variable that tells the :ref:`Makefile` that the configuration was successful. - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-0024 -* REQ-ML-0025 -* REQ-ML-0026 -* REQ-ML-0027 -* REQ-ML-0028 -* REQ-ML-0090 -* REQ-ML-0100 -* REQ-ML-0115 -* REQ-ML-0180 -* REQ-ML-1901 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* configure - -References -^^^^^^^^^^ - -* :ref:`Makefile` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/3100_makefile.rst b/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/3100_makefile.rst deleted file mode 100644 index 3cbfd92f..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/4_Software_Component_Design_Aspects_Of_Each_Component/3100_makefile.rst +++ /dev/null @@ -1,48 +0,0 @@ -Makefile -~~~~~~~~ - -Description and Use -^^^^^^^^^^^^^^^^^^^ - -The ``Makefile`` is a commonly used script to build software, in this case a library. - -This ``Makefile`` has to be run after :ref:`configure` was run successfully, otherwise it shall throw an error. This may be avoidable by adding the configuration successful variable to the ``make`` call, but shall not be encouraged. - -This ``Makefile`` shall provide the following targets: ``all`` (builds the library), ``debug`` (same as ``all``), ``release`` (same as ``debug`` but with extra flag ``-DNDBUG``), ``clean`` (removes the build corresponding to the current configuration), ``cleanall`` (removes all builds), and ``distclean`` (removes ``user_make`` and the C program built for testing purposes within :ref:`configure` (if :ref:`configure` was run successfully the testing files should already be removed)). - -Approach -^^^^^^^^ - -#. Include ``user_make``. -#. Check for the configuration successful variable, if it is not set (either via ``user_make`` or manually) stop and throw an error. -#. Check if the user provided a build name, if not create one based on toolchain and target. -#. Define include paths. -#. Define source paths. Check if the user wanted ``long double`` and/or ``complex`` procedures and add them if so. -#. Add compilation/linking flags (library specific flags, user flags, coverage, etc.). -#. Build it all. -#. Add mechanism for verbose output throughout all steps. -#. Add mechanism to create a ``build_log`` in YAML format. - -Requirements -^^^^^^^^^^^^ - -* REQ-ML-0024 -* REQ-ML-0025 -* REQ-ML-0026 -* REQ-ML-0027 -* REQ-ML-0028 -* REQ-ML-0090 -* REQ-ML-0100 -* REQ-ML-0115 -* REQ-ML-0180 -* REQ-ML-1901 - -Source Code Files -^^^^^^^^^^^^^^^^^ - -* Makefile - -References -^^^^^^^^^^ - -* :ref:`configure` diff --git a/libm/libmcs/doc/sdd/5_Software_Design/5_Internal_Interface_Design.rst b/libm/libmcs/doc/sdd/5_Software_Design/5_Internal_Interface_Design.rst deleted file mode 100644 index be5a9784..00000000 --- a/libm/libmcs/doc/sdd/5_Software_Design/5_Internal_Interface_Design.rst +++ /dev/null @@ -1,20 +0,0 @@ -Internal Interface Design -------------------------- - -.. raw:: html - - - -The internal interface design is limited to the interactions between different procedures. - -For each procedure :ref:`Software Components Design – Aspects of Each Component` describes which other procedures are called. diff --git a/libm/libmcs/doc/sdd/6_Requirements_to_Design_Components_Traceability.rst b/libm/libmcs/doc/sdd/6_Requirements_to_Design_Components_Traceability.rst deleted file mode 100644 index feffffee..00000000 --- a/libm/libmcs/doc/sdd/6_Requirements_to_Design_Components_Traceability.rst +++ /dev/null @@ -1,761 +0,0 @@ -Requirements to Design Components Traceability -============================================== - -.. raw:: html - - - -The :numref:`Tbl. %s ` contains the traceability of the software components in :ref:`Software Components Design – Aspects of Each Component` (or the :ref:`SDD ` section responing to the requirement) to the :ref:`SRS ` :ref:`[RD01] ` requirements. - -.. table:: Requirement upward traceability - :name: req-upward - - ========================================== =========== - Component Requirement - ========================================== =========== - acos REQ-ML-0450 - acos REQ-ML-0460 - acos REQ-ML-0470 - acos REQ-ML-0480 - acos REQ-ML-0490 - acosh REQ-ML-2710 - acosh REQ-ML-3010 - acosh REQ-ML-3020 - acosh REQ-ML-3030 - acosh REQ-ML-3040 - asin REQ-ML-0250 - asin REQ-ML-0260 - asin REQ-ML-0270 - asin REQ-ML-0280 - asin REQ-ML-0281 - asinh REQ-ML-2620 - asinh REQ-ML-2630 - asinh REQ-ML-2640 - asinh REQ-ML-2700 - atan REQ-ML-0600 - atan REQ-ML-0610 - atan REQ-ML-0620 - atan REQ-ML-0621 - atan2 REQ-ML-0650 - atan2 REQ-ML-0652 - atan2 REQ-ML-0660 - atan2 REQ-ML-0661 - atan2 REQ-ML-0662 - atan2 REQ-ML-0663 - atan2 REQ-ML-0670 - atan2 REQ-ML-0680 - atan2 REQ-ML-0681 - atan2 REQ-ML-0682 - atan2 REQ-ML-0683 - atan2 REQ-ML-0684 - atan2 REQ-ML-0685 - atan2 REQ-ML-0686 - atanh REQ-ML-3100 - atanh REQ-ML-3110 - atanh REQ-ML-3120 - atanh REQ-ML-3121 - atanh REQ-ML-3140 - atanh REQ-ML-3141 - cabs REQ-ML-7400 - cacos REQ-ML-6000 - cacosh REQ-ML-6600 - carg REQ-ML-7700 - casin REQ-ML-6100 - casinh REQ-ML-6700 - catan REQ-ML-6200 - catanh REQ-ML-6800 - cbrt REQ-ML-2300 - cbrt REQ-ML-2310 - cbrt REQ-ML-2320 - cbrt REQ-ML-2340 - ccos REQ-ML-6300 - ccosh REQ-ML-6900 - ceil REQ-ML-1080 - ceil REQ-ML-1091 - ceil REQ-ML-1092 - cexp REQ-ML-7200 - cimag REQ-ML-7800 - clog REQ-ML-7300 - cmplx REQ-ML-7900 - conj REQ-ML-8000 - copysign REQ-ML-1380 - copysign REQ-ML-1381 - cos REQ-ML-0300 - cos REQ-ML-0310 - cos REQ-ML-0320 - cos REQ-ML-0330 - cosh REQ-ML-2200 - cosh REQ-ML-2210 - cosh REQ-ML-2220 - cosh REQ-ML-2240 - cpow REQ-ML-7500 - cproj REQ-ML-8100 - creal REQ-ML-8200 - csin REQ-ML-6400 - csinh REQ-ML-7000 - csqrt REQ-ML-7600 - ctan REQ-ML-6500 - ctanh REQ-ML-7100 - erf REQ-ML-3600 - erf REQ-ML-3610 - erf REQ-ML-3620 - erf REQ-ML-3630 - erf REQ-ML-3640 - erfc REQ-ML-3700 - erfc REQ-ML-3710 - erfc REQ-ML-3720 - erfc REQ-ML-3730 - erfc REQ-ML-3740 - exp REQ-ML-0800 - exp REQ-ML-0831 - exp REQ-ML-0832 - exp REQ-ML-0833 - exp REQ-ML-0834 - exp2 REQ-ML-3200 - exp2 REQ-ML-3210 - exp2 REQ-ML-3220 - exp2 REQ-ML-3240 - exp2 REQ-ML-3250 - expm1 REQ-ML-2500 - expm1 REQ-ML-2510 - expm1 REQ-ML-2520 - expm1 REQ-ML-2540 - expm1 REQ-ML-2550 - fabs REQ-ML-1012 - fabs REQ-ML-1000 - fabs REQ-ML-1010 - fabs REQ-ML-1011 - fdim REQ-ML-2600 - fdim REQ-ML-2610 - fdim REQ-ML-2620 - fdim REQ-ML-2630 - fdim REQ-ML-2640 - floor REQ-ML-1040 - floor REQ-ML-1051 - floor REQ-ML-1052 - fma REQ-ML-2500 - fma REQ-ML-2510 - fma REQ-ML-2520 - fma REQ-ML-2700 - fmax REQ-ML-1240 - fmax REQ-ML-1250 - fmax REQ-ML-1252 - fmin REQ-ML-1220 - fmin REQ-ML-1230 - fmin REQ-ML-1232 - fmod REQ-ML-1100 - fmod REQ-ML-1120 - fmod REQ-ML-1121 - fmod REQ-ML-1122 - fmod REQ-ML-1130 - fmod REQ-ML-1131 - fpclassify REQ-ML-5700 - frexp REQ-ML-4000 - frexp REQ-ML-4010 - frexp REQ-ML-4020 - frexp REQ-ML-4040 - hypot REQ-ML-1260 - hypot REQ-ML-1270 - hypot REQ-ML-1271 - ilogb REQ-ML-4300 - ilogb REQ-ML-4310 - ilogb REQ-ML-4320 - ilogb REQ-ML-4340 - isfinite REQ-ML-1300 - isgreater REQ-ML-5000 - isgreater REQ-ML-5010 - isgreaterequal REQ-ML-5100 - isgreaterequal REQ-ML-5110 - isinf REQ-ML-1320 - isless REQ-ML-5200 - isless REQ-ML-5210 - islessequal REQ-ML-5300 - islessequal REQ-ML-5310 - islessgreater REQ-ML-5400 - islessgreater REQ-ML-5410 - isnan REQ-ML-1340 - isnormal REQ-ML-5500 - isunordered REQ-ML-4900 - isunordered REQ-ML-4910 - j0 REQ-ML-8500 - j0 REQ-ML-8510 - j0 REQ-ML-8520 - j1 REQ-ML-8530 - j1 REQ-ML-8540 - j1 REQ-ML-8550 - jn REQ-ML-8560 - jn REQ-ML-8570 - jn REQ-ML-8580 - ldexp REQ-ML-4100 - ldexp REQ-ML-4110 - ldexp REQ-ML-4120 - ldexp REQ-ML-4130 - ldexp REQ-ML-4140 - lgamma REQ-ML-3800 - lgamma REQ-ML-3810 - lgamma REQ-ML-3820 - lgamma REQ-ML-3830 - lgamma REQ-ML-3840 - lgamma REQ-ML-3850 - llrint REQ-ML-4670 - llround REQ-ML-8400 - log REQ-ML-0900 - log REQ-ML-0910 - log REQ-ML-0920 - log REQ-ML-0921 - log REQ-ML-0930 - log REQ-ML-0931 - log10 REQ-ML-0950 - log10 REQ-ML-0960 - log10 REQ-ML-0970 - log10 REQ-ML-0971 - log10 REQ-ML-0980 - log10 REQ-ML-0981 - log1p REQ-ML-3400 - log1p REQ-ML-3410 - log1p REQ-ML-3420 - log1p REQ-ML-3430 - log1p REQ-ML-3440 - log1p REQ-ML-3450 - log2 REQ-ML-3300 - log2 REQ-ML-3310 - log2 REQ-ML-3320 - log2 REQ-ML-3330 - log2 REQ-ML-3340 - log2 REQ-ML-3350 - logb REQ-ML-3500 - logb REQ-ML-3510 - logb REQ-ML-3520 - logb REQ-ML-3540 - lrint REQ-ML-4650 - lrint REQ-ML-4653 - lrint REQ-ML-4656 - lrint REQ-ML-4659 - lrint REQ-ML-4662 - lround REQ-ML-8300 - lround REQ-ML-8310 - lround REQ-ML-8320 - lround REQ-ML-8330 - lround REQ-ML-8340 - modf REQ-ML-1200 - modf REQ-ML-1201 - modf REQ-ML-1210 - modf REQ-ML-1211 - nan REQ-ML-4400 - nearbyint REQ-ML-4500 - nearbyint REQ-ML-4510 - nearbyint REQ-ML-4520 - nearbyint REQ-ML-4540 - nextafter REQ-ML-4700 - nextafter REQ-ML-4710 - nextafter REQ-ML-4720 - nextafter REQ-ML-4731 - nextafter REQ-ML-4740 - nextafter REQ-ML-4741 - nexttoward REQ-ML-4750 - pow REQ-ML-0850 - pow REQ-ML-0860 - pow REQ-ML-0864 - pow REQ-ML-0870 - pow REQ-ML-0871 - pow REQ-ML-0872 - pow REQ-ML-0873 - pow REQ-ML-0874 - pow REQ-ML-0875 - pow REQ-ML-0876 - pow REQ-ML-0877 - pow REQ-ML-0878 - pow REQ-ML-0879 - pow REQ-ML-0880 - pow REQ-ML-0881 - pow REQ-ML-0882 - pow REQ-ML-0883 - pow REQ-ML-0885 - pow REQ-ML-0886 - remainder REQ-ML-3900 - remainder REQ-ML-3910 - remainder REQ-ML-3920 - remainder REQ-ML-3940 - remquo REQ-ML-5600 - remquo REQ-ML-5601 - remquo REQ-ML-5620 - remquo REQ-ML-5620 - remquo REQ-ML-5640 - rint REQ-ML-4600 - rint REQ-ML-4610 - rint REQ-ML-4620 - rint REQ-ML-4640 - round REQ-ML-1020 - round REQ-ML-1031 - round REQ-ML-1032 - scalbln REQ-ML-4250 - scalbn REQ-ML-4200 - scalbn REQ-ML-4210 - scalbn REQ-ML-4220 - scalbn REQ-ML-4230 - scalbn REQ-ML-4240 - signbit REQ-ML-1360 - signgam REQ-ML-3850 - sin REQ-ML-0200 - sin REQ-ML-0210 - sin REQ-ML-0220 - sin REQ-ML-0240 - sinh REQ-ML-2100 - sinh REQ-ML-2110 - sinh REQ-ML-2120 - sinh REQ-ML-2140 - sqrt REQ-ML-0700 - sqrt REQ-ML-0710 - sqrt REQ-ML-0720 - sqrt REQ-ML-0730 - sqrt REQ-ML-0740 - tan REQ-ML-0500 - tan REQ-ML-0520 - tan REQ-ML-0530 - tan REQ-ML-0550 - tanh REQ-ML-2540 - tanh REQ-ML-2550 - tanh REQ-ML-2600 - tanh REQ-ML-2610 - tgamma REQ-ML-5800 - tgamma REQ-ML-5810 - tgamma REQ-ML-5820 - tgamma REQ-ML-5830 - tgamma REQ-ML-5840 - tgamma REQ-ML-5841 - trunc REQ-ML-1060 - trunc REQ-ML-1070 - trunc REQ-ML-1071 - y0 REQ-ML-8600 - y0 REQ-ML-8601 - y0 REQ-ML-8605 - y0 REQ-ML-8610 - y0 REQ-ML-8620 - y0 REQ-ML-8621 - y1 REQ-ML-8630 - y1 REQ-ML-8631 - y1 REQ-ML-8635 - y1 REQ-ML-8640 - y1 REQ-ML-8650 - y1 REQ-ML-8651 - yn REQ-ML-8660 - yn REQ-ML-8661 - yn REQ-ML-8665 - yn REQ-ML-8670 - yn REQ-ML-8680 - yn REQ-ML-8681 - all REQ-ML-0020 - all REQ-ML-0021 - all REQ-ML-0061 - all REQ-ML-0062 - all REQ-ML-0063 - all REQ-ML-0064 - all REQ-ML-0110 - all REQ-ML-0112 - all REQ-ML-1600 - all REQ-ML-1800 - all REQ-ML-1900 - all REQ-ML-2000 - :ref:`Makefile`/:ref:`configure` REQ-ML-0024 - :ref:`Makefile`/:ref:`configure` REQ-ML-0025 - :ref:`Makefile`/:ref:`configure` REQ-ML-0026 - :ref:`Makefile`/:ref:`configure` REQ-ML-0027 - :ref:`Makefile`/:ref:`configure` REQ-ML-0028 - :ref:`Makefile`/:ref:`configure` REQ-ML-0090 - :ref:`Makefile`/:ref:`configure` REQ-ML-0100 - :ref:`Makefile`/:ref:`configure` REQ-ML-0115 - :ref:`Makefile`/:ref:`configure` REQ-ML-0180 - :ref:`Makefile`/:ref:`configure` REQ-ML-1901 - :ref:`Interfaces Context` REQ-ML-0010 - :ref:`Interfaces Context` REQ-ML-0011 - :ref:`Software Design - General ` REQ-ML-1499 - :ref:`Software Design - General ` REQ-ML-1500 - :ref:`Software Design - General ` REQ-ML-1501 - :ref:`Software Design - General ` REQ-ML-1502 - :ref:`Software Design - General ` REQ-ML-1503 - :ref:`Software Design - General ` REQ-ML-1504 - :ref:`fenv ` REQ-ML-8700 - :ref:`tgmath ` REQ-ML-8800 - :ref:`Handling of Subnormal Numbers` REQ-ML-0029 - :ref:`Errno` REQ-ML-0022 - ========================================== =========== - -The :numref:`Tbl. %s ` contains the traceability of the :ref:`SRS ` :ref:`[RD01] ` requirements to the software components in :ref:`Software Components Design – Aspects of Each Component` (or the :ref:`SDD ` section responing to the requirement). - -.. table:: Requirement downward traceability - :name: req-downward - - ============== ========================================== - Requirement Component - ============== ========================================== - REQ-ML-0010 :ref:`Interfaces Context` - REQ-ML-0011 :ref:`Interfaces Context` - REQ-ML-0020 all - REQ-ML-0021 all - REQ-ML-0022 :ref:`Errno` - REQ-ML-0024 :ref:`Makefile`/:ref:`configure` - REQ-ML-0025 :ref:`Makefile`/:ref:`configure` - REQ-ML-0026 :ref:`Makefile`/:ref:`configure` - REQ-ML-0027 :ref:`Makefile`/:ref:`configure` - REQ-ML-0028 :ref:`Makefile`/:ref:`configure` - REQ-ML-0029 :ref:`Handling of Subnormal Numbers` - REQ-ML-0061 all - REQ-ML-0062 all - REQ-ML-0063 all - REQ-ML-0064 all - REQ-ML-0090 :ref:`Makefile`/:ref:`configure` - REQ-ML-0100 :ref:`Makefile`/:ref:`configure` - REQ-ML-0110 all - REQ-ML-0112 all - REQ-ML-0115 :ref:`Makefile`/:ref:`configure` - REQ-ML-0180 :ref:`Makefile`/:ref:`configure` - REQ-ML-0200 sin - REQ-ML-0210 sin - REQ-ML-0220 sin - REQ-ML-0240 sin - REQ-ML-0250 asin - REQ-ML-0260 asin - REQ-ML-0270 asin - REQ-ML-0280 asin - REQ-ML-0281 asin - REQ-ML-0300 cos - REQ-ML-0310 cos - REQ-ML-0320 cos - REQ-ML-0330 cos - REQ-ML-0450 acos - REQ-ML-0460 acos - REQ-ML-0470 acos - REQ-ML-0480 acos - REQ-ML-0490 acos - REQ-ML-0500 tan - REQ-ML-0520 tan - REQ-ML-0530 tan - REQ-ML-0550 tan - REQ-ML-0600 atan - REQ-ML-0610 atan - REQ-ML-0620 atan - REQ-ML-0621 atan - REQ-ML-0650 atan2 - REQ-ML-0652 atan2 - REQ-ML-0660 atan2 - REQ-ML-0661 atan2 - REQ-ML-0662 atan2 - REQ-ML-0663 atan2 - REQ-ML-0670 atan2 - REQ-ML-0680 atan2 - REQ-ML-0681 atan2 - REQ-ML-0682 atan2 - REQ-ML-0683 atan2 - REQ-ML-0684 atan2 - REQ-ML-0685 atan2 - REQ-ML-0686 atan2 - REQ-ML-0700 sqrt - REQ-ML-0710 sqrt - REQ-ML-0720 sqrt - REQ-ML-0730 sqrt - REQ-ML-0740 sqrt - REQ-ML-0800 exp - REQ-ML-0831 exp - REQ-ML-0832 exp - REQ-ML-0833 exp - REQ-ML-0834 exp - REQ-ML-0850 pow - REQ-ML-0860 pow - REQ-ML-0864 pow - REQ-ML-0870 pow - REQ-ML-0871 pow - REQ-ML-0872 pow - REQ-ML-0873 pow - REQ-ML-0874 pow - REQ-ML-0875 pow - REQ-ML-0876 pow - REQ-ML-0877 pow - REQ-ML-0878 pow - REQ-ML-0879 pow - REQ-ML-0880 pow - REQ-ML-0881 pow - REQ-ML-0882 pow - REQ-ML-0883 pow - REQ-ML-0885 pow - REQ-ML-0886 pow - REQ-ML-0900 log - REQ-ML-0910 log - REQ-ML-0920 log - REQ-ML-0921 log - REQ-ML-0930 log - REQ-ML-0931 log - REQ-ML-0950 log10 - REQ-ML-0960 log10 - REQ-ML-0970 log10 - REQ-ML-0971 log10 - REQ-ML-0980 log10 - REQ-ML-0981 log10 - REQ-ML-1000 fabs - REQ-ML-1010 fabs - REQ-ML-1011 fabs - REQ-ML-1012 fabs - REQ-ML-1020 round - REQ-ML-1031 round - REQ-ML-1032 round - REQ-ML-1040 floor - REQ-ML-1051 floor - REQ-ML-1052 floor - REQ-ML-1060 trunc - REQ-ML-1070 trunc - REQ-ML-1071 trunc - REQ-ML-1080 ceil - REQ-ML-1091 ceil - REQ-ML-1092 ceil - REQ-ML-1100 fmod - REQ-ML-1120 fmod - REQ-ML-1121 fmod - REQ-ML-1122 fmod - REQ-ML-1130 fmod - REQ-ML-1131 fmod - REQ-ML-1200 modf - REQ-ML-1201 modf - REQ-ML-1210 modf - REQ-ML-1211 modf - REQ-ML-1220 fmin - REQ-ML-1230 fmin - REQ-ML-1232 fmin - REQ-ML-1240 fmax - REQ-ML-1250 fmax - REQ-ML-1252 fmax - REQ-ML-1260 hypot - REQ-ML-1270 hypot - REQ-ML-1271 hypot - REQ-ML-1300 isfinite - REQ-ML-1320 isinf - REQ-ML-1340 isnan - REQ-ML-1360 signbit - REQ-ML-1380 copysign - REQ-ML-1381 copysign - REQ-ML-1499 :ref:`Software Design - General ` - REQ-ML-1500 :ref:`Software Design - General ` - REQ-ML-1501 :ref:`Software Design - General ` - REQ-ML-1502 :ref:`Software Design - General ` - REQ-ML-1504 :ref:`Software Design - General ` - REQ-ML-1600 all - REQ-ML-1800 all - REQ-ML-1900 all - REQ-ML-1901 :ref:`Makefile`/:ref:`configure` - REQ-ML-2000 all - REQ-ML-2100 sinh - REQ-ML-2110 sinh - REQ-ML-2120 sinh - REQ-ML-2140 sinh - REQ-ML-2200 cosh - REQ-ML-2210 cosh - REQ-ML-2220 cosh - REQ-ML-2240 cosh - REQ-ML-2300 cbrt - REQ-ML-2310 cbrt - REQ-ML-2320 cbrt - REQ-ML-2340 cbrt - REQ-ML-2500 expm1 - REQ-ML-2500 fma - REQ-ML-2510 expm1 - REQ-ML-2510 fma - REQ-ML-2520 expm1 - REQ-ML-2520 fma - REQ-ML-2540 expm1 - REQ-ML-2540 tanh - REQ-ML-2550 expm1 - REQ-ML-2550 tanh - REQ-ML-2600 fdim - REQ-ML-2600 tanh - REQ-ML-2610 fdim - REQ-ML-2610 tanh - REQ-ML-2620 asinh - REQ-ML-2620 fdim - REQ-ML-2630 asinh - REQ-ML-2630 fdim - REQ-ML-2640 asinh - REQ-ML-2640 fdim - REQ-ML-2700 asinh - REQ-ML-2700 fma - REQ-ML-2710 acosh - REQ-ML-3010 acosh - REQ-ML-3020 acosh - REQ-ML-3030 acosh - REQ-ML-3040 acosh - REQ-ML-3100 atanh - REQ-ML-3110 atanh - REQ-ML-3120 atanh - REQ-ML-3121 atanh - REQ-ML-3140 atanh - REQ-ML-3141 atanh - REQ-ML-3200 exp2 - REQ-ML-3210 exp2 - REQ-ML-3220 exp2 - REQ-ML-3240 exp2 - REQ-ML-3250 exp2 - REQ-ML-3300 log2 - REQ-ML-3310 log2 - REQ-ML-3320 log2 - REQ-ML-3330 log2 - REQ-ML-3340 log2 - REQ-ML-3350 log2 - REQ-ML-3400 log1p - REQ-ML-3410 log1p - REQ-ML-3420 log1p - REQ-ML-3430 log1p - REQ-ML-3440 log1p - REQ-ML-3450 log1p - REQ-ML-3500 logb - REQ-ML-3510 logb - REQ-ML-3520 logb - REQ-ML-3540 logb - REQ-ML-3600 erf - REQ-ML-3610 erf - REQ-ML-3620 erf - REQ-ML-3630 erf - REQ-ML-3640 erf - REQ-ML-3700 erfc - REQ-ML-3710 erfc - REQ-ML-3720 erfc - REQ-ML-3730 erfc - REQ-ML-3740 erfc - REQ-ML-3800 lgamma - REQ-ML-3810 lgamma - REQ-ML-3820 lgamma - REQ-ML-3830 lgamma - REQ-ML-3840 lgamma - REQ-ML-3850 lgamma - REQ-ML-3850 signgam - REQ-ML-3900 remainder - REQ-ML-3910 remainder - REQ-ML-3920 remainder - REQ-ML-3940 remainder - REQ-ML-4000 frexp - REQ-ML-4010 frexp - REQ-ML-4020 frexp - REQ-ML-4040 frexp - REQ-ML-4100 ldexp - REQ-ML-4110 ldexp - REQ-ML-4120 ldexp - REQ-ML-4130 ldexp - REQ-ML-4140 ldexp - REQ-ML-4200 scalbn - REQ-ML-4210 scalbn - REQ-ML-4220 scalbn - REQ-ML-4230 scalbn - REQ-ML-4240 scalbn - REQ-ML-4250 scalbln - REQ-ML-4300 ilogb - REQ-ML-4310 ilogb - REQ-ML-4320 ilogb - REQ-ML-4340 ilogb - REQ-ML-4400 nan - REQ-ML-4500 nearbyint - REQ-ML-4510 nearbyint - REQ-ML-4520 nearbyint - REQ-ML-4540 nearbyint - REQ-ML-4600 rint - REQ-ML-4610 rint - REQ-ML-4620 rint - REQ-ML-4640 rint - REQ-ML-4650 lrint - REQ-ML-4653 lrint - REQ-ML-4656 lrint - REQ-ML-4659 lrint - REQ-ML-4662 lrint - REQ-ML-4670 llrint - REQ-ML-4700 nextafter - REQ-ML-4710 nextafter - REQ-ML-4720 nextafter - REQ-ML-4731 nextafter - REQ-ML-4740 nextafter - REQ-ML-4741 nextafter - REQ-ML-4750 nexttoward - REQ-ML-4900 isunordered - REQ-ML-4910 isunordered - REQ-ML-5000 isgreater - REQ-ML-5010 isgreater - REQ-ML-5100 isgreaterequal - REQ-ML-5110 isgreaterequal - REQ-ML-5200 isless - REQ-ML-5210 isless - REQ-ML-5300 islessequal - REQ-ML-5310 islessequal - REQ-ML-5400 islessgreater - REQ-ML-5410 islessgreater - REQ-ML-5500 isnormal - REQ-ML-5600 remquo - REQ-ML-5601 remquo - REQ-ML-5620 remquo - REQ-ML-5620 remquo - REQ-ML-5640 remquo - REQ-ML-5700 fpclassify - REQ-ML-5800 tgamma - REQ-ML-5810 tgamma - REQ-ML-5820 tgamma - REQ-ML-5830 tgamma - REQ-ML-5840 tgamma - REQ-ML-5841 tgamma - REQ-ML-6000 cacos - REQ-ML-6100 casin - REQ-ML-6200 catan - REQ-ML-6300 ccos - REQ-ML-6400 csin - REQ-ML-6500 ctan - REQ-ML-6600 cacosh - REQ-ML-6700 casinh - REQ-ML-6800 catanh - REQ-ML-6900 ccosh - REQ-ML-7000 csinh - REQ-ML-7100 ctanh - REQ-ML-7200 cexp - REQ-ML-7300 clog - REQ-ML-7400 cabs - REQ-ML-7500 cpow - REQ-ML-7600 csqrt - REQ-ML-7700 carg - REQ-ML-7800 cimag - REQ-ML-7900 cmplx - REQ-ML-8000 conj - REQ-ML-8100 cproj - REQ-ML-8200 creal - REQ-ML-8300 lround - REQ-ML-8310 lround - REQ-ML-8320 lround - REQ-ML-8330 lround - REQ-ML-8340 lround - REQ-ML-8400 llround - REQ-ML-8500 j0 - REQ-ML-8510 j0 - REQ-ML-8520 j0 - REQ-ML-8530 j1 - REQ-ML-8540 j1 - REQ-ML-8550 j1 - REQ-ML-8560 jn - REQ-ML-8570 jn - REQ-ML-8580 jn - REQ-ML-8600 y0 - REQ-ML-8601 y0 - REQ-ML-8605 y0 - REQ-ML-8610 y0 - REQ-ML-8620 y0 - REQ-ML-8621 y0 - REQ-ML-8630 y1 - REQ-ML-8631 y1 - REQ-ML-8635 y1 - REQ-ML-8640 y1 - REQ-ML-8650 y1 - REQ-ML-8651 y1 - REQ-ML-8660 yn - REQ-ML-8661 yn - REQ-ML-8665 yn - REQ-ML-8670 yn - REQ-ML-8680 yn - REQ-ML-8681 yn - REQ-ML-8700 :ref:`fenv ` - REQ-ML-8800 :ref:`tgmath ` - ============== ========================================== diff --git a/libm/libmcs/doc/sdd/conf.py b/libm/libmcs/doc/sdd/conf.py deleted file mode 100644 index d310fae8..00000000 --- a/libm/libmcs/doc/sdd/conf.py +++ /dev/null @@ -1,84 +0,0 @@ -# Configuration file for the Sphinx documentation builder. -# -# This file only contains a selection of the most common options. For a -# full list see the documentation: -# https://www.sphinx-doc.org/en/master/usage/configuration.html - -# -- Path setup ------------------------------------------------------- - -# If extensions (or modules to document with autodoc) are in another -# directory, add these directories to sys.path here. If the directory is -# relative to the documentation root, use os.path.abspath to make it -# absolute, like shown here. -# -import os -import sys -from shutil import copyfile -import sphinx_rtd_theme # pylint: disable=unused-import -from sphinx.errors import ConfigError - -sys.path.insert(0, os.path.abspath("..")) - -# -- Project information ---------------------------------------------- - -project = "LibmCS - SDD" -copyright = "2025, GTD GmbH" -author = "GTD GmbH" - - -# -- General configuration -------------------------------------------- - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = [ - "matplotlib.sphinxext.plot_directive", - "sphinx.ext.autodoc", - "sphinx.ext.autosectionlabel", - "sphinx.ext.mathjax", - "sphinx-mathjax-offline", - "sphinx_rtd_theme", - "hawkmoth", -] - -# Figures are referenced by number -numfig = True - -# Configuration for hawkmoth -hawkmoth_clang = ["-Ilibm/include", "-Isw-quality/dummy_includes"] -hawkmoth_root = os.path.abspath("../../libm") - -# Add any paths that contain templates here, relative to this directory. -templates_path = ["../_templates"] - -# -- Options for HTML output ------------------------------------------ - -# The theme to use for HTML and HTML Help pages. See the documentation -# for a list of builtin themes. -# -html_theme = "sphinx_rtd_theme" - -html_theme_options = { - "collapse_navigation": False, - "logo_only": True, -} - -html_logo = "../logo/libmcs-logo.png" -html_favicon = "../logo/libmcs-favicon.ico" - -# Add any paths that contain custom static files (such as style sheets) -# here, relative to this directory. They are copied after the builtin -# static files, so a file named "default.css" will overwrite the builtin -# "default.css". -html_static_path = ["../_static"] - -html_css_files = ["css/custom.css"] - -html_context = { - "display_gitlab": True, # Integrate Gitlab - "gitlab_host": "gitlab.com", - "gitlab_user": "gtd-gmbh", # Organization or User - "gitlab_repo": "libmcs", # Repo name - "gitlab_version": "development", # Version - "conf_py_path": "/doc/sdd/", # Path in the checkout to the docs root -} diff --git a/libm/libmcs/doc/sdd/index.rst b/libm/libmcs/doc/sdd/index.rst deleted file mode 100644 index dd3ec3ef..00000000 --- a/libm/libmcs/doc/sdd/index.rst +++ /dev/null @@ -1,18 +0,0 @@ -Mathematical Library for Critical Systems -========================================== - -The LibmCS library has been developed by re-engineering the ``libm`` included in the ``Newlib`` library version 4.0.0. The work has been carried out under ESA Contract No. 4000130278/20/NL/AS. - -The following pages in this documentation try to give a xenodochial introduction into LibmCS with focus on the software design. - -.. toctree:: - :numbered: - :maxdepth: 4 - :caption: Software Design Document - - 1_Introduction - 2_Applicable_and_Reference_Documents - 3_Abbreviations - 4_Software_Design_Overview - 5_Software_Design/0_Software_Design - 6_Requirements_to_Design_Components_Traceability diff --git a/libm/libmcs/doc/sum/10_Bindings.rst b/libm/libmcs/doc/sum/10_Bindings.rst deleted file mode 100644 index d2e1e2eb..00000000 --- a/libm/libmcs/doc/sum/10_Bindings.rst +++ /dev/null @@ -1,179 +0,0 @@ -Bindings for LibmCS -=================== - -.. raw:: html - - - -To enable the usage of the library from Matlab and using the Ada programming language we wish to provide some best practices and examples. This will cover the usage of library functions, but not the macros and constants as those are not directly accessible, they can however be easily wrapped with C-functions that return the result/value of the macros and constants. These functions can then be placed into Matlab/Ada the same as all other functions. - -Matlab -~~~~~~ - -This section describes the best practice to use the library from within Matlab using the sine function as an example. - -.. _BindingsMatlabGCC: - -Wrapper for GCC -^^^^^^^^^^^^^^^ - -Verify that your system has a working :ref:`GCC ` toolchain. Officially supported by Matlab is :ref:`GCC ` 4.9, but newer versions seem to work as well (at least for this example). Next, create a file named ``gcc`` with the following content: - -.. code-block:: bash - - #!/bin/bash - - /usr/bin/gcc $(echo $@ | sed 's/-lm //g') - -Place this script in your path before the real :ref:`GCC ` and check that ``which gcc`` in your shell returns the path to this script instead of the real :ref:`GCC `: - -.. code-block:: bash - - % which gcc - - /home//bin/gcc - -This strips ``-lm``, the default math library from the :ref:`GCC ` command line which allows to use the library's ``libm.a`` instead. Now start Matlab. - -Wrapper for a C Function -^^^^^^^^^^^^^^^^^^^^^^^^ - -Create a wrapper for the :ref:`sin` function available in the library's ``libm.a``. Name the file ``libmcs_sin.m`` and fill it with this content: - -.. code-block:: matlab - - function y = libmcs_sin(u) - - y = 0.0; - - y = coder.ceval('sin', u); - -Using the C Function Wrapper from Matlab -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The wrapper cannot be called directly because ``ceval`` cannot be called from Matlab. Thus it is necessary to generate a MEX function from this wrapper with ``codegen``. Generate and compile the code with the following command: - -.. code-block:: matlab - - codegen -config:mex -args 0.0 -o libmcs_sin ../libmcs/build-/bin/libm.a libmcs_sin - -Then calling the C function is possible from Matlab as one would expect. Matlab automatically uses the generated MEX function instead of the ``.m`` function: - -.. code-block:: matlab - - >> libmcs_sin(3.14) - - ans = - - 0.0016 - -After all MEX functions are generated, remove the :ref:`GCC ` wrapper created in :ref:`BindingsMatlabGCC`. Otherwise you may not be able to build other software correctly. - -Using the Wrapper from Simulink -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Create a new Model. Go to ``Simulation -> Model Configuration Parameters -> Simulation Target``. Under ``Additional Build Information -> Libraries`` enter the path to the library's ``libm.a``. In the reserved name field enter the function which shall not be used from the default libm, in this example ``sin``. The options are shown in the figure: - -.. raw:: html - - - -Go to ``Simulation -> Model Configuration Parameters -> Code Generation -> Custom Code`` and check the checkbox reading "Use the same custom code settings as simulation target". The options are shown in the figure: - -.. raw:: html - - - -Now add a Constant Block, a Matlab Function Block and a Scope Block to your model, so it looks like shown in the figure: - -.. raw:: html - - - -Double-click the Matlab Function Block and type in your Matlab Code calling the previously defined Wrapper: - -.. code-block:: matlab - - function y = fcn(u) - - y = libmcs_sin(u); - -You can now run your model as usual or use code generation. - -Verify that the Correct Function is Called -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -If you want to check whether the correct function is called, go to the library source code and edit the file ``libm/mathd/sind.c``. Change the sin function to return an arbitrary, but fixed value by inserting a ``return 99;`` statement right at the beginning of the function. After recompiling the library, as well as the MEX and S-functions, using the libmcs_sin function in Matlab and Simulink should then return ``99`` for all input values. This proves that the library's :ref:`sin` function is called and not the one from standard libm. - -Ada -~~~ - -This section describes the best practice to use the library as part of the Ada programming language using the sine function as an example. - -Create Bindings for Functions -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -For function bindings first create a thin binding that uses C-type input and output objects, then create a thick binding to convert the C-types to Ada-types. The following two example files contain some more description in the form of comments. - -.. code-block:: ada - - with Interfaces.C; - - -- This package contains thin & thick bindings for the mathematical functions - -- as defined in Ada LRM Annex A.5.1. - package LIBMCS.Elementary_Functions is - - -- Declaration of the thick binding function that should - -- be used to call 'sinf'. This function converts the Math_Float to the - -- appropriate C types and calls 'c_sinf' that is declared in - -- the private part of this package. - function Sinf (X : Math_Float) return Math_Float; - - -- ... More functions see Ada LRM Annex A.5.1 - - private - use Interfaces.C; - - -- The thin binding declaration for 'sinf'. - function c_sinf (X : c_float) return c_float; - - -- This import pragma tells the compiler to substitute calls to 'c_sinf' - -- with appropriate calls to the C function 'sinf' - -- This pragma could be an aspect in Ada2012. - pragma Import (Convention => C, - Entity => c_sinf, - External_Name => "sinf"); - - end LIBMCS.Elementary_Functions; - -.. code-block:: ada - - -- Implementation file for the LIBMCS.Elementary_Functions package. - package body LIBMCS.Elementary_Functions is - use Interfaces.C; - - -- Thick binding for 'sinf'. This function converts the argument given as - -- the native Ada type 'Math_Float' to the appropriate C type. - -- This function can be responsible for additional range/boundary checking - -- and raise exceptions if invalid values are provided. - -- The function also converts the return value of 'sinf' from the C type to - -- the native Ada type. - function Sinf (X : Math_Float) return Math_Float is - c_X : c_float := c_float (X); - Sine : c_float; - begin - Sine := c_sinf (c_X); - return Math_Float (Sine); - end Sinf; - - -- ... More functions see Ada LRM Annex A.5.1 - - end LIBMCS.Elementary_Functions; diff --git a/libm/libmcs/doc/sum/1_Abbreviations.rst b/libm/libmcs/doc/sum/1_Abbreviations.rst deleted file mode 100644 index f2d094af..00000000 --- a/libm/libmcs/doc/sum/1_Abbreviations.rst +++ /dev/null @@ -1,112 +0,0 @@ -.. _ABBR: - -Terms, Definitions and Abbreviated Terms -======================================== - -.. raw:: html - - - -Agency - refers to :ref:`ESA ` - -BSP - Board Support Package - -CPU - Central Processing Unit - -DAZ - Denormals are Zero (see also :ref:`FTZ `) - -denormal - See subnormal. - -DRD - Document Requirements Definition - -ECSS - European Cooperation for Space Standardization - -ESA - European Space Agency - -FMA - Fused-Multiply-Add - -FPU - Floating Point Unit - -FSR - :ref:`FPU ` State Register - -FTZ - Flush to Zero (see also :ref:`DAZ `) - -GCC - :ref:`GNU ` Compiler Collection - -GNU - recursive acronym for "GNU's Not Unix!", GNU is an extensive collection of free software which can be used as (or as part of) an operating system - -ICD - Interface Control Document - -IEEE - Institute of Electrical and Electronics Engineers - -ISO - International Organization for Standardization - -OS - Operating System - -POSIX - Portable Operating System Interface - -PSR - Processor State Register - -QG - Qualification Guideline - -RAM - Random Access Memory - -RTEMS - Real-Time Executive for Multiprocessor Systems - -SCF - Software Configuration File - -SDD - Software Design Document - -SPDX - Software Package Data Exchange - -SRF - Software Reuse File - -SRS - Software Requirements Specification - -subnormal - See IEEE-754 standard for the definition. - -SUITR - Software Unit- and Integration-Test Report - -SValR - Software Validation-Test Report - -SVR - Software Verification Report - -ULP - Unit in the Last Place - -YAML - YAML Ain't Markup Language (formerly: Yet Another Markup Language) diff --git a/libm/libmcs/doc/sum/2_Conventions.rst b/libm/libmcs/doc/sum/2_Conventions.rst deleted file mode 100644 index b009841c..00000000 --- a/libm/libmcs/doc/sum/2_Conventions.rst +++ /dev/null @@ -1,39 +0,0 @@ -Conventions -=========== - -This chapter lists the symbols, stylistic conventions, and command syntax used in this document. Each convention is identified by a name and described by an example and the additional -explanation. - -.. table:: Notation conventions - :width: 100% - - +---------------------------+---------------------------+----------------------------------------------------------+ - | Convention | Example | Explanation | - +===========================+===========================+==========================================================+ - | Pi | :math:`\pi` | The mathematical constant :math:`\pi` | - +---------------------------+---------------------------+----------------------------------------------------------+ - | Not a Number | NaN or ``NaN`` | Representation for "not a number"-value | - +---------------------------+---------------------------+----------------------------------------------------------+ - | Quiet NaN | qNaN, ``qNaN`` | Representation for "quiet not a number"-value | - +---------------------------+---------------------------+----------------------------------------------------------+ - | Signalling NaN | sNaN, ``sNaN`` | Representation for "signalling not a number"-value | - +---------------------------+---------------------------+----------------------------------------------------------+ - | Signed NaN | +NaN or -NaN | Representation for "not a number"-value, that explicitly | - | | | has the signbit unset/set. This definition does not | - | | | exist within the IEEE-754 standard and is added for | - | | | better readability of the table | - +---------------------------+---------------------------+----------------------------------------------------------+ - | Infinity | +/-Inf or ±Inf | Representation for an Infinity value | - +---------------------------+---------------------------+----------------------------------------------------------+ - | File | ``k_sin.c`` | Indication of a code file | - +---------------------------+---------------------------+----------------------------------------------------------+ - | Source Code | ``sin(double x)`` | Indication of code | - +---------------------------+---------------------------+----------------------------------------------------------+ - | Constants | ``M_PI``, ``FLT_MAX`` | Indication of code | - +---------------------------+---------------------------+----------------------------------------------------------+ - -We define the set of all floating-point numbers as :math:`\mathbb{F}` and the set of all subnormal numbers as :math:`\mathbb{S}` to be used in mathematical formulae. The set of floating-point numbers :math:`\mathbb{F}` contains all floating-point numbers, that is normals, subnormals (therefore :math:`\mathbb{S} \subset \mathbb{F}`), zeroes, infinities and ``NaN``, of the type given by the context. If a reduction to a specific type is needed, this will be indicated as follows: :math:`\mathbb{F}_s` for single precision, :math:`\mathbb{F}_d` for double precision, and :math:`\mathbb{F}_{ld}` for long double precision. The same will be done for :math:`\mathbb{S}` with :math:`\mathbb{S}_s`, :math:`\mathbb{S}_d`, and :math:`\mathbb{S}_{ld}` respectively. Furthermore :math:`\mathbb{F}^{+}` symbolizes all floating-point numbers where the sign bit is not set, while :math:`\mathbb{F}^{-}` contains all those where the sign bit is set (this includes :math:`-0.0`, ``-Inf``, and ``NaNs`` where the signbit is set). Using these sets we are able to express floating-point numbers in mathematical formulae, for example the formula :math:`x \in \mathbb{F} \setminus \left \{ \pm \text{Inf}, \text{NaN} \right \}` denotes that `x` is a floating-point number that is neither infinity nor ``NaN``, which leaves `x` to be either zero, a normal or a subnormal number. :math:`\mathbb{F}` cannot be fully represented by conventional number classifications due to the introduction of :math:`\pm 0.0`, explicit infinities and ``NaNs``, however the following is valid: :math:`(\mathbb{F} \setminus \left \{ -0.0, \pm \text{Inf}, \text{NaN} \right \}) \subset \mathbb{Q}`. - -Similarly we define the set of all 32bit integer numbers as :math:`\mathbb{I}`. :math:`\mathbb{I}` is a subset of :math:`\mathbb{Z}` limited by the size of the integer, therefore :math:`\mathbb{I} \subset \mathbb{Z}`. The same concept applies for :math:`\mathbb{I}_{l}` which represents either 32bit or 64bit integer numbers depending on the size of ``long int``, and :math:`\mathbb{I}_{ll}` which represents 64bit integer numbers. - -To denote the similarity, but not always equality, between the mathematical function and its representing procedure we use :math:`\approx` where appropriate. This is not used if a procedure is able to exactly mimic the functionality of the mathematical function. diff --git a/libm/libmcs/doc/sum/3_Purpose_of_the_Software.rst b/libm/libmcs/doc/sum/3_Purpose_of_the_Software.rst deleted file mode 100644 index cbd93ddf..00000000 --- a/libm/libmcs/doc/sum/3_Purpose_of_the_Software.rst +++ /dev/null @@ -1,318 +0,0 @@ -Purpose of the Software -======================= - -The software in this project is intended to be included in other software projects. It is designed -and developed to be integrated in other software projects up to criticality B. - -The library contains the following procedures which can be included with ``math.h`` (these lists only contain the name of the ``double`` procedure, you can expect all procedures (except for the Bessel functions) to have versions for ``float`` suffixed with ``f`` and ``long double`` suffixed with ``l`` (note however that ``long double`` only exists when it has the same size as ``double``)): - -.. table:: List of all procedures in math.h - :name: List of math procedures - - +--------------------+-----------------------------------------------------------+ - | Procedure | Description | - +====================+===========================================================+ - | ``fpclassify`` | Procedure returning the classification of the argument | - +--------------------+-----------------------------------------------------------+ - | ``isfinite`` | Procedure returning whether the value of the argument is | - | | finite or not (not :math:`±Inf` and not :math:`NaN`) | - +--------------------+-----------------------------------------------------------+ - | ``isinf`` | Procedure returning whether the value of the argument is | - | | positive or negative Infinity or not | - +--------------------+-----------------------------------------------------------+ - | ``isnan`` | Procedure returning whether the argument is a | - | | :math:`NaN` floating-point value or not | - +--------------------+-----------------------------------------------------------+ - | ``isnormal`` | Procedure returning whether the argument is a normal | - | | floating-point value or not | - +--------------------+-----------------------------------------------------------+ - | ``signbit`` | Procedure returning whether the argument is negative or | - | | not | - +--------------------+-----------------------------------------------------------+ - | ``acos`` | Procedure returning the trigonometric arccosine | - +--------------------+-----------------------------------------------------------+ - | ``asin`` | Procedure returning the trigonometric arcsine | - +--------------------+-----------------------------------------------------------+ - | ``atan`` | Procedure returning the trigonometric arctangent | - +--------------------+-----------------------------------------------------------+ - | ``atan2`` | Procedure returning the trigonometric arctangent of | - | | :math:`\frac{y}{x}` | - +--------------------+-----------------------------------------------------------+ - | ``cos`` | Procedure returning the trigonometric cosine | - +--------------------+-----------------------------------------------------------+ - | ``sin`` | Procedure returning the trigonometric sine | - +--------------------+-----------------------------------------------------------+ - | ``tan`` | Procedure returning the trigonometric tangent | - +--------------------+-----------------------------------------------------------+ - | ``acosh`` | Procedure returning the hyperbolic arccosine | - +--------------------+-----------------------------------------------------------+ - | ``asinh`` | Procedure returning the hyperbolic arcsine | - +--------------------+-----------------------------------------------------------+ - | ``atanh`` | Procedure returning the hyperbolic arctangent | - +--------------------+-----------------------------------------------------------+ - | ``cosh`` | Procedure returning the hyperbolic cosine | - +--------------------+-----------------------------------------------------------+ - | ``sinh`` | Procedure returning the hyperbolic sine | - +--------------------+-----------------------------------------------------------+ - | ``tanh`` | Procedure returning the hyperbolic tangent | - +--------------------+-----------------------------------------------------------+ - | ``exp`` | Procedure returning the base :math:`e` exponential of | - | | :math:`x` | - +--------------------+-----------------------------------------------------------+ - | ``exp2`` | Procedure returning the base :math:`2` exponential of | - | | :math:`x` | - +--------------------+-----------------------------------------------------------+ - | ``expm1`` | Procedure returning the base :math:`e` exponential of | - | | :math:`x` minus :math:`1` | - +--------------------+-----------------------------------------------------------+ - | ``frexp`` | Procedure breaking :math:`x` into a normalized fraction | - | | and an integral power of :math:`2` | - +--------------------+-----------------------------------------------------------+ - | ``ilogb`` | Procedure returning the binary exponent of :math:`x` as | - | | integer | - +--------------------+-----------------------------------------------------------+ - | ``ldexp`` | Procedure returning :math:`x` multiplied by an integral | - | | power of :math:`2` | - +--------------------+-----------------------------------------------------------+ - | ``log`` | Procedure returning the natural logarithm | - +--------------------+-----------------------------------------------------------+ - | ``log10`` | Procedure returning the base :math:`10` logarithm | - +--------------------+-----------------------------------------------------------+ - | ``log1p`` | Procedure returning the natural logarithm of | - | | :math:`x + 1` | - +--------------------+-----------------------------------------------------------+ - | ``log2`` | Procedure returning the base :math:`2` logarithm | - +--------------------+-----------------------------------------------------------+ - | ``logb`` | Procedure returning the binary exponent of :math:`x` | - +--------------------+-----------------------------------------------------------+ - | ``modf`` | Procedure breaking :math:`x` in its integral and | - | | fractional part | - +--------------------+-----------------------------------------------------------+ - | ``scalbn`` | Procedure returning :math:`x` multiplied by an integral | - | | power of :math:`2` | - +--------------------+-----------------------------------------------------------+ - | ``scalbln`` | Procedure returning :math:`x` multiplied by an integral | - | | power of :math:`2` | - +--------------------+-----------------------------------------------------------+ - | ``cbrt`` | Procedure returning the cubic root | - +--------------------+-----------------------------------------------------------+ - | ``fabs`` | Procedure returning the absolute value | - +--------------------+-----------------------------------------------------------+ - | ``hypot`` | Procedure returning the square root of :math:`x^2+y^2` | - +--------------------+-----------------------------------------------------------+ - | ``pow`` | Procedure returning :math:`x` raised to the power of | - | | :math:`y` | - +--------------------+-----------------------------------------------------------+ - | ``sqrt`` | Procedure returning the square root | - +--------------------+-----------------------------------------------------------+ - | ``erf`` | Procedure returning the error function | - +--------------------+-----------------------------------------------------------+ - | ``erfc`` | Procedure returning the complementary error function | - | | (``erfc`` = :math:`1 -` ``erf``) | - +--------------------+-----------------------------------------------------------+ - | ``lgamma`` | Procedure returning the natural logarithm of the absolute | - | | value of gamma of :math:`x` | - +--------------------+-----------------------------------------------------------+ - | ``tgamma`` | Procedure returning gamma function of :math:`x` | - +--------------------+-----------------------------------------------------------+ - | ``ceil`` | Procedure for rounding upwards to the nearest integer | - +--------------------+-----------------------------------------------------------+ - | ``floor`` | Procedure for rounding downwards to the nearest integer | - +--------------------+-----------------------------------------------------------+ - | ``nearbyint`` | Procedure for rounding to the nearest integer using the | - | | current rounding direction | - +--------------------+-----------------------------------------------------------+ - | ``rint`` | Procedure for rounding to the nearest integer using the | - | | current rounding direction (raises inexact) | - +--------------------+-----------------------------------------------------------+ - | ``lrint`` | Procedure for rounding to the nearest integer using the | - | | current rounding direction | - +--------------------+-----------------------------------------------------------+ - | ``llrint`` | Procedure for rounding to the nearest integer using the | - | | current rounding direction | - +--------------------+-----------------------------------------------------------+ - | ``round`` | Procedure for rounding to the nearest integer (Halfway | - | | values rounded away from :math:`0`) | - +--------------------+-----------------------------------------------------------+ - | ``lround`` | Procedure for rounding to the nearest integer (Halfway | - | | values rounded away from :math:`0`) | - +--------------------+-----------------------------------------------------------+ - | ``llround`` | Procedure for rounding to the nearest integer (Halfway | - | | values rounded away from :math:`0`) | - +--------------------+-----------------------------------------------------------+ - | ``trunc`` | Procedure for rounding towards :math:`0` to the nearest | - | | integer | - +--------------------+-----------------------------------------------------------+ - | ``fmod`` | Procedure returning the floating-point remainder of | - | | :math:`\frac{y}{x}` (rounded towards zero) | - +--------------------+-----------------------------------------------------------+ - | ``remainder`` | Procedure returning the floating-point remainder of | - | | :math:`\frac{y}{x}` (rounded to nearest integral value) | - +--------------------+-----------------------------------------------------------+ - | ``remquo`` | Procedure returning the same value as ``remainder`` and | - | | puts the quotient in :math:`*quo` | - +--------------------+-----------------------------------------------------------+ - | ``copysign`` | Procedure returning a floating-point number with the | - | | magnitude of :math:`x` and the sign of :math:`y` | - +--------------------+-----------------------------------------------------------+ - | ``nan`` | Procedure returning a :math:`NaN` | - +--------------------+-----------------------------------------------------------+ - | ``nextafter`` | Procedure returning the next floating-point value after | - | | :math:`x` in direction of :math:`y` | - +--------------------+-----------------------------------------------------------+ - | ``nexttoward`` | Procedure returning the next floating-point value after | - | | :math:`x` in direction of :math:`y` | - +--------------------+-----------------------------------------------------------+ - | ``fdim`` | Procedure returning the positive difference between the | - | | arguments | - +--------------------+-----------------------------------------------------------+ - | ``fmax`` | Procedure returning the larger of two values | - +--------------------+-----------------------------------------------------------+ - | ``fmin`` | Procedure returning the smaller of two values | - +--------------------+-----------------------------------------------------------+ - | ``fma`` | Procedure returning the result of :math:`x \cdot y + z` | - +--------------------+-----------------------------------------------------------+ - | ``isgreater`` | Procedure returning whether :math:`x` is greater than | - | | :math:`y` | - +--------------------+-----------------------------------------------------------+ - | ``isgreaterequal`` | Procedure returning whether :math:`x` is greater than or | - | | equal to :math:`y` | - +--------------------+-----------------------------------------------------------+ - | ``isless`` | Procedure returning whether :math:`x` is less than | - | | :math:`y` | - +--------------------+-----------------------------------------------------------+ - | ``islessequal`` | Procedure returning whether :math:`x` is less than or | - | | equal to :math:`y` | - +--------------------+-----------------------------------------------------------+ - | ``islessgreater`` | Procedure returning whether :math:`x` is less or greater | - | | than :math:`y` | - +--------------------+-----------------------------------------------------------+ - | ``isunordered`` | Procedure returning whether the arguments are unordered | - | | (aka at least one is :math:`NaN`) | - +--------------------+-----------------------------------------------------------+ - | ``j0`` | Procedure returning the Bessel value of :math:`x` of the | - | | first kind of order :math:`0` | - +--------------------+-----------------------------------------------------------+ - | ``j1`` | Procedure returning the Bessel value of :math:`x` of the | - | | first kind of order :math:`1` | - +--------------------+-----------------------------------------------------------+ - | ``jn`` | Procedure returning the Bessel value of :math:`x` of the | - | | first kind of order :math:`n` | - +--------------------+-----------------------------------------------------------+ - | ``y0`` | Procedure returning the Bessel value of :math:`x` of the | - | | second kind of order :math:`0` | - +--------------------+-----------------------------------------------------------+ - | ``y1`` | Procedure returning the Bessel value of :math:`x` of the | - | | second kind of order :math:`1` | - +--------------------+-----------------------------------------------------------+ - | ``yn`` | Procedure returning the Bessel value of :math:`x` of the | - | | second kind of order :math:`n` | - +--------------------+-----------------------------------------------------------+ - -Additionally ``complex.h`` includes the following procedures: - -.. table:: List of all procedures in complex.h - :name: List of complex procedures - - +--------------------+-----------------------------------------------------------+ - | Procedure | Description | - +====================+===========================================================+ - | ``cacos`` | Procedure returning the complex trigonometric arccosine | - +--------------------+-----------------------------------------------------------+ - | ``casin`` | Procedure returning the complex trigonometric arcsine | - +--------------------+-----------------------------------------------------------+ - | ``catan`` | Procedure returning the complex trigonometric arctangent | - +--------------------+-----------------------------------------------------------+ - | ``ccos`` | Procedure returning the complex trigonometric cosine | - +--------------------+-----------------------------------------------------------+ - | ``csin`` | Procedure returning the complex trigonometric sine | - +--------------------+-----------------------------------------------------------+ - | ``ctan`` | Procedure returning the complex trigonometric tangent | - +--------------------+-----------------------------------------------------------+ - | ``cacosh`` | Procedure returning the complex hyperbolic arccosine | - +--------------------+-----------------------------------------------------------+ - | ``casinh`` | Procedure returning the complex hyperbolic arcsine | - +--------------------+-----------------------------------------------------------+ - | ``catanh`` | Procedure returning the complex hyperbolic arctangent | - +--------------------+-----------------------------------------------------------+ - | ``ccosh`` | Procedure returning the complex hyperbolic cosine | - +--------------------+-----------------------------------------------------------+ - | ``csinh`` | Procedure returning the complex hyperbolic sine | - +--------------------+-----------------------------------------------------------+ - | ``ctanh`` | Procedure returning the complex hyperbolic tangent | - +--------------------+-----------------------------------------------------------+ - | ``cexp`` | Procedure returning the complex base :math:`e` | - | | exponential of :math:`z` | - +--------------------+-----------------------------------------------------------+ - | ``clog`` | Procedure returning the complex natural logarithm | - +--------------------+-----------------------------------------------------------+ - | ``cabs`` | Procedure returning the complex absolute value | - +--------------------+-----------------------------------------------------------+ - | ``cpow`` | Procedure returning the complex value :math:`x` raised to | - | | the power of :math:`y` | - +--------------------+-----------------------------------------------------------+ - | ``csqrt`` | Procedure returning the complex square root | - +--------------------+-----------------------------------------------------------+ - | ``carg`` | Procedure returning the value of :math:`z` in the | - | | interval [:math:`-\pi`, :math:`+\pi`] | - +--------------------+-----------------------------------------------------------+ - | ``cimag`` | Procedure returning the imaginary part of the value of | - | | :math:`z` | - +--------------------+-----------------------------------------------------------+ - | ``CMPLX`` | Procedure returning the complex value with real part | - | | :math:`x` and imaginary part :math:`y` | - +--------------------+-----------------------------------------------------------+ - | ``conj`` | Procedure returning the complex conjugate value of | - | | :math:`z` | - +--------------------+-----------------------------------------------------------+ - | ``cproj`` | Procedure returning the value of the projection onto the | - | | Riemann sphere of :math:`z` | - +--------------------+-----------------------------------------------------------+ - | ``creal`` | Procedure returning the real part of the value of | - | | :math:`z` | - +--------------------+-----------------------------------------------------------+ - -Furthermore the library provides a number of constants, as part of ``math.h``: - -.. table:: List of all constant defines in math.h - :name: List of math constants - - ===================== =============================================== - Name Description - ===================== =============================================== - ``M_E`` Value of :math:`e` - ``M_LOG2E`` Value of :math:`log_{2} e` - ``M_LOG10E`` Value of :math:`log_{10} e` - ``M_LN2`` Value of :math:`log_e 2` - ``M_LN10`` Value of :math:`log_e 10` - ``M_PI`` Value of :math:`\pi` - ``M_PI_2`` Value of :math:`\frac{\pi}{2}` - ``M_PI_4`` Value of :math:`\frac{\pi}{4}` - ``M_1_PI`` Value of :math:`\frac{1}{\pi}` - ``M_2_PI`` Value of :math:`\frac{2}{\pi}` - ``M_2_SQRTPI`` Value of :math:`\frac{2}{\sqrt{\pi}}` - ``M_SQRT2`` Value of :math:`\sqrt{2}` - ``M_SQRT1_2`` Value of :math:`\sqrt{\frac{1}{2}}` - ``HUGE_VAL`` Value of :math:`+Inf` (double) - ``HUGE_VALF`` Value of :math:`+Inf` (float) - ``HUGE_VALL`` Value of :math:`+Inf` (long double) - ``INFINITY`` Value of :math:`+Inf` - ``NAN`` Value of :math:`NaN` - ``MAXFLOAT`` Synonym of ``FLT_MAX`` - ``FP_INFINITE`` :math:`1` - ``FP_NAN`` :math:`0` - ``FP_NORMAL`` :math:`4` - ``FP_SUBNORMAL`` :math:`3` - ``FP_ZERO`` :math:`2` - ``FP_ILOGB0`` Value to return for :ref:`ilogb` (:math:`0`) - ``FP_ILOGBNAN`` Value to return for :ref:`ilogb` (:math:`NaN`) - ``MATH_ERRNO`` :math:`1` - ``MATH_ERREXCEPT`` :math:`2` - ``math_errhandling`` ``MATH_ERREXCEPT`` - ===================== =============================================== - -*Remark:* Both ``INFINITY`` and ``NAN`` expand to floats or doubles depending on the context. - -``math.h`` further declares the types ``double_t`` and ``float_t`` as ``double`` and ``float``. - -``complex.h`` declares the types ``complex``, ``imaginary``, ``_Complex_I``, ``_Imaginary_I`` and ``I`` as ``_Complex``, ``_Imaginary``, ``const float _Complex``, ``const float _Imaginary``, and ``_Complex_I`` respectively. (Note that your toolchain (such as GCC) may not properly implement imaginary types, as such it is likely that all definitions are complex types.) \ No newline at end of file diff --git a/libm/libmcs/doc/sum/4_General_Behaviour.rst b/libm/libmcs/doc/sum/4_General_Behaviour.rst deleted file mode 100644 index fa7fbfd4..00000000 --- a/libm/libmcs/doc/sum/4_General_Behaviour.rst +++ /dev/null @@ -1,395 +0,0 @@ -General Behaviour -================= - -All procedures can handle all input values of its respective types, including special values such as ``NaNs`` or infinities. Pointers used to output additional return values are under the user’s control, using misplaced or ``NULL`` pointers may cause unwanted behaviour or even a crash of the system. The ``NULL`` pointers are handled appropriately by the library, but no action can be taken against using misplaced pointers. - -NaN Values -~~~~~~~~~~ - -As can be seen in :ref:`Conventions` there exist different types of ``NaNs``. - -What are they? ``NaN`` is the result of a procedure that does not generate a valid and representable result. This happens for example with :math:`\frac{0.0}{0.0}`, with ``sqrt(-1.0)`` :math:`(= \sqrt{-1})`, or with ``Inf - Inf``, in the first and third cases because the behavior is undefined, in the second because complex/imaginary numbers cannot be represented in the data type of the procedure. ``NaN`` can also be used as an input argument for procedures, in most cases this results in a ``NaN`` return value. - -What's the difference between ``NaN``, ``qNaN`` and ``sNaN``? Both ``qNaNs`` and ``sNaNs`` are a subgroup of all ``NaNs``, they differ in a specific bit that is either set (``qNaN``) or not set (``sNaN``). All procedures will only return ``qNaNs`` and never ``sNaNs``. The difference is on the other side: when an ``sNaN`` is put as an argument to a procedure, the :ref:`FPU ` shall signal an ``invalid operation`` exception, while a ``qNaN`` is quietly accepted, hence the names. As ``sNaNs`` are never produced by the :ref:`FPU ` they can be regarded as a testing feature. - -In :ref:`Conventions` we also differentiate between ``-NaN`` (``NaN`` where the signbit is set) and ``+NaN`` (``NaN`` where the signbit is not set). This separation does not exist anywhere within the :ref:`IEEE-754 ` or C18 standards, ``NaNs`` are simply ``NaNs`` regardless of their sign. We however need this differentiation for the procedures :ref:`signbit` and :ref:`copysign`, as both only check the sign of a value and ignore the rest. - -The ``nan (const char *payload)``, ``nanf (const char *payload)``, and ``nanl (const char *payload)`` functions of the library are not fully ISO C compliant as they return a fix defined ``NaN`` regardless of the function parameter. The rationale for this is to keep the LibmCS standalone, without any dependency to other standard C library functions. A workaround is proposed in the section describing these functions. - -.. _GeneralBehaviourSubnormalValues: - -Subnormal Values -~~~~~~~~~~~~~~~~ - -The library regards subnormals the same as any other value, meaning when a procedure is called with a subnormal input argument, the procedures will do their work just as well as for any non subnormal value. This however only works as expected, if the :ref:`FPU ` in use supports subnormal values. - -In case the :ref:`FPU ` does not fully support subnormals the user should enable the preprocessor define ``LIBMCS_FPU_DAZ`` while running the library's configuration when prompted to make the decision. This forces every input value to first be checked by the :ref:`FPU ` for being a subnormal, and if it is, act according to the implementation of the :ref:`FPU `. This behavior will apply to most of the procedures contained in the library. Exceptions to this behavior being (i.e., the following procedures do correctly handle subnormals even if the FPU has no subnormal support): - -* ``fabs`` and ``fabsf`` -* ``copysign`` and ``copysignf`` -* ``fpclassify`` -* ``isfinite`` -* ``isinf`` -* ``isnan`` -* ``isnormal`` -* ``signbit`` -* ``isunordered`` -* ``isgreater`` (only on GRFPUs before GRFPU5) -* ``isgreaterequal`` (only on GRFPUs before GRFPU5) -* ``isless`` (only on GRFPUs before GRFPU5) -* ``islessequal`` (only on GRFPUs before GRFPU5) -* ``islessgreater`` (only on GRFPUs before GRFPU5) - -In addition to this the following procedures implement a non-standard behavior to ensure that they don't get stuck at subnormals when using them on FPUs without subnormal support (i.e., they jump over the subnormal range): - -* ``nextafter`` and ``nextafterf`` -* ``nexttoward`` and ``nexttowardf`` - -One example of such a non-supporting :ref:`FPU ` is the :ref:`GRFPU ` from CAES/Gaisler. The :ref:`GRFPU ` causes a trap if subnormal numbers occur and the :ref:`GRFPU ` is not configured to use non-standard mode [#]_. If the non-standard mode is enabled however, the :ref:`FPU ` behaves in a :ref:`DAZ ` and :ref:`FTZ ` way. This means when ``LIBMCS_FPU_DAZ`` is defined, every call to the library's procedures with a subnormal input will either cause a trap (in standard mode) or behave as if the input was zero (in non-standard mode). - -If the user's :ref:`FPU ` behaves as the :ref:`GRFPU ` we suggest using the standard mode during production and switching to non-standard mode after sufficient testing (or if the user decides that subnormals are part of normal behaviour). This has the benefit that errors can be found more easily during production (as subnormal numbers in most cases should be an error in the source code), and not causing a trap on the final product in the odd case that a subnormal still appears. - -The following table shows some FPUs, their support regarding subnormal floating-point numbers and the particularities of the supported :ref:`DAZ ` and :ref:`FTZ ` mode: - -+--------------------------+-----------------------+-------------------------------------------------------------+ -| FPU | Subnormal support | Operations not affected by FTZ/DAZ mode | -+==========================+=======================+=============================================================+ -| MEIKO FPU | Yes | Not applicable | -+--------------------------+-----------------------+-------------------------------------------------------------+ -| GRFPU (until v4) | No | compare, move, negate, and absolute value | -+--------------------------+-----------------------+-------------------------------------------------------------+ -| GRFPU-Lite | No | compare, move, negate, and absolute value | -+--------------------------+-----------------------+-------------------------------------------------------------+ -| GRFPU5 | Yes | Not applicable | -+--------------------------+-----------------------+-------------------------------------------------------------+ -| Gaisler NanoFPU | No | compare, move, negate, and absolute value | -+--------------------------+-----------------------+-------------------------------------------------------------+ -| GRFPUnv | Yes | Not applicable | -+--------------------------+-----------------------+-------------------------------------------------------------+ -| ARM FPUs (NEON and VFPU) | Selectable | V{Q}ABS, V{Q}NEG, VMOV, VMVN, VDUP, VLDR VSTR, VLDM, VSTM | -+--------------------------+-----------------------+-------------------------------------------------------------+ -| SiFive FPU | Yes | Not applicable | -+--------------------------+-----------------------+-------------------------------------------------------------+ -| x86 | Selectable | x87 floating point instructions | -+--------------------------+-----------------------+-------------------------------------------------------------+ - -This table is by no means exhaustive and shall only be used for preliminary iformation purposes. The user of the library shall the concretely check the specification of the :ref:`FPU ` as there are may additional particularities to be taken into account. For example we have the particular case of ARM FPUs: - -* NEON and VFPv3 flush-to-zero preserves the sign bit. VFPv2 flush-to-zero flushes to +0. -* NEON always uses flush-to-zero mode. - -.. [#] See `Handling denormalized numbers with the GRFPU `_ Section 4.1 for more information on how to enable non-standard mode on the :ref:`GRFPU `. - -Fused Multiply-Add -~~~~~~~~~~~~~~~~~~ - -The IEEE-754 floating-point arithmetic standard requires since its 2008 version that compliant systems must support the :ref:`FMA ` operation. This operation is also required by the ISO C standard. Older FPUs and the SPARC V8 instruction set however do not support nor require this operation. - -Because of this reason the LibmCS includes the ``fma`` and ``fmaf`` procedures but only with a non-standard conform naive implementation carrying out a multiplication and addition in sequence with two roundings instead of the single rounding step required by the :ref:`FMA ` operation. - -On systems supporting the :ref:`FMA ` operation users can use compiler built-ins to explicitely call ``fma`` if needed. - -Exceptions -~~~~~~~~~~ - -Exceptions raised by the procedures are listed in the :ref:`Reference Manual`. These are in accordance with the :ref:`ISO ` C, :ref:`IEEE-754 ` and :ref:`POSIX ` standards. The :ref:`Reference Manual` will only list the exceptions ``invalid operation``, ``divide by zero`` and ``overflow`` while not stating ``underflow`` and ``inexact``. These are the three exceptions deemed as important in *IEEE 754 Error Handling and Programming Languages* [NM]_. - -The :ref:`POSIX ` standard does not define errors/exceptions for complex procedures. The implementations however make use of multiple non-complex procedures which do raise exceptions. As such the :ref:`Reference Manual` does not list the exceptions thrown by complex procedures, it is assumed that the exceptions of their underlying procedures apply. - -All procedures raise ``invalid operation`` exception when the input argument is ``sNaN`` unless stated otherwise in the :ref:`Reference Manual`. - -.. [NM] *IEEE 754 Error Handling and Programming Languages* by Nick Maclaren. - -Limitations of the Libm -~~~~~~~~~~~~~~~~~~~~~~~ - -Qualification Status -^^^^^^^^^^^^^^^^^^^^ - -This software release is qualified to :ref:`ECSS ` category B, but only for the following configurations: - -#. target GR-CPCI-AT697 ("Compact PCI LEON2-FT (AT697E) Development Board") with a compiler toolchain based on EDISOFT's :ref:`RTEMS ` 4.8 (including :ref:`GCC ` 4.2.1), and -#. target GR-CPCI-LEON4-N2X ("Quad-Core LEON4 Next Generation Microprocessor Evaluation Board") with a compiler toolchain based on OAR's :ref:`RTEMS ` 4.11 (including :ref:`GCC ` 4.9.3), -#. using DMON (2.0.11.13) to connect to the targets, -#. build as per build instructions in :ref:`Operations Environment` and :ref:`Operations Manual` as well as using the configuration and Makefile included in the release, -#. ``LIBMCS_DOUBLE_IS_32BITS`` is not defined, -#. the :ref:`FPU's ` rounding direction is set to *round to nearest with tie to even*. - -The general configuration status of the library can be found in the :ref:`SCF ` and the specific qualification evidences (for the above configuration) are in the :ref:`SUITR `, :ref:`SValR `, and :ref:`SVR `. All life-cycle documents apart from the specific qualification evidences are part of the qualification kit provided to the user. - -If this release is intended to be used in a different configuration then the one given above, then the qualification status needs to be reassessed in a :ref:`SRF ` and a delta-qualification carried out following the :ref:`QG ` OP-QG.00-ML. - -Compliance -^^^^^^^^^^ - -This software is compliant to :ref:`ISO ` C18 (ISO/IEC 9899:2018), :ref:`IEEE-754-2019 `, POSIX (IEEE Std 1003.1-2017), and MISRA C:2012. - -The use of some library macros will issue justifiable MISRA C non-compliances. These MISRA C non-compliances have been justified within the qualification of the LibmCS but in the case of macros, these non-compliances will be visible while compiling the software that is using the LibmCS. - -Compliance to :ref:`ISO ` TS 18661-1 is not yet met. - -Rounding Mode -^^^^^^^^^^^^^ - -The library is only qualified for the rounding mode *round to nearest, tie to even*. - -Platform Architecture -^^^^^^^^^^^^^^^^^^^^^ - -In case the :ref:`FPU ` of the target platform is not implementing all :ref:`IEEE-754 ` features, the :ref:`FPU ` has to be configured appropriately otherwise the library may trap on those missing features. One such example is the GRFPU as seen in :ref:`GeneralBehaviourSubnormalValues`. - -Errno -^^^^^ - -The library does not set the ``errno`` variable to report errors nor does the library read it, ``errno`` is completely ignored. - -Compiler -^^^^^^^^ - -In general the library is prepared to be used with a :ref:`GCC ` toolchain. It might be necessary to change parts of the library when using a different toolchain. -The compiler used on the library shall be able to understand the ``asm`` keyword. For example :ref:`GCC ` has the flag ``-std=gnu99`` to enable the :ref:`GNU ` C language extensions which contain ``asm``. - -Data Model -^^^^^^^^^^ - -The library is compatibility with the following data model processor and compiler tool-chains combinations: - -* ILP32 or 4/4/4 (``int`` and ``long int`` are 32 bit) -* LP64 or 4/8/8 (``int`` is 32 bit and ``long int`` is 64-bit) - -.. note:: - The ``long long int`` type shall always be 64 bits. - -Bessel functions -^^^^^^^^^^^^^^^^ - -The procedures :ref:`jn` and :ref:`yn` have only been qualified until an ``n`` value of 15. If you for some reason need to use them with higher values for ``n``, just change the value in the unit- and validation-tests. The other Bessel procedures (:ref:`j0`, :ref:`j1`, :ref:`y0`, and :ref:`y1`) however are fully qualified. - -Complex procedures -^^^^^^^^^^^^^^^^^^ - -The complex procedures have a lower number of requirements than the procedures defined in ``math.h`` and are less detailed. This mirrors what happens in the :ref:`ISO ` C and :ref:`POSIX ` standards where far less information and requirements are defined for these procedures. As such their requirements fall short of what one could usually expect for Cat. B software. However the fact that these procedures are seldom if ever used in flight and critical software justifies their subpar requirements, while their existence is justified by the need to be able to integrate the library with other :ref:`COTS ` software without restrictions (be aware that having them for integration purposes does not necessarily mean that they are used by other software components but that they expect them to exist). - -fenv.h -^^^^^^ - -The mathematical library contains the header file ``fenv.h``. It declares - but does not implement - the functionalities listed in this section. The ``fenv.h`` header does not contain type definitions nor macros. This header file is only provided as the starting point for the user of the library to implement their own ``fenv.h`` as it is highly hardware dependent. Inclusion of the ``fenv.h`` file in an unmodified version produces an error at compile time, which should be removed by the user after implementing their own procedures. The library also provides an implementation file ``fenv.c`` which contains stub implementations for all procedures in ``fenv.h`` which simply return :math:`-1` which is a valid return value for all procedures and denotes that an error has accrued while calling said procedure. User software will have to check for negative output values anyway as this is how the procedures are defined to give notice of errors. As such this is a reliable way to tell the user that an implementation of the procedures still needs to be provided. - -A custom ``fenv.h`` file needs to contain the type definition of ``fenv_t`` and ``fexcept_t`` provided by the user: - -* ``fenv_t`` represents the entire state of the floating-point environment including its status flags and control modes. -* ``fexcept_t`` represents the state of all floating-point status flags collectively, including the active floating-point exceptions along with additional information the implementation associates with their status. - -A custom ``fenv.h`` file needs to contain the following defines and constants: - -* Constants which need to contain the position of their respective exception flag in the given hardware environment in the form of a bitmask (and as such be easily combineable), their type is ``int`` and should be used by the functions ``feclearexcept``, ``feraiseexcept``, ``fegetexceptflag`` and ``fesetexceptflag``: - - * ``FE_DIVBYZERO`` - * ``FE_INEXACT`` - * ``FE_INVALID`` - * ``FE_OVERFLOW`` - * ``FE_UNDERFLOW`` - * ``FE_ALL_EXCEPT`` - -* Constants which need to represent the given rounding mode in the given hardware environment, their type is ``int`` and should be used by the functions ``fegetround`` and ``fesetround``: - - * ``FE_DOWNWARD`` - * ``FE_TONEAREST`` - * ``FE_TOWARDSZERO`` - * ``FE_UPWARD`` - -* Constant pointer to access the environment in the given hardware environment, the type is ``fenv_t*`` and should be used as input for the functions ``fesetenv`` and ``fegetenv``: - - * ``FE_DFL_ENV`` - -These are the expected procedures of a proper ``fenv.h`` implementation: - -* Floating-point Exceptions - - #. Clear floating-point exceptions - - * ``int feclearexcept(int excepts)`` - - #. Raise floating-point exceptions - - * ``int feraiseexcept(int excepts)`` - - #. Get floating-point exception flags - - * ``int fegetexceptflag(fexcept_t* flagp, int excepts)`` - - #. Set floating-point exception flags - - * ``int fesetexceptflag(const fexcept_t* flagp, int excepts)`` - -* Rounding Direction - - #. Get rounding direction mode - - * ``int fegetround(void)`` - - #. Set rounding direction mode - - * ``int fesetround(int rdir)`` - -* Entire Environment - - #. Get floating-point environment - - * ``int fegetenv(fenv_t* envp)`` - - #. Set floating-point environment - - * ``int fesetenv(const fenv_t* envp)`` - - #. Hold floating-point exceptions - - * ``int feholdexcept(fenv_t* envp)`` - - #. Update floating-point environment - - * ``int feupdateenv(const fenv_t* envp)`` - -* Other - - #. Test for floating-point exceptions - - * ``int fetestexcept(int excepts)`` - -A typical use of the floating-point environment for critical systems will anyways be a direct writing to the floating point registers once during initialization (e.g., setting the rounding mode) thus, avoiding the interface provided by ``fenv.h``. - -tgmath.h -^^^^^^^^ - -The mathematical library contains the header file ``tgmath.h`` which except for adding an error message upon compilation has not been changed from its ``Newlib`` state. ``tgmath.h`` procedures are not qualified. - -Inclusion of the ``tgmath.h`` file produces an intentional error at compile time. Contrary to the ``fenv.h`` header file we descourage any use of the ``tgmath.h`` header and suggest users to not create their own. Type generic function calls should never be used in critical software. - -Thread Safety and Reentrancy -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The library is thread safe and reentrant. For software that is using the library it has to be noted that usage of the ``signgam`` variable is not thread safe when executing the ``lgamma`` procedures on -multiple threads at once, as each procedure call operates on the same variable. This is a limitation forced on the library by the :ref:`POSIX ` standard that demands the availability of the ``signgam`` global variable. - -Other Header Files -^^^^^^^^^^^^^^^^^^ - -The library does not contain any externally available header files other than those that should be part of a ``libm`` according to the ISO C and :ref:`POSIX ` standards. It contains ``math.h``, ``complex.h``, ``fenv.h``, and ``tgmath.h``, although the limitations of the latter two have already been stated in this chapter. This means there will be no ``float.h`` or ``limits.h`` or any other header that does not belong into a ``libm``. All those headers need to be provided by the toolchain. - -Assert Usage -~~~~~~~~~~~~ - -The library contains an ``assert`` in its source code. More specifically assertions are used in the :ref:`frexp`, :ref:`modf` and :ref:`remquo` procedures to ensure that the library does not cause a trap when the procedures are called with a NULL-pointer. - -The implementation of the library assumes that the used toolchain contains an ``assert.h`` file with the standard implementation of ``assert``. That being the case, the ``assert`` can be disabled by defining ``NDEBUG`` either in source code or during compilation. The easiest way to do this would be using the ``make release`` command. - -It is of course possible to add your own definition of ``assert`` using a custom ``assert.h`` file. - -We suggest enabling the ``assert`` during production and disabling it after sufficient testing. This has the benefit that errors can be found more easily during production, and not having the assertion in the object code of the final product. - -Modular Arithmetic Procedures -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -As the modular arithmetic functions are often a source of confusion we want to use this section to show the differences between the modular arithmetic functions and give examples for each. This information is specific to the C programming language, and the C99 and :ref:`IEEE-754 ` standards. - -Modulus Operator: ``%`` -^^^^^^^^^^^^^^^^^^^^^^^ - -Although this operator is not part of the library but of the C language itself, we include it here to complete the overview of modular arithmetic. The ``%`` operator is specific to integers and shall only be used with integer types. The result of using the ``%`` operator is the remainder of using the ``/`` operator on the same operands. Given two variables ``a`` and ``b`` the following must be true: :math:`a \% b = a - (\frac{a}{b} \cdot b)` with integral truncation of :math:`\frac{a}{b}` towards zero. - -Examples: - -+-----------+------------+-------------+--------------+ -| 4 % 1 = 0 | 4 % -1 = 0 | -4 % 1 = 0 | -4 % -1 = 0 | -+-----------+------------+-------------+--------------+ -| 4 % 2 = 0 | 4 % -2 = 0 | -4 % 2 = 0 | -4 % -2 = 0 | -+-----------+------------+-------------+--------------+ -| 4 % 3 = 1 | 4 % -3 = 1 | -4 % 3 = -1 | -4 % -3 = -1 | -+-----------+------------+-------------+--------------+ -| 4 % 4 = 0 | 4 % -4 = 0 | -4 % 4 = 0 | -4 % -4 = 0 | -+-----------+------------+-------------+--------------+ -| 4 % 5 = 4 | 4 % -5 = 4 | -4 % 5 = -4 | -4 % -5 = -4 | -+-----------+------------+-------------+--------------+ -| 4 % 6 = 4 | 4 % -6 = 4 | -4 % 6 = -4 | -4 % -6 = -4 | -+-----------+------------+-------------+--------------+ - -The fmod procedure -^^^^^^^^^^^^^^^^^^ - -The :ref:`fmod` procedure returns the remainder of :math:`x` divided by :math:`y`. Given two variables :math:`x` and :math:`y` the following must be true: :math:`fmod(x, y) = x - n \cdot y`, for an integer :math:`n` such that the result has the same sign as :math:`x` and magnitude less than the magnitude of :math:`y`. If :math:`y` is zero the result will be ``qNaN``. - -Examples: - -+--------------+--------+---+---------------+--------+---+---------------+--------+---+----------------+--------+ -| Input (x, y) | Return | | Input (x, y) | Return | | Input (x, y) | Return | | Input (x, y) | Return | -+==============+========+===+===============+========+===+===============+========+===+================+========+ -| (3.14, 0.2) | 0.14 | | (3.14, -0.2) | 0.14 | | (-3.14, 0.2) | -0.14 | | (-3.14, -0.2) | -0.14 | -+--------------+--------+ +---------------+--------+ +---------------+--------+ +----------------+--------+ -| (3.14, 1.0) | 0.14 | | (3.14, -1.0) | 0.14 | | (-3.14, 1.0) | -0.14 | | (-3.14, -1.0) | -0.14 | -+--------------+--------+ +---------------+--------+ +---------------+--------+ +----------------+--------+ -| (3.14, 1.5) | 0.14 | | (3.14, -1.5) | 0.14 | | (-3.14, 1.5) | -0.14 | | (-3.14, -1.5) | -0.14 | -+--------------+--------+ +---------------+--------+ +---------------+--------+ +----------------+--------+ -| (3.14, 2.0) | 1.14 | | (3.14, -2.0) | 1.14 | | (-3.14, 2.0) | -1.14 | | (-3.14, -2.0) | -1.14 | -+--------------+--------+ +---------------+--------+ +---------------+--------+ +----------------+--------+ -| (3.14, 2.34) | 0.80 | | (3.14, -2.34) | 0.80 | | (-3.14, 2.34) | -0.80 | | (-3.14, -2.34) | -0.80 | -+--------------+--------+ +---------------+--------+ +---------------+--------+ +----------------+--------+ -| (3.14, 3.0) | 0.14 | | (3.14, -3.0) | 0.14 | | (-3.14, 3.0) | -0.14 | | (-3.14, -3.0) | -0.14 | -+--------------+--------+ +---------------+--------+ +---------------+--------+ +----------------+--------+ -| (3.14, 3.7) | 3.14 | | (3.14, -3.7) | 3.14 | | (-3.14, 3.7) | -3.14 | | (-3.14, -3.7) | -3.14 | -+--------------+--------+ +---------------+--------+ +---------------+--------+ +----------------+--------+ -| (3.14, 4.0) | 3.14 | | (3.14, -4.0) | 3.14 | | (-3.14, 4.0) | -3.14 | | (-3.14, -4.0) | -3.14 | -+--------------+--------+---+---------------+--------+---+---------------+--------+---+----------------+--------+ - -The remainder and remquo procedures -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The :ref:`remainder` and :ref:`remquo` procedures returns the remainder of :math:`x` divided by :math:`y`. Given two variables :math:`x` and :math:`y` the following must be true: :math:`remainder(x, y) = x - n \cdot y`, where :math:`n` is the integer nearest to the exact result of :math:`\frac{x}{y}` (when the exact result is exactly in the middle of two integers, :math:`n` is even). If :math:`y` is zero the result will be ``qNaN``. - -Examples: - -+--------------+--------+---+---------------+--------+---+---------------+--------+---+----------------+--------+ -| Input (x, y) | Return | | Input (x, y) | Return | | Input (x, y) | Return | | Input (x, y) | Return | -+==============+========+===+===============+========+===+===============+========+===+================+========+ -| (3.14, 0.2) | -0.06 | | (3.14, -0.2) | -0.06 | | (-3.14, 0.2) | -0.06 | | (-3.14, -0.2) | -0.06 | -+--------------+--------+ +---------------+--------+ +---------------+--------+ +----------------+--------+ -| (3.14, 1.0) | 0.14 | | (3.14, -1.0) | 0.14 | | (-3.14, 1.0) | 0.14 | | (-3.14, -1.0) | 0.14 | -+--------------+--------+ +---------------+--------+ +---------------+--------+ +----------------+--------+ -| (3.14, 1.5) | 0.14 | | (3.14, -1.5) | 0.14 | | (-3.14, 1.5) | 0.14 | | (-3.14, -1.5) | 0.14 | -+--------------+--------+ +---------------+--------+ +---------------+--------+ +----------------+--------+ -| (3.14, 2.0) | -0.86 | | (3.14, -2.0) | -0.86 | | (-3.14, 2.0) | -0.86 | | (-3.14, -2.0) | -0.86 | -+--------------+--------+ +---------------+--------+ +---------------+--------+ +----------------+--------+ -| (3.14, 2.34) | 0.80 | | (3.14, -2.34) | 0.80 | | (-3.14, 2.34) | -0.80 | | (-3.14, -2.34) | -0.80 | -+--------------+--------+ +---------------+--------+ +---------------+--------+ +----------------+--------+ -| (3.14, 3.0) | 0.14 | | (3.14, -3.0) | 0.14 | | (-3.14, 3.0) | 0.14 | | (-3.14, -3.0) | 0.14 | -+--------------+--------+ +---------------+--------+ +---------------+--------+ +----------------+--------+ -| (3.14, 3.7) | -0.56 | | (3.14, -3.7) | -0.56 | | (-3.14, 3.7) | -0.56 | | (-3.14, -3.7) | -0.56 | -+--------------+--------+ +---------------+--------+ +---------------+--------+ +----------------+--------+ -| (3.14, 4.0) | -0.86 | | (3.14, -4.0) | -0.86 | | (-3.14, 4.0) | -0.86 | | (-3.14, -4.0) | -0.86 | -+--------------+--------+---+---------------+--------+---+---------------+--------+---+----------------+--------+ - -The modf procedure -^^^^^^^^^^^^^^^^^^ - -The :ref:`modf` procedure returns the fractional part of :math:`x` and puts the integral part of :math:`x` to the outward pointer :math:`iptr`. It's easier to think of :ref:`modf` as a procedure with one input and two outputs. - -Examples: - -+---------+--------+-------------+---+---------+--------+-------------+ -| Input x | Return | Output iptr | | Input x | Return | Output iptr | -+=========+========+=============+===+=========+========+=============+ -| 0.14 | 0.14 | 0.0 | | -0.14 | -0.14 | -0.0 | -+---------+--------+-------------+ +---------+--------+-------------+ -| 3.0 | 0.0 | 3.0 | | -3.0 | -0.0 | -3.0 | -+---------+--------+-------------+ +---------+--------+-------------+ -| 3.14 | 0.14 | 3.0 | | -3.14 | -0.14 | -3.0 | -+---------+--------+-------------+---+---------+--------+-------------+ - -Side Effects -~~~~~~~~~~~~ - -This library does not produce any side effects, apart from the exceptions that have been described, - -* to the software that uses the library, -* nor to the hardware, - -as it does not configure any hardware. diff --git a/libm/libmcs/doc/sum/5_External_View_of_the_Software.rst b/libm/libmcs/doc/sum/5_External_View_of_the_Software.rst deleted file mode 100644 index 366563df..00000000 --- a/libm/libmcs/doc/sum/5_External_View_of_the_Software.rst +++ /dev/null @@ -1,177 +0,0 @@ -External View of the Software -============================= - -The library is delivered as an archive consisting of the source files, licenses, a Makefile, a configuration script, and everything to create documentation. - -The following is a depiction of the directory structure: - - libmcs/ - doc/ - _static/css/custom.css - CSS file to be used by the HTML documentation. - figure/ - Directory to contain figures used by one or multiple generated documents. - sdd/ - conf.py - Configuration file for the Sphinx documentation builder. - index.rst - Index file for the document. This is the starting point for document generation, all - other files should be referenced directly or indirectly by this one. - other files - Other reStructuredText files for the document. Usually each chapter either has its - own directory or at least its own file. - sum/ - conf.py - Configuration file for the Sphinx documentation builder. - index.rst - Index file for the document. This is the starting point for document generation, all - other files should be referenced directly or indirectly by this one. - other files - Other reStructuredText files for the document. Usually each chapter has its own - file. You're currently reading one of them. - libm/ - common/ - fenv.c - Implementation file for ``fenv.h`` which contains only stub implementations that - return an error value. - signgam.c - This file only provides the ``signgam`` global variable used by the :ref:`lgamma` - procedures. - tool.[c|h] - Header file that provides several library internal convenience procedures to be used - by many library procedures. - other files - Other ``.c`` files which have no content other than comments to describe procedures - (mostly macros) that are implemented in ``math.h`` or ``complex.h``. - complexd/ - internal/ - Internal ``.c`` files only used by procedures in the directory above. - - Contains all ``.c`` files for double precision complex procedures. - complexf/ - internal/ - Internal ``.c`` files only used by procedures in the directory above. - - Contains all ``.c`` files for single precision complex procedures. - complexfe/ - internal/ - .gitkeep - Placeholder file that only exists so that git does not remove the otherwise empty - directory. - - Placeholder directory which shall contain all ``.c`` files for single precision complex - procedures which have been implemented using double precision. - complexl/ - internal/ - .gitkeep - Placeholder file that only exists so that git does not remove the otherwise empty - directory. - - Placeholder directory which shall contain all ``.c`` files for long double precision - complex procedures which do not have the same size as double. - include/ - config.h - Header file that contains the configuration of the library, as chosen during the - configuration step. This file gets generated by running ``configure``. - complex.h - Header file which needs to be included when building the user project and complex - procedures are needed. - fenv.h - Header file which should not be included as is. The procedures have no functionality - other than returning an error value and providing prototypes. If the user wants to - use ``fenv`` s/he will have to implement the features her/himself (or copy them from - somewhere). We cannot provide these functionalities for the user as their - implementation is highly platform dependant. - internal_config.h - Header file that converts the choices the user has made during configuration into - defines used by the library. - math.h - Header file which needs to be included when building the user project. - tgmath.h - Header file which should never be included. - machine/ - .gitkeep - Placeholder file that only exists so that git does not remove the otherwise empty - directory. - - Placeholder directory which shall contain sub-directories for each architecture that - needs a hardware specific implementation of a procedure. Those files are only compiled - if the appropriate changes are made to the Makefile. Example structure if the user - were to add a procedure to directly call a hardware square root instruction on a SPARC - V8 platform: - - sparc_v8/ - mathd/ - sqrtd.c - mathf/ - sqrtf.c - mathd/ - internal/ - Internal ``.c`` files only used by procedures in the directory above. - - Contains all ``.c`` files for double precision procedures. - mathf/ - internal/ - Internal ``.c`` files only used by procedures in the directory above. - - Contains all ``.c`` files for single precision procedures. - mathfe/ - internal/ - .gitkeep - Placeholder file that only exists so that git does not remove the otherwise empty - directory. - - Placeholder directory which shall contain all ``.c`` files for single precision - procedures which have been implemented using double precision. - mathl/ - internal/ - .gitkeep - Placeholder file that only exists so that git does not remove the otherwise empty - directory. - - Placeholder directory which shall contain all ``.c`` files for long double precision - procedures which do not have the same size as double. - LICENSES/ - Contains license files which are referenced by the :ref:`SPDX ` headers in the other - implementation files. - sw-quality/ - Contains the configuration and scripts to run pc-lint. - .gitignore - Typical gitignore file. - .gitlab-ci.yml - Continuous integration file for usage with Gitlab. Automatically runs documentation - generation. - configure - Configuration script that has to be run by the user before running ``make``. - COPYING.md - License file which lists all other licenses and states the overall license of the library. - Dockerfile - Dockerfile used for continuous integration. - Makefile - Build the library. - README.md - Typical readme file. - requirements.in - Contains the python package requirements used for document generation, it's fed into - ``pip-compile`` to create the ``requirements.txt`` file. - requirements.txt - Contains the python package requirements used for document generation. Autogenerated from - ``requirements.in`` and used by the Dockerfile. - -After using the included Makefile the directory structure will be extended with build specific directories: - - libmcs/ - build-ARCH/ - bin/ - libm.a - This is the final static library, the product and heart of the library. - obj/ - Contains the intermediate object files which were created by the Makefile to produce - the static library. - build-info.yml - Contains information on the built library, such as its build date, toolchain used, - compilation flags used, and git commit used. - [...] - Each architecture has its own build directory. - -How to use the Makefile is depicted in :ref:`Operations Manual` diff --git a/libm/libmcs/doc/sum/6_Operations_Environment.rst b/libm/libmcs/doc/sum/6_Operations_Environment.rst deleted file mode 100644 index b36fad6a..00000000 --- a/libm/libmcs/doc/sum/6_Operations_Environment.rst +++ /dev/null @@ -1,77 +0,0 @@ -Operations Environment -====================== - -General -~~~~~~~ - -The software in this project is designed to be included in other software. - -Other than a compiler no additional software is necessary to build, or access the library's procedures. - -The hardware parts used by the library are the :ref:`CPU `, :ref:`FPU ` and :ref:`RAM `. - -The following sections describe additional constraints which have to be considered when using the library on specific hardware platforms. - -.. _OperationsEnviromentHardwareConfiguration: - -Hardware Configuration -~~~~~~~~~~~~~~~~~~~~~~ - -The software described here contains several mathematical procedures which execute floating point operations. For this to be possible the target platform's configuration needs to be modified, in particular the :ref:`FPU `: - -#. Enable the :ref:`FPU ` before executing any floating-point procedure. -#. Configure the :ref:`FPU ` regarding subnormal numbers and other trap causing situations. See also :ref:`GeneralBehaviourSubnormalValues`. - -As these are platform dependent actions, their procedures cannot reasonably be described here for every platform and have to be researched in the corresponding hardware manuals. - -.. _OperationsEnviromentSoftwareConfiguration: - -Software Configuration -~~~~~~~~~~~~~~~~~~~~~~ - -The software configuration is confined to the configuration script and the compile switches. At runtime, there is no option to configure the library itself. - -To include the library in other software projects while guaranteeing :ref:`IEEE-754 ` standard compliance, the following compilation flags should be enabled when building the project when using :ref:`GCC `: - -* ``-frounding-math`` -* ``-fsignaling-nans`` -* ``-fno-builtin`` - -We advise using the following flag combination to include exclusively those procedures into the final executable that are actually used within your software: - -* ``-ffunction-sections -fdata-sections`` - -For this to work you also have to add the linker option ``-gc-sections`` while building your project. - -On the other hand the following compilation flags shall not be used, since they can produce code which is not compliant to the :ref:`IEEE-754 ` standard: - -* ``-O3`` -* ``-ffast-math``, it activates ``-funsafe-math-optimizations``, ``-fno-rounding-math``, ``-ffinite-math-only``, ``-fno-signaling-nans``, and ``-fcx-limited-range`` - -Depending on the processor and :ref:`FPU ` you are using consider adding architecture specific flags, for example those listed in `SPARC Options `_ (especially those starting with ``-mfix``). - -Additionally we have tested the following compilation flags which caused no problems to the behaviour of the library (tested with the :ref:`RTEMS ` 4.8 toolchain provided by EDISOFT): - -* ``-O2`` -* ``-mhard-float`` [#]_ -* ``-mcpu=v8`` -* ``-fno-zero-initialized-in-bss`` -* ``-fno-inline-functions-called-once`` - -In case the used architecture and toolchain support :ref:`FMA ` instructions we advise using the flag ``-mno-fused-madd`` as the library was not tested for compatibility with said instruction. - -Remember to also add flags that alter the sizes of different types such as ``long double`` or ``long int`` to those appropriate for your hardware, for example ``-mlong-double-64`` can be set for x86 targets that typically use 80-bit ``long double``. These flags are different depending on the toolchain and should be in line with the rest of your software. - -.. _OperationsEnviromentUsingHardwareInstructions: - -Using Hardware Instructions -~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -To replace LibmCS procedures with custom procedures, such as hardware instruction calling procedures, several steps need to be followed: - -* Add the file containing the procedure into an architecture specific sub-directory within the ``libm/machine`` directory. If the directory does not exist, make one for your architecture. An example for this step has already been added to the library for the SPARC V8 architecture. -* Replace the file you want to replace in the ``Makefile.in``. As an example for this step we have added a patch for the library where this is done for the SPARC V8 ``sqrt`` procedure. - -Note that replacing procedures may cause different results and in turn may cause unit tests to fail. You will have to justify those fails, or change the respective tests and justify that change. - -.. [#] The flag ``-mhard-float`` is the default behaviour for SPARC compilations with :ref:`GCC `. diff --git a/libm/libmcs/doc/sum/7_Operations_Manual.rst b/libm/libmcs/doc/sum/7_Operations_Manual.rst deleted file mode 100644 index 9b137cef..00000000 --- a/libm/libmcs/doc/sum/7_Operations_Manual.rst +++ /dev/null @@ -1,95 +0,0 @@ -Operations Manual -================= - -Set-up and Initialization -~~~~~~~~~~~~~~~~~~~~~~~~~ - -In short: - -* call ``configure`` -* call ``make`` - -The first step to include the mathematical library into another software project is to build the static library from the library source code. For this procedure, a configuration script and a Makefile are prepared. - -First the user has to run the configuration script which will interactively ask for several configuration items. To reduce the number of questions asked interactively the ``configure`` script can be called with flags. During configuration you will be asked ... - -* ... for the path to the compilation toolchain. (Flag: ``--cross-compile ``) -* ... for additional compilation flags. (Flag: ``--compilation-flags ``) -* ... whether the platform does not support subnormals and as such uses a non-standard :ref:`FTZ/DAZ ` mode. (Flag: ``--enable-denormal-handling`` or ``--disable-denormal-handling``) -* ... whether you want ``long double`` procedures (this will only be asked if the toolchain informs the configuration script that ``long double`` are 64 bit in size). (Flag: ``--enable-long-double-procedures`` or ``--disable-long-double-procedures``) -* ... for your platforms endianess (this will only be asked if the toolchain does not provide the answer). (Flag: ``--big-endian`` or ``--little-endian``) -* ... whether you want complex procedures. (Flag: ``--enable-complex-procedures`` or ``--disable-complex-procedures``) - -The configuration creates a secondary Makefile ``user_make.mk``, which will then be used by the primary Makefile. As such it should not be moved elsewhere (if it is not where it should be the primary Makefile will assume ``configure`` has not been executed and display an error). It contains flags and variables based on the choices made during ``configure`` as well as an additional variable which tells the primary Makefile that the configuration was properly finished. - -The Makefile provides the following targets: - -* ``all``: Compiles and builds the library. -* ``debug``: Compiles and builds the library. Same as ``all``. -* ``release``: Compiles and builds the library. Add the compilation flag ``-DNDEBUG``, afterwards runs ``all``. -* ``clean``: Removes the object files and the static library of the chosen build. -* ``cleanall``: Removes the object files and static libraries from all builds. -* ``distclean``: Removes files generated by the configuration script. -* ``install``: The library does not need to be installed. As such running ``install`` only yields an information message. - -The targets ``all``, ``debug``, ``release``, and ``clean`` can be modified using the following constants: - -* ``CROSS_COMPILE``: Prefix to tell the Makefile which compiler to use. This is usually already set during configuration. -* ``ARCH``: Tells the Makefile for which architecture the build is intended. If not provided this defaults to a target stated by the :ref:`GCC ` provided via ``CROSS_COMPILE``. -* ``COVERAGE=true``: Tells the Makefile to use flags specific to the generation of coverage reports. - -.. note:: - The library has been built to compile without warnings but the compilation process might show some warnings about the use of potentially - uninitialized variables depending on the compiler version (and or specific compiler flags). These warnings can be - disregarded as all variable uses have been statically analyzed and shown to be correct - in all cases. - -The resulting libraries can be found in the ``build-ARCH/bin`` directory, with ``ARCH`` being the provided constant, or if not provided defaults to the target defined by :ref:`GCC ` (this can be inspected with the shell command ``gcc -v``). The intermediate object files can be found in the ``build-ARCH/obj`` directory. - -After finishing the build `make` will also create a build info file within the ``build-ARCH`` directory. This file is aptly named ``build_info.yml`` and contains the following information in :ref:`YAML ` format: - -* timestamp on when the build was made, -* path to the compiler, information provided by the compiler (such as version), compilation flags, includes, -* git information: branch name, commit hash, check if the commit is clean or if changes were made (dirty), -* sha256 of the generated libm.a - -Both of the files ``build_info.yml`` and ``user_make.mk`` provide information to MAXI while creating the final reports, as such they need to stay at the path they were generated at. The same applies to the ``libm.a`` itself. - -Getting Started -~~~~~~~~~~~~~~~ - -In the last section, the code of the mathematical library is prepared in a static library. To use the library, the library header files have to be included in the user's source code. The useable header files are ``math.h``, and ``complex.h``. The complex procedures however will only exist if they were chosen to during configuration. - -Mode Selection and Control -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -After writing the project specific code, the last step to build a program which includes the library is to compile the new software. During the compilation two steps are necessary for success: - -#. Link to the static library (``libm.a``). -#. Include the header files located in ``libm/include`` - -As an example by using :ref:`GCC ` the following line should work:: - - $ gcc -o new_executable_software new_software_source_code.c libmcs/build-x86_64-linux-gnu/bin/libm.a -Ilibmcs/libm/include - -The user has to add a number of additional flags, beginning with those listed in :ref:`OperationsEnviromentSoftwareConfiguration`. One might also need a number of platform or hardware specific flags, e.g. the flag ``-qleon2`` when building for the Leon2 platform with Gaisler's :ref:`RTEMS `. Extra flags depend on the :ref:`OS `, the compilation toolchain, and possibly a :ref:`BSP `; please check the corresponding documentation for your situation. It is suggested to write a Makefile for this (or use tools for the creation of Makefiles). - -Normal Operations -~~~~~~~~~~~~~~~~~ - -All accessible procedures within the library are shown in chapter :ref:`Purpose of the Software`. For detailed information on each procedure, take a look at the related subsection in :ref:`Reference Manual`. - -Normal Termination -~~~~~~~~~~~~~~~~~~ - -Each procedure in the library is executed when called and computes a result. There is no software interruption foreseen during the computation and the procedure terminates by returning the result. If there is an interrupt, e.g. a context switch caused by the underlying operating system, the correct re-schedule has to be managed by the causing operating system. - -.. _OperationsManualErrorConditions: - -Error Conditions -~~~~~~~~~~~~~~~~ - -There is no error condition handling in the library. The ``errno`` variable proposed by the :ref:`ISO ` C standard is not set by the library. Error states may only be caused by the used hardware and must be handled by the user's software. For example the following errors may occur: - -* Any :ref:`FPU ` can produce traps depending on its configuration. See :ref:`OperationsEnviromentHardwareConfiguration` for more information. -* The program stack can overflow if the stack size limit is exceeded by calling one of the provided procedures, even though their memory footprint is rather low. diff --git a/libm/libmcs/doc/sum/8_Reference_Manual.rst b/libm/libmcs/doc/sum/8_Reference_Manual.rst deleted file mode 100644 index 5c1efa59..00000000 --- a/libm/libmcs/doc/sum/8_Reference_Manual.rst +++ /dev/null @@ -1,556 +0,0 @@ -Reference Manual -================ - -This chapter provides the detailed documentation of all the procedures (C functions and macros) listed in chapter :ref:`Purpose of the Software`. - -Each procedure is described in a separate subsection with the style similar to the documentation of the procedures in the ISO C and POSIX standards. Each subsection starts with a synopsis specifying the -procedure’s signature, followed by a short description of the evaluated mathematical function and its return value. Further the raised exceptions are noted. - -Classification Macros -""""""""""""""""""""" - -fpclassify -~~~~~~~~~~ - -.. c:autodoc:: mathd/internal/fpclassifyd.c - -isfinite -~~~~~~~~ - -.. c:autodoc:: common/isfinite.c - -isinf -~~~~~ - -.. c:autodoc:: common/isinf.c - -isnan -~~~~~ - -.. c:autodoc:: common/isnan.c - -isnormal -~~~~~~~~ - -.. c:autodoc:: common/isnormal.c - -signbit -~~~~~~~ - -.. c:autodoc:: mathd/internal/signbitd.c - -Trigonometric Functions -""""""""""""""""""""""" - -acos -~~~~ - -.. c:autodoc:: mathd/acosd.c - -asin -~~~~ - -.. c:autodoc:: mathd/asind.c - -atan -~~~~ - -.. c:autodoc:: mathd/atand.c - -atan2 -~~~~~ - -.. c:autodoc:: mathd/atan2d.c - -cos -~~~ - -.. c:autodoc:: mathd/cosd.c - -sin -~~~ - -.. c:autodoc:: mathd/sind.c - -tan -~~~ - -.. c:autodoc:: mathd/tand.c - -Hyperbolic Functions -"""""""""""""""""""" - -acosh -~~~~~ - -.. c:autodoc:: mathd/acoshd.c - -asinh -~~~~~ - -.. c:autodoc:: mathd/asinhd.c - -atanh -~~~~~ - -.. c:autodoc:: mathd/atanhd.c - -cosh -~~~~ - -.. c:autodoc:: mathd/coshd.c - -sinh -~~~~ - -.. c:autodoc:: mathd/sinhd.c - -tanh -~~~~ - -.. c:autodoc:: mathd/tanhd.c - -Exponential and Logarithmic Functions -""""""""""""""""""""""""""""""""""""" - -exp -~~~ - -.. c:autodoc:: mathd/expd.c - -exp2 -~~~~ - -.. c:autodoc:: mathd/exp2d.c - -expm1 -~~~~~ - -.. c:autodoc:: mathd/expm1d.c - -frexp -~~~~~ - -.. c:autodoc:: mathd/frexpd.c - -ilogb -~~~~~ - -.. c:autodoc:: mathd/ilogbd.c - -ldexp -~~~~~ - -.. c:autodoc:: mathd/ldexpd.c - -log -~~~ - -.. c:autodoc:: mathd/logd.c - -log10 -~~~~~ - -.. c:autodoc:: mathd/log10d.c - -log1p -~~~~~ - -.. c:autodoc:: mathd/log1pd.c - -log2 -~~~~ - -.. c:autodoc:: mathd/log2d.c - -logb -~~~~ - -.. c:autodoc:: mathd/logbd.c - -modf -~~~~ - -.. c:autodoc:: mathd/modfd.c - -scalbn -~~~~~~ - -.. c:autodoc:: mathd/scalbnd.c - -scalbln -~~~~~~~ - -.. c:autodoc:: mathd/scalblnd.c - -Power and Absolute-value Functions -"""""""""""""""""""""""""""""""""" - -cbrt -~~~~ - -.. c:autodoc:: mathd/cbrtd.c - -fabs -~~~~ - -.. c:autodoc:: mathd/fabsd.c - -hypot -~~~~~ - -.. c:autodoc:: mathd/hypotd.c - -pow -~~~ - -.. c:autodoc:: mathd/powd.c - -sqrt -~~~~ - -.. c:autodoc:: mathd/sqrtd.c - -Error and Gamma Functions -""""""""""""""""""""""""" - -erf -~~~ - -.. c:autodoc:: mathd/erfd.c - -erfc -~~~~ - -.. c:autodoc:: mathd/erfcd.c - -lgamma -~~~~~~ - -.. c:autodoc:: mathd/lgammad.c - -tgamma -~~~~~~ - -.. c:autodoc:: mathd/tgammad.c - -signgam -~~~~~~~ - -.. c:autodoc:: common/signgam.c - -Nearest Integer Functions -""""""""""""""""""""""""" - -ceil -~~~~ - -.. c:autodoc:: mathd/ceild.c - -floor -~~~~~ - -.. c:autodoc:: mathd/floord.c - -nearbyint -~~~~~~~~~ - -.. c:autodoc:: mathd/nearbyintd.c - -rint -~~~~ - -.. c:autodoc:: mathd/rintd.c - -lrint -~~~~~ - -.. c:autodoc:: mathd/lrintd.c - -llrint -~~~~~~ - -.. c:autodoc:: mathd/llrintd.c - -round -~~~~~ - -.. c:autodoc:: mathd/roundd.c - -lround -~~~~~~ - -.. c:autodoc:: mathd/lroundd.c - -llround -~~~~~~~ - -.. c:autodoc:: mathd/llroundd.c - -trunc -~~~~~ - -.. c:autodoc:: mathd/truncd.c - -Remainder Functions -""""""""""""""""""" - -fmod -~~~~ - -.. c:autodoc:: mathd/fmodd.c - -remainder -~~~~~~~~~ - -.. c:autodoc:: mathd/remainderd.c - -remquo -~~~~~~ - -.. c:autodoc:: mathd/remquod.c - -Manipulation Functions -"""""""""""""""""""""" - -copysign -~~~~~~~~ - -.. c:autodoc:: mathd/copysignd.c - -nan -~~~ - -.. c:autodoc:: mathd/nand.c - -nextafter -~~~~~~~~~ - -.. c:autodoc:: mathd/nextafterd.c - -nexttoward -~~~~~~~~~~ - -.. c:autodoc:: mathd/nexttowardd.c - -Maximum, Minimum and Positive Difference Functions -"""""""""""""""""""""""""""""""""""""""""""""""""" - -fdim -~~~~ - -.. c:autodoc:: mathd/fdimd.c - -fmax -~~~~ - -.. c:autodoc:: mathd/fmaxd.c - -fmin -~~~~ - -.. c:autodoc:: mathd/fmind.c - -Floating Multiply-Add -""""""""""""""""""""" - -fma -~~~ - -.. c:autodoc:: mathd/fmad.c - -Comparison Macros -""""""""""""""""" - -isgreater -~~~~~~~~~ - -.. c:autodoc:: common/isgreater.c - -isgreaterequal -~~~~~~~~~~~~~~ - -.. c:autodoc:: common/isgreaterequal.c - -isless -~~~~~~ - -.. c:autodoc:: common/isless.c - -islessequal -~~~~~~~~~~~ - -.. c:autodoc:: common/islessequal.c - -islessgreater -~~~~~~~~~~~~~ - -.. c:autodoc:: common/islessgreater.c - -isunordered -~~~~~~~~~~~ - -.. c:autodoc:: common/isunordered.c - -Bessel Functions (POSIX) -"""""""""""""""""""""""" - -j0 -~~ - -.. c:autodoc:: mathd/j0d.c - -j1 -~~ - -.. c:autodoc:: mathd/j1d.c - -jn -~~ - -.. c:autodoc:: mathd/jnd.c - -y0 -~~ - -.. c:autodoc:: mathd/y0d.c - -y1 -~~ - -.. c:autodoc:: mathd/y1d.c - -yn -~~ - -.. c:autodoc:: mathd/ynd.c - -Complex Trigonometric Functions -""""""""""""""""""""""""""""""" - -cacos -~~~~~ - -.. c:autodoc:: complexd/cacosd.c - -casin -~~~~~ - -.. c:autodoc:: complexd/casind.c - -catan -~~~~~ - -.. c:autodoc:: complexd/catand.c - -ccos -~~~~ - -.. c:autodoc:: complexd/ccosd.c - -csin -~~~~ - -.. c:autodoc:: complexd/csind.c - -ctan -~~~~ - -.. c:autodoc:: complexd/ctand.c - -Complex Hyperbolic Functions -"""""""""""""""""""""""""""" - -cacosh -~~~~~~ - -.. c:autodoc:: complexd/cacoshd.c - -casinh -~~~~~~ - -.. c:autodoc:: complexd/casinhd.c - -catanh -~~~~~~ - -.. c:autodoc:: complexd/catanhd.c - -ccosh -~~~~~ - -.. c:autodoc:: complexd/ccoshd.c - -csinh -~~~~~ - -.. c:autodoc:: complexd/csinhd.c - -ctanh -~~~~~ - -.. c:autodoc:: complexd/ctanhd.c - -Complex Exponential and Logarithmic Functions -""""""""""""""""""""""""""""""""""""""""""""" - -cexp -~~~~ - -.. c:autodoc:: complexd/cexpd.c - -clog -~~~~ - -.. c:autodoc:: complexd/clogd.c - -Complex Power and Absolute-value Functions -"""""""""""""""""""""""""""""""""""""""""" - -cabs -~~~~ - -.. c:autodoc:: complexd/cabsd.c - -cpow -~~~~ - -.. c:autodoc:: complexd/cpowd.c - -csqrt -~~~~~ - -.. c:autodoc:: complexd/csqrtd.c - -Complex Manipulation Functions -"""""""""""""""""""""""""""""" - -carg -~~~~ - -.. c:autodoc:: complexd/cargd.c - -cimag -~~~~~ - -.. c:autodoc:: complexd/cimagd.c - -CMPLX -~~~~~ - -.. c:autodoc:: common/cmplx.c - -conj -~~~~ - -.. c:autodoc:: complexd/conjd.c - -cproj -~~~~~ - -.. c:autodoc:: complexd/cprojd.c - -creal -~~~~~ - -.. c:autodoc:: complexd/creald.c diff --git a/libm/libmcs/doc/sum/9_Tutorial.rst b/libm/libmcs/doc/sum/9_Tutorial.rst deleted file mode 100644 index 5817b9ad..00000000 --- a/libm/libmcs/doc/sum/9_Tutorial.rst +++ /dev/null @@ -1,265 +0,0 @@ -Tutorial -======== - -This tutorial presents how to implement the library into user software, how to use the provided procedures, how to build it, and the execution's output. - -The examples use an :ref:`RTEMS ` :ref:`OS ` (version 4.10, it includes :ref:`GCC ` 4.4.6) provided by Cobham Gaisler including their :ref:`BSP `. - -The user's experience will vary (possibly heavily) when using different hardware and/or :ref:`OS `. - -It is assumed, that the library was built as shown in the :ref:`Operations Manual`. - -Example 1: LEON2 with Meiko FPU -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The first example is done for a LEON2 platform with a Meiko :ref:`FPU `. This :ref:`FPU ` is perfectly able to work with subnormal numbers and does not throw any traps when executed with those. - -Getting Started -^^^^^^^^^^^^^^^ - -The first important step is to include the library part we want to use: - -.. code-block:: c - - #include "math.h" - -The second step is to start the :ref:`FPU `. This step is :ref:`FPU ` and :ref:`BSP ` specific and simply enables the :ref:`FPU ` in the :ref:`PSR `: - -.. code-block:: c - - uint32_t psr; - sparc_get_psr(psr); - psr |= SPARC_PSR_EF_MASK; - sparc_set_psr(psr); - -The Meiko :ref:`FPU ` has an :ref:`ISO ` C18 standard conform handling of subnormal numbers, and the non-standard bit in the :ref:`FSR ` cannot be set. - -The final step is an actual call to some library procedures: - -.. code-block:: c - - double input = M_PI_4; - double result = sin(input); - - float inputX = 3.5f; - float inputY = 1.2f; - float resultf = fmodf(inputX, inputY); - -Using all those snipets we can create a small test program. Sadly :ref:`RTEMS ` and the :ref:`BSP ` need some more configuring, but as the program would not run without them, we're going to show that as well. We've also added some ``printf`` to actually get a visible output (which one can only see if some type of console output is possible...): - -.. code-block:: c - - #include - - #include - - #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER - #define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER - - #define CONFIGURE_RTEMS_INIT_TASKS_TABLE - #define CONFIGURE_MAXIMUM_TASKS 1 - - #define CONFIGURE_INIT - #include - - #include - #include - - #include "math.h" - - void test() - { - double dbuf, ret; - - double d1 = 0.5, d2 = -2.0; - float f1 = 0.5f, f2 = -2.0f; - - printf("sin(%lf) = %lf\n", d1, sin(d1)); - printf("atan2(%lf, %lf) = %lf\n", d1, d2, atan2(d1, d2)); - ret = modf(d1, &dbuf); - printf("modf(%lf, %lf) = %lf\n", d1, dbuf, ret); - printf("isfinite(%lf) = %d\n", d1, isfinite(d1)); - - printf("cosf(%f) = %f\n", f1, cosf(f1)); - printf("powf(%f, %f) = %f\n", f1, f2, powf(f1, f2)); - printf("fmodf(%f, %f) = %f\n", f1, f2, fmodf(f1, f2)); - printf("signbit(%f) = %d\n", f1, signbit(f1)); - } - - void ConfigurationMultiprocessingEnableFpu() - { - uint32_t psr; - sparc_get_psr(psr); - psr |= SPARC_PSR_EF_MASK; - sparc_set_psr(psr); - } - - rtems_task Init(rtems_task_argument arg) - { - ConfigurationMultiprocessingEnableFpu(); - - test(); - exit(0); - } - -Using the Software on a Typical Task -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Let's build the software using a shell command:: - - $ sparc-rtems-gcc test test_rtems.c libmcs/build-sparc_v8/bin/libm.a -Ilibmcs/libm/include -qleon2 -frounding-math -fsignaling-nans -fno-builtin - -As one can see the command builds with the library, includes the header files, uses the LEON2 specific flag ``-qleon2``, and uses the flags provided in :ref:`OperationsEnviromentSoftwareConfiguration`, before finally producing the ``test`` executable. - -After running this program on the LEON2 platform it produces the following output on the console: - -.. code-block:: none - - sin(0.500000) = 0.479426 - atan2(0.500000, -2.000000) = 2.896614 - modf(0.500000, 0.000000) = 0.500000 - isfinite(0.500000) = 1 - - cosf(0.500000) = 0.877583 - powf(0.500000, -2.000000) = 4.000000 - fmodf(0.500000, -2.000000) = 0.500000 - signbit(0.500000) = 0 - -Example 2: LEON4 with GRFPU -~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The second example is done for a LEON4 platform with a GRFPU. This :ref:`FPU ` has to be configured to prevent traps on subnormal numbers as described in :ref:`OperationsManualErrorConditions`. - -Getting Started -^^^^^^^^^^^^^^^ - -The first important step is to include the library: - -.. code-block:: c - - #include "math.h" - -The second step is to start the :ref:`FPU `. This step is :ref:`FPU ` and :ref:`BSP ` specific and simply enables the :ref:`FPU ` in the :ref:`PSR `: - -.. code-block:: c - - uint32_t psr; - sparc_get_psr(psr); - psr |= SPARC_PSR_EF_MASK; - sparc_set_psr(psr); - -The third step is to set the :ref:`FPU ` to non-standard mode (if wanted). This step is :ref:`FPU ` and :ref:`BSP ` specific and sets the appropriate bit in the :ref:`FSR `. The :ref:`BSP ` did not provide direct access to the :ref:`FSR ` therefore some asm-macros were needed: - -.. code-block:: c - - #define GET_FSR(fsr) \ - asm volatile("st %%fsr, %[reg]" : [reg] "=g" (fsr) : "0" (fsr)); - #define SET_FSR(fsr) \ - asm volatile("ld %[reg], %%fsr" : : [reg] "g" (fsr)); - - uint32_t fsr; - GET_FSR(fsr); - fsr |= (1 << 22); - SET_FSR(fsr); - -The final step is an actual call to some library procedures: - -.. code-block:: c - - double input = M_PI_4; - double result = sin(input); - - float inputX = 3.5f; - float inputY = 1.2f; - float resultf = fmodf(inputX, inputY); - -Using all those snipets we can create a small test program. Sadly :ref:`RTEMS ` and the :ref:`BSP ` need some more configuring, but as the program would not run without them, we're going to show that as well. We've also added some ``printf`` to actually get a visible output (which one can only see if some type of console output is possible...): - -.. code-block:: c - - #include - - #include - - #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER - #define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER - - #define CONFIGURE_RTEMS_INIT_TASKS_TABLE - #define CONFIGURE_MAXIMUM_TASKS 1 - - #define CONFIGURE_INIT - #include - - #include - #include - - #include "math.h" - - void test() - { - double dbuf, ret; - - double d1 = 0.5, d2 = -2.0; - float f1 = 0.5f, f2 = -2.0f; - - printf("sin(%lf) = %lf\n", d1, sin(d1)); - printf("atan2(%lf, %lf) = %lf\n", d1, d2, atan2(d1, d2)); - ret = modf(d1, &dbuf); - printf("modf(%lf, %lf) = %lf\n", d1, dbuf, ret); - printf("isfinite(%lf) = %d\n", d1, isfinite(d1)); - - printf("cosf(%f) = %f\n", f1, cosf(f1)); - printf("powf(%f, %f) = %f\n", f1, f2, powf(f1, f2)); - printf("fmodf(%f, %f) = %f\n", f1, f2, fmodf(f1, f2)); - printf("signbit(%f) = %d\n", f1, signbit(f1)); - } - - #define GET_FSR(fsr) \ - asm volatile("st %%fsr, %[reg]" : [reg] "=g" (fsr) : "0" (fsr)); - - #define SET_FSR(fsr) \ - asm volatile("ld %[reg], %%fsr" : : [reg] "g" (fsr)); - - void ConfigurationMultiprocessingEnableFpu() - { - uint32_t psr; - sparc_get_psr(psr); - psr |= SPARC_PSR_EF_MASK; - sparc_set_psr(psr); - - uint32_t fsr; - GET_FSR(fsr); - fsr |= (1 << 22); - SET_FSR(fsr); - } - - rtems_task Init(rtems_task_argument arg) - { - ConfigurationMultiprocessingEnableFpu(); - - test(); - exit(0); - } - -Using the Software on a Typical Task -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Let's build the software using a shell command:: - - $ sparc-rtems-gcc test test_rtems.c libmcs/build-sparc_v8/bin/libm.a -Ilibmcs/libm/include -qleon3mp -frounding-math -fsignaling-nans -fno-builtin - -As one can see the command builds with the library, includes the header files, uses the LEON4 specific flag ``-qleon3mp`` (LEON3 and LEON4 use the same in this toolchain), and uses the flags provided in :ref:`OperationsEnviromentSoftwareConfiguration`, before finally producing the ``test`` executable. - -After running this program on the LEON4 platform it produces the following output on the console: - -.. code-block:: none - - sin(0.500000) = 0.479426 - atan2(0.500000, -2.000000) = 2.896614 - modf(0.500000, 0.000000) = 0.500000 - isfinite(0.500000) = 1 - - cosf(0.500000) = 0.877583 - powf(0.500000, -2.000000) = 4.000000 - fmodf(0.500000, -2.000000) = 0.500000 - signbit(0.500000) = 0 diff --git a/libm/libmcs/doc/sum/conf.py b/libm/libmcs/doc/sum/conf.py deleted file mode 100644 index 4414b1e1..00000000 --- a/libm/libmcs/doc/sum/conf.py +++ /dev/null @@ -1,84 +0,0 @@ -# Configuration file for the Sphinx documentation builder. -# -# This file only contains a selection of the most common options. For a -# full list see the documentation: -# https://www.sphinx-doc.org/en/master/usage/configuration.html - -# -- Path setup ------------------------------------------------------- - -# If extensions (or modules to document with autodoc) are in another -# directory, add these directories to sys.path here. If the directory is -# relative to the documentation root, use os.path.abspath to make it -# absolute, like shown here. -# -import os -import sys -from shutil import copyfile -import sphinx_rtd_theme # pylint: disable=unused-import -from sphinx.errors import ConfigError - -sys.path.insert(0, os.path.abspath("..")) - -# -- Project information ---------------------------------------------- - -project = "LibmCS - SUM" -copyright = "2025, GTD GmbH" -author = "GTD GmbH" - - -# -- General configuration -------------------------------------------- - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = [ - "matplotlib.sphinxext.plot_directive", - "sphinx.ext.autodoc", - "sphinx.ext.autosectionlabel", - "sphinx.ext.mathjax", - "sphinx-mathjax-offline", - "sphinx_rtd_theme", - "hawkmoth", -] - -# Figures are referenced by number -numfig = True - -# Configuration for hawkmoth -hawkmoth_clang = ["-Ilibm/include", "-Isw-quality/dummy_includes"] -hawkmoth_root = os.path.abspath("../../libm") - -# Add any paths that contain templates here, relative to this directory. -templates_path = ["../_templates"] - -# -- Options for HTML output ------------------------------------------ - -# The theme to use for HTML and HTML Help pages. See the documentation -# for a list of builtin themes. -# -html_theme = "sphinx_rtd_theme" - -html_theme_options = { - "collapse_navigation": False, - "logo_only": True, -} - -html_logo = "../logo/libmcs-logo.png" -html_favicon = "../logo/libmcs-favicon.ico" - -# Add any paths that contain custom static files (such as style sheets) -# here, relative to this directory. They are copied after the builtin -# static files, so a file named "default.css" will overwrite the builtin -# "default.css". -html_static_path = ["../_static"] - -html_css_files = ["css/custom.css"] - -html_context = { - "display_gitlab": True, # Integrate Gitlab - "gitlab_host": "gitlab.com", - "gitlab_user": "gtd-gmbh", # Organization or User - "gitlab_repo": "libmcs", # Repo name - "gitlab_version": "development", # Version - "conf_py_path": "/doc/sum/", # Path in the checkout to the docs root -} diff --git a/libm/libmcs/doc/sum/index.rst b/libm/libmcs/doc/sum/index.rst deleted file mode 100644 index dfe87533..00000000 --- a/libm/libmcs/doc/sum/index.rst +++ /dev/null @@ -1,26 +0,0 @@ -Mathematical Library for Critical Systems -========================================== - -The LibmCS library has been developed by re-engineering the ``libm`` included in the ``Newlib`` library version 4.0.0. The work has been carried out under ESA Contract No. 4000130278/20/NL/AS. - -Whenever changes were made to ``Newlib`` after version 4.0.0 they were checked and tested before being added to the library. Only those changes that made sense to be a part of the library were added. - -The following pages in this documentation try to give a xenodochial introduction into LibmCS to the user. - -This user manual also contains the :ref:`ICD `, most of its information can be found in the :ref:`Reference Manual`. - -.. toctree:: - :numbered: - :maxdepth: 2 - :caption: Software User Manual - - 1_Abbreviations - 2_Conventions - 3_Purpose_of_the_Software - 4_General_Behaviour - 5_External_View_of_the_Software - 6_Operations_Environment - 7_Operations_Manual - 8_Reference_Manual - 9_Tutorial - 10_Bindings diff --git a/libm/libmcs/libm/include/complex.h b/libm/libmcs/libm/include/complex.h index 1daf671f..8e9774e9 100644 --- a/libm/libmcs/libm/include/complex.h +++ b/libm/libmcs/libm/include/complex.h @@ -15,7 +15,6 @@ extern "C"{ #endif -#include "config.h" #include "internal_config.h" #ifndef __LIBMCS_WANT_COMPLEX diff --git a/libm/libmcs/libm/include/config.h b/libm/libmcs/libm/include/config.h deleted file mode 100644 index 1b79f95e..00000000 --- a/libm/libmcs/libm/include/config.h +++ /dev/null @@ -1,17 +0,0 @@ -/* SPDX-License-Identifier: GTDGmbH */ -/* Copyright 2020-2022 by GTD GmbH. */ - -#ifndef LIBMCS_CONFIG_H -#define LIBMCS_CONFIG_H - -// #ifndef LIBMCS_FPU_DAZ -// #define LIBMCS_FPU_DAZ -// #endif /* !LIBMCS_FPU_DAZ */ -// #ifdef LIBMCS_LONG_DOUBLE_IS_64BITS -// #undef LIBMCS_LONG_DOUBLE_IS_64BITS -// #endif /* LIBMCS_LONG_DOUBLE_IS_64BITS */ -// #ifndef LIBMCS_WANT_COMPLEX -// #define LIBMCS_WANT_COMPLEX -// #endif /* !LIBMCS_WANT_COMPLEX */ - -#endif /* !LIBMCS_CONFIG_H */ diff --git a/libm/libmcs/libm/include/math.h b/libm/libmcs/libm/include/math.h index 1bbdf20c..4c12ed59 100644 --- a/libm/libmcs/libm/include/math.h +++ b/libm/libmcs/libm/include/math.h @@ -5,7 +5,6 @@ extern "C"{ #endif -#include "config.h" #include "internal_config.h" /* diff --git a/libm/phoenix/compatibility.c b/libm/phoenix/compatibility.c new file mode 100644 index 00000000..b19ec2e7 --- /dev/null +++ b/libm/phoenix/compatibility.c @@ -0,0 +1,49 @@ +/* + * Phoenix-RTOS + * + * libphoenix + * + * Compatibility source file for libmcs header file + * + * Copyright 2025 Phoenix Systems + * Author: Mikolaj Matalowski + * + * This file is part of Phoenix-RTOS. + * + * %LICENSE% + */ +#include + + +int __fpclassifyf(float x) +{ + return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, x); +} + + +int __fpclassifyd(double x) +{ + return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, x); +} + + +float nanf(const char *) +{ + return __builtin_nanf(""); +} + + +int __signbitf(float x) +{ + return __builtin_signbitf(x); +} + + +int __signbitd(double x) +{ + return __builtin_signbit(x); +} + + +const float __inff = __builtin_inff(); +const double __infd = __builtin_inf(); From fae9abe83934cc5e23d9a2d2bc1c232ce5a64ca6 Mon Sep 17 00:00:00 2001 From: Mikolaj Matalowski Date: Tue, 30 Sep 2025 17:58:39 +0200 Subject: [PATCH 3/3] Move libphoenix math library implementation JIRA: RTOS-1132 --- Makefile | 5 +- include/complex.h | 255 ------------------------------- include/math.h | 230 ---------------------------- include/math/consts.h | 71 --------- libm/Makefile | 2 +- {math => libm/phoenix}/common.c | 1 - {math => libm/phoenix}/common.h | 0 {math => libm/phoenix}/complex.c | 0 {math => libm/phoenix}/exp.c | 36 +++++ {math => libm/phoenix}/hyper.c | 18 +++ {math => libm/phoenix}/power.c | 6 + {math => libm/phoenix}/trig.c | 42 +++++ math/Makefile | 7 - 13 files changed, 106 insertions(+), 567 deletions(-) delete mode 100644 include/complex.h delete mode 100644 include/math.h delete mode 100644 include/math/consts.h rename {math => libm/phoenix}/common.c (99%) rename {math => libm/phoenix}/common.h (100%) rename {math => libm/phoenix}/complex.c (100%) rename {math => libm/phoenix}/exp.c (93%) rename {math => libm/phoenix}/hyper.c (88%) rename {math => libm/phoenix}/power.c (97%) rename {math => libm/phoenix}/trig.c (91%) delete mode 100644 math/Makefile diff --git a/Makefile b/Makefile index 69467c08..373e6dc0 100644 --- a/Makefile +++ b/Makefile @@ -46,7 +46,7 @@ include ctype/Makefile include err/Makefile include errno/Makefile include locale/Makefile -include math/Makefile +include libm/Makefile include misc/Makefile include net/Makefile include netinet/Makefile @@ -82,7 +82,8 @@ install: install-headers install-libs install-headers: $(SRCHEADERS) @echo INSTALL "$(HEADERS_INSTALL_DIR)/*"; \ mkdir -p "$(HEADERS_INSTALL_DIR)"; \ - cp -a include/* "$(HEADERS_INSTALL_DIR)"; + cp -a include/* "$(HEADERS_INSTALL_DIR)"; \ + cp -a libm/libmcs/libm/include/* "$(HEADERS_INSTALL_DIR)"; # TODO: remove `rm crt0.o` when we will be sure it's not a symlink to libphoenix.a anymore install-libs: $(LIB_TARGETS) diff --git a/include/complex.h b/include/complex.h deleted file mode 100644 index 9c7a3427..00000000 --- a/include/complex.h +++ /dev/null @@ -1,255 +0,0 @@ -/* - * Phoenix-RTOS - * - * libphoenix - * - * mathematical functions on complex numbers - * - * Copyright 2023 Phoenix Systems - * Author: Gerard Swiderski - * - * This file is part of Phoenix-RTOS. - * - * %LICENSE% - */ - -#ifndef _COMPLEX_H_ -#define _COMPLEX_H_ - -/* define complex numbers specifers */ -#define complex _Complex -#define _Complex_I 1.0fi -#define I _Complex_I - - -#ifdef __cplusplus -extern "C" { -#endif - - -static inline double creal(double complex z) -{ - return (__real__(z)); -} - - -static inline float crealf(float complex z) -{ - return (__real__(z)); -} - - -static inline double cimag(double complex z) -{ - return (__imag__(z)); -} - - -static inline float cimagf(float complex z) -{ - return (__imag__(z)); -} - - -static inline double complex conj(double complex z) -{ - return __builtin_complex((__real__(z)), -(__imag__(z))); -} - - -static inline float complex conjf(float complex z) -{ - return __builtin_complex((__real__(z)), -(__imag__(z))); -} - - -double cabs(double complex); - - -float cabsf(float complex); - - -double carg(double complex); - - -float cargf(float complex); - - -double complex cexp(double complex); - - -float complex cexpf(float complex); - - -/* - * TODO: functions not yet implemented - */ - -long double cabsl(long double complex); - - -double complex cacos(double complex); - - -float complex cacosf(float complex); - - -double complex cacosh(double complex); - - -float complex cacoshf(float complex); - - -long double complex cacoshl(long double complex); - - -long double complex cacosl(long double complex); - - -long double cargl(long double complex); - - -double complex casin(double complex); - - -float complex casinf(float complex); - - -double complex casinh(double complex); - - -float complex casinhf(float complex); - - -long double complex casinhl(long double complex); - - -long double complex casinl(long double complex); - - -double complex catan(double complex); - - -float complex catanf(float complex); - - -double complex catanh(double complex); - - -float complex catanhf(float complex); - - -long double complex catanhl(long double complex); - - -long double complex catanl(long double complex); - - -double complex ccos(double complex); - - -float complex ccosf(float complex); - - -double complex ccosh(double complex); - - -float complex ccoshf(float complex); - - -long double complex ccoshl(long double complex); - - -long double complex ccosl(long double complex); - - -long double complex cexpl(long double complex); - - -long double cimagl(long double complex); - - -double complex clog(double complex); - - -float complex clogf(float complex); - - -long double complex clogl(long double complex); - - -long double complex conjl(long double complex); - - -double complex cpow(double complex, double complex); - - -float complex cpowf(float complex, float complex); - - -long double complex cpowl(long double complex, long double complex); - - -double complex cproj(double complex); - - -float complex cprojf(float complex); - - -long double complex cprojl(long double complex); - - -long double creall(long double complex); - - -double complex csin(double complex); - - -float complex csinf(float complex); - - -double complex csinh(double complex); - - -float complex csinhf(float complex); - - -long double complex csinhl(long double complex); - - -long double complex csinl(long double complex); - - -double complex csqrt(double complex); - - -float complex csqrtf(float complex); - - -long double complex csqrtl(long double complex); - - -double complex ctan(double complex); - - -float complex ctanf(float complex); - - -double complex ctanh(double complex); - - -float complex ctanhf(float complex); - - -long double complex ctanhl(long double complex); - - -long double complex ctanl(long double complex); - - -#ifdef __cplusplus -} -#endif - - -#endif /* end of _COMPLEX_H_ */ diff --git a/include/math.h b/include/math.h deleted file mode 100644 index 3353192c..00000000 --- a/include/math.h +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Phoenix-RTOS - * - * libphoenix - * - * math.h - * - * Copyright 2017, 2022 Phoenix Systems - * Author: Aleksander Kaminski, Damian Loewnau - * - * This file is part of Phoenix-RTOS. - * - * %LICENSE% - */ - -#ifndef _LIBPHOENIX_MATH_H_ -#define _LIBPHOENIX_MATH_H_ - - -#include -#include - - -#ifdef __cplusplus -extern "C" { -#endif - -#define MATH_ERRNO 1 -#define MATH_ERREXCEPT 2 -#define math_errhandling (MATH_ERRNO) - -#define FP_NAN 0 -#define FP_INFINITE 1 -#define FP_ZERO 2 -#define FP_SUBNORMAL 3 -#define FP_NORMAL 4 - - -#define fpclassify(x) __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL, FP_ZERO, x) -#define isfinite(x) __builtin_isfinite(x) -#define isgreater(x, y) __builtin_isgreater(x, y) -#define isgreaterequal(x, y) __builtin_isgreaterequal(x, y) -#define isinf(x) __builtin_isinf(x) -#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 isnan(x) __builtin_isnan(x) -#define signbit(x) __builtin_signbit(x) -#define isnormal(x) __builtin_isnormal(x) -#define isunordered(x, y) __builtin_isunordered(x, y) - -#define HUGE_VAL __builtin_huge_val() -#define HUGE_VALF __builtin_huge_valf() -#define HUGE_VALL __builtin_huge_vall() -#define INFINITY __builtin_inff() -#define NAN __builtin_nanf("") - - -/* Trigonometric functions */ - - -/* Returns the cosine of an angle of x radians. */ -extern double cos(double x); - - -/* Returns the sine of an angle of x radians. */ -extern double sin(double x); - - -/* Returns the tangent of an angle of x radians. */ -extern double tan(double x); - - -/* Returns the principal value of the arc cosine of x, expressed in radians. */ -extern double acos(double x); - - -/* Returns the principal value of the arc sine of x, expressed in radians. */ -extern double asin(double x); - - -/* Returns the principal value of the arc tan of x, expressed in radians. */ -extern double atan(double x); - - -/* Returns the principal value of the arc tangent of y/x, expressed in radians. */ -extern double atan2(double y, double x); - - -/* Hyperbolic functions */ - - -/* Returns the hyperbolic cosine of x. */ -extern double cosh(double x); - - -/* Returns the hyperbolic sine of x. */ -extern double sinh(double x); - - -/* Returns the hyperbolic tangent of x. */ -extern double tanh(double x); - - -/* Exponential and logarithmic functions */ - - -/* Returns the base-e exponential function of x, which is e raised to the power x: e^x. */ -extern double exp(double x); - - -/* Breaks the floating point number x into its binary significand - * (a floating point with an absolute value between 0.5(included) and 1.0(excluded)) - * and an integral exponent for 2. */ -extern double frexp(double x, int *exp); - - -/* Returns the result of multiplying x (the significand) by 2 raised to the power of exp (the exponent). */ -extern double ldexp(double x, int exp); - - -/* Returns the natural logarithm of x. */ -extern double log(double x); - - -/* Returns the common (base-2) logarithm of x. */ -extern double log2(double x); - - -/* Returns the common (base-10) logarithm of x. */ -extern double log10(double x); - - -/* Breaks x into an integral and a fractional part. */ -extern double modf(double x, double *intpart); -extern float modff(float x, float *intpart); - - -/* Power functions */ - - -/* Returns base raised to the power exponent. */ -extern double pow(double base, double exponent); - - -/* Returns the square root of x. */ -extern double sqrt(double x); - - -/* Rounding and remainder functions */ - - -/* Rounds x upward, returning the smallest integral value that is not less than x. */ -extern double ceil(double x); -extern float ceilf(float x); - - -/* Rounds x downward, returning the largest integral value that is not greater than x. */ -extern double floor(double x); -extern float floorf(float x); - - -/* Returns the floating-point remainder of numer/denom (rounded towards zero). */ -extern double fmod(double numer, double denom); - - -/* Return the integral value nearest to x */ -extern double round(double x); -extern float roundf(float x); - - -/* Rounds x toward zero, returning the nearest integral value that is not larger in magnitude than x. */ -extern double trunc(double x); -extern float truncf(float x); - - -/* Miscellaneous */ - - -/* Returns the absolute value of x: |x|. */ -extern double fabs(double x); -extern float fabsf(float x); - - -/* C99 extensions */ -float cosf(float x); -float sinf(float x); -float tanf(float x); -float acosf(float x); -float asinf(float x); -float atanf(float x); -float atan2f(float y, float x); -float coshf(float x); -float sinhf(float x); -float tanhf(float x); -float expf(float x); -float frexpf(float x, int *exp); -float ldexpf(float x, int exp); -float logf(float x); -float log10f(float x); -float powf(float base, float exponent); -float sqrtf(float x); -float fmodf(float num, float denom); - - -#define cosf(x) ((float)cos(x)) -#define sinf(x) ((float)sin(x)) -#define tanf(x) ((float)tan(x)) -#define acosf(x) ((float)acos(x)) -#define asinf(x) ((float)asin(x)) -#define atanf(x) ((float)atan(x)) -#define atan2f(y, x) ((float)atan2(y, x)) -#define coshf(x) ((float)cosh(x)) -#define sinhf(x) ((float)sinh(x)) -#define tanhf(x) ((float)tanh(x)) -#define expf(x) ((float)exp(x)) -#define frexpf(x, exp) ((float)frexp(x, exp)) -#define ldexpf(x, exp) ((float)ldexp(x, exp)) -#define logf(x) ((float)log(x)) -#define log10f(x) ((float)log10(x)) -#define powf(base, exponent) ((float)pow(base, exponent)) -#define fmodf(num, denom) ((float)fmod(num, denom)) - - -#ifdef __cplusplus -} -#endif - - -#endif diff --git a/include/math/consts.h b/include/math/consts.h deleted file mode 100644 index 40ac3e7d..00000000 --- a/include/math/consts.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Phoenix-RTOS - * - * libphoenix - * - * math.h constants - * - * Copyright 2017 Phoenix Systems - * Author: Aleksander Kaminski - * - * This file is part of Phoenix-RTOS. - * - * %LICENSE% - */ - -#ifndef _LIBPHOENIX_MATH_CONSTS_H_ -#define _LIBPHOENIX_MATH_CONSTS_H_ - -/* The base of natural logarithms. */ -#define M_E 2.7182818284590452354 - - -/* The logarithm to base 2 of M_E. */ -#define M_LOG2E 1.4426950408889634074 - - -/* The logarithm to base 10 of M_E. */ -#define M_LOG10E 0.43429448190325182765 - - -/* The natural logarithm of 2. */ -#define M_LN2 0.69314718055994530942 - - -/* The natural logarithm of 10. */ -#define M_LN10 2.30258509299404568402 - - -/* Pi, the ratio of a circle's circumference to its diameter. */ -#define M_PI 3.14159265358979323846 - - -/* Pi divided by two. */ -#define M_PI_2 1.57079632679489661923 - - -/* Pi divided by four. */ -#define M_PI_4 0.78539816339744830962 - - -/* The reciprocal of pi (1/pi) */ -#define M_1_PI 0.31830988618379067154 - - -/* Two times the reciprocal of pi. */ -#define M_2_PI 0.63661977236758134308 - - -/* Two times the reciprocal of the square root of pi. * */ -#define M_2_SQRTPI 1.12837916709551257390 - - -/* The square root of two. */ -#define M_SQRT2 1.41421356237309504880 - - -/* The reciprocal of the square root of two (also the square root of 1/2). */ -#define M_SQRT1_2 0.70710678118654752440 - - -#endif diff --git a/libm/Makefile b/libm/Makefile index 4d314515..35ce473f 100644 --- a/libm/Makefile +++ b/libm/Makefile @@ -58,7 +58,7 @@ CFLAGS += -Ilibm/libmcs/libm/include # TODO: Separate math library implementation from libphoenix # Build for libmcs -ifeq ($(USE_LIBMCS), y) +ifeq ($(LIBM_USE_LIBMCS), y) ifeq ($(LIBM_WANT_COMPLEX), y) CPPFLAGS += -DLIBM_WANT_COMPLEX OBJS += $(addprefix $(PREFIX_O), $(patsubst %.c,%.o,$(wildcard libm/libmcs/libm/complexd/internal/*.c))) diff --git a/math/common.c b/libm/phoenix/common.c similarity index 99% rename from math/common.c rename to libm/phoenix/common.c index 97c772ed..8f9d3602 100644 --- a/math/common.c +++ b/libm/phoenix/common.c @@ -19,7 +19,6 @@ #include #include "common.h" - void normalizeSub(double *x, int *exp) { conv_t *conv = (conv_t *)x; diff --git a/math/common.h b/libm/phoenix/common.h similarity index 100% rename from math/common.h rename to libm/phoenix/common.h diff --git a/math/complex.c b/libm/phoenix/complex.c similarity index 100% rename from math/complex.c rename to libm/phoenix/complex.c diff --git a/math/exp.c b/libm/phoenix/exp.c similarity index 93% rename from math/exp.c rename to libm/phoenix/exp.c index 77c9c76a..6226219d 100644 --- a/math/exp.c +++ b/libm/phoenix/exp.c @@ -47,6 +47,12 @@ double frexp(double x, int *exp) } +float frexpf(float x, int *exp) +{ + return (float)frexp((double)x, exp); +} + + double ldexp(double x, int exp) { if (isnan(x) != 0) { @@ -84,6 +90,12 @@ double ldexp(double x, int exp) } +float ldexpf(float x, int exp) +{ + return (float)ldexp((double)x, exp); +} + + double log(double x) { double tmp, pow, res; @@ -129,6 +141,12 @@ double log(double x) } +float logf(float x) +{ + return (float)log((double)x); +} + + double log2(double x) { return (log(x) / M_LN2); @@ -142,6 +160,12 @@ double log10(double x) } +float log10f(float x) +{ + return (float)log10((double)x); +} + + double modf(double x, double *intpart) { conv_t *conv = (conv_t *)&x; @@ -232,6 +256,12 @@ double exp(double x) } +float expf(float x) +{ + return (float)exp((double)x); +} + + double ceil(double x) { #ifdef __IEEE754_CEIL @@ -321,6 +351,12 @@ double fmod(double number, double denom) } +float fmodf(float x, float y) +{ + return (float)fmod((double)x, (double)y); +} + + double round(double x) { #ifdef __IEEE754_ROUND diff --git a/math/hyper.c b/libm/phoenix/hyper.c similarity index 88% rename from math/hyper.c rename to libm/phoenix/hyper.c index c3afb86f..b0a55509 100644 --- a/math/hyper.c +++ b/libm/phoenix/hyper.c @@ -41,6 +41,12 @@ double cosh(double x) } +float coshf(float x) +{ + return (float)cosh((double)x); +} + + double sinh(double x) { double y, f; @@ -72,6 +78,12 @@ double sinh(double x) } +float sinhf(float x) +{ + return (double)sin((double)x); +} + + double tanh(double x) { if (isnan(x) != 0) { @@ -88,3 +100,9 @@ double tanh(double x) /* cosh is never equal to zero */ return (sinh(x) / cosh(x)); } + + +float tanhf(float x) +{ + return (float)tanh((double)x); +} diff --git a/math/power.c b/libm/phoenix/power.c similarity index 97% rename from math/power.c rename to libm/phoenix/power.c index 45837430..5ea5c583 100644 --- a/math/power.c +++ b/libm/phoenix/power.c @@ -93,6 +93,12 @@ double pow(double base, double exponent) } +float powf(float x, float exp) +{ + return (float)pow((double)x, (double)exp); +} + + double sqrt(double x) { if (isnan(x) != 0) { diff --git a/math/trig.c b/libm/phoenix/trig.c similarity index 91% rename from math/trig.c rename to libm/phoenix/trig.c index 5a9e6695..834ac314 100644 --- a/math/trig.c +++ b/libm/phoenix/trig.c @@ -71,6 +71,12 @@ double cos(double x) } +float cosf(float x) +{ + return (float)cos((double)x); +} + + /* Calculates value of sine using Maclaurin series. */ double sin(double x) { @@ -129,6 +135,12 @@ double sin(double x) } +float sinf(float x) +{ + return (float)sin((double)x); +} + + double tan(double x) { double c; @@ -153,6 +165,12 @@ double tan(double x) } +float tanf(float x) +{ + return (float)tan((double)x); +} + + /* Calculates value of arc cosine using secant method */ double acos(double x) { @@ -187,6 +205,12 @@ double acos(double x) } +float acosf(float x) +{ + return (float)acos((double)x); +} + + /* Calculates value of arc sine using asin(x) = pi/2 - acos(x) relationship. */ double asin(double x) { @@ -202,6 +226,12 @@ double asin(double x) } +float asinf(float x) +{ + return (float)asin((double)x); +} + + static const double atan_wi[] = { 0.2152638534631578, 0.2152638534631578, 0.2051984637212956, 0.2051984637212956, 0.1855383974779378, 0.1855383974779378, 0.1572031671581935, 0.1572031671581935, 0.1215185706879032, 0.1215185706879032, 0.0801580871597602, @@ -244,6 +274,12 @@ double atan(double x) } +float atanf(float x) +{ + return (float)atan((double)x); +} + + double atan2(double y, double x) { if ((isnan(y) != 0) || (isnan(x) != 0)) { @@ -299,3 +335,9 @@ double atan2(double y, double x) return 0.0; } + + +float atan2f(float y, float x) +{ + return (float)atan2((double)y, (double)x); +} diff --git a/math/Makefile b/math/Makefile deleted file mode 100644 index f8f1a967..00000000 --- a/math/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# -# Makefile for libphoenix/math -# -# Copyright 2012-2015, 2020 Phoenix Systems -# - -OBJS += $(addprefix $(PREFIX_O)math/, trig.o power.o exp.o common.o complex.o hyper.o)