Como imprimo pi (3.14159)? [fechadas]


35

Que comando poderia imprimir pi para mim? Quero especificar quantos dígitos serão impressos. Não encontrei nada on-line. Eu só quero poder imprimir pi.


28
Faça a sua escolha de idiomas: rosettacode.org/wiki/Pi
Mark Plotnick

4
Note-se que ele fica mais divertido se você quer mais dígitos que cerca de 15.
Thorbjørn Ravn Andersen

2
@DisplayName: significa que você não pode mais usar nenhum programa que armazene / calcule internamente o PI usando valores de ponto flutuante de precisão dupla (que geralmente é o tipo de dados FP "embutido" de maior precisão disponível na maioria dos idiomas).
Matteo Italia

5
Minha solução, décadas atrás, antes que isso fosse comumente fornecido pelas bibliotecas de idiomas, era memorizá-lo em mais lugares do que os pontos flutuantes que eu estava usando: 3,1415926535897932384626 geralmente está perto o suficiente para fins práticos e até os mais impraticáveis ​​- qualquer coisa real -world terá mais erros do que nos outros números e, para os teóricos, eu ficaria com o valor simbólico e não numérico.
keshlam

3
O interesse @syntaxerror é irrelevante. Se você colocasse uma pergunta solicitando fotos nuas de celebridades, receberia milhares de visualizações e, possivelmente, votos positivos. Isso não aparece no tópico. Esta questão é um exemplo clássico de muito amplo. Basta olhar para o número de respostas. Observe também que o OP não especificou nenhuma limitação que torna as respostas possíveis essencialmente infinitas. De qualquer forma, o fechamento não está excluindo. A pergunta e todas as suas 23 respostas ainda estarão aqui. Fechar significa apenas que não são mais aceitas respostas. Realmente precisamos de ainda mais maneiras de imprimir π?
terdon

Respostas:


52

Você pode usar este comando:

echo "scale=5; 4*a(1)" | bc -l
3.14159

Onde escala é o número de dígitos após o ponto decimal.

Referência: http://www.tux-planet.fr/calculer-le-chiffre-pi-en-ligne-de-commande-sous-linux/


12
Versão mais curta em bashe outras conchas de apoio aqui strings: bc -l <<< "scale=5; 4*a(1)".
Pabouk

2
Gostaria de saber quantos dígitos isso pode levar?
DisplayName

4
@DisplayName bastante. scale=1000fornece 999 dígitos corretos rapidamente (o último dígito é 1 por zero, razoável, pois estamos computando pi / 4 e depois multiplicando por 4). scale=4000fornece 4000 dígitos corretos em alguns segundos. scale=10000demora mais do que tenho paciência, mas provavelmente fornece 9999 ou 10.000 dígitos corretos.
Hbbs #

4
Isso gera um resultado incorreto na minha máquina, digitando 'echo "scale = 5; 4 * a (1)" | bc -l 'retorna 3,14156, quando o último dígito deve ser 9
Jordan Bentley

1
@ JordanBentley, adicionei uma resposta com o arredondamento correto do resultado .
Pabouk

61

Se você tex(1)instalou:

tex --version | head -1 | cut -f2 -d' '

13
Isso quase vale a pena ser votado apenas por ser inteligente. Embora a saída disso mude quando você atualiza o pacote. Devemos considerar isso um recurso ou um bug?
um CVn

8
@ MichaelKjörling Na verdade, ele muda para ser uma aproximação mais precisa do pi.
Abrixas2

@ Abrixas2 Sim, eu sei. Com a última versão do TeX sendo a versão π.
um CVn

30
@DavidRicherby Menos dígitos podem ser impressos por meio de uma chamada adicional de cut. Mais dígitos podem ser impressos, aguardando muito tempo e executando o comando novamente.
6114 Steven D

1
@Ruslan depende da implementação. Eu esperaria neste caso em particular que isso fosse feito "certo".
Thorbjørn Ravn Andersen

