ฉันจะพิมพ์ pi (3.14159) ได้อย่างไร [ปิด]


35

คำสั่งใดที่สามารถพิมพ์ pi ให้ฉันได้? ฉันต้องการระบุจำนวนหลักที่พิมพ์ฉันไม่พบสิ่งใดทางออนไลน์ ฉันแค่อยากจะพิมพ์ปี่


28
เลือกภาษาของคุณ: rosettacode.org/wiki/Pi
Mark Plotnick

4
โปรดทราบว่ามันสนุกมากขึ้นถ้าคุณต้องการตัวเลขมากกว่าประมาณ 15
Thorbjørn Ravn Andersen

2
@DisplayName: หมายความว่าคุณไม่สามารถใช้โปรแกรมใด ๆ ที่จัดเก็บ / คำนวณ PI ภายในโดยใช้ค่าจุดลอยตัวที่มีความแม่นยำสองเท่า (ซึ่งโดยปกติจะเป็นประเภทข้อมูล FP ในตัวที่มีความแม่นยำสูงสุด "ในตัว")
Matteo Italia

5
วิธีแก้ปัญหาของฉันเมื่อหลายสิบปีก่อนที่ห้องสมุดภาษามักจะให้ความทรงจำกับสถานที่มากกว่าจุดลอยตัวที่ฉันเคยใช้: 3.141592653589793232464626 มักจะใกล้พอสำหรับการใช้งานจริงและแม้แต่สิ่งที่ไม่สามารถทำได้จริง - โลกจะมีข้อผิดพลาดมากกว่านั้นในตัวเลขอื่น ๆ และสำหรับทฤษฎีฉันจะใช้สัญลักษณ์แทนค่าตัวเลข
keshlam

3
@syntaxerror สนใจไม่เกี่ยวข้อง หากคุณต้องการโพสต์คำถามเพื่อขอภาพเปลือยของดารามันจะได้รับมุมมองนับพันและอาจ upvotes ที่ไม่ได้ทำให้มันอยู่ในหัวข้อ คำถามนี้เป็นตัวอย่างคลาสสิกที่กว้างเกินไป เพียงดูที่จำนวนคำตอบ โปรดทราบด้วยว่า OP ไม่ได้ระบุข้อ จำกัดใด ๆซึ่งทำให้คำตอบที่เป็นไปได้ไม่มีที่สิ้นสุด ไม่ว่าในกรณีใดการปิดจะไม่ถูกลบ คำถามและคำตอบทั้งหมด 23 ข้อยังคงอยู่ที่นี่ การปิดเพียงหมายความว่าจะไม่ยอมรับคำตอบเพิ่มเติม เราต้องการวิธีการพิมพ์มากกว่านี้หรือไม่?
terdon

คำตอบ:


52

คุณสามารถใช้คำสั่งนี้:

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

โดยที่ scale คือจำนวนของตัวเลขหลังจุดทศนิยม

การอ้างอิง: http://www.tux-planet.fr/calculer-le-chiffre-pi-en-ligne-de-commande-sous-linux/


12
รุ่นสั้นbashและเปลือกหอยอื่น ๆ bc -l <<< "scale=5; 4*a(1)"ที่สนับสนุนที่นี่สตริง:
pabouk

2
ฉันสงสัยว่าตัวเลขนี้สามารถไปได้กี่หลัก?
DisplayName

4
@DisplayName ค่อนข้างน้อย scale=1000ให้ 999 ตัวเลขที่ถูกต้องค่อนข้างเร็ว (ตัวเลขสุดท้ายปิดด้วย 1 เหมาะสมเนื่องจากเราคำนวณ pi / 4 แล้วคูณด้วย 4) scale=4000ให้ตัวเลขที่ถูกต้อง 4000 ในไม่กี่วินาที scale=10000ใช้เวลานานกว่าที่ฉันมีความอดทน แต่อาจให้ตัวเลขที่ถูกต้อง 9999 หรือ 10,000
ฮอบส์

4
สิ่งนี้ให้ผลลัพธ์ที่ไม่ถูกต้องบนเครื่องของฉันโดยพิมพ์ 'echo "scale = 5; 4 * a (1)" | bc -l 'ส่งคืน 3.14156 เมื่อตัวเลขหลักสุดท้ายควร 9
Jordan Bentley

1
@JordanBentley ผมได้เพิ่มคำตอบกับการปัดเศษที่ถูกต้องของผล
pabouk

61

หากคุณtex(1)ติดตั้งแล้ว:

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

13
นี่เป็นสิ่งที่คุ้มค่ากับการลงคะแนนเพียงเพื่อความฉลาด แม้ว่าผลลัพธ์ของการเปลี่ยนแปลงนี้เมื่อคุณอัพเกรดแพ็คเกจ เราจะพิจารณาว่าเป็นคุณสมบัติหรือข้อบกพร่องหรือไม่?
CVn

