سؤال

أنا أعمل على برنامج حيث أقوم بتخزين بعض البيانات في عدد صحيح ومعالجتها بطريقة البت.على سبيل المثال، قد أتلقى الرقم 48، والذي سأقوم بمعالجته خطوة بخطوة.بشكل عام، تعتمد نهاية الأعداد الصحيحة على التمثيل الآلي للأعداد الصحيحة، ولكن هل تفعل بايثون أي شيء لضمان أن تكون ints دائمًا صغيرة؟أو هل أحتاج إلى التحقق من endianness كما أفعل في لغة C ثم كتابة رمز منفصل للحالتين؟

أسأل لأن الكود الخاص بي يعمل على جهاز Sun، وعلى الرغم من أن الجهاز الذي يعمل عليه الآن يستخدم معالجات Intel، فقد أضطر إلى التبديل إلى جهاز مزود بمعالجات Sun في المستقبل، وهو ما أعلم أنه أمر بالغ الأهمية.

هل كانت مفيدة؟

المحلول

بايثون int لديه نفس endianness مثل المعالج الذي يعمل عليه.ال struct تتيح لك الوحدة النمطية تحويل وحدات البايت النقطية إلى ints (والعكس، وبعض أنواع البيانات الأخرى أيضًا) إما بطرق أصلية أو ذات نهاية صغيرة أو كبيرة، اعتمادًا على سلسلة التنسيق اختار أنت:ابدأ التنسيق بـ @ أو لا توجد شخصية endianness لاستخدام endianness الأصلية (والأحجام الأصلية-كل شيء آخر يستخدم الأحجام القياسية) أو '~' بالنسبة إلى الأصلي أو '<' بالنسبة إلى Little-endian ، '>' أو '!' للإنديان الكبير.

وهذا بايت بايت، وليس بايتًا بايت؛لست متأكدًا تمامًا مما تعنيه بالمعالجة شيئًا فشيئًا في هذا السياق، لكنني أفترض أنه يمكن استيعابها بالمثل.

للحصول على معالجة سريعة "مجمعة" في الحالات البسيطة، ضع في اعتبارك أيضًا مجموعة مصفوفة الوحدة النمطية-- fromstring و tostring يمكن أن تعمل الأساليب على عدد كبير من البايتات بسرعة، ويمكن أن تعمل byteswap يمكن أن تحصل الطريقة على endianness "الآخر" (الأصلي لغير الأصلي أو العكس)، ومرة ​​أخرى بسرعة ولعدد كبير من العناصر (المصفوفة بأكملها).

نصائح أخرى

إذا كنت بحاجة إلى معالجة "أحادي المعامل" البيانات الخاصة بك ثم جبروت bitstring حدة تكون عونا لك. ويمكن أيضا التعامل مع endianness بين منصات (على أحدث البنية جذع على الأقل - أن يصدر في الأيام القليلة المقبلة).

struct حدة هو أفضل طريقة موحدة للتعامل مع endianness بين المنصات. على سبيل المثال هذا حزم وفك الأعداد الصحيحة 1، 2، 3 إلى قسمين "شورت" و (2 و 4 بايت على معظم المنصات) واحد "الطويل" باستخدام endianness الأصلي:

>>> from struct import *
>>> pack('hhl', 1, 2, 3)
'\x00\x01\x00\x02\x00\x00\x00\x03'
>>> unpack('hhl', '\x00\x01\x00\x02\x00\x00\x00\x03')
(1, 2, 3)

لمراجعة endianness من منصة برمجية يمكنك استخدام

>>> import sys
>>> sys.byteorder

والتي إما العودة "big" أو "little".

وتحقق متى؟

عند القيام بعمليات المختصة بالبت، فإن في كثافة العمليات لديهم نفس endianess باسم [إينتس] كنت وضعت فيه أنت لا تحتاج إلى التحقق من ذلك. ما عليك سوى أن نهتم هذا عند التحويل إلى / من تسلسل بايت، في كل اللغات، AFAIK.

في بيثون استخدام وحدة البنية لهذا، struct.pack الأكثر شيوعا () وstruct.unpack ().

والمقتطف التالي سوف اقول لكم اذا كان النظام الافتراضي الخاص بك هو endian قليلا (وإلا أنها كبيرة-endian)

import struct
little_endian = (struct.unpack('<I', struct.pack('=I', 1))[0] == 1)

ملحوظة، ولكن هذا لن يؤثر على سلوك مشغلي المختصة بالبت: 1<<1 تساوي 2 بغض النظر عن endianness الافتراضي للنظام الخاص بك

.
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top