Wie drucke ich pi (3.14159)? [geschlossen]


35

Welcher Befehl könnte pi für mich drucken? Ich möchte angeben, wie viele Stellen gedruckt werden sollen. Ich konnte online nichts finden. Ich möchte nur Pi drucken können.



4
Beachten Sie, dass es mehr Spaß macht, wenn Sie mehr Ziffern als gegen 15 möchten.
Thorbjørn Ravn Andersen

2
@DisplayName: Dies bedeutet, dass Sie kein Programm mehr verwenden können, das PI mit Gleitkommawerten doppelter Genauigkeit intern speichert / berechnet (dies ist normalerweise der "eingebaute" FP-Datentyp mit der höchsten Genauigkeit, der in den meisten Sprachen verfügbar ist).
Matteo Italia

5
Meine Lösung vor Jahrzehnten, bevor dies allgemein von Sprachbibliotheken bereitgestellt wurde, bestand darin, es an mehr Stellen zu speichern, als ich jemals für Fließkommazahlen benötigt hätte: 3.1415926535897932384626 ist für praktische Zwecke in der Regel nah genug, und selbst für die unpraktischsten - alles Reale -world wird mehr Fehler haben als die anderen Zahlen, und theoretisch würde ich mich eher an den symbolischen als an den numerischen Wert halten.
Keshlam

3
@syntaxerror Interesse ist irrelevant. Wenn Sie eine Frage stellen und nach nackten Bildern von Prominenten fragen, erhalten Sie Tausende von Ansichten und möglicherweise positive Stimmen. Das macht es nicht zum Thema. Diese Frage ist ein klassisches Beispiel für zu breit. Schauen Sie sich einfach die Anzahl der Antworten an. Beachten Sie auch, dass im OP keine Einschränkungen festgelegt wurden, die die möglichen Antworten im Wesentlichen unbegrenzt machen. In jedem Fall wird das Schließen nicht gelöscht. Die Frage und alle 23 Antworten werden noch hier sein. Das Schließen bedeutet nur, dass keine weiteren Antworten akzeptiert werden. Brauchen wir wirklich noch mehr Möglichkeiten, um π zu drucken?
terdon

Antworten:


52

Sie können diesen Befehl verwenden:

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

Wobei scale die Anzahl der Nachkommastellen ist.

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


12
Kürzere Version in bashund andere Shells hier Strings unterstützt: bc -l <<< "scale=5; 4*a(1)".
Pabouk

2
Ich frage mich, wie viele Ziffern dies gehen kann?
DisplayName

4
@DisplayName ziemlich viele. scale=1000gibt ziemlich schnell 999 korrekte Ziffern aus (die letzte Ziffer ist um 1 versetzt, da wir pi / 4 berechnen und dann mit 4 multiplizieren). scale=4000gibt in wenigen Sekunden 4000 richtige Stellen. scale=10000dauert länger als ich habe geduldig, gibt aber wahrscheinlich 9999 oder 10000 richtige Ziffern.
Hobbs

4
Dies führt auf meinem Computer zu einem falschen Ergebnis, wenn Sie "echo" scale = 5; 4 * a (1) "| eingeben bc -l 'gibt 3.14156 zurück, wenn die letzte Ziffer um 9 sein sollte
Jordan Bentley

1
@JordanBentley, ich habe eine Antwort mit korrekter Rundung des Ergebnisses hinzugefügt .
Pabouk

61

Wenn Sie tex(1)installiert haben:

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

13
Dies ist fast eine Aufwertung wert, nur um klug zu sein. Die Ausgabe ändert sich jedoch, wenn Sie das Paket aktualisieren. Sollen wir das für ein Feature oder einen Bug halten?
ein Lebenslauf vom

8
@ MichaelKjörling Eigentlich ändert es sich zu einer genaueren Näherung von pi.
Abrixas2

@ Abrixas2 Ja, ich weiß. Mit der letzten Version von TeX als Version π.
ein Lebenslauf vom

30
@DavidRicherby Durch einen zusätzlichen Aufruf von können weniger Ziffern gedruckt werden cut. Sie können weitere Ziffern drucken, indem Sie lange warten und den Befehl erneut ausführen.
Steven D

