2012-08-27 7 views
32

Ich mag würde die folgende Operation in meinem Skript tun:Division Skript und Floating-Point-

1 - ((m - 20)/34) 

würde Ich mag das Ergebnis dieser Operation auf eine andere Variable zuweisen. Ich möchte, dass mein Skript Gleitkommazahlen verwendet. Zum Beispiel für m = 34:

results = 1 - ((34 - 20)/34) == 0.588 

Antwort

24

Bash führt keine Fließkomma-Mathematik durch. Sie können dazu awk oder bc verwenden. Hier ist ein awk Beispiel:

$ m=34; awk -v m=$m 'BEGIN { print 1 - ((m - 20)/34) }' 
0.588235 

Um die Ausgabe einer Variablen zuweisen:

var=$(awk -v m=$m 'BEGIN { print 1 - ((m - 20)/34) }') 
47

Sie könnten den bc Rechner verwenden. Es wird mit beliebiger Genauigkeit Mathematik tun Dezimalstellen (nicht binär floating point), wenn Sie increease scale von seinem Standardwert 0 gesetzt:

$ m=34 
$ bc <<< "scale = 10; 1 - (($m - 20)/34)" 
.5882352942 

Die -l Option, um die Standard-Mathematik-Bibliothek wird geladen und die Skala bis 20 Default:

$ bc -l <<< "1 - (($m - 20)/34)" 
.58823529411764705883 

Sie können dann printf verwenden, um die Ausgabe zu formatieren, wenn Sie so wählen:

printf "%.3f\n" "$(bc -l ...)" 
+0

@ rubo77 habe ich so etwas wie dieses 'lassen fail_percent = 0 total = $ lassen ((pass_count + fail_count)) printf "Fail Prozentsatz% f \ n" $ (bc - l <<< "($ fail_count/$ total)") ' hier die Summe = 16 und fail_count = 15, bekomme ich die Antwort als .93750000000000000000, aber es kommt mit einem Fehler als printf ungültige Nummer Ich habe angegeben #!/bin/bash im Skriptanfang ... Eine Idee warum der Fehler? –

+0

mit 'printf '% f \ n' $ (bc -l <<< 1.2)' Ich bekomme den Fehler 'bash: printf: 1.2: Unglaubliche Zahl. ' – rubo77

17

Teach bash zB Integer-Division mit Gleitkommaergebnisse:

#!/bin/bash 

div() # Arguments: dividend and divisor 
{ 
     if [ $2 -eq 0 ]; then echo division by 0; exit; fi 
     local p=12       # precision 
     local c=${c:-0}      # precision counter 
     local d=.        # decimal separator 
     local r=$(($1/$2)); echo -n $r  # result of division 
     local m=$(($r*$2)) 
     [ $c -eq 0 ] && [ $m -ne $1 ] && echo -n $d 
     [ $1 -eq $m ] || [ $c -eq $p ] && return 
     local e=$(($1-$m)) 
     let c=c+1 
     div $(($e*10)) $2 
} 

    result=$(div 1080 633)     # write to variable 
    echo $result 

    result=$(div 7 34) 
    echo $result 

    result=$(div 8 32) 
    echo $result 

    result=$(div 246891510 2) 
    echo $result 

    result=$(div 5000000 177) 
    echo $result 

Ausgang:

1.706161137440 
    0.205882352941 
    0.25 
    123445755 
    28248.587570621468 
+0

Sehr nett. Dies wäre sogar POSIX-konform, wenn das 'let c = c + 1' in' c = $ (($ c + 1)) '' geändert würde, aber diese Rekursion sieht teuer aus ... –

-2

Verwenden Sie dieses Skript wie Sie diese Datei mit einem Editor öffnen:

$ sudo vim /usr/bin/div 

Dann diesen Code einfügen:

#!/bin/bash 
# Author: Danial Rikhteh Garan ([email protected]) 

if [[ -z "$1" ]] || [[ -z "$2" ]]; then 
    echo "Please input two number" 
    echo "for 100/50 use: div 10 50" 
    exit 1; 
fi 

div=$(echo "$1/$2" | bc -l); 
echo 0$div | sed 's/[0]*$//g' 

chmod es nun 755:

$ sudo chmod 755 /usr/bin/div 

es jetzt verwenden:

$ div 5 100 
0.05 

In Ihrem Skript Sie diese verwenden können:

var=$(div 5 100); 
echo "$var" 
3
echo $a/$b|bc -l 

gibt das Ergebnis aus.

Beispiel:

read a b 
echo $a/$b|bc -l 

Geben Sie einen & b-Wert als 10 3, erhalten Sie 3.3333333333

Wenn Sie den Wert in einer anderen Variablen speichern möchten, verwenden Sie dann den Code

read a b 
c=`echo $a/$b|bc -l` 
echo $c 

Es gibt auch das gleiche Ergebnis wie oben. Probieren Sie es ...