8
@ MichaelKjörlingที่จริงแล้วมันเปลี่ยนเป็นการประมาณที่แม่นยำยิ่งขึ้นของ pi
Abrixas2

@ Abrixas2 ใช่ฉันรู้ ด้วยเวอร์ชันล่าสุดของ TeX เป็นเวอร์ชันπ
CVn

30
@DavidRicherby cutตัวเลขลดจำนวนสามารถพิมพ์ผ่านการภาวนาที่เพิ่มขึ้นของ ตัวเลขเพิ่มเติมสามารถพิมพ์ได้โดยรอเป็นเวลานานและรันคำสั่งอีกครั้ง
Steven D

1
@Ruslan ขึ้นอยู่กับการใช้งาน ฉันคาดหวังว่าในกรณีนี้จะทำให้ถูกต้อง
Thorbjørn Ravn Andersen

23

สำหรับการพิมพ์ด้วยความแม่นยำโดยพลการคุณสามารถใช้bcและสูตรpi = 4*atan(1):

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

2
มีบางอย่างตลกเกี่ยวกับscaleตัวเลือกpi = 3.141592..แต่ด้วยecho "scale=5; 4*a(1)" | bc -l => 3.14156แล้วฉันจะคาดหวังที่จะเห็น3.14159?
fduff

7
scaleระบุความแม่นยำที่จะใช้สำหรับการคำนวณดังนั้นหากscale=5ไม่มีการดำเนินการใด ๆ จะใช้ตัวเลขเศษส่วนมากกว่าห้าหลักสำหรับการดำเนินการปรมาณูใด ๆ
Abrixas2

@fduff ผมได้เพิ่มคำตอบกับการปัดเศษที่ถูกต้องของผล
pabouk

20

หากคุณต้องการบางสิ่งที่สามารถคำนวณค่าของπได้นั้นมีหลายวิธี บางทีทางออกที่ชัดเจนที่สุดคือการใช้แพคเกจสำเร็จรูปเช่นpi(ลิงก์แพ็กเกจ Debian)ซึ่งหากคำอธิบายแพคเกจของ Debian เชื่อถือได้สามารถคำนวณค่าให้แม่นยำโดยมีข้อ จำกัด โดยหน่วยความจำเท่านั้น

piเป็นจริงตัวอย่างเช่นที่มาพร้อมกับที่ห้องสมุด CLN (ไลบรารีคลาสสำหรับเบอร์) มันมีตัวอย่างแอพพลิเคชั่นที่ให้เครื่องมือในการสร้างความยาวของตัวเลขเช่น Pi, Fibonacci และอื่น ๆ แพ็คเกจ CLN นั้นมีอยู่ในแพ็คเกจล่วงหน้าใน Debian / Ubuntu (นั่นคือสิ่งที่ลิงก์ Debian ด้านบนชี้)

ตัวอย่าง
$ ./pi 10
3.141592653

$ ./pi 20
3.1415926535897932384

หมายเหตุ:แหล่งที่มาของตัวอย่างเหล่านี้คือที่นี่ในแหล่งสำหรับฐานรหัส CLN ที่

สิ่งรบกวนอื่น ๆ

Fedora

ใน Fedora ฉันต้องดาวน์โหลด tarball ต้นฉบับและสร้างด้วยตัวเอง แต่มันสร้างด้วยความยุ่งยากเล็กน้อย ไม่ว่าจะด้วยเหตุผลใดก็ตามแพ็คเกจclnใน Fedora มีเพียงแค่ห้องสมุด แต่ละเลยตัวอย่างที่มีอยู่ในรุ่น Debian / Ubuntu (ด้านบน)

โค้ง

ประตูชัยให้โปรแกรมเดียวกันในแพคเกจ (ขอบคุณAmphiteót )cln


ใช่ฉันหมายถึงมูลค่ารวมที่ฉันเพิ่งพิมพ์สิ่งที่ฉันมีในหัวของฉัน
DisplayName

2
"มูลค่ารวม" ?? หมายความว่าอะไร...?
Kyle Strand

2
@DisplayName อ่านคำตอบที่เหลือ โปรแกรมเฉพาะเช่นpiเสียงเหมือนสิ่งที่คุณกำลังมองหา คุณสามารถทำสิ่งต่าง ๆ เช่นpi 300พิมพ์ตัวเลข 300 ตัวแรก
terdon

3
@ KyleStrand ฉันได้ค้นพบคำตอบที่ยิ่งใหญ่อย่างแท้จริงซึ่งความคิดเห็นนี้แคบเกินไปที่จะมี เฮ้มันใช้ได้กับแฟร์มาต์ !
terdon

ฉันชอบที่จะรู้ว่าทำไมสิ่งนี้ถึงได้รับสอง downvote คนที่ลงคะแนนไม่ได้อ่านคำตอบก่อนที่จะตัดสินใจว่ามันไม่มีประโยชน์หรือไม่?
CVn

