Jakie polecenie może dla mnie wypisać pi? Chcę określić, ile cyfr ma drukować, nie mogłem znaleźć niczego online. Chcę tylko móc wydrukować pi.
Jakie polecenie może dla mnie wypisać pi? Chcę określić, ile cyfr ma drukować, nie mogłem znaleźć niczego online. Chcę tylko móc wydrukować pi.
Odpowiedzi:
Możesz użyć tego polecenia:
echo "scale=5; 4*a(1)" | bc -l
3.14159
Gdzie skala to liczba cyfr po przecinku.
Odniesienie: http://www.tux-planet.fr/calculer-le-chiffre-pi-en-ligne-de-commande-sous-linux/
bash
i inne pociski wspierające tutaj ciągi: bc -l <<< "scale=5; 4*a(1)"
.
scale=1000
daje 999 poprawnych cyfr raczej szybko (ostatnia cyfra jest wyłączona o 1, rozsądne, ponieważ obliczamy pi / 4, a następnie mnożymy przez 4). scale=4000
daje 4000 poprawnych cyfr w kilka sekund. scale=10000
trwa dłużej niż mam cierpliwość, ale prawdopodobnie daje 9999 lub 10000 poprawnych cyfr.
Jeśli tex(1)
zainstalowałeś:
tex --version | head -1 | cut -f2 -d' '
cut
. Więcej cyfr można wydrukować, czekając długo i ponownie uruchamiając polecenie.
Do drukowania z dowolną precyzją można użyć bc
formuły pi = 4*atan(1)
:
# bc -l
scale=<your precision>
4*a(1)
scale
opcji, pi = 3.141592..
ale z echo "scale=5; 4*a(1)" | bc -l => 3.14156
tym spodziewałbym się zobaczyć 3.14159
?
scale
określa precyzję używaną do obliczeń, więc przy scale=5
żadnej operacji żadna operacja atomowa nie użyje więcej niż pięciu cyfr ułamkowych.
Jeśli chcesz czegoś, co może obliczyć wartość π, istnieje kilka podejść. Być może najbardziej oczywistym rozwiązaniem byłoby użycie gotowego pakietu, takiego jak pi
(link do pakietu Debiana) , który jeśli można zaufać opisowi pakietu Debian, może obliczyć wartość z dowolną dokładnością, ograniczoną tylko pamięcią.
pi
jest właściwie przykładem zawartym w bibliotece CLN (Class Library for Numbers) . Zawiera przykładowe aplikacje, które zapewniają narzędzia do generowania dowolnych długości liczb, takich jak Pi, Fibonacci itp. Pakiety CLN są dostępne w paczkach w Debianie / Ubuntu (na to wskazuje powyższy link Debiana).
$ ./pi 10
3.141592653
$ ./pi 20
3.1415926535897932384
UWAGA: Źródło tych przykładów znajduje się tutaj w źródle podstawy kodu CLN .
Na Fedorze musiałem pobrać źródłowy plik archiwum i sam go zbudować, ale kompiluje się bez większego zamieszania. Z jakiegokolwiek powodu pakiet cln
na Fedorze zawiera tylko bibliotekę, ale pomija przykłady dostępne w wersji Debian / Ubuntu (powyżej).
Arch zapewnia ten sam program w tym cln
opakowaniu (dzięki Amphiteót ).
pi
brzmi dokładnie tak, jak szukasz. Możesz na przykład pi 300
wydrukować pierwsze 300 cyfr.
Dla maksymalnie miliona cyfr możesz użyć następujących (tutaj dla 3000 cyfr):
curl --silent http://www.angio.net/pi/digits/pi1000000.txt | cut -c1-3000
cut
kończy się? Jeśli tak jest, zgadzam się, że byłoby O (n).
Niektóre inne odpowiedzi pokazują niepoprawne cyfry w ostatnich miejscach wyjścia. Poniżej znajduje się odmiana odpowiedzi przy użyciu,bc
ale z poprawnie zaokrąglonym wynikiem. Zmienna s
zawiera liczbę cyfr znaczących (w tym 3
przed kropką dziesiętną).
$ bc -l <<< "s=5; scale=s+2; pi=4*a(1)+5*10^(-s); scale=s-1; pi/1"
3.1416
$ bc -l <<< "s=5; scale=s+2; pi=4*a(1); scale=s-1; pi/1"
3.1415
Zaokrąglanie odbywa się bezpośrednio w bc
. Nie ma to ograniczenia polecenia, printf
które używa reprezentacji double
typu języka C dla liczb, które mają dokładność około 17 cyfr znaczących. Zobacz odpowiedź printf
zaokrąglając .
scale=s-1
ustawia liczbę cyfr, które mają zostać obcięte. pi/1
dzieli wynik przez 1, aby zastosować obcinanie. Prosty pi
nie obcina liczby.
Zaokrąglanie w górę pół wymaga, aby dodać 5 do pierwszej cyfry, które zostaną odcięte (5 x 10 -s ), tak, że w przypadku wyższych cyfr równej 5 ostatnia cyfra, która pozostanie zostanie zwiększony.
Z testów przeprowadzonych przez hobbs wydaje się, że trzy dodatkowe cyfry, które zostaną zaokrąglone / odcięte ( scale=s+2
), wystarczą nawet dla bardzo długich liczb.
Powyższe przykłady zastosowania tutaj ciągi , które są obsługiwane na przykład bash
, ksh
i zsh
. Jeśli twoja powłoka nie obsługuje tutaj ciągów znaków echo
i potoku zamiast tego:
$ echo "s=5; scale=s+2; pi=4*a(1); scale=s-1; pi/1" | bc -l
3.1415
Z python2:
$ python -c "import math; print(str(math.pi)[:7])"
3.14159
(..)
działa to w Pythonie 2 i 3. Wydaje się, że ma tylko 12 cyfr.
python -c "import gmpy2; print(str(gmpy2.const_pi(8192))[:400])"
. Zwiększ precyzję, aby uzyskać więcej cyfr ... np.python -c "import gmpy2; print(str(gmpy2.const_pi(16384))[:4400])"
from mpmath import mp; mp.dps = 1000000 ; print(mp.pi)
zaledwie kilka sekund na milion cyfr. Tak ogólnie to nieźle !!!.
W bash:
$ read -a a <<< $(grep M_PIl /usr/include/math.h) ; echo ${a[3]} | tr -d L
3.141592653589793238462643383279502884
afmtodit
wymaga groff
instalacji. Tutaj na Ubuntu (i smakach), to nie norma. JFYI.
Bardzo prosty w PHP przy użyciu wbudowanej funkcji pi ():
<?php
echo round(pi(), 2);
?>
Jak przegapiłem to pytanie ...
Oto mój mały program Python pi, który zamieściłem kilka tygodni temu na Stack Overflow. Nie jest to szczególnie szybkie, ale potrafi zrobić wiele cyfr. :) Jednak, jak wspomniałem w tym wątku, zwykle używam modułu mpmath Pythona do arytmetyki o dowolnej precyzji, a mpmath ma dość szybki program do tworzenia pi.
Na przykład,
time python -c "from mpmath import mp;mp.dps=500000;print mp.pi" >bigpi
real 0m4.709s
user 0m4.556s
sys 0m0.084s
500 000 miejsc po przecinku w mniej niż 5 sekund nie jest zbyt odrapane, IMHO, biorąc pod uwagę, że działa na maszynie z pojedynczym rdzeniem 2GHz, 2 gig RAM i zapisuje na starszym dysku IDE.
from mpmath import mp; mp.dps = 1000000 ; print(mp.pi)
(po instalacji mpmath pip3) w ciągu dwóch sekund na milion cyfr. Tak ogólnie to nieźle !!!.
Jeśli node.js
zainstalowałeś, zrobi to najlepiej, aby znaleźć pi dla ciebie, chociaż jego najlepsze nie jest zbyt dobre:
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)'
Przykładowe wyniki:
3.14157749
3.1416426
3.14159055
3.14171554
3.14176165
3.14157587
3.14161137
3.14167685
3.14172371
node -e 'console.log(Math.PI)'
jest trochę lepszy niż najlepszy.
echo pie
?
Metoda Monte Carlo
Patrz, na przykład ten o wyjaśnienie tej metody.
Ostrzeżenia
Zalety
Zabawa :-)
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
}'
Uwaga: najpierw spróbowałem bez, srand
ale utknął, 3.14
a cyfry dalej oscylowały, nigdy się nie zbiegając. Jest tak prawdopodobnie dlatego, że po chwili PRNG zaczyna się powtarzać. Zastosowanie srand
spowoduje uniknięcie tego lub przynajmniej wydłuży okres pseudolosowej sekwencji. To wszystko przypuszczenie, więc nie wahaj się mnie poprawić, jeśli się mylę.
bignum
operacjach w Perlu i nie znam żadnych konkretnych części powyższego programu, które wymagałyby nowszego Perla. W każdym razie interesujący jest sam algorytm. Spróbuj wdrożyć go w wybranym języku, jeśli ten Perl nie działa dla Ciebie.
($x,$y,$circle,$not_circle)=(0,0,0);
przed pętlą, aby upewnić się, że wszystkie zmienne są zdefiniowane przed użyciem.
(0,0,0,0)
.
($x,$y,$circle,$not_circle)=(0,0,0,0)
. Po minucie lub dwóch krążyło wokół pożądanej wartości, a potem zatrzymałem się znacznie bliżej 3,1409. Ciekawe i zabawne! Dziękuję Ci!
Możesz użyć algorytmu czopka dla pi. Poniższy program C autorstwa Dika Wintera i Achima Flammenkampa da pierwsze 15 000 cyfr liczby pi, po jednej cyfrze na raz.
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;}
PHP
Kilka przykładów:
php -r "print pi();"
php -r 'echo M_PI;'
echo "<?=pi();" | php
Jeśli chcesz zmienić precyzję, spróbuj:
php -d precision=100 -r 'echo pi();'
Rozmiar liczby zmiennoprzecinkowej jest zależny od platformy, chociaż wspólna wartość to maksymalnie ~ 1,8e308 z dokładnością około 14 cyfr dziesiętnych (64-bitowy format IEEE). [Czytaj więcej]
Jeśli szukasz jeszcze dokładniejszej precyzji, sprawdź Rosetta Code lub Code Golf SE, aby znaleźć rozwiązania programistyczne.
Powiązane: Oprogramowanie, które może obliczyć PI do co najmniej tysiąca cyfr w SR.SE
Oto skrypt, który wypisuje pi z liczbą cyfr określoną (łącznie z „.”) Przez użytkownika.
pi.sh
#!/bin/bash
len=${1:-7}
echo "4*a(1)" | bc -l | cut -c 1-"$len"
wydajność
$ ./pi.sh 10
3.14159265
i z wartością domyślną:
$ ./pi.sh
3.14159
Widziałem ludzi korzystających scale
z bc
opcji, ale w moim przypadku ( bc 1.06.95
) nie wyświetla to poprawnej wartości:
$ echo "scale=5;4*a(1)" | bc -l
3.14156
Zwróć uwagę na ostatnią cyfrę.
./pi.sh 10
odciski dziewięciu cyfr, liczenie początkowe 3
. Wskazujesz również błąd zaokrąglania, ale ./pi.sh 6
wyniki 3.1415
, które mogą nie być optymalne.
scale=X
opcja bc
NIE zaokrągli liczby, ale po prostu odetnie liczbę przy X-tej cyfrze dziesiętnej.
Podoba mi się odpowiedź Abeya, ale nie podobało mi się, jak bc zmieniał ostatnią cyfrę.
echo "scale=5; 4*a(1)" | bc -l
3.14156
Więc usunąłem skalę używaną printf, aby ustawić liczbę cyfr.
printf "%0.5f\n" $(echo "4*a(1)" | bc -l)
3.14159
printf
ma poważne ograniczenie liczb zmiennoprzecinkowych w porównaniu do bc
. Są one reprezentowane przez double
typ języka C z dokładnością około 17 cyfr, więc nawet niezerowe cyfry po około 17 cyfrach są fałszywe! ------ Dodałem odpowiedź z poprawnym zaokrągleniem wyniku nieograniczonego przezprintf
. ------ Również, aby upewnić się, że to polecenie działa z różnymi ustawieniami narodowymi, musisz zrobić coś takiego: LC_ALL=C printf
...
Co jeśli nie możesz sobie przypomnieć tego życia arctan
? Załóżmy, że nawet nie wiesz, że ta funkcja istnieje bc
, a następnie spróbuj zapamiętać ten prosty podział:
echo "scale=6; 355 / 113" | bc
3.141592
Będzie działać tylko dla 6 cyfr, ale w przypadku obliczeń nienaukowych będzie to dobrze.
Jeśli uważasz, że nie pamiętasz tych dwóch liczb, najpierw napisz mianownik, a następnie licznik:
113 355
A dlaczego nie
11 33 55
„podwójne 1, podwójne 3, podwójne 5”. Wszystkie liczby są nieparzyste. Aby obliczyć, ponownie podziel 6-cyfrową liczbę na pół i zamień mianownik i licznik przed ich podzieleniem. O to chodzi.
4 * arctan(1)
o wiele łatwiej mi zapamiętać, że 2 trzycyfrowe liczby ... Z łatwością użyłbym 335 zamiast 355 lub 133 zamiast 113.
Można założyć, że OP jest zainteresowany krótkim, łatwym do zapamiętania poleceniem powłoki, aby wydrukować π - ale pytanie tak naprawdę nie mówi. Ta odpowiedź ignoruje to założenie i odpowiada na pytanie dokładnie tak, jak napisano;
Chociaż jest już 18 odpowiedzi, wciąż brakuje jednego podejścia - a przy tak wielu odpowiedziach można by pomyśleć, że nie brakuje tylko jednego:
Trywialne: Jak wydrukować π? Po prostu wydrukuj π!
Takie podejście wydaje się zbyt bezużyteczne, aby nawet o tym myśleć, ale pokażę, że ma swoje wady:
Zwykle obliczamy wartość π. Nie widzę, co powstrzymuje nas przed optymalizacją rozwiązania, przez wstępne obliczenie wartości - jest to stała, zrobiłby to każdy kompilator.
Chcemy pewnej liczby cyfr π, z maksymalną precyzją. Możemy więc wziąć prefiks stałej jako tekst:
echo 3.1415926535897932384626433832795 | cut -b -7
3.14159
Wariant z wyraźnym argumentem za precyzją, np. dla precyzji 5
:
echo 3.1415926535897932384626433832795 | cut -b -$((2+5))
3.14159
Maksymalną precyzję można wybrać dowolnie, stosując odpowiednią stałą obliczoną przy użyciu jednej z pozostałych odpowiedzi. Jest ograniczony tylko maksymalną długością wiersza poleceń.
Ma stałą złożoność czasową w celu znalezienia wartości.
Sprawia, że wszystkie ograniczenia i ograniczenia są oczywiste, w oparciu o małą złożoność implementacji.
Z wdziękiem obsługuje precyzję większą niż maksimum, zwracając stałą z pełną dostępną precyzją (bez trailing 0
).
To trywialne rozwiązanie ma jednak zalety. Może być przydatny, na przykład, gdy jest używany w funkcji powłoki.
Funkcjonalność powyższego rozwiązania można również uzupełnić bez tworzenia procesu cut
(zakładając, że echo
jest to wbudowana powłoka). Używa polecenia printf
(zwykle wbudowanego) w nieco niejasny sposób:
stała jest całkowicie sprzedawana jako ciąg (używa formatu %s
), nie ma tu zastosowania arytmetyki zmiennoprzecinkowej, więc ograniczenia float
lub double
nie mają tutaj zastosowania.
Wartość precyzji zmiany znaczenia %s
( 5
w poniższym przykładzie) określa długość przedrostka łańcucha do wydrukowania - która jest dokładnością. Jest 3.
to część printf
formatu, która chroni go przed obliczeniami dokładności.
$ printf "3.%.5s\n" 1415926535897932384626433832795
3.14159
Alternatywa z precyzją jako oddzielny argument:
$ printf "3.%.*s\n" 5 1415926535897932384626433832795
3.14159
Lub nieco bardziej czytelny (zwróć uwagę na spację między 3.
i 14159...
, to osobne argumenty):
$ printf "%s%.5s\n" 3. 1415926535897932384626433832795
3.14159
printf
Można się spodziewać, że ten wariant będzie bardzo szybki: ponieważ printf
jest powłoką wbudowaną we wspólne powłoki, takie jak bash
i zsh
, nie tworzy żadnych procesów.
Ponadto nie dotyka żadnego rodzaju kodu zmiennoprzecinkowego, a jedynie manipulację tablicami bajtów (wyraźnie nie znakami wielobajtowymi). Jest to zwykle szybsze, często znacznie szybsze niż użycie zmiennoprzecinkowe.
Często istnieją powody do zastąpienia printf
, /usr/bin/printf
aby zagwarantować spójność lub zgodność. W tym przypadku myślę, że możemy użyć wbudowanego - co jest ważne, ponieważ użycie /usr/bin/printf
zmniejsza „szybką” przewagę poprzez rozwiązywanie procesu.
Częstym problemem związanym ze printf
zgodnością jest format wyjściowy liczb w zależności od ustawień regionalnych. Oddzielanie .
liczb można zmienić na ,
zależne od ustawień regionalnych; Ale nie używamy liczb, a jedynie ciąg znaków zawierający literał .
- na który nie ma wpływu lokalizacja.
StéphaneChazelas zwrócił na to uwagęprintf %.5s
działa inaczejzsh
, licząc znaki, a nie bajty jak zwykle. Na szczęście nasze stałe używają tylko znaków z dolnego zakresu ASCII, który jest kodowany przez jeden bajt na znak w dowolnym odpowiednim kodowaniu, o ile używamy wspólnego UTF-8
kodowania dla Unicode, a nie kodowania o stałej szerokości.
printf %.5s
jest oparty na char (nie bajt) w zsh (rozsądnie, ale przeciw POSIX). ksh93
„s %.5Ls
opiera graphem.