시도한 증분으로 0.02로 bash에서 for 루프를 만들고 싶습니다.
for ((i=4.00;i<5.42;i+=0.02))
do
commands
done
그러나 작동하지 않았습니다.
bc
있지만 4.52에서 중지하는 것은 까다로울 수 있습니다. @roaima 제안을 사용하고 2 단계의 보조 변수가 있고 사용i=$(echo $tmp_var / 100 | bc)
시도한 증분으로 0.02로 bash에서 for 루프를 만들고 싶습니다.
for ((i=4.00;i<5.42;i+=0.02))
do
commands
done
그러나 작동하지 않았습니다.
bc
있지만 4.52에서 중지하는 것은 까다로울 수 있습니다. @roaima 제안을 사용하고 2 단계의 보조 변수가 있고 사용i=$(echo $tmp_var / 100 | bc)
답변:
bash
매뉴얼 페이지를 읽으면 다음 정보가 제공됩니다.
for (( expr1 ; expr2 ; expr3 )) ; do list ; done
먼저, 산술 식은
expr1
ARITHMETIC EVALUATION에서 아래에 설명 된 규칙에 따라 평가됩니다. [...]
우리는이 섹션을 얻을
산술 평가
쉘을 사용하면 특정 상황에서 산술 표현식을 평가할 수 있습니다 (
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
k=400;k<542;k+=2
잠재적 인 부동 소수점 산술 문제를 피하는 가장 좋은 해결책이라고 생각합니다 .
bc
) 프로세스를 분기하고 임시 파일 (here-string 용)을 작성하고 실행 bc
하십시오 (실행 파일 및 공유 라이브러리로드 및 초기화하고 기다렸다가 정리하십시오. bc
루프를 수행하기 위해 한 번 실행 하면 훨씬 더 효율적입니다.
i=$(bc <<< "scale...")
또는i=$(echo "scale..." | bc)
<<<
오는 곳) bash
및 속도가 빠릅니다 ksh
. 다른 셸로 전환 bash
하면 다른 구문을 사용하는 것보다 성능이 향상됩니다.
<<<
(zsh을, mksh, 경우 ksh93, YASH)도 부동 소수점를 arithmetics를 (지원 zsh
, ksh93
, yash
)).
쉘에서 루프를 피하십시오.
당신은 산술, 사용하고 싶은 경우 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 유형). 결과적으로 해당 숫자는 10 진수의 이진 근사치이므로 몇 가지 놀라운 점이 있습니다.
$ 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
하거나 사용 하지 않는 한 printf
) 부동 소수점 숫자를 표시하는 awk
데 사용 %.6g
되므로 1,000,000보다 큰 부동 소수점 숫자의 경우 1e6 이상으로 전환하고 높은 숫자 (100000.02)의 소수 부분을 자릅니다. 100000으로 표시됨).
당신은 정말 예를 들어 당신이 그 루프의 각 반복에 대해 특정 명령을 실행하려는 때문에, 쉘 루프를 사용하여, 하나 같이 소수점 산술 지원 부동 쉘을 사용해야하는 경우 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
위 버전 보다 더 우아하게 처리합니다 .
seq
(GNU 명령) 이 없으면 다음 과 같은 함수로보다 안정적인 것을 만들 수 있습니다.
seq() { # args: first increment last
bc << EOF
for (i = $1; i <= $3; i += $2) i
EOF
}
그것은 같은 것들에 더 잘 작동 seq 100000000001 0.000000001 100000000001.000000005
합니다. 그러나 임의로 높은 정밀도의 숫자를 갖는 것은 지원하지 않는 명령에 숫자를 전달하는 경우 큰 도움이되지 않습니다.
unset IFS
첫 번째 예에서 왜 필요한 가요?
IFS=$'\n'
있지만 모든 껍질에서 작동하지는 않습니다. 아니면 IFS='<a-litteral-newline-here>'
읽기가 쉽지 않습니다. 또는 기본값 $ IFS를 사용하거나 IFS를 설정 해제하고 여기에서도 작동하는 것처럼 단어 (공백, 탭, 줄 바꿈)로 대신 나눌 수 있습니다.
IFS
. 왜냐하면 우리는 seq
출력에 분할을 피할 공간이 없다는 것을 알고 있기 때문이다 . 이 예제가에 의존한다는 것을 알기 위해 주로 존재합니다 IFS
. 이는 다른 목록 생성 명령에 중요 할 수 있습니다.
"seq"사용-일련의 숫자 인쇄
첫 번째 증분 마지막
for i in $(seq 4.00 0.02 5.42)
do
echo $i
done