시도한 증분으로 0.02를 사용하여 bash에서 for 루프를 만들고 싶습니다.
for ((i=4.00;i<5.42;i+=0.02))
do
commands
done
그러나 성공하지 못했습니다.
답변1
셸에서 루프를 피하세요.
산술을 수행하려면 awk
다음을 사용하십시오 bc
.
awk '
BEGIN{
for (i = 4.00; i < 5.42; i+ = 0.02)
print i
}'
또는
bc << EOF
for (i = 4.00; i < 5.42; i += 0.02) i
EOF
awk
(와는 반대로 bc
) 프로세서에 적용할 수 있는 부동 소수점 숫자 표현 ( double
아마도IEEE 754유형). 따라서 이 숫자는 십진수의 이진 근사치이므로 놀랄 수도 있습니다.
$ gawk 'BEGIN{for (i=0; i<=0.3; i+=0.1) print i}'
0
0.1
0.2
하나를 추가하면 OFMT="%.17g"
누락된 이유를 확인할 수 있습니다 0.3
.
$ gawk 'BEGIN{OFMT="%.17g"; for (i=0; i<=0.5; i+=0.1) print i}'
0
0.10000000000000001
0.20000000000000001
0.30000000000000004
0.40000000000000002
0.5
bc
임의의 정밀도를 가지므로 그러한 문제는 없습니다.
기본적으로(출력 형식을 수정 하거나 명시적인 형식 사양을 OFMT
사용 하지 않는 한) 부동 소수점 숫자를 표시하기 위해 1,000,000 이상의 부동 소수점 숫자는 1e6 이상으로 전환되고 높은 숫자는 소수 부분(100000.02)이 잘립니다. 100000으로 표시됩니다.)printf
awk
%.6g
예를 들어 루프의 각 반복에 대해 특정 명령을 실행하기 때문에 루프에 셸을 사용해야 하는 경우 부동 소수점 연산을 지원하는 셸을 사용 zsh
하거나 위 명령 중 하나를 사용하여 생성합니다 yash
. ksh93
값 목록(또는 seq
사용 가능한 경우) 및 출력을 반복합니다.
좋다:
unset -v IFS # configure split+glob for default word splitting
for i in $(seq 4 0.02 5.42); do
something with "$i"
done
또는:
seq 4 0.02 5.42 | while IFS= read i; do
something with "$i"
done
프로세서의 부동 소수점 수의 한계를 초과하지 않는 한 seq
부동 소수점 근사치로 인해 발생한 오류는 위 버전보다 더 원활하게 처리됩니다 awk
.
GNU 명령 이 없는 경우 seq
다음과 같이 보다 안정적인 기능을 만들 수 있습니다.
seq() { # args: first increment last
bc << EOF
for (i = $1; i <= $3; i += $2) i
EOF
}
이런 경우에는 이것이 더 효율적일 것입니다 seq 100000000001 0.000000001 100000000001.000000005
. 그러나 임의의 높은 정밀도 숫자를 지원하지 않는 명령에 전달하는 경우에는 큰 도움이 되지 않습니다.
답변2
독서bash
매뉴얼 페이지다음 정보를 고려하면:
for (( expr1 ; expr2 ; expr3 )) ; do list ; done
expr1
먼저, 아래의 산술 평가에 설명된 규칙에 따라 산술 표현식이 평가됩니다. [...]
그러면 우리는 이 부분을 얻습니다.
산술 평가
쉘은 특정 상황에서 산술 표현식의 평가를 허용합니다( 내장 명령 및 산술 확장 참조)
let
.declare
오버플로를 확인하지 않고 고정 너비 정수로 평가가 수행됩니다. [...]
for
따라서 정수가 아닌 값을 가진 루프는 사용할 수 없다는 것이 분명합니다 .
한 가지 해결책은 다음과 같이 나중에 사용하기 위해 모든 루프 구성 요소에 100을 곱하는 것입니다.
for ((k=400;k<542;k+=2))
do
i=$(bc <<<"scale=2; $k / 100" ) # when k=402 you get i=4.02, etc.
...
done
시작 값과 끝 값의 유효 자릿수가 동일한 경우(이 경우 3개) bc
for 루프의 각 반복을 호출하지 않고 대신 문자열 처리를 사용하여 10진수 값을 생성할 수 있습니다.
i="${k%??}.${k#?}" # POSIX; when k=402 you get i=4.02, etc.
i="${k:0:1}.${k:1}" # bash; when k=402 you get i=4.02, etc.
답변3
"seq" 사용 - 일련의 숫자를 인쇄합니다.
seq 첫 번째 증분 마지막
for i in $(seq 4.00 0.02 5.42)
do
echo $i
done
답변4
다른 사람들이 제안한 것처럼 bc를 사용할 수 있습니다.
i="4.00"
while [[ "$(bc <<< "$i < 5.42")" == "1" ]]; do
# do something with i
i="$(bc <<< "$i + 0.02")"
done