Add cube root and a few other functions

This commit is contained in:
lemon-sh 2021-11-17 20:31:32 +01:00
parent db9c2922db
commit 2ccfe5f374
5 changed files with 74 additions and 66 deletions

View File

@ -21,16 +21,17 @@ Explaination:
You can enter the Fn mode by tapping the Fn key (see keymap above).
```
+-----+-----+-----+-----+-----+
| sqr | abs | | | clr |
| sqr | abs | cbr | | clr |
+-----+-----+-----+-----+-----+
| sin | cos | tan | | |
+-----+-----+-----+-----+-----+
| pi | | x | ( | ) |
| pi | e | x | ( | ) |
+-----+-----+-----+-----+-----+
| | | | ^ | |
| flo | cei | log | ^ | |
+-----+-----+-----+-----+-----+
```
Explaination:
* `x`: last calculation result.
* `sqr`: square root
* `clr`: clear input box
* `cbr`: cubic root
* `clr`: clear input box

View File

@ -19,9 +19,9 @@ namespace App
// operators
add, sub, mul, div, pow,
// functions
sqrt, abs, sin, cos, tan,
sqrt, cbrt, floor, ceil, log, abs, sin, cos, tan,
// special
dot, parbeg, parend, pi, x
dot, parbeg, parend, pi, e, x
};
void init();

View File

@ -111,13 +111,13 @@ namespace App
te_free(expr);
slavebuf[0] = '=';
slavebuf[1] = ' ';
if (isnan(evalout)) {
if (fp64_isnan(evalout)) {
cursoroffset = terr-1;
int snsize = snprintf_P(slavebuf+2, 15, nanerr, terr);
if (snsize < 14) {
memset(slavebuf+snsize+2, ' ', 14-snsize);
}
} else if (isinf(evalout)) {
} else if (fp64_isinf(evalout)) {
memcpy_P(slavebuf+2, inferr, 14);
} else {
char* result = fp64_to_string(evalout, 14, 6);
@ -172,11 +172,16 @@ namespace App
case InputType::clr: clearmaster(); break;
case InputType::sqrt: insert_cursor("sqrt()", 1); break;
case InputType::cbrt: insert_cursor("cbrt()", 1); break;
case InputType::abs: insert_cursor("abs()", 1); break;
case InputType::sin: insert_cursor("sin()", 1); break;
case InputType::cos: insert_cursor("cos()", 1); break;
case InputType::tan: insert_cursor("tan()", 1); break;
case InputType::log: insert_cursor("log()", 1); break;
case InputType::ceil: insert_cursor("ceil()", 1); break;
case InputType::floor: insert_cursor("floor()", 1); break;
case InputType::pi: insert_cursor("pi", 0); break;
case InputType::e: insert_cursor("e", 0); break;
}
}
}

View File

