Differences between revisions 1 and 3 (spanning 2 versions)
Revision 1 as of 2007-05-02 23:08:44
Size: 1939
Editor: redondos
Comment:
Revision 3 as of 2007-10-16 18:27:21
Size: 2179
Comment: all versions of ksh93 have floating point arithmetic. zsh also has support for FP arithmetic.
Deletions are marked like this. Additions are marked like this.
Line 3: Line 3:
["BASH"] does not have built-in floating point arithmetic: ["BASH"] does not have built-in floating point [:ArithmeticExpression:arithmetic]:
Line 10: Line 10:
For better precision, an external program must be used, e.g. {{{bc}}}, {{{awk}}} or {{{dc}}}: Bash cannot do ''anything'' with floating point numbers, ''including'' compare them to each other(*). Instead, an external program must be used, e.g. {{{bc}}}, {{{awk}}} or {{{dc}}}:
Line 19: Line 19:
If you are trying to compare floating point numbers, be aware that a simple ''x < y'' is not supported by all versions of {{{bc}}}. Alternatively, you could use this: If you are trying to compare floating point numbers, be aware that a simple ''x < y'' is not supported by all versions of {{{bc}}}.

{{{
    # This would work with some versions, but not HP-UX 10.20.
    # The here string feature, inherited from rc->zsh->ksh93 was
    # introduced in bash 2.05b-alpha1
    imadev:~$ bc <<< '1 < 2'
    syntax error on line 1,
}}}

Alternatively, you could use this:
Line 27: Line 37:
This example substracts 2.5 from 1.4, and checks the sign of the result. If it is negative, the former number is less than the latter. This example subtracts 2.5 from 1.4, and checks the sign of the result. If it is negative, the former number is less than the latter.
Line 29: Line 39:
{{{awk}}} can be used for calculations, too: Portable version:
Line 32: Line 42:
    $ awk 'BEGIN {printf "%.3f\n", 10 / 3}' /dev/null     case "`echo "1.4 - 2.5" | bc`" in
      -*) echo "1.4 is less than 2.5";;
    esac
}}}

["AWK"] can be used for calculations, too:

{{{
    $ awk 'BEGIN {printf "%.3f\n", 10 / 3}'
Line 36: Line 54:
There is a subtle but important difference between the {{{bc}}} and the {{{awk}}} solution here: {{{bc}}} reads commands and expressions ''from standard input''. {{{awk}}} on the other hand evaluates the expression as ''part of the program''. Expressions on standard input are ''not'' evaluated, i.e. {{{echo 10/3 | awk '{print $0}'}}} will print {{{10/3}}} instead of the evaluated result of the expression. There is a subtle but important difference between the {{{bc}}} and the {{{awk}}} solution here: {{{bc}}} reads commands and expressions from ''standard input''. {{{awk}}} on the other hand evaluates the expression as ''part of the program''. Expressions on standard input are ''not'' evaluated, i.e. {{{echo 10/3 | awk '{print $0}'}}} will print {{{10/3}}} instead of the evaluated result of the expression.
Line 38: Line 56:
This explains why the example uses {{{/dev/null}}} as an input file for {{{awk}}}: the program evaluates the {{{BEGIN}}} action, evaluating the expression and printing the result. Afterwards the work is already done: it reads its standard input, gets an end-of-file indication, and terminates. If no file had been specified, {{{awk}}} would wait for data on standard input. Newer versions zsh and KornShell93 have built-in floating point arithmetic, together with mathematical functions like {{{sin()}}} or {{{cos()}}} .
Line 40: Line 58:
Newer versions of KornShell93 have built-in floating point arithmetic, together with mathematical functions like {{{sin()}}} or {{{cos()}}} . (*)Actually, I lied. It can print them, using {{{printf}}} and one of the {{{%e}}} or {{{%f}}} or {{{%g}}} format strings. But that's all.

Anchor(faq22)

How can I calculate with floating point numbers instead of just integers?

["BASH"] does not have built-in floating point [:ArithmeticExpression:arithmetic]:

    $ echo $((10/3))
    3

Bash cannot do anything with floating point numbers, including compare them to each other(*). Instead, an external program must be used, e.g. bc, awk or dc:

    $ echo "scale=3; 10/3" | bc
    3.333

The "scale=3" command notifies bc that three digits of precision after the decimal point are required.

If you are trying to compare floating point numbers, be aware that a simple x < y is not supported by all versions of bc.

    # This would work with some versions, but not HP-UX 10.20.
    # The here string feature, inherited from rc->zsh->ksh93 was
    # introduced in bash 2.05b-alpha1
    imadev:~$ bc <<< '1 < 2'
    syntax error on line 1,

Alternatively, you could use this:

    if [[ $(bc <<< "1.4 - 2.5") = -* ]]; then
        echo "1.4 is less than 2.5."
    fi

This example subtracts 2.5 from 1.4, and checks the sign of the result. If it is negative, the former number is less than the latter.

Portable version:

    case "`echo "1.4 - 2.5" | bc`" in
      -*) echo "1.4 is less than 2.5";;
    esac

["AWK"] can be used for calculations, too:

    $ awk 'BEGIN {printf "%.3f\n", 10 / 3}'
    3.333

There is a subtle but important difference between the bc and the awk solution here: bc reads commands and expressions from standard input. awk on the other hand evaluates the expression as part of the program. Expressions on standard input are not evaluated, i.e. echo 10/3 | awk '{print $0}' will print 10/3 instead of the evaluated result of the expression.

Newer versions zsh and KornShell93 have built-in floating point arithmetic, together with mathematical functions like sin() or cos() .

(*)Actually, I lied. It can print them, using printf and one of the %e or %f or %g format strings. But that's all.

BashFAQ/022 (last edited 2021-09-01 06:31:58 by geirha)