From 9635c223b1d39d753afbe23406b45c58dfa38f8f Mon Sep 17 00:00:00 2001 From: Victor Akpan <67718730+victorakpan-dev@users.noreply.github.com> Date: Wed, 30 Mar 2022 18:44:01 +0100 Subject: [PATCH] Added new Math functions (#160) * Added log and round functions to math module * Added log and round functions to math module * Added a few math functions * Static checks * Maybe this will fix linux * Fixed errors with styles and tests --- src/pk_core.c | 93 +++++++++++++++++++++++++++++++++++++++++++++- tests/lang/core.pk | 17 +++++++++ 2 files changed, 109 insertions(+), 1 deletion(-) diff --git a/src/pk_core.c b/src/pk_core.c index 97c4cf7..3bed1f1 100644 --- a/src/pk_core.c +++ b/src/pk_core.c @@ -1049,7 +1049,8 @@ DEF(stdMathArcTangent, DEF(stdMathLog10, "log10(value:num) -> num\n" - "Return the logarithm to base 10 of argument [value]") { + "Return the logarithm to base 10 of argument [value]" + ) { double num; if (!validateNumeric(vm, ARG(1), &num, "Argument 1")) return; @@ -1065,6 +1066,89 @@ DEF(stdMathRound, RET(VAR_NUM(round(num))); } +DEF(stdMathLog2, + "log2(value:num) -> num\n" + "Returns the logarithm to base 2 of the argument [value]" + ) { + + double num; + if (!validateNumeric(vm, ARG(1), &num, "Argument 1")) return; + RET(VAR_NUM(log2(num))); +} + +DEF(stdMathHypot, + "hypot(x:num,y:num) -> num\n" + "Returns the hypotenuse of a right-angled triangle with side [x] and [y]" + ) { + + double x, y; + if (!validateNumeric(vm, ARG(1), &x, "Argument 1")) return; + if (!validateNumeric(vm, ARG(2), &y, "Argument 2")) return; + RET(VAR_NUM(hypot(x, y))); +} + +DEF(stdMathCbrt, + "cbrt(value:num) -> num\n" + "Returns the cuberoot of argument [value]" + ) { + + double num; + if (!validateNumeric(vm, ARG(1), &num, "Argument 1")) return; + RET(VAR_NUM(cbrt(num))); +} + +DEF(stdMathGamma, + "gamma(value:num) -> num\n" + "Returns the gamma function of argument [value]" + ) { + + double num; + if (!validateNumeric(vm, ARG(1), &num, "Argument 1")) return; + RET(VAR_NUM(tgamma(num))); +} + +#if defined(__USE_GNU) || defined(__USE_BSD) +DEF(stdMathGamma, + "gamma(value:num) -> num\n" + "Returns the gamma function of argument [value]" + ) { + + double num; + if (!validateNumeric(vm, ARG(1), &num, "Argument 1")) return; + RET(VAR_NUM(gamma(num))); +} +#endif + +DEF(stdMathLgamma, + "lgamma(value:num) -> num\n" + "Returns the complementary gamma function of argument [value]" + ) { + + double num; + if (!validateNumeric(vm, ARG(1), &num, "Argument 1")) return; + RET(VAR_NUM(lgamma(num))); +} + +DEF(stdMathErf, + "erf(value:num) -> num\n" + "Returns the error function of argument [value]" + ) { + + double num; + if (!validateNumeric(vm, ARG(1), &num, "Argument 1")) return; + RET(VAR_NUM(erf(num))); +} + +DEF(stdMathErfc, + "erfc(value:num) -> num\n" + "Returns the complementary error function of argument [value]" + ) { + + double num; + if (!validateNumeric(vm, ARG(1), &num, "Argument 1")) return; + RET(VAR_NUM(erfc(num))); +} + // 'Fiber' module methods. // ----------------------- @@ -1210,6 +1294,13 @@ void initializeCore(PKVM* vm) { MODULE_ADD_FN(math, "atan", stdMathArcTangent, 1); MODULE_ADD_FN(math, "log10", stdMathLog10, 1); MODULE_ADD_FN(math, "round", stdMathRound, 1); + MODULE_ADD_FN(math, "log2", stdMathLog2, 1); + MODULE_ADD_FN(math, "hypot", stdMathHypot, 2); + MODULE_ADD_FN(math, "cbrt", stdMathCbrt, 1); + MODULE_ADD_FN(math, "gamma", stdMathGamma, 1); + MODULE_ADD_FN(math, "lgamma",stdMathLgamma, 1); + MODULE_ADD_FN(math, "erf", stdMathErf, 1); + MODULE_ADD_FN(math, "erfc", stdMathErfc, 1); // Note that currently it's mutable (since it's a global variable, not // constant and pocketlang doesn't support constant) so the user shouldn't diff --git a/tests/lang/core.pk b/tests/lang/core.pk index 9bd5fae..40c4f99 100644 --- a/tests/lang/core.pk +++ b/tests/lang/core.pk @@ -84,6 +84,23 @@ assert(round(1.4) == 1) assert(round(1.5) == 2) assert(round(-1.5) == -2) +assert(abs(log2(2) - 1) < threshold) +assert(abs(log2(1) - 0) < threshold) +assert(abs(log2(5) - 2.321928094887362) < threshold) + +assert(abs(hypot(1,1) - 1.414213562373095) < threshold) +assert(abs(hypot(3,5) - 5.830951894845301) < threshold) + +assert(abs(cbrt(27) - 3) < threshold) +assert(abs(cbrt(9) - 2.080083823051904) < threshold) + +assert(abs(gamma(5) - 24) < threshold) +assert(abs(gamma(2.2) - 1.101802490879713) < threshold) + + + + + # If we got here, that means all test were passed. print('All TESTS PASSED')