help-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Kludge for handling REPL arithmetic expressions


From: Eric Pruitt
Subject: Re: Kludge for handling REPL arithmetic expressions
Date: Wed, 4 Aug 2021 08:36:41 -0700
User-agent: Mutt/1.10.1 (2018-07-13)

On Wed, Aug 04, 2021 at 11:12:01AM +0100, Chris Elvidge wrote:
> On 03/08/2021 04:32 am, Eric Pruitt wrote:
> > I have a command setup in Bash that allows me to use "=" to do
> > arithmetic in an interactive session:
> > 
> >      ~$ = 1/42 * 9
> >      0.2142857142857143 (3/14)
> >      ~$ = log(2048, 2)
> >      11
> >      ~$ = 1/3 + 7
> >      7.333333333333333 (22/3)
> >      ~$ = x * 3
> >      22
> 
> I was intrigued by this. So tried:
> =() { echo "scale=5; $@" | bc; }
> as an experiment.
> Seems to work for simple calculations.
> 
> A couple of questions, though.
> 1) How do you 'export -f ='? Or is it impossible?
> 2) How do you type in '= log(2048,2)' without getting a syntax error?

You can find my bashrc at
<https://github.com/ericpruitt/emus/blob/master/configuration/bashrc>.
The relevant bits are:

    ...

    BASH_ALIASES[=]='calculate #'

    ...

    # Handler used to intercept arithmetic expressions so they can be
    # entered without having to add a space after the "=".
    #
    function command_not_found_handle()
    {
        if [[ "$1" != =* ]]; then
            printf "%s: command not found\n" "$1" >&2
            return 127
        fi

        eval "= ${1#=} ${@:2}"
    }

    # Handler used to intercept arithmetic expressions so they can be
    # entered without having to add a space after the "=".
    #
    function no_such_file_handle()
    {
        if [[ "$1" != =* ]]; then
            printf "%s: No such file or directory\n" "$1" >&2
            return 127
        fi

        eval "= ${1#=} ${@:2}"
    }

    # Calculate the result of an expression. The result of the last
    # successfully evaluated expression is made available as the
    # variable "x". The expression must appear in the command history to
    # be evaluated.
    #
    function calculate()
    {
        local result

        result="$(
            expression="$(HISTTIMEFORMAT= \history 1)"
            pc "x = $LAST_RESULT" "$(eval "echo \" ${expression#*=}\"")"
        )"

        test -n "$result" && LAST_RESULT="${result#* }" && echo "$result"
    }

The "pc" command is a script I created that uses Python as an
alternative to "bc" which you can find at
<https://github.com/ericpruitt/emus/blob/master/scripts/pc>. The script
represents rational numbers as fractions internally to reduce floating
point errors:

    $ python3 -c "print(1/9 * 7 + 2/9)"
    0.9999999999999999

    $ bc <<< "1/9 * 7 + 2/9"
    .99999999999999999999

    $ pc "1/9 * 7 + 2/9"
    1

Eric



reply via email to

[Prev in Thread] Current Thread [Next in Thread]