FWIW,
prob=$(echo "0.0139" | bc)
é desnecessário - você pode apenas fazer
prob=0.0139
Por exemplo,
$ prob=0.0139; echo "scale=5;1/$prob" | bc
71.94244
Existe outro problema com o seu código, além do problema de underflow. A aritmética de bash pode não ser adequada para lidar com números grandes na sua função nCk2
. Por exemplo, em um sistema de 32 bits, passar 10 para essa função retorna um número negativo , -133461297271.
Para lidar com o problema de underflow, você precisa calcular em uma escala maior, conforme mencionado nas outras respostas. Para os parâmetros dados no OP, uma escala de 25 a 30 é adequada.
Eu reescrevi seu código para fazer toda a aritmética em bc
. Em vez de apenas direcionar comandos para bc
via echo
, escrevi um script bc
completo como aqui documento dentro de um script Bash, já que isso facilita a passagem de parâmetros do Bash para 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
saída
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