17

มากถึงหนึ่งล้านหลักคุณสามารถใช้ต่อไปนี้ (ที่นี่สำหรับ 3000 หลัก):

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

2
สิ่งนี้มีประโยชน์เพิ่มเติมที่ควรอยู่ใกล้กับความซับซ้อน O (1) อย่างสมเหตุสมผล หรืออาจจะไม่เป็นประโยชน์เลย ...
CVn

7
นอกจากนี้ยังเป็นการยากที่จะบอกว่าปฏิสัมพันธ์เครือข่ายใด ๆ คือความซับซ้อนของเวลา O (1) ในโลกที่ใช้งานได้จริง : P
HalosGhost

2
@HalosGhost สำหรับจุดประสงค์ของเรา (เมื่อเทียบกับการคำนวณnหลักของ pi ในแต่ละครั้ง) การดาวน์โหลดข้อมูลจำนวนคงที่จากเซิร์ฟเวอร์เฉพาะผ่านเครือข่ายน่าจะมีประสิทธิภาพ O (1) ในขณะที่การคำนวณnหลักของ pi น่าจะเป็นอย่างน้อยก็อย่าง O (log n) และค่อนข้างสูงกว่า (ฉันไม่คุ้นเคยกับอัลกอริธึมเหล่านั้น) การดาวน์โหลดข้อมูลจริงอาจใช้เวลานานกว่าค่าโสหุ้ยในการเริ่มต้นการดาวน์โหลดดังนั้นเวลาในการดาวน์โหลดจะเพิ่มขึ้นและคุณจะอยู่ที่ไหนสักแห่งในบริเวณใกล้เคียงของ O (1) เนื่องจากอัตราการส่งข้อมูลคงที่พอสมควร ดังนั้น O (1)
CVn

4
@ MichaelKjörlingเมื่อคุณพูดว่า O (1) คุณไม่ได้หมายถึง O (n) จริงหรือ เวลาดาวน์โหลดเป็นเส้นตรงตามจำนวนหลักที่คุณต้องการดังนั้น O (n)
CodesInChaos

1
@CodesInChaos ไม่เวลาในการดาวน์โหลดเป็นค่าคงที่ (กำหนดอัตราการส่งข้อมูลคงที่) เพราะคุณกำลังดาวน์โหลดตัวเลขจำนวนคงที่ (หนึ่งล้านที่นี่) ยกเว้น (ในกรณีนี้) curl ฉลาดพอที่จะพิมพ์ในขณะที่ดาวน์โหลดและหยุดการดาวน์โหลดเมื่อท่อแตกเพราะcutออก? หากเป็นกรณีนี้ฉันยอมรับมันจะเป็น O (n)
CVn

15

คำตอบอื่น ๆ บางส่วนแสดงตัวเลขที่ไม่ถูกต้องในตำแหน่งสุดท้ายของผลลัพธ์ ด้านล่างนี้เป็นรูปแบบของคำตอบที่ใช้bcแต่มีผลลัพธ์ที่ถูกต้อง ตัวแปรsประกอบด้วยจำนวนของตัวเลขที่มีนัยสำคัญ (รวมถึง3ด้านหน้าของจุดทศนิยม)

ปัดครึ่งขึ้น

$ 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

คำอธิบายของการปัดเศษ

bcปัดเศษจะดำเนินการโดยตรงใน สิ่งนี้ไม่มีข้อ จำกัด ของคำสั่งprintfที่ใช้การแทนค่าdoubleชนิดภาษา C สำหรับตัวเลขที่มีความแม่นยำประมาณ 17 หลักสำคัญ ดูคำตอบที่มีprintfการปัดเศษ

scale=s-1ตั้งค่าจำนวนหลักเพื่อตัดให้เป็น pi/1หารผลลัพธ์ด้วย 1 เพื่อใช้การตัด Simple piไม่ตัดทอนตัวเลข

การปัดเศษครึ่งขึ้นต้องเพิ่ม 5 หลักแรกซึ่งจะถูกตัดออก (5 × 10- s ) ดังนั้นในกรณีที่ตัวเลขที่สูงกว่าเท่ากับ 5 หลักสุดท้ายซึ่งจะยังคงเพิ่มขึ้น

จากการทดสอบโดย hobbsดูเหมือนว่าตัวเลขสามหลักเพิ่มเติมซึ่งจะถูกปัดเศษ / ตัด ( scale=s+2) จะพอเพียงสำหรับตัวเลขที่ยาวมาก

นี่คือสตริง

ตัวอย่างข้างต้นการใช้งานที่นี่สตริงซึ่งได้รับการสนับสนุนเช่นในbash, และksh zshหากเชลล์ของคุณไม่รองรับการใช้สตริงechoและไพพ์แทน:

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

