bash 산술의 나눗셈이 왜 대부분의 백분율을 0으로 계산합니까?


15

스크립트에 대해 bash arithemetic을 시도하지만 $e끝날 때까지 업데이트되지 않습니다. 출력 자체를 말합니다.

max=5
for e in $(seq 1 1 $max); do 
    percent=$(( $e/$max*100 ))
    echo "echo $e / $max : = $percent"
done

T1; DR : 1..5를 백분율로 표시한다.

출력 :

echo 1 / 5 : = 0
echo 2 / 5 : = 0
echo 3 / 5 : = 0
echo 4 / 5 : = 0
echo 5 / 5 : = 100

왜 이런거야?


1
관련 : Bash는 계산을 수행 할 때 입력에 관계없이 출력으로 정수만 제공합니다 (여기서 설명 된 문제와 달리 작업 순서를
변경해

답변:


24

bash정수가 아닌 산술을 처리 할 수 ​​없습니다. 모든 표현식이 정수인 한 올바른 결과를 제공합니다. 따라서 계산 어딘가에 정수가 아닌 값을 얻는 것을 피해야합니다.

당신이 평가하고 귀하의 경우에서 1 / 5, 2 / 5등은 일부 비 정수 값으로 정수를 bash는 correspondings에서 0 값을 생성하고 결과는 따라 제로로 나오고있다. 나누기와 곱셈의 우선 순위 는 동일하며 동일한 선행 연산자는 항상 식에 배치 될 때 왼쪽에서 오른쪽으로 실행됩니다.

한 가지 해결 방법은 곱셈을 먼저 한 다음 나누기이므로 bash는 정수가 아닌 값을 처리 할 필요가 없습니다. 올바른 표현은

$ max=5; for e in $(seq 1 1 $max); do percent=$(( $e*100/$max )); echo "echo $e / $max : = $percent"; done
echo 1 / 5 : = 20
echo 2 / 5 : = 40
echo 3 / 5 : = 60
echo 4 / 5 : = 80
echo 5 / 5 : = 100

1
하위 표현식 1/5정수아닌 값을 작성하지 않습니다 . 1로 5 0정수 나누기 결과 가 0 이므로 정수 값을 작성 합니다. 추가 조작은 해당 값을 성공적으로 사용합니다 0. 이것은 OP가 의도 한 것이 아니지만 어떤 연산도 정수가 아닌 값을 생성하고 아무 연산도 실패하지 않습니다.
Eliah Kagan

@EliahKagan은 결함을 지적 해 주셔서 감사합니다. 편집했습니다.
souravc

16

Bash는 이런 종류의 산술에서 잘하지 못합니다 ... 문제는 다음과 같습니다.

$ echo $((1/5))
0
$ echo $((2/5))
0
$ echo $((4/5))
0
$ echo $((4/5))
0

정수가 아닌 값을 처리해야하는 경우 bc

$ max=5; for e in $(seq 1 1 "$max"); do percent=$(bc <<< "scale=1 ; $e/$max*100") ; echo "echo $e / $max : = ${percent%.*}"; done
echo 1 / 5 : = 20
echo 2 / 5 : = 40
echo 3 / 5 : = 60
echo 4 / 5 : = 80
echo 5 / 5 : = 100

(출력을 정수로 형식화하는 방법을 지적한 @Arronical 덕분에)


다시 한 번 감사드립니다!
Cybex

1
당신은 트리밍 할 수 .0변경하여 출력에서을 $percent 로 에코에 ${percent%.*}:)
Arronical

11

bash와 달리 awk는 완전한 부동 소수점 산술을 제공합니다. 예를 들면 다음과 같습니다.

$ awk -v max=5 'BEGIN{for (e=1;e<=max;e++) print "echo " e " / " max " : = " 100*e/max}' 
echo 1 / 5 : = 20
echo 2 / 5 : = 40
echo 3 / 5 : = 60
echo 4 / 5 : = 80
echo 5 / 5 : = 100

5

시험

percent=$(( $e*100/$max ))

:)

다음의 산술 평가 섹션을 참조하십시오.

man bash

정수만 지원합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.