1
@ Ruslan hängt von der Implementierung ab. Ich würde in diesem speziellen Fall erwarten, dass es "richtig" gemacht wird.
Thorbjørn Ravn Andersen

23

Zum Drucken mit beliebiger Genauigkeit können Sie bcund die Formel verwenden pi = 4*atan(1):

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

2
Es ist etwas komisch an der scaleOption, pi = 3.141592..aber mit echo "scale=5; 4*a(1)" | bc -l => 3.14156wem würde ich dann rechnen 3.14159?
Fduff

7
scaleGibt die Genauigkeit an, die für die Berechnung verwendet werden soll. Daher werden bei scale=5keiner Operation mehr als fünf Nachkommastellen für eine atomare Operation verwendet.
Abrixas2

@fduff, ich habe eine Antwort mit korrekter Rundung des Ergebnisses hinzugefügt .
Pabouk

20

Wenn Sie etwas wollen, das den Wert von π berechnen kann , gibt es mehrere Ansätze. Die vielleicht naheliegendste Lösung wäre die Verwendung eines vorgefertigten Pakets wie pi(Debian-Paket-Link) , das, wenn Debians Paketbeschreibung als vertrauenswürdig eingestuft wird, den Wert mit einer willkürlichen Genauigkeit berechnen kann, die nur durch den Speicher begrenzt ist.

piist eigentlich ein Beispiel, das in der CLN-Bibliothek (Class Library for Numbers) enthalten ist . Es enthält Beispielanwendungen, die Werkzeuge zum Erzeugen von Zahlen beliebiger Länge wie Pi, Fibonacci usw. bereitstellen. CLN-Pakete sind in Debian / Ubuntu vorab gepackt erhältlich (darauf weist der obige Debian-Link hin).

Beispiele
$ ./pi 10
3.141592653

$ ./pi 20
3.1415926535897932384

HINWEIS: Die Quelle dieser Beispiele befindet sich hier in der Quelle für die CLN-Codebasis .

Andere Distributionen

Fedora

Auf Fedora musste ich das Quell-Tarball herunterladen und es selbst erstellen, aber es funktioniert ohne großen Aufwand. Aus irgendeinem Grund enthält das Paket clnauf Fedora nur die Bibliothek, vernachlässigt jedoch die Beispiele, die in der Debian / Ubuntu-Version (oben) verfügbar sind.

Bogen

Arch bietet das gleiche Programm in dem clnPaket (dank Amphiteót ).


Ja, heh, ich meinte den Gesamtwert, den ich gerade eingetippt habe, was ich in meinem Kopf hatte.
DisplayName

2
Der "Gesamtwert" ?? Was soll das heißen ...?
Kyle Strand

2
@DisplayName liest den Rest der Antwort. Ein spezielles Programm piklingt genau so, wie Sie es suchen. Sie können pi 300beispielsweise die ersten 300 Stellen drucken.
terdon

3
@KyleStrand Ich habe eine wirklich wundervolle Antwort darauf gefunden, die dieser Kommentar nicht enthalten kann. Hey, es hat bei Fermat funktioniert !
Terdon

Ich würde gerne wissen, warum dies zwei Abwertungen erhalten hat. Haben die Abgestimmten die Antwort nicht gelesen, bevor sie entschieden haben, dass sie nicht nützlich ist?
ein Lebenslauf vom

17

Für bis zu eine Million Stellen können Sie Folgendes verwenden (hier für 3000 Stellen):

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

2
Dies hat den zusätzlichen Vorteil, dass es der Komplexität von O (1) einigermaßen nahe kommen sollte. Oder vielleicht ist das doch kein Vorteil ...
ein

7
Es ist auch schwierig zu sagen, dass jede Netzwerkinteraktion in einer praktischen Welt eine O (1) -Zeitkomplexität ist. : P
HalosGhost

2
@HalosGhost Für unsere Zwecke ( im Vergleich zu der Berechnung n Stellen von P jedes Mal), eine festgelegte Menge von Daten von einem bestimmten Server über ein Netzwerk herunterzuladen ist wahrscheinlich zu sein effektiven O (1), wobei die Berechnung n Stellen von P wahrscheinlich zu sein ist , Zumindest so etwas wie O (log n) und möglicherweise höher (ich kenne diese Algorithmen nicht). Das eigentliche Herunterladen der Daten nimmt wahrscheinlich erheblich mehr Zeit in Anspruch als der Aufwand zum Starten des Herunterladens, daher dominiert die Download-Zeit und Sie kommen bei einer angemessenen festen Datenübertragungsrate in die Nähe von O (1). Daher O (1).
ein Lebenslauf vom

