diff options
-rw-r--r-- | help/C/functions.page | 8 | ||||
-rw-r--r-- | src/mp-equation.c | 5 | ||||
-rw-r--r-- | src/mp.c | 34 | ||||
-rw-r--r-- | src/mp.h | 6 | ||||
-rw-r--r-- | src/test-mp-equation.c | 8 |
5 files changed, 61 insertions, 0 deletions
diff --git a/help/C/functions.page b/help/C/functions.page index 0da00cf..f1db17b 100644 --- a/help/C/functions.page +++ b/help/C/functions.page @@ -37,6 +37,10 @@ <td><p><link xref="trigonometry">Hyperbolic Cosine</link></p></td> </tr> <tr> + <td><p>erf</p></td> + <td><p>Gauss Error function</p></td> + </tr> + <tr> <td><p>frac</p></td> <td><p>Fractional Component</p></td> </tr> @@ -84,6 +88,10 @@ <td><p>twos</p></td> <td><p>Twos complement</p></td> </tr> + <tr> + <td><p>zeta</p></td> + <td><p>Riemann zeta function</p></td> + </tr> </table> <p> <app>MATE Calculator</app> does not support user-defined functions. diff --git a/src/mp-equation.c b/src/mp-equation.c index 4778298..df9d872 100644 --- a/src/mp-equation.c +++ b/src/mp-equation.c @@ -174,6 +174,7 @@ function_is_defined(ParserState *state, const char *name) strcmp(lower_name, "sin⁻¹") == 0 || strcmp(lower_name, "cos⁻¹") == 0 || strcmp(lower_name, "tan⁻¹") == 0 || strcmp(lower_name, "sinh") == 0 || strcmp(lower_name, "cosh") == 0 || strcmp(lower_name, "tanh") == 0 || strcmp(lower_name, "sinh⁻¹") == 0 || strcmp(lower_name, "cosh⁻¹") == 0 || strcmp(lower_name, "tanh⁻¹") == 0 || + strcmp(lower_name, "erf") == 0 || strcmp(lower_name, "zeta") == 0 || strcmp(lower_name, "asinh") == 0 || strcmp(lower_name, "acosh") == 0 || strcmp(lower_name, "atanh") == 0 || strcmp(lower_name, "ones") == 0 || strcmp(lower_name, "twos") == 0) { @@ -261,6 +262,10 @@ get_function(ParserState *state, const char *name, const MPNumber *x, MPNumber * mp_acosh(x, z); else if (strcmp(lower_name, "tanh⁻¹") == 0 || strcmp(lower_name, "atanh") == 0) mp_atanh(x, z); + else if (strcmp(lower_name, "erf") == 0) + mp_erf(x, z); + else if (strcmp(lower_name, "zeta") == 0) + mp_zeta(x, z); else if (strcmp(lower_name, "ones") == 0) mp_ones_complement(x, state->options->wordlen, z); else if (strcmp(lower_name, "twos") == 0) @@ -583,6 +583,40 @@ mp_xpowy_integer(const MPNumber *x, int64_t n, MPNumber *z) mpc_pow_si(z->num, x->num, (long) n, MPC_RNDNN); } +void +mp_erf(const MPNumber *x, MPNumber *z) +{ + if (mp_is_complex(x)) + { /* Translators: Error displayed when error function (erf) value is undefined */ + mperr(_("The error function is only defined for real numbers")); + mp_set_from_integer(0, z); + return; + } + + mpfr_set_zero(mpc_imagref(z->num), MPFR_RNDN); + mpfr_erf(mpc_realref(z->num), mpc_realref(x->num), MPFR_RNDN); +} + +void +mp_zeta(const MPNumber *x, MPNumber *z) +{ + MPNumber one = mp_new(); + + mp_set_from_integer(1, &one); + if (mp_is_complex(x) || mp_compare(x, &one) == 0) + { /* Translators: Error displayed when zeta function value is undefined */ + mperr(_("The Riemann zeta function is only defined for real numbers ≠1")); + mp_set_from_integer(0, z); + mp_clear(&one); + return; + } + + mpfr_set_zero(mpc_imagref(z->num), MPFR_RNDN); + mpfr_zeta(mpc_realref(z->num), mpc_realref(x->num), MPFR_RNDN); + + mp_clear(&one); +} + GList* mp_factorize(const MPNumber *x) { @@ -298,6 +298,12 @@ void mp_acosh(const MPNumber *x, MPNumber *z); /* Sets z = tanh⁻¹ x */ void mp_atanh(const MPNumber *x, MPNumber *z); +/* Sets z to the value of the error function of x */ +void mp_erf(const MPNumber *x, MPNumber *z); + +/* Sets z to the value of the Riemann Zeta function of x */ +void mp_zeta(const MPNumber *x, MPNumber *z); + /* Returns true if x is cannot be represented in a binary word of length 'wordlen' */ bool mp_is_overflow(const MPNumber *x, int wordlen); diff --git a/src/test-mp-equation.c b/src/test-mp-equation.c index becf742..861c445 100644 --- a/src/test-mp-equation.c +++ b/src/test-mp-equation.c @@ -590,6 +590,14 @@ test_equations(void) options.angle_units = MP_GRADIANS; test("sin 100", "1", 0); + test("zeta 0", "−0.5", 0); + test("zeta 2", "1.644934067", 0); + test("zeta −2", "0", 0); + + test("erf 0", "0", 0); + test("erf 1", "0.842700793", 0); + test("erf −1", "−0.842700793", 0); + /* Complex numbers */ options.angle_units = MP_DEGREES; test("i", "i", 0); |