23

Para imprimir com precisão arbitrária, você pode usar bce a fórmula pi = 4*atan(1):

# bc -l
scale=<your precision>
4*a(1)

2
Há algo de engraçado nessa scaleopção, pi = 3.141592..mas com isso echo "scale=5; 4*a(1)" | bc -l => 3.14156eu esperaria ver 3.14159?
Fduff

7
scaleespecifica a precisão a ser usada no cálculo; portanto scale=5, nenhuma operação utilizará mais de cinco dígitos fracionais para qualquer operação atômica.
precisa saber é o seguinte


20

Se você deseja algo que possa calcular o valor de π, existem várias abordagens. Talvez a solução mais óbvia seja usar um pacote pronto como pi(link do pacote Debian) , que se a descrição do pacote Debian for confiável, pode calcular o valor com uma precisão arbitrária, limitada apenas pela memória.

pié na verdade um exemplo incluído na biblioteca CLN (Class Library for Numbers) . Inclui aplicativos de exemplo que fornecem ferramentas para gerar comprimentos arbitrários de números como Pi, Fibonacci, etc. Pacotes CLN estão disponíveis pré-empacotados no Debian / Ubuntu (é para isso que o link Debian acima está apontando).

Exemplos
$ ./pi 10
3.141592653

$ ./pi 20
3.1415926535897932384

NOTA: A fonte desses exemplos está aqui na fonte da base de código CLN .

Outras distros

Fedora

No Fedora eu tive que baixar o tarball de origem e construí-lo, mas ele é construído com pouco esforço. Por qualquer motivo, o pacote clnno Fedora inclui apenas a biblioteca, mas negligencia os exemplos que estão disponíveis na versão Debian / Ubuntu (acima).

Arco

Arch fornece o mesmo programa no clnpacote (graças Amphiteót ).


Sim, heh, eu quis dizer o valor total que acabei de digitar o que tinha na minha cabeça.
DisplayName 5/14

2
O "valor total" ?? Significado o que ...?
Kyle Strand

2
@DisplayName leia o restante da resposta. Um programa dedicado piparece exatamente o que você está procurando. Você pode fazer coisas como pi 300imprimir os primeiros 300 dígitos, por exemplo.
terdon

3
@KyleStrand Eu descobri uma resposta realmente maravilhosa para isso, que esse comentário é muito estreito para conter. Ei, funcionou para Fermat !
terdon

Eu adoraria saber por que isso recebeu dois votos negativos. As pessoas que votaram negativamente não leram a resposta antes de decidirem que não era útil?
um CVn

17

Para até um milhão de dígitos, você pode usar o seguinte (aqui para 3000 dígitos):

curl --silent http://www.angio.net/pi/digits/pi1000000.txt | cut -c1-3000

2
Isso tem o benefício adicional de que ele deve estar razoavelmente próximo da complexidade O (1). Ou talvez isso não seja um benefício, afinal ...
um CVn

7
Além disso, é difícil dizer que qualquer interação de rede tem complexidade de tempo O (1) em um mundo prático. : P
HalosGhost

2
@HalosGhost Para os nossos propósitos (em comparação com a computação n dígitos de pi de cada vez), transferir uma quantidade fixa de dados a partir de um servidor específico através de uma rede é provável que seja eficaz ó (1), ao passo que a computação n dígitos de pi é provável que seja pelo menos algo como O (log n) e possivelmente mais alto (não estou familiarizado com esses algoritmos). O download real dos dados provavelmente levará muito mais tempo do que a sobrecarga para iniciar o download; portanto, o tempo de download é predominante e você chega a algum lugar nas proximidades de O (1), dada uma taxa de transmissão de dados razoavelmente fixa. Daí O (1).
um CVn

4
@ MichaelKjörling Quando você diz O (1), você realmente não quer dizer O (n)? O tempo de download é linear no número de dígitos que você precisa, daí O (n).
CodesInChaos