4
@ MichaelKjörling Wenn du O (1) sagst, meinst du nicht tatsächlich O (n)? Die Download-Zeit ist linear in der Anzahl der Stellen, die Sie benötigen, daher O (n).
CodesInChaos

1
@CodesInChaos Nein, die Download-Zeit ist konstant (bei konstanter Übertragungsrate), da Sie eine konstante Anzahl von Ziffern herunterladen (hier eine Million). Es sei denn, (in diesem speziellen Fall) Curl ist intelligent genug, um während des Herunterladens zu drucken und den Download zu stoppen, sobald die Pipe bricht, weil sie beendet wird cut. Wenn das der Fall ist, stimme ich zu, wäre es O (n).
einen Lebenslauf vom

15

Einige der anderen Antworten zeigen falsche Ziffern an den letzten Stellen der Ausgabe. Nachfolgend finden Sie eine Variation der Antwort unter Verwendung von,bc jedoch mit einem korrekt gerundeten Ergebnis. Die Variable senthält die Anzahl der signifikanten Stellen (einschließlich 3vor dem Dezimalpunkt).

Runden Sie die Hälfte auf

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

Abrunden (abschneiden)

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

Erläuterung der Rundung

Die Rundung erfolgt direkt in bc. Dies hat nicht die Begrenzung des Befehls printf, der die C - Sprache verwendet doubleTyp Darstellung für die Zahlen , die eine Genauigkeit von etwa 17 signifikanten Ziffern hat. Siehe die Antwort mit printfRundung .

scale=s-1Legt die Anzahl der Stellen fest, auf die gekürzt werden soll. pi/1dividiert das Ergebnis durch 1, um die Kürzung anzuwenden. Simple pischneidet die Zahl nicht ab.

Beim Aufrunden der Hälfte muss 5 zur ersten Stelle addiert werden, die abgeschnitten wird (5 × 10 -s ), damit bei höheren Stellen als 5 die letzte verbleibende Stelle inkrementiert wird.

Aus den Tests von Hobbs geht hervor, dass drei zusätzliche Stellen, die gerundet / abgeschnitten werden ( scale=s+2), auch für sehr lange Zahlen ausreichen.

Hier Streicher

In den obigen Beispielen werden hier Zeichenfolgen verwendet, die beispielsweise in unterstützt werdenbash , kshund zsh. Wenn Ihre Shell dies nicht unterstützt, verwenden Sie echostattdessen string use und pipe:

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

2
Wie Sie in einem Kommentar behaupten, ist die Berechnung von drei zusätzlichen Stellen zum Zwecke der Rundung keine „richtige Rundung“. Erstens sind Sie nicht an den Fehler der Berechnung gebunden. Wenn es um 3 Einheiten an letzter Stelle falsch sein kann, wie von fduff behauptet, warum würde es dann nicht um 1000 Einheiten an letzter Stelle falsch sein? Zweitens, siehe "das Dilemma des Tischmachers".
Kompliziert siehe Bio

12

Perl eine Zeile (mit Bignum ):

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

z.B

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

Für 10.000 Stellen: Fast 8 Minuten in Perl, weniger als 4 in bc. Nicht der schnellste.
Isaac

9

Mit python2:

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

4
Der Vollständigkeit halber ist diese Lösung python2-spezifisch.
HalosGhost

Nach dem Editieren (..)funktioniert das mit Python 2 und 3. Scheint nur 12 Stellen zu haben.
Anthon

$ Python -c "import math; print (Format (math.pi, '.400f'))" 3,1415926535897931159979634685441851615905761718750000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Artem Shitov

1
@ArtemShitov - mein schlecht, versuchen , den Import gmpy2 (wenn Sie es installiert haben): python -c "import gmpy2; print(str(gmpy2.const_pi(8192))[:400])". python -c "import gmpy2; print(str(gmpy2.const_pi(16384))[:4400])"
Erhöhen Sie die

