Come si stampa pi (3.14159)? [chiuso]


35

Quale comando potrebbe stampare pi per me? Voglio specificare quante cifre stampa, non sono riuscito a trovare nulla online. Voglio solo essere in grado di stampare pi.


28
Scegli la tua lingua: rosettacode.org/wiki/Pi
Mark Plotnick,

4
Nota che diventa più divertente se vuoi più cifre di circa il 15.
Thorbjørn Ravn Andersen

2
@DisplayName: significa che non è più possibile utilizzare alcun programma che archivia / calcola internamente PI utilizzando valori in virgola mobile a doppia precisione (che di solito è il tipo di dati FP "incorporato" di massima precisione disponibile nella maggior parte delle lingue).
Matteo Italia,

5
La mia soluzione, decenni fa prima che questo fosse comunemente fornito dalle biblioteche linguistiche, era di memorizzarla in più luoghi di quanti ne avessero mai bisogno i punti fluttuanti che stavo usando: 3.1415926535897932384626 di solito è abbastanza vicino per scopi pratici, e persino quelli poco pratici - qualcosa di reale -world avrà più errori di quello negli altri numeri, e per i teorici rimarrei con il valore simbolico piuttosto che numerico.
Keshlam,

3
L'interesse di @syntaxerror è irrilevante. Se dovessi pubblicare una domanda chiedendo foto di celebrità nude, otterresti migliaia di visualizzazioni e molto probabilmente valutazioni. Questo non lo fa sull'argomento. Questa domanda è un classico esempio di troppo ampio. Guarda il numero di risposte. Si noti inoltre che l'OP non ha specificato alcuna limitazione che renda sostanzialmente possibili le possibili risposte. In ogni caso, la chiusura non viene cancellata. La domanda e tutte le sue 23 risposte saranno ancora qui. Chiudere significa solo che non vengono accettate più risposte. Abbiamo davvero bisogno di ancora più modi per stampare π?
terdon

Risposte:


52

Puoi usare questo comando:

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

Dove scala è il numero di cifre dopo il punto decimale.

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


12
Versione più breve in bashe altre shell di supporto qui stringhe: bc -l <<< "scale=5; 4*a(1)".
pabouk,

2
Mi chiedo quante cifre questo può andare?
DisplayName

