bash의 부동 소수점 숫자

bash의 부동 소수점 숫자

변수가 있고 여기에 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

관련 정보