1
Die schnellste, die ich finden konnte, war from mpmath import mp; mp.dps = 1000000 ; print(mp.pi)nur ein paar Sekunden für eine Million Stellen. Gar nicht so schlecht !!!.
Isaac

7

Ruby benutzen:

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

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

3.141592654

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

4

In der Bash:

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

@ Amphiteóth afmtoditmuss groffinstalliert sein. Hier auf Ubuntu (& Flavours) ist es nicht Standard. JFYI.
Syntaxfehler

@syntaxerror Danke, guter Punkt! Ich habe mein Beispiel entfernt. Mein Punkt war nur, als diese KI gelesen wurde und grepauf meinem System nach der Konstante suchte und sie an mehreren Stellen fand. Deshalb war das +1 für mich!


3

Wie habe ich diese Frage verpasst ...

Hier ist ein kleines Python-Pi-Programm von mir, das ich vor ein paar Wochen auf Stack Overflow gepostet habe. Es ist nicht besonders schnell, aber es kann viel bewirken Ziffern machen. :) Wie ich jedoch in diesem Thread erwähnt habe, verwende ich im Allgemeinen das mpmath-Modul von Python für Arithmetik mit willkürlicher Genauigkeit, und mpmath hat einen ziemlich schnellen pi-Maker.

Z.B,

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

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

500000 Dezimalstellen Pi in weniger als 5 Sekunden sind meiner Meinung nach nicht allzu schäbig, wenn man bedenkt, dass sie auf einer Maschine mit einem Single-Core-2-GHz-Prozessor, 2 Gigabyte RAM und einem älteren IDE-Laufwerk ausgeführt werden.


Versuchen Sie es from mpmath import mp; mp.dps = 1000000 ; print(mp.pi)(nach einer Pip3-Installation von mpmath) unter zwei Sekunden für eine Million Stellen. Gar nicht so schlecht !!!.
Isaac

2

Wenn Sie node.jsinstalliert haben, wird dies sein Bestes tun, um pi für Sie zu finden, obwohl das Beste nicht sehr gut ist:

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

Beispielausgaben:

3.14157749
3.1416426
3.14159055
3.14171554
3.14176165
3.14157587
3.14161137
3.14167685
3.14172371

4
Je kürzer, node -e 'console.log(Math.PI)'desto besser.
Chbrown

1
@chbrown Das erfüllt die OPs nicht "nicht ernst" Anforderung.
Paul

1
Welche "nicht ernst" Anforderung? Das OP erklärte nur, dass sie um Spaß bitten, nicht, dass sie Antworten wollen, die irgendwie "nicht ernst" sind. Was heißt das überhaupt? So etwas wie echo pie?
Terdon

Ich habe das getippt, weil wenn man Fragen stellt, manchmal Leute sagen, dass "dies keine Skript-Schreibfabrik ist", also habe ich gesagt, weil es keinen wirklichen Grund dafür gibt, möchte ich nur wissen, wie man Pi druckt.
DisplayName

@ Amphiteóth Es dauert ungefähr 20 Sekunden, um auf meinem Computer zu laufen. Möglicherweise müssen Sie ihm nur etwas Zeit geben.
Paul

2

Monte-Carlo-Methode

In diesem Beispiel finden Sie eine Erläuterung dieser Methode.

Vorbehalte

  • Nicht willkürlich genau
  • Die Konvergenz zu etwas Nützlichem dauert lange

Vorteile

Spaß :-)

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

Hinweis: Ich habe es zuerst ohne ausprobiert, srandaber es blieb hängen, 3.14und die Ziffern danach schwangen weiter, konvergierten nie. Dies liegt wahrscheinlich daran, dass sich das PRNG nach einer Weile wiederholt. Die Verwendung von srandwird diese vermeiden oder zumindest die Periode der Pseudozufallssequenz verlängern. Das ist alles eine Vermutung, also zögern Sie nicht, mich zu korrigieren, wenn ich falsch liege.


