Comment imprimer un pi (3.14159)? [fermé]


35

Quelle commande pourrait imprimer pi pour moi? Je veux spécifier le nombre de chiffres imprimés, je n'ai rien trouvé en ligne. Je veux juste être capable d'imprimer pi.


28
Faites votre choix de langues: rosettacode.org/wiki/Pi
Mark Plotnick

4
Notez que cela devient plus amusant si vous voulez plus de chiffres qu'environ 15.
Thorbjørn Ravn Andersen

2
@ NomAffichage: cela signifie que vous ne pouvez plus utiliser aucun programme qui stocke / calcule en interne des PI à l'aide de valeurs à virgule flottante double précision (qui est généralement le type de données de FP "intégré" le plus précis disponible dans la plupart des langues).
Matteo Italia

5
Ma solution, il y a plusieurs décennies, était communément fournie par les bibliothèques de langues et consistait à la mémoriser à plus d'endroits que les points flottants que j'utilisais n'auraient jamais besoin. -world va avoir plus d'erreur que cela dans les autres nombres, et pour les théoriques, je resterais avec la valeur symbolique plutôt que numérique.
Keshlam

3
l'intérêt de @syntaxerror n'est pas pertinent. Si vous posez une question demandant des images nues de célébrités, vous obtiendrez des milliers de vues et très probablement des votes positifs. Cela ne fait pas sur le sujet. Cette question est un exemple classique de trop large. Il suffit de regarder le nombre de réponses. Notez également que le PO ne spécifiait aucune limitation, ce qui rend les réponses possibles essentiellement infinies. Dans tous les cas, la fermeture n'est pas la suppression. La question et l'ensemble de ses 23 réponses seront toujours là. La fermeture signifie simplement qu’aucune autre réponse n’est acceptée. Avons-nous vraiment besoin de plus de façons d'imprimer π?
terdon

Réponses:


52

Vous pouvez utiliser cette commande:

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

Où scale est le nombre de chiffres après le point décimal.

Référence: http://www.tux-planet.fr/calculer-le-chiffre-pen-en-ligne-de-commande-sous-linux/


12
Version plus courte dans bashet d' autres coquilles de support ici cordes: bc -l <<< "scale=5; 4*a(1)".
Pabouk

2
Je me demande combien de chiffres cela peut aller?
DisplayName

4
@DisplayName plusieurs. scale=1000donne 999 chiffres corrects assez rapidement (le dernier chiffre est désactivé de 1, raisonnable puisque nous calculons pi / 4 et que nous multiplions ensuite par 4). scale=4000donne 4000 chiffres corrects en quelques secondes. scale=10000prend plus de temps que je n'ai de patience, mais donne probablement 9999 ou 10000 chiffres corrects.
Hobbs

4
Cela donne un résultat incorrect sur ma machine en tapant 'echo "scale = 5; 4 * a (1)" | bc -l 'renvoie 3.14156, alors que le dernier chiffre devrait être avant le 9
Jordan Bentley

1
@ JordanBentley, j'ai ajouté une réponse avec l'arrondi correct du résultat .
Pabouk

61

Si vous avez tex(1)installé:

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

13
Cela vaut presque un vote positif juste pour être intelligent. Bien que la sortie de ceci change lorsque vous mettez à jour le paquet. Doit-on considérer cela comme une fonctionnalité ou un bug?
un CVn

8
@ MichaelKjörling En fait, il se change en une approximation plus précise de pi.
Abrixas2

@ Abrixas2 Oui, je sais. La dernière version de TeX étant la version π.
un CVn

30
@DavidRicherby Moins de chiffres peuvent être imprimés via un appel supplémentaire de cut. Plus de chiffres peuvent être imprimés en attendant longtemps et en exécutant à nouveau la commande.
Steven D

1
@Ruslan dépend de la mise en œuvre. Je m'attendrais dans ce cas particulier à ce que ce soit fait "correctement".
Thorbjørn Ravn Andersen

23

Pour imprimer avec une précision arbitraire, vous pouvez utiliser bcla formule suivante pi = 4*atan(1):

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

2
Il y a quelque chose de drôle à propos de l' scaleoption, pi = 3.141592..mais avec echo "scale=5; 4*a(1)" | bc -l => 3.14156quoi puis-je m'attendre à voir 3.14159?
Fduff

