2179
Comment: all versions of ksh93 have floating point arithmetic. zsh also has support for FP arithmetic.
|
3341
Add the dc part and the caveat at the end --- gniourf_gniourf
|
Deletions are marked like this. | Additions are marked like this. |
Line 1: | Line 1: |
[[Anchor(faq22)]] | <<Anchor(faq22)>> |
Line 3: | Line 3: |
["BASH"] does not have built-in floating point [:ArithmeticExpression:arithmetic]: | [[BASH]] does not have built-in floating point [[ArithmeticExpression|arithmetic]]: |
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}}}. | Same example with {{{dc}}} (reversed polish calculator, lighter than bc): {{{ $ echo "3 k 10 3 / p" | dc }}} {{{k}}} sets the precision to 3, and {{{p}}} prints the value of the top of the stack with a newline. The stack is not altered, though. If you are trying to compare floating point numbers, be aware that a simple ''x < y'' is not supported by all versions of {{{bc}}}. |
Line 32: | Line 39: |
# Bash | |
Line 37: | Line 45: |
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. | This example subtracts 2.5 from 1.4, and checks the sign of the result. If it is negative, the first number is less than the second. |
Line 42: | Line 50: |
# Bourne | |
Line 47: | Line 56: |
["AWK"] can be used for calculations, too: | [[AWK]] can be used for calculations, too: |
Line 56: | Line 65: |
Newer versions zsh and KornShell93 have built-in floating point arithmetic, together with mathematical functions like {{{sin()}}} or {{{cos()}}} . | Newer versions of zsh and the KornShell have built-in floating point arithmetic, together with mathematical functions like {{{sin()}}} or {{{cos()}}} . |
Line 59: | Line 68: |
Caveat: Many problems that look like floating point arithmetic can in fact be solved using integers only, and thus do not require these tools: Problems dealing with rational numbers. For example, to check if too number {{{x}}} and {{{y}}} are in a ration of 4:3 or 16:9 you may use something along these lines: {{{ # Variables x and y are integers if (( $x*9-$y*16==0 )) ; then echo "16:9." elif (( $x*3-$y*4==0 )) ; then echo "4:3." else echo "Neither 16:9 nor 4:3." fi }}} A more elaborate test could tell if the ratio is closest to 4:3 or 16:9 without using floating point arithmetic. Note that this very simple example that apparently involves floating point numbers and division is solved with integers and no division. If possible, it's usually more efficient to convert your problem to integer arithmetic than to use floating point arithmetic. |
How can I calculate with floating point numbers instead of just integers?
BASH does not have built-in floating point 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.
Same example with dc (reversed polish calculator, lighter than bc):
$ echo "3 k 10 3 / p" | dc
k sets the precision to 3, and p prints the value of the top of the stack with a newline. The stack is not altered, though.
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:
# Bash 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 first number is less than the second.
Portable version:
# Bourne 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 of zsh and the KornShell 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.
Caveat: Many problems that look like floating point arithmetic can in fact be solved using integers only, and thus do not require these tools: Problems dealing with rational numbers. For example, to check if too number x and y are in a ration of 4:3 or 16:9 you may use something along these lines:
# Variables x and y are integers if (( $x*9-$y*16==0 )) ; then echo "16:9." elif (( $x*3-$y*4==0 )) ; then echo "4:3." else echo "Neither 16:9 nor 4:3." fi
A more elaborate test could tell if the ratio is closest to 4:3 or 16:9 without using floating point arithmetic. Note that this very simple example that apparently involves floating point numbers and division is solved with integers and no division. If possible, it's usually more efficient to convert your problem to integer arithmetic than to use floating point arithmetic.