4
@DisplayName abbastanza. scale=1000fornisce 999 cifre corrette piuttosto rapidamente (l'ultima cifra è disattivata di 1, ragionevole poiché stiamo calcolando pi / 4 e quindi moltiplicando per 4). scale=4000fornisce 4000 cifre corrette in pochi secondi. scale=10000impiega più tempo di quanto ho pazienza, ma probabilmente fornisce 9999 o 10000 cifre corrette.
Hobbs

4
Questo dà un risultato errato sulla mia macchina, digitando 'echo "scale = 5; 4 * a (1)" | bc -l 'restituisce 3.14156, quando l'ultima cifra dovrebbe essere di 9
Jordan Bentley,

1
@JordanBentley, ho aggiunto una risposta con arrotondamento corretto del risultato .
pabouk,

61

Se hai tex(1)installato:

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

13
Questo vale quasi un voto solo per essere intelligente. Sebbene l'output di questo cambi quando si aggiorna il pacchetto. Lo consideriamo una caratteristica o un bug?
un CVn

8
@ MichaelKjörling In realtà, cambia per essere un'approssimazione più precisa di pi.
Abrixas2,

@ Abrixas2 Sì, lo so. Con l'ultima versione di TeX la versione π.
un CVn

30
@DavidRicherby È possibile stampare meno cifre tramite un'ulteriore chiamata di cut. È possibile stampare più cifre attendendo a lungo ed eseguendo nuovamente il comando.
Steven D,

1
@Ruslan dipende dall'implementazione. Mi aspetterei in questo caso particolare che sarebbe fatto "bene".
Thorbjørn Ravn Andersen,

23

Per la stampa con precisione arbitraria, è possibile utilizzare bce la formula pi = 4*atan(1):

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

2
C'è qualcosa di divertente circa la scalepossibilità, pi = 3.141592..ma con echo "scale=5; 4*a(1)" | bc -l => 3.14156Vorrei poi aspettare di vedere 3.14159?
fduff,

7
scalespecifica la precisione da utilizzare per il calcolo, quindi con scale=5nessuna operazione verranno utilizzate più di cinque cifre frazionarie per qualsiasi operazione atomica.
Abrixas2,


20

Se vuoi qualcosa che possa calcolare il valore di π, allora ci sono diversi approcci. Forse la soluzione più ovvia sarebbe quella di usare un pacchetto già pronto come pi(collegamento del pacchetto Debian) , che se la descrizione del pacchetto di Debian è affidabile può calcolare il valore con una precisione arbitraria, limitata solo dalla memoria.

piè in realtà un esempio incluso nella libreria CLN (Class Library for Numbers) . Comprende applicazioni di esempio che forniscono strumenti per generare lunghezze arbitrarie di numeri come Pi, Fibonacci, ecc. I pacchetti CLN sono disponibili preconfezionati in Debian / Ubuntu (questo è ciò a cui punta il collegamento Debian sopra).

Esempi
$ ./pi 10
3.141592653

$ ./pi 20
3.1415926535897932384

NOTA: l'origine di questi esempi è qui nell'origine per la base di codice CLN .

Altre distro

Fedora

Su Fedora ho dovuto scaricare il tarball sorgente e costruirlo da solo, ma si costruisce con poca confusione. Per qualsiasi motivo il pacchetto clnsu Fedora include solo la libreria ma trascura gli esempi disponibili nella versione Debian / Ubuntu (sopra).

Arco

Arco fornisce lo stesso programma nella il clnpacchetto (grazie Amphiteót ).


Sì, intendevo il valore totale che ho appena digitato quello che avevo in testa.
DisplayName

2
Il "valore totale" ?? Vuoi dire cosa ...?
Kyle Strand,

2
@DisplayName ha letto il resto della risposta. Un programma dedicato come pisembra esattamente quello che stai cercando. Ad esempio, puoi fare cose come pi 300stampare le prime 300 cifre.
terdon

3
@KyleStrand Ho scoperto una risposta davvero meravigliosa a questo, che questo commento è troppo stretto per contenere. Ehi, ha funzionato per Fermat !
terdon

Mi piacerebbe sapere perché questo ha ricevuto due voti negativi. Le persone che hanno effettuato il downgrade non hanno letto la risposta prima di aver deciso che non era utile?
un CVn

17

Per un massimo di un milione di cifre è possibile utilizzare quanto segue (qui per 3000 cifre):

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

2
Ciò ha l'ulteriore vantaggio di essere ragionevolmente vicino alla complessità O (1). O forse non è un vantaggio dopo tutto ...
un CVn del

7
Inoltre, è difficile dire che qualsiasi interazione di rete è O (1) complessità temporale in un mondo pratico. : P
HalosGhost

2
@HalosGhost Per i nostri scopi (rispetto al calcolo di n cifre di pi ogni volta), è probabile che il download di una quantità fissa di dati da un server specifico su una rete sia effettivamente O (1), mentre è probabile che il calcolo di n cifre di pi almeno qualcosa come O (log n) e molto probabilmente più in alto (non ho familiarità con quegli algoritmi). È probabile che il download effettivo dei dati impieghi molto più tempo dell'overhead per avviare il download, quindi il tempo di download domina e si arriva da qualche parte nelle vicinanze di O (1) data una velocità di trasmissione dati ragionevolmente fissa. Quindi O (1).
un CVn

4
@ MichaelKjörling Quando dici O (1) non intendi davvero O (n)? Il tempo di download è lineare nel numero di cifre necessarie, quindi O (n).
CodesInChaos

1
@CodesInChaos No, il tempo di download è costante (data la velocità di trasmissione costante) perché stai scaricando un numero costante di cifre (un milione, qui). A meno che (in questo caso specifico) il ricciolo non sia abbastanza intelligente da stampare durante il download e interrompere il download una volta che la pipa si rompe perché cutesce? In tal caso, sono d'accordo, sarebbe O (n).
un CVn

15

Alcune delle altre risposte mostrano cifre errate negli ultimi punti dell'output. Di seguito è riportata una variazione della risposta utilizzandobc ma con un risultato correttamente arrotondato. La variabile scontiene il numero di cifre significative (incluso 3davanti al punto decimale).

Arrotondare per metà

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

Arrotondare (troncare)

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

Spiegazione dell'arrotondamento

L'arrotondamento viene eseguito direttamente in bc. Ciò non ha la limitazione del comando printfche utilizza la rappresentazione del doubletipo di linguaggio C per i numeri con una precisione di circa 17 cifre significative. Vedi la risposta con printfarrotondamento .

scale=s-1imposta il numero di cifre su cui troncare. pi/1divide il risultato per 1 per applicare il troncamento. Semplice pinon tronca il numero.

L'arrotondamento per metà richiede di aggiungere 5 alla prima cifra che verrà tagliata (5 × 10 -s ) in modo che in caso di cifre più alte di 5 uguale all'ultima cifra che rimarrà verrà incrementata.

Dai test di Hobbs sembra che tre cifre aggiuntive che verranno arrotondate / troncate ( scale=s+2) saranno sufficienti anche per numeri molto lunghi.

Qui stringhe

Gli esempi sopra usano qui stringhe che sono supportate ad esempio in bash, kshe zsh. Se la tua shell non supporta qui usa stringhe echoe pipe invece:

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

2
Il calcolo di tre cifre aggiuntive ai fini dell'arrotondamento non è "arrotondamento corretto" come si afferma in un commento. Innanzitutto, non hai un limite sull'errore del calcolo. Se può essere errato di 3 unità nell'ultimo posto, come affermato da fduff, perché non dovrebbe essere sbagliato di 1000 unità nell'ultimo posto? In secondo luogo, vedere "il dilemma del produttore di tavoli".
Complicato vedi biografia

12

perl una riga (usando bignum ):

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

per esempio

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

Per 10.000 cifre: quasi 8 minuti in perl, meno di 4 in bc. Non il più veloce.
Isaac,

9

Con python2:

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

4
Per completezza, questa soluzione è specifica per python2.
HalosGhost

Dopo la modifica, con (..)questo funziona in Python 2 e 3. Sembra avere solo 12 cifre.
Anthon,

$ Python -c "import math; stampa (formato (Math.PI, '.400f'))" 3,1415926535897931159979634685441851615905761718750000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Artem Shitov

1
@ArtemShitov - il mio male, prova a importare gmpy2 (se lo avete installato): python -c "import gmpy2; print(str(gmpy2.const_pi(8192))[:400])". Aumenta la precisione per più cifre ... ad es.python -c "import gmpy2; print(str(gmpy2.const_pi(16384))[:4400])"
don_crissti

1
Il più veloce che ho trovato è stato from mpmath import mp; mp.dps = 1000000 ; print(mp.pi)solo un paio di secondi per un milione di cifre. Non è affatto male !!!.
Isaac,

7

Usando Ruby:

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

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

3.141592654

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

4

In bash:

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

@ Amphiteóth afmtoditrichiede groffl'installazione. Qui su Ubuntu (e sapori), è non è standard. JFYI.
syntaxerror

@syntaxerror Grazie, buon punto! Ho rimosso il mio esempio. Il mio punto era proprio quando leggevo che questa IA correva grepsul mio sistema alla ricerca della costante e la trovava in più di una posizione. Ecco perché questo era +1 per me!


3

Come ho perso questa domanda ...

Ecco un mio piccolo programma Python pi che ho pubblicato un paio di settimane fa su Stack Overflow. Non è particolarmente veloce, ma può fare molte cifre. :) Comunque, come ho detto in quel thread, generalmente uso il modulo mpmath di Python per l'aritmetica di precisione arbitraria e mpmath ha un creatore di pi piuttosto veloce.