@ -28,17 +28,23 @@ void loop() {
char key = keypad.waitForKey();
if (fnmode) {
switch(key) {
case '0': App::input(App::InputType::floor); break;
case 'X': App::input(App::InputType::ceil); break;
case 'Z': App::input(App::InputType::log); break;
case '1': App::input(App::InputType::pi); break;
case '2': App::input(App::InputType::e); break;
case '3': App::input(App::InputType::x); break;
case '4': App::input(App::InputType::sin); break;
case '5': App::input(App::InputType::cos); break;
case '6': App::input(App::InputType::tan); break;
case '7': App::input(App::InputType::sqrt); break;
case '8': App::input(App::InputType::abs); break;
case '9': App::input(App::InputType::cbrt); break;
case 'B': App::input(App::InputType::clr); break;
case 'E': App::input(App::InputType::parbeg); break;
case 'F': App::input(App::InputType::parend); break;
case 'G': App::input(App::InputType::pow); break;
case '7': App::input(App::InputType::sqrt); break;
case '8': App::input(App::InputType::abs); break;
case '6': App::input(App::InputType::tan); break;
case '5': App::input(App::InputType::cos); break;
case '4': App::input(App::InputType::sin); break;
case '1': App::input(App::InputType::pi); break;
case 'B': App::input(App::InputType::clr); break;
case '3': App::input(App::InputType::x); break;
}
fnmode = 0;
} else switch(key) {

View File

@ -24,10 +24,6 @@
* 3. This notice may not be removed or altered from any source distribution.
*/
// For log = base 10 log do nothing
// For log = natural log uncomment the next line.
//#define TE_NAT_LOG
#include "tinyexpr.h"
#include <stdlib.h>
#include <string.h>
@ -102,66 +98,66 @@ void te_free(te_expr *n) {
static float64_t pi(void) {return float64_NUMBER_PI;}
static float64_t e(void) {return float64_EULER_E;}
static float64_t fac(float64_t a) {/* simplest version of fac */
if (a < 0.0)
return float64_ONE_POSSIBLE_NAN_REPRESENTATION;
if (a > UINT_MAX)
return float64_PLUS_INFINITY;
unsigned int ua = fp64_to_uint16(a);
unsigned long int result = 1, i;
for (i = 1; i <= ua; i++) {
if (i > ULONG_MAX / result)
return float64_PLUS_INFINITY;
result *= i;
}
return fp64_uint32_to_float64(result);
}
static float64_t ncr(float64_t n, float64_t r) {
if (fp64_compare(n, float64_NUMBER_PLUS_ZERO) == -1 || fp64_compare(r, float64_NUMBER_PLUS_ZERO) == -1 || fp64_compare(n, r) == -1) return float64_ONE_POSSIBLE_NAN_REPRESENTATION;
if (fp64_compare(n, fp64_uint16_to_float64(UINT_MAX)) == 1 || fp64_compare(r, fp64_uint16_to_float64(UINT_MAX)) == 1) return float64_PLUS_INFINITY;
unsigned long int un = fp64_to_uint16(n), ur = fp64_to_uint16(r), i;
unsigned long int result = 1;
if (ur > un / 2) ur = un - ur;
for (i = 1; i <= ur; i++) {
if (result > ULONG_MAX / (un - ur + i))
return float64_PLUS_INFINITY;
result *= un - ur + i;
result /= i;
}
return result;
}
static float64_t npr(float64_t n, float64_t r) {return fp64_mul(ncr(n, r), fac(r));}
// commented out functions are for later implementation
// static float64_t fac(float64_t a) {/* simplest version of fac */
// if (a < 0.0)
// return float64_ONE_POSSIBLE_NAN_REPRESENTATION;
// if (a > UINT_MAX)
// return float64_PLUS_INFINITY;
// unsigned int ua = fp64_to_uint16(a);
// unsigned long int result = 1, i;
// for (i = 1; i <= ua; i++) {
// if (i > ULONG_MAX / result)
// return float64_PLUS_INFINITY;
// result *= i;
// }
// return fp64_uint32_to_float64(result);
// }
// static float64_t ncr(float64_t n, float64_t r) {
// if (fp64_compare(n, float64_NUMBER_PLUS_ZERO) == -1 || fp64_compare(r, float64_NUMBER_PLUS_ZERO) == -1 || fp64_compare(n, r) == -1) return float64_ONE_POSSIBLE_NAN_REPRESENTATION;
// if (fp64_compare(n, fp64_uint16_to_float64(UINT_MAX)) == 1 || fp64_compare(r, fp64_uint16_to_float64(UINT_MAX)) == 1) return float64_PLUS_INFINITY;
// unsigned long int un = fp64_to_uint16(n), ur = fp64_to_uint16(r), i;
// unsigned long int result = 1;
// if (ur > un / 2) ur = un - ur;
// for (i = 1; i <= ur; i++) {
// if (result > ULONG_MAX / (un - ur + i))
// return float64_PLUS_INFINITY;
// result *= un - ur + i;
// result /= i;
// }
// return result;
// }
// static float64_t npr(float64_t n, float64_t r) {return fp64_mul(ncr(n, r), fac(r));}
static const te_variable functions[] = {
/* must be in alphabetical order */
{"abs", fp64_abs, TE_FUNCTION1 | TE_FLAG_PURE, 0},
{"acos", fp64_acos, TE_FUNCTION1 | TE_FLAG_PURE, 0},
{"asin", fp64_asin, TE_FUNCTION1 | TE_FLAG_PURE, 0},
{"atan", fp64_atan, TE_FUNCTION1 | TE_FLAG_PURE, 0},
{"atan2", fp64_atan2, TE_FUNCTION2 | TE_FLAG_PURE, 0},
// {"acos", fp64_acos, TE_FUNCTION1 | TE_FLAG_PURE, 0},
// {"asin", fp64_asin, TE_FUNCTION1 | TE_FLAG_PURE, 0},
// {"atan", fp64_atan, TE_FUNCTION1 | TE_FLAG_PURE, 0},
// {"atan2", fp64_atan2, TE_FUNCTION2 | TE_FLAG_PURE, 0},
{"cbrt", fp64_cbrt, TE_FUNCTION1 | TE_FLAG_PURE, 0},
{"ceil", fp64_ceil, TE_FUNCTION1 | TE_FLAG_PURE, 0},
{"cos", fp64_cos, TE_FUNCTION1 | TE_FLAG_PURE, 0},
{"cosh", fp64_cosh, TE_FUNCTION1 | TE_FLAG_PURE, 0},
// {"cosh", fp64_cosh, TE_FUNCTION1 | TE_FLAG_PURE, 0},
{"e", e, TE_FUNCTION0 | TE_FLAG_PURE, 0},
{"exp", fp64_exp, TE_FUNCTION1 | TE_FLAG_PURE, 0},
{"fac", fac, TE_FUNCTION1 | TE_FLAG_PURE, 0},
//{"exp", fp64_exp, TE_FUNCTION1 | TE_FLAG_PURE, 0},
//{"fac", fac, TE_FUNCTION1 | TE_FLAG_PURE, 0},
{"floor", fp64_floor, TE_FUNCTION1 | TE_FLAG_PURE, 0},
{"ln", fp64_log, TE_FUNCTION1 | TE_FLAG_PURE, 0},
#ifdef TE_NAT_LOG
{"log", fp64_log, TE_FUNCTION1 | TE_FLAG_PURE, 0},
#else
//{"ln", fp64_log, TE_FUNCTION1 | TE_FLAG_PURE, 0},
{"log", fp64_log10, TE_FUNCTION1 | TE_FLAG_PURE, 0},
#endif
{"log10", fp64_log10, TE_FUNCTION1 | TE_FLAG_PURE, 0},
{"ncr", ncr, TE_FUNCTION2 | TE_FLAG_PURE, 0},
{"npr", npr, TE_FUNCTION2 | TE_FLAG_PURE, 0},
// {"ncr", ncr, TE_FUNCTION2 | TE_FLAG_PURE, 0},
// {"npr", npr, TE_FUNCTION2 | TE_FLAG_PURE, 0},
{"pi", pi, TE_FUNCTION0 | TE_FLAG_PURE, 0},
{"pow", fp64_pow, TE_FUNCTION2 | TE_FLAG_PURE, 0},
{"sin", fp64_sin, TE_FUNCTION1 | TE_FLAG_PURE, 0},
{"sinh", fp64_sinh, TE_FUNCTION1 | TE_FLAG_PURE, 0},
// {"sinh", fp64_sinh, TE_FUNCTION1 | TE_FLAG_PURE, 0},
{"sqrt", fp64_sqrt, TE_FUNCTION1 | TE_FLAG_PURE, 0},
{"tan", fp64_tan, TE_FUNCTION1 | TE_FLAG_PURE, 0},
{"tanh", fp64_tanh, TE_FUNCTION1 | TE_FLAG_PURE, 0},
// {"tanh", fp64_tanh, TE_FUNCTION1 | TE_FLAG_PURE, 0},
{0, 0, 0, 0}
};