Perintah apa yang bisa mencetak pi untuk saya? Saya ingin menentukan jumlah digit yang dicetak, saya tidak dapat menemukan apa pun secara online. Saya hanya ingin dapat mencetak pi.
Perintah apa yang bisa mencetak pi untuk saya? Saya ingin menentukan jumlah digit yang dicetak, saya tidak dapat menemukan apa pun secara online. Saya hanya ingin dapat mencetak pi.
Jawaban:
Anda dapat menggunakan perintah ini:
echo "scale=5; 4*a(1)" | bc -l
3.14159
Di mana skala adalah jumlah digit setelah titik desimal.
Referensi: http://www.tux-planet.fr/calculer-le-chiffre-pi-en-ligne-de-commande-sous-linux/
bash
dan kerang lain yang mendukung disini string: bc -l <<< "scale=5; 4*a(1)"
.
scale=1000
memberikan 999 digit yang benar agak cepat (digit terakhir dimatikan oleh 1, masuk akal karena kita menghitung pi / 4 dan kemudian mengalikannya dengan 4). scale=4000
memberikan 4000 digit yang benar dalam beberapa detik. scale=10000
membutuhkan waktu lebih lama daripada yang saya sabar, tetapi mungkin memberikan angka 9999 atau 10000 yang benar.
Jika Anda telah tex(1)
menginstal:
tex --version | head -1 | cut -f2 -d' '
cut
. Lebih banyak digit dapat dicetak dengan menunggu lama dan menjalankan perintah lagi.
Untuk mencetak dengan presisi sewenang-wenang, Anda dapat menggunakan bc
dan rumusnya pi = 4*atan(1)
:
# bc -l
scale=<your precision>
4*a(1)
scale
pilihan itu, pi = 3.141592..
tetapi dengan itu echo "scale=5; 4*a(1)" | bc -l => 3.14156
saya akan berharap untuk melihat 3.14159
?
scale
menentukan ketepatan untuk digunakan untuk perhitungan, jadi dengan scale=5
, tidak ada operasi yang akan menggunakan lebih dari lima digit fraksional untuk setiap operasi atom.
Jika Anda menginginkan sesuatu yang dapat menghitung nilai π, maka ada beberapa pendekatan. Mungkin solusi yang paling jelas adalah dengan menggunakan paket siap pakai seperti pi
(tautan paket Debian) , yang jika deskripsi paket Debian dapat dipercaya dapat menghitung nilainya dengan presisi yang sewenang-wenang, hanya dibatasi oleh memori.
pi
sebenarnya adalah contoh yang disertakan dengan perpustakaan CLN (Perpustakaan Kelas untuk Angka) . Ini termasuk contoh aplikasi yang menyediakan alat untuk menghasilkan panjang angka yang sewenang-wenang seperti Pi, Fibonacci, dll. Paket CLN tersedia dalam paket awal di Debian / Ubuntu (itulah yang ditunjukkan oleh tautan Debian di atas).
$ ./pi 10
3.141592653
$ ./pi 20
3.1415926535897932384
CATATAN: Sumber dari contoh-contoh ini ada di sini di sumber untuk basis kode CLN .
Di Fedora saya harus mengunduh source tarball dan membangunnya sendiri, tetapi dibangun dengan sedikit keributan. Untuk alasan apa pun paket cln
di Fedora mencakup hanya pustaka tetapi mengabaikan contoh-contoh yang tersedia dalam versi Debian / Ubuntu (di atas).
Arch menyediakan program yang sama di dalam cln
paket (terima kasih Amphiteót ).
pi
suara persis seperti yang Anda cari. Anda dapat melakukan hal-hal seperti pi 300
mencetak 300 digit pertama misalnya.
Untuk hingga satu juta digit Anda dapat menggunakan yang berikut (di sini untuk 3000 digit):
curl --silent http://www.angio.net/pi/digits/pi1000000.txt | cut -c1-3000
cut
keluar? Jika itu masalahnya, saya setuju, itu akan menjadi O (n).
Beberapa jawaban lain menunjukkan angka yang salah di tempat terakhir dari output. Di bawah ini adalah variasi dari jawaban yang menggunakanbc
tetapi dengan hasil yang dibulatkan dengan benar. Variabel s
berisi jumlah digit signifikan (termasuk 3
di depan titik desimal).
$ 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
Pembulatan dilakukan langsung di bc
. Ini tidak memiliki batasan perintah printf
yang menggunakan representasi double
tipe bahasa C untuk angka-angka yang memiliki ketepatan sekitar 17 digit signifikan. Lihat jawabannya dengan printf
pembulatan .
scale=s-1
mengatur jumlah digit untuk dipotong. pi/1
bagi hasil dengan 1 untuk menerapkan pemotongan. Sederhana pi
tidak memotong angka.
Membulatkan setengah ke atas perlu menambahkan 5 ke digit pertama yang akan dipotong (5 × 10 -s ) sehingga dalam hal digit lebih tinggi sama dengan 5 digit terakhir yang akan tetap akan bertambah.
Dari tes oleh hobbs , tampaknya tiga digit tambahan yang akan dibulatkan / dipotong ( scale=s+2
) akan cukup bahkan untuk angka yang sangat panjang.
Contoh di atas menggunakan string di sini yang didukung misalnya dalam bash
, ksh
dan zsh
. Jika shell Anda tidak mendukung penggunaan string echo
dan pipa di sini:
$ echo "s=5; scale=s+2; pi=4*a(1); scale=s-1; pi/1" | bc -l
3.1415
Dengan python2:
$ python -c "import math; print(str(math.pi)[:7])"
3.14159
(..)
ini berfungsi dalam Python 2 dan 3. Tampaknya hanya memiliki 12 digit.
python -c "import gmpy2; print(str(gmpy2.const_pi(8192))[:400])"
. Tingkatkan presisi untuk lebih banyak digit ... mis.python -c "import gmpy2; print(str(gmpy2.const_pi(16384))[:4400])"
from mpmath import mp; mp.dps = 1000000 ; print(mp.pi)
hanya beberapa detik untuk satu juta digit. Tidak buruk sama sekali !!!.
Dalam bash:
$ read -a a <<< $(grep M_PIl /usr/include/math.h) ; echo ${a[3]} | tr -d L
3.141592653589793238462643383279502884
afmtodit
membutuhkan groff
untuk dipasang. Di sini, di Ubuntu (& rasa), ini bukan standar. JFYI.
Sangat sederhana dalam PHP menggunakan fungsi built in pi ():
<?php
echo round(pi(), 2);
?>
Bagaimana saya melewatkan pertanyaan ini ...
Berikut ini adalah program pi Python kecil saya yang saya posting beberapa minggu lalu di Stack Overflow. Ini tidak terlalu cepat, tetapi dapat melakukan banyak digit. :) Namun, seperti yang saya sebutkan di utas itu, saya biasanya menggunakan modul mpmath Python untuk aritmatika presisi sewenang-wenang, dan mpmath memiliki pembuat pi yang agak cepat.
Misalnya,
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 desimal pi dalam waktu di bawah 5 detik tidak terlalu buruk, IMHO, mengingat itu berjalan pada mesin dengan prosesor 2GHz single core, 2 pertunjukan RAM, dan menulis ke drive IDE tua.
from mpmath import mp; mp.dps = 1000000 ; print(mp.pi)
(setelah instalasi pip3 mpmath) di bawah dua detik untuk satu juta digit. Tidak buruk sama sekali !!!.
Jika Anda telah node.js
menginstal, ini akan melakukan yang terbaik untuk menemukan pi untuk Anda, meskipun yang terbaik tidak terlalu baik:
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 sampel:
3.14157749
3.1416426
3.14159055
3.14171554
3.14176165
3.14157587
3.14161137
3.14167685
3.14172371
node -e 'console.log(Math.PI)'
sedikit lebih baik daripada yang terbaik.
echo pie
?
Metode Monte Carlo
Lihat, misalnya, ini untuk penjelasan tentang metode ini.
Peringatan
Keuntungan
Menyenangkan :-)
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
}'
Catatan: Saya pertama kali mencobanya tanpa srand
tetapi macet 3.14
dan digit setelah itu terus berosilasi, tidak pernah konvergen. Ini mungkin karena, setelah beberapa saat PRNG mulai terulang. Penggunaan srand
akan menghindari itu atau setidaknya memperpanjang periode urutan pseudo-acak. Ini semua dugaan, jadi silakan koreksi saya jika saya salah.
bignum
operasi di Perl, saya takut dan saya tidak tahu ada bagian tertentu dari program di atas yang memerlukan Perl yang lebih baru. Lagi pula, yang menarik dari ini adalah algoritme itu sendiri. Cobalah menerapkannya dalam bahasa pilihan Anda jika Perl ini tidak cocok untuk Anda.
($x,$y,$circle,$not_circle)=(0,0,0);
sebelum loop untuk memastikan semua variabel didefinisikan sebelum digunakan.
(0,0,0,0)
.
($x,$y,$circle,$not_circle)=(0,0,0,0)
. Setelah satu atau dua menit, nilainya tergantung pada nilai yang diinginkan, kemudian semakin dekat ke 3.1409 sebelum saya berhenti. Menarik dan menyenangkan! Terima kasih!
Anda dapat menggunakan algoritma keran untuk pi. Program C berikut oleh Dik Winter dan Achim Flammenkamp akan menghasilkan 15.000 digit pertama pi, satu digit pada satu waktu.
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
Beberapa contoh:
php -r "print pi();"
php -r 'echo M_PI;'
echo "<?=pi();" | php
Jika Anda ingin mengubah presisi coba:
php -d precision=100 -r 'echo pi();'
Ukuran float tergantung pada platform, meskipun maksimum ~ 1.8e308 dengan presisi sekitar 14 digit desimal adalah nilai umum (format IEEE 64 bit). [Baca lebih lajut]
Jika Anda mencari presisi yang lebih akurat, lihat Rosetta Code atau Code Golf SE untuk beberapa solusi pemrograman.
Terkait: Perangkat lunak yang dapat menghitung PI hingga setidaknya seribu digit di SR.SE
Berikut ini skrip yang mencetak pi dengan jumlah digit yang ditentukan (termasuk '.') Oleh pengguna.
pi.sh
#!/bin/bash
len=${1:-7}
echo "4*a(1)" | bc -l | cut -c 1-"$len"
keluaran
$ ./pi.sh 10
3.14159265
dan dengan nilai default:
$ ./pi.sh
3.14159
Saya telah melihat orang menggunakan scale
sebagai bc
opsi, tetapi dalam kasus saya ( bc 1.06.95
) ini tidak menampilkan nilai yang benar:
$ echo "scale=5;4*a(1)" | bc -l
3.14156
Perhatikan digit terakhir.
./pi.sh 10
mencetak sembilan digit, menghitung awal 3
. Juga, Anda menunjuk jari kesalahan pembulatan, tetapi ./pi.sh 6
output Anda 3.1415
, yang mungkin tidak optimal.
scale=X
opsi bc
TIDAK akan membulatkan angka, tetapi cukup memotong angka pada angka desimal X-th.
Saya suka jawaban Abey tetapi tidak suka bagaimana bc mengubah digit terakhir.
echo "scale=5; 4*a(1)" | bc -l
3.14156
Jadi saya menghapus skala yang digunakan printf untuk mengatur jumlah digit.
printf "%0.5f\n" $(echo "4*a(1)" | bc -l)
3.14159
printf
memiliki batasan parah pada angka floating point dibandingkan dengan bc
. Mereka diwakili oleh double
tipe bahasa C dengan presisi sekitar 17 digit sehingga bahkan digit non-nol setelah sekitar 17 adalah palsu! ------ Saya telah menambahkan jawaban dengan pembulatan yang benar dari hasil yang tidak dibatasi olehprintf
. ------ Juga untuk memastikan bahwa perintah ini bekerja dengan berbagai lokal Anda harus melakukan sesuatu seperti ini: LC_ALL=C printf
...
Bagaimana jika Anda tidak bisa seumur hidup mengingat arctan
hal ini ? Atau seandainya Anda bahkan tidak tahu fungsi ini ada bc
, maka cobalah untuk menghafal pembagian sederhana ini:
echo "scale=6; 355 / 113" | bc
3.141592
Hanya akan bekerja untuk 6 digit, tetapi untuk perhitungan non-ilmiah ini akan baik-baik saja.
Jika Anda pikir Anda tidak dapat mengingat kedua angka ini juga, tulis penyebut terlebih dahulu, kemudian pembilangnya:
113 355
Atau mengapa tidak
11 33 55
"ganda 1, ganda 3, ganda 5". Semua angka aneh. Untuk menghitung, pisahkan angka 6 digit menjadi dua lagi, dan tukar penyebut dan pembilang sebelum membaginya. Itu saja.
4 * arctan(1)
jauh lebih mudah untuk mengingat bahwa 2 angka tiga digit ... Saya akan dengan mudah menggunakan 335 alih-alih 355, atau 133 alih-alih 113.
Dapat diasumsikan bahwa OP tertarik pada perintah shell yang pendek dan mudah diingat untuk dicetak π - tetapi pertanyaannya tidak benar-benar mengatakan itu. Jawaban ini mengabaikan anggapan itu dan menjawab pertanyaan itu dengan ketat sebagaimana tertulis;
Meskipun sudah ada 18 jawaban, satu pendekatan masih hilang - dan dengan begitu banyak jawaban, orang bisa berpikir itu bukan satu-satunya yang hilang:
Yang sepele: Bagaimana cara mencetak π? Cukup cetak π!
Pendekatan itu tampaknya terlalu tidak berguna untuk dipikirkan, tetapi saya akan menunjukkan bahwa itu memang memiliki kelebihan:
Kami biasanya menghitung nilai π. Saya tidak melihat apa yang membuat kami tidak mengoptimalkan solusi, dengan menghitung ulang nilainya - ini adalah konstan, kompiler mana pun akan melakukannya.
Kami ingin beberapa digit π, hingga presisi maksimum. Jadi kita bisa mengambil awalan konstanta, sebagai teks:
echo 3.1415926535897932384626433832795 | cut -b -7
3.14159
Varian dengan argumen eksplisit untuk presisi, mis. untuk presisi 5
:
echo 3.1415926535897932384626433832795 | cut -b -$((2+5))
3.14159
Ketepatan maksimum dapat dipilih secara sewenang-wenang dengan menggunakan konstanta yang sesuai yang dihitung menggunakan salah satu jawaban lainnya. Ini dibatasi hanya oleh panjang maksimal baris perintah.
Ini memiliki kompleksitas waktu yang konstan untuk menemukan nilai.
Ini membuat semua batasan dan kendala menjadi jelas, berdasarkan kompleksitas implementasi yang rendah.
Ini menangani presisi lebih besar dari maksimum dengan anggun dengan mengembalikan konstanta dalam presisi penuh yang tersedia (tanpa trailing 0
).
Jadi solusi ini, meski sepele, memang memiliki kelebihan. Ini mungkin berguna ketika digunakan dalam fungsi shell, misalnya.
Fungsionalitas dari solusi di atas juga dapat ditambahkan tanpa membuat proses untuk cut
(dengan asumsi echo
shell builtin). Ini menggunakan perintah printf
(biasanya builtin) dengan cara yang agak tidak jelas:
Konstanta sepenuhnya handeled sebagai string (format menggunakan %s
), tidak ada floating point arithmethic yang terlibat, sehingga batas float
atau double
tidak berlaku di sini.
Nilai presisi %s
pelarian ( 5
dalam contoh di bawah) menentukan panjang awalan string yang akan dicetak - yang merupakan presisi. Ini 3.
adalah bagian dari printf
format untuk tetap keluar dari perhitungan presisi.
$ printf "3.%.5s\n" 1415926535897932384626433832795
3.14159
Alternatif dengan presisi sebagai argumen terpisah:
$ printf "3.%.*s\n" 5 1415926535897932384626433832795
3.14159
Atau sedikit lebih mudah dibaca (Catat ruang di antara 3.
dan 14159...
, mereka adalah argumen yang terpisah):
$ printf "%s%.5s\n" 3. 1415926535897932384626433832795
3.14159
Varian menggunakan printf
dapat diharapkan menjadi sangat cepat: Karena printf
shell builtin pada shell umum seperti bash
dan zsh
, itu tidak membuat proses apa pun.
Juga, itu tidak menyentuh segala jenis kode terkait floating point, tetapi hanya manipulasi array byte (secara eksplisit bukan karakter multibyte). Ini biasanya lebih cepat, seringkali jauh lebih cepat daripada penggunaan floating point.
Seringkali, ada alasan untuk mengganti printf
dengan /usr/bin/printf
untuk menjamin konsistensi atau kompatibilitas. Dalam hal ini, saya pikir kita dapat menggunakan builtin - yang penting, karena menggunakan /usr/bin/printf
mengurangi keuntungan "cepat" dengan melakukan proses.
Masalah umum dengan printf
kompatibilitas adalah format angka keluaran tergantung pada lokal. Pemisahan .
untuk angka dapat diubah menjadi ,
berdasarkan pengaturan lokal; Tapi kami tidak menggunakan angka, hanya konstanta string yang mengandung literal .
- tidak terpengaruh oleh lokal.
StéphaneChazelas menunjukkan bahwa cara printf %.5s
kerjanya berbedazsh
, dengan menghitung karakter, bukan byte seperti biasa. Untungnya, konstanta kami hanya menggunakan karakter dalam rentang ASCII yang lebih rendah, yang dikodekan oleh satu byte per karakter dalam pengkodean yang relevan, selama kami menggunakan UTF-8
pengkodean umum untuk Unicode, dan bukan pengodean lebar tetap.
printf %.5s
char (bukan byte) berbasis di zsh (masuk akal, tetapi terhadap POSIX). ksh93
's %.5Ls
adalah graphem berbasis.