Numeric-Data
bc scale:如何避免四捨五入?(計算小二項式機率)
以下程式碼計算 n 次試驗中成功事件 k 的二項式機率:
n=144 prob=$(echo "0.0139" | bc) echo -e "Enter no.:" read passedno k=$passedno nCk2() { num=1 den=1 for((i = 1; i <= $2; ++i)); do ((num *= $1 + 1 - i)) && ((den *= i)) done echo $((num / den)) } binomcoef=$(nCk2 $n $k) binprobab=$(echo "scale=8; $binomcoef*($prob^$k)*((1-$prob)^($n-$k))" | bc) echo $binprobab
當 $passedno (=k) 輸入“5”時,結果顯示為 0(而不是“0.03566482”),而通過“4”我得到“.07261898”。
如何在不獲取輸出的捨入值的情況下以 8 位十進制數字的給定精度列印輸出?
FWIW,
prob=$(echo "0.0139" | bc)
是不必要的 - 你可以做
prob=0.0139
例如,
$ prob=0.0139; echo "scale=5;1/$prob" | bc 71.94244
除了下溢問題之外,您的程式碼還有另一個問題。Bash 算法可能不足以處理
nCk2
函式中的大量數字。例如,在 32 位系統上,將 10 傳遞給該函式會返回一個負數-133461297271。如其他答案中所述,要處理下溢問題,您需要進行更大規模的計算。對於 OP 中給出的參數,25 到 30 的範圍就足夠了。
我已經重寫了你的程式碼來做所有的算術
bc
。我在 Bash 腳本中編寫了一個完整的腳本作為此處的文件,而不僅僅是將命令通過管道傳輸到bc
via ,因為這樣可以輕鬆地將參數從 Bash 傳遞到.echo``bc``bc
#!/usr/bin/env bash # Binomial probability calculations using bc # Written by PM 2Ring 2015.07.30 n=144 p='1/72' m=16 scale=30 bc << EOF define ncr(n, r) { auto v,i v = 1 for(i=1; i<=r; i++) { v *= n-- v /= i } return v } define binprob(p, n, r) { auto v v = ncr(n, r) v *= (1 - p) ^ (n - r) v *= p ^ r return v } sc = $scale scale = sc outscale = 8 n = $n p = $p m = $m for(i=0; i<=m; i++) { v = binprob(p, n, i) scale = outscale print i,": ", v/1, "\n" scale = sc } EOF
輸出
0: .13345127 1: .27066174 2: .27256781 3: .18171187 4: .09021610 5: .03557818 6: .01160884 7: .00322338 8: .00077747 9: .00016547 10: .00003146 11: .00000539 12: .00000084 13: .00000012 14: .00000001 15: 0 16: 0
介紹
假設您要計算 7 佔 116 的百分比。
您只需將 7 除以 116 並將結果乘以 100。
它應該是這樣的:
bc -l <<< '(7/116)*100' **6.03448275862068965500**
問題
你希望它精確到小數點後兩位,所以你添加
scale=2;
,期望這個:bc -l <<< 'scale=2; 100*(7/116)' **6.00**
您嘗試增加
scale
值:bc -l <<< 'scale=3; 100*(7/116)' **6.000**
出於某種原因
scale=4;
,精確到 2 個位置,但有這些尾隨0
sbc -l <<< 'scale=4; 100*(7/116)' **6.0300**
原因
解決方案
理想的解決方案是
bash
/原sh
生支持浮點計算。他們為什麼不呢?我不知道。不做好像很傻。在此之前,您可以使用這些:公元前
- 定義一個變數。
- 設置
scale
.- 除以 1。
bc -l <<< "x=(7/116)*100; scale=2; x/1" **6.03**
列印
- 用…包裝
bc
命令以進行命令替換。"$(``)"
- 傳給
printf
.%.2f
在格式字元串中使用(%f
表示浮點數,.2
表示精確到小數點後 2 位(如scale=2
))。printf '%.2f\n' "$(bc -l <<< '(7/116)*100')" **6.03**
awk
- 僅供參考:
awk
也可以做算術- 我認為
echo
以某種方式打破了互動循環。可能有更好的方法來做到這一點。- 它不能讓您控制浮點數。我相信它可以以某種方式完成。
echo | awk '{print 100*(7/116)}' **6.03448**