Per esempio,

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

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

500000 decimali di pi in meno di 5 secondi non sono troppo squallidi, IMHO, considerando che è in esecuzione su una macchina con un processore single core da 2 GHz, 2 gig di RAM e la scrittura su un disco IDE anziano.


Prova from mpmath import mp; mp.dps = 1000000 ; print(mp.pi)(dopo l'installazione di pip3 mpmath) in meno di due secondi per un milione di cifre. Non è affatto male !!!.
Isaac,

2

Se hai node.jsinstallato, questo farà del suo meglio per trovare pi per te, anche se il suo meglio non è molto buono:

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

Output di esempio:

3.14157749
3.1416426
3.14159055
3.14171554
3.14176165
3.14157587
3.14161137
3.14167685
3.14172371

4
Il più corto node -e 'console.log(Math.PI)'è un po 'meglio del suo meglio.
Chbrown

1
@chbrown Non soddisfa i requisiti "non seri" dei PO.
Paolo,

1
Quale requisito "non grave"? L'OP ha appena affermato che stanno chiedendo divertimento non che vogliono risposte in qualche modo "non serie". Che cosa significa comunque? Qualcosa del genere echo pie?
terdon

L'ho scritto perché a volte quando si fanno domande la gente dice che "questa non è una fabbrica di sceneggiatura", quindi ho detto che, poiché non esiste un motivo reale, voglio solo sapere come stampare pi.
DisplayName

@ Amphiteóth Ci vogliono circa 20 secondi per funzionare sul mio computer. Potresti aver bisogno di concedergli un po 'di tempo.
Paul,

2

Metodo Monte Carlo

Vedi, ad esempio, questo per una spiegazione di questo metodo.

Avvertenze

  • Non arbitrariamente preciso
  • Ci vuole molto tempo per convergere in qualcosa di utile

vantaggi

Divertimento :-)

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: l'ho provato per la prima volta senza, srandma si è bloccato 3.14e le cifre successive hanno continuato a oscillare, senza mai convergere. Questo probabilmente perché dopo un po 'il PRNG inizia a ripetersi. L'uso di srandeviterà questo o almeno allungherà il periodo della sequenza pseudo-casuale. Questa è tutta una congettura, quindi sentiti libero di correggermi se sbaglio.