1
@CodesInChaos Não, o tempo de download é constante (dada a taxa de transmissão constante) porque você está baixando um número constante de dígitos (um milhão aqui). A menos que (neste caso específico) a curvatura seja inteligente o suficiente para imprimir durante o download e interrompa o download assim que o tubo quebrar porque cutsair? Se for esse o caso, eu concordo, seria O (n).
um CVn

15

Algumas das outras respostas mostram dígitos incorretos nos últimos locais da saída. Abaixo está uma variação da resposta usandobc mas com um resultado arredondado corretamente. A variável scontém o número de dígitos significativos (inclusive 3na frente do ponto decimal).

Rodada para cima

$ bc -l <<< "s=5; scale=s+2; pi=4*a(1)+5*10^(-s); scale=s-1; pi/1"
3.1416

Arredondar para baixo (truncar)

$ bc -l <<< "s=5; scale=s+2; pi=4*a(1); scale=s-1; pi/1"
3.1415

Explicação do arredondamento

O arredondamento é realizado diretamente em bc. Isso não tem a limitação do comando printfque usa a representação do doubletipo de linguagem C para os números que possuem uma precisão de cerca de 17 dígitos significativos. Veja a resposta com printfarredondamento .

scale=s-1define o número de dígitos para truncar. pi/1divide o resultado por 1 para aplicar o truncamento. Simples pinão trunca o número.

O arredondamento para metade exige a adição de 5 ao primeiro dígito que será cortado (5 × 10- s ), de modo que, no caso de dígitos maiores que 5, o último dígito que permanecerá será incrementado.

A partir dos testes de hobbs , parece que três dígitos adicionais que serão arredondados / cortados ( scale=s+2) serão suficientes mesmo para números muito longos.

Here strings

Os exemplos acima usam aqui strings que são suportadas, por exemplo bash, em , kshe zsh. Se o seu shell não suportar aqui, use string echoe pipe:

$ echo "s=5; scale=s+2; pi=4*a(1); scale=s-1; pi/1" |  bc -l
3.1415

2
O cálculo de três dígitos adicionais para fins de arredondamento não é o "arredondamento correto", como você afirma em um comentário. Primeiro, você não tem um limite para o erro da computação. Se ele pode estar errado em 3 unidades em último lugar, conforme reivindicado pelo fduff, por que não estaria errado em 1000 unidades em último lugar? Segundo, consulte "o dilema do fabricante de mesas".
Complicado, veja a biografia

12

perl uma linha (usando bignum ):

perl -Mbignum=bpi -wle 'print bpi(NUM)'

por exemplo

perl -Mbignum=bpi -wle 'print bpi(6)'
3.14159

Para 10.000 dígitos: perto de 8 minutos em perl, menos de 4 em bc. Não é o mais rápido.
Isaac

9

Com python2:

$ python -c "import math; print(str(math.pi)[:7])"
3.14159

4
Por uma questão de integridade, esta solução é específica para python2.
precisa saber é o seguinte

Após a edição, com (..)isso funciona em Python 2 e 3. Apenas parece ter 12 dígitos.
Anthon

$ Python -c "matemática importação; impressão (formato (math.pi, '.400f'))" 3,1415926535897931159979634685441851615905761718750000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Artem Shitov

1
@ArtemShitov - meu mau, tente importar gmpy2 (se tiver instalado): python -c "import gmpy2; print(str(gmpy2.const_pi(8192))[:400])". Aumente a precisão para obter mais dígitos ... por exemplopython -c "import gmpy2; print(str(gmpy2.const_pi(16384))[:4400])"
don_crissti

1
O mais rápido que pude encontrar foi from mpmath import mp; mp.dps = 1000000 ; print(mp.pi)apenas alguns segundos para um milhão de dígitos. Nada mal !!!.
Isaac

7

Usando Ruby:

require "bigdecimal"
require "bigdecimal/math"
include BigMath

