Essa é a maneira correta de fazer a conversão de float para número inteiro no bash? Existe algum outro método?
flotToint() {
printf "%.0f\n" "$@"
}
bash
floating-point
Rahul Patil
fonte
fonte
%.0f
arredondará para cima ou para baixo. É isso que você quer? Você pode usarprintf "%d\n" "$@" 2>/dev/null
para cortar a fração.Respostas:
bater
Em
bash
, isso é provavelmente tão bom quanto ele ganha. Isso usa um shell embutido. Se você precisar do resultado em uma variável, poderá usar a substituição de comandos ou obash
específico (embora agora também seja suportado porzsh
):Você poderia fazer:
Mas isso removeria a parte fracionária em vez de fornecer o número inteiro mais próximo e não funcionaria para valores
$float
iguais1.2e9
ou.12
por exemplo.Observe também as possíveis limitações devido à representação interna dos carros alegóricos:
Você recebe um número inteiro, mas é provável que não possa usá-lo em nenhum lugar.
Além disso, como observado pelo @BinaryZebra, em várias
printf
implementações (bash, ksh93, yash, não GNU, zsh, dash), ele é afetado pelo código do idioma (o separador decimal que pode ser.
ou,
).Portanto, se seus carros alegóricos são sempre expressos com o período como separador decimal e você deseja que ele seja tratado como tal,
printf
independentemente do código do idioma do usuário que está invocando seu script, será necessário corrigir o código do idioma para C:Com
yash
, você também pode fazer:(ver abaixo).
POSIX
não é POSIX, pois
%f
não é necessário ter suporte do POSIX.POSIXly, você pode fazer:
Esse não é afetado pelo código do idioma (a vírgula não pode ser um separador decimal,
awk
pois já existe um caractere especial na sintaxe (oprint 1,2
mesmo queprint 1, 2
passar dois argumentos paraprint
)zsh
Em
zsh
(que suporta aritmética de ponto flutuante (o separador decimal é sempre o período)), você tem arint()
função matemática para fornecer o número inteiro mais próximo como ponto flutuante (como emC
) eint()
para fornecer um número inteiro a partir de um ponto flutuante (como emawk
). Então você pode fazer:Ou:
No entanto, observe que, enquanto
double
s pode representar números muito grandes, números inteiros são muito mais limitados.ksh93
O ksh93 foi o primeiro shell tipo Bourne a suportar aritmética de ponto flutuante. O ksh93 otimiza a substituição de comandos, não usando um pipe ou bifurcação quando os comandos são apenas comandos internos. assim
não bifurca. Ou melhor ainda:
que não bifurca, mas também não dá todo o trabalho de criar um ambiente de subcamação falso.
Você também pode fazer:
Mas cuidado com:
Você também pode fazer:
Mas como para
zsh
:Cuidado com o fato de que a
ksh93
aritmética de ponto flutuante honra a configuração do separador decimal no código do idioma (mesmo que,
seja um operador matemático ($((1,2))
seria 6/5 em um código de idioma francês / alemão ... e o mesmo$((1, 2))
que é 2 em um código de idioma em inglês) .yash
O yash também suporta aritmética de ponto flutuante, mas não possui funções matemáticas como
ksh93
/zsh
'srint()
. Você pode converter um número em número inteiro usando o binário ou o operador, por exemplo (também funciona em,zsh
mas não emksh93
). Observe, no entanto, que ele trunca a parte decimal, não fornece o número inteiro mais próximo:yash
honra o separador decimal da localidade na saída, mas não para as constantes literais de ponto flutuante em suas expressões aritméticas, o que pode causar surpresas:É bom, de certa forma, que você possa usar constantes de ponto flutuante em seus scripts que usam o período e não tenha que se preocupar que ele pare de funcionar em outros locais, mas ainda assim seja capaz de lidar com os números expressos pelo usuário desde como você se lembra de fazer:
fonte
int=${float%.*}
funcionou muito bem no meu script bash (versão 3.2.57 (1) -release)) em um Mac (versão 10.13.4 (17E199)).,
o valor decimal. Veja a seção sobreLC_ALL=C
bc
- Uma linguagem de calculadora de precisão arbitráriaint (float) deve se parecer com:
Para arredondar melhor use isso:
Exemplo:
fonte
float=-2; echo "($float+0.5)/1" | bc
dá-1
.A resposta anterior enviada estava quase correta: "Você poderia fazer:
Mas isso removeria a parte fracionária em vez de fornecer o número inteiro mais próximo e não funcionaria para valores de $ float como 1,2e9 ou 0,12, por exemplo ... "
Apenas use
${float%%.*}
.fonte
Um hacky muito simples é
Saída de amostra
fonte
sed
, mas acut
solução é mais simples. Eu prefirosed
oucut
como eles são IMHO mais acessível em alvos embutidos do queawk
(que ainda é bastante comum atravésbusybox
debc
).Relacionado:
Complementando a resposta de Stéphane Chazelas
awk
:fonte
printf
faz, ou se há algum outro motivo para preferir o awk do que o incorporadoprintf
.