2
การคำนวณตัวเลขสามหลักเพิ่มเติมเพื่อจุดประสงค์ในการปัดเศษไม่ใช่ "การปัดเศษที่ถูกต้อง" ตามที่คุณอ้างสิทธิ์ในความคิดเห็น ก่อนอื่นคุณไม่มีข้อผูกมัดกับข้อผิดพลาดของการคำนวณ หากสามารถผิดได้ 3 ยูนิตในตำแหน่งสุดท้ายตามที่อ้างสิทธิ์โดย fduff เหตุใดจึงไม่ผิด 1000 หน่วยในตำแหน่งสุดท้าย ประการที่สองดู“ ภาวะที่กลืนไม่เข้าคายไม่ออกของผู้ผลิตโต๊ะ”
ซับซ้อนดูชีวภาพ

12

Perl หนึ่งบรรทัด (ใช้bignum ):

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

เช่น

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

สำหรับ 10.000 หลัก: ใกล้กับ 8 นาทีใน perl, น้อยกว่า 4 ใน bc ไม่ใช่วิธีที่เร็วที่สุด
ไอแซค

9

ด้วย python2:

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

4
เพื่อประโยชน์ของความครบถ้วนสมบูรณ์โซลูชันนี้ใช้เฉพาะ python2
HalosGhost

หลังจากแก้ไขด้วยการ(..)ทำงานใน Python 2 และ 3 ดูเหมือนว่าจะมี 12 หลักเท่านั้น
Anthon

$ หลาม -c "คณิตศาสตร์นำเข้าพิมพ์ (รูปแบบ (Math.PI '.400f'))" 3,1415926535897931159979634685441851615905761718750000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Artem Shitov

1
@ArtemShitov - เลวของฉันลองนำเข้าgmpy2python -c "import gmpy2; print(str(gmpy2.const_pi(8192))[:400])" (ถ้าคุณได้ติดตั้ง): เพิ่มความแม่นยำสำหรับตัวเลขเพิ่มเติม ... เช่นpython -c "import gmpy2; print(str(gmpy2.const_pi(16384))[:4400])"
don_crissti

1
เร็วที่สุดที่ฉันสามารถหาได้คือfrom mpmath import mp; mp.dps = 1000000 ; print(mp.pi)เพียงไม่กี่วินาทีสำหรับตัวเลขล้าน ไม่เลวเลย !!!
ไอแซค

7

ใช้ทับทิม:

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

ในทุบตี:

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

afmtoditต้องgroffติดตั้ง@ Amphiteóth ที่นี่บน Ubuntu (& รสชาติ) ไม่ใช่มาตรฐาน JFYI
ไวยากรณ์

@syntaxerror ขอบคุณจุดดี! ฉันลบตัวอย่างแล้ว ประเด็นของฉันคือเมื่ออ่าน AI นี้grepบนระบบของฉันเพื่อค้นหาค่าคงที่และพบว่ามันอยู่ในสถานที่มากกว่าหนึ่งแห่ง นั่นเป็นสาเหตุที่ +1 สำหรับฉัน!


3

ฉันคิดถึงคำถามนี้ได้อย่างไร ...

นี่เป็นโปรแกรม Python pi เล็กน้อยของฉันที่ฉันโพสต์เมื่อไม่กี่สัปดาห์ที่ผ่านมาใน Stack Overflow มันไม่ได้โดยเฉพาะอย่างยิ่งได้อย่างรวดเร็ว แต่ก็สามารถทำจำนวนมากของตัวเลข :) อย่างไรก็ตามตามที่ฉันกล่าวถึงในหัวข้อนั้นโดยทั่วไปฉันใช้โมดูล mpmath ของ Python สำหรับการคำนวณทางคณิตศาสตร์ที่มีความแม่นยำตามอำเภอใจและ mpmath มีผู้สร้าง pi ที่ค่อนข้างเร็ว

เช่น,

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

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

500000 ทศนิยมของ pi ภายใน 5 วินาทีนั้นไม่โทรมเกินไป IMHO เมื่อพิจารณาว่ามันทำงานบนเครื่องที่มีหน่วยประมวลผล 2GHz แกนเดียว, RAM 2 กิ๊กและเขียนไปยังไดรฟ์ IDE รุ่นเก่า


ลองfrom mpmath import mp; mp.dps = 1000000 ; print(mp.pi)(หลังจากติดตั้ง pip3 mpmath) ภายในสองวินาทีเพื่อรับหน่วยหลักล้าน ไม่เลวเลย !!!
Isaac

2

หากคุณnode.jsติดตั้งสิ่งนี้จะทำให้ดีที่สุดในการค้นหา pi ให้คุณ

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

ตัวอย่างผลลัพธ์:

3.14157749
3.1416426
3.14159055
3.14171554
3.14176165
3.14157587
3.14161137
3.14167685
3.14172371

