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.
Perhatikan bahwa ini akan lebih menyenangkan jika Anda ingin lebih banyak angka daripada sekitar 15.
Thorbjørn Ravn Andersen
2
@DisplayName: itu berarti bahwa Anda tidak dapat lagi menggunakan program apa pun yang secara internal menyimpan / menghitung PI menggunakan nilai floating point presisi ganda (yang biasanya tipe data FP "built-in" presisi tertinggi yang tersedia dalam sebagian besar bahasa).
Matteo Italia
5
Solusi saya, beberapa dekade yang lalu sebelum ini biasanya disediakan oleh perpustakaan bahasa, adalah menghafalkannya ke lebih banyak tempat daripada yang perlu saya gunakan: 3.1415926535897932384626 biasanya cukup dekat untuk tujuan praktis, dan bahkan yang paling tidak praktis - apa pun yang nyata -Dunia akan memiliki lebih banyak kesalahan daripada itu di angka-angka lain, dan untuk teori saya akan tetap dengan nilai simbolik daripada nilai numerik.
keshlam
3
Minat @syntaxerror tidak relevan. Jika Anda memposting pertanyaan yang meminta gambar telanjang para selebritas, itu akan mendapat ribuan pandangan dan sangat mungkin mendapat dukungan. Itu tidak membuatnya pada topik. Pertanyaan ini adalah contoh klasik yang terlalu luas. Lihat saja sejumlah jawaban. Perhatikan juga bahwa OP tidak menentukan batasan apa pun yang membuat kemungkinan jawaban pada dasarnya tidak terbatas. Bagaimanapun, penutupan tidak menghapus. Pertanyaan dan semua 23 jawabannya masih ada di sini. Menutup berarti tidak ada lagi jawaban yang diterima. Apakah kita benar-benar membutuhkan lebih banyak cara untuk mencetak π?
terdon
Jawaban:
52
Anda dapat menggunakan perintah ini:
echo "scale=5; 4*a(1)" | bc -l
3.14159
Di mana skala adalah jumlah digit setelah titik desimal.
Versi yang lebih pendek di bashdan kerang lain yang mendukung disini string: bc -l <<< "scale=5; 4*a(1)".
pabouk
2
Saya bertanya-tanya berapa banyak angka yang bisa didapat?
DisplayName
4
@DisplayName beberapa. scale=1000memberikan 999 digit yang benar agak cepat (digit terakhir dimatikan oleh 1, masuk akal karena kita menghitung pi / 4 dan kemudian mengalikannya dengan 4). scale=4000memberikan 4000 digit yang benar dalam beberapa detik. scale=10000membutuhkan waktu lebih lama daripada yang saya sabar, tetapi mungkin memberikan angka 9999 atau 10000 yang benar.
hobbs
4
Ini memberikan hasil yang salah pada mesin saya, mengetik 'echo "scale = 5; 4 * a (1)" | bc -l 'mengembalikan 3.14156, ketika digit terakhir harus oleh 9
Ini hampir layak mendapat pujian hanya karena pintar. Meskipun output dari ini berubah ketika Anda meningkatkan paket. Haruskah kita menganggap itu sebagai fitur atau bug?
CVn
8
@ MichaelKjörling Sebenarnya, ini berubah menjadi perkiraan pi yang lebih tepat.
Abrixas2
@ Abrixas2 Ya, saya tahu. Dengan versi terakhir TeX menjadi versi π.
CVn
30
@ DavidRicherby Lebih sedikit digit dapat dicetak melalui doa tambahan cut. Lebih banyak digit dapat dicetak dengan menunggu lama dan menjalankan perintah lagi.
Steven D
1
@Ruslan tergantung pada implementasinya. Saya berharap dalam kasus khusus ini akan dilakukan "benar".
Thorbjørn Ravn Andersen
23
Untuk mencetak dengan presisi sewenang-wenang, Anda dapat menggunakan bcdan rumusnya pi = 4*atan(1):
Ada sesuatu yang lucu tentang scalepilihan itu, pi = 3.141592..tetapi dengan itu echo "scale=5; 4*a(1)" | bc -l => 3.14156saya akan berharap untuk melihat 3.14159?
fduff
7
scalemenentukan 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.
pisebenarnya 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).
Di Fedora saya harus mengunduh source tarball dan membangunnya sendiri, tetapi dibangun dengan sedikit keributan. Untuk alasan apa pun paket clndi Fedora mencakup hanya pustaka tetapi mengabaikan contoh-contoh yang tersedia dalam versi Debian / Ubuntu (di atas).
Ya, heh maksud saya nilai total saya hanya mengetik apa yang ada di kepala saya.
DisplayName
2
"Nilai total" ?? Berarti apa...?
Kyle Strand
2
@DisplayName membaca sisa jawabannya. Program berdedikasi seperti pisuara persis seperti yang Anda cari. Anda dapat melakukan hal-hal seperti pi 300mencetak 300 digit pertama misalnya.
terdon
3
@KyleStrand Saya telah menemukan jawaban yang benar-benar luar biasa untuk itu, yang terlalu sempit untuk dikomentari. Hei, itu berhasil untuk Fermat !
terdon
Saya ingin tahu mengapa ini menerima dua downvotes. Apakah orang-orang yang turun memilih tidak membaca jawaban sebelum mereka memutuskan itu tidak berguna?
CVn
17
Untuk hingga satu juta digit Anda dapat menggunakan yang berikut (di sini untuk 3000 digit):
Ini memiliki manfaat tambahan yang harusnya mendekati kompleksitas O (1). Atau mungkin itu sama sekali bukan manfaat ...
CVn
7
Juga, sulit untuk mengatakan bahwa setiap interaksi jaringan adalah O (1) kompleksitas waktu dalam dunia praktis. : P
HalosGhost
2
@HalosGhost Untuk keperluan kami (dibandingkan dengan menghitung n digit pi setiap kali), mengunduh jumlah data tetap dari server tertentu melalui jaringan cenderung efektif O (1), sedangkan komputasi n digit pi cenderung menjadi setidaknya sesuatu seperti O (log n) dan sangat mungkin lebih tinggi (Saya tidak terbiasa dengan algoritma tersebut). Pengunduhan data yang sebenarnya kemungkinan akan memakan waktu lebih lama daripada overhead untuk memulai pengunduhan, oleh karena itu waktu pengunduhan mendominasi dan Anda mendapatkan tempat di sekitar O (1) mengingat laju transmisi data yang cukup tetap. Maka O (1).
CVn
4
@ MichaelKjörling Ketika Anda mengatakan O (1) bukankah Anda benar-benar bermaksud O (n)? Waktu pengunduhan dalam linear dalam jumlah digit yang Anda butuhkan, maka O (n).
CodesInChaos
1
@CodesInChaos Tidak, waktu pengunduhan adalah konstan (diberikan laju transmisi konstan) karena Anda mengunduh jumlah digit yang konstan (satu juta, di sini). Kecuali (dalam kasus khusus ini) curl cukup pintar untuk mencetak saat mengunduh dan berhenti mengunduh begitu pipa putus karena cutkeluar? Jika itu masalahnya, saya setuju, itu akan menjadi O (n).
CVn
15
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 sberisi jumlah digit signifikan (termasuk 3di depan titik desimal).
Bulat setengah
$ bc -l <<< "s=5; scale=s+2; pi=4*a(1)+5*10^(-s); scale=s-1; pi/1"
3.1416
Round down (terpotong)
$ bc -l <<< "s=5; scale=s+2; pi=4*a(1); scale=s-1; pi/1"
3.1415
Penjelasan tentang pembulatan
Pembulatan dilakukan langsung di bc. Ini tidak memiliki batasan perintah printfyang menggunakan representasi doubletipe bahasa C untuk angka-angka yang memiliki ketepatan sekitar 17 digit signifikan. Lihat jawabannya dengan printfpembulatan .
scale=s-1mengatur jumlah digit untuk dipotong. pi/1bagi hasil dengan 1 untuk menerapkan pemotongan. Sederhana pitidak 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.
Di sini string
Contoh di atas menggunakan string di sini yang didukung misalnya dalam bash, kshdan zsh. Jika shell Anda tidak mendukung penggunaan string echodan pipa di sini:
Menghitung tiga digit tambahan untuk tujuan pembulatan bukanlah "pembulatan yang benar" seperti yang Anda klaim dalam komentar. Pertama, Anda tidak terikat pada kesalahan perhitungan. Jika itu bisa salah dengan 3 unit di tempat terakhir seperti yang diklaim oleh fduff, mengapa tidak salah dengan 1000 unit di tempat terakhir? Kedua, lihat "dilema pembuat meja".
@ArtemShitov - saya buruk, coba impor gmpy2 (jika Anda memilikinya diinstal): 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])"
don_crissti
1
Yang tercepat yang bisa saya temukan adalah from mpmath import mp; mp.dps = 1000000 ; print(mp.pi)hanya beberapa detik untuk satu juta digit. Tidak buruk sama sekali !!!.
Isaac
7
Menggunakan Ruby:
require "bigdecimal"
require "bigdecimal/math"
include BigMath
BigDecimal(PI(100)).round(9).to_s("F")
3.141592654
@ Amphiteóth afmtoditmembutuhkan groffuntuk dipasang. Di sini, di Ubuntu (& rasa), ini bukan standar. JFYI.
syntaxerror
@syntaxerror Terima kasih, bagus! Saya telah menghapus contoh saya. Maksud saya adalah ketika membaca AI ini berjalan greppada sistem saya mencari konstanta dan menemukannya di lebih dari satu tempat. Itu sebabnya ini +1 untuk saya!
3
Sangat sederhana dalam PHP menggunakan fungsi built in pi ():
Bisakah Anda mengedit ini untuk memberikan versi baris perintah?
curiousdannii
3
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.
Coba 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 !!!.
Isaac
2
Jika Anda telah node.jsmenginstal, ini akan melakukan yang terbaik untuk menemukan pi untuk Anda, meskipun yang terbaik tidak terlalu baik:
Yang lebih pendek node -e 'console.log(Math.PI)'sedikit lebih baik daripada yang terbaik.
chbrown
1
@chbrown Itu tidak memenuhi persyaratan OP "tidak serius".
Paul
1
Apa persyaratan "tidak serius"? OP hanya menyatakan bahwa mereka meminta kesenangan bukan karena mereka menginginkan jawaban yang entah bagaimana "tidak serius". Apa artinya itu? Sesuatu seperti echo pie?
terdon
Saya mengetik itu karena ketika Anda mengajukan pertanyaan kadang-kadang orang mengatakan bahwa "ini bukan pabrik penulisan skrip", jadi saya mengatakan bahwa karena tidak ada alasan untuk itu, saya hanya ingin tahu cara mencetak pi.
DisplayName
@ Amphiteóth Diperlukan waktu sekitar 20 detik untuk berjalan di komputer saya. Anda mungkin perlu memberinya waktu.
Paul
2
Metode Monte Carlo
Lihat, misalnya, ini untuk penjelasan tentang metode ini.
Peringatan
Tidak akurat sembarang
Butuh waktu lama untuk menyatu dengan sesuatu yang bermanfaat
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 srandtetapi macet 3.14dan digit setelah itu terus berosilasi, tidak pernah konvergen. Ini mungkin karena, setelah beberapa saat PRNG mulai terulang. Penggunaan srandakan menghindari itu atau setidaknya memperpanjang periode urutan pseudo-acak. Ini semua dugaan, jadi silakan koreksi saya jika saya salah.
@ Amphiteót Tidak begitu yakin apa yang sedang terjadi di sana. Jika itu membantu Perl saya adalah v5.14.2. Saya tidak begitu berpengalaman dengan bignumoperasi 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.
Joseph R.
1
@ Amphiteót begitu. Apakah hasil edit memecahkan masalah Anda?
Joseph R.
@ Amphiteót Anda dapat mencoba menambahkan ($x,$y,$circle,$not_circle)=(0,0,0);sebelum loop untuk memastikan semua variabel didefinisikan sebelum digunakan.
Joseph R.
@ Amphiteót Kesalahan saya. Parens di atas seharusnya (0,0,0,0).
Joseph R.
Re ini /5.20.1: Masuk akal tetapi tidak melihatnya! Memang ($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!
2
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.
Saya suka algoritma keran untuk konstanta logaritmik oleh Borwein, Bailey dan Plouffe, namun, ini bukan kode golf, jadi bolehkah saya meningkatkan keterbacaan kode Anda dengan memformat ulangnya? Juga perhatikan bahwa algoritme gaya BPP hanya dapat menampilkan digit untuk pi dalam basis yang memiliki kekuatan 2, setidaknya tanpa menggunakan memori tambahan.
Franki
@ Franki apakah memformat kode mengubah arti atau maksud dari posting? Jika tidak, itu harus baik-baik saja (dan pengeditan selalu dapat dibatalkan). Saya tidak melihat bagaimana mengurangi beberapa kode bisa melakukan hal lain selain mengklarifikasi.
11684
1
@syntaxerror Ini adalah untuk menghasilkan tepat 15.000 digit sebelum berhenti. Output dalam for-loop kedua menghasilkan 4 digit pi dan mengurangi jumlah misteri 52514 oleh 14. Persamaannya akan menjadi 4 * (52514/14) yang sama dengan 15004. Nilai-nilai 14 terakhir dalam array diabaikan untuk diambil manfaat lebih sedikit token untuk mendapatkan nilai tepat kami 15000.
Daniel Henneberger
1
@ 11684 Tidak, itu benar-benar tidak akan mengubah arti atau maksud kode. Namun, saya menyadari ini bukan algoritma keran gaya BBP untuk pi, tapi yang lain yang orang lain telah deobfuscated di sini stackoverflow.com/a/25837097
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.
Pertanyaannya mengatakan, "Saya ingin menentukan berapa banyak angka yang dicetaknya," yang, sebenarnya, ambigu - tetapi saya pikir jawaban Anda gagal (berdasarkan teknis) di bawah interpretasi yang masuk akal; Anda ./pi.sh 10mencetak sembilan digit, menghitung awal 3. Juga, Anda menunjuk jari kesalahan pembulatan, tetapi ./pi.sh 6output Anda 3.1415, yang mungkin tidak optimal.
G-Man Mengatakan 'Reinstate Monica'
Dari memori, scale=Xopsi bcTIDAK akan membulatkan angka, tetapi cukup memotong angka pada angka desimal X-th.
syntaxerror
1
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.
Pernahkah Anda memperhatikan, setelah skala 62 digit, semuanya 0 sedangkan ini tidak terjadi dengan perintah asli.
2
@ Amphiteót, Itu karena printfmemiliki batasan parah pada angka floating point dibandingkan dengan bc. Mereka diwakili oleh doubletipe 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...
pabouk
1
Bagaimana jika Anda tidak bisa seumur hidup mengingat arctanhal 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.
Sejauh yang saya ketahui, saya menemukan 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.
John WH Smith
Yah, saya pikir ini masalah preferensi pribadi. :) Orang-orang (seperti saya) yang dapat dengan mudah menghafal nomor telepon (darat!) Akan dapat menghafal dua angka sama seperti satu nomor telepon tunggal. Ini juga akan membantu orang-orang yang di sekolah merasa bahwa trigonometri pasti dibuat oleh kekuatan jahat.
syntaxerror
1
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;
Sepele?
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:
Dioptimalkan
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:
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.
Minimal
Fungsionalitas dari solusi di atas juga dapat ditambahkan tanpa membuat proses untuk cut(dengan asumsi echoshell 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 floatatau doubletidak berlaku di sini.
Nilai presisi %spelarian ( 5dalam contoh di bawah) menentukan panjang awalan string yang akan dicetak - yang merupakan presisi. Ini 3.adalah bagian dari printfformat untuk tetap keluar dari perhitungan presisi.
Varian menggunakan printfdapat diharapkan menjadi sangat cepat: Karena printfshell builtin pada shell umum seperti bashdan 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.
kompatibilitas printf
Seringkali, ada alasan untuk mengganti printfdengan /usr/bin/printfuntuk menjamin konsistensi atau kompatibilitas. Dalam hal ini, saya pikir kita dapat menggunakan builtin - yang penting, karena menggunakan /usr/bin/printfmengurangi keuntungan "cepat" dengan melakukan proses.
Masalah umum dengan printfkompatibilitas 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 %.5skerjanya 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-8pengkodean umum untuk Unicode, dan bukan pengodean lebar tetap.
Jawaban:
Anda dapat menggunakan perintah ini:
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/
sumber
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:sumber
cut
. Lebih banyak digit dapat dicetak dengan menunggu lama dan menjalankan perintah lagi.Untuk mencetak dengan presisi sewenang-wenang, Anda dapat menggunakan
bc
dan rumusnyapi = 4*atan(1)
:sumber
scale
pilihan itu,pi = 3.141592..
tetapi dengan ituecho "scale=5; 4*a(1)" | bc -l => 3.14156
saya akan berharap untuk melihat3.14159
?scale
menentukan ketepatan untuk digunakan untuk perhitungan, jadi denganscale=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.
Contohnyapi
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).CATATAN: Sumber dari contoh-contoh ini ada di sini di sumber untuk basis kode CLN .
Distro lainnya
FedoraDi Fedora saya harus mengunduh source tarball dan membangunnya sendiri, tetapi dibangun dengan sedikit keributan. Untuk alasan apa pun paket
Lengkungancln
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 ).sumber
pi
suara persis seperti yang Anda cari. Anda dapat melakukan hal-hal sepertipi 300
mencetak 300 digit pertama misalnya.Untuk hingga satu juta digit Anda dapat menggunakan yang berikut (di sini untuk 3000 digit):
sumber
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 menggunakan
bc
tetapi dengan hasil yang dibulatkan dengan benar. Variabels
berisi jumlah digit signifikan (termasuk3
di depan titik desimal).Bulat setengah
Round down (terpotong)
Penjelasan tentang pembulatan
Pembulatan dilakukan langsung di
bc
. Ini tidak memiliki batasan perintahprintf
yang menggunakan representasidouble
tipe bahasa C untuk angka-angka yang memiliki ketepatan sekitar 17 digit signifikan. Lihat jawabannya denganprintf
pembulatan .scale=s-1
mengatur jumlah digit untuk dipotong.pi/1
bagi hasil dengan 1 untuk menerapkan pemotongan. Sederhanapi
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.Di sini string
Contoh di atas menggunakan string di sini yang didukung misalnya dalam
bash
,ksh
danzsh
. Jika shell Anda tidak mendukung penggunaan stringecho
dan pipa di sini:sumber
perl satu baris (menggunakan bignum ):
misalnya
sumber
Dengan python2:
sumber
(..)
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 !!!.Menggunakan Ruby:
sumber
ruby -e 'require "bigdecimal"; require "bigdecimal/math"; include BigMath; puts BigDecimal(PI(100)).round(9).to_s("F")'
Dalam bash:
sumber
afmtodit
membutuhkangroff
untuk dipasang. Di sini, di Ubuntu (& rasa), ini bukan standar. JFYI.grep
pada sistem saya mencari konstanta dan menemukannya di lebih dari satu tempat. Itu sebabnya ini +1 untuk saya!Sangat sederhana dalam PHP menggunakan fungsi built in pi ():
sumber
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,
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.
sumber
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:Output sampel:
sumber
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 :-)
Catatan: Saya pertama kali mencobanya tanpa
srand
tetapi macet3.14
dan digit setelah itu terus berosilasi, tidak pernah konvergen. Ini mungkin karena, setelah beberapa saat PRNG mulai terulang. Penggunaansrand
akan menghindari itu atau setidaknya memperpanjang periode urutan pseudo-acak. Ini semua dugaan, jadi silakan koreksi saya jika saya salah.sumber
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.
sumber
PHP
Beberapa contoh:
Jika Anda ingin mengubah presisi coba:
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
sumber
Berikut ini skrip yang mencetak pi dengan jumlah digit yang ditentukan (termasuk '.') Oleh pengguna.
pi.sh
keluaran
dan dengan nilai default:
Saya telah melihat orang menggunakan
scale
sebagaibc
opsi, tetapi dalam kasus saya (bc 1.06.95
) ini tidak menampilkan nilai yang benar:Perhatikan digit terakhir.
sumber
./pi.sh 10
mencetak sembilan digit, menghitung awal3
. Juga, Anda menunjuk jari kesalahan pembulatan, tetapi./pi.sh 6
output Anda3.1415
, yang mungkin tidak optimal.scale=X
opsibc
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.
Jadi saya menghapus skala yang digunakan printf untuk mengatur jumlah digit.
sumber
printf
memiliki batasan parah pada angka floating point dibandingkan denganbc
. Mereka diwakili olehdouble
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 adabc
, maka cobalah untuk menghafal pembagian sederhana ini: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.
sumber
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;
Sepele?
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:
Dioptimalkan
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:
Varian dengan argumen eksplisit untuk presisi, mis. untuk presisi
5
:Keuntungan
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.
Minimal
Fungsionalitas dari solusi di atas juga dapat ditambahkan tanpa membuat proses untuk
cut
(dengan asumsiecho
shell builtin). Ini menggunakan perintahprintf
(biasanya builtin) dengan cara yang agak tidak jelas:Konstanta sepenuhnya handeled sebagai string (format menggunakan
%s
), tidak ada floating point arithmethic yang terlibat, sehingga batasfloat
ataudouble
tidak berlaku di sini.Nilai presisi
%s
pelarian (5
dalam contoh di bawah) menentukan panjang awalan string yang akan dicetak - yang merupakan presisi. Ini3.
adalah bagian dariprintf
format untuk tetap keluar dari perhitungan presisi.Alternatif dengan presisi sebagai argumen terpisah:
Atau sedikit lebih mudah dibaca (Catat ruang di antara
3.
dan14159...
, mereka adalah argumen yang terpisah):Cepat
Varian menggunakan
printf
dapat diharapkan menjadi sangat cepat: Karenaprintf
shell builtin pada shell umum sepertibash
danzsh
, 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.
kompatibilitas printf
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 menggunakanUTF-8
pengkodean umum untuk Unicode, dan bukan pengodean lebar tetap.sumber
printf %.5s
char (bukan byte) berbasis di zsh (masuk akal, tetapi terhadap POSIX).ksh93
's%.5Ls
adalah graphem berbasis.