7
scalespécifie la précision à utiliser pour le calcul. Ainsi, avec scale=5, aucune opération n'utilisera plus de cinq chiffres fractionnaires pour une opération atomique.
Abrixas2


20

Si vous voulez quelque chose qui puisse calculer la valeur de π, il y a plusieurs approches. La solution la plus évidente serait peut-être d'utiliser un paquet prêt à l'emploi tel que pi(lien du paquet Debian) , qui, si la description du paquet Debian doit être approuvée, peut calculer la valeur avec une précision arbitraire, limitée uniquement par la mémoire.

piest en fait un exemple inclus dans la bibliothèque CLN (Class Library for Numbers) . Il inclut des exemples d'applications fournissant des outils permettant de générer des longueurs arbitraires de nombres tels que Pi, Fibonacci, etc. Des packages CLN sont disponibles pré-emballés dans Debian / Ubuntu (c'est ce que le lien Debian ci-dessus pointe vers).

Exemples
$ ./pi 10
3.141592653

$ ./pi 20
3.1415926535897932384

Remarque: la source de ces exemples est ici dans la source pour la base de code CLN .

Autres distributions

Feutre

Sur Fedora, je devais télécharger l’archive source et la construire moi-même, mais elle se construit sans problème. Pour une raison quelconque, le paquet clnsur Fedora n'inclut que la bibliothèque, mais néglige les exemples disponibles dans la version Debian / Ubuntu (ci-dessus).

Cambre

Arch fournit le même programme dans le clnpackage (merci Amphiteót ).


Ouais, je parlais de la valeur totale que je viens de taper ce que j'avais dans la tête.
DisplayName

2
La "valeur totale" ?? Ce qui signifie...?
Kyle Strand

2
@ NomAffichage lit le reste de la réponse. Un programme dédié piressemble exactement à ce que vous recherchez. Vous pouvez faire des choses comme pi 300imprimer les 300 premiers chiffres, par exemple.
Terdon

3
@KyleStrand J'ai découvert une réponse vraiment merveilleuse à cela, que ce commentaire est trop étroit pour contenir. Hé, ça a fonctionné pour Fermat !
terdon

J'aimerais savoir pourquoi cela a reçu deux votes négatifs. Les personnes qui ont voté vers le bas n'ont-elles pas lu la réponse avant d'avoir décidé que cela n'était pas utile?
un CVn

17

Pour un million de chiffres maximum, vous pouvez utiliser les éléments suivants (ici pour 3000 chiffres):

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

2
Cela présente l’avantage supplémentaire qu’il devrait être raisonnablement proche de la complexité O (1). Ou peut-être que ce n'est pas un avantage après tout ...
un CVn

7
En outre, il est difficile de dire que toute interaction réseau est une complexité temporelle O (1) dans un monde pratique. : P
HalosGhost

2
@HalosGhost Pour nos besoins (comparé au calcul de n chiffres de pi à chaque fois), le téléchargement d’une quantité fixe de données d’un serveur spécifique sur un réseau est susceptible d’être réellement efficace (1), alors que le calcul de n chiffres de pi est susceptible d’être au moins quelque chose comme O (log n) et probablement plus haut (je ne suis pas familier avec ces algorithmes). Le téléchargement des données prendra probablement beaucoup plus de temps que le temps système nécessaire pour le démarrer. Par conséquent, le temps de téléchargement prédomine et vous obtenez quelque part dans les environs de O (1) avec un débit de transmission de données raisonnablement fixe. D'où O (1).
un CVn

4
@ MichaelKjörling Lorsque vous dites O (1), ne voulez-vous pas dire réellement O (n)? La durée de téléchargement en linéaire dans le nombre de chiffres dont vous avez besoin, d'où O (n).
CodesInChaos

1
@CodesInChaos Non, le temps de téléchargement est constant (avec un taux de transmission constant) car vous téléchargez un nombre constant de chiffres (un million, ici). À moins que (dans ce cas particulier) curl ne soit assez intelligent pour imprimer pendant le téléchargement et arrêter de télécharger une fois que le tuyau se rompt parce que se cuttermine? Si tel est le cas, je conviens que ce serait O (n).
un CVn

15

Certaines des autres réponses affichent des chiffres incorrects aux derniers endroits de la sortie. Vous trouverez ci-dessous une variation de la réponse utilisantbc mais avec un résultat correctement arrondi. La variable scontient le nombre de chiffres significatifs (y compris3 devant le signe décimal).