4
สั้นnode -e 'console.log(Math.PI)'กว่าดีกว่าเล็กน้อย
chbrown

1
@chbrown ที่ไม่เป็นไปตามข้อกำหนดของ "ไม่ร้ายแรง"
พอล

1
ข้อกำหนด "ไม่จริงจัง" คืออะไร? OP เพิ่งกล่าวว่าพวกเขากำลังขอความสนุกไม่ใช่ว่าพวกเขาต้องการคำตอบที่ "ไม่จริงจัง" นั่นหมายความว่าอย่างไร สิ่งที่ชอบecho pie?
terdon

ฉันพิมพ์เพราะเมื่อคุณถามคำถามบางครั้งคนพูดว่า "นี่ไม่ใช่โรงงานเขียนสคริปต์" ดังนั้นฉันจึงบอกว่าเพราะไม่มีเหตุผลที่แท้จริงสำหรับมันฉันแค่อยากรู้วิธีพิมพ์ปี่
DisplayName

@ Amphiteóthใช้เวลาประมาณ 20 วินาทีในการทำงานบนคอมพิวเตอร์ของฉัน คุณอาจต้องให้เวลาสักครู่
พอล

2

วิธีมอนติคาร์โล

ดูตัวอย่างนี้สำหรับคำอธิบายของวิธีนี้

คำเตือน

  • ไม่ถูกต้องตามอำเภอใจ
  • ใช้เวลานานในการรวมเข้ากับสิ่งที่มีประโยชน์

ข้อดี

สนุก :-)

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

หมายเหตุ: ฉันพยายามครั้งแรกโดยไม่ต้องsrandติดอยู่กับที่3.14และหลังจากนั้นตัวเลขก็ยังคงสั่นอยู่ไม่เคยมาบรรจบกัน อาจเป็นเพราะหลังจากนั้นไม่นาน PRNG ก็เริ่มทำซ้ำตัวเอง การใช้srandจะหลีกเลี่ยงอย่างนั้นหรืออย่างน้อยก็ยืดระยะเวลาของลำดับหลอกสุ่ม นี่คือการคาดเดาทั้งหมดดังนั้นโปรดแก้ไขให้ฉันถ้าฉันผิด


@ Amphiteótไม่แน่ใจจริงๆว่าเกิดอะไรขึ้นที่นั่น ถ้าช่วย Perl ของฉันคือ v5.14.2 ฉันไม่เชี่ยวชาญbignumในการดำเนินการใน Perl ฉันกลัวและไม่รู้ส่วนใด ๆ ของโปรแกรมข้างต้นที่ต้องใช้ Perl รุ่นใหม่ อย่างไรก็ตามสิ่งที่น่าสนใจเกี่ยวกับเรื่องนี้ก็คืออัลกอริธึมเอง ลองใช้มันในภาษาที่คุณเลือกถ้า Perl นี้ไม่ได้ผลสำหรับคุณ
โจเซฟอาร์

1
@ Amphiteótฉันเห็น การแก้ไขแก้ปัญหาของคุณหรือไม่?
โจเซฟอาร์

@ Amphiteótคุณสามารถลองเพิ่ม($x,$y,$circle,$not_circle)=(0,0,0);ก่อนที่จะวนรอบเพื่อให้แน่ใจว่าตัวแปรทั้งหมดจะถูกกำหนดไว้ก่อนที่จะถูกนำมาใช้
โจเซฟอาร์

@ Amphiteótความผิดพลาดของฉัน parens (0,0,0,0)ข้างต้นควรจะได้รับ
โจเซฟอาร์

Re นี้ /5.20.1: เหมาะสม แต่ไม่เห็น! ($x,$y,$circle,$not_circle)=(0,0,0,0)จริง หลังจากหนึ่งหรือสองนาทีมันแขวนอยู่รอบ ๆ ค่าที่ต้องการจากนั้นมันก็เข้าใกล้ 3.1409 ก่อนที่ฉันจะหยุด น่าสนใจและสนุก! ขอขอบคุณ!

2

คุณสามารถใช้อัลกอริทึมเดือยสำหรับ pi โปรแกรม C ต่อไปนี้โดย Dik Winter และ Achim Flammenkamp จะสร้าง pi จำนวน 15,000 หลักแรกต่อครั้ง

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

บริบท: วิกิพีเดีย , ที่นี่และที่นี่

1
ฉันชอบอัลกอริธึมหัวจุกสำหรับค่าคงที่แบบลอการิทึมโดย Borwein, Bailey และ Plouffe อย่างไรก็ตามนี่ไม่ใช่รหัสกอล์ฟดังนั้นฉันจะปรับปรุงความสามารถในการอ่านรหัสของคุณโดยการฟอร์แมตใหม่หรือไม่ นอกจากนี้โปรดทราบว่าอัลกอริทึมแบบ BPP สามารถส่งออกหลักสำหรับ pi ในฐานที่เป็นพาวเวอร์ 2 อย่างน้อยโดยไม่ต้องใช้หน่วยความจำเพิ่มเติม
Franki

@Franki การจัดรูปแบบรหัสเปลี่ยนความหมายหรือความตั้งใจของโพสต์หรือไม่? หากไม่เป็นเช่นนั้นควรจะใช้ได้ (และการแก้ไขสามารถย้อนกลับได้ตลอดเวลา) ฉันไม่เห็นว่า deobfuscating รหัสบางอย่างสามารถทำอย่างอื่นได้มากกว่าการชี้แจง
11684

1
@syntaxerror มันคือการผลิต 15,000 หลักก่อนที่จะหยุด เอาท์พุทในครั้งที่สองสำหรับวง - ผลิต 4 หลักของปี่และลดจำนวนลึกลับของ 52514 โดย 14 จากนั้นสมการจะเป็น 4 * (52514/14) ซึ่งเท่ากับ 1,5004 14 ค่าสุดท้ายในอาร์เรย์จะถูกละเว้นที่จะ ได้รับประโยชน์จากโทเค็นน้อยลงเพื่อรับค่าที่แน่นอนของเรา 15,000
Daniel Henneberger

1
@ 11684 ไม่จริง ๆ แล้วมันจะไม่เปลี่ยนความหมายหรือความตั้งใจของรหัส อย่างไรก็ตามฉันรู้ว่านี่ไม่ใช่อัลกอริธึมเดือยสำหรับ BB แบบ pi แต่เป็นอีกวิธีหนึ่งที่คนอื่นได้ deobfuscated แล้วที่นี่stackoverflow.com/a/25837097
Franki

2

PHP

ตัวอย่างไม่กี่:

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

หากคุณต้องการเปลี่ยนความแม่นยำลอง:

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

ขนาดของการลอยขึ้นอยู่กับแพลตฟอร์มแม้ว่าสูงสุด ~ 1.8e308 ที่มีความแม่นยำประมาณ 14 หลักทศนิยมเป็นค่าทั่วไป (รูปแบบ IEEE 64 บิต) [อ่านเพิ่มเติม]


หากคุณกำลังมองหาความแม่นยำที่แม่นยำยิ่งขึ้นให้ตรวจสอบRosetta CodeหรือCode Golf SEสำหรับวิธีแก้ไขปัญหาการเขียนโปรแกรมบางอย่าง

ที่เกี่ยวข้อง: ซอฟต์แวร์ที่สามารถคำนวณ PI อย่างน้อยหนึ่งพันหลักที่ SR.SE


1

นี่คือสคริปต์ที่พิมพ์ pi ตามจำนวนตัวเลขที่ระบุ (รวมถึง '.') โดยผู้ใช้

pi.sh

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

เอาท์พุต

$ ./pi.sh 10
3.14159265

และมีค่าเริ่มต้น:

$ ./pi.sh
3.14159

ฉันเคยเห็นคนที่ใช้scaleเป็นbcตัวเลือก แต่ในกรณีของฉัน ( bc 1.06.95) สิ่งนี้จะไม่ส่งออกค่าที่ถูกต้อง:

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

สังเกตุตัวเลขตัวสุดท้าย


4
คำถามกล่าวว่า "ฉันต้องการระบุจำนวนหลักที่พิมพ์" ซึ่งพูดอย่างเคร่งครัดคลุมเครือ - แต่ฉันคิดว่าคำตอบของคุณล้มเหลว (ตามหลักวิชาการ) ภายใต้การตีความที่สมเหตุสมผล คุณพิมพ์เก้าตัวเลขนับเริ่มต้น./pi.sh 10 3นอกจากนี้คุณกำลังชี้นิ้วของข้อผิดพลาดในการปัดเศษ แต่./pi.sh 6ผลลัพธ์ของคุณ3.1415ซึ่งอาจไม่เหมาะสม
G-Man กล่าวว่า 'Reinstate Monica'

จากหน่วยความจำscale=Xตัวเลือกของbcจะไม่ปัดเศษตัวเลข แต่เพียงตัดเลขทศนิยมที่สิบหลัก
ไวยากรณ์

1

ฉันชอบคำตอบของ Abey แต่ไม่ชอบวิธีที่ bc เปลี่ยนเลขหลักสุดท้าย

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

ดังนั้นฉันจึงลบสเกลที่ใช้ printf เพื่อตั้งค่าจำนวนหลัก

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

คุณสังเกตไหมหลังจากสเกล 62 หลักแล้วพวกมันทั้งหมด 0 แต่สิ่งนี้ไม่ได้เกิดขึ้นกับคำสั่งดั้งเดิม

2
@ Amphiteót, นั่นเป็นเพราะprintfมีข้อ จำกัด bcอย่างรุนแรงในตัวเลขลอยจุดเมื่อเทียบกับ พวกเขาจะถูกแสดงด้วยภาษา C doubleประเภทที่ มีความแม่นยำประมาณ 17 หลักดังนั้นแม้ตัวเลขที่ไม่ใช่ศูนย์หลังจากที่ 17 เกี่ยวกับปลอม! ------ ผมได้เพิ่มคำตอบกับการปัดเศษที่ถูกต้องของผลที่ได้โดยไม่ จำกัด printf------ เพื่อให้แน่ใจว่าคำสั่งนี้ใช้ได้กับตำแหน่งที่ตั้งต่าง ๆ คุณต้องทำสิ่งนี้: LC_ALL=C printf...
pabouk

1

เกิดอะไรขึ้นถ้าคุณไม่สามารถสำหรับชีวิตของคุณจำไว้ว่านี้arctanสิ่งที่? หรือสมมุติว่าคุณไม่รู้ด้วยซ้ำว่ามีฟังก์ชั่นนี้อยู่bcจากนั้นลองจดจำการหารง่ายๆนี้:

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

จะใช้งานได้เพียง 6 หลัก แต่สำหรับการคำนวณที่ไม่ใช่ทางวิทยาศาสตร์จะทำได้ดี

หากคุณคิดว่าคุณจำตัวเลขสองตัวนี้ไม่ได้ให้เขียนตัวส่วนก่อนจากนั้นจึงเป็นตัวเศษ:

113 355

หรือทำไมไม่

11 33 55

"double 1, double 3, double 5" ตัวเลขทั้งหมดเป็นเลขคี่ ในการคำนวณให้แบ่งจำนวน 6 หลักครึ่งและสลับส่วนและตัวเศษก่อนหาร เกี่ยวกับมัน.


เท่าที่ฉันกังวลฉันพบว่า4 * arctan(1)ง่ายมากที่จะจำว่าตัวเลขสามหลัก 2 ตัว ... ฉันจะใช้ 335 แทน 355 หรือ 133 แทน 113 ได้อย่างง่ายดาย
John WH Smith

ฉันคิดว่ามันเป็นเรื่องของความชอบส่วนตัว :) คน (อย่างฉัน) ที่สามารถจดจำหมายเลขโทรศัพท์ (โทรศัพท์พื้นฐาน!) ได้อย่างง่ายดายจะสามารถจดจำหมายเลขสองหมายเลขได้เช่นเดียวกับหมายเลขโทรศัพท์เดียว นอกจากนี้ยังจะช่วยให้ผู้คนที่โรงเรียนรู้สึกว่าตรีโกณมิติจะต้องถูกสร้างขึ้นด้วยพลังชั่วร้าย
ไวยากรณ์เมื่อ

1

มันสามารถสันนิษฐานได้ว่า OP มีความสนใจในคำสั่งเชลล์สั้น ๆ และง่ายต่อการจดจำเพื่อพิมพ์π - แต่คำถามไม่ได้พูดอย่างนั้น คำตอบนี้ละเลยข้อสันนิษฐานนั้นและตอบคำถามอย่างเคร่งครัดตามที่เขียนไว้;

จิ๊บจ๊อย?

ในขณะที่มีคำตอบอยู่แล้ว 18 คำตอบแนวทางหนึ่งยังคงหายไป - และด้วยคำตอบมากมายมันอาจคิดว่ามันไม่ใช่วิธีเดียวที่ขาดหายไป:
ความรู้เล็กน้อย: วิธีการพิมพ์π? เพียงพิมพ์π!

วิธีการนั้นดูเหมือนจะไร้ประโยชน์เกินกว่าที่จะคิดเกี่ยวกับมัน แต่ฉันจะแสดงให้เห็นว่ามันมีความสนุกสนาน:

เพิ่มประสิทธิภาพ

ปกติแล้วเราจะคำนวณค่าของπ ฉันไม่เห็นสิ่งที่ทำให้เราไม่สามารถเพิ่มประสิทธิภาพโซลูชันโดยการคำนวณค่าล่วงหน้า - เป็นค่าคงที่คอมไพเลอร์ใด ๆ จะทำเช่นนั้น

เราต้องการตัวเลขจำนวน of บางส่วนเพื่อความแม่นยำสูงสุด ดังนั้นเราจึงสามารถใช้คำนำหน้าของค่าคงที่เป็นข้อความ:

echo 3.1415926535897932384626433832795 | cut -b -7
3.14159

ตัวแปรที่มีอาร์กิวเมนต์ชัดเจนสำหรับความแม่นยำเช่น เพื่อความแม่นยำ5:

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

ข้อดี

