diff --git a/README.md b/README.md index af172ae..2bcbaa3 100644 --- a/README.md +++ b/README.md @@ -10,12 +10,11 @@ Quick examples: - easy calculation with **stacked results** ``` -rpn> 1 exp 3 * -8.1548454853771357061 +rpn> 1 2 + +3 rpn> 2 sqrt -2> 8.1548454853771357061 +2> 3 1> 1.4142135623730950488 -rpn> ``` - **programs** and **variables**, eg same example as in HP28S Quick Reference: @@ -67,8 +66,6 @@ rpn> |uname | show rpn complete identification string |type | show type of stack first entry |default | set float representation and precision to default -|prec | get float precision in bits when first stack is not a number, set float precision in bits when first stack entry is a number. ex: ```256 prec``` -|round| set float rounding mode. Authoerized values are: ```["nearest", "toward zero", "toward +inf", "toward -inf", "away from zero"] round```. ex: ```"nearest" round``` #### real @@ -87,14 +84,17 @@ rpn> |sq| (or sqr) square |mod| modulo |abs| absolute value +|dec| decimal representation +|hex| hexadecimal representation +|prec | get float precision in bits when first stack is not a number, set float precision in bits when first stack entry is a number. ex: ```256 prec``` +|round| set float rounding mode. Authoerized values are: ```["nearest", "toward zero", "toward +inf", "toward -inf", "away from zero"] round```. ex: ```"nearest" round``` +|fact| n! for integer n or Gamma(x+1) for fractional x +|sign| 1 if number at stack level 1 is > 0, 0 if == 0, -1 if <= 0 -#### real representation +#### mode |keyword|description| |-|-| -|dec| decimal representation -|hex| hexadecimal representation -|bin| binary representation |std| standard floating numbers representation. ex: [25] std |fix| fixed point representation. ex: 6 fix |sci| scientific floating point representation. ex: 20 sci diff --git a/src/program.cpp b/src/program.cpp index ce9521f..b95f27f 100644 --- a/src/program.cpp +++ b/src/program.cpp @@ -50,6 +50,8 @@ program::keyword_t program::s_keywords[] = { cmd_keyword, "prec", &program::precision, "get float precision in bits when first stack is not a number\n\t" "set float precision in bits when first stack entry is a number. ex: 256 prec" }, { cmd_keyword, "round", &program::round, "set float rounding mode.\n\tex: [\"nearest\", \"toward zero\", \"toward +inf\", \"toward -inf\", \"away from zero\"] round" }, + { cmd_keyword, "fact", &program::fact, "n! for integer n or Gamma(x+1) for fractional x" }, + { cmd_keyword, "sign", &program::sign, "1 if number at stack level 1 is > 0, 0 if == 0, -1 if <= 0" }, //TEST { cmd_undef, "", NULL, "\nTEST"}, diff --git a/src/rpn-real.hpp b/src/rpn-real.hpp index 2d87a5b..fc33f9d 100644 --- a/src/rpn-real.hpp +++ b/src/rpn-real.hpp @@ -150,3 +150,28 @@ void dec() ARG_MUST_BE_OF_TYPE(0, cmd_number); ((number*)_stack->back())->_representation = number::dec; } + +void fact() +{ + MIN_ARGUMENTS(1); + ARG_MUST_BE_OF_TYPE(0, cmd_number); + + // fact(n) = gamma(n+1) + number* left = (number*)_stack->back(); + number* right = (number*)_stack->allocate_back(number::calc_size(), cmd_number); + right->_value = 1L; + plus(); + + CHECK_MPFR(mpfr_gamma(left->_value.mpfr, left->_value.mpfr, floating_t::s_mpfr_rnd)); +} + +void sign() +{ + MIN_ARGUMENTS(1); + ARG_MUST_BE_OF_TYPE(0, cmd_number); + + // fact(n) = gamma(n+1) + number* left = (number*)_stack->back(); + int result = mpfr_sgn(left->_value.mpfr); + left->_value = (long)result; +} diff --git a/test/06-real.txt b/test/06-real.txt index d241f42..7e9e5ed 100644 --- a/test/06-real.txt +++ b/test/06-real.txt @@ -332,4 +332,30 @@ abs -> error should be 2 erase +# fact (1) +6 fact +-> stack should be 720 +erase + +# fact (2) +'r' fact +-> error should be 3 +-> stack size should be 1 +erase + +# fact (3) +fact +-> error should be 2 +erase + +# sign (1) +23 sign -34 sign 0 sign +-> stack should be 1, -1, 0 +erase + +# sign (2) +sign +-> error should be 2 +erase + default