Tenga en cuenta que se vuelve más divertido si quiere más dígitos que alrededor de 15.
Thorbjørn Ravn Andersen
2
@DisplayName: significa que ya no puede usar ningún programa que almacene / calcule internamente PI utilizando valores de coma flotante de doble precisión (que generalmente es el tipo de datos FP "incorporado" de mayor precisión disponible en la mayoría de los idiomas).
Matteo Italia
55
Mi solución, hace décadas antes de que esto fuera comúnmente proporcionado por las bibliotecas de idiomas, era memorizarlo en más lugares de los que los puntos flotantes que estaba usando necesitarían: 3.1415926535897932384626 generalmente es lo suficientemente cerca para fines prácticos, e incluso la mayoría de los poco prácticos, algo real -world tendrá más errores que eso en los otros números, y para los teóricos me quedaría con el valor simbólico en lugar del numérico.
keshlam
3
El interés de @syntaxerror es irrelevante. Si publicara una pregunta pidiendo fotos desnudas de celebridades, obtendría miles de visitas y posiblemente votos positivos. Eso no lo hace en el tema. Esta pregunta es un ejemplo clásico de demasiado amplio. Solo mira el número de respuestas. También tenga en cuenta que el OP no especificó ninguna limitación, lo que hace que las posibles respuestas sean esencialmente infinitas. En cualquier caso, cerrar no es eliminar. La pregunta y todas sus 23 respuestas aún estarán aquí. Cerrar solo significa que no se aceptan más respuestas. ¿Realmente necesitamos aún más formas de imprimir π?
terdon
Respuestas:
52
Puedes usar este comando:
echo "scale=5; 4*a(1)" | bc -l
3.14159
Donde escala es el número de dígitos después del punto decimal.
Versión más corta en bashy otras envolventes de apoyo aquí cuerdas: bc -l <<< "scale=5; 4*a(1)".
pabouk
2
Me pregunto cuántos dígitos puede tener esto.
DisplayName
44
@DisplayName bastantes. scale=1000da 999 dígitos correctos bastante rápido (el último dígito está apagado por 1, razonable ya que estamos calculando pi / 4 y luego multiplicando por 4). scale=4000da 4000 dígitos correctos en unos pocos segundos. scale=10000lleva más tiempo del que tengo paciencia, pero probablemente da 9999 o 10000 dígitos correctos.
hobbs
44
Esto da un resultado incorrecto en mi máquina, escribiendo 'echo "scale = 5; 4 * a (1)" | bc -l 'devuelve 3.14156, cuando el último dígito debería ser 9
Casi vale la pena un voto positivo solo por ser inteligente. Aunque el resultado de esto cambia cuando actualiza el paquete. ¿Consideramos que eso es una característica o un error?
un CVn
8
@ MichaelKjörling En realidad, cambia para ser una aproximación más precisa de pi.
Abrixas2
@ Abrixas2 Sí, lo sé. Con la última versión de TeX siendo la versión π.
un CVn
30
@DavidRicherby Se pueden imprimir menos dígitos mediante una invocación adicional de cut. Se pueden imprimir más dígitos al esperar mucho tiempo y ejecutar el comando nuevamente.
Steven D
1
@Ruslan depende de la implementación. En este caso particular, esperaría que se hiciera "bien".
Thorbjørn Ravn Andersen
23
Para imprimir con precisión arbitraria, puede usar bcy la fórmula pi = 4*atan(1):
Hay algo divertido en la scaleopción, pi = 3.141592..pero ¿con echo "scale=5; 4*a(1)" | bc -l => 3.14156qué esperaría ver 3.14159?
fduff
77
scaleespecifica la precisión que se utilizará para el cálculo, por lo que, con scale=5ninguna operación, se utilizarán más de cinco dígitos fraccionarios para cualquier operación atómica.
Si quieres algo que pueda calcular el valor de π, existen varios enfoques. Quizás la solución más obvia sería usar un paquete listo como pi(enlace del paquete Debian) , que si se puede confiar en la descripción del paquete Debian puede calcular el valor con una precisión arbitraria, limitada solo por la memoria.
pies en realidad un ejemplo que se incluye con la biblioteca CLN (Biblioteca de clases para números) . Incluye aplicaciones de ejemplo que proporcionan herramientas para generar longitudes arbitrarias de números como Pi, Fibonacci, etc. Los paquetes CLN están disponibles preenvasados en Debian / Ubuntu (a eso apunta el enlace de Debian anterior).
En Fedora tuve que descargar el tarball de origen y construirlo yo mismo, pero se construye con poco alboroto. Por alguna razón el paquetecln en Fedora incluye solo la biblioteca pero descuida los ejemplos que están disponibles en la versión Debian / Ubuntu (arriba).
Sí, heh, quise decir el valor total que acabo de escribir lo que tenía en mi cabeza.
DisplayName
2
El "valor total" ?? Que quieres decir...?
Kyle Strand
2
@DisplayName lee el resto de la respuesta. Un programa dedicado como pisuena exactamente como lo que estás buscando. Puede hacer cosas como pi 300imprimir los primeros 300 dígitos, por ejemplo.
terdon
3
@KyleStrand He descubierto una respuesta realmente maravillosa a eso, que este comentario es demasiado limitado para contener. ¡Hola, funcionó para Fermat !
terdon
Me encantaría saber por qué esto ha recibido dos votos negativos. ¿Las personas que votaron en contra no leyeron la respuesta antes de decidir que no era útil?
un CVn
17
Para hasta un millón de dígitos, puede usar lo siguiente (aquí para 3000 dígitos):
Esto tiene el beneficio adicional de que debería estar razonablemente cerca de la complejidad O (1). O tal vez eso no sea un beneficio después de todo ...
un CVn
77
Además, es difícil decir que cualquier interacción de red es O (1) complejidad de tiempo en un mundo práctico. : P
HalosGhost
2
@HalosGhost Para nuestros propósitos (en comparación con el cálculo de n dígitos de pi cada vez), es probable que la descarga de una cantidad fija de datos de un servidor específico a través de una red sea efectivamente O (1), mientras que el cálculo de n dígitos de pi sea al menos algo como O (log n) y posiblemente más alto (no estoy familiarizado con esos algoritmos). Es probable que la descarga real de los datos tome significativamente más tiempo que la sobrecarga para comenzar la descarga, por lo tanto, el tiempo de descarga domina y usted llega a algún lugar cercano a O (1) dada una velocidad de transmisión de datos razonablemente fija. De ahí O (1).
un CVn
44
@ MichaelKjörling Cuando dices O (1), ¿no te refieres a O (n)? El tiempo de descarga en lineal en el número de dígitos que necesita, por lo tanto, O (n).
CodesInChaos
1
@CodesInChaos No, el tiempo de descarga es constante (dada la velocidad de transmisión constante) porque está descargando un número constante de dígitos (un millón, aquí). ¿A menos que (en este caso específico) el rizo sea lo suficientemente inteligente como para imprimir mientras se descarga y detener la descarga una vez que se rompa la tubería porque cutsale? Si ese es el caso, estoy de acuerdo, sería O (n).
un CVn
15
Algunas de las otras respuestas muestran dígitos incorrectos en los últimos lugares de la salida. A continuación se muestra una variación de la respuesta usandobc pero con un resultado correctamente redondeado. La variable scontiene el número de dígitos significativos (incluidos3 delante del punto decimal).
Redondear a la mitad
$ bc -l <<< "s=5; scale=s+2; pi=4*a(1)+5*10^(-s); scale=s-1; pi/1"
3.1416
Redondear hacia abajo (truncar)
$ bc -l <<< "s=5; scale=s+2; pi=4*a(1); scale=s-1; pi/1"
3.1415
Explicación del redondeo.
El redondeo se realiza directamente en bc. Esto no tiene la limitación del comando printfque usa la representación del doubletipo de lenguaje C para los números que tiene una precisión de aproximadamente 17 dígitos significativos. Vea la respuesta con printfredondeo .
scale=s-1establece el número de dígitos para truncar. pi/1divide el resultado entre 1 para aplicar el truncamiento. Simplepi no trunca el número.
El redondeo a la mitad requiere agregar 5 al primer dígito que se cortará (5 × 10 -s ) para que, en el caso de dígitos superiores a igual a 5, se incremente el último dígito restante.
De las pruebas de hobbs parece que tres dígitos adicionales que se redondearán / cortarán (scale=s+2 ) serán suficientes incluso para números muy largos.
Aquí cuerdas
Los ejemplos anteriores usan aquí cadenas que son compatibles, por ejemplo bash, en kshy zsh. Si su shell no admite aquí el uso de cadenas echoy la tubería en su lugar:
Calcular tres dígitos adicionales con el propósito de redondear no es "redondeo correcto" como usted afirma en un comentario. Primero, no tienes un límite en el error del cálculo. Si puede estar equivocado por 3 unidades en el último lugar como lo afirma fduff, ¿por qué no estaría mal por 1000 unidades en el último lugar? Segundo, vea "el dilema del fabricante de la mesa".
@ArtemShitov - mi mal, intente importar gmpy2 (si lo tienes instalado): python -c "import gmpy2; print(str(gmpy2.const_pi(8192))[:400])". Aumente la precisión para obtener más dígitos ... por ejemplopython -c "import gmpy2; print(str(gmpy2.const_pi(16384))[:4400])"
don_crissti
1
Lo más rápido que pude encontrar fue from mpmath import mp; mp.dps = 1000000 ; print(mp.pi)solo un par de segundos por un millón de dígitos. No está mal !!!.
Isaac
7
Usando Ruby:
require "bigdecimal"
require "bigdecimal/math"
include BigMath
BigDecimal(PI(100)).round(9).to_s("F")
3.141592654
@ Amphiteóth afmtoditrequiere groffser instalado. Aquí en Ubuntu (y sabores), es no estándar. JFYI
syntaxerror
@syntaxerror Gracias, buen punto! He eliminado mi ejemplo. Mi punto fue justo cuando leí esta IA grepen mi sistema buscando la constante y la encontré en más de un lugar. ¡Por eso fue +1 para mí!
3
Muy simple en PHP usando la función incorporada pi ():
¿Puedes editar esto para dar una versión de línea de comando?
curiousdannii
3
¿Cómo me perdí esta pregunta ...
Aquí hay un pequeño programa de Python pi que publiqué hace un par de semanas en Stack Overflow. No es particularmente rápido, pero puede hacer muchos dígitos. :) Sin embargo, como mencioné en ese hilo, generalmente uso el módulo mpmath de Python para aritmética de precisión arbitraria, y mpmath tiene un generador de pi bastante rápido.
P.ej,
time python -c "from mpmath import mp;mp.dps=500000;print mp.pi" >bigpi
real 0m4.709s
user 0m4.556s
sys 0m0.084s
En mi humilde opinión, 500000 decimales de pi en menos de 5 segundos no es nada malo, considerando que se está ejecutando en una máquina con un procesador de 2 GHz de un solo núcleo, 2 gigas de RAM y escribiendo en una unidad IDE antigua.
Intente from mpmath import mp; mp.dps = 1000000 ; print(mp.pi)(después de una instalación pip3 mpmath) menos de dos segundos por un millón de dígitos. No está mal !!!.
Isaac
2
Si lo ha node.jsinstalado, hará todo lo posible para encontrar pi por usted, aunque lo mejor no es muy bueno:
Cuanto más corto node -e 'console.log(Math.PI)'es un poco mejor que lo mejor.
chrrown
1
@chbrown Eso no satisface el requisito "no serio" de los OP.
Paul
1
¿Qué requisito "no serio"? El OP simplemente declaró que están pidiendo diversión, no que quieran respuestas que de alguna manera "no son serias". ¿Qué significa eso, de todos modos? Algo como echo pie?
terdon
Escribí eso porque cuando haces preguntas a veces la gente dice que "esto no es una fábrica de escritura de guiones", así que dije que debido a que no hay una razón real para ello, solo quiero saber cómo imprimir pi.
DisplayName
@ Amphiteóth Se tarda unos 20 segundos en ejecutarse en mi computadora. Es posible que solo necesite darle algo de tiempo.
Paul
2
Método Monte Carlo
Ver, por ejemplo, esto para una explicación de este método.
Advertencias
No es arbitrariamente preciso
Toma mucho tiempo converger a algo útil
Ventajas
Divertido :-)
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: Primero lo probé sin, srandpero se quedó atascado 3.14y los dígitos siguieron oscilando, sin converger. Esto probablemente se deba a que, después de un tiempo, el PRNG comienza a repetirse. El uso de srandevitará eso o al menos alargará el período de la secuencia pseudoaleatoria. Todo esto es una conjetura, así que siéntete libre de corregirme si me equivoco.
@ Anfiteót No estoy muy seguro de lo que está pasando allí. Si ayuda, mi Perl es v5.14.2. No estoy muy familiarizado con las bignumoperaciones en Perl, me temo y no conozco ninguna parte en particular del programa anterior que requiera una Perl más nueva. De todos modos, lo interesante de esto es el algoritmo en sí. Intenta implementarlo en el idioma que elijas si este Perl no funciona para ti.
Joseph R.
1
@ Anfiteót ya veo. ¿La edición resuelve tu problema?
Joseph R.
@ Anfiteót Puede intentar agregar ($x,$y,$circle,$not_circle)=(0,0,0);antes del ciclo para asegurarse de que todas las variables estén definidas antes de ser utilizadas.
Joseph R.
@ Anfiteót Mi error. Los parens de arriba deberían haber sido (0,0,0,0).
Joseph R.
Re esto /5.20.1: ¡Tiene sentido pero no lo vi! De hecho ($x,$y,$circle,$not_circle)=(0,0,0,0). Después de un minuto o dos, rondaba el valor deseado, luego se acercó mucho más a 3.1409 antes de que me detuviera. ¡Interesante y divertido! ¡Gracias!
2
Puede usar un algoritmo de espiga para pi. El siguiente programa C de Dik Winter y Achim Flammenkamp producirá los primeros 15,000 dígitos de pi, un dígito a la vez.
Me encanta el algoritmo de espita para las constantes logarítmicas de Borwein, Bailey y Plouffe, sin embargo, esto no es código golf, así que ¿puedo mejorar la legibilidad de su código reformateándolo? También tenga en cuenta que los algoritmos de estilo BPP solo pueden generar dígitos para pi en bases que son potencias de 2, al menos sin usar memoria adicional.
Franki
@Franki ¿formatear el código cambia el significado o la intención de la publicación? Si no, debería estar bien (y la edición siempre se puede revertir). No veo cómo desobuscar un código podría hacer algo más que aclarar.
11684
1
@syntaxerror Produce exactamente 15,000 dígitos antes de detenerse. La salida en el segundo bucle for produce 4 dígitos de pi y disminuye el número misterioso de 52514 por 14. La ecuación sería entonces 4 * (52514/14) que equivale a 15004. Los últimos 14 valores en la matriz se ignoran para tomar ventaja de menos tokens para obtener nuestro valor exacto de 15000.
Daniel Henneberger
1
@ 11684 No, realmente no cambiaría el significado o la intención del código. Sin embargo, me di cuenta de que este no es un algoritmo de espiga de estilo BBP para pi, sino otro que alguien más ya ha desofuscado aquí stackoverflow.com/a/25837097
El tamaño de un flotante depende de la plataforma, aunque un máximo de ~ 1.8e308 con una precisión de aproximadamente 14 dígitos decimales es un valor común (el formato IEEE de 64 bits). [Lee mas]
Si busca una precisión aún más precisa, consulte Rosetta Code o Code Golf SE para obtener algunas soluciones de programación.
La pregunta dice: "Quiero especificar cuántos dígitos imprime", lo cual, estrictamente hablando, es ambiguo, pero creo que su respuesta falla (en un tecnicismo) bajo cualquier interpretación razonable; sus ./pi.sh 10impresiones nueve dígitos, contando la inicial 3. Además, está señalando con el dedo un error de redondeo, pero sus ./pi.sh 6resultados 3.1415, que pueden no ser óptimos.
G-Man dice 'reinstalar a Monica' el
De memoria, la scale=Xopción bcNO redondeará el número, sino que simplemente cortará el número en el décimo dígito decimal.
syntaxerror
1
Me gusta la respuesta de Abey pero no me gustó cómo bc estaba cambiando el último dígito.
echo "scale=5; 4*a(1)" | bc -l
3.14156
Así que eliminé la escala utilizada printf para establecer el número de dígitos.
¿Te has dado cuenta, después de una escala de 62 dígitos, todos son 0, mientras que esto no sucede con el comando original.
2
@ Anfiteót, eso se debe a que printftiene una limitación severa en los números de coma flotante en comparación con bc. Están representados por el doubletipo de lenguaje C con una precisión de aproximadamente 17 dígitos, por lo que incluso los dígitos distintos de cero después del 17 son falsos ------ He agregado una respuesta con el redondeo correcto del resultado no limitado porprintf . ------ También para asegurarse de que este comando funcione con varias configuraciones regionales, debe hacer algo como esto: LC_ALL=C printf...
pabouk
1
¿Qué pasa si no puedes por tu vida recordar esto arctan? O suponiendo que ni siquiera sabe que existe esta función bc, intente memorizar esta división simple:
echo "scale=6; 355 / 113" | bc
3.141592
Solo funcionará para 6 dígitos, pero para cálculos no científicos esto funcionará bien.
Si crees que tampoco puedes recordar estos dos números, primero escribe el denominador y luego el numerador:
113 355
O porque no
11 33 55
"doble 1, doble 3, doble 5". Todas las figuras son extrañas. Para calcular, divida nuevamente el número de 6 dígitos por la mitad e intercambie el denominador y el numerador antes de dividirlos. Eso es todo.
En lo que a mí respecta, me resulta 4 * arctan(1)mucho más fácil recordar que 2 números de tres dígitos ... usaría fácilmente 335 en lugar de 355, o 133 en lugar de 113.
John WH Smith,
Bueno, creo que es una cuestión de preferencia personal. :) Las personas (como yo) que pueden memorizar fácilmente (¡teléfono fijo!) Podrían memorizar dos números como un solo número de teléfono. También ayudará a aquellas personas que en la escuela sintieron que la trigonometría debe haber sido realizada por poderes malvados.
syntaxerror
1
Se puede suponer que el OP está interesado en un comando de shell corto y fácil de memorizar para imprimir π, pero la pregunta realmente no dice eso. Esta respuesta ignora esa suposición y responde la pregunta estrictamente como está escrita;
¿Trivial?
Si bien ya hay 18 respuestas, todavía falta un enfoque, y con tantas respuestas, uno podría pensar que no es el único que falta:
El trivial: ¿Cómo imprimir π? Solo imprime π!
Ese enfoque parece ser demasiado inútil como para pensarlo, pero demostraré que tiene sus ventajas:
Optimizado
Normalmente calcularíamos el valor de π. No veo lo que nos impide optimizar la solución, calculando previamente el valor; es una constante, cualquier compilador haría eso.
Queremos cierto número de dígitos de π, hasta una precisión máxima. Entonces podemos tomar el prefijo de la constante, como texto:
La precisión máxima se puede elegir arbitrariamente usando una constante adecuada calculada usando una de las otras respuestas. Está limitado solo por la longitud máxima de una línea de comando.
Tiene una complejidad de tiempo constante para encontrar el valor.
Hace obvios todos los límites y restricciones, en función de la baja complejidad de la implementación.
Maneja la precisión más grande que el máximo con gracia al devolver la constante en la precisión total disponible (sin arrastre 0).
Entonces, esta solución, aunque trivial, tiene ventajas. Puede ser útil cuando se usa en una función de shell, por ejemplo.
Mínimo
La funcionalidad de la solución anterior también se puede implementar sin crear un proceso para cut(suponiendo que echosea un shell incorporado). Utiliza el comando printf(normalmente integrado) de una manera algo oscura:
la constante se maneja completamente como una cadena (el formato usa %s), no hay aritmética de punto flotante involucrada, por lo que los límites de floato doubleno se aplican aquí.
El valor de precisión del %sescape ( 5en el ejemplo a continuación) especifica la longitud del prefijo de cadena a imprimir, que es la precisión. El 3.es parte del printfformato para mantenerlo fuera del cálculo de precisión.
Se printfpuede esperar que la variante de uso sea muy rápida: debido a que printfes un shell incorporado en shells comunes como bashy zsh, no crea ningún proceso.
Además, no toca ningún tipo de código relacionado con coma flotante, sino solo la manipulación de conjuntos de bytes (explícitamente no caracteres multibyte). Esto suele ser más rápido, a menudo mucho más rápido que el uso de coma flotante.
compatibilidad de printf
A menudo, hay razones para reemplazar printfpor /usr/bin/printfgarantizar la coherencia o compatibilidad. En este caso, creo que podemos usar el incorporado, lo cual es importante, ya que el uso /usr/bin/printfreduce la ventaja "rápida" al bifurcar un proceso.
Un problema común con la printfcompatibilidad es el formato de salida del número según la configuración regional. La separación .de números se puede cambiar ,según la configuración regional; Pero no usamos números, solo una constante de cadena que contiene un literal ., no afectado por la configuración regional.
StéphaneChazelas señaló queprintf %.5s funciona de manera diferente enzsh, contando caracteres, no bytes como de costumbre. Afortunadamente, nuestras constantes usan solo caracteres en el rango ASCII inferior, que está codificado por un byte por carácter en cualquier codificación relevante, siempre que usemos la UTF-8codificación común para Unicode, y no una codificación de ancho fijo.
Respuestas:
Puedes usar este comando:
Donde escala es el número de dígitos después del punto decimal.
Referencia: http://www.tux-planet.fr/calculer-le-chiffre-pi-en-ligne-de-commande-sous-linux/
fuente
bash
y otras envolventes de apoyo aquí cuerdas:bc -l <<< "scale=5; 4*a(1)"
.scale=1000
da 999 dígitos correctos bastante rápido (el último dígito está apagado por 1, razonable ya que estamos calculando pi / 4 y luego multiplicando por 4).scale=4000
da 4000 dígitos correctos en unos pocos segundos.scale=10000
lleva más tiempo del que tengo paciencia, pero probablemente da 9999 o 10000 dígitos correctos.Si ha
tex(1)
instalado:fuente
cut
. Se pueden imprimir más dígitos al esperar mucho tiempo y ejecutar el comando nuevamente.Para imprimir con precisión arbitraria, puede usar
bc
y la fórmulapi = 4*atan(1)
:fuente
scale
opción,pi = 3.141592..
pero ¿conecho "scale=5; 4*a(1)" | bc -l => 3.14156
qué esperaría ver3.14159
?scale
especifica la precisión que se utilizará para el cálculo, por lo que, conscale=5
ninguna operación, se utilizarán más de cinco dígitos fraccionarios para cualquier operación atómica.Si quieres algo que pueda calcular el valor de π, existen varios enfoques. Quizás la solución más obvia sería usar un paquete listo como
pi
(enlace del paquete Debian) , que si se puede confiar en la descripción del paquete Debian puede calcular el valor con una precisión arbitraria, limitada solo por la memoria.
Ejemplospi
es en realidad un ejemplo que se incluye con la biblioteca CLN (Biblioteca de clases para números) . Incluye aplicaciones de ejemplo que proporcionan herramientas para generar longitudes arbitrarias de números como Pi, Fibonacci, etc. Los paquetes CLN están disponibles preenvasados en Debian / Ubuntu (a eso apunta el enlace de Debian anterior).NOTA: La fuente de estos ejemplos está aquí en la fuente de la base del código CLN .
Otras distribuciones
FedoraEn Fedora tuve que descargar el tarball de origen y construirlo yo mismo, pero se construye con poco alboroto. Por alguna razón el paquete
Arcocln
en Fedora incluye solo la biblioteca pero descuida los ejemplos que están disponibles en la versión Debian / Ubuntu (arriba).Arch proporciona el mismo programa en el
cln
paquete (gracias Amphiteót ).fuente
pi
suena exactamente como lo que estás buscando. Puede hacer cosas comopi 300
imprimir los primeros 300 dígitos, por ejemplo.Para hasta un millón de dígitos, puede usar lo siguiente (aquí para 3000 dígitos):
fuente
cut
sale? Si ese es el caso, estoy de acuerdo, sería O (n).Algunas de las otras respuestas muestran dígitos incorrectos en los últimos lugares de la salida. A continuación se muestra una variación de la respuesta usando
bc
pero con un resultado correctamente redondeado. La variables
contiene el número de dígitos significativos (incluidos3
delante del punto decimal).Redondear a la mitad
Redondear hacia abajo (truncar)
Explicación del redondeo.
El redondeo se realiza directamente en
bc
. Esto no tiene la limitación del comandoprintf
que usa la representación deldouble
tipo de lenguaje C para los números que tiene una precisión de aproximadamente 17 dígitos significativos. Vea la respuesta conprintf
redondeo .scale=s-1
establece el número de dígitos para truncar.pi/1
divide el resultado entre 1 para aplicar el truncamiento. Simplepi
no trunca el número.El redondeo a la mitad requiere agregar 5 al primer dígito que se cortará (5 × 10 -s ) para que, en el caso de dígitos superiores a igual a 5, se incremente el último dígito restante.
De las pruebas de hobbs parece que tres dígitos adicionales que se redondearán / cortarán (
scale=s+2
) serán suficientes incluso para números muy largos.Aquí cuerdas
Los ejemplos anteriores usan aquí cadenas que son compatibles, por ejemplo
bash
, enksh
yzsh
. Si su shell no admite aquí el uso de cadenasecho
y la tubería en su lugar:fuente
perl una línea (usando bignum ):
p.ej
fuente
Con python2:
fuente
(..)
esto funciona en Python 2 y 3. Solo parece tener 12 dígitos.python -c "import gmpy2; print(str(gmpy2.const_pi(8192))[:400])"
. Aumente la precisión para obtener más dígitos ... por ejemplopython -c "import gmpy2; print(str(gmpy2.const_pi(16384))[:4400])"
from mpmath import mp; mp.dps = 1000000 ; print(mp.pi)
solo un par de segundos por un millón de dígitos. No está mal !!!.Usando Ruby:
fuente
ruby -e 'require "bigdecimal"; require "bigdecimal/math"; include BigMath; puts BigDecimal(PI(100)).round(9).to_s("F")'
En bash:
fuente
afmtodit
requieregroff
ser instalado. Aquí en Ubuntu (y sabores), es no estándar. JFYIgrep
en mi sistema buscando la constante y la encontré en más de un lugar. ¡Por eso fue +1 para mí!Muy simple en PHP usando la función incorporada pi ():
fuente
¿Cómo me perdí esta pregunta ...
Aquí hay un pequeño programa de Python pi que publiqué hace un par de semanas en Stack Overflow. No es particularmente rápido, pero puede hacer muchos dígitos. :) Sin embargo, como mencioné en ese hilo, generalmente uso el módulo mpmath de Python para aritmética de precisión arbitraria, y mpmath tiene un generador de pi bastante rápido.
P.ej,
En mi humilde opinión, 500000 decimales de pi en menos de 5 segundos no es nada malo, considerando que se está ejecutando en una máquina con un procesador de 2 GHz de un solo núcleo, 2 gigas de RAM y escribiendo en una unidad IDE antigua.
fuente
from mpmath import mp; mp.dps = 1000000 ; print(mp.pi)
(después de una instalación pip3 mpmath) menos de dos segundos por un millón de dígitos. No está mal !!!.Si lo ha
node.js
instalado, hará todo lo posible para encontrar pi por usted, aunque lo mejor no es muy bueno:Resultados de muestra:
fuente
node -e 'console.log(Math.PI)'
es un poco mejor que lo mejor.echo pie
?Método Monte Carlo
Ver, por ejemplo, esto para una explicación de este método.
Advertencias
Ventajas
Divertido :-)
Nota: Primero lo probé sin,
srand
pero se quedó atascado3.14
y los dígitos siguieron oscilando, sin converger. Esto probablemente se deba a que, después de un tiempo, el PRNG comienza a repetirse. El uso desrand
evitará eso o al menos alargará el período de la secuencia pseudoaleatoria. Todo esto es una conjetura, así que siéntete libre de corregirme si me equivoco.fuente
bignum
operaciones en Perl, me temo y no conozco ninguna parte en particular del programa anterior que requiera una Perl más nueva. De todos modos, lo interesante de esto es el algoritmo en sí. Intenta implementarlo en el idioma que elijas si este Perl no funciona para ti.($x,$y,$circle,$not_circle)=(0,0,0);
antes del ciclo para asegurarse de que todas las variables estén definidas antes de ser utilizadas.(0,0,0,0)
.($x,$y,$circle,$not_circle)=(0,0,0,0)
. Después de un minuto o dos, rondaba el valor deseado, luego se acercó mucho más a 3.1409 antes de que me detuviera. ¡Interesante y divertido! ¡Gracias!Puede usar un algoritmo de espiga para pi. El siguiente programa C de Dik Winter y Achim Flammenkamp producirá los primeros 15,000 dígitos de pi, un dígito a la vez.
fuente
PHP
Pocos ejemplos:
Si quieres cambiar la precisión prueba:
Si busca una precisión aún más precisa, consulte Rosetta Code o Code Golf SE para obtener algunas soluciones de programación.
Relacionado: Software que puede calcular PI a al menos mil dígitos en SR.SE
fuente
Aquí hay un script que imprime pi con el número de dígitos especificados (incluido '.') Por el usuario.
pi.sh
salida
y con valor por defecto:
He visto personas que usan
scale
comobc
opción, pero en mi caso (bc 1.06.95
) esto no genera el valor correcto:Observe el último dígito.
fuente
./pi.sh 10
impresiones nueve dígitos, contando la inicial3
. Además, está señalando con el dedo un error de redondeo, pero sus./pi.sh 6
resultados3.1415
, que pueden no ser óptimos.scale=X
opciónbc
NO redondeará el número, sino que simplemente cortará el número en el décimo dígito decimal.Me gusta la respuesta de Abey pero no me gustó cómo bc estaba cambiando el último dígito.
Así que eliminé la escala utilizada printf para establecer el número de dígitos.
fuente
printf
tiene una limitación severa en los números de coma flotante en comparación conbc
. Están representados por eldouble
tipo de lenguaje C con una precisión de aproximadamente 17 dígitos, por lo que incluso los dígitos distintos de cero después del 17 son falsos ------ He agregado una respuesta con el redondeo correcto del resultado no limitado porprintf
. ------ También para asegurarse de que este comando funcione con varias configuraciones regionales, debe hacer algo como esto:LC_ALL=C printf
...¿Qué pasa si no puedes por tu vida recordar esto
arctan
? O suponiendo que ni siquiera sabe que existe esta funciónbc
, intente memorizar esta división simple:Solo funcionará para 6 dígitos, pero para cálculos no científicos esto funcionará bien.
Si crees que tampoco puedes recordar estos dos números, primero escribe el denominador y luego el numerador:
113 355
O porque no
11 33 55
"doble 1, doble 3, doble 5". Todas las figuras son extrañas. Para calcular, divida nuevamente el número de 6 dígitos por la mitad e intercambie el denominador y el numerador antes de dividirlos. Eso es todo.
fuente
4 * arctan(1)
mucho más fácil recordar que 2 números de tres dígitos ... usaría fácilmente 335 en lugar de 355, o 133 en lugar de 113.Se puede suponer que el OP está interesado en un comando de shell corto y fácil de memorizar para imprimir π, pero la pregunta realmente no dice eso. Esta respuesta ignora esa suposición y responde la pregunta estrictamente como está escrita;
¿Trivial?
Si bien ya hay 18 respuestas, todavía falta un enfoque, y con tantas respuestas, uno podría pensar que no es el único que falta:
El trivial: ¿Cómo imprimir π? Solo imprime π!
Ese enfoque parece ser demasiado inútil como para pensarlo, pero demostraré que tiene sus ventajas:
Optimizado
Normalmente calcularíamos el valor de π. No veo lo que nos impide optimizar la solución, calculando previamente el valor; es una constante, cualquier compilador haría eso.
Queremos cierto número de dígitos de π, hasta una precisión máxima. Entonces podemos tomar el prefijo de la constante, como texto:
Una variante con un argumento explícito para la precisión, por ejemplo. para precisión
5
:Ventajas
La precisión máxima se puede elegir arbitrariamente usando una constante adecuada calculada usando una de las otras respuestas. Está limitado solo por la longitud máxima de una línea de comando.
Tiene una complejidad de tiempo constante para encontrar el valor.
Hace obvios todos los límites y restricciones, en función de la baja complejidad de la implementación.
Maneja la precisión más grande que el máximo con gracia al devolver la constante en la precisión total disponible (sin arrastre
0
).Entonces, esta solución, aunque trivial, tiene ventajas. Puede ser útil cuando se usa en una función de shell, por ejemplo.
Mínimo
La funcionalidad de la solución anterior también se puede implementar sin crear un proceso para
cut
(suponiendo queecho
sea un shell incorporado). Utiliza el comandoprintf
(normalmente integrado) de una manera algo oscura:la constante se maneja completamente como una cadena (el formato usa
%s
), no hay aritmética de punto flotante involucrada, por lo que los límites defloat
odouble
no se aplican aquí.El valor de precisión del
%s
escape (5
en el ejemplo a continuación) especifica la longitud del prefijo de cadena a imprimir, que es la precisión. El3.
es parte delprintf
formato para mantenerlo fuera del cálculo de precisión.Alternativa con precisión como argumento separado:
O un poco más legible (tenga en cuenta el espacio entre
3.
y14159...
, son argumentos separados):Rápido
Se
printf
puede esperar que la variante de uso sea muy rápida: debido a queprintf
es un shell incorporado en shells comunes comobash
yzsh
, no crea ningún proceso.Además, no toca ningún tipo de código relacionado con coma flotante, sino solo la manipulación de conjuntos de bytes (explícitamente no caracteres multibyte). Esto suele ser más rápido, a menudo mucho más rápido que el uso de coma flotante.
compatibilidad de printf
A menudo, hay razones para reemplazar
printf
por/usr/bin/printf
garantizar la coherencia o compatibilidad. En este caso, creo que podemos usar el incorporado, lo cual es importante, ya que el uso/usr/bin/printf
reduce la ventaja "rápida" al bifurcar un proceso.Un problema común con la
printf
compatibilidad es el formato de salida del número según la configuración regional. La separación.
de números se puede cambiar,
según la configuración regional; Pero no usamos números, solo una constante de cadena que contiene un literal.
, no afectado por la configuración regional.StéphaneChazelas señaló que
printf %.5s
funciona de manera diferente enzsh
, contando caracteres, no bytes como de costumbre. Afortunadamente, nuestras constantes usan solo caracteres en el rango ASCII inferior, que está codificado por un byte por carácter en cualquier codificación relevante, siempre que usemos laUTF-8
codificación común para Unicode, y no una codificación de ancho fijo.fuente
printf %.5s
es char (no byte) basado en zsh (sensiblemente, pero contra POSIX).ksh93
's%.5Ls
está basado en gráficos.