@ Amphiteót Non sono proprio sicuro di quello che sta succedendo lì. Se aiuta il mio Perl è v5.14.2. Non sono molto esperto delle bignumoperazioni in Perl, temo e non conosco particolari parti del programma sopra che richiedono un Perl più recente. Comunque, ciò che è interessante di questo è l'algoritmo stesso. Prova a implementarlo nella tua lingua preferita se questo Perl non funziona per te.
Joseph R.,

1
@ Anfite - Capisco. La modifica risolve il tuo problema?
Joseph R.,

@ Amphiteót Puoi provare ad aggiungere ($x,$y,$circle,$not_circle)=(0,0,0);prima del ciclo per assicurarti che tutte le variabili siano definite prima di essere utilizzate.
Joseph R.,

@ Amphiteót Il mio errore. I genitori sopra avrebbero dovuto essere (0,0,0,0).
Joseph R.,

Con questo /5.20.1: ha senso ma non l'ho visto! Anzi ($x,$y,$circle,$not_circle)=(0,0,0,0). Dopo un minuto o due si è aggirato attorno al valore desiderato, quindi è andato molto più vicino a 3.1409 prima che mi fermassi. Interessante e divertente! Grazie!

2

Puoi usare un algoritmo spigot per pi. Il seguente programma C di Dik Winter e Achim Flammenkamp produrrà le prime 15.000 cifre di pi, una cifra alla volta.

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;}

Contesto: wiki , qui e qui .

1
Adoro l'algoritmo spigot per le costanti logaritmiche di Borwein, Bailey e Plouffe, tuttavia, questo non è il golf del codice, quindi posso migliorare la leggibilità del tuo codice riformattandolo? Si noti inoltre che gli algoritmi in stile BPP possono solo generare cifre per pi in basi che sono potenze di 2, almeno senza usare memoria aggiuntiva.
Franki,

@Franki la formattazione del codice cambia il significato o l'intenzione del post? In caso contrario, dovrebbe andare bene (e la modifica può sempre essere ripristinata). Non vedo come deobuscolare un po 'di codice potrebbe fare qualcos'altro che chiarire.
11684