@ Amphiteót Bin mir nicht ganz sicher, was da los ist. Wenn es hilft, ist mein Perl v5.14.2. Ich bin mit bignumPerl-Operationen nicht wirklich vertraut , ich fürchte, und ich kenne keine bestimmten Teile des obigen Programms, die ein neueres Perl erfordern. Das Interessante daran ist der Algorithmus. Versuchen Sie es in der Sprache Ihrer Wahl zu implementieren, wenn dieses Perl nicht für Sie funktioniert.
Joseph R.

1
@ Amphiteót Ich verstehe. Löst die Bearbeitung Ihr Problem?
Joseph R.

@ Amphiteót Sie können versuchen, ($x,$y,$circle,$not_circle)=(0,0,0);vor der Schleife einzufügen , um sicherzustellen, dass alle Variablen definiert sind, bevor Sie sie verwenden.
Joseph R.

@ Amphiteót Mein Fehler. Die oben genannten Eltern sollten gewesen sein (0,0,0,0).
Joseph R.

Re diese /5.20.1: Das macht Sinn , aber habe es nicht gesehen ! In der Tat ($x,$y,$circle,$not_circle)=(0,0,0,0). Nach ein oder zwei Minuten hing es um den gewünschten Wert, dann näherte es sich 3.1409, bevor ich aufhörte. Interessant und lustig! Vielen Dank!

2

Sie können einen Zapfenalgorithmus für pi verwenden. Das folgende C-Programm von Dik Winter und Achim Flammenkamp wird die ersten 15.000 Stellen von pi nacheinander produzieren.

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

Kontext: Wiki , hier und hier .

1
Ich mag den Spigot-Algorithmus für logarithmische Konstanten von Borwein, Bailey und Plouffe. Dies ist jedoch kein Code-Golf. Darf ich die Lesbarkeit Ihres Codes verbessern, indem ich ihn neu formatiere? Beachten Sie auch, dass BPP-Algorithmen nur Ziffern für pi in Basen mit Zweierpotenzen ausgeben können, zumindest ohne zusätzlichen Speicher.
Franki

@Franki Ändert die Formatierung des Codes die Bedeutung oder Absicht des Posts? Wenn nicht, sollte es in Ordnung sein (und die Bearbeitung kann immer zurückgesetzt werden). Ich verstehe nicht, wie die Deobuscation eines Codes etwas anderes als eine Klärung bewirken könnte.
11684

1
@syntaxerror Vor dem Anhalten müssen genau 15.000 Stellen erzeugt werden. Die Ausgabe in der zweiten for-Schleife erzeugt 4 Stellen von pi und dekrementiert die Geheimzahl von 52514 um 14. Die Gleichung wäre dann 4 * (52514/14), was 15004 entspricht. Die letzten 14 Werte im Array werden ignoriert Vorteil von weniger Token, um unseren genauen Wert von 15000 zu erhalten.
Daniel Henneberger

1
@ 11684 Nein, das würde die Bedeutung oder Absicht des Codes wirklich nicht ändern. Allerdings wurde mir klar, dass dies kein BBP-artiger Spigot-
Franki

2

PHP

Einige Beispiele:

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

Wenn Sie die Genauigkeit ändern möchten, versuchen Sie Folgendes:

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

Die Größe eines Floats ist plattformabhängig, obwohl ein Maximum von ~ 1.8e308 mit einer Genauigkeit von ungefähr 14 Dezimalstellen ein üblicher Wert ist (das 64-Bit-IEEE-Format). [Weiterlesen]


Wenn Sie auf der Suche nach noch genauerer Präzision sind, finden Sie in Rosetta Code oder Code Golf SE einige Programmierlösungen.

Verwandte: Software, die PI auf mindestens tausend Stellen bei SR.SE berechnen kann


1

Hier ist ein Skript, das pi mit der vom Benutzer angegebenen Anzahl von Ziffern (einschließlich '.') Ausgibt.

pi.sh

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

Ausgabe

$ ./pi.sh 10
3.14159265

und mit Standardwert:

$ ./pi.sh
3.14159

Ich habe Leute gesehen, die scaleals bcOption verwendet haben, aber in meinem Fall ( bc 1.06.95) gibt dies nicht den richtigen Wert aus:

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

Beachten Sie die letzte Ziffer.


