2012-08-27 23 views
32

chciałbym wykonać następującą operację w moim skryptu:Division w skrypcie i zmiennoprzecinkowych

1 - ((m - 20)/34) 

Chciałbym przypisać wynik tej operacji do innej zmiennej. Chcę, aby mój skrypt korzystał z matematyki zmiennoprzecinkowej. Na przykład dla m = 34:

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

Odpowiedz

24

Bash nie wykonuje matematyki zmiennoprzecinkowej. Możesz użyć awk lub bc, aby sobie z tym poradzić. Oto przykład awk:

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

Aby przypisać wyjście do zmiennej:

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

Można korzystać z kalkulatora bc. Będzie to zrobić dowolną dokładnością matematyki za pomocą dziesiętnych (nie binarnej zmiennoprzecinkową), jeśli ustawisz increease scale z domyślnej 0:

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

Opcja -l załaduje standardową bibliotekę matematyczną i domyślną skalę do 20:

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

następnie można użyć printf do formatowania danych wyjściowych, jeśli więc wybrać:

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

@ rubo77 zrobiłem coś jak ten 'niech fail_percent = 0 niech suma = $ ((pass_count + fail_count)) printf "Fail procentowa wynosi% f \ n" $ (bc - l <<< "($ fail_count/$ total)") ' tutaj suma = 16 i fail_count = 15, otrzymuję odpowiedź jako .93750000000000000000, ale przychodzi z błędem jako nieprawidłowy numer printf Dałem #!/bin/bash w początku skryptu ... KAŻDY pomysł, dlaczego błąd? –

+0

używając 'printf '% f \ n' $ (bc -l <<< 1.2)' Otrzymuję błąd 'bash: printf: 1.2: Ungültige Zahl. ' – rubo77

17

Teach np bash Podział całkowitą pływających wyników punktowych:

#!/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 

wyjściowa:

1.706161137440 
    0.205882352941 
    0.25 
    123445755 
    28248.587570621468 
+0

Bardzo ładne. Byłoby to nawet zgodne z POSIX, jeśli zmienna 'let c = c + 1' została zmieniona na' c = $ (($ c + 1)), ale rekurencja wygląda drogo ... –

-2

użyć tego skryptu, otwórz ten plik w edytorze jak:

$ sudo vim /usr/bin/div 

Następnie wklej ten kod:

#!/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' 

Teraz chmod go 755:

$ sudo chmod 755 /usr/bin/div 

teraz używać go:

$ div 5 100 
0.05 

W skrypcie można użyć to:

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

daje wynik.

Przykład:

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

Wprowadź wartość & B jako 10 3, masz 3.3333333333

Jeśli chcesz przechowywać wartość w innej zmiennej, a następnie użyć kodu

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

To również daje taki sam efekt jak wyżej. Spróbuj ...

Powiązane problemy