Arrondir la moitié

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

Arrondir (tronquer)

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

Explication de l'arrondi

L'arrondi est effectué directement en format bc. Cela n'a pas la limitation de la commande printfqui utilise la représentation du doubletype de langage C pour les nombres qui a une précision d'environ 17 chiffres significatifs. Voir la réponse en printfarrondissant .

scale=s-1définit le nombre de chiffres à tronquer. pi/1divise le résultat par 1 pour appliquer la troncature. Simplepi ne tronque pas le nombre.

Pour arrondir la moitié supérieure, il faut ajouter 5 au premier chiffre qui sera coupé (5 × 10 -s ) afin que, dans le cas de chiffres supérieurs à 5, le dernier chiffre restant sera incrémenté.

D'après les tests effectués par Hobbs, il semble que trois chiffres supplémentaires qui seront arrondis / coupés ( scale=s+2) suffiront, même pour des nombres très longs.

Ici des cordes

Les exemples ci-dessus utilisent ici des chaînes qui sont supportées par exemple dans bash, kshet zsh. Si votre shell ne supporte pas ici string use echoet pipe à la place:

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

2
Le calcul de trois chiffres supplémentaires aux fins d’arrondir n’est pas un «arrondi correct» comme vous le déclarez dans un commentaire. Premièrement, vous n'avez pas de limite à l'erreur du calcul. S'il peut se tromper de trois unités à la dernière place, comme le prétend fduff, pourquoi ne pas se tromper de 1000 unités à la dernière place? Deuxièmement, voir «le dilemme du fabricant de la table».
Compliqué voir bio

12

perl une ligne (en utilisant bignum ):

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

par exemple

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

Pour 10 000 chiffres: près de 8 minutes en perl, moins de 4 en av. Pas le plus rapide.
Isaac

9

Avec python2:

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

4
Par souci d'exhaustivité, cette solution est spécifique à python2.
HalosGhost

Après l'édition, (..)cela fonctionne avec Python 2 et 3. Cela semble seulement avoir 12 chiffres.
Anthon

$ Python -c "math d'importation; impression (format (Math.PI. '.400f'))" 3,1415926535897931159979634685441851615905761718750000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Artem Shitov

1
@ArtemShitov - mon mauvais, essayez d' importer gmpy2 (si vous l' avez installé): python -c "import gmpy2; print(str(gmpy2.const_pi(8192))[:400])". Augmentez la précision pour plus de chiffres ... par exemplepython -c "import gmpy2; print(str(gmpy2.const_pi(16384))[:4400])"
don_crissti

1
Le plus rapide que j'ai pu trouver était from mpmath import mp; mp.dps = 1000000 ; print(mp.pi)juste quelques secondes pour un million de chiffres. Pas mal du tout !!!.
Isaac

7

Utiliser Ruby:

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

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

3.141592654

1
Une doublure: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

@ Amphiteóth afmtoditnécessite groffd'être installé. Ici sur Ubuntu (et les saveurs), ce n'est pas standard. JFYI.
erreur de syntaxe

@ Syntaxerror Merci, bon point! J'ai enlevé mon exemple. Mon argument était juste au moment de lire cette IA fonctionnait grepsur mon système à la recherche de la constante et la retrouvait à plusieurs endroits. C'est pourquoi c'était +1 pour moi!

3

Très simple en PHP en utilisant la fonction pi () intégrée:

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

1
Pouvez-vous éditer ceci pour donner une version en ligne de commande?
curieuxdannii

3

Comment ai-je raté cette question ...

Voici un petit programme Python pi que j’ai posté il ya quelques semaines sur Stack Overflow. Ce n'est pas particulièrement rapide, mais cela peut faire beaucoup de chiffres. :) Cependant, comme je l'ai mentionné dans ce fil de discussion, j'utilise généralement le module mpmath de Python pour l'arithmétique en précision arbitraire, et mpmath a un créateur de pi assez rapide.

Par exemple,

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

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

500000 décimales de pi en moins de 5 secondes, ce n'est pas si grave, à mon humble avis, vu qu'il tourne sur une machine dotée d'un processeur à cœur unique à 2 GHz, de 2 Go de RAM et écrit sur un lecteur IDE âgé.


Essayez from mpmath import mp; mp.dps = 1000000 ; print(mp.pi)(après un pip3 installer mpmath) moins de deux secondes pour un million de chiffres. Pas mal du tout !!!.
Isaac

