Apakah ada signifikansi khusus untuk 16331239353195370.0?

88

Menggunakan import numpy as npSaya telah memperhatikan itu

np.tan(np.pi/2)

memberi nomor pada judul dan bukan np.inf

16331239353195370.0

Saya penasaran dengan nomor ini. Apakah ini terkait dengan beberapa parameter presisi mesin sistem? Bisakah saya menghitungnya dari sesuatu? (Saya sedang memikirkan sesuatu yang mirip dengan sys.float_info)

EDIT: Hasil yang sama memang dapat direproduksi di lingkungan lain seperti Java, oktase, matlab ... Namun, penipuan yang disarankan tidak menjelaskan mengapa.

Seorang pria
sumber
10
Saya tidak suka jawaban itu - itu sepenuhnya bergelombang, tidak benar-benar menjelaskan penyebabnya. "Nah, tan (pi / 2) dalam radian pada dasarnya tidak terbatas, bukan?" tidak menjelaskan apa-apa tentang mengapa - sebagai OP bertanya di sini - jawabannya tidak sebenarnya np.inf. Tetapi mudah untuk tidak hanya menjelaskan mengapa tidak, tetapi juga menjelaskan mengapa jawabannya persis seperti yang terlihat - dan jadi saya melakukannya ;-)
Tim Peters

Jawaban:

119

pitidak dapat direpresentasikan sebagai float Python (sama seperti tipe platform C double). Pendekatan terdekat yang dapat direpresentasikan digunakan.

Berikut perkiraan yang tepat digunakan di kotak saya (mungkin sama seperti di kotak Anda):

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

Untuk menemukan tangen rasio itu, saya akan beralih ke wxMaxima sekarang:

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

Jadi pada dasarnya identik dengan apa yang Anda dapatkan. Perkiraan biner yang pi/2digunakan sedikit lebih kecil dari nilai matematis ("presisi tak terbatas") pi/2. Jadi, Anda mendapatkan garis singgung yang sangat besar, bukan infinity. Penghitungan tan()sesuai untuk input aktual!

Untuk jenis alasan yang persis sama, misalnya,

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

tidak mengembalikan 0. Pendekatannya math.pisedikit kurang dari pi, dan hasil yang ditampilkan benar mengingat kebenaran itu.

CARA LAIN MELIHAT math.pi

Ada beberapa cara untuk melihat perkiraan yang tepat yang digunakan:

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

math.pi sama persis dengan nilai matematika ("presisi tak terbatas") dari rasio itu.

Atau sebagai pelampung yang tepat dalam notasi hex:

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

Atau dengan cara yang paling mudah dipahami oleh hampir semua orang:

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

Meskipun mungkin tidak langsung terlihat jelas, setiap pelampung biner hingga persis dapat direpresentasikan sebagai pelampung desimal hingga (kebalikannya tidak benar; misalnya desimal 0.1tidak dapat secara tepat dapat direpresentasikan sebagai pelampung biner hingga), dan Decimal(some_float)konstruktor menghasilkan padanan yang tepat.

Inilah nilai sebenarnya dari pidiikuti dengan nilai desimal yang tepat dari math.pi, dan tanda sisipan pada baris ketiga menunjuk ke digit pertama yang berbeda:

true    3.14159265358979323846264338327950288419716939937510...
math.pi 3.141592653589793115997963468544185161590576171875
                         ^

math.pisekarang sama di "hampir semua" kotak, karena hampir semua kotak sekarang menggunakan format titik mengambang biner yang sama (presisi ganda IEEE 754). Anda dapat menggunakan salah satu cara di atas untuk mengonfirmasi hal itu pada kotak Anda , atau untuk menemukan perkiraan yang tepat digunakan jika kotak Anda merupakan pengecualian.

Tim Peters
sumber
@ Tim Peters - Ini sangat jelas. Untuk kelengkapan, saya menduga bahwa representasi ini np.piadalah representasi rasional yang paling dekat dengan dalam epsilon sistem?
Aguy
3
Dengan asumsi np.pimemiliki nilai yang sama dengan Python math.pi(saya tidak memeriksanya, tetapi Anda bisa ;-)), itu adalah nilai terdekat dengan pi matematika yang dapat direpresentasikan dalam C doubleformat floating-point asli platform . Yang berarti presisi ganda IEEE 754 di hampir semua kotak sekarang, dan begitu juga float biner terdekat dengan presisi 53 bit (mantissa). Jadi himpunan rasio dibatasi ke bentuk di +/- I * 2**Jmana bilangan bulat Iadalah 0 atau 2**52 <= I < 2**53, dan kisaran bilangan bulat Jcukup luas untuk mencakup semua rasio bentuk ini di mana saja pi.
Tim Peters
2
Dan inilah mengapa saya ingin sekali jika fungsi trigonometri "biner" lebih umum diterapkan. Karena pi tidak pernah dapat direpresentasikan secara rasional, itu akan berguna dengan serangkaian fungsi yang beroperasi pada sudut dari 0 hingga 1.
pipa
Ya, mereka mengimpor np.pi, bukan math.pi.
EKons
2
@ Έρικ Κωνσταντόπουλος math.pi, np.pidan scipy.pisemuanya sama; mereka digandakan hanya untuk kenyamanan penamaan; stackoverflow.com/questions/12645547/…
Tim Peters