Bash에서 두 개의 부동 소수점 숫자를 비교하는 방법은 무엇입니까? 숫자를 간단히 비교하고 싶습니다. st=`echo “$num1 <

bash 스크립트 내에서 두 개의 부동 소수점 숫자를 비교하려고 열심히 노력하고 있습니다. 예를 들어 변수를 사용해야합니다

let num1=3.17648e-22
let num2=1.5

이제이 두 숫자를 간단히 비교하고 싶습니다.

st=`echo "$num1 < $num2" | bc`
if [ $st -eq 1]; then
  echo -e "$num1 < $num2"
else
  echo -e "$num1 >= $num2"
fi

불행히도, 나는 “e 형식”일 수있는 num1의 올바른 처리에 약간의 문제가 있습니다. 🙁

도움, 힌트를 환영합니다!



답변

더 편리하게

이것은 Bash의 숫자 컨텍스트를 사용하여보다 편리하게 수행 할 수 있습니다.

if (( $(echo "$num1 > $num2" |bc -l) )); then
  
fi

설명

기본 계산기 명령을 통해 파이핑 bc하면 1 또는 0이 반환됩니다.

이 옵션 -l--mathlib; 표준 수학 라이브러리를로드합니다.

큰 괄호 사이에 전체 표현식을 묶으면 (( ))이러한 값이 각각 true 또는 false로 변환됩니다.

bc기본 계산기 패키지가 설치되어 있는지 확인하십시오 .

E예를 들어 대문자 를 사용 하는 경우 과학 형식의 수레에 대해서도 동일하게 작동합니다.num1=3.44E6


답변

bash는 정수 수학 만 처리하지만 bc다음과 같이 명령을 사용할 수 있습니다 .

$ num1=3.17648E-22
$ num2=1.5
$ echo $num1'>'$num2 | bc -l
0
$ echo $num2'>'$num1 | bc -l
1

지수 부호는 대문자 여야합니다.


답변

awk정수가 아닌 수학 에 사용 하는 것이 좋습니다 . 이 bash 유틸리티 기능을 사용할 수 있습니다 :

numCompare() {
   awk -v n1="$1" -v n2="$2" 'BEGIN {printf "%s " (n1<n2?"<":">=") " %s\n", n1, n2}'
}

그리고 그것을 다음과 같이 부르십시오.

numCompare 5.65 3.14e-22
5.65 >= 3.14e-22

numCompare 5.65e-23 3.14e-22
5.65e-23 < 3.14e-22

numCompare 3.145678 3.145679
3.145678 < 3.145679


답변

지수 표기법, 선행 또는 후행 0없이 플로트를 비교하기위한 순수 bash 솔루션 :

if [ ${FOO%.*} -eq ${BAR%.*} ] && [ ${FOO#*.} \> ${BAR#*.} ] || [ ${FOO%.*} -gt ${BAR%.*} ]; then
  echo "${FOO} > ${BAR}";
else
  echo "${FOO} <= ${BAR}";
fi

논리 연산자의 순서가 중요 합니다. 정수 부분은 숫자로 비교되고 소수 부분은 의도적으로 문자열로 비교됩니다. 변수는 이 방법을 사용하여 정수 부분과 분수 부분으로 나뉩니다 .

부동 소수점을 정수와 비교하지 않습니다 (점없이).


답변

조건, AWK 인쇄 할 경우 당신은 떠들썩한 파티와 AWK 함께 사용할 수있는 1 또는 0을 그 함께하면 절에 의해 해석됩니다 또는 거짓 .

if awk 'BEGIN {print ('$d1' >= '$d2')}'; then
    echo "yes"
else
    echo "no"
fi


답변

grep 2.20이 버전 2.6보다 큰지 확인하는 것과 같이 패키지 버전 인 숫자를 비교할 때주의하십시오.

$ awk 'BEGIN { print (2.20 >= 2.6) ? "YES" : "NO" }'
NO

$ awk 'BEGIN { print (2.2 >= 2.6) ? "YES" : "NO" }'
NO

$ awk 'BEGIN { print (2.60 == 2.6) ? "YES" : "NO" }'
YES

그런 쉘 / awk 기능으로 이러한 문제를 해결했습니다.

# get version of GNU tool
toolversion() {
    local prog="$1" operator="$2" value="$3" version

    version=$($prog --version | awk '{print $NF; exit}')

    awk -vv1="$version" -vv2="$value" 'BEGIN {
        split(v1, a, /\./); split(v2, b, /\./);
        if (a[1] == b[1]) {
            exit (a[2] '$operator' b[2]) ? 0 : 1
        }
        else {
            exit (a[1] '$operator' b[1]) ? 0 : 1
        }
    }'
}

if toolversion grep '>=' 2.6; then
   # do something awesome
fi


답변

물론 실제로 부동 소수점 산술이 필요하지 않은 경우, 항상 정확히 두 개의 십진수가있는 달러 값에 대한 산술은 점을 떨어 뜨리고 (효과적으로 100을 곱한 결과) 정수를 비교할 수 있습니다.

if [[ $((10#${num1/.})) < $((10#${num2/.})) ]]; then
    ...

이를 위해서는 두 값의 소수점 이하 자릿수가 같아야합니다.