2

Si vous avez node.jsinstallé, ceci fera de son mieux pour trouver le pi pour vous, bien que son meilleur ne soit pas très bon:

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

Exemples de sortie:

3.14157749
3.1416426
3.14159055
3.14171554
3.14176165
3.14157587
3.14161137
3.14167685
3.14172371

4
Le plus court node -e 'console.log(Math.PI)'est un peu meilleur que son meilleur.
Chbrown

1
@chbrown Cela ne satisfait pas l'exigence "pas grave" des PO.
Paul

1
Quelle exigence "pas grave"? Le PO a simplement déclaré qu'il demandait du plaisir, mais pas des réponses "non sérieuses". Qu'est-ce que cela veut dire de toute façon? Quelque chose comme echo pie?
terdon

J'ai tapé ça parce que quand on pose des questions, parfois, les gens disent que "ce n'est pas une usine d'écriture de script", alors j'ai dit ça parce qu'il n'y a pas de vraie raison pour cela, je veux juste savoir comment imprimer pi.
DisplayName

@ Amphiteóth Cela prend environ 20 secondes pour fonctionner sur mon ordinateur. Vous pourriez juste avoir besoin de lui donner un peu de temps.
Paul

2

Méthode Monte Carlo

Voir, par exemple, cette pour une explication de cette méthode.

Mises en garde

  • Pas arbitrairement précis
  • Il faut beaucoup de temps pour converger vers quelque chose d'utile

Avantages

Amusement :-)

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

Remarque: je l'ai d'abord essayé sans, srandmais il est resté bloqué 3.14et les chiffres suivants ont continué à osciller, sans jamais converger. C'est probablement parce que, au bout d'un moment, le PRNG commence à se répéter. L’utilisation de of srandévitera ou du moins allongera la période de la séquence pseudo-aléatoire. Tout cela est une conjecture, alors n'hésitez pas à me corriger si je me trompe.


@ Amphiteót Pas vraiment sûr de ce qui se passe là-bas. Si cela aide mon Perl est v5.14.2. Je ne suis pas vraiment familiarisé avec les bignumopérations en Perl. Je crains et je ne connais aucune partie du programme ci-dessus qui nécessite un Perl plus récent. Quoi qu'il en soit, ce qui est intéressant, c'est l'algorithme lui-même. Essayez de l’implémenter dans la langue de votre choix si ce Perl ne fonctionne pas pour vous.
Joseph R.

1
@ Amphiteót je vois. Est-ce que l'édition résout votre problème?
Joseph R.

@ Amphiteót Vous pouvez essayer d'ajouter ($x,$y,$circle,$not_circle)=(0,0,0);avant la boucle pour vous assurer que toutes les variables sont définies avant d'être utilisées.
Joseph R.

@ Amphiteót mon erreur. Les parens ci-dessus auraient dû être (0,0,0,0).
Joseph R.

Re ce /5.20.1: Fait sens , mais ne pas le voir! En effet ($x,$y,$circle,$not_circle)=(0,0,0,0). Au bout d'une minute ou deux, la valeur désirée traînait, puis elle s'est beaucoup rapprochée de 3,1409 avant que je m'arrête. Intéressant et amusant! Merci!

2

Vous pouvez utiliser un algorithme de broche pour pi. Le programme C suivant de Dik Winter et Achim Flammenkamp produira les 15 000 premiers chiffres de pi, un chiffre à la fois.

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

Contexte: wiki , ici et ici .

1
J'adore l'algorithme à broche pour les constantes logarithmiques de Borwein, Bailey et Plouffe, cependant, ce n'est pas du code golf, puis-je améliorer la lisibilité de votre code en le reformatant? Notez également que les algorithmes de type BPP peuvent uniquement générer des chiffres pour pi dans des bases de puissance égale à 2, au moins sans utiliser de mémoire supplémentaire.
Franki

@Franki le formatage du code modifie-t-il le sens ou l'intention du message? Sinon, ça devrait aller (et l'édition peut toujours être annulée). Je ne vois pas comment désobfuser un code pourrait faire autre chose que clarifier.
11684

