• handy shell function/alias that wraps bc

    From Michael Sanders@porkchop@invalid.foo to comp.unix.shell on Fri Oct 31 06:32:18 2025
    From Newsgroup: comp.unix.shell

    #!/bin/sh

    <<'NOTES'

    handy shell function/alias that wraps bc
    tested & working with bash, busybox ash

    Michael Sanders 2025

    usage example: exp 5*2-1

    NOTES

    exp() {
    s=3 # optional scale
    e=$(printf '%s' "$*" | tr -d '[:space:]') # compress
    [ -z "$e" ] && { echo "usage: exp <expression>"; return 1; }

    # short-circuit invalid characters
    echo "$e" | grep -Eq '^[0-9+*/().^-]+$' || \
    { echo "invalid expression"; return 1; }

    # evaluate with bc -l
    r=$(echo "scale=$s; $e" | bc -l 2>/dev/null) \
    && [ -n "$r" ] && printf "%.*f\n" "$s" "$r" \
    || { echo "invalid expression"; return 1; }
    }

    # test cases: expression|expected output
    tests="
    1+2|3.000
    7-4|3.000
    5*6|30.000
    8/2|4.000
    1+2*3|7.000
    10-2*3|4.000
    10/2+4*3|17.000
    10/2*3+5|20.000
    (1+2)*3|9.000
    (10-2)/4|2.000
    100-(20+5)*2|50.000
    5*(3+(2*2))|35.000
    -3+2|-1.000
    2*-5|-10.000
    -(4+1)*2|-10.000
    -(2*-5)|10.000
    -(-3)|3.000
    2*(3+4*5)-10/2|41.000
    (1+2)*(3+4)|21.000
    ((2+3)*4)-5|15.000
    3*(2+(4*(1+1)))|30.000
    ((1+2)*3-(4/2))*5|35.000
    0|0.000
    0-0|0.000
    10/3|3.333
    3.5*2|7.000
    -3.5+1.5|-2.000
    1+2|3.000
    7-4|3.000
    5*6|30.000
    8/2|4.000
    2^3|8.000
    3^4|81.000
    (2+3)^2|25.000
    4^(1+1)|16.000
    -2^3|-8.000
    1+2*foo|invalid expression
    12+%|invalid expression
    |usage: exp <expression>
    "

    # print CSV header
    echo "Input|Expected|Actual|Pass"

    IFS='
    '
    for t in $tests; do
    str=$(echo "$t" | cut -d'|' -f1)
    expected=$(echo "$t" | cut -d'|' -f2)
    actual=$(exp "$str")
    [ "$actual" = "$expected" ] && pass="YES" || pass="NO"
    echo "$str|$expected|$actual|$pass"
    done

    # eof
    --
    :wq
    Mike Sanders
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.unix.shell on Fri Oct 31 06:38:34 2025
    From Newsgroup: comp.unix.shell

    On Fri, 31 Oct 2025 06:32:18 -0000 (UTC), Michael Sanders wrote:

    usage example: exp 5*2-1

    ldo@theon:~> bc <<<'5*2-1'
    9

    DonrCOt need a whole script to save a few characters of typing ...
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Janis Papanagnou@janis_papanagnou+ng@hotmail.com to comp.unix.shell on Fri Oct 31 10:38:15 2025
    From Newsgroup: comp.unix.shell

    Your script looks quite complicated and hard to read. Quite some shell
    commands used just ask for replacement (say, by Awk for example) to
    make that simpler and (re: Subject) more "handy".

    With GNU Awk (and co-process support) it might get yet even simpler.

    Unfortunately I cannot test that since my 'bc' strangely doesn't react
    on scale=3 but the idea is something along the lines of [untested; may
    require tweaks]...

    awk '
    BEGIN { FS = OFS = "|" ; bc = "bc -ql" }
    { print $1 |& bc }
    $2 { bc |& getline res
    print $0, res, (res == $2) ? "YES" : "NO" }
    '

    with input like
    scale=3|
    1+2|3.000
    7-4|3.000
    ...

    (Note that the scale should be coupled with the data, not hard-coded,
    if you want to compare exact strings and not just the numeric values.)

    Just an idea.

    Janis


    On 31.10.2025 07:32, Michael Sanders wrote:
    #!/bin/sh

    <<'NOTES'

    handy shell function/alias that wraps bc
    tested & working with bash, busybox ash

    Michael Sanders 2025

    usage example: exp 5*2-1

    NOTES

    exp() {
    s=3 # optional scale
    e=$(printf '%s' "$*" | tr -d '[:space:]') # compress
    [ -z "$e" ] && { echo "usage: exp <expression>"; return 1; }

    # short-circuit invalid characters
    echo "$e" | grep -Eq '^[0-9+*/().^-]+$' || \
    { echo "invalid expression"; return 1; }

    # evaluate with bc -l
    r=$(echo "scale=$s; $e" | bc -l 2>/dev/null) \
    && [ -n "$r" ] && printf "%.*f\n" "$s" "$r" \
    || { echo "invalid expression"; return 1; }
    }

    # test cases: expression|expected output
    tests="
    1+2|3.000
    7-4|3.000
    5*6|30.000
    8/2|4.000
    1+2*3|7.000
    10-2*3|4.000
    10/2+4*3|17.000
    10/2*3+5|20.000
    (1+2)*3|9.000
    (10-2)/4|2.000
    100-(20+5)*2|50.000
    5*(3+(2*2))|35.000
    -3+2|-1.000
    2*-5|-10.000
    -(4+1)*2|-10.000
    -(2*-5)|10.000
    -(-3)|3.000
    2*(3+4*5)-10/2|41.000
    (1+2)*(3+4)|21.000
    ((2+3)*4)-5|15.000
    3*(2+(4*(1+1)))|30.000
    ((1+2)*3-(4/2))*5|35.000
    0|0.000
    0-0|0.000
    10/3|3.333
    3.5*2|7.000
    -3.5+1.5|-2.000
    1+2|3.000
    7-4|3.000
    5*6|30.000
    8/2|4.000
    2^3|8.000
    3^4|81.000
    (2+3)^2|25.000
    4^(1+1)|16.000
    -2^3|-8.000
    1+2*foo|invalid expression
    12+%|invalid expression
    |usage: exp <expression>
    "

    # print CSV header
    echo "Input|Expected|Actual|Pass"

    IFS='
    '
    for t in $tests; do
    str=$(echo "$t" | cut -d'|' -f1)
    expected=$(echo "$t" | cut -d'|' -f2)
    actual=$(exp "$str")
    [ "$actual" = "$expected" ] && pass="YES" || pass="NO"
    echo "$str|$expected|$actual|$pass"
    done

    # eof


    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From gazelle@gazelle@shell.xmission.com (Kenny McCormack) to comp.unix.shell on Fri Oct 31 10:16:26 2025
    From Newsgroup: comp.unix.shell

    In article <10e1lha$8tbu$1@dont-email.me>,
    Lawrence DOliveiro <ldo@nz.invalid> wrote:
    On Fri, 31 Oct 2025 06:32:18 -0000 (UTC), Michael Sanders wrote:

    usage example: exp 5*2-1

    ldo@theon:~> bc <<<'5*2-1'
    9

    Dont need a whole script to save a few characters of typing ...

    Well, then, you should have just clicked "Next" and moved along.

    No point in your telling us that you don't need it.

    Anyway, I just use the following little script, called "iPerl":

    --- Cut Here ---
    #!/usr/bin/perl
    print ":-) ";
    while (<>) { print eval; print ( ($@ || "\n") . ":-) " ) }
    --- Cut Here ---

    Note that you can't do this directly in AWK, b/c AWK (*) doesn't have "eval".

    (*) Yes, not even TAWK has eval.

    Note also that you can wrap the above script in something like "rlwrap" (or similar) to get keyboard scrolling, which is nice to have.
    --
    I shot a man on Fifth Aveneue, just to see him die.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From gazelle@gazelle@shell.xmission.com (Kenny McCormack) to comp.unix.shell on Fri Oct 31 12:39:27 2025
    From Newsgroup: comp.unix.shell

    In article <10e2029$cc2l$1@dont-email.me>,
    Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:
    Your script looks quite complicated and hard to read. Quite some shell >commands used just ask for replacement (say, by Awk for example) to
    make that simpler and (re: Subject) more "handy".

    With GNU Awk (and co-process support) it might get yet even simpler.

    A couple of other things to note:

    1) One problem with Mike's general approach, which I think we've all
    hit at some point in our respective shell journeys, is that you end up
    running and exiting 'bc' each time you invoke the
    macro/alias/function/whatever. You thus lose any context you may have
    built up in 'bc' - starting from scratch each time. So, ...

    Before there was 'fltexpr' (see below), in one of my scripts that
    needed floating point math, I constructed a system where 'bc' was run
    as a bash co-process. This worked well, since 'bc' gets run just once,
    saving on process startup/exit cycles and also preserving context.

    2) bash now has a loadable module called 'fltexpr' that evaluates
    floating point expressions - much like $(( ... )) already does with
    integer expressions. I haven't used this loadable much, because the
    need just hasn't arisen, but the concept looks interesting (and long
    overdue).

    BTW, I understand that this loadable isn't needed in ksh, 'cause ksh
    already does floating point. I never understood why bash didn't follow
    ksh's lead and do likewise (until very recently...)
    --
    Trump has normalized hate.

    The media has normalized Trump.

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Geoff Clare@geoff@clare.See-My-Signature.invalid to comp.unix.shell on Fri Oct 31 13:16:58 2025
    From Newsgroup: comp.unix.shell

    Lawrence DrCOOliveiro wrote:

    ldo@theon:~> bc <<<'5*2-1'
    9

    DonrCOt need a whole script to save a few characters of typing ...

    That's *more* typing than just using bc interactively.

    Your command is 14 characters (including CR to enter the command).

    Interactive bc would be 10: b c CR 5 * 2 - 1 CR Ctrl-D
    --
    Geoff Clare <netnews@gclare.org.uk>
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Christian Weisgerber@naddy@mips.inka.de to comp.unix.shell on Fri Oct 31 14:56:02 2025
    From Newsgroup: comp.unix.shell

    On 2025-10-31, Michael Sanders <porkchop@invalid.foo> wrote:

    # short-circuit invalid characters
    echo "$e" | grep -Eq '^[0-9+*/().^-]+$' || \
    { echo "invalid expression"; return 1; }

    # evaluate with bc -l
    r=$(echo "scale=$s; $e" | bc -l 2>/dev/null) \

    Why use -l if you disallow the functions it includes?
    --
    Christian "naddy" Weisgerber naddy@mips.inka.de
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Michael Sanders@porkchop@invalid.foo to comp.unix.shell on Fri Oct 31 15:31:20 2025
    From Newsgroup: comp.unix.shell

    On Fri, 31 Oct 2025 06:38:34 -0000 (UTC), Lawrence DrCOOliveiro wrote:

    ldo@theon:~> bc <<<'5*2-1'
    9

    DonrCOt need a whole script to save a few characters of typing ...

    And requires bash... c'mon.
    --
    :wq
    Mike Sanders
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Michael Sanders@porkchop@invalid.foo to comp.unix.shell on Fri Oct 31 15:49:45 2025
    From Newsgroup: comp.unix.shell

    On Fri, 31 Oct 2025 10:16:26 -0000 (UTC), Kenny McCormack wrote:

    Anyway, I just use the following little script, called "iPerl":

    --- Cut Here ---
    #!/usr/bin/perl print ":-) ";
    while (<>) { print eval; print ( ($@ || "\n") . ":-) " ) }
    --- Cut Here ---

    Note that you can't do this directly in AWK, b/c AWK (*) doesn't have
    "eval".

    (*) Yes, not even TAWK has eval.

    Note also that you can wrap the above script in something like "rlwrap"
    (or similar) to get keyboard scrolling, which is nice to have.

    rlwrap! I need to check that out, have gotten this far without it:

    #!/bin/sh

    exp() {
    e=$*
    [ -z "$e" ] && { echo "usage: exp <expression>"; return 1; }
    echo "$e" | grep -Eq '^[0-9+*/().^eE-]+$' || { echo "invalid
    expression"; return 1; }
    r=$(awk "BEGIN{print ($e)}" 2>/dev/null)
    [ -z "$r" ] && r="invalid expression"
    echo "$r"
    }

    # minimal repl
    while printf "> "; do
    IFS= read -r line || break
    [ -z "$line" ] && continue
    exp "$line"
    done

    # eof

    But you all are correct about loosing context.
    Slow & steady I'm getting there...
    --
    :wq
    Mike Sanders
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Michael Sanders@porkchop@invalid.foo to comp.unix.shell on Fri Oct 31 15:53:09 2025
    From Newsgroup: comp.unix.shell

    On Fri, 31 Oct 2025 10:38:15 +0100, Janis Papanagnou wrote:

    Your script looks quite complicated and hard to read. Quite some shell commands used just ask for replacement (say, by Awk for example) to make
    that simpler and (re: Subject) more "handy".

    With GNU Awk (and co-process support) it might get yet even simpler.

    Unfortunately I cannot test that since my 'bc' strangely doesn't react
    on scale=3 but the idea is something along the lines of [untested; may require tweaks]...

    awk '
    BEGIN { FS = OFS = "|" ; bc = "bc -ql" }
    { print $1 |& bc }
    $2 { bc |& getline res
    print $0, res, (res == $2) ? "YES" : "NO" }
    '

    with input like
    scale=3|
    1+2|3.000 7-4|3.000 ...

    (Note that the scale should be coupled with the data, not hard-coded, if
    you want to compare exact strings and not just the numeric values.)

    Just an idea.

    Janis

    1st attempt... it does what I need right now. Certainly worth exploring
    more down the line. But I want just mainly posix which limits me...
    --
    :wq
    Mike Sanders
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Michael Sanders@porkchop@invalid.foo to comp.unix.shell on Fri Oct 31 15:54:38 2025
    From Newsgroup: comp.unix.shell

    On Fri, 31 Oct 2025 14:56:02 -0000 (UTC), Christian Weisgerber wrote:

    Why use -l if you disallow the functions it includes?

    Its not 'all there' yet. Make it better & post your results.
    --
    :wq
    Mike Sanders
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Kaz Kylheku@643-408-1753@kylheku.com to comp.unix.shell on Fri Oct 31 17:03:47 2025
    From Newsgroup: comp.unix.shell

    On 2025-10-31, Kenny McCormack <gazelle@shell.xmission.com> wrote:
    In article <10e2029$cc2l$1@dont-email.me>,
    Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:
    Your script looks quite complicated and hard to read. Quite some shell >>commands used just ask for replacement (say, by Awk for example) to
    make that simpler and (re: Subject) more "handy".

    With GNU Awk (and co-process support) it might get yet even simpler.

    A couple of other things to note:

    1) One problem with Mike's general approach, which I think we've all
    hit at some point in our respective shell journeys, is that you end up
    running and exiting 'bc' each time you invoke the
    macro/alias/function/whatever.

    Which adds horribly to all the times you're already launching a process
    every time you release a fart while standing under a #!/bin/sh sign.
    --
    TXR Programming Language: http://nongnu.org/txr
    Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
    Mastodon: @Kazinator@mstdn.ca
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Janis Papanagnou@janis_papanagnou+ng@hotmail.com to comp.unix.shell on Fri Oct 31 18:14:50 2025
    From Newsgroup: comp.unix.shell

    On 31.10.2025 13:39, Kenny McCormack wrote:

    A couple of other things to note:

    1) One problem with Mike's general approach, which I think we've all
    hit at some point in our respective shell journeys, is that you end up
    running and exiting 'bc' each time you invoke the
    macro/alias/function/whatever. You thus lose any context you may have
    built up in 'bc' - starting from scratch each time. So, ...

    Before there was 'fltexpr' (see below), in one of my scripts that
    needed floating point math, I constructed a system where 'bc' was run
    as a bash co-process. This worked well, since 'bc' gets run just once,
    saving on process startup/exit cycles and also preserving context.

    Yep. For such "external services" co-processes are a fine feature. Interestingly, AFAIR, in Ksh, they were supported already with the
    old 1988 version. In that light, Bash added that rather late.

    There was just one caveat with co-processes; some external commands
    do not use line-buffering and then, depending on tools' behavior, the co-process might not work correctly (without some pty feature added).


    2) bash now has a loadable module called 'fltexpr' that evaluates
    floating point expressions - much like $(( ... )) already does with
    integer expressions. I haven't used this loadable much, because the
    need just hasn't arisen, but the concept looks interesting (and long
    overdue).

    You mean in Bash we need (or needed?) two different methods for int
    and float arithmetic respectively...?

    BTW, I understand that this loadable isn't needed in ksh, 'cause ksh
    already does floating point. I never understood why bash didn't follow
    ksh's lead and do likewise (until very recently...)

    ...or does that mean it is that now both supported with $((...)) ?

    Janis

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Michael Sanders@porkchop@invalid.foo to comp.unix.shell on Fri Oct 31 17:51:13 2025
    From Newsgroup: comp.unix.shell

    On Fri, 31 Oct 2025 06:32:18 -0000 (UTC), Michael Sanders wrote:

    handy shell function/alias that wraps bc tested & working with bash,
    busybox ash

    ahh something else: operator precedence (* and / before + and -)

    I'll rebuild so that everything is evaluated strictly in the order entered (just like a handheld calc)...
    --
    :wq
    Mike Sanders
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From ram@ram@zedat.fu-berlin.de (Stefan Ram) to comp.unix.shell on Fri Oct 31 18:21:35 2025
    From Newsgroup: comp.unix.shell

    Michael Sanders <porkchop@invalid.foo> wrote or quoted:
    # test cases: expression|expected output

    Oh man, that takes me back to my old parsers. I just tried
    writing one for Bash. It's really just a bare-bones demo though -
    everything's integers, the numbers can only have a single digit, and
    the power operator only works if both sides are between 0 and 11.

    #!/bin/bash

    g=""
    pos=0
    REPLY="" # Used as a global return variable

    # xpow: only for args between 0 and 11
    xpow() {
    local x=$1 y=$2 result=1 i
    if [ "$x" -lt 11 ] && [ "$y" -lt 11 ]; then
    for i in $(seq 1 $y); do
    result=$((result * x))
    done
    echo "$result"
    fi
    }

    xmul() {
    echo $(($1 * $2))
    }

    xdiv() {
    echo $(($1 / $2))
    }

    xadd() {
    echo $(($1 + $2))
    }

    xsub() {
    echo $(($1 - $2))
    }

    declare -A op_func op_left

    op_func["^"]="xpow"; op_left["^"]=0 # right associative
    op_func["*"]="xmul"; op_left["*"]=1 # left associative
    op_func["/"]="xdiv"; op_left["/"]=1
    op_func["+"]="xadd"; op_left["+"]=1
    op_func["-"]="xsub"; op_left["-"]=1

    lookup() {
    local name=$1
    if [[ -n ${op_func[$name]} ]]; then
    echo "$name ${op_func[$name]} ${op_left[$name]}"
    else
    echo "0 0 0"
    fi
    }

    peek() {
    REPLY="${g:pos:1}"
    }

    get() {
    REPLY="${g:pos:1}"
    if [[ -n "$REPLY" ]]; then
    pos=$((pos + 1))
    fi
    }

    check() {
    local op_chars="$1"
    peek
    local ch="$REPLY"
    if [[ "$op_chars" == *"$ch"* ]]; then
    get
    else
    REPLY=""
    fi
    }

    numeral() {
    local ch
    get
    ch="$REPLY"
    REPLY=$((10#$ch - 0))
    }

    prefix() {
    local sign=1
    peek
    while [[ "$REPLY" == "-" ]]; do
    get
    sign=$((sign * -1))
    peek
    done
    numeral
    REPLY=$((sign * REPLY))
    }

    parse() {
    local op_chars="$1" # $1: op_chars (e.g., "+-")
    local next_func="$2" # $2: next_func (e.g., "product")
    local result

    $next_func
    result="$REPLY"

    while true; do
    local sym
    check "$op_chars"
    sym="$REPLY"

    [[ -z "$sym" ]] && break

    local _name func left_assoc
    read -r _name func left_assoc <<<"$(lookup "$sym")"

    local ll=$left_assoc

    local x
    if [[ "$ll" -eq 1 ]]; then
    $next_func
    x="$REPLY"
    else
    parse "$op_chars" "$next_func"
    x="$REPLY"
    fi

    result=$($func "$result" "$x")
    done

    REPLY="$result"
    }

    power() {
    parse "^" prefix
    }

    product() {
    parse "*/" power
    }

    sum() {
    parse "+-" product
    }

    start() {
    sum
    }

    test_expr() {
    local s="$1"
    g="$s"
    pos=0
    start
    printf "Test '%s' Result: %g\n" "$s" "$REPLY"
    }

    test_expr "-2"
    test_expr "--2"
    test_expr "-2*-2"
    test_expr "2^3^2"
    test_expr "2*2^3^2-1"
    test_expr "1+2^3^2/2"


    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Michael Sanders@porkchop@invalid.foo to comp.unix.shell on Fri Oct 31 19:15:09 2025
    From Newsgroup: comp.unix.shell

    On 31 Oct 2025 18:21:35 GMT, Stefan Ram wrote:

    Oh man, that takes me back to my old parsers. I just tried writing one
    for Bash. It's really just a bare-bones demo though - everything's
    integers, the numbers can only have a single digit, and the power
    operator only works if both sides are between 0 and 11.

    [...]

    Ha! Great, there's some stuff in here I can steal (learn from!).

    Added to my notes & thanks for sharing.
    --
    :wq
    Mike Sanders
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.unix.shell on Fri Oct 31 23:29:27 2025
    From Newsgroup: comp.unix.shell

    On Fri, 31 Oct 2025 13:16:58 +0000, Geoff Clare wrote:

    Lawrence DrCOOliveiro wrote:

    ldo@theon:~> bc <<<'5*2-1'
    9

    DonrCOt need a whole script to save a few characters of typing ...

    That's *more* typing than just using bc interactively.

    I rarely use bc interactively.

    stardate()
    {
    bc <<<"scale = 1; ($(date -d "${1:-now}" +%s)) / 86400"
    } # stardate
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Nuno Silva@nunojsilva@invalid.invalid to comp.unix.shell on Sat Nov 1 10:43:30 2025
    From Newsgroup: comp.unix.shell

    On 2025-10-31, Michael Sanders wrote:

    On Fri, 31 Oct 2025 14:56:02 -0000 (UTC), Christian Weisgerber wrote:

    Why use -l if you disallow the functions it includes?

    Its not 'all there' yet. Make it better & post your results.

    Why? The potential issue has already been written by Christian in
    English and we can discuss it in the programming/design stage. No need
    to write code (coding) to discuss this or to point out an issue.

    (Also, is there even much to write code-wise, given it's, as far as I
    can tell, about removing "-l" from the option list?)

    (If you're not here to discuss the code, why did you post the code?)
    --
    Nuno Silva
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Michael Sanders@porkchop@invalid.foo to comp.unix.shell on Sat Nov 1 12:29:40 2025
    From Newsgroup: comp.unix.shell

    On Sat, 01 Nov 2025 10:43:30 +0000, Nuno Silva wrote:

    On 2025-10-31, Michael Sanders wrote:

    On Fri, 31 Oct 2025 14:56:02 -0000 (UTC), Christian Weisgerber wrote:

    Why use -l if you disallow the functions it includes?

    Its not 'all there' yet. Make it better & post your results.

    Why? The potential issue has already been written by Christian in
    English and we can discuss it in the programming/design stage. No need
    to write code (coding) to discuss this or to point out an issue.

    (Also, is there even much to write code-wise, given it's, as far as I
    can tell, about removing "-l" from the option list?)

    (If you're not here to discuss the code, why did you post the code?)

    Because Nuno, the characters in the regex are allowed, lets reread it:

    grep -Eq '^[0-9+*/().^-]+$'

    Christian, I'm guessing, made a mistake when he wrote 'disallow',
    unless I misunderstand him. If he or you or whoever has something
    to add he/you/they always can. And removing '-l' huh?

    That is the string that's fed into 'bc -l'
    --
    :wq
    Mike Sanders
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Ed Morton@mortonspam@gmail.com to comp.unix.shell on Sat Nov 1 11:47:47 2025
    From Newsgroup: comp.unix.shell

    On 10/31/2025 1:32 AM, Michael Sanders wrote:
    #!/bin/sh

    <<'NOTES'

    handy shell function/alias that wraps bc
    tested & working with bash, busybox ash

    Michael Sanders 2025

    usage example: exp 5*2-1

    NOTES

    exp() {
    s=3 # optional scale
    e=$(printf '%s' "$*" | tr -d '[:space:]') # compress
    [ -z "$e" ] && { echo "usage: exp <expression>"; return 1; }

    # short-circuit invalid characters
    echo "$e" | grep -Eq '^[0-9+*/().^-]+$' || \
    { echo "invalid expression"; return 1; }

    # evaluate with bc -l
    r=$(echo "scale=$s; $e" | bc -l 2>/dev/null) \
    && [ -n "$r" ] && printf "%.*f\n" "$s" "$r" \
    || { echo "invalid expression"; return 1; }
    }

    It's not clear why you'd use bc instead of awk to evaluate the
    expression, e.g. using any POSIX awk:

    $ exp() { awk -v s=3 'BEGIN{ printf("%.*f\n", s, '"$*"') }'; }

    $ exp '1+2'
    3.000

    $ exp 'log(10) * cos(90)'
    -1.032

    $ exp "$RANDOM / 3"
    9936.333

    Regards,

    Ed.

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.unix.shell on Sat Nov 1 20:21:13 2025
    From Newsgroup: comp.unix.shell

    On Sat, 1 Nov 2025 11:47:47 -0500, Ed Morton wrote:

    It's not clear why you'd use bc instead of awk to evaluate the
    expression, e.g. using any POSIX awk:

    I never bothered with Awk. I realized early on that Perl did everything
    that Awk could do, and a lot more, just as concisely.

    I realize Awk is officially part of POSIX, and Perl is not. But all real-
    world POSIXish systems have Perl readily available anyway (or even part of
    the default install), so thatrCOs not a problem.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From gazelle@gazelle@shell.xmission.com (Kenny McCormack) to comp.unix.shell on Sat Nov 1 21:27:19 2025
    From Newsgroup: comp.unix.shell

    In article <10e5q3p$1h87f$9@dont-email.me>,
    Lawrence DOliveiro <ldo@nz.invalid> wrote:
    On Sat, 1 Nov 2025 11:47:47 -0500, Ed Morton wrote:

    It's not clear why you'd use bc instead of awk to evaluate the
    expression, e.g. using any POSIX awk:

    I never bothered with Awk. I realized early on that Perl did everything
    that Awk could do, and a lot more, just as concisely.

    I never bothered with Perl. I realized early on that Intercal did
    everything that Perl could do, and a lot more, just as crypticly.
    --
    The randomly chosen signature file that would have appeared here is more than 4 lines long. As such, it violates one or more Usenet RFCs. In order to remain in compliance with said RFCs, the actual sig can be found at the following URL:
    http://user.xmission.com/~gazelle/Sigs/LadyChatterley
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Ed Morton@mortonspam@gmail.com to comp.unix.shell on Sun Nov 2 16:58:54 2025
    From Newsgroup: comp.unix.shell

    On 11/1/2025 3:21 PM, Lawrence DrCOOliveiro wrote:
    On Sat, 1 Nov 2025 11:47:47 -0500, Ed Morton wrote:

    It's not clear why you'd use bc instead of awk to evaluate the
    expression, e.g. using any POSIX awk:

    I never bothered with Awk. I realized early on that Perl did everything
    that Awk could do, and a lot more, just as concisely.

    Conciseness is brevity plus clarity and perl scripts are invariably
    missing one of those qualities. I think the meme at https://www.zoitz.com/comics/perl_small.png says all that needs to be
    said about perl.

    Ed.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.unix.shell on Mon Nov 3 01:53:45 2025
    From Newsgroup: comp.unix.shell

    On Sun, 2 Nov 2025 16:58:54 -0600, Ed Morton wrote:

    On 11/1/2025 3:21 PM, Lawrence DrCOOliveiro wrote:
    On Sat, 1 Nov 2025 11:47:47 -0500, Ed Morton wrote:

    It's not clear why you'd use bc instead of awk to evaluate the
    expression, e.g. using any POSIX awk:

    I never bothered with Awk. I realized early on that Perl did everything
    that Awk could do, and a lot more, just as concisely.

    Conciseness is brevity plus clarity and perl scripts are invariably
    missing one of those qualities.

    Nope. Things like rCLperl -lnerCY or even rCLperl -lneprCY allow you to write short one-liners that are just as powerful as anything in Awk.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From gazelle@gazelle@shell.xmission.com (Kenny McCormack) to comp.unix.shell on Mon Nov 3 02:39:16 2025
    From Newsgroup: comp.unix.shell

    In article <10e91v9$2ie01$2@dont-email.me>,
    Lawrence DOliveiro <ldo@nz.invalid> wrote:
    On Sun, 2 Nov 2025 16:58:54 -0600, Ed Morton wrote:

    On 11/1/2025 3:21 PM, Lawrence DOliveiro wrote:
    On Sat, 1 Nov 2025 11:47:47 -0500, Ed Morton wrote:

    It's not clear why you'd use bc instead of awk to evaluate the
    expression, e.g. using any POSIX awk:

    I never bothered with Awk. I realized early on that Perl did everything
    that Awk could do, and a lot more, just as concisely.

    Conciseness is brevity plus clarity and perl scripts are invariably
    missing one of those qualities.

    Nope. Things like perl -lne or even perl -lnep allow you to write
    short one-liners that are just as powerful as anything in Awk.

    Spoken like a True Believer.

    The cult lives on.
    --
    If you ask a Trumper who is to blame for the debacle of Jan 6, they will almost certainly say
    something about Antifa/BLM/something/whatever. This shows just how screwed up they are; they can't
    even get their narrative straight. What they *should* say is "Eugene Goodman". If not for him, the plot
    would probably have succeeded, so he (Eugene) is clearly to blame for the failure.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Richard Harnden@richard.nospam@gmail.invalid to comp.unix.shell on Mon Nov 3 14:03:18 2025
    From Newsgroup: comp.unix.shell

    On 31/10/2025 17:14, Janis Papanagnou wrote:
    On 31.10.2025 13:39, Kenny McCormack wrote:

    A couple of other things to note:

    1) One problem with Mike's general approach, which I think we've all
    hit at some point in our respective shell journeys, is that you end up >> running and exiting 'bc' each time you invoke the
    macro/alias/function/whatever. You thus lose any context you may have >> built up in 'bc' - starting from scratch each time. So, ...

    Before there was 'fltexpr' (see below), in one of my scripts that
    needed floating point math, I constructed a system where 'bc' was run >> as a bash co-process. This worked well, since 'bc' gets run just once, >> saving on process startup/exit cycles and also preserving context.

    Yep. For such "external services" co-processes are a fine feature. Interestingly, AFAIR, in Ksh, they were supported already with the
    old 1988 version. In that light, Bash added that rather late.

    There was just one caveat with co-processes; some external commands
    do not use line-buffering and then, depending on tools' behavior, the co-process might not work correctly (without some pty feature added).


    2) bash now has a loadable module called 'fltexpr' that evaluates
    floating point expressions - much like $(( ... )) already does with
    integer expressions. I haven't used this loadable much, because the
    need just hasn't arisen, but the concept looks interesting (and long
    overdue).

    You mean in Bash we need (or needed?) two different methods for int
    and float arithmetic respectively...?

    BTW, I understand that this loadable isn't needed in ksh, 'cause ksh
    already does floating point. I never understood why bash didn't follow >> ksh's lead and do likewise (until very recently...)

    ...or does that mean it is that now both supported with $((...)) ?

    In ksh:
    $ echo $((4*atan(1)))


    3.14159265358979324

    In bash:
    $ echo $((4*atan(1)))
    bash: 4*atan(1): syntax error in expression (error token is "(1)")

    Everything, it seems to me, is just easier with ksh.

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Janis Papanagnou@janis_papanagnou+ng@hotmail.com to comp.unix.shell on Mon Nov 3 15:10:31 2025
    From Newsgroup: comp.unix.shell

    On 03.11.2025 15:03, Richard Harnden wrote:
    On 31/10/2025 17:14, Janis Papanagnou wrote:
    On 31.10.2025 13:39, Kenny McCormack wrote:

    BTW, I understand that this loadable isn't needed in ksh, 'cause
    ksh
    already does floating point. I never understood why bash didn't
    follow
    ksh's lead and do likewise (until very recently...)

    ...or does that mean it is that now both supported with $((...)) ?

    In ksh:
    $ echo $((4*atan(1)))

    3.14159265358979324

    In bash:
    $ echo $((4*atan(1)))
    bash: 4*atan(1): syntax error in expression (error token is "(1)")

    Is that the "very recent" version of Bash that Kenny was speaking
    about? - I read his post that Bash would *now* support what Ksh
    supported for long.


    Everything, it seems to me, is just easier with ksh.

    Most things, indeed. (That's why I'm using Ksh since about 1990.)

    Janis

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Richard Harnden@richard.nospam@gmail.invalid to comp.unix.shell on Mon Nov 3 14:40:13 2025
    From Newsgroup: comp.unix.shell

    On 03/11/2025 14:10, Janis Papanagnou wrote:
    On 03.11.2025 15:03, Richard Harnden wrote:
    On 31/10/2025 17:14, Janis Papanagnou wrote:
    On 31.10.2025 13:39, Kenny McCormack wrote:

    BTW, I understand that this loadable isn't needed in ksh, 'cause >>>> ksh
    already does floating point. I never understood why bash didn't >>>> follow
    ksh's lead and do likewise (until very recently...)

    ...or does that mean it is that now both supported with $((...)) ?

    In ksh:
    $ echo $((4*atan(1)))

    3.14159265358979324

    In bash:
    $ echo $((4*atan(1)))
    bash: 4*atan(1): syntax error in expression (error token is "(1)")

    Is that the "very recent" version of Bash that Kenny was speaking
    about? - I read his post that Bash would *now* support what Ksh
    supported for long.

    No, that was 5.1.8. fltexpr needs at least 5.3.



    Everything, it seems to me, is just easier with ksh.

    Most things, indeed. (That's why I'm using Ksh since about 1990.)




    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From gazelle@gazelle@shell.xmission.com (Kenny McCormack) to comp.unix.shell on Mon Nov 3 16:11:16 2025
    From Newsgroup: comp.unix.shell

    In article <10eaesd$2u47l$1@dont-email.me>,
    Richard Harnden <nospam.harnden@invalid.com> wrote:
    ...
    Is that the "very recent" version of Bash that Kenny was speaking
    about? - I read his post that Bash would *now* support what Ksh
    supported for long.

    No, that was 5.1.8. fltexpr needs at least 5.3.

    To be pedantic about it, I don't think fltexpr actually requires 5.3, but
    it became publicly available with the release of 5.3. You could probably
    get the source and compile it and run it with earlier versions (I haven't tested this).

    And to answer Janis's question: No, it is not integrated into $(( ... ))
    It is "bash loadable", which means you have to:
    a) Either find a compiled version of it (i.e., a shared library) or
    find the source (a .c file) and compile it yourself.
    and
    b) "enable" it in your script or interactive shell to use it.

    Note that many (most?) distributions do not build/install the bash
    loadables, so you usually end up having to self-compile bash in order to
    use the loadables (including fltexpr).

    It is all kind of a bodge and it would have been better if it could have
    just been integrated into $(( ... )), like in ksh. The general "feel" I
    get from the bash "community" is that the loadables are for things that
    aren't really "ready for prime time" - that is, not ready to be integrated
    into the main bash binary.

    FWIW, I have no great love for bash, even though it is my primary shell and
    my primary shell hacking enterprise these days. I still think tcsh has the best user experience, but it sucks as a programming language and isn't
    really supported/maintained these days. I still use tcsh as my login/interactive shell on one of the machines I use (but the rest are
    bash).
    --
    The randomly chosen signature file that would have appeared here is more than 4 lines long. As such, it violates one or more Usenet RFCs. In order to remain in compliance with said RFCs, the actual sig can be found at the following URL:
    http://user.xmission.com/~gazelle/Sigs/Voltaire
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Janis Papanagnou@janis_papanagnou+ng@hotmail.com to comp.unix.shell on Mon Nov 3 17:24:27 2025
    From Newsgroup: comp.unix.shell

    On 03.11.2025 17:11, Kenny McCormack wrote:
    [...]

    It is all kind of a bodge and it would have been better if it could have
    just been integrated into $(( ... )), like in ksh. [...]

    Indeed. Especially if the lib is just adding FP (and nothing else).
    Also with the paragon of Ksh or Zsh using already $((...)) for that.
    I also cannot see an extension of $((...)) would break anything in
    Bash, or would it?

    Alas, re: Zsh, I just noticed...

    $ zsh -c 'echo $(( 1.0+2.3 ))'
    3.2999999999999998

    $ ksh -c 'echo $(( 1.0+2.3 ))'
    3.3

    Zsh is not really confidence-inspiring here. - Hmm..

    Janis

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Christian Weisgerber@naddy@mips.inka.de to comp.unix.shell on Mon Nov 3 15:56:11 2025
    From Newsgroup: comp.unix.shell

    On 2025-11-03, Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:

    In bash:
    $ echo $((4*atan(1)))
    bash: 4*atan(1): syntax error in expression (error token is "(1)")

    Is that the "very recent" version of Bash that Kenny was speaking
    about? - I read his post that Bash would *now* support what Ksh
    supported for long.

    Bash now ships with a loadable module fltexpr that evaluates a
    floating-point arithmetic expression. It's not clear to me what
    the purpose of those modules is. I think they are more intended
    as demos of the loadable module functionality than as serious
    extensions of bash itself. They are not loaded by default and I
    wouldn't expect every installation of bash to actually include them.

    Anyway:

    bash$ enable fltexpr
    bash$ help fltexpr
    fltexpr: fltexpr [-p] expression
    Evaluate floating-point arithmetic expression.

    Evaluate EXPRESSION as a floating-point arithmetic expression and,
    if the -p option is supplied, print the value to the standard output.

    Exit Status:
    If the EXPRESSION evaluates to 0, the return status is 1; 0 otherwise. bash$ fltexpr -p 4 * 'atan(1)'
    4
    bash$ fltexpr -p '4 * atan(1)'
    3.141592653589793
    --
    Christian "naddy" Weisgerber naddy@mips.inka.de
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From gazelle@gazelle@shell.xmission.com (Kenny McCormack) to comp.unix.shell on Mon Nov 3 17:33:44 2025
    From Newsgroup: comp.unix.shell

    In article <10eakvt$30ji5$1@dont-email.me>,
    Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:
    On 03.11.2025 17:11, Kenny McCormack wrote:
    [...]

    It is all kind of a bodge and it would have been better if it could have
    just been integrated into $(( ... )), like in ksh. [...]

    Indeed. Especially if the lib is just adding FP (and nothing else).

    That's pretty much the way bash loadables work (*). There is usually a
    1-to-1 relationship between the file and the command that it implements.

    This is not required - and there are exceptions - but it is the general pattern.

    (*) GAWK is similar.
    --
    The randomly chosen signature file that would have appeared here is more than 4 lines long. As such, it violates one or more Usenet RFCs. In order to remain in compliance with said RFCs, the actual sig can be found at the following URL:
    http://user.xmission.com/~gazelle/Sigs/Windows
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.unix.shell on Mon Nov 3 20:06:30 2025
    From Newsgroup: comp.unix.shell

    On Mon, 3 Nov 2025 14:03:18 +0000, Richard Harnden wrote:

    Everything, it seems to me, is just easier with ksh.

    The saying rCLto someone with a hammer, every problem looks like a nailrCY comes to mind ...
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Janis Papanagnou@janis_papanagnou+ng@hotmail.com to comp.unix.shell on Mon Nov 3 21:25:47 2025
    From Newsgroup: comp.unix.shell

    On 03.11.2025 21:06, Lawrence DrCOOliveiro wrote:
    On Mon, 3 Nov 2025 14:03:18 +0000, Richard Harnden wrote:

    Everything, it seems to me, is just easier with ksh.

    The saying rCLto someone with a hammer, every problem looks like a nailrCY comes to mind ...

    Richard was comparing Ksh with Bash here. - And only a blind man would
    disagree with him. (Or someone not knowing these shells and religiously adhering to some dogma.)

    There's a few details where Bash has a "pro", but only very very few.

    Richard's "everything" is of course debatable in that light, but it's
    already more than compensated by his "it seems to me", a subjective
    summarized feeling.

    Janis

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Kaz Kylheku@643-408-1753@kylheku.com to comp.unix.shell on Mon Nov 3 21:11:35 2025
    From Newsgroup: comp.unix.shell

    On 2025-11-03, Lawrence DrCOOliveiro <ldo@nz.invalid> wrote:
    On Mon, 3 Nov 2025 14:03:18 +0000, Richard Harnden wrote:

    Everything, it seems to me, is just easier with ksh.

    The saying rCLto someone with a hammer, every problem looks like a nailrCY

    Including your pin-like head.
    --
    TXR Programming Language: http://nongnu.org/txr
    Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
    Mastodon: @Kazinator@mstdn.ca
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Christian Weisgerber@naddy@mips.inka.de to comp.unix.shell on Mon Nov 3 23:19:26 2025
    From Newsgroup: comp.unix.shell

    On 2025-11-03, Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:

    $ zsh -c 'echo $(( 1.0+2.3 ))'
    3.2999999999999998

    $ ksh -c 'echo $(( 1.0+2.3 ))'
    3.3

    Zsh is not really confidence-inspiring here. - Hmm..

    I think 0.3 cannot be represented in binary floating point format,
    so you are getting an approximation. Zsh and ksh appear to apply
    different rounding on output. It's probably just the difference
    between %.17g and %g or such.
    --
    Christian "naddy" Weisgerber naddy@mips.inka.de
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Kaz Kylheku@643-408-1753@kylheku.com to comp.unix.shell on Tue Nov 4 00:35:09 2025
    From Newsgroup: comp.unix.shell

    On 2025-11-03, Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:
    On 03.11.2025 17:11, Kenny McCormack wrote:
    [...]

    It is all kind of a bodge and it would have been better if it could have
    just been integrated into $(( ... )), like in ksh. [...]

    Indeed. Especially if the lib is just adding FP (and nothing else).
    Also with the paragon of Ksh or Zsh using already $((...)) for that.
    I also cannot see an extension of $((...)) would break anything in
    Bash, or would it?

    Alas, re: Zsh, I just noticed...

    $ zsh -c 'echo $(( 1.0+2.3 ))'
    3.2999999999999998

    $ ksh -c 'echo $(( 1.0+2.3 ))'
    3.3

    Zsh is not really confidence-inspiring here. - Hmm..

    It's just an artifact of rounding the number when printing, together
    with the inability of 1/3 to have an exact representation in binary.

    IEEE 64 bit floats can record a 15 digit number and reproduce
    every digit.

    The reverse is not the case; 15 decimal mantissa digits are not enough
    to record every IEEE 64 bit value.

    You need 17 digits. Look: that's exactly the digit count in the zsh
    output.

    When you print 17 digits, that reveals the approximation that is
    being used: it is slightly less than 3 1/3.

    When you print to 15 digits, it disappears in the rounding.

    This is the TXR Lisp interactive listener of TXR 302.
    Quit with :quit or Ctrl-D on an empty line. Ctrl-X ? for cheatsheet.
    0.3
    0.3
    *print-flo-precision*
    15
    (set *print-flo-precision* 17)
    17
    0.3
    0.29999999999999999


    A similar experiment can be conducted with printf, playing with the
    precision value in the formatting, between 15 and 17.

    Note that like ksh, I set the default to 15. By that, I am pandering
    to the "optics". Zsh decided not to pander to optics and stick with
    precision: output the number in such a way that if it is transmitted
    to another program and converted back to 64 bit double, the same
    number will be reproduced. By printing to 15 digits, we lose that transparency. We alias several possible approximations of 3.3 to one textual representation.
    --
    TXR Programming Language: http://nongnu.org/txr
    Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
    Mastodon: @Kazinator@mstdn.ca
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Kaz Kylheku@643-408-1753@kylheku.com to comp.unix.shell on Tue Nov 4 01:04:28 2025
    From Newsgroup: comp.unix.shell

    On 2025-11-04, Kaz Kylheku <643-408-1753@kylheku.com> wrote:
    IEEE 64 bit floats can record a 15 digit number and reproduce
    every digit.

    Trivia: this 15 value is in the ISO C <float.h> under the name DBL_DIG.
    (I mean, on platforms with IEEE 64 bit doubles, of course.)

    The 17 value appears under the name DBL_DECIMAL_DIG.

    DBL_DIG is how many digits of decimal precision can we round-trip
    into double and back.

    DBL_DECIMAL_DIG is how many decimal digits we need to round trip
    a double to decimal text and back.

    I think DBL_DECIMAL_DIG might be newer. ANSI C89 / ISO C90 had DBL_DIG,
    but I seem to recall even C99 didn't have DBL_DECIMAL_DIG yet.
    --
    TXR Programming Language: http://nongnu.org/txr
    Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
    Mastodon: @Kazinator@mstdn.ca
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Janis Papanagnou@janis_papanagnou+ng@hotmail.com to comp.unix.shell on Tue Nov 4 05:34:08 2025
    From Newsgroup: comp.unix.shell

    On 04.11.2025 00:19, Christian Weisgerber wrote:
    On 2025-11-03, Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:

    $ zsh -c 'echo $(( 1.0+2.3 ))'
    3.2999999999999998

    $ ksh -c 'echo $(( 1.0+2.3 ))'
    3.3

    Zsh is not really confidence-inspiring here. - Hmm..

    I think 0.3 cannot be represented in binary floating point format,
    so you are getting an approximation. Zsh and ksh appear to apply
    different rounding on output. It's probably just the difference
    between %.17g and %g or such.

    Yes, sure. - It's just that my "simple" pocket-calculator that
    I bought around 1980 does not show such obvious rounding errors
    (i.e. with numbers it can not exactly represent).

    Janis

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Kaz Kylheku@643-408-1753@kylheku.com to comp.unix.shell on Tue Nov 4 04:40:26 2025
    From Newsgroup: comp.unix.shell

    On 2025-11-04, Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:
    On 04.11.2025 00:19, Christian Weisgerber wrote:
    On 2025-11-03, Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:

    $ zsh -c 'echo $(( 1.0+2.3 ))'
    3.2999999999999998

    $ ksh -c 'echo $(( 1.0+2.3 ))'
    3.3

    Zsh is not really confidence-inspiring here. - Hmm..

    I think 0.3 cannot be represented in binary floating point format,
    so you are getting an approximation. Zsh and ksh appear to apply
    different rounding on output. It's probably just the difference
    between %.17g and %g or such.

    Yes, sure. - It's just that my "simple" pocket-calculator that
    I bought around 1980 does not show such obvious rounding errors
    (i.e. with numbers it can not exactly represent).

    Calculators use the same base for calculating that they do for
    displaying and input. That makes all the difference.

    You literally cannot input anything into your calculator that
    it cannot represent. It supports an exact representation of 0.3,
    or anything else you can punch in.

    You can calculate something it cannot represent, like dividing 1 by 3.
    But it does that in decimal and can truncate and round as you would
    using pencil-and-paper calculations. If it agrees with pencil-and-paper
    model decimal calculations, you will find it flawless. :)
    --
    TXR Programming Language: http://nongnu.org/txr
    Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
    Mastodon: @Kazinator@mstdn.ca
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Janis Papanagnou@janis_papanagnou+ng@hotmail.com to comp.unix.shell on Tue Nov 4 05:57:31 2025
    From Newsgroup: comp.unix.shell

    On 04.11.2025 05:40, Kaz Kylheku wrote:
    On 2025-11-04, Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:
    On 04.11.2025 00:19, Christian Weisgerber wrote:
    On 2025-11-03, Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote: >>>
    $ zsh -c 'echo $(( 1.0+2.3 ))'
    3.2999999999999998

    $ ksh -c 'echo $(( 1.0+2.3 ))'
    3.3

    Zsh is not really confidence-inspiring here. - Hmm..

    I think 0.3 cannot be represented in binary floating point format,
    so you are getting an approximation. Zsh and ksh appear to apply
    different rounding on output. It's probably just the difference
    between %.17g and %g or such.

    Yes, sure. - It's just that my "simple" pocket-calculator that
    I bought around 1980 does not show such obvious rounding errors
    (i.e. with numbers it can not exactly represent).

    Calculators use the same base for calculating that they do for
    displaying and input. That makes all the difference.

    You literally cannot input anything into your calculator that
    it cannot represent. It supports an exact representation of 0.3,
    or anything else you can punch in.

    You can calculate something it cannot represent, like dividing 1 by 3.
    But it does that in decimal and can truncate and round as you would
    using pencil-and-paper calculations. If it agrees with pencil-and-paper
    model decimal calculations, you will find it flawless. :)

    That old one (that I still use) uses BCD, it displays mantissas
    of 10 digits, it uses internally 12 digits for the calculations,
    and does rounding. Yes. It handles and displays correctly both
    arithmetic (by internal rounding with two spare decimal digits),
    those it can represent exactly (like 0.1, a "problematic" value
    in binary encoding), and those it cannot represent exactly (like
    the result of an [intermediate] value of 1/3.

    Here, in the topic of shells, as depicted above, I see what Ksh
    produces in a _simple expression_, and I see the Zsh behavior.
    (I wouldn't even want to imagine how errors propagate in Zsh.)

    Janis

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Ed Morton@mortonspam@gmail.com to comp.unix.shell on Tue Nov 4 16:49:57 2025
    From Newsgroup: comp.unix.shell

    On 11/2/2025 7:53 PM, Lawrence DrCOOliveiro wrote:
    On Sun, 2 Nov 2025 16:58:54 -0600, Ed Morton wrote:

    On 11/1/2025 3:21 PM, Lawrence DrCOOliveiro wrote:
    On Sat, 1 Nov 2025 11:47:47 -0500, Ed Morton wrote:

    It's not clear why you'd use bc instead of awk to evaluate the
    expression, e.g. using any POSIX awk:

    I never bothered with Awk. I realized early on that Perl did everything
    that Awk could do, and a lot more, just as concisely.

    Conciseness is brevity plus clarity and perl scripts are invariably
    missing one of those qualities.

    Nope. Things like rCLperl -lnerCY or even rCLperl -lneprCY allow you to write short one-liners that are just as powerful as anything in Awk.

    Standard perl proponent type of response there.

    The rest of the world: "perl scripts lack clarity"/"deserts lack water"
    Perl proponents: "No, perl scripts are short and powerful"/"No, deserts
    have sand and heat".

    Ah well, not worth discussing further.

    Ed.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Kaz Kylheku@643-408-1753@kylheku.com to comp.unix.shell on Tue Nov 4 23:06:53 2025
    From Newsgroup: comp.unix.shell

    On 2025-11-03, Lawrence DrCOOliveiro <ldo@nz.invalid> wrote:
    On Sun, 2 Nov 2025 16:58:54 -0600, Ed Morton wrote:

    On 11/1/2025 3:21 PM, Lawrence DrCOOliveiro wrote:
    On Sat, 1 Nov 2025 11:47:47 -0500, Ed Morton wrote:

    It's not clear why you'd use bc instead of awk to evaluate the
    expression, e.g. using any POSIX awk:

    I never bothered with Awk. I realized early on that Perl did everything
    that Awk could do, and a lot more, just as concisely.

    Conciseness is brevity plus clarity and perl scripts are invariably
    missing one of those qualities.

    Nope. Things like rCLperl -lnerCY or even rCLperl -lneprCY allow you to write
    short one-liners that are just as powerful as anything in Awk.

    There Is More Than One Way To Do It!

    For instance, -lnep can appear in any of these combinations:

    (flow "lnep" perm tprint)
    lnep
    lnpe
    lenp
    lepn
    lpne
    lpen
    nlep
    nlpe
    nelp
    nepl
    nple
    npel
    elnp
    elpn
    enlp
    enpl
    epln
    epnl
    plne
    plen
    pnle
    pnel
    peln
    penl

    Essentially 24 different tokens for the same configuration.

    No Perl one-liner is shorter than awk'!a[$0]++'.

    "I still say awk { print $1} a lot!" --- Larry Wall

    The options to set up an Awk-like input processing loop take up
    characters. They way you reference $0 is longer too. The array will
    need a % sigil on it.

    That whole sigil thing is retarded. And why would you choose
    stream names to be the thing that doesn't have sigis? How often
    do you manipulate streams compared to variables? Streams can often
    be made implicit (output goes to stdout, input from stdin).

    Awk function: practically the prototype for Javascript:

    function f(x, y)
    {
    return x + y;
    }

    Perl:

    sub f {
    my ($x, $y) = @_;
    return $x + $y;
    }

    Yikes!
    --
    TXR Programming Language: http://nongnu.org/txr
    Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
    Mastodon: @Kazinator@mstdn.ca
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.unix.shell on Wed Nov 5 00:06:02 2025
    From Newsgroup: comp.unix.shell

    On Tue, 4 Nov 2025 16:49:57 -0600, Ed Morton wrote:

    On 11/2/2025 7:53 PM, Lawrence DrCOOliveiro wrote:

    On Sun, 2 Nov 2025 16:58:54 -0600, Ed Morton wrote:

    On 11/1/2025 3:21 PM, Lawrence DrCOOliveiro wrote:

    On Sat, 1 Nov 2025 11:47:47 -0500, Ed Morton wrote:

    It's not clear why you'd use bc instead of awk to evaluate the
    expression, e.g. using any POSIX awk:

    I never bothered with Awk. I realized early on that Perl did
    everything that Awk could do, and a lot more, just as concisely.

    Conciseness is brevity plus clarity and perl scripts are invariably
    missing one of those qualities.

    Nope. Things like rCLperl -lnerCY or even rCLperl -lneprCY allow you to write
    short one-liners that are just as powerful as anything in Awk.

    Standard perl proponent type of response there.

    Which doesnrCOt exactly refute my point, does it?
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Jim@zsd+ng@jdvb.ca to comp.unix.shell on Fri Nov 7 10:09:57 2025
    From Newsgroup: comp.unix.shell

    On 2025-10-31 at 03:38 ADT, Lawrence DrCOOliveiro <ldo@nz.invalid> wrote:
    On Fri, 31 Oct 2025 06:32:18 -0000 (UTC), Michael Sanders wrote:

    usage example: exp 5*2-1

    ldo@theon:~> bc <<<'5*2-1'
    9

    DonrCOt need a whole script to save a few characters of typing ...

    Or in zsh, to avoid having to type quotes

    In .zshrc put
    aliases[==]='noglob bcfn'
    bcfn () {
    echo "scale=6 ; $*" | bc
    }

    At the prompt type

    $ == 5*2+1
    11
    $

    Jim
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.unix.shell on Sat Nov 8 00:00:54 2025
    From Newsgroup: comp.unix.shell

    On Fri, 7 Nov 2025 10:09:57 -0400, Jim wrote:

    On 2025-10-31 at 03:38 ADT, Lawrence DrCOOliveiro <ldo@nz.invalid> wrote:

    On Fri, 31 Oct 2025 06:32:18 -0000 (UTC), Michael Sanders wrote:

    usage example: exp 5*2-1

    ldo@theon:~> bc <<<'5*2-1'
    9

    DonrCOt need a whole script to save a few characters of typing ...

    Or in zsh, to avoid having to type quotes

    In .zshrc put
    aliases[==]='noglob bcfn'
    bcfn () {
    echo "scale=6 ; $*" | bc
    }

    At the prompt type

    $ == 5*2+1
    11
    $

    Interesting: this

    ==() { bc <<<"scale=6; $*"; }

    is directly valid in bash, but not zsh.

    This definition

    bcfn() { bc <<<"scale=6; $*"; }

    was accepted, but then

    bcfn 5*2+1

    produced the error

    zsh: no matches found: 5*2+1

    (Did print the answer rCL11rCY in bash, but probably unsafe there too.)
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Christian Weisgerber@naddy@mips.inka.de to comp.unix.shell on Sat Nov 8 16:51:25 2025
    From Newsgroup: comp.unix.shell

    On 2025-11-08, Lawrence DrCOOliveiro <ldo@nz.invalid> wrote:

    This definition

    bcfn() { bc <<<"scale=6; $*"; }

    was accepted, but then

    bcfn 5*2+1

    produced the error

    zsh: no matches found: 5*2+1

    The issue here is that 5*2+1 is interpreted as a glob to be expanded. Apparently you don't have any files matching this in your current
    directory.

    (Did print the answer rCL11rCY in bash, but probably unsafe there too.)

    You can tell bash to error out when glob expansion fails:

    bash$ shopt -s failglob
    bash$ bcfn 5*2+1
    bash: no match: 5*2+1

    I think it's safe to assume that you can also toggle zsh's behavior.

    But really, what all this means is that you want to call

    bcfn '5*2+1'

    or

    bcfn 5\*2+1
    --
    Christian "naddy" Weisgerber naddy@mips.inka.de
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.unix.shell on Sat Nov 8 21:55:35 2025
    From Newsgroup: comp.unix.shell

    On Sat, 8 Nov 2025 16:51:25 -0000 (UTC), Christian Weisgerber wrote:

    The issue here is that 5*2+1 is interpreted as a glob to be expanded.

    ThatrCOs what the person I was replying to was doing.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Jim Diamond@zsd@jdvb.ca to comp.unix.shell on Wed Nov 19 20:37:26 2025
    From Newsgroup: comp.unix.shell

    On 2025-11-07 at 20:00 AST, Lawrence DrCOOliveiro <ldo@nz.invalid> wrote:
    On Fri, 7 Nov 2025 10:09:57 -0400, Jim wrote:

    On 2025-10-31 at 03:38 ADT, Lawrence DrCOOliveiro <ldo@nz.invalid> wrote: >>>
    On Fri, 31 Oct 2025 06:32:18 -0000 (UTC), Michael Sanders wrote:

    usage example: exp 5*2-1

    ldo@theon:~> bc <<<'5*2-1'
    9

    DonrCOt need a whole script to save a few characters of typing ...

    Or in zsh, to avoid having to type quotes

    In .zshrc put
    aliases[==]='noglob bcfn'
    bcfn () {
    echo "scale=6 ; $*" | bc
    }

    At the prompt type

    $ == 5*2+1
    11
    $

    Interesting: this

    ==() { bc <<<"scale=6; $*"; }

    is directly valid in bash, but not zsh.


    This definition

    bcfn() { bc <<<"scale=6; $*"; }

    was accepted, but then

    bcfn 5*2+1

    produced the error

    zsh: no matches found: 5*2+1

    (Did print the answer rCL11rCY in bash, but probably unsafe there too.)

    The joys of the subtle differences between different shells...

    I was originally going to say "I generally don't use bash, but I will admit
    to being surprised that bash doesn't try to glob the argument(s)".
    But then I tried some spaces, for visual appeal:

    $ ==() { bc <<<"scale=6; $*"; }
    $ == 3 * 4
    (standard_in) 1: syntax error
    (standard_in) 1: syntax error
    (standard_in) 1: syntax error
    (standard_in) 1: syntax error
    (standard_in) 1: syntax error


    With my zsh definitions,
    $ == 3 * 4
    12
    as expected.

    Jim
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Brian Patrie@bpatrie@bellsouth.spamisicky.net to comp.unix.shell on Sun Nov 23 14:40:48 2025
    From Newsgroup: comp.unix.shell

    Jim Diamond wrote:
    ...I will admit to being surprised that bash doesn't try
    to glob the argument(s)...

    It does. But upon failure, bash follows the (dangerous) precedent, established by sh, of passing globs that don't match anything as
    literals. The danger in this is that, if you get in the habit of
    relying upon the behaviour, you might find it matching something when
    you didn't expect it.

    I much prefer zsh's (default) behaviour of complaining. I can quote the thing, or use noglob if needed.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.unix.shell on Sun Nov 23 20:58:43 2025
    From Newsgroup: comp.unix.shell

    On Sun, 23 Nov 2025 14:40:48 -0600, Brian Patrie wrote:

    Jim Diamond wrote:

    ...I will admit to being surprised that bash doesn't try to glob
    the argument(s)...

    It does. But upon failure, bash follows the (dangerous) precedent, established by sh, of passing globs that don't match anything as
    literals. The danger in this is that, if you get in the habit of
    relying upon the behaviour, you might find it matching something
    when you didn't expect it.

    ThatrCOs what rCLshopt failglobrCY is for.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Jim Diamond@zsd@jdvb.ca to comp.unix.shell on Mon Nov 24 21:12:30 2025
    From Newsgroup: comp.unix.shell

    On 2025-11-23 at 16:40 AST, Brian Patrie <bpatrie@bellsouth.spamisicky.net> wrote:
    Jim Diamond wrote:
    ...I will admit to being surprised that bash doesn't try
    to glob the argument(s)...

    It does. But upon failure, bash follows the (dangerous) precedent, established by sh, of passing globs that don't match anything as
    literals. The danger in this is that, if you get in the habit of
    relying upon the behaviour, you might find it matching something when
    you didn't expect it.

    I much prefer zsh's (default) behaviour of complaining. I can quote the thing, or use noglob if needed.

    Duh. It is so long since I used a shell which passes through unmatched
    globs that I forget such things exist.

    Thanks for the reminder. That is sort of a dangerous thing to forget.

    Jim
    --- Synchronet 3.21a-Linux NewsLink 1.2