Cython trả về 0 cho biểu thức nên đánh giá là 0,5?


8

Vì một số lý do, Cython đang trả về 0 trên biểu thức toán học nên ước tính là 0,5:

print(2 ** (-1))  # prints 0

Thật kỳ lạ, trộn các biến vào và nó sẽ hoạt động như mong đợi:

i = 1
print(2 ** (-i))  # prints 0.5

Vanilla CPython trả lại 0,5 cho cả hai trường hợp. Tôi đang biên dịch 37m-x86_64-linux-gnulanguage_levelđược đặt thành 3.

Phù thủy này là gì?


Bạn đang sử dụng cài đặt biên dịch nào và bạn đang biên dịch phiên bản Python nào? Bạn language_levelđã thiết lập phiên bản Python mà bạn đang biên dịch chưa? (Sự không nhất quán có thể là một lỗi ngay cả khi bạn có sự không phù hợp giữa language_levelphiên bản Python và phiên bản Python của bạn, nhưng thông tin này rất quan trọng để chẩn đoán sự cố.)
user2357112 hỗ trợ Monica

Chỉnh sửa câu hỏi để bao gồm những chi tiết này. 10
iTayb

DavidW hoàn toàn đúng, bạn có thể thử chỉ sử dụng 1.0 để làm cho nó nổi: in (2 ** -1.0)
Fanto

Câu trả lời:


4

Đó là bởi vì nó sử dụng C int chứ không phải số nguyên Python nên nó phù hợp với hành vi C hơn là hành vi Python. Tôi tương đối chắc chắn điều này từng được ghi nhận là một giới hạn ở đâu đó nhưng tôi không thể tìm thấy nó ngay bây giờ. Nếu bạn muốn báo cáo đó là một lỗi, hãy truy cập https://github.com/cython/cython/issues , nhưng tôi nghi ngờ đây là sự đánh đổi có chủ ý về tốc độ để tương thích.

Mã được dịch sang

__Pyx_pow_long(2, -1L)

trong đó __Pyx_pow_longlà một chức năng của loại static CYTHON_INLINE long __Pyx_pow_long(long b, long e).


Cách dễ nhất để khắc phục là thay đổi một / cả hai số thành số dấu phẩy động

 print(2. ** (-1))

Như một nhận xét chung về lựa chọn thiết kế: mọi người từ thế giới C thường mong đợi được int operator inttrả lại intvà tùy chọn này sẽ nhanh nhất. Python đã cố gắng làm điều này trong quá khứ với hành vi phân chia Python 2 (nhưng không nhất quán - sức mạnh luôn trả về một số dấu phẩy động).

Cython thường cố gắng theo dõi hành vi của Python. Tuy nhiên, rất nhiều người đang sử dụng nó cho tốc độ nên họ cũng cố gắng quay lại các thao tác nhanh, giống như C, đặc biệt là khi mọi người chỉ định loại (vì những người đó muốn tốc độ). Tôi nghĩ những gì đã xảy ra ở đây là nó có thể tự động suy ra các loại và do đó được mặc định là hành vi C. Tôi nghi ngờ lý tưởng là nó nên phân biệt giữa các loại được chỉ định và các loại mà nó được suy ra. Tuy nhiên, có lẽ cũng đã quá muộn để bắt đầu thay đổi điều đó.


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.