1
@syntaxerror Il s'agit de produire exactement 15 000 chiffres avant de vous arrêter. La sortie dans la seconde boucle for produit 4 chiffres de pi et décrémente le nombre mystère de 52514 par 14. L'équation serait alors de 4 * (52514/14), ce qui équivaut à 15004. Les 14 dernières valeurs du tableau ne sont pas prises en compte. avantage de moins de jetons pour obtenir notre valeur exacte de 15000.
Daniel Henneberger

1
@ 11684 Non, cela ne changerait vraiment pas le sens ou l'intention du code. Cependant, je me suis rendu compte que ce n'était pas un algorithme de broche de style BBP pour pi, mais un autre que quelqu'un d'autre a déjà désobfusqué ici stackoverflow.com/a/25837097
Franki

2

PHP

Quelques exemples:

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

Si vous voulez changer la précision, essayez:

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

La taille d'un float dépend de la plate-forme, bien qu'un maximum d'environ 1.8e308 avec une précision d'environ 14 chiffres décimaux soit une valeur commune (format IEEE 64 bits). [Lire la suite]


Si vous recherchez une précision encore plus précise, consultez les solutions de programmation Rosetta Code ou Code Golf SE .

Connexes: logiciels permettant de calculer l'IP à au moins mille chiffres chez SR.SE


1

Voici un script qui imprime pi avec le nombre de chiffres spécifié (y compris '.') Par l'utilisateur.

pi.sh

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

sortie

$ ./pi.sh 10
3.14159265

et avec la valeur par défaut:

$ ./pi.sh
3.14159

J'ai vu des gens en utilisant scalecomme bcoption, mais dans mon cas ( bc 1.06.95) cela ne sort pas la valeur correcte:

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

Remarquez le dernier chiffre.


4
La question dit: "Je veux spécifier le nombre de chiffres imprimés", ce qui, à proprement parler, est ambigu - mais je pense que votre réponse échoue (techniquement) sous une interprétation raisonnable; votre ./pi.sh 10affiche neuf chiffres, en comptant l'initiale 3. De plus, vous pointez le doigt de l'erreur d'arrondi, mais vos ./pi.sh 6sorties 3.1415, qui peuvent ne pas être optimales.
G-Man dit 'Réintégrez Monica'

De mémoire, l' scale=Xoption de bcne arrondira PAS le nombre, mais simplement couper le nombre au X-ème chiffre décimal.
erreur de syntaxe

1

J'aime la réponse d’Abey mais je n’ai pas aimé comment bc changeait le dernier chiffre.

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

J'ai donc supprimé l'échelle utilisée printf pour définir le nombre de chiffres.

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

Avez-vous remarqué, après une échelle de 62 chiffres, ils sont tous 0 alors que cela ne se produit pas avec la commande d'origine.

2
@ Amphiteót, En effet printf, les nombres en virgule flottante sont fortement limités par rapport à bc. Ils sont représentés par le doubletype de langage C avec une précision d'environ 17 chiffres, de sorte que même les chiffres non nuls après le 17e sont erronés! ------ J'ai ajouté une réponse avec un arrondi correct du résultat non limité parprintf . ------ Pour vous assurer que cette commande fonctionne avec différents paramètres régionaux, vous devez procéder de la manière suivante: LC_ALL=C printf...
pabouk

1

Et si vous ne pouvez pas pour la vie de vous souvenir de cette arctanchose? Ou en supposant que vous ne sachiez même pas que cette fonction existe bc, essayez de mémoriser cette division simple:

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

Ne fonctionnera que pour 6 chiffres, mais pour des calculs non scientifiques, cela fonctionnera bien.

Si vous pensez ne pas vous souvenir de ces deux nombres, écrivez d'abord le dénominateur, puis le numérateur:

113 355

Ou pourquoi pas

11 33 55

"double 1, double 3, double 5". Tous les chiffres sont étranges. Pour calculer, divisez à nouveau le nombre à 6 chiffres en deux, et permutez le dénominateur et le numérateur avant de les diviser. C'est à peu près ça.


En ce qui me concerne, je trouve 4 * arctan(1)beaucoup plus facile de me rappeler que deux nombres à trois chiffres ... J'utiliserais facilement 335 au lieu de 355, ou 133 au lieu de 113.
John WH Smith

Eh bien, je pense que c'est une question de préférence personnelle. :) Les personnes (comme moi) qui peuvent facilement mémoriser (numéros de téléphone fixes) des numéros de téléphone seraient capables de mémoriser deux numéros comme un seul numéro de téléphone. Cela aidera également les personnes qui, à l'école, ont le sentiment que la trigonométrie a dû être faite par des puissances diaboliques.
erreur de syntaxe

