tec - Tiny Expression Calculator

Moderator: Forum moderators

Post Reply
Burunduk
Posts: 249
Joined: Thu Jun 16, 2022 6:16 pm
Has thanked: 7 times
Been thanked: 124 times

tec - Tiny Expression Calculator

Post by Burunduk »

tec - Tiny Expression Calculator

Evaluate floating-point expressions.

version 0.1.1

This is a simple command line tool for comparing double precision floating-point numbers and evaluating floating-point expressions.
It is similar to the expr utility (but it cannot compare strings).
It is mainly intended to be used in bash scripts instead of bc - its syntax is simpler and more suitable for bash test constructs.
It also can be used as a calculator in the terminal or in the geany lua plugin (the lua script is included). It has many math functions available OOTB.

The program comes without any warranty.

It's more like an exercise in C.
An interesting small program for comparing float numbers created by @Jafadmin always returned 0 regardless of test results,
so I decided to write a tool that would return 1 when a test fails. Of course, my poor C programming skills wouldn't allow this,
but all the hard work is done by an external library, my program is just a simple wrapper around it.

The Library

The library is TinyExpr from https://github.com/codeplea/tinyexpr

Best thanks to its author and contributors!

The version used is from the "logic" branch and it's outdated - newer versions have no comparison operators. I've made the following modifications:

  • changed precedence of comparison and logical operators to conform to C

  • added operator mnemonics and square brackets for easier use in shell command line

  • added an approximate equality operator '?=' (works as math.isclose() in Python)

  • added max and min functions because fmax and fmin are not available with -ansi

  • changed precedence of the power operator to conform to Python and other languages

  • added '**' alias for the power operator

  • redefined combinatorics functions to use lgamma

  • added a tiny lgamma definition (the stock lgamma is not available with -ansi)

  • added rad and deg functions to convert between radians and degrees

  • leading and trailing parentheses made optional

  • implicit multiplication operator is assumed in certain positions

Changes

0.1.1

  • fixed power operator and unary function relative precedence

  • added a manual page

Usage

tec [OPTION | FORMAT] [EXPRESSION]

--help, -h show help message and exit
--version show version information and exit
-q do not output result
-s do not output result and error messages

FORMAT is a single floating-point number format specification for the result as in printf,
e.g. %15.5f where 15 - optional min width, .5 - optional precision, f - fixed point (supported formats: f g G e E),
%i is an alias for %.0f. Default format is %g.

