변수가 있고 여기에 1000을 곱한 후 5개의 유효 숫자를 인쇄하고 싶다고 가정해 보겠습니다. zsh
다음을 수행할 수 있습니다.
zsh$ x=2.8026407e+00
zsh$ printf "%.5g\n" "$(( 1000*${x} ))"
zsh> 2802.6
그것도 할 수 있나요 bash
?
bash$ x=2.8026407e+00
bash$ printf "%.5g\n" "$(( 1000*${x} ))"
bash> bash: 1000*2.8026407e+00 : syntax error: invalid arithmetic operator (error token is ".8026407e+00 ")
네이티브 bash가 부동 소수점 연산을 이해하도록 하는 방법이 없다고 생각합니다. 그렇죠? eg 를 사용할 수 있다는 것을 알고 있지만 이것이 가능한지 awk
알고 싶습니다 .bash
bash
( 플로트를 처리할 수 없다는 것은 놀랍지 않지만 , zsh
처리됩니다!)
답변1
bash
부동 소수점 연산 대신 소수점이 0으로 고정되는 고정 소수점 연산(즉, 정수 연산)을 수행합니다. 이것은 당신을 의미합니다할 수 있는이에 대해 매우 기본적인 계산을 수행하십시오.
$ a=1;b=3
$ echo $(( (a*1000 / b ) ))
333
따라서 1/3~3자리는 0.333이다.
이것은 나쁜 생각입니다.
명령줄에서 FP 수학 계산을 수행하는 방법에는 여러 가지가 있습니다. 다음은 두 가지 예입니다.
$ python -c 'print( 1.0 / 3 )'
0.333333333333
$ echo 'scale=3; 1.0/3' | bc
.333
답변2
bash
소수점 수학 연산은 수행할 수 없으며 정수 연산만 수행할 수 있습니다.
robert@pip2:/tmp$ echo $((2 * 3))
6
robert@pip2:/tmp$ echo $((2 * 3.5))
bash: 2 * 3.5: syntax error: invalid arithmetic operator (error token is ".5")
robert@pip2:/tmp$
답변3
예, 대시와 마찬가지로 bash는 실제로 기본적으로 모든 쉘(기본 POSIX)은 37을 인쇄합니다 $((…))
.
$ echo "$((1000/27))"
37
[POSIX][1]에서:
부호 있는 긴 산술만 필요합니다.
ksh, zsh 및 yash(jsh, dash, ash, lksh, mksh 및 bash 제외)에서 부동 소수점 수학을 얻으려면 숫자를 약간 변경해야 합니다.
$ echo $((1000/27.0))
37.037037037037037
하지만 zsh 우선순위와 정밀도에 주의하세요.
$ for sh in ksh yash zsh; do $sh -c 'printf "%20d\n" "$(( 1<<63 - 5))"'; done
288230376151711744
288230376151711744
9223372036854775803
$ for sh in ksh yash zsh; do $sh -c 'printf "%-20s\n" "$((1/10.0))"'; done
0.1
0.1
0.10000000000000001
예상치 못한 zsh 잘림 제한:
$ zsh -c 'echo $((12345678901234567890));echo $((12345678901234567890123))'
zsh:1: number truncated after 19 digits: 12345678901234567890
1234567890123456789
zsh:1: number truncated after 22 digits: 12345678901234567890123
-1363962815083169260
bash에는 printf 함수를 사용하는 해결 방법이 있습니다(~10자리로 제한됨).
$ bash -c 'printf "%.10f\n" "$(( 10**10* 1000/27 ))e-10"'
37.0370370370
하지만 bc
사용 가능한 것이 있는데 왜 귀찮게합니까?
$ echo '1000/27' | bc -l
37.03703703703703703703
[1]: 부호 있는 긴 산술만 필요합니다.
답변4
특별히 bash를 사용하지는 않지만 다음을 사용할 수 있어야 합니다 bc
.
# bc doesn't like exponential numbers in the manner provided. It can be done, but this number is equivalent.
x=2.8026407
printf "1000 * %s" "$x" | bc