BigDecimal(PI(100)).round(9).to_s("F")

3.141592654

1
Um liner:ruby -e 'require "bigdecimal"; require "bigdecimal/math"; include BigMath; puts BigDecimal(PI(100)).round(9).to_s("F")'

4

Na festança:

$ read -a a <<< $(grep M_PIl /usr/include/math.h) ; echo ${a[3]} | tr -d L
3.141592653589793238462643383279502884

@ Amphiteóth afmtoditprecisa groffestar instalado. Aqui no Ubuntu (e sabores), é não padrão. JFYI.
Syntaxerror 11/11/14

@syntaxerror Obrigado, bom ponto! Eu removi meu exemplo. Meu ponto foi justamente quando a leitura desta IA foi executada grepno meu sistema procurando a constante e a encontrei em mais de um local. Por isso foi +1 para mim!

3

Muito simples em PHP usando a função pi () integrada:

<?php 
echo round(pi(), 2);
?>

1
Você pode editar isso para fornecer uma versão da linha de comando?
curiousdannii

3

Como eu perdi essa pergunta ...

Aqui está um pequeno programa Python pi que publiquei algumas semanas atrás no Stack Overflow. Não é particularmente rápido, mas pode gerar muitos dígitos. :) No entanto, como mencionei nesse tópico, geralmente uso o módulo mpmath do Python para aritmética de precisão arbitrária, e o mpmath possui um fabricante de pi bastante rápido.

Por exemplo,

time python -c "from mpmath import mp;mp.dps=500000;print mp.pi" >bigpi

real    0m4.709s
user    0m4.556s
sys     0m0.084s

500000 decimais de pi em menos de 5 segundos não é muito ruim, IMHO, considerando que está sendo executado em uma máquina com um processador de núcleo único de 2 GHz, 2 GB de RAM e gravando em uma unidade IDE antiga.


Tente from mpmath import mp; mp.dps = 1000000 ; print(mp.pi)(depois de instalar o mp3 mpmath) em menos de dois segundos por um milhão de dígitos. Nada mal !!!.
Isaac

2

Se você node.jsinstalou, isso fará o melhor para encontrar pi para você, embora o melhor não seja muito bom:

node -e 'for(a=0,b=4E8,m=Math,r=m.random;b--;)a+=(1>m.sqrt((c=r())*c+(d=r())*d));console.log(a/1E8)'

Saídas de amostra:

3.14157749
3.1416426
3.14159055
3.14171554
3.14176165
3.14157587
3.14161137
3.14167685
3.14172371

4
Quanto menor, node -e 'console.log(Math.PI)'é um pouco melhor que o melhor.
chbrown

1
@chbrown Isso não atende aos requisitos "não sérios" dos POs.
Paul

1
Qual requisito "não sério"? O OP acabou de declarar que está pedindo diversão, não que queira respostas que de alguma forma "não sejam sérias". O que significa isso, afinal? Algo como echo pie?
terdon

Eu digitei isso porque, quando você faz perguntas, às vezes as pessoas dizem que "essa não é uma fábrica de escrita de scripts", então eu disse que, como não há uma razão real para isso, eu só quero saber como imprimir pi.
DisplayName

@ Amphiteóth Demora cerca de 20 segundos para executar no meu computador. Você pode precisar apenas de um tempo.
Paul

2

Método de Monte Carlo

Veja, por exemplo, isto para obter uma explicação desse método.

Ressalvas

  • Não é arbitrariamente preciso
  • Leva muito tempo para convergir para algo útil

Vantagens

Diversão :-)

perl -Mbignum -E '
    for(0 .. 1_000_000){
        srand;
        $x=rand; # Random x coordinate
        $y=rand; # Random Y coordinate
        $decision = $x**2 + $y**2 <=1 ? 1:0; # Is this point inside the unit circle?
        $circle += $decision;
        $not_circle += 1-$decision;
        $pi = 4*($circle/($circle+$not_circle)); 
        say $pi
     }'

