Tenho um arquivo em uma máquina Linux, com um número por linha:
3073771824
1513517589
4982173058
1539400944
3175320163
5247018359
14359014635
....
Como posso multiplicar cada um por 1,03 (3%) e depois arredondar o resultado, retirando a vírgula? Por exemplo:
3073771824 * 1,03 = 3165984978,72 | I would have the result 3165984979
1513517589 * 1,03 = 1558923116,67 | I would have the result 1558923117
....
Eu sei que o awk pode arredondar:
echo 2.5 | awk '{print int($1+0.5)}'
arredonda para 3, mas há "." e não ",".
Vamos supor que seus números estejam em um arquivo
numbers
e que o seulocale
seja usado,
como ponto decimal, comofr_FR.UTF-8
. Também adicionei10000000000
como um dos seus números de origem para demonstrar que o arredondamento não ocorre para resultados inteiros:Se os números de entrada puderem ser negativos, o código de arredondamento precisará ser mais complexo para arredondar a partir de zero. Deixe-me saber se isso pode ser um problema e incluirei um código para resolvê-lo.
Resultado, incluindo as colunas de depuração, usando seus dados
Resultado sem depuração, usando seus dados
Remova ou comente a
printf
linha para remover as duas colunas de depuração. Você pode travar oawk
comando em uma única linha, se necessário, removendo os comentários e concatenando as linhas restantes.Agora, em relação ao local. O
awk
programa espera que suas constantes numéricas sejam usadas.
como ponto decimal, independentemente da localidade; este é um requisito sintático. Por exemplo,print 3,1
imprime dois valores separados por um espaço (3 1
), masprint 3.1
imprime um único valor decimal (3.1
).Se você estiver usando GNU,
gawk
você pode especificar o-N
sinalizador (--use-lc-numeric
) para que ele leia e grave valores de dados e converta strings em números usando sua localidade:No entanto, na sua pergunta você está lendo e escrevendo valores inteiros, portanto o ponto decimal da localidade não é relevante.
Usando Moleiro :
Para arredondar números para o número inteiro superior, o seguinte comando pode ser usado.
Para ser claro, na
echo 2.5 | awk '{print int($1+0.5)}'
sua pergunta, esse código awk não está arredondando para cima3
, está adicionando0.5
e arredondando para baixo para 3 (mas já é 3, entãoint()
na verdade não está arredondando). Se você começasse com2.4
em vez de2.5
o resultado seria2
, não3
como você esperaria do arredondamento, porqueint()
sempre arredonda para baixo.Usando qualquer awk:
Se você usar
,
em vez de.
como ponto decimal em sua localidade, é possível usar1,03
em vez de1.03
em seu cálculo, mas eu não recomendaria (recomendo usarLC_ALL=C
por padrão), pois isso requer código diferente em diferentes variantes do awk e não é tão simples quanto parece, por exemplo, com GNU awk precisamos adicionar-N
para dizer ao gawk para usar sua localidade para isso, e então escrever1,03
como uma string"1,03"
em vez de um número literal e confiar em usá-lo em um contexto aritmético (multiplicando) para converta-o em um número porque um literal,
significa coisas diferentes em um script awk:Consulte https://www.gnu.org/software/gawk/manual/gawk.html#Locale-influences-conversions para obter mais informações sobre isso.
Em geral, porém, o que você está pedindo é uma função
ceil()
(para " teto ") conforme mostrado acima. É importante incluir zero e números negativos em seu exemplo quando você estiver procurando por qualquer tipo de função de arredondamento, pois é fácil errar, usando este arquivo de entrada:podemos testar uma
ceil()
função:e a
floor()
função oposta:O acima funciona porque
int()
trunca em direção a zero (do manual GNU awk):então
int()
, um número negativo já faz o que você deseja para uma função teto, ou seja, arredondar para cima, e você só precisa adicionar 1 ao resultado seint()
arredondar para baixo um número positivo.Usei
0.000001
, etc. nas amostras para evitar que as pessoas obtivessem um falso positivo testando uma solução que adiciona algum número como0.9
e depoisint()
ing.Observe também que
ceil()
pode ser abreviado para:mas escrevi como acima para maior clareza (não está claro/óbvio se o resultado
x>int(x)
é 1 ou 0) e eficiência (ligue apenasint()
uma vez em vez de duas).você poderia usar um script no qual os números são sua entrada. Aqui está um exemplo de uma função que ajudaria.
Certamente sou inclinado a usar Perl, já que muitas vezes é minha ferramenta preferida para fazer coisas, mas sem usar o próprio Bash ou ferramentas mais simples como
bc
, que não lidam com arredondamentos nativamente (é claro que ainda pode ser facilmente implementado, mas ainda assim), Perl pode ter a maneira mais simples de usarceil()
a partir doPOSIX
módulo. Devido à forma como o Perl funciona, o preenchimento que aparentemente lidera os números será tratado de forma automática e elegante:Se desejar preservar o preenchimento (você precisará ajustar
11
se os números resultantes tiverem mais de 11 dígitos):Usando Raku (anteriormente conhecido como Perl_6)
Raku pode ser usado de maneira semelhante à excelente resposta Perl de @kos. A rotina do Raku
ceiling
é integrada, portanto nenhum módulo precisa ser chamado na linha de comando. Aput
chamada adiciona um terminador de nova linha para você e, no primeiro exemplo, parênteses extrasput
não são necessários.Entrada de amostra:
Saída de amostra:
Isso levanta a questão do que fazer se um número não-inteiro for encontrado na entrada. Ignorar essa linha é o mais fácil, mas (se isso causar desalinhamento dos dados colunares), um espaço reservado como "NaN" pode ser usado. Ambas as correções demonstradas abaixo (coagir
+$_
e testar):https://docs.raku.org/routine/ceiling
https://raku.org
Já faz muito, muito tempo desde que usei
awk
, e já faz mais tempo ainda desde que aprendi matemática de números inteiros.Você terá que verificar se seus números não ultrapassam os limites, mas...
fornecerá um valor inteiro que é 103% do número inteiro
x
arredondado para cima .Se você precisar arredondar de zero e puder ter valores negativos para começar, use alguma lógica para subtrair 99 em vez de adicionar 99 (para valores positivos).
Exemplos simples:
Experimente você mesmo com alguns números.
Além disso, consulte utilitários
dc
ebc
dois programas de calculadora simples . Para uma transformação de dados simples como essa, isso pode ser ainda mais fácil do que lidar com a riqueza doawk
.