1
@syntaxerror Deve produrre esattamente 15.000 cifre prima di fermarsi. L'output nel secondo for-loop produce 4 cifre di pi e diminuisce il numero misterioso di 52514 di 14. L'equazione sarebbe quindi 4 * (52514/14) che equivale a 15004. Gli ultimi 14 valori nell'array vengono ignorati per prendere vantaggio di un minor numero di token per ottenere il nostro valore esatto di 15000.
Daniel Henneberger,

1
@ 11684 No, non cambierebbe davvero il significato o l'intenzione del codice. Tuttavia, ho capito che questo non è un algoritmo rubinetto BBP-stile per pi greco, ma un altro che qualcun altro ha già deobfuscated qui stackoverflow.com/a/25837097
Franki

2

PHP

Alcuni esempi:

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

Se vuoi cambiare la precisione prova:

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

La dimensione di un float dipende dalla piattaforma, sebbene un massimo di ~ 1,8e308 con una precisione di circa 14 cifre decimali sia un valore comune (il formato IEEE a 64 bit). [leggi di più]


Se stai cercando una precisione ancora più accurata, controlla Rosetta Code o Code Golf SE per alcune soluzioni di programmazione.

Correlati: software in grado di calcolare PI ad almeno un migliaio di cifre su SR.SE


1

Ecco uno script che stampa pi con il numero di cifre specificato (incluso '.') Dall'utente.

pi.sh

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

produzione

$ ./pi.sh 10
3.14159265

e con valore predefinito:

$ ./pi.sh
3.14159

Ho visto persone che usano scalecome bcopzione, ma nel mio caso ( bc 1.06.95) questo non produce il valore corretto:

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

Si noti l'ultima cifra.


4
La domanda dice: "Voglio specificare quante cifre stampa", il che, in senso stretto, è ambiguo - ma penso che la tua risposta fallisca (su un tecnicismo) sotto qualsiasi ragionevole interpretazione; le tue ./pi.sh 10stampe sono di nove cifre, contando l'iniziale 3. Inoltre, stai indicando l'errore di arrotondamento, ma le tue ./pi.sh 6uscite 3.1415, che potrebbero non essere ottimali.
G-Man dice "Ripristina Monica" il

Dalla memoria, l' scale=Xopzione bcNON arrotonderà il numero, ma semplicemente taglierà il numero alla cifra decimale X.
syntaxerror,

1

Mi piace la risposta di Abey ma non mi è piaciuto come bc stesse cambiando l'ultima cifra.

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

Quindi ho rimosso la scala usando printf per impostare il numero di cifre.

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

Hai notato, dopo una scala di 62 cifre, sono tutte 0 mentre ciò non accade con il comando originale.

2
@ Amphiteót, Questo perché printfha una grave limitazione dei numeri in virgola mobile rispetto a bc. Sono rappresentati dal doubletipo di linguaggio C con una precisione di circa 17 cifre, quindi anche le cifre diverse da zero dopo il 17 ° sono fasulle! ------ Ho aggiunto una risposta con arrotondamento corretto del risultato non limitato daprintf . ------ Anche per assicurarti che questo comando LC_ALL=C printf
funzioni

1

E se non riesci per la vita a ricordare questa arctancosa? O supponendo che tu non sappia nemmeno che questa funzione esiste bc, quindi prova a memorizzare questa semplice divisione:

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

Funzionerà solo per 6 cifre, ma per i calcoli non scientifici questo andrà bene.

Se pensi di non ricordare nemmeno questi due numeri, scrivi prima il denominatore, quindi il numeratore:

113 355

O perché no

11 33 55

"doppio 1, doppio 3, doppio 5". Tutte le cifre sono strane. Per calcolare, dividere nuovamente il numero di 6 cifre a metà e scambiare denominatore e numeratore prima di dividerli. Questo è tutto.


Per quanto mi riguarda, trovo 4 * arctan(1)molto più facile ricordare che 2 numeri a tre cifre ... Userei facilmente 335 invece di 355 o 133 invece di 113.
John WH Smith

Beh, penso che sia una questione di preferenze personali. :) Le persone (come me) che possono facilmente memorizzare (numeri di telefono fissi!) Sarebbero in grado di memorizzare due numeri come un solo numero di telefono. Aiuterà anche quelle persone che a scuola sentivano che la trigonometria doveva essere stata creata da poteri malvagi.
syntaxerror