4
Die Frage lautet: "Ich möchte angeben, wie viele Stellen gedruckt werden", was streng genommen mehrdeutig ist - aber ich denke, Ihre Antwort schlägt (aus technischen Gründen) bei jeder vernünftigen Interpretation fehl. Ihre ./pi.sh 10Ausdrucke bestehen aus neun Ziffern, wobei die Initiale gezählt wird 3. Außerdem zeigst du den Finger von Rundungsfehlern, aber deinen ./pi.sh 6Ausgaben 3.1415, die möglicherweise nicht optimal sind.
G-Man sagt, dass Monica

Aus dem Speicher wird mit der scale=XOption bcNICHT die Zahl gerundet, sondern die Zahl einfach an der X-ten Dezimalstelle abgeschnitten.
Syntaxfehler

1

Ich mochte Abeys Antwort, aber es gefiel mir nicht, wie bc die letzte Ziffer änderte.

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

Also habe ich scale used printf entfernt, um die Anzahl der Stellen einzustellen.

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

Haben Sie bemerkt, dass nach einer Skala von 62 Stellen alle 0 sind, während dies beim ursprünglichen Befehl nicht der Fall ist?

2
@ Amphiteót, Das liegt daran, dass printfdie Gleitkommazahlen im Vergleich zu einer strengen Einschränkung unterliegen bc. Sie werden durch den C- doubleSprachtyp mit einer Genauigkeit von ungefähr 17 Stellen dargestellt, so dass selbst die von Null verschiedenen Stellen nach ungefähr der 17. falsch sind! ------ Ich habe eine Antwort mit korrekter Rundung des Ergebnissesprintf hinzugefügt, die nicht durch beschränkt ist . ------ Auch um sicherzustellen, dass dieser Befehl mit verschiedenen Gebietsschemas funktioniert, müssen Sie LC_ALL=C printf
Folgendes

1

Was ist, wenn Sie sich nicht an dieses arctanDing erinnern können ? Oder nehmen Sie an, Sie wissen nicht einmal, dass diese Funktion in existiert bc, und versuchen Sie, diese einfache Unterteilung auswendig zu lernen:

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

Funktioniert nur für 6 Stellen, aber für nicht-wissenschaftliche Berechnungen ist dies in Ordnung.

Wenn Sie glauben, dass Sie sich auch an diese beiden Zahlen nicht erinnern können, schreiben Sie zuerst den Nenner und dann den Zähler:

113 355

Oder warum nicht?

11 33 55

"double 1, double 3, double 5". Alle Zahlen sind ungerade. Teilen Sie zur Berechnung die 6-stellige Zahl erneut in zwei Hälften und tauschen Sie Nenner und Zähler, bevor Sie sie teilen. Das ist alles.


Was mich betrifft, fällt es mir 4 * arctan(1)viel leichter, mich an diese zwei dreistelligen Zahlen zu erinnern ... Ich würde leicht 335 anstelle von 355 oder 133 anstelle von 113 verwenden.
John WH Smith

Nun, ich denke, es ist eine Frage persönlicher Vorlieben. :) Leute (wie ich), die sich leicht Telefonnummern (aus dem Festnetz!) Merken können, können sich zwei Nummern einfach als eine einzige Telefonnummer merken. Es wird auch den Leuten helfen, die in der Schule das Gefühl hatten, dass die Trigonometrie von bösen Mächten gemacht worden sein muss.
Syntaxfehler

1

Es kann angenommen werden, dass das OP an einem kurzen, leicht zu merkenden Shell-Befehl zum Drucken von π interessiert ist - aber die Frage sagt das nicht wirklich aus. Diese Antwort ignoriert diese Annahme und beantwortet die Frage streng wie geschrieben.

Trivial?

Obwohl es bereits 18 Antworten gibt, fehlt ein Ansatz - und bei so vielen Antworten könnte man meinen, dass er nicht der einzige ist, der fehlt:
Der triviale: Wie drucke ich π? Einfach π ausdrucken!

Dieser Ansatz scheint zu nutzlos zu sein, um überhaupt darüber nachzudenken, aber ich werde zeigen, dass er seine Fehler hat:

Optimiert

Wir würden normalerweise den Wert von π berechnen. Ich verstehe nicht, was uns davon abhält, die Lösung durch Vorausberechnung des Werts zu optimieren - es ist eine Konstante, die jeder Compiler tun würde.

