Nowe posty

Autor Wątek: [bash] Problem operacja na liczbach zmienno przecinkowych  (Przeczytany 2086 razy)

wiatrak

  • Gość
Witam,

Jestem początkująca jeśli chodzi o linux i bash. Mam problem przy dzieleniu zmiennych przecinkowych (np. 9.35).
Przy obliczaniu sum_sd, sum_mean, sum_max - bc działa ok - otrzymuje wyniki 31,200
Natomiast przy final results : otrzymuje 9 3 1
Nie mam pojęcia gdzie robię jakiś błąd ?

Tutaj mój kod :
k=0
sum_mean=0
sum_sd=0
sum_max=0
while read LINE; do
k=$(($k+1))
echo $LINE
TAB=(${LINE})
sum_mean=$(echo "$sum_mean" + "${TAB[0]}" | bc)
sum_sd=$(echo "$sum_sd" + "${TAB[1]}" | bc)
sum_max=$(echo "$sum_max" + "${TAB[2]}" | bc)
done < "residual_results.txt"

echo $sum_mean
echo $sum_sd
echo $sum_max

MAX=$(echo "$sum_max/10" | bc)
MEAN=$(echo "$sum_mean/10"|bc)
SD=$(echo "$sum_sd/10"|bc)

echo "Final resutls : "
echo $MAX   # ???
echo $MEAN  # ??
echo $SD # ???


Czyta z pliku w formacie txt  :
5.9 2.72 14
6.34 2.94 16
5.64 2.91 16
3.63 2.26 14.1
1.87 1.69 10.1
0.224 0.606 2.23
0 0 0
0.516 0.81 2.96
2.81 1.74 8
4.27 2.16 12


Będę wdzięczna za każdą pomoc.

Offline Paweł Kraszewski

  • Administrator
  • Guru
  • *****
  • Wiadomości: 3056
  • Lenistwo jest matką potrzeby = babcią wynalazku
    • Zobacz profil
[bash] Problem operacja na liczbach zmienno przecinkowych
« Odpowiedź #1 dnia: 2013-10-13, 18:53:45 »
Podstawowy błąd polega na zastosowaniu niewłaściwego narzędzia. BASH nie służy do obliczeń numerycznych :/

Ale zlituję się - w niezwykle trudno osiągalnym manualu do programu BC (kosztuje tysiące dolarów na czarnym rynku) jest taki paragraf:
Cytuj
wyrażenie / wyrażenie
              Wynikiem tego wyrażenia jest iloraz obu wyrażeń. Liczba cyfr po kropce dziesiętnej wyniku jest równa wartości zmiennej scale.
Domyślnie scale jest równe 0.

Dużo czystszy kod wychodzi np AWKiem, przeznaczonym do zabawy z plikami tabelarycznymi:
Plik sumator.awk
BEGIN {
    # blok BEGIN uruchamiany jest przed wczytaniem pierwszej linijki danych
    sum_mean=0.0
    sum_sd=0.0
    sum_max=0.0
}

{
    # Blok uruchamiany jest dla każdej linijki danych
    # $1 to pierwsze słowo, $2 drugie, itd
    sum_mean = sum_mean+$1
    sum_sd = sum_sd+$2
    sum_max = sum_max+$3
}

END {
    # Blok END uruchamiany jest po przetworzeniu ostatniej linijki danych.
    # NR automagicznie zawiera liczbę wczytanych linijek
    mean_mean = sum_mean/NR
    mean_sd = sum_sd/NR
    mean_max = sum_max/NR
   
    print "MEAN=",mean_mean
    print "SD=",mean_sd
    print "MAX=",mean_max
}
Wywołanie:
$> awk -f sumator.awk data.txt 
MEAN= 3.12
SD= 1.7836
MAX= 9.539
Paweł Kraszewski
~Arch/Void/Gentoo/FreeBSD/OpenBSD/Specjalizowane customy