EXPRESSION may contain:

  • standard C math operators (except bitwise) and a left-associative exponentiation operator ^ or **
    (it's right-associative if TE_POW_FROM_RIGHT is defined before compilation)

  • comparison and logical operators: >, >=, <, <=, ==, !=, &&, ||, !

  • an approximate equality operator ?= (~= and =~ are already used by many languages and have a different meaning there)

  • standard C math functions: abs, acos, asin, atan, atan2, ceil, cos, cosh, exp, floor, log10, max, min, pow, sin, sinh, sqrt, tan, tanh;
    ln is C log, log is C log10 (it's C log if TE_NAT_LOG is defined before compilation)

  • combinaiorics functions fac, ncr, npr (defined using lgamma)

  • lgamma (that has a tiny home-grown definition based on a simple approximation formula from wikipedia,
    the stock lgamma is used if TE_LIBM_LGAMMA is defined and the program compiled without -ansi flag)

  • conversion functions rad and deg

  • constants pi and e

  • mnemonics: add, sub, mul, div, mod, gt, ge, lt, le, eq, ne, ae (almost equal), and, or, not

  • [ ] can be used interchangeably besides ( )

Special shell characters (* & | ( ) < > !) need to be quoted or escaped,
while [ ] are special too, they usually can be used without quotes (if separated by a space).
I don't really understand what is the problem with the shell quoting and how the mnemonics can be useful, but they are here if someone needs them.
The arithmetic operator mnemonics are from the old busybox dc and assembler languages (and not from Algol68!).

Leading and trailing brackets can be omitted, an implicit multiplication operator is assumed between bracketed sub-expressions.
E.g. tec '(2 * pi * sqrt (2) - 0.5) * (10 - 3 * sin(5))' can be written in a shorter form: tec '2pi sqrt 2 - .5)(10 - 3sin 5'.

Only one expression is allowed. It should be short, less than 10k characters (this limit is defined in tec.c and can be increased if necessary).
Multiple arguments are concatenated.

EXIT CODES: 0 if result != 0, 1 if result == 0, 2 on error, 3 if NaN or Inf.
The exit code is set accordingly to the formatted result, e.g. tec 0.01 exits with 0 but tec %.1f 0.01 exits with 1
because the result is rounded to 0 by the specified format.

Examples

  • tec '100 * 5' -> 500

  • echo '5 / 100' | tec %f -> 0.0500000

  • tec -q '.1234 < 5.6789' && echo yes || echo no -> yes

  • tec -q '3 * 1.1 ?= 3.3' && echo yes || echo no -> yes

  • tec '6)7' -> 42

See additional examples in the next post.

The Package

The pet contains a static 64-bit binary compiled against musl. It should work on any amd64 puppy.

Attachments
tec-0.1.1_amd64.pet
Tested on Fossapup64-9.5 and S15Pup64
(53.97 KiB) Downloaded 20 times
Last edited by Burunduk on Sun Jul 16, 2023 8:57 pm, edited 1 time in total.
Burunduk
Posts: 249
Joined: Thu Jun 16, 2022 6:16 pm
Has thanked: 7 times
Been thanked: 124 times

Re: tec - Tiny Expression Calculator

Post by Burunduk »

Additional Usage Examples

Bash conditional constructs

  • if statement:

    Code: Select all

    var1=0.12345
    var2=0.6789
    if tec -q "$var1 < $var2"; then
      echo true
    fi

    -> true

  • control operators: tec -q '2/3 > 3/4' && echo true || echo false -> false

Inexact representation problem

Floating-point numbers are not always represented exactly: tec '3 * 1.1 == 3.3' -> 0 (not equal)
because there is a small difference here: tec %.3e '3 * 1.1 - 3.3' -> 4.441e-16.
To work around this an "almost equal" operator can be used: tec '3 * 1.1 ?= 3.3' -> 1 (almost equal)

Unquoted expressions

  • tec [ 2 add 3 ] 4 -> 20

  • tec 2 add 3 mul 4 -> 14

  • tec 5 gt 6 -> 0

Syntax peculiarities

  • left-associative exponentiation: tec '2^3^2' -> 64

  • unmatched brackets and implicit multiplication operators: tec 7 [ 8 [ 9 -> 504 (it stands for 7 * (8 * (9)))

  • rounding to the nearest integer: tec %i exp 5 -> 148

Using the geany lua plugin

To replace an expression in the edited text file with its calculated result:

  • select the expression

  • click: geany menu -> tools -> lua scripts -> edit -> tec calculator

Creating a Custom Function Definition (in C)

A custom function definition can be easily added to the program. Functions are defined in the tinyexpr.c file. They can accept up to 7 double float type arguments and return a double float too. For example, insert this definition of a function that converts temperature from F° to C° and add a line to the functions array in alphabetical order:

Code: Select all

/* right before the functions array is a good place */
static double tempftoc(double a) {
  if (a < -459.67) return NAN;
  double res;
  res =  (a - 32) / 1.8;
  return res;
}
/* maybe this function is useful too */
static double tempctof(double a) { return a < -273.15 ? NAN : a * 1.8 + 32; }

static const te_variable functions[] = {
  /* must be in alphabetical order */
  ...
  {"tanh", tanh,    TE_FUNCTION1 | TE_FLAG_PURE, 0},
  {"tempc", tempftoc, TE_FUNCTION1 | TE_FLAG_PURE, 0},
  {"tempf", tempctof, TE_FUNCTION1 | TE_FLAG_PURE, 0},
  {0, 0, 0, 0}
};

That's it. Save the file and recompile the program. Tec now can do the conversion: tec tempc 100 -> 37.7778

Compiling

Unpack the source archive, copy the appropriate gcc command from the justfile and run it in the terminal.
The musl C library is not required.

Burunduk
Posts: 249
Joined: Thu Jun 16, 2022 6:16 pm
Has thanked: 7 times
Been thanked: 124 times

Re: tec - Tiny Expression Calculator

Post by Burunduk »

tec version 0.1.1

Fixed a bug introduced by the power operator precedence change.
Added a manual page.

The pet package is attached to the first post.

Post Reply

Return to “Utilities”