From 5da9327e128ff9eb46983b7769e98528ce90fbc0 Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Sat, 18 Aug 2018 17:35:33 -0700 Subject: [PATCH] Implement factorial powered by the Gamma function. --- external/libabacus | 2 +- include/functions.hpp | 1 + src/main.cpp | 2 ++ src/operator_functions.cpp | 16 ++++++++++++++++ 4 files changed, 20 insertions(+), 1 deletion(-) diff --git a/external/libabacus b/external/libabacus index 8c9acaf..0172091 160000 --- a/external/libabacus +++ b/external/libabacus @@ -1 +1 @@ -Subproject commit 8c9acafc932541d9a1c09f1fa0a93ac992254309 +Subproject commit 01720914e0899023747c94ef7cf4c5d17782d7dd diff --git a/include/functions.hpp b/include/functions.hpp index d12a276..20f2357 100644 --- a/include/functions.hpp +++ b/include/functions.hpp @@ -55,6 +55,7 @@ FUNCTION(gt); FUNCTION(gte); FUNCTION(negate); +FUNCTION(factorial); FUNCTION(ln); FUNCTION(exp); diff --git a/src/main.cpp b/src/main.cpp index 6c5e57a..6c9bf97 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -55,6 +55,7 @@ int main() { ab.add_function("divide", function_divide, "(num, num)->num"); ab.add_function("pow", function_pow, "(num, num)->num"); ab.add_function("negate", function_negate, "(num)->num"); + ab.add_function("factorial", function_factorial, "(num)->num"); ab.add_function("ln", function_ln, "(num)->num"); ab.add_function("exp", function_exp, "(num)->num"); @@ -78,6 +79,7 @@ int main() { ab.add_operator_infix("/", "divide", -1, 3); ab.add_operator_infix("^", "pow", 1, 3); ab.add_operator_prefix("-", "negate"); + ab.add_operator_postfix("!", "factorial"); while(!close_requested) { char* data = readline(" > "); diff --git a/src/operator_functions.cpp b/src/operator_functions.cpp index d13db0c..acc31ad 100644 --- a/src/operator_functions.cpp +++ b/src/operator_functions.cpp @@ -7,6 +7,22 @@ FUNCTION_MPFR2(divide, div) FUNCTION_MPFR2(pow, pow); FUNCTION_MPFR(negate, neg); +FUNCTION(factorial) { + number* left = (number*) libab_unwrap_param(params, 0); + mpfr_t plus_one; + mpfr_t gamma; + + mpfr_init2(plus_one, PRECISION); + mpfr_init2(gamma, PRECISION); + mpfr_add_ui(plus_one, left->value, 1, MPFR_RNDN); + mpfr_gamma(gamma, plus_one, MPFR_RNDN); + + number* to_return = new number(std::move(gamma)); + ref return_value = create_value(ab, to_return); + libab_ref_copy(return_value, into); + + return LIBAB_SUCCESS; +} FUNCTION_COMPARE(lt, <); FUNCTION_COMPARE(lte, <=);