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