1

Si può presumere che l'OP sia interessato a un comando di shell breve e facile da memorizzare per stampare π - ma la domanda non lo dice davvero. Questa risposta ignora tale presupposto e risponde alla domanda rigorosamente come scritto;

Banale?

Mentre ci sono già 18 risposte, manca ancora un approccio - e con così tante risposte, si potrebbe pensare che non sia l'unico che manca:
Quello banale: come stampare π? Basta stampare π!

Questo approccio sembra essere troppo inutile per pensarci, ma mostrerò che ha le sue allegre:

ottimizzata

Normalmente calcoliamo il valore di π. Non vedo cosa ci impedisce di ottimizzare la soluzione, precalcolando il valore: è una costante, qualsiasi compilatore lo farebbe.

Vogliamo un numero di cifre di π, con la massima precisione. Quindi possiamo semplicemente prendere il prefisso della costante, come testo:

echo 3.1415926535897932384626433832795 | cut -b -7
3.14159

Una variante con un argomento esplicito per la precisione, ad es. per precisione 5:

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

vantaggi

La massima precisione può essere scelta arbitrariamente usando una costante adatta calcolata usando una delle altre risposte. È limitato solo dalla lunghezza massima di una riga di comando.
Ha una complessità temporale costante per la ricerca del valore.
Rende evidenti tutti i limiti e i vincoli, in base alla bassa complessità dell'implementazione.
Gestisce con precisione una precisione maggiore del massimo restituendo la costante nella massima precisione disponibile (senza trascinamento 0).
Quindi questa soluzione, sebbene banale, ha dei vantaggi. Può essere utile quando viene utilizzato in una funzione shell, ad esempio.

Minimo

La funzionalità della soluzione sopra può anche essere implementata senza creare un processo per cut(supponendo che echosia incorporato nella shell). Usa il comando printf(normalmente un builtin) in un modo un po 'oscuro:
la costante è completamente gestita come una stringa (il formato utilizza %s), non vi è alcun calcolo in virgola mobile, quindi i limiti di floato doublenon si applicano qui.
Il valore di precisione %sdell'escape ( 5nell'esempio seguente) specifica la lunghezza del prefisso della stringa da stampare, che è la precisione. Fa 3.parte del printfformato per tenerlo fuori dal calcolo di precisione.

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

Alternativa con precisione come argomento separato:

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

O leggermente più leggibile (Nota lo spazio tra 3.e 14159..., sono argomenti separati):

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

Veloce

printfCi si può aspettare che la variante che usi sia molto veloce: poiché printfè una shell integrata in shell comuni come bashe zsh, non crea alcun processo.
Inoltre, non tocca alcun tipo di codice in virgola mobile, ma solo la manipolazione di array di byte (caratteri esplicitamente non multibyte). Questo di solito è più veloce, spesso molto più veloce dell'uso del virgola mobile.

compatibilità printf

Spesso, ci sono ragioni per sostituire printfda /usr/bin/printfa consistenza garanzia o compatibilità. In questo caso, penso che possiamo usare il builtin, il che è importante, poiché l'uso /usr/bin/printfriduce il vantaggio "veloce" tramite il fork di un processo.
Un problema comune con la printfcompatibilità è il formato di output del numero in base alla locale. La separazione .per i numeri può essere modificata in ,base all'impostazione internazionale; Ma non usiamo numeri, solo una costante di stringa contenente un valore letterale ., non influenzato dalle impostazioni locali.
StéphaneChazelas lo ha sottolineatoprintf %.5s funziona diversamentezsh, contando i caratteri, non i byte come al solito. Fortunatamente, le nostre costanti utilizzano solo caratteri nell'intervallo ASCII inferiore, che è codificato da un byte per carattere in qualsiasi codifica pertinente, purché utilizziamo la UTF-8codifica comune per Unicode e non una codifica a larghezza fissa.


Si noti che printf %.5sè char (non byte) basato su zsh (sensibilmente, ma rispetto a POSIX). ksh93's %.5Lssi basa Graphem.
Stéphane Chazelas,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.