Você pode usar os recursos bc
para isso:
echo "a=305; b=15; if ( a%b ) a/b+1 else a/b" | bc
O contexto é que existem 2 variáveis que são divididas em um resultado ponto flutuante da seguinte forma:
printf "%0.5f\n" $(echo 305/15 | bc -l)
20.33333
Como posso sempre arredondar para o próximo inteiro, ou seja, 21 ? Não se trata de arredondar um valor acima de 20,5 a 21, ou seja, o número inteiro mais próximo . Estou perguntando porque quero que um valor seja exatamente o inteiro ou o próximo inteiro, se estiver acima de qualquer maneira. Então, como posso avaliar isso? Com uma declaração if
? Se eu colocar um float , o shell reclama que ele espera um inteiro. Não entendo como aproveitar as informações em perguntas e respostas como este para efetuar uma conversão "para cima "para o próximo inteiro. Algo que eu sinto falta?
Tente:
ceil() {
echo "define ceil (x) {if (x<0) {return x/1} \
else {if (scale(x)==0) {return x} \
else {return x/1 + 1 }}} ; ceil($1)" | bc
}
Então:
$ ceil 5.1
6
$ ceil 5.5
6
$ ceil 5.9
6
para inteiros positivos:
a=305
b=15
echo $((a%b?a/b+1:a/b))
21
Em ksh93
ou zsh
, você pode usar a função ceil()
em expressões aritméticas.
Em zsh
, você precisa carregar primeiro o módulo zsh/mathfunc
( zmodload zsh/mathfunc
)
Em ksh93
e zsh
, note que para uma divisão produzir um float, você precisa de pelo menos um operando para ser um float (caso contrário você obtém uma divisão inteira, como em C), então:
echo "$((ceil(305. / 15)))"
Caso contrário, $((ceil(305 / 15)))
seria $((ceil(20)))
. Em ksh93
, você precisará alterar isso para $((ceil(305, / 15)))
se a localidade do usuário indicar que o separador decimal é uma vírgula.
As saídas acima são 21
em ksh93
e 21.
(para garantir que ainda seja uma flutuação) em zsh
. Se você quiser evitar esse .
, você pode converter em inteiro com:
echo $(( int(ceil(305. / 15)) ))
Por meio de awk
e adicione 0.5
ao resultado, então .f
arredondará para o número mais próximo por si só.
awk 'BEGIN{printf("%.f\n", (305/15)+0.5)}'
21
Se você quiser sua função floor , use -0.5
Suplemento para a resposta do cuonglm.
Se ele arredondar valores negativos para baixo e valores positivos para cima,
pode-se definir além de ceil()
como acima:
ceil2() {
echo "define ceil2 (x) {if (x/1 == x) {return x} \
else { if (x<0) {return x/1 -1} \
else {return x/1 + 1 }}} ; ceil2($1)" | bc
}
Editar: eu mudei se (escala (x) == 0) para if (x / 1 == x); caso contrário, o 6.0 será arredondado para 7
Você pode usar a biblioteca de Velud do awk:
$ velour -n 'print mt_ceil(305 / 15)'
21
Tags shell floating-point