쉘의 부동 소수점 비교

쉘의 부동 소수점 비교

이를 기반으로 쉘 스크립트에서 부동 소수점 값을 비교하고 있습니다.인용하다. 다음은 스크립트 내용입니다

num1=50.960
num2=6.65E+07
echo "${num1} < ${num2}" | bc

스크립트를 실행하면 출력이 "0"입니다. 그러나 비교에 따르면 "1"이어야 합니다. 비교가 예상대로 작동하지 않는 이유를 이해해야 합니까?

답변1

유틸리티 가 원하는 번호를 bc인식하지 못합니다 .6.65E+07

OpenBSD에서는 E16진수이므로 6.65E6.664(6.65 + 0.014)이고, +077을 더하면 13.664가 되는데 이는 분명히 50.960보다 작습니다. GNU 시스템에서도 6.65E이는 6.659여러분이 원하는 것이 아닙니다.

대신에 num2문자열 6.65*10^7또는 66500000.

$ num1=50.960; num2='6.65*10^7'; printf '%s < %s\n' "$num1" "$num2" | bc
1

답변2

num2를 그대로 사용하려면 awk를 사용할 수 있습니다.

awk -v num1="$num1" -v num2="$num2" 'BEGIN{exit num1<=num2}'

두 숫자를 비교하여 num1이 num2보다 작으면 1을 종료하고, 그렇지 않으면 0을 종료합니다.

참고: num1과 num2가 같으면 1이 종료됩니다. 이는 이 경우 bc에서 볼 수 있는 것과 동일한 동작입니다. 이 경우 0을 종료하려면 를 사용해야 <합니다 <=.

답변3

dc한 가지 방법은 먼저 공학 표기법을 부동 소수점으로 변환하여 이 유틸리티를 사용하는 것입니다.

num1=50.960
num2=6.65E+07

set -- "$num1" "$num2"

e2f() {
  case $1 in
    *[eE]*) :;;
    *) set -- "$1e0"
  esac
  set -- "${1//+/}"
  set -- "${1//-/  _}"
  set -- "${1//[eE]/ 10 }"
  echo "$1^*"
}

eCmp() {
  test "$(dc -e "
15k[1p]sa$(e2f "$1") $(e2f "$2")r>a")" = 1
}

## and then...
if eCmp "$@"
then
  echo "$1 > $2"
else
  echo "$1 <= $2"
fi

산출:

50.960 <= 6.65E+07

답변4

예, bc다양한 수학 연산을 수행하는 것이 가능합니다. 그러나 수레를 이해하지 못합니다. 최신 쉘의 printf는 부동 소수점 숫자를 이해할 수 있지만 수학은 할 수 없습니다.

그들과 함께하자:

$ num1=50.960
$ num2=6.65E+07
$ printf '%f < %f\n' "$num1" "$num2" | bc -l
1

관련 정보