Numpy: فشل np.left_shift و np.right_shift في أنواع عددية np.uint64 (تراك # 1931)

تم إنشاؤها على ٢٠ أكتوبر ٢٠١٢  ·  7تعليقات  ·  مصدر: numpy/numpy

_التذكرة الأصلية http://projects.scipy.org/numpy/ticket/1931 بتاريخ 2011-08-10 بواسطة trac user tlatorre ، المخصصة لـ unknown.

>>> 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

التعليق الأكثر فائدة

الحل الأسهل هو استخدام عدد صحيح بدون إشارة لإزاحة:

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

كما ذكر charris أعلاه ، فإن المشكلة تكمن في الطريقة التي يتم بها توحيد الأنواع. ليس من التافه أن يتم الإصلاح بشكل عام (انظر أيضًا # 5668) ، على الرغم من أنه ربما يمكن أن يكون مشغلو النقل بغلاف خاص. (نرحب بالعلاقات العامة ، كما قيل ، هذا ليس تافهًا ، ولكنه يتطلب فهمًا عادلًا لكيفية تحديد الحلقات الداخلية في ufucs ...).

ال 7 كومينتر

_ @ كتب

هذا لأن رقم الإزاحة يتم تحويله كنوع موقّع ولا يوجد نوع عدد صحيح بعلامة كبيرة بما يكفي لاستيعاب uint64. يحتاج مشغلو النقل إلى غلاف خاص ، ويمكن أن يفشلوا أيضًا في Intel لأن الأجهزة تخفي البتات غير الضرورية ، أي بالنسبة لـ int32 ، يتم النظر فقط إلى 5 بتات أقل.

_trac user parejkoj كتب في 27 يوليو 2012_

تمكنت من كتابة التعليمات البرمجية حول هذا باستخدام لامدا التالية:

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

هذا يعمل ، لكنه ليس مثاليًا. سيكون الحصول على هذا الإصلاح في numpy مفيدًا جدًا.

بعد خمس سنوات ... أليست هذه قضية مهمة؟ يجب ألا تحتوي الأعداد الصحيحة غير الموقعة على أي غموض حول التحولات.

الحل الأسهل هو استخدام عدد صحيح بدون إشارة لإزاحة:

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

كما ذكر charris أعلاه ، فإن المشكلة تكمن في الطريقة التي يتم بها توحيد الأنواع. ليس من التافه أن يتم الإصلاح بشكل عام (انظر أيضًا # 5668) ، على الرغم من أنه ربما يمكن أن يكون مشغلو النقل بغلاف خاص. (نرحب بالعلاقات العامة ، كما قيل ، هذا ليس تافهًا ، ولكنه يتطلب فهمًا عادلًا لكيفية تحديد الحلقات الداخلية في ufucs ...).

الحل الأسهل هو استخدام عدد صحيح بدون إشارة لإزاحة:

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

... والتي تعمل إذا كنت تعرف أنك تعمل على أعداد صحيحة عددية ، ولكن إذا كنت تستخدم رمزًا عامًا (لا سيما شيء تمت كتابته بالفعل في وحدة أخرى وهو خارج عن إرادتك) مثل

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

ثم لا يمكنك جعله يعمل على كل من أنواع Python الصحيحة وأنواع np.uint64.

لا أحاول أن أقول إن هذا أمر تافه (يتفوق على مجموعة المهارات الخاصة بي) لكنني أعتقد أنه يجب أن يكون أولوية عالية.

@ jason-s - أوافق على أن المشكلة مزعجة للغاية ... للأسف ، لا يوجد الكثير منا على دراية كافية بكيفية عمل ufuncs داخليًا ...

ربما يمكن للمرء على الأقل استخدام مقاييس الحالة الخاصة لتغيير الطريقة ، على الرغم من ذلك ، بدلاً من الاعتماد على آلية ufunc العامة. charris : هل كان هذا ما كنت تفكر فيه (إذا كنت تستطيع تذكر ذلك بعد 6 سنوات ؛-).

راجع أيضًا # 8002.

شخصيًا ، إذا تمكنا من القيام بكل شيء مرة أخرى ، فسأفضل إعادة كل عمليات الصب / الإكراه بحيث يتصرف أسلوب الصب غير المقبول بشكل أساسي مثل C casting ، ويتبع روح C-casting في الحالات غير الموجودة في C. القواعد غريبة ومربكة في بعض الأحيان (على سبيل المثال ، تحويل uint64 + int64 إلى float64 ). لكننا ناقشنا هذا كثيرًا في القائمة ، ويبدو أنه من الصعب تغييره.

عندما أواجه مثل هذه المواقف (انظر تعليقي هناك) ، أقوم فقط بلف كل قيمة مفردة بـ np.uint64 .

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات