2010-04-21 16 views
5

w bash muszę porównać dwie liczby float, jedną które definiują w skrypcie, a drugi czytać jako paramter, za to zrobić:Float warunkowego w bash

if [[ $aff -gt 0 ]] 
    then 
      a=b 
      echo "xxx "$aff 
      #echo $CX $CY $CZ $aff 
    fi 

ale pojawia się błąd:

[[: -309,585300: błąd składni: nieprawidłowy operator arytmetyczny (błąd Token jest”0,585300")

Co jest nie tak?

Dzięki

+0

Zakładam, że już znasz [Co każdy informatyk powinien wiedzieć o arytmetyki zmiennoprzecinkowej] (http://docs.sun.com/source/806-3568/ncg_goldberg.html) . –

+2

to tak, jak mówię, że aby zrozumieć ludzkie zachowanie, wystarczy znać równanie Schroedingera: – flow

+2

@Dennis: to pytanie nie wymaga żadnej wiedzy z tego artykułu; nie * wszystko * na temat elementów pływających jest trudne, a porównania większe/mniejsze działają po prostu zgodnie z oczekiwaniami. –

Odpowiedz

4

wykorzystanie awk

#!/bin/bash 
num1=0.3 
num2=0.2 
if [ -n "$num1" -a -n "$num2" ];then 
    result=$(awk -vn1="$num1" -vn2="$num2" 'BEGIN{print (n1>n2)?1:0 }') 
    echo $result 
    if [ "$result" -eq 1 ];then 
    echo "$num1 greater than $num2" 
    fi 
fi 
+0

bardzo ładnie. ostatni komentarz, numer 1 jest odczytywany z jakiegoś pliku, aw niektórych przypadkach jest pusty, więc porównanie daje dziwne wyniki. w jaki sposób można w jakiś sposób sprawdzić, czy "jeśli num1 jest pusty, to num1 = 0"? – flow

+0

użyj '-n', aby przetestować niepusty ciąg. zobacz 'man test', aby uzyskać więcej informacji – ghostdog74

3

Zarówno test (który jest zazwyczaj połączony z co [) i bash -builtin równoważnych tylko pomocy liczb całkowitych.

0

użyłbym awk za to:

e=2.718281828459045 
pi=3.141592653589793 
if [ "yes" = "$(echo | awk "($e <= $pi) { print \"yes\"; }")" ]; then 
    echo "lessthanorequal" 
else 
    echo "larger" 
fi 
6

Korzystanie bc zamiast awk:

float1='0.43255' 
float2='0.801222' 

if [[ $(echo "if (${float1} > ${float2}) 1 else 0" | bc) -eq 1 ]]; then 
    echo "${float1} > ${float2}" 
else 
    echo "${float1} <= ${float2}" 
fi 
1

Korzystanie bc sprawdzić matematyka

a="1.21231" 
b="2.22454" 
c=$(echo "$a < $b" | bc) 
if [ $c = '1' ]; then 
    echo 'a is smaller than b' 
else 
    echo 'a is larger than b' 
fi 
0

Najprostszym rozwiązaniem jest to:

f1=0.45 
f2=0.33 
if [[ $f1 > $f2 ]] ; then echo "f1 is greater then f2"; fi 

który (na OSX) Wyjścia:

f1 is greater then f2 

Oto kolejny przykład łącząc zmiennoprzecinkowych i arytmetyki liczb całkowitych (trzeba wielki mały skrypt Perla calc.pl że można pobrać z here):

dateDiff=1.9864 
nObs=3 
i=1 
while [[ $dateDiff > 0 ]] && [ $i -le $nObs ] 
do 
    echo "$dateDiff > 0" 
    dateDiff=`calc.pl $dateDiff-0.224` 
    i=$((i+1)) 
done 

które wyjścia

1.9864 > 0 
1.7624 > 0 
1.5384 > 0 
+0

Po prostu zdałem sobie sprawę, że ** to tak naprawdę nie działa, ponieważ bash ignoruje separator dziesiętny ** w trybie cichym. Działa tylko przy porównywaniu pływaków w szczególnych okolicznościach, np. Gdy mają one taką samą liczbę cyfr PRZED przecinkiem dziesiętnym. Rozwiązaniem jest użycie tylko części całkowitej porównywanych zmiennoprzecinkowych (użycie -gt zamiast> i -lt zamiast <; jest to wystarczająco dobre dla moich aplikacji), lub podzielenie części całkowitych i dziesiętnych i porównanie ich _as liczby całkowite_ osobno. –