Como eu imprimo pi (3,14159)? [fechadas]

34

Qual comando poderia imprimir pi para mim? Quero especificar quantos dígitos ele imprime, não consegui encontrar nada on-line. Eu só quero ser capaz de imprimir pi.

    
por DisplayName 05.11.2014 / 21:17

20 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: link

    
por 05.11.2014 / 21:25
61

Se você tem tex(1) instalado:

tex --version | head -1 | cut -f2 -d' '
    
por 05.11.2014 / 21:25
23

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

# bc -l
scale=<your precision>
4*a(1)
    
por 05.11.2014 / 21:25
20

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

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

Exemplos
$ ./pi 10
3.141592653

$ ./pi 20
3.1415926535897932384

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

Outras distros

Fedora

No Fedora eu tive que baixar o tarball de código-fonte e compilá-lo sozinho, mas ele foi criado com pouco barulho. Por qualquer motivo, o pacote cln no Fedora inclui apenas a biblioteca, mas negligencia os exemplos que estão disponíveis na versão Debian / Ubuntu (acima).

Arch

Arch fornece o mesmo programa em o pacote cln (obrigado Amphiteót ).

    
por 05.11.2014 / 21:23
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
    
por 05.11.2014 / 21:49
15

Algumas das outras respostas mostram dígitos incorretos nos últimos lugares da saída. Abaixo está uma variação de a resposta usando bc , mas com um resultado corretamente arredondado. A variável s contém o número de dígitos significativos (incluindo 3 na frente do ponto decimal).

Meio round up

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

Arredondar (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 printf que usa a representação double type da linguagem C. para os números que tem uma precisão de cerca de 17 dígitos significativos. Veja a resposta com printf arredondamento .

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

Arredondar até a metade requer adicionar 5 ao primeiro dígito que será cortado (5 × 10 -s ) para que no caso de dígitos maiores de 5 o último dígito que permanecerá ser incrementado.

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.

Aqui strings

Os exemplos acima usam aqui strings , que são suportados, por exemplo, em bash , ksh e% código%. Se o seu shell não suportar aqui, use zsh e pipe:

$ echo "s=5; scale=s+2; pi=4*a(1); scale=s-1; pi/1" |  bc -l
3.1415
    
por 07.11.2014 / 10:26
12

perl one line (usando bignum ):

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

por exemplo

perl -Mbignum=bpi -wle 'print bpi(6)'
3.14159
    
por 05.11.2014 / 21:40
9

com python2:

$ python -c "import math; print(str(math.pi)[:7])"
3.14159
    
por 05.11.2014 / 23:12
7

Usando o Ruby:

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

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

3.141592654
    
por 06.11.2014 / 00:08
4

No bash:

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

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

<?php 
echo round(pi(), 2);
?>
    
por 06.11.2014 / 12:34
3

Como eu perdi essa pergunta ...

Aqui está um pequeno programa pi do Python que eu postei há algumas semanas no Stack Overflow. Não é particularmente rápido, mas pode fazer lotes de 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 tem um pi muito 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

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

    
por 07.11.2014 / 14:59
2

Se você tiver node.js instalado, 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)'

Exemplos de saídas:

3.14157749
3.1416426
3.14159055
3.14171554
3.14176165
3.14157587
3.14161137
3.14167685
3.14172371
    
por 06.11.2014 / 00:47
2

Método de Monte Carlo

Veja, por exemplo, este para obter uma explicação sobre esse método.

Advertências

  • Não é arbitrariamente preciso
  • Demora 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 pela primeira vez sem srand , mas ficou preso em 3.14 e os dígitos depois disso continuaram oscilando, nunca convergindo. Isto é provavelmente porque, depois de um tempo, o PRNG começa a se repetir. O uso de srand evitará ou, pelo menos, prolongará o período da sequência pseudo-aleatória. Isso tudo é conjectura, então sinta-se à vontade para me corrigir se eu estiver errado.

    
por 06.11.2014 / 05:19
2

Você pode usar um algoritmo spigot para pi. O seguinte programa em 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;}
    
por 06.11.2014 / 16:38
2

PHP

Alguns exemplos:

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

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

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

The size of a float is platform-dependent, although a maximum of ~1.8e308 with a precision of roughly 14 decimal digits is a common value (the 64 bit IEEE format). [read more]

Se você está procurando uma precisão ainda mais precisa, verifique Código Rosetta ou Código Golf SE para algumas soluções de programação.

Relacionados: Software que pode calcular PI para pelo menos mil dígitos em SR.SE

    
por 06.11.2014 / 16:36
1

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

Trivial?

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

Essa abordagem parece ser inútil demais para pensar nisso, mas vou mostrar que ela tem seus merrits:

Otimizado

Normalmente, calculamos o valor de π. Eu não vejo o que está nos impedindo de otimizar a solução, precalculando o valor - é uma constante, qualquer compilador faria isso.

Queremos um certo número de dígitos de π, até uma 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. Ele é limitado apenas pelo comprimento máximo de uma linha de comando.
Tem complexidade de tempo constante para encontrar o valor.
Isso torna todos os limites e restrições óbvios, baseados na baixa complexidade da implementação.
Ele manipula precisão maior que o máximo normalmente, retornando a constante na precisão total disponível (sem 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 (assumindo que echo é um shell embutido). Ele usa o comando printf (normalmente um construído) de maneira um tanto obscura:
A constante é completamente handeled como uma string (o formato usa %s ), não há aritmética de ponto flutuante envolvida, portanto os limites de float ou double não se aplicam aqui.
O valor de precisão da %s escape ( 5 no exemplo abaixo) especifica o comprimento do prefixo da cadeia para imprimir - que é a precisão. O 3. faz parte do formato printf 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

A variante que usa printf pode ser muito rápida: como printf é um shell embutido em shells comuns como bash e 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 manipulação de matrizes de bytes (explicitamente não caracteres multibyte). Isso geralmente é mais rápido, geralmente muito mais rápido que o uso de ponto flutuante.

compatibilidade com printf

Geralmente, há motivos para substituir printf por /usr/bin/printf para garantir consistência ou compatibilidade. Nesse caso, acho que podemos usar o builtin - o que é importante, já que usar /usr/bin/printf reduz a vantagem "rápida" ao bifurcar um processo.
Um problema comum com a compatibilidade printf é o formato de saída do número, dependendo da localidade. A porcentagem de . para números pode ser alterada para , com base na configuração de localidade; Mas nós não usamos números, apenas uma constante de string contendo um literal . - não afetado pela localidade.
StéphaneChazelas apontou que printf %.5s funciona de maneira diferente em zsh , contando caracteres e 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 usemos a codificação UTF-8 comum para Unicode e não uma codificação de largura fixa.

    
por 09.11.2014 / 07:13
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 vi pessoas usando a opção scale como bc , 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.

    
por 05.11.2014 / 22:59
1

Eu 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

Por isso, removi o printf usado em escala para definir o número de dígitos.

printf "%0.5f\n" $(echo "4*a(1)" | bc -l)
3.14159
    
por 06.11.2014 / 14:04
1

E se você não puder pela vida de você se lembrar dessa coisa arctan ? Ou, supondo que você nem saiba que esta função existe em bc , tente memorizar essa divisão simples:

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

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

Se você acha que não consegue lembrar esses dois números, escreva o denominador primeiro e depois o numerador:

113 355

Ou porque não

11 33 55

"double 1, double 3, double 5". Todas as figuras são estranhas. 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.

    
por 09.11.2014 / 09:10

Tags