User Tools

Site Tools


floating_point_calculation

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
floating_point_calculation [2012/01/27 16:02]
k2patel
floating_point_calculation [2020/08/10 02:35] (current)
Line 1: Line 1:
 ====== Floating Point Calculation ====== ====== Floating Point Calculation ======
 This is an example represent how to compute Floating point in bash. This is an example represent how to compute Floating point in bash.
 +
 +==== Using in Script for Comparision ====
 +
 +To use ''​bc''​ in our bash scripts we'll package it up into a couple of functions: ​
 +
 +<code oobas>
 +    float_eval EXPRESSION
 +and
 +    float_cond CONDITIONAL-EXPRESSION
 +</​code>​
 +Both functions expect a single floating point expression, ''​float_eval''​ writes the result of the expression evaluation to standard out, ''​float_cond''​ assumes the expression is a conditional expression and sets the return/​status code to zero if the expression is true and one if it's false. ​
 +
 +Usage is quite simple: ​
 +
 +<code bash>
 +  float_eval '12.0 / 3.0'
 +  if float_cond '10.0 > 9.0'; then
 +    echo 'As expected, 10.0 is greater than 9.0'
 +  fi
 +  a=12.0
 +  b=3.0
 +  c=$(float_eval "$a / $b")
 +</​code>​
 +The code for the functions follows: ​
 +
 +<code bash>
 +#!/bin/bash
 +#
 +# Floating point number functions.
 +
 +#####################################################################​
 +# Default scale used by float functions.
 +
 +float_scale=2
 +
 +
 +#####################################################################​
 +# Evaluate a floating point number expression.
 +
 +function float_eval()
 +{
 +    local stat=0
 +    local result=0.0
 +    if [[ $# -gt 0 ]]; then
 +        result=$(echo "​scale=$float_scale;​ $*" | bc -q 2>/​dev/​null)
 +        stat=$?
 +        if [[ $stat -eq 0  && ​ -z "​$result"​ ]]; then stat=1; fi
 +    fi
 +    echo $result
 +    return $stat
 +}
 +
 +
 +#####################################################################​
 +# Evaluate a floating point number conditional expression.
 +
 +function float_cond()
 +{
 +    local cond=0
 +    if [[ $# -gt 0 ]]; then
 +        cond=$(echo "​$*"​ | bc -q 2>/​dev/​null)
 +        if [[ -z "​$cond"​ ]]; then cond=0; fi
 +        if [[ "​$cond"​ != 0  && ​ "​$cond"​ != 1 ]]; then cond=0; fi
 +    fi
 +    local stat=$((cond == 0))
 +    return $stat
 +}
 +
 +
 +# Test code if invoked directly.
 +if [[ $(basename $0 .sh) == '​float'​ ]]; then
 +    # Use command line arguments if there are any.
 +    if [[ $# -gt 0 ]]; then
 +        echo $(float_eval $*)
 +    else
 +        # Turn off pathname expansion so * doesn'​t get expanded
 +        set -f
 +        e="​12.5 / 3.2"
 +        echo $e is $(float_eval "​$e"​)
 +        e="​100.4 / 4.2 + 3.2 * 6.5"
 +        echo $e is $(float_eval "​$e"​)
 +        if float_cond '10.0 > 9.3'; then
 +            echo "10.0 is greater than 9.3"
 +        fi
 +        if float_cond '10.0 < 9.3'; then
 +            echo "​Oops"​
 +        else
 +            echo "10.0 is not less than 9.3"
 +        fi
 +        a=12.0
 +        b=3.0
 +        c=$(float_eval "$a / $b")
 +        echo "$a / $b" is $c
 +        set +f
 +    fi
 +fi
 +
 +# vim: tabstop=4: shiftwidth=4:​ noexpandtab:​
 +# kate: tab-width 4; indent-width 4; replace-tabs false;
 +</​code>​
 +The work of the functions is done by feeding the arguments to ''​bc'': ​
 +
 +<code bash>
 +   ​result=$(echo "​scale=$float_scale;​ $*" | bc -q 2>/​dev/​null)
 +</​code>​
 +By default ''​bc''​ outputs its result with no digits to the right of the decimal point and without a decimal point. To change this you have to change one of ''​bc'''​s builtin variables: ''​scale''​. This is where the "​language"​ features of ''​bc''​ are relevant, in ''​bc''​ as in C statements are separated by semi-colons. We set ''​bc'''​s ''​scale''​ variable by preceding the expression that we pass to ''​bc''​ with ''​scale=$float_scale;''​. This sets the scale in ''​bc''​ to the value of the bash global variable ''​float_scale'',​ which is by default set to two (near the top of the script). ​
 +
 +The main gotcha here has to do with the fact that "​*",​ "<",​ and ">"​ have other meanings in bash. You can eliminate the problem of "<"​ and ">"​ by quoting your expressions,​ but this only works with "​*"​ if you use single quotes and that would mean you couldn'​t include bash variables in the expression. The other option is to bracket your code with "''​set -f''"​ and "''​set +f''"​ to turn off pathname/​wildcard expansion. ​
 +
 +If you save the script as ''​float.sh''​ and run it directly it will execute the test code at the bottom: ​
 +
 +<code bash>
 +  $ sh float.sh
 +  12.5 / 3.2 is 3.90
 +  100.4 / 4.2 + 3.2 * 6.5 is 44.70
 +  10.0 is greater than 9.3
 +  10.0 is not less than 9.3
 +  12.0 / 3.0 is 4.00
 +</​code>​
 +The one unaswered question you may have is: "and why would I want to do this?" Next time around I'll show you one place you can put this to real world use. 
 +
 +Ref : [[ http://​www.linuxjournal.com/​content/​floating-point-math-bash | Linux Journal ]]
 +
 +==== Doing Calculation ====
 +
  
 **Details** **Details**
Line 129: Line 254:
 </​code>​ </​code>​
  
-Ref. [[http://​www.novell.com/​coolsolutions/​tools/​17043.html|http://​www.novell.com/​coolsolutions/​tools/​17043.html]]+Ref. [[ http://​www.novell.com/​coolsolutions/​tools/​17043.html | Novell Cool Solutions ​]]
  
  
floating_point_calculation.1327680141.txt.gz ยท Last modified: 2020/08/10 02:30 (external edit)