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
Next revision Both sides next revision
floating_point_calculation [2012/01/27 16:02]
k2patel
floating_point_calculation [2012/01/27 16:34]
k2patel [Using in Script for Comparision]
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 oobas>
 +  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 oobas>
 +   ​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 oobas>
 +  $ 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.txt ยท Last modified: 2020/08/10 02:35 (external edit)