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
...
이를 위해서는 두 값의 소수점 이하 자릿수가 같아야합니다.