16331239353195370.0 มีความสำคัญเป็นพิเศษหรือไม่


88

การใช้import numpy as npฉันสังเกตเห็นว่า

np.tan(np.pi/2)

ให้หมายเลขในชื่อเรื่องไม่ใช่ np.inf

16331239353195370.0

ฉันอยากรู้เกี่ยวกับตัวเลขนี้ มันเกี่ยวข้องกับพารามิเตอร์ความแม่นยำของเครื่องจักรของระบบหรือไม่? ฉันสามารถคำนวณจากบางสิ่งได้หรือไม่? (ฉันกำลังคิดอะไรบางอย่างที่คล้ายกับsys.float_info)

แก้ไข:ผลลัพธ์เดียวกันนี้สามารถทำซ้ำได้ในสภาพแวดล้อมอื่น ๆ เช่น Java, octace, matlab ... การหลอกลวงที่แนะนำไม่ได้อธิบายว่าทำไม



10
ฉันไม่ชอบคำตอบนั้น - มันเป็นคลื่นมือโดยสิ้นเชิงไม่ได้อธิบายถึงสาเหตุจริงๆ "อืมตาล (pi / 2) ในหน่วยเรเดียนเป็นค่าอนันต์ไม่ใช่หรือ" ไม่ได้อธิบายอะไรเกี่ยวกับว่าทำไม - เป็น OP ถามนี่ - คำตอบไม่ได้np.infในความเป็นจริง แต่มันตรงไปตรงมาที่ไม่เพียง แต่อธิบายว่าทำไมจึงไม่เป็นเช่นนั้น แต่ยังอธิบายด้วยว่าทำไมคำตอบคือสิ่งที่เห็น - และฉันก็ทำเช่นนั้น
Tim Peters

คำตอบ:


119

piไม่สามารถแสดงเป็น Python float ได้อย่างแน่นอน (เช่นเดียวกับdoubleประเภทของแพลตฟอร์ม C ) มีการใช้การประมาณค่าที่แสดงได้ใกล้เคียงที่สุด

นี่คือการประมาณที่แน่นอนที่ใช้กับกล่องของฉัน (อาจจะเหมือนกับในกล่องของคุณ):

>>> import math
>>> (math.pi / 2).as_integer_ratio()
(884279719003555, 562949953421312)

ในการหาค่าแทนเจนต์ของอัตราส่วนนั้นตอนนี้ฉันจะเปลี่ยนเป็น wxMaxima:

(%i1) fpprec: 32;
(%o1) 32
(%i2) tan(bfloat(884279719003555) / 562949953421312);
(%o2) 1.6331239353195369755967737041529b16

โดยพื้นฐานแล้วก็เหมือนกับสิ่งที่คุณได้รับ ประมาณไบนารีpi/2ที่ใช้เป็นเล็กน้อยน้อยกว่ามูลค่าทางคณิตศาสตร์ ( "ความแม่นยำที่ไม่มีที่สิ้นสุด") pi/2ของ infinityเพื่อให้คุณได้สัมผัสขนาดใหญ่มากแทน การคำนวณtan()นั้นเหมาะสมกับการป้อนข้อมูลจริง!

ด้วยเหตุผลประเภทเดียวกันทุกประการเช่น

>>> math.sin(math.pi)
1.2246467991473532e-16

ไม่คืนค่า 0 ค่าประมาณmath.piน้อยกว่าเล็กน้อยpiและผลลัพธ์ที่แสดงจะถูกต้องเนื่องจากความจริงนั้น

วิธีอื่น ๆ ในการดู math.pi

มีหลายวิธีในการดูการประมาณที่แน่นอนในการใช้งาน:

>>> import math
>>> math.pi.as_integer_ratio()
(884279719003555, 281474976710656)

math.pi เท่ากับค่าทางคณิตศาสตร์ ("ความแม่นยำไม่มีที่สิ้นสุด") ของอัตราส่วนนั้น

หรือเป็นลอยที่แน่นอนในสัญกรณ์ฐานสิบหก:

>>> math.pi.hex()
'0x1.921fb54442d18p+1'

หรือในทางที่ทุกคนเข้าใจได้ง่ายที่สุด:

>>> import decimal
>>> decimal.Decimal(math.pi)
Decimal('3.141592653589793115997963468544185161590576171875')

แม้ว่าอาจจะไม่ชัดเจนในทันที แต่การลอยตัวไบนารีแบบ จำกัด ทุกครั้งสามารถแสดงได้ว่าเป็นทศนิยมที่แน่นอน (การย้อนกลับไม่เป็นความจริงเช่นทศนิยม0.1ไม่สามารถแสดงได้อย่างแน่นอนว่าเป็นเลขฐานสองแบบ จำกัด ) และตัวDecimal(some_float)สร้างจะสร้างค่าเท่ากัน

นี่คือค่าที่แท้จริงของpiตามด้วยค่าทศนิยมที่แน่นอนmath.piและเครื่องหมายคาเร็ตในบรรทัดที่สามจะชี้ไปที่ตัวเลขตัวแรกที่ต่างกัน:

true    3.14159265358979323846264338327950288419716939937510...
math.pi 3.141592653589793115997963468544185161590576171875
                         ^

math.piตอนนี้เหมือนกันในกล่อง "เกือบทั้งหมด" เพราะตอนนี้กล่องเกือบทั้งหมดใช้รูปแบบจุดลอยตัวไบนารีเดียวกัน (IEEE 754 double precision) คุณสามารถใช้วิธีใดก็ได้ข้างต้นเพื่อยืนยันสิ่งนั้นบนกล่องของคุณหรือค้นหาการประมาณที่แม่นยำในการใช้งานหากกล่องของคุณเป็นข้อยกเว้น


@ Tim Peters - นี่เป็นสิ่งที่ชัดเจน เพื่อความสมบูรณ์ฉันคาดเดาว่าการแสดงนี้เป็นการแสดงnp.piที่มีเหตุผลใกล้เคียงที่สุดกับภายใน epsilon ของระบบหรือไม่?
Aguy

3
สมมติว่าnp.piมีค่าเดียวกับ Python math.pi(ฉันไม่ได้ตรวจสอบ แต่คุณทำได้ ;-)) ซึ่งเป็นค่าที่ใกล้เคียงที่สุดกับค่า pi ทางคณิตศาสตร์ที่แสดงได้ในC doubleรูปแบบทศนิยมดั้งเดิมของแพลตฟอร์ม ซึ่งหมายความว่า IEEE 754 double-precision ในเกือบทุกกล่องในขณะนี้ดังนั้น binary float ที่ใกล้เคียงที่สุดโดยมีความแม่นยำ (mantissa) 53 บิต ดังนั้นชุดของ rationals เป็นข้อ จำกัด ในรูปแบบ+/- I * 2**Jที่เป็นจำนวนเต็มIคือ 0 หรือ2**52 <= I < 2**53และช่วงของจำนวนเต็มJเป็นวิธีที่กว้างพอที่จะครอบคลุม rationals piทั้งหมดของแบบฟอร์มนี้ที่ใดก็ได้ที่อยู่ใกล้
Tim Peters

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

ดีที่พวกเขานำเข้ามาไม่ได้np.pi math.pi
EKons

2
@ ΈρικΚωνσταντόπουλος math.pi, np.piและscipy.piมีทั้งหมดเดียวกัน; ซ้ำกันเพียงเพื่อความสะดวกในการตั้งชื่อ stackoverflow.com/questions/12645547/…
Tim Peters
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.