From a1805c033817d0208a482daaded21eb70505bab7 Mon Sep 17 00:00:00 2001 From: Louis Rubet Date: Sun, 6 May 2018 14:59:15 +0200 Subject: [PATCH] #192: added expm and lnp1, changed wrong test for sqrt (2), removed extra command 'q' --- src/program.cpp | 5 +-- src/rpn-logs.hpp | 82 ++++++++++++++++++++++++++++++++------------- test/10-complex.txt | 56 ++++++++++++++++++++++++++++--- 3 files changed, 113 insertions(+), 30 deletions(-) diff --git a/src/program.cpp b/src/program.cpp index b66f778..e3ab77e 100644 --- a/src/program.cpp +++ b/src/program.cpp @@ -12,7 +12,6 @@ program::keyword_t program::s_keywords[] = { cmd_keyword, "help", &program::rpn_help, "this help message" }, { cmd_keyword, "h", &program::rpn_help, "" }, { cmd_keyword, "?", &program::rpn_help, "" }, - { cmd_keyword, "q", &program::rpn_good_bye, "" }, { cmd_keyword, "quit", &program::rpn_good_bye, "quit software" }, { cmd_keyword, "q", &program::rpn_good_bye, "" }, { cmd_keyword, "exit", &program::rpn_good_bye, "" }, @@ -170,14 +169,16 @@ program::keyword_t program::s_keywords[] = { cmd_keyword, "tan", &program::rpn_tan, "tangent" }, { cmd_keyword, "atan", &program::rpn_atan, "arg tangent" }, { cmd_keyword, "d->r", &program::rpn_d2r, "convert degrees to radians" }, - { cmd_keyword, "r->d", &program::rpn_r2d, "convert radians to degrees" }, + { cmd_keyword, "r->d", &program::rpn_r2d, "convert radians to degrees" }, //LOGS ON REALS AND COMPLEXES { cmd_undef, "", NULL, "\nLOGS ON REALS AND COMPLEXES"}, { cmd_keyword, "e", &program::rpn_e, "Euler constant" }, { cmd_keyword, "ln", &program::rpn_ln, "logarithm base e" }, { cmd_keyword, "log", &program::rpn_ln, "" }, + { cmd_keyword, "lnp1", &program::rpn_lnp1, "ln(1+x) which is useful when x is close to 0" }, { cmd_keyword, "exp", &program::rpn_exp, "exponential" }, + { cmd_keyword, "expm", &program::rpn_expm, "exp(x)-1 which is useful when x is close to 0" }, { cmd_keyword, "log10", &program::rpn_log10, "logarithm base 10" }, { cmd_keyword, "alog10", &program::rpn_alog10, "exponential base 10" }, { cmd_keyword, "exp10", &program::rpn_alog10, "" }, diff --git a/src/rpn-logs.hpp b/src/rpn-logs.hpp index d14f477..2df7766 100644 --- a/src/rpn-logs.hpp +++ b/src/rpn-logs.hpp @@ -10,7 +10,7 @@ void rpn_log10() MIN_ARGUMENTS(1); if (_stack->get_type(0) == cmd_number || _stack->get_type(0) == cmd_complex) - { + { //log10(z)=ln(z)/ln(10) rpn_ln(); @@ -28,7 +28,7 @@ void rpn_alog10() MIN_ARGUMENTS(1); if (_stack->get_type(0) == cmd_number || _stack->get_type(0) == cmd_complex) - { + { floating_t* left = &((number*)_stack->get_obj(0))->_value; number* ten = (number*)_stack->allocate_back(number::calc_size(), cmd_number); CHECK_MPFR(mpfr_set_d(ten->_value.mpfr, 10.0, floating_t::s_mpfr_rnd)); @@ -61,7 +61,7 @@ void rpn_alog2() MIN_ARGUMENTS(1); if (_stack->get_type(0) == cmd_number || _stack->get_type(0) == cmd_complex) - { + { floating_t* left = &((number*)_stack->get_obj(0))->_value; number* two = (number*)_stack->allocate_back(number::calc_size(), cmd_number); CHECK_MPFR(mpfr_set_d(two->_value.mpfr, 2.0, floating_t::s_mpfr_rnd)); @@ -74,9 +74,9 @@ void rpn_alog2() void rpn_ln() { MIN_ARGUMENTS(1); - + if (_stack->get_type(0) == cmd_number) - { + { number* left = (number*)_stack->back(); // x<0 -> ln(x) = ln(-x)+i*pi @@ -115,7 +115,7 @@ void rpn_ln() CHECK_MPFR(mpfr_add(re->mpfr, x->mpfr, y->mpfr, floating_t::s_mpfr_rnd)); CHECK_MPFR(mpfr_log(re->mpfr, re->mpfr, floating_t::s_mpfr_rnd)); CHECK_MPFR(mpfr_mul_d(re->mpfr, re->mpfr, 0.5, floating_t::s_mpfr_rnd)); - + _calc_stack.pop_back(); } else @@ -125,9 +125,9 @@ void rpn_ln() void rpn_exp() { MIN_ARGUMENTS(1); - + if (_stack->get_type(0) == cmd_number) - { + { floating_t* left = &((number*)_stack->get_obj(0))->_value; CHECK_MPFR(mpfr_exp(left->mpfr, left->mpfr, floating_t::s_mpfr_rnd)); } @@ -151,7 +151,41 @@ void rpn_exp() _calc_stack.pop_back(); } else - ERR_CONTEXT(ret_bad_operand_type); + ERR_CONTEXT(ret_bad_operand_type); +} + +void rpn_expm() +{ + MIN_ARGUMENTS(1); + + if (_stack->get_type(0) == cmd_number || _stack->get_type(0) == cmd_complex) + { + //exp(x)-1 + rpn_exp(); + + number* one = (number*)_stack->allocate_back(number::calc_size(), cmd_number); + CHECK_MPFR(mpfr_set_d(one->_value.mpfr, 1.0, floating_t::s_mpfr_rnd)); + rpn_minus(); + } + else + ERR_CONTEXT(ret_bad_operand_type); +} + +void rpn_lnp1() +{ + MIN_ARGUMENTS(1); + + if (_stack->get_type(0) == cmd_number || _stack->get_type(0) == cmd_complex) + { + //ln(x+1) + number* one = (number*)_stack->allocate_back(number::calc_size(), cmd_number); + CHECK_MPFR(mpfr_set_d(one->_value.mpfr, 1.0, floating_t::s_mpfr_rnd)); + rpn_plus(); + + rpn_ln(); + } + else + ERR_CONTEXT(ret_bad_operand_type); } void rpn_sinh() @@ -159,7 +193,7 @@ void rpn_sinh() MIN_ARGUMENTS(1); if (_stack->get_type(0) == cmd_number) - { + { floating_t* left = &((number*)_stack->get_obj(0))->_value; CHECK_MPFR(mpfr_sinh(left->mpfr, left->mpfr, floating_t::s_mpfr_rnd)); } @@ -186,7 +220,7 @@ void rpn_sinh() _calc_stack.pop_back(2); } else - ERR_CONTEXT(ret_bad_operand_type); + ERR_CONTEXT(ret_bad_operand_type); } void rpn_asinh() @@ -194,7 +228,7 @@ void rpn_asinh() MIN_ARGUMENTS(1); if (_stack->get_type(0) == cmd_number) - { + { floating_t* left = &((number*)_stack->get_obj(0))->_value; CHECK_MPFR(mpfr_asinh(left->mpfr, left->mpfr, floating_t::s_mpfr_rnd)); } @@ -211,7 +245,7 @@ void rpn_asinh() rpn_ln(); } else - ERR_CONTEXT(ret_bad_operand_type); + ERR_CONTEXT(ret_bad_operand_type); } void rpn_cosh() @@ -219,7 +253,7 @@ void rpn_cosh() MIN_ARGUMENTS(1); if (_stack->get_type(0) == cmd_number) - { + { floating_t* left = &((number*)_stack->get_obj(0))->_value; CHECK_MPFR(mpfr_cosh(left->mpfr, left->mpfr, floating_t::s_mpfr_rnd)); } @@ -227,14 +261,14 @@ void rpn_cosh() { // acosh(x+iy)=cosh(x)cos(y)+isinh(x)sin(y) stack::copy_and_push_back(*_stack, _stack->size()-1, _calc_stack); - + floating_t* tmp = &((number*)_calc_stack.allocate_back(number::calc_size(), cmd_number))->_value; floating_t* x = ((complex*)_calc_stack.get_obj(1))->re(); floating_t* y = ((complex*)_calc_stack.get_obj(1))->im(); floating_t* re = ((complex*)_stack->get_obj(0))->re(); floating_t* im = ((complex*)_stack->get_obj(0))->im(); - + CHECK_MPFR(mpfr_cosh(re->mpfr, x->mpfr, floating_t::s_mpfr_rnd)); CHECK_MPFR(mpfr_cos(tmp->mpfr, y->mpfr, floating_t::s_mpfr_rnd)); CHECK_MPFR(mpfr_mul(re->mpfr, re->mpfr, tmp->mpfr, floating_t::s_mpfr_rnd)); @@ -246,7 +280,7 @@ void rpn_cosh() _calc_stack.pop_back(2); } else - ERR_CONTEXT(ret_bad_operand_type); + ERR_CONTEXT(ret_bad_operand_type); } void rpn_acosh() @@ -254,7 +288,7 @@ void rpn_acosh() MIN_ARGUMENTS(1); if (_stack->get_type(0) == cmd_number) - { + { floating_t* left = &((number*)_stack->get_obj(0))->_value; CHECK_MPFR(mpfr_acosh(left->mpfr, left->mpfr, floating_t::s_mpfr_rnd)); } @@ -275,7 +309,7 @@ void rpn_acosh() rpn_ln(); } else - ERR_CONTEXT(ret_bad_operand_type); + ERR_CONTEXT(ret_bad_operand_type); } void rpn_tanh() @@ -283,7 +317,7 @@ void rpn_tanh() MIN_ARGUMENTS(1); if (_stack->get_type(0) == cmd_number) - { + { floating_t* left = &((number*)_stack->get_obj(0))->_value; CHECK_MPFR(mpfr_tanh(left->mpfr, left->mpfr, floating_t::s_mpfr_rnd)); } @@ -297,7 +331,7 @@ void rpn_tanh() floating_t* re = ((complex*)_stack->get_obj(1))->re(); floating_t* im = ((complex*)_stack->get_obj(1))->im(); - + CHECK_MPFR(mpfr_tanh(re->mpfr, x->mpfr, floating_t::s_mpfr_rnd)); CHECK_MPFR(mpfr_tan(im->mpfr, y->mpfr, floating_t::s_mpfr_rnd)); @@ -308,7 +342,7 @@ void rpn_tanh() rpn_div(); } else - ERR_CONTEXT(ret_bad_operand_type); + ERR_CONTEXT(ret_bad_operand_type); } void rpn_atanh() @@ -316,7 +350,7 @@ void rpn_atanh() MIN_ARGUMENTS(1); if (_stack->get_type(0) == cmd_number) - { + { floating_t* left = &((number*)_stack->get_obj(0))->_value; CHECK_MPFR(mpfr_atanh(left->mpfr, left->mpfr, floating_t::s_mpfr_rnd)); } @@ -339,5 +373,5 @@ void rpn_atanh() rpn_mul(); } else - ERR_CONTEXT(ret_bad_operand_type); + ERR_CONTEXT(ret_bad_operand_type); } diff --git a/test/10-complex.txt b/test/10-complex.txt index 90f486f..b95158f 100644 --- a/test/10-complex.txt +++ b/test/10-complex.txt @@ -53,17 +53,17 @@ del del # sub (1) -(1.2,2.3) (2,2) - +(1.2,2.3) (2,2) - -> stack should be (-0.8,0.3) del # sub (2) -(1.2,2.3) (1,2)- +(1.2,2.3) (1,2)- -> stack should be (0.2,0.3) del # sub (3) -(1.2,2.3) 1- +(1.2,2.3) 1- -> stack should be (0.2,2.3) del @@ -326,7 +326,7 @@ del # sqrt (2) -3 sqrt --> stack should be (-0.000000,1.732051) +-> stack should be (0.000000,1.732051) del # sin (1) @@ -469,6 +469,30 @@ del -> stack should be (0.804719,2.034444) del +# lnp1 (1) +(1,2) lnp1 +(1,2) 1 + ln == +-> stack should be 1.000000 +del + +# lnp1 (2) +(1,-2) lnp1 +(1,-2) 1 + ln == +-> stack should be 1.000000 +del + +# lnp1 (3) +(-1,-2) lnp1 +(-1,-2) 1 + ln == +-> stack should be 1.000000 +del + +# lnp1 (4) +(-1,2) lnp1 +(-1,2) 1 + ln == +-> stack should be 1.000000 +del + # log (1) (1,2) log -> stack should be (0.804719,1.107149) @@ -549,6 +573,30 @@ del -> stack should be (-0.153092,0.334512) del +# expm (1) +(1,2) expm +(1,2) exp 1 - == +-> stack should be 1.000000 +del + +# expm (2) +(1,-2) expm +(1,-2) exp 1 - == +-> stack should be 1.000000 +del + +# expm (3) +(-1,-2) expm +(-1,-2) exp 1 - == +-> stack should be 1.000000 +del + +# expm (4) +(-1,2) expm +(-1,2) exp 1 - == +-> stack should be 1.000000 +del + # alog2 (1) (1,2) alog2 -> stack should be (0.366914,1.966055)