Wir wollen eine Anzahl von Stellen von π, bis zu einer maximalen Genauigkeit. Wir können also einfach das Präfix der Konstanten als Text verwenden:

echo 3.1415926535897932384626433832795 | cut -b -7
3.14159

Eine Variante mit einem expliziten Argument für die Genauigkeit, z. für die Präzision 5:

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

Vorteile

Die maximale Genauigkeit kann durch Verwendung einer geeigneten Konstante, die unter Verwendung einer der anderen Antworten berechnet wird, willkürlich gewählt werden. Es ist nur durch die maximale Länge einer Befehlszeile begrenzt.
Es hat eine konstante zeitliche Komplexität, um den Wert zu finden.
Aufgrund der geringen Komplexität der Implementierung werden alle Grenzen und Einschränkungen offensichtlich.
Er handhabt eine Genauigkeit, die größer als das Maximum ist, indem er die Konstante mit der vollen verfügbaren Genauigkeit (ohne Nachlauf 0) zurückgibt .
Diese Lösung ist zwar trivial, hat jedoch Vorteile. Es kann nützlich sein, wenn es beispielsweise in einer Shell-Funktion verwendet wird.

Minimal

Die Funktionalität der obigen Lösung kann auch implementiert werden, ohne einen Prozess für cut(vorausgesetzt, es echohandelt sich um eine eingebaute Shell) zu erstellen. Der Befehl printf(normalerweise ein eingebauter Befehl) wird auf etwas unklare Weise verwendet:
Die Konstante wird vollständig als Zeichenfolge behandelt (das verwendete Format %s), es ist keine Gleitkomma-Arithmetik beteiligt, daher gelten die Grenzen von floatoder doublehier nicht.
Der Genauigkeitswert des %sEscape-Zeichens ( 5im folgenden Beispiel) gibt die Länge des zu druckenden Zeichenfolgepräfixes an. Hierbei handelt es sich um die Genauigkeit. Dies 3.ist Teil des printfFormats, um es aus der Präzisionsberechnung herauszuhalten.

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

Alternative mit Genauigkeit als separates Argument:

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

Oder etwas besser lesbar (Beachten Sie das Leerzeichen zwischen 3.und 14159..., es handelt sich um separate Argumente):

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

Schnell

Es printfist zu erwarten, dass die Verwendung der Variante sehr schnell ist: Da printfes sich um eine Shell handelt, die in gängigen Shells wie bashund eingebaut ist zsh, werden keine Prozesse erstellt.
Es berührt auch keinen Gleitkomma-Code, sondern nur die Manipulation von Byte-Arrays (explizit keine Multibyte-Zeichen). Dies ist normalerweise schneller, oft viel schneller als die Verwendung von Gleitkommazahlen.

PrintF-Kompatibilität

Häufig gibt es Gründe für die Ersetzung printfdurch /usr/bin/printf, um die Konsistenz oder Kompatibilität zu gewährleisten. In diesem Fall, denke ich, können wir das eingebaute verwenden - was wichtig ist, da die Verwendung /usr/bin/printfden "schnellen" Vorteil verringert, indem ein Prozess gegabelt wird.
Ein häufiges printfKompatibilitätsproblem ist das Ausgabeformat für Zahlen, das vom Gebietsschema abhängt. Die Trennung .für Zahlen kann je nach ,Gebietsschema geändert werden . Wir verwenden jedoch keine Zahlen, sondern nur eine Zeichenfolgenkonstante, die ein Literal enthält .- unabhängig vom Gebietsschema.
StéphaneChazelas wies darauf hin, dass dies printf %.5sanders funktioniertzshdurch Zählen von Zeichen, nicht wie üblich von Bytes. Glücklicherweise verwenden unsere Konstanten nur Zeichen im unteren ASCII-Bereich, die in jeder relevanten Codierung mit einem Byte pro Zeichen codiert sind, sofern wir die gemeinsame UTF-8Codierung für Unicode verwenden und keine Codierung mit fester Breite.


Beachten Sie, dass printf %.5schar (nicht byte) auf zsh basiert (sinnvoll, aber gegen POSIX). ksh93‚s %.5Lsist graphem basiert.
Stéphane Chazelas
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.