Nota: Eu tentei primeiro sem ele, srandmas ele ficou preso 3.14e os dígitos depois continuaram oscilando, nunca convergindo. Provavelmente porque, depois de um tempo, o PRNG começa a se repetir. O uso de srandevitará isso ou pelo menos prolongará o período da sequência pseudo-aleatória. Isso tudo é conjectura, então fique à vontade para me corrigir se eu estiver errado.


@ Amphiteót Não tenho certeza do que está acontecendo lá. Se ajudar, meu Perl é a v5.14.2. Não sou muito versado em bignumoperações no Perl, receio e não conheço nenhuma parte específica do programa acima que exija um Perl mais recente. Enfim, o que é interessante sobre isso é o próprio algoritmo. Tente implementá-lo no seu idioma de escolha se este Perl não estiver funcionando para você.
Joseph R.

1
@ Amphiteót eu vejo. A edição resolve seu problema?
Joseph R.

@ Amphiteót Você pode tentar adicionar ($x,$y,$circle,$not_circle)=(0,0,0);antes do loop para garantir que todas as variáveis ​​sejam definidas antes de serem usadas.
Joseph R.

@ Amphiteót Meu erro. Os parênteses acima deveriam ter sido (0,0,0,0).
Joseph R.

Re this /5.20.1: Faz sentido, mas não o viu! De fato ($x,$y,$circle,$not_circle)=(0,0,0,0). Depois de um ou dois minutos, ele estava pendurado no valor desejado e foi muito mais próximo de 3.1409 antes de eu parar. Interessante e divertido! Obrigado!

2

Você pode usar um algoritmo de torneira para pi. O seguinte programa C de Dik Winter e Achim Flammenkamp produzirá os primeiros 15.000 dígitos de pi, um dígito de cada vez.

a[52514],b,c=52514,d,e,f=1e4,g,h;main(){for(;b=c-=14;h=printf("%04d",e+d/f))for(e=d%=f;g=--b*2;d/=g)d=d*b+f*(h?a[b]:f/5),a[b]=d%--g;}

Contexto: wiki , aqui e aqui .

1
Adoro o algoritmo de torneira para constantes logarítmicas de Borwein, Bailey e Plouffe; no entanto, este não é um código de golfe, então posso melhorar a legibilidade do seu código reformatando-o? Observe também que algoritmos no estilo BPP podem gerar apenas dígitos para pi em bases com potências de 2, pelo menos sem o uso de memória adicional.
7194 Franki

@Franki a formatação do código altera o significado ou a intenção da publicação? Caso contrário, deve ser bom (e a edição sempre pode ser revertida). Não vejo como desobstruir algum código poderia fazer outra coisa senão esclarecer.
11684

1
@ syntaxerror É para produzir exatamente 15.000 dígitos antes de parar. A saída no segundo loop for produz 4 dígitos de pi e diminui o número misterioso de 52514 por 14. A equação seria então 4 * (52514/14), igual a 15004. Os últimos 14 valores da matriz são ignorados vantagem de menos fichas para obter o nosso valor exato de 15000.
Daniel Henneberger

1
@ 11684 Não, isso realmente não mudaria o significado ou a intenção do código. No entanto, eu percebi que este não é um algoritmo de torneira no estilo BBP para pi, mas outro que outra pessoa já desofuscou aqui stackoverflow.com/a/25837097 #
Franki

2

PHP

Poucos exemplos:

php -r "print pi();"
php -r 'echo M_PI;'
echo "<?=pi();" | php

Se você deseja alterar a precisão, tente:

php -d precision=100 -r 'echo pi();'

O tamanho de um flutuador depende da plataforma, embora um máximo de ~ 1.8e308 com uma precisão de aproximadamente 14 dígitos decimais seja um valor comum (o formato IEEE de 64 bits). [consulte Mais informação]