1

On peut supposer que le PO s'intéresse à une commande shell courte, facile à mémoriser, pour imprimer π - mais la question ne dit pas vraiment cela. Cette réponse ignore cette hypothèse et répond à la question strictement telle que écrite;

Banal?

Bien qu'il y ait déjà 18 réponses, une approche est toujours manquante - et avec tant de réponses, on pourrait penser que ce n'est pas la seule qui manque:
la plus triviale: comment imprimer π? Il suffit d'imprimer π!

Cette approche semble être trop inutile pour même y penser, mais je montrerai qu'elle a ses merrits:

Optimisé

Nous calculerions normalement la valeur de π. Je ne vois pas ce qui nous empêche d'optimiser la solution en calculant la valeur à l'avance. C'est une constante, tout compilateur le ferait.

Nous voulons un nombre de chiffres de π, avec une précision maximale. Nous pouvons donc simplement prendre le préfixe de la constante, sous forme de texte:

echo 3.1415926535897932384626433832795 | cut -b -7
3.14159

Une variante avec un argument explicite pour la précision, par exemple. pour la précision 5:

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

Avantages

La précision maximale peut être choisie arbitrairement en utilisant une constante appropriée calculée à l'aide de l'une des autres réponses. Il n'est limité que par la longueur maximale d'une ligne de commande.
Il a une complexité de temps constante pour trouver la valeur.
Toutes les limites et contraintes sont évidentes, en raison de la faible complexité de la mise en œuvre.
Il gère avec précision la précision supérieure au maximum en renvoyant la constante dans toute la précision disponible (sans fin 0).
Cette solution, bien que triviale, présente donc des avantages. Cela peut être utile lorsqu'il est utilisé dans une fonction shell, par exemple.

Minimal

Les fonctionnalités de la solution ci-dessus peuvent également être implémentées sans créer de processus cut(en supposant echoque le shell est intégré). Elle utilise la commande printf(normalement une commande intégrée) d'une manière quelque peu obscure:
la constante est complètement manipulée comme une chaîne (le format utilisé %s), il n'y a pas d'arithmétique à virgule flottante impliquée, donc les limites de floatou doublene s'appliquent pas ici.
La valeur de précision de l' %séchappement ( 5dans l'exemple ci-dessous) spécifie la longueur du préfixe de chaîne à imprimer - qui est la précision. Le 3.fait partie du printfformat pour le garder en dehors du calcul de précision.

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

Alternative avec précision comme argument séparé:

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

Ou légèrement plus lisible (Notez l'espace entre 3.et 14159..., ce sont des arguments séparés):

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

Vite

On printfpeut s’attendre à ce que la variante à utiliser soit très rapide: printfc’est un shell intégré aux shell communs comme bashet zsh, il ne crée aucun processus.
En outre, il ne touche à aucun type de code associé à une virgule flottante, mais uniquement à la manipulation de tableaux d'octets (explicitement, pas de caractères multi-octets). C'est généralement plus rapide, souvent beaucoup plus rapide que l'utilisation de la virgule flottante.

compatibilité printf

Il y a souvent des raisons de remplacer printfpar /usr/bin/printfpour garantir la cohérence ou la compatibilité. Dans ce cas, je pense que nous pouvons utiliser la fonction intégrée - ce qui est important, car l'utilisation /usr/bin/printfréduit l'avantage "rapide" en forçant un processus.
Un problème courant avec la printfcompatibilité est le format de sortie du nombre en fonction des paramètres régionaux. La séparation .des nombres peut être modifiée en ,fonction des paramètres régionaux. Mais nous n'utilisons pas de chiffres, mais simplement une constante de chaîne contenant un littéral .- non affecté par les paramètres régionaux.
Stéphane Chazelas a souligné queprintf %.5s fonctionne différemment danszsh, en comptant les caractères, pas les octets comme d’habitude. Heureusement, nos constantes utilisent uniquement des caractères de la plage ASCII inférieure, codés par un octet par caractère dans tout codage pertinent, tant que nous utilisons le UTF-8codage commun pour Unicode, et non un codage à largeur fixe.


Notez que printf %.5schar (non byte) est basé sur zsh (de manière raisonnable, mais contre POSIX). ksh93's %.5Lsest basé sur le graphem.
Stéphane Chazelas
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.