ความแม่นยำสูงสุดสามารถเลือกได้เองโดยใช้ค่าคงที่ที่เหมาะสมซึ่งคำนวณโดยใช้หนึ่งในคำตอบอื่น มันถูก จำกัด ด้วยความยาวสูงสุดของบรรทัดคำสั่ง
มันมีความซับซ้อนของเวลาคงที่สำหรับการค้นหาค่า
มันทำให้ข้อ จำกัด และข้อ จำกัด ทั้งหมดชัดเจนขึ้นอยู่กับความซับซ้อนต่ำของการใช้งาน
มันจัดการกับความแม่นยำที่ใหญ่กว่าค่าสูงสุดอย่างสง่างามโดยการคืนค่าคงที่ในความแม่นยำเต็มรูปแบบที่มีอยู่ (โดยไม่ต้องต่อท้าย0)
ดังนั้นวิธีแก้ปัญหานี้ในขณะที่เล็กน้อยก็มีข้อดี มันอาจมีประโยชน์เมื่อมันถูกใช้ในฟังก์ชันเชลล์เช่น

ต่ำสุด

ฟังก์ชันการทำงานของโซลูชันด้านบนสามารถใช้งานได้โดยไม่ต้องสร้างกระบวนการสำหรับcut(สมมติว่าechoเป็นเชลล์ในตัว) มันใช้คำสั่งprintf(ปกติเป็น builtin) ในทางที่ค่อนข้างคลุมเครือ:
ค่าคงที่จะถูกจัดเรียงอย่างสมบูรณ์เป็นสตริง (รูปแบบที่ใช้%s) ไม่มีจุดลอยตัวที่เกี่ยวข้องกับคณิตศาสตร์ดังนั้นข้อ จำกัด ของfloatหรือdoubleไม่ใช้ที่นี่
ค่าความแม่นยำของการ%sหลบหนี ( 5ในตัวอย่างด้านล่าง) ระบุความยาวของคำนำหน้าสตริงที่จะพิมพ์ - ซึ่งเป็นความแม่นยำ 3.เป็นส่วนหนึ่งของprintfรูปแบบที่จะให้มันออกมาจากการคำนวณที่มีความแม่นยำ

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

ทางเลือกที่มีความแม่นยำเป็นอาร์กิวเมนต์แยกต่างหาก:

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

หรือสามารถอ่านได้มากขึ้นเล็กน้อย (โปรดสังเกตช่องว่างระหว่าง3.และกับ14159...พวกเขาเป็นอาร์กิวเมนต์ที่แยกต่างหาก):

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

รวดเร็ว

การใช้ตัวแปรprintfสามารถคาดว่าจะเร็วมาก: เนื่องจากprintfเชลล์มีอยู่แล้วภายในเชลล์ทั่วไปbashและzshไม่สร้างกระบวนการใด ๆ
นอกจากนี้มันจะไม่แตะต้องรหัสที่เกี่ยวข้องกับจุดลอยตัวใด ๆ แต่จะจัดการเฉพาะอาร์เรย์ไบต์เท่านั้น (ไม่ใช่อักขระหลายไบต์อย่างชัดเจน) โดยทั่วไปแล้วจะเร็วกว่าหรือเร็วกว่าการใช้จุดลอยตัวมาก

ความเข้ากันได้ printf

บ่อยครั้งมีเหตุผลที่จะแทนที่ printfด้วย /usr/bin/printfเพื่อรับประกันความสอดคล้องหรือเข้ากันได้ ในกรณีนี้ฉันคิดว่าเราสามารถใช้ builtin ซึ่งเป็นสิ่งสำคัญเนื่องจากการใช้/usr/bin/printfช่วยลดข้อได้เปรียบ "เร็ว" โดยการทำกระบวนการ
ปัญหาทั่วไปเกี่ยวกับprintfความเข้ากันได้คือรูปแบบเอาต์พุตตัวเลขขึ้นอยู่กับโลแคล การแยก.ตัวเลขสามารถเปลี่ยนแปลงได้,ตามการตั้งค่าภาษา แต่เราไม่ใช้ตัวเลขเพียงค่าคงที่สตริงที่มีตัวอักษร.- ไม่ได้รับผลกระทบจากสถานที่เกิดเหตุ
StéphaneChazelasชี้ให้เห็นว่าการprintf %.5sทำงานแตกต่างกันzshโดยการนับอักขระไม่ใช่ไบต์ตามปกติ โชคดีที่ค่าคงที่ของเราใช้เฉพาะอักขระในช่วง ASCII ที่ต่ำกว่าซึ่งถูกเข้ารหัสโดยหนึ่งไบต์ต่ออักขระในการเข้ารหัสที่เกี่ยวข้องตราบใดที่เราใช้การUTF-8เข้ารหัสทั่วไปสำหรับ Unicode ไม่ใช่การเข้ารหัสความกว้างคงที่


โปรดทราบว่าprintf %.5sเป็นถ่าน (ไม่ใช่ไบต์) ที่ใช้เป็น zsh (สมเหตุสมผล แต่ต่อ POSIX) ksh93's %.5Lsเป็น graphem based
Stéphane Chazelas
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.