Có ý nghĩa đặc biệt đối với 16331239353195370.0 không?


88

Sử dụng import numpy as nptôi nhận thấy rằng

np.tan(np.pi/2)

cho số trong tiêu đề và không np.inf

16331239353195370.0

Tôi tò mò về con số này. Nó có liên quan đến một số thông số chính xác của máy hệ thống không? Tôi có thể đã tính toán nó từ một cái gì đó? (Tôi đang nghĩ về một thứ tương tự như sys.float_info)

CHỈNH SỬA: Kết quả tương tự thực sự có thể tái tạo trong các môi trường khác như Java, octace, matlab ... Tuy nhiên, bản dupe được đề xuất không giải thích tại sao.



10
Tôi không thích câu trả lời đó - nó hoàn toàn bằng tay, không thực sự giải thích nguyên nhân. "Chà, tan (pi / 2) tính bằng radian về cơ bản là vô hạn, phải không?" không giải thích bất cứ điều gì về lý do tại sao - như OP đã hỏi ở đây - câu trả lời không thực tế np.inf. Nhưng đó là đơn giản để không chỉ giải thích lý do tại sao nó không phải là, nhưng để cũng giải thích tại sao câu trả lời là chính xác những gì được nhìn thấy - và vì vậy tôi đã làm ;-)
Tim Peters

Câu trả lời:


119

pikhông thể đại diện chính xác như Python float (giống như kiểu của nền tảng C double). Giá trị gần đúng nhất có thể biểu diễn được sử dụng.

Đây là giá trị gần đúng được sử dụng trên hộp của tôi (có thể giống như trên hộp của bạn):

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

Để tìm tiếp tuyến của tỷ lệ đó, tôi sẽ chuyển sang wxMaxima bây giờ:

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

Vì vậy, về cơ bản giống hệt với những gì bạn nhận được. Giá trị xấp xỉ nhị phân pi/2được sử dụng nhỏ hơn một chút so với giá trị toán học ("độ chính xác vô hạn") của pi/2. Vì vậy, bạn nhận được một tiếp tuyến rất lớn thay vì infinity. Tính toán tan()phù hợp với đầu vào thực tế!

Vì những lý do giống hệt nhau, ví dụ:

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

không trả về 0. Giá trị gần đúng math.pinhỏ hơn một chút pivà kết quả được hiển thị là đúng với sự thật đó.

CÁC CÁCH KHÁC ĐỂ XEM math.pi

Có một số cách để xem giá trị gần đúng chính xác đang được sử dụng:

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

math.pi chính xác bằng giá trị toán học ("độ chính xác vô hạn") của tỷ lệ đó.

Hoặc như một float chính xác trong ký hiệu hex:

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

Hoặc theo cách dễ hiểu nhất đối với mọi người:

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

Mặc dù nó có thể không rõ ràng ngay lập tức, nhưng mọi số float nhị phân hữu hạn đều có thể biểu diễn chính xác dưới dạng float thập phân hữu hạn (điều ngược lại là không đúng; ví dụ: số thập phân 0.1không thể biểu diễn chính xác như float nhị phân hữu hạn) và hàm Decimal(some_float)tạo tạo ra giá trị tương đương chính xác.

Đây là giá trị thực của pitheo sau là giá trị thập phân chính xác của math.pivà một dấu mũ trên dòng thứ ba trỏ đến chữ số đầu tiên nơi chúng khác nhau:

true    3.14159265358979323846264338327950288419716939937510...
math.pi 3.141592653589793115997963468544185161590576171875
                         ^

math.pihiện nay trên hầu hết các hộp "hầu như tất cả" đều giống nhau, vì hầu hết tất cả các hộp hiện sử dụng cùng một định dạng dấu phẩy động nhị phân (độ chính xác kép IEEE 754). Bạn có thể sử dụng bất kỳ cách nào ở trên để xác nhận điều đó trên hộp của mình hoặc để tìm giá trị gần đúng chính xác đang được sử dụng nếu hộp của bạn là một ngoại lệ.


@Tim Peters - Điều này hoàn toàn rõ ràng. Để hoàn thiện, tôi đoán rằng biểu diễn np.pinày là biểu diễn hợp lý gần nhất với trong epsilon của hệ thống?
Aguy

3
Giả sử np.picó cùng giá trị với Python math.pi(tôi không kiểm tra, nhưng bạn có thể ;-)), thì đó là giá trị gần nhất với số pi toán học có thể biểu diễn ở C doubleđịnh dạng dấu phẩy động gốc của nền tảng . Điều đó có nghĩa là IEEE 754 có độ chính xác kép trên hầu hết tất cả các hộp hiện nay và do đó, số float nhị phân gần nhất với độ chính xác 53 bit (phần định trị). Vì vậy, tập hợp các số hữu tỷ bị giới hạn ở dạng +/- I * 2**Jtrong đó số nguyên Ilà 0 hoặc 2**52 <= I < 2**53, và phạm vi số nguyên Jđủ rộng để bao gồm tất cả các số hữu tỷ ở bất kỳ đâu gần đó pi.
Tim Peters

2
Và đây là lý do tại sao tôi rất thích nếu các hàm lượng giác "nhị phân" được triển khai phổ biến hơn. Kể từ pi không bao giờ có thể được biểu diễn một cách hợp lý, nó sẽ là tiện dụng với một tập hợp các chức năng hoạt động trên các góc độ từ 0 đến 1.
ống

Chà, họ nhập khẩu np.pi, không phải math.pi.
EKons

2
@ Έρικ Κωνσταντόπουλος math.pi, np.piscipy.piđều giống nhau; chúng được sao chép chỉ để tiện đặt tên; stackoverflow.com/questions/12645547/…
Tim Peters
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.