Se você procura precisão ainda mais precisa, consulte o Rosetta Code ou o Code Golf SE para obter algumas soluções de programação.

Relacionado: Software que pode calcular o PI com pelo menos mil dígitos no SR.SE


1

Aqui está um script que imprime pi com o número de dígitos especificado (incluindo '.') Pelo usuário.

pi.sh

#!/bin/bash
len=${1:-7}
echo "4*a(1)" | bc -l | cut -c 1-"$len"

saída

$ ./pi.sh 10
3.14159265

e com valor padrão:

$ ./pi.sh
3.14159

Eu já vi pessoas usando scalecomo bcopção, mas no meu caso ( bc 1.06.95) isso não gera o valor correto:

$ echo "scale=5;4*a(1)" | bc -l
3.14156

Observe o último dígito.


4
A pergunta diz: "Quero especificar quantos dígitos ele imprime", o que, estritamente falando, é ambíguo - mas acho que sua resposta falha (em um detalhe técnico) sob qualquer interpretação razoável; suas ./pi.sh 10impressões nove dígitos, contando a inicial 3. Além disso, você está apontando o dedo do erro de arredondamento, mas suas ./pi.sh 6saídas 3.1415, que podem não ser ideais.
G-Man diz 'Reinstate Monica'

A partir da memória, a scale=Xopção bcNÃO NÃO arredonda o número, mas simplesmente corta o número no décimo-dígito decimal.
Syntaxerror 10/11/14

1

Gosto da resposta de Abey, mas não gostei de como bc estava mudando o último dígito.

echo "scale=5; 4*a(1)" | bc -l
3.14156

Então eu removi a escala usada printf para definir o número de dígitos.

printf "%0.5f\n" $(echo "4*a(1)" | bc -l)
3.14159

Você notou que, após uma escala de 62 dígitos, todos são 0, enquanto isso não acontece com o comando original.

2
@ Amphiteót, isso porque printftem uma limitação severa nos números de ponto flutuante em comparação com bc. Eles são representados pelo doubletipo de linguagem C com precisão de cerca de 17 dígitos, portanto, mesmo os dígitos diferentes de zero após o 17º são falsos! ------ Adicionei uma resposta com o arredondamento correto do resultado, não limitado porprintf . ------ Além disso, para garantir que este comando funcione com vários LC_ALL=C printf
códigos de idioma

1

E se você não puder, pelo resto da vida, se lembrar dessa arctancoisa? Ou supondo que você nem saiba que essa função existe bc, tente memorizar esta divisão simples:

echo "scale=6; 355 / 113" | bc
3.141592

Funcionará apenas com 6 dígitos, mas para cálculos não científicos, isso funcionará bem.

Se você também não consegue se lembrar desses dois números, escreva primeiro o denominador e depois o numerador:

113 355

Ou porque não

11 33 55

"dobro 1, dobro 3, dobro 5". Todos os números são ímpares. Para calcular, divida o número de 6 dígitos ao meio novamente e troque o denominador e o numerador antes de dividi-los. É sobre isso.


Tanto quanto eu estou preocupado, eu acho 4 * arctan(1)muito mais fácil de lembrar números que 2 de três dígitos ... Eu facilmente usar 335 em vez de 355, ou 133 em vez de 113.
John WH Smith

Bem, acho que é uma questão de preferência pessoal :) Pessoas (como eu) que podem memorizar facilmente números de telefone (telefones fixos!) Poderiam memorizar dois números como um único número de telefone. Também ajudará as pessoas que na escola acham que a trigonometria deve ter sido feita por poderes do mal.
Syntaxerror 10/11/14

1

Pode-se supor que o OP esteja interessado em um comando shell curto e fácil de memorizar para imprimir π - mas a questão não diz isso realmente. Esta resposta está ignorando essa suposição e responde a pergunta estritamente como escrita;

Trivial?

