bash 산술의 나눗셈이 왜 대부분의 백분율을 0으로 계산합니까? 1 $max); do

스크립트에 대해 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

왜 이런거야?



답변

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

답변

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 덕분에)


답변

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

답변

시험

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

🙂

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

man bash

정수만 지원합니다.