¿Cómo imprimo pi (3.14159)? [cerrado]

35

¿Qué comando podría imprimir pi para mí? Quiero especificar cuántos dígitos imprime, no pude encontrar nada en línea. Solo quiero poder imprimir pi.

Nombre para mostrar
fuente
28
Elija su idioma: rosettacode.org/wiki/Pi
Mark Plotnick
44
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.

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

Abey
fuente
12
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
Jordan Bentley
1
@JordanBentley, he agregado una respuesta con el redondeo correcto del resultado .
Pabouk
61

Si ha tex(1)instalado:

tex --version | head -1 | cut -f2 -d' '
Steven D
fuente
13
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):

# bc -l
scale=<your precision>
4*a(1)
Abrixas2
fuente
2
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.
Abrixas2
@fduff, he agregado una respuesta con el redondeo correcto del resultado .
Pabouk
20

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).

Ejemplos
$ ./pi 10
3.141592653

$ ./pi 20
3.1415926535897932384

NOTA: La fuente de estos ejemplos está aquí en la fuente de la base del código CLN .

Otras distribuciones

Fedora

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).

Arco

Arch proporciona el mismo programa en el clnpaquete (gracias Amphiteót ).

un CVn
fuente
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):

curl --silent http://www.angio.net/pi/digits/pi1000000.txt | cut -c1-3000
Anthon
fuente
2
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:

$ echo "s=5; scale=s+2; pi=4*a(1); scale=s-1; pi/1" |  bc -l
3.1415
pabouk
fuente
2
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".
Complicado ver biografía
12

perl una línea (usando bignum ):

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

p.ej

perl -Mbignum=bpi -wle 'print bpi(6)'
3.14159
don_crissti
fuente
Para 10.000 dígitos: cerca de 8 minutos en perl, menos de 4 en bc. No es el mas rapido.
Isaac
9

Con python2:

$ python -c "import math; print(str(math.pi)[:7])"
3.14159
mkc
fuente
44
Para completar, esta solución es específica de python2.
HalosGhost
Después de la edición, con (..)esto funciona en Python 2 y 3. Solo parece tener 12 dígitos.
Anthon
$ Python -c "import math; de impresión (formato (math.pi, '.400f'))" 3,1415926535897931159979634685441851615905761718750000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Artem Shitov
1
@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
Vástago
fuente
1
One liner:ruby -e 'require "bigdecimal"; require "bigdecimal/math"; include BigMath; puts BigDecimal(PI(100)).round(9).to_s("F")'
4

En bash:

$ read -a a <<< $(grep M_PIl /usr/include/math.h) ; echo ${a[3]} | tr -d L
3.141592653589793238462643383279502884
Edouard Thiel
fuente
@ 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 ():

<?php 
echo round(pi(), 2);
?>
Mark Farnell
fuente
1
¿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.

PM 2Ring
fuente
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:

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)'

Resultados de muestra:

3.14157749
3.1416426
3.14159055
3.14171554
3.14176165
3.14157587
3.14161137
3.14167685
3.14172371
Paul
fuente
44
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.

Joseph R.
fuente
@ 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.

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;}
Daniel Henneberger
fuente
Contexto: wiki , aquí y aquí .
1
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
Franki
2

PHP

Pocos ejemplos:

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

Si quieres cambiar la precisión prueba:

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

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.

Relacionado: Software que puede calcular PI a al menos mil dígitos en SR.SE

kenorb
fuente
1

Aquí hay un script que imprime pi con el número de dígitos especificados (incluido '.') Por el usuario.

pi.sh

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

salida

$ ./pi.sh 10
3.14159265

y con valor por defecto:

$ ./pi.sh
3.14159

He visto personas que usan scalecomo bcopción, pero en mi caso ( bc 1.06.95) esto no genera el valor correcto:

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

Observe el último dígito.

fduff
fuente
44
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.

printf "%0.5f\n" $(echo "4*a(1)" | bc -l)
3.14159
LinuxGuru
fuente
¿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.

error de sintaxis
fuente
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:

echo 3.1415926535897932384626433832795 | cut -b -7
3.14159

Una variante con un argumento explícito para la precisión, por ejemplo. para precisión 5:

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

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 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.

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

Alternativa con precisión como argumento separado:

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

O un poco más legible (tenga en cuenta el espacio entre 3.y 14159..., son argumentos separados):

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

Rápido

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.

Volker Siegel
fuente
Tenga en cuenta que printf %.5ses char (no byte) basado en zsh (sensiblemente, pero contra POSIX). ksh93's %.5Lsestá basado en gráficos.
Stéphane Chazelas