Embora já existam 18 respostas, uma abordagem ainda está faltando - e com tantas respostas, pode-se pensar que não é a única que está faltando:
A trivial: Como imprimir π? Apenas imprima π!

Essa abordagem parece ser inútil demais para pensar nisso, mas mostrarei que ela tem seus méritos:

Otimizado

Normalmente, calcularíamos o valor de π. Não vejo o que nos impede de otimizar a solução, pré-calculando o valor - é uma constante, qualquer compilador faria isso.

Queremos um número de dígitos de π, até a precisão máxima. Então, podemos pegar o prefixo da constante, como texto:

echo 3.1415926535897932384626433832795 | cut -b -7
3.14159

Uma variante com um argumento explícito para a precisão, por exemplo. para precisão 5:

echo 3.1415926535897932384626433832795 | cut -b -$((2+5))
3.14159

Vantagens

A precisão máxima pode ser escolhida arbitrariamente usando uma constante adequada calculada usando uma das outras respostas. É limitado apenas pelo comprimento máximo de uma linha de comando.
Possui complexidade de tempo constante para encontrar o valor.
Torna óbvios todos os limites e restrições, com base na baixa complexidade de implementação.
Ele lida com precisão maior que o máximo normalmente, retornando a constante na precisão total disponível (sem rastro 0).
Portanto, essa solução, embora trivial, tem vantagens. Pode ser útil quando usado em uma função shell, por exemplo.

Mínimo

A funcionalidade da solução acima também pode ser implementada sem a criação de um processo para cut(supondo que echoseja um shell embutido). Ele usa o comando printf(normalmente um builtin) de uma maneira um tanto obscura:
a constante é manipulada completamente como uma string (o formato usa %s); não há aritmética de ponto flutuante envolvida; portanto, os limites floatou doublenão se aplicam aqui.
O valor de precisão do %sescape ( 5no exemplo abaixo) especifica o comprimento do prefixo da string a ser impresso - que é a precisão. Faz 3.parte do printfformato para mantê-lo fora do cálculo de precisão.

$ printf "3.%.5s\n" 1415926535897932384626433832795 
3.14159

Alternativa com precisão como argumento separado:

$ printf "3.%.*s\n" 5 1415926535897932384626433832795 
3.14159

Ou um pouco mais legível (observe o espaço entre 3.e 14159..., eles são argumentos separados):

$ printf "%s%.5s\n" 3. 1415926535897932384626433832795
3.14159

Rápido

printfPode-se esperar que a variante usando seja muito rápida: como printfé um shell embutido em shells comuns como bashe zsh, ele não cria nenhum processo.
Além disso, ele não toca em nenhum tipo de código relacionado a ponto flutuante, mas apenas na manipulação de matrizes de bytes (explicitamente, não caracteres multibyte). Isso geralmente é mais rápido, geralmente muito mais rápido que o uso do ponto flutuante.

compatibilidade printf

Muitas vezes, há razões para substituir printfpor /usr/bin/printfpara garantir consistência ou compatibilidade. Nesse caso, acho que podemos usar o built-in - o que é importante, pois o uso /usr/bin/printfreduz a vantagem "rápida" ao bifurcar um processo.
Um problema comum com printfcompatibilidade é o formato de saída de número, dependendo da localidade. A separação .de números pode ser alterada para com ,base na configuração da localidade; Mas não usamos números, apenas uma constante de string contendo um literal .- não afetada pela localidade.
StéphaneChazelas destacou que printf %.5sfunciona de maneira diferentezsh, contando caracteres, não bytes, como de costume. Felizmente, nossas constantes usam apenas caracteres no intervalo ASCII inferior, que é codificado por um byte por caractere em qualquer codificação relevante, desde que utilizemos a UTF-8codificação comum para Unicode, e não uma codificação de largura fixa.


Note que printf %.5sé char (não byte) baseado em zsh (sensatamente, mas contra POSIX). ksh93's %.5Lsé baseado graphem.
Stéphane Chazelas
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.