Numpy: np.left_shift dan np.right_shift gagal pada jenis skalar np.uint64 (Trac # 1931)

Dibuat pada 20 Okt 2012  ·  7Komentar  ·  Sumber: numpy/numpy

_Tiket asli http://projects.scipy.org/numpy/ticket/1931 pada 2011-08-10 oleh pengguna trac tlatorre, ditetapkan ke tidak diketahui._

>>> np.uint64(5) << 1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: ufunc 'left_shift' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule 'safe'
>>> np.uint64(5) >> 3
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: ufunc 'right_shift' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule 'safe'
00 - Bug numpy.core

Komentar yang paling membantu

Solusi yang lebih mudah adalah dengan menggunakan unsigned integer untuk shift:

np.uint64(5) << np.uint64(1)

Seperti yang disebutkan @charris di atas, masalahnya ada pada cara dtypes dibuat seragam. Tidaklah mudah untuk memperbaikinya secara umum (lihat juga # 5668), meskipun mungkin operator shift dapat menggunakan kasing khusus. (Humas menyambut, seperti yang dikatakan, ini tidak sepele, tetapi membutuhkan pemahaman yang adil tentang bagaimana loop internal di ufuc diputuskan ...).

Semua 7 komentar

_ @ charris menulis pada 2011-08-13_

Ini karena nomor shift diubah sebagai tipe bertanda dan tidak ada tipe bilangan bulat bertanda yang cukup besar untuk menampung uint64. Operator shift perlu menggunakan casing khusus, mereka juga bisa gagal di Intel karena hardware menutupi bit yang tidak diperlukan, yaitu untuk int32 hanya 5 bit yang lebih rendah yang dilihat.

_trac user parejkoj menulis pada 2012-07-27_

Saya bisa membuat kode di sekitar ini dengan lambda berikut:

lshift = lambda x,s: np.uint64(x)*np.uint64(2**s)

Ini berhasil, tetapi tidak ideal. Memperbaiki ini di numpy akan sangat berguna.

lima tahun kemudian ... bukankah ini masalah penting? bilangan bulat unsigned seharusnya tidak memiliki ambiguitas tentang pergeseran.

Solusi yang lebih mudah adalah dengan menggunakan unsigned integer untuk shift:

np.uint64(5) << np.uint64(1)

Seperti yang disebutkan @charris di atas, masalahnya ada pada cara dtypes dibuat seragam. Tidaklah mudah untuk memperbaikinya secara umum (lihat juga # 5668), meskipun mungkin operator shift dapat menggunakan kasing khusus. (Humas menyambut, seperti yang dikatakan, ini tidak sepele, tetapi membutuhkan pemahaman yang adil tentang bagaimana loop internal di ufuc diputuskan ...).

Solusi yang lebih mudah adalah dengan menggunakan unsigned integer untuk shift:

np.uint64 (5) << np.uint64 (1)

... yang berfungsi jika Anda tahu Anda beroperasi pada bilangan bulat numpy, tetapi jika Anda menggunakan kode generik (khususnya sesuatu yang telah ditulis di modul lain dan di luar kendali Anda) seperti

def f(x):
    return x | (x >> 1)

maka Anda tidak dapat membuatnya berfungsi pada bilangan bulat Python biasa dan jenis np.uint64.

Saya tidak mencoba untuk menyatakan bahwa ini sepele (wayyyy di atas keahlian saya) tetapi saya pikir itu harus menjadi prioritas tinggi.

@ jason-s - Saya setuju bahwa masalahnya sangat menjengkelkan ... Sayangnya, tidak banyak dari kita yang cukup paham tentang cara kerja ufunc secara internal ...

Mungkin seseorang dapat setidaknya menggunakan skalar kasus khusus untuk pergeseran metode, daripada mengandalkan mesin ufunc umum. @charris : apakah ini yang ada dalam pikiran Anda (jika Anda dapat mengingatnya setelah 6 tahun ;-).

Lihat juga # 8002.

Secara pribadi, jika kita bisa melakukan semuanya lagi, saya akan memilih mengulangi semua casting / paksaan sehingga casting numpy pada dasarnya berperilaku seperti casting C, dan mengikuti semangat C-casting untuk kasus-kasus yang tidak ada di C. Casting numpy aturannya agak aneh dan terkadang membingungkan (mis. konversi uint64 + int64 menjadi float64 ). Tapi kami telah banyak membahas ini di daftar, sepertinya sulit untuk diubah.

Ketika saya menemukan situasi seperti ini (lihat komentar saya di sana) saya hanya membungkus setiap nilai dalam np.uint64 .

Apakah halaman ini membantu?
0 / 5 - 0 peringkat