Bash에서 부동 소수점 값 비교

Bash에서 부동 소수점 값 비교

내 if 표현식은 항상 TRUE로 평가됩니다. ROTATION 변수는 0.000 또는 90.000으로 부동 소수점 값입니다.

ROTATION="$(mediainfo --Inform="Video;%Rotation%" $VIDEO$ORIGINALEXTENTION)"
echo $ROTATION

ROTATION_PARAMETER=""

if [ $ROTATION -eq 90 ]
then
    ROTATION_PARAMETER=" --rotate=4"
fi

echo $ROTATION_PARAMETER

변수와 값을 비교하는 방법은 무엇입니까?

답변1

이를 달성하려면 bc 명령을 사용할 수 있습니다.

echo "$ROTATION == 90"|bc

거짓이면 0을 얻게 되고, 참이면 1을 얻게 됩니다.

PS 동등한 부동 소수점 수를 비교하는 것은 프로그래밍에서 가장 현명한 방법이 아니라는 점에 유의하십시오. :)

답변2

문자열이기 때문에 연결된 여러 문자열을 서로 비교할 수 있습니다. 균형 잡힌 값은 여러 쉘 테스트를 동시에 처리하는 쉬운 방법을 제공합니다.

[ "${num#90.}${num%[!0]*}" = "90${num%[!0]*}" ] && do_it

하지만 이는 $num절대 숫자인 경우에만 작동합니다. 다음과 같은 정수 값의 유효성을 검사할 수 있습니다 $num.

[ "$num" -eq "$num" ]

또는 다음과 같은 부동 소수점:

[ "${#num}${num#*.}" -ne "${num%.*}${#num}" ]

하지만 case일반적으로 가장 좋은 방법은...

case ".${num##*[!-.0-9]*}" in
(.|.[!9]*|.9[!0]*|.90.*[!0]*) 
! :;;esac 

외부 유틸리티에 관한 한, 나는 일반적으로 임의의 시스템 명령을 실행하는 데 사용할 수 있기 때문에 dc이것을 선호합니다.bc

dc -e '[!echo execute arbitrary system command]s=' \
   -e '90 90.0 =='

괄호 안의 모든 내용 []은 문자열이며, 메인 스택의 처음 두 값이 명령으로 실행되는 s경우 명명된 배열에 저장됩니다.=dc(여기서는 90과 90.0) =또 다른. !문자열의 첫 번째 연산자는 !뒤에 오는 모든 연산자를 시스템 명령으로 실행하는 연산자입니다. 연산자를 사용하여 조건부 실행을 dc위해 입력에서 더 많은 스크립트를 읽을 수도 있습니다 .?

그러나 표현식 -e구문은 GNUism입니다. Heredoc을 사용하여 동일한 효과를 얻거나 명령을 표준 입력으로 다시 파이프할 수 있습니다.

예를 들어:

! dc -e '[!kill -PIPE "$PPID"]s= 90 90.0 ==' && do_it

답변3

문자열처럼 값을 비교할 수 있습니다.

{ printf "[ %.3f == %.3f ]\n" $ROTATION 90 | bash ; } && ROTATION_PARAMETER=" --rotate=4"

심지어

[ $(printf "%.3f == %.3f" $ROTATION 90) ] && ROTATION_PARAMETER=" --rotate=4"

일부 로케일에는 소수 구분 기호가 필요하므로 ,해당 형식을 사용해야 합니다..$ROTATION90,000

답변4

다음과 같이 부동 소수점 값을 처리하는 데 더 적합한 스크립팅 언어를 호출하는 것을 고려해 보세요.

ROTATION=...
if $( perl -e 'use POSIX "fmod";if(fmod($ENV{ROTATION}, 90.0)<0.001) {exit(0)} else{exit(1)}' )
then...

(아마도 역방향 종료 반환 코드 사용)

관련 정보