From c762c624647f6c188177c79f62608fb844f2ba8f Mon Sep 17 00:00:00 2001 From: Ilan Cosman Date: Sun, 28 Mar 2021 08:58:41 -0700 Subject: [PATCH] Add max and min math functions --- CHANGELOG.rst | 1 + doc_src/cmds/math.rst | 2 ++ src/tinyexpr.cpp | 16 ++++++++++++++++ tests/checks/math.fish | 12 +++++++++--- 4 files changed, 28 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 494581e57..13fc60e05 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -26,6 +26,7 @@ Interactive improvements - Fish now automatically creates ``config.fish`` and the configuration directories in ``$XDG_CONFIG_HOME/fish`` (by default ``~/.config/fish``) if they do not already exist. - ``__fish_prepend_sudo`` now toggles sudo even when it took the commandline from history instead of only adding it. - Fish now defaults job-control to "full" meaning it more sensibly handles assigning the terminal and process groups (:issue:`5036`, :issue:`5832`, :issue:`7721`) +- ``math`` learned two new functions, ``max`` and ``min`. New or improved bindings ^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/doc_src/cmds/math.rst b/doc_src/cmds/math.rst index cb4041c08..44d95d188 100644 --- a/doc_src/cmds/math.rst +++ b/doc_src/cmds/math.rst @@ -88,6 +88,8 @@ Functions - ``ln`` - the base-e logarithm - ``log`` or ``log10`` - the base-10 logarithm - ``log2`` - the base-2 logarithm +- ``max`` - returns the larger of two numbers +- ``min`` - returns the smaller of two numbers - ``ncr`` - "from n choose r" combination function - how many subsets of size r can be taken from n (order doesn't matter) - ``npr`` - the number of subsets of size r that can be taken from a set of n elements (including different order) - ``pow(x,y)`` returns x to the y (and can be written as ``x ^ y``) diff --git a/src/tinyexpr.cpp b/src/tinyexpr.cpp index 19e5501be..0898f22c9 100644 --- a/src/tinyexpr.cpp +++ b/src/tinyexpr.cpp @@ -182,6 +182,20 @@ static constexpr double bit_xor(double a, double b) { return static_cast(static_cast(a) ^ static_cast(b)); } +static double max(double a, double b) { + if (isnan(a)) return a; + if (isnan(b)) return b; + if (a == b) return signbit(a) ? b : a; // treat +0 as larger than -0 + return a > b ? a : b; +} + +static double min(double a, double b) { + if (isnan(a)) return a; + if (isnan(b)) return b; + if (a == b) return signbit(a) ? a : b; // treat -0 as smaller than +0 + return a < b ? a : b; +} + static const te_builtin functions[] = { /* must be in alphabetical order */ {L"abs", reinterpret_cast(static_cast(fabs)), TE_FUNCTION1}, @@ -203,6 +217,8 @@ static const te_builtin functions[] = { {L"log", reinterpret_cast(static_cast(log10)), TE_FUNCTION1}, {L"log10", reinterpret_cast(static_cast(log10)), TE_FUNCTION1}, {L"log2", reinterpret_cast(static_cast(log2)), TE_FUNCTION1}, + {L"max", reinterpret_cast(static_cast(max)), TE_FUNCTION2}, + {L"min", reinterpret_cast(static_cast(min)), TE_FUNCTION2}, {L"ncr", reinterpret_cast(static_cast(ncr)), TE_FUNCTION2}, {L"npr", reinterpret_cast(static_cast(npr)), TE_FUNCTION2}, {L"pi", reinterpret_cast(static_cast(pi)), TE_FUNCTION0}, diff --git a/tests/checks/math.fish b/tests/checks/math.fish index 2a410cbc6..294dc71d2 100644 --- a/tests/checks/math.fish +++ b/tests/checks/math.fish @@ -33,6 +33,12 @@ math -- -4 / 2 math -- '-4 * 2' # CHECK: -8 +# Validate max and min +math 'max(1,2)' +math 'min(1,2)' +# CHECK: 2 +# CHECK: 1 + # Validate some rounding functions math 'round(3/2)' math 'floor(3/2)' @@ -100,10 +106,10 @@ not math 'ncr(1)' # CHECKERR: 'ncr(1)' # CHECKERR: ^ -# There is no "max" function. -not math 'max()' +# There is no "blah" function. +not math 'blah()' # CHECKERR: math: Error: Unknown function -# CHECKERR: 'max()' +# CHECKERR: 'blah()' # CHECKERR: ^ math n + 4