سؤال

لدي بضعة أسطر من التعليمات البرمجية داخل مشروع، لا أستطيع رؤية قيمة ...

buffer[i] = (currentByte & 0x7F) | (currentByte & 0x80);

يقرأ ملف filebuffer من ملف، مخزن ك bytes، ثم ينقل بعد ذلك إلى المخزن المؤقت [i] كما هو موضح، لكنني لا أستطيع أن أفهم ما هو الغرض العام، أي أفكار؟

شكرا

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

المحلول

كما ذكرت الإجابات الأخرى بالفعل، (currentByte & 0x7F) | (currentByte & 0x80) أي ما يعادل (currentByte & 0xFF). وبعد JLS3. 15.22.1 يقول هذا يتم الترويج ل int:

عندما كلا المعاملين لمشغل و، ^، أو | هي من نوع قابلة للتحويل (§5.1.8) إلى نوع متكامل بدائي، يتم تنفيذ الترويج الرقمي الثنائي لأول مرة على المعاملات (§5.6.2). نوع تعبير المشغل Bitwise هو النوع المعزز للمعاملات.

لأن JLS3. 5.6.2 يقول أنه عندما currentByte لديه نوع byte و 0x7F هو int (وهذا هو الحال)، ثم يتم ترقيت كلا المعاملين إلى int.

لذلك، buffer سيكون مجموعة من نوع العنصر int أو أوسع.

الآن، عن طريق الأداء & 0xFF على int, ، نحن خريطة فعالة الأصلي byte Range -128..127 في النطاق غير المائعين 0..255، عملية تستخدم غالبا بواسطة java.io تيارات على سبيل المثال.

يمكنك أن ترى هذا في العمل في مقتطف التعليمات البرمجية التالية. لاحظ أنه لفهم ما يحدث هنا، عليك أن تعرف أن Java يخزن أنواعا لا يتجزأ، باستثناء char, ، كما 2 تكملة القيم.

byte b = -123;
int r = b;
System.out.println(r + "= " + Integer.toBinaryString(r));
int r2 = b & 0xFF;
System.out.println(r2 + "= " + Integer.toBinaryString(r2));

أخيرا، للحصول على مثال عالمي حقيقي، تحقق من جافادوك وتنفيذ read طريقة java.io.ByteArrayInputStream:

/**
 * Reads the next byte of data from this input stream. The value 
 * byte is returned as an <code>int</code> in the range 
 * <code>0</code> to <code>255</code>. If no byte is available 
 * because the end of the stream has been reached, the value 
 * <code>-1</code> is returned. 
 */
public synchronized int read() {
return (pos < count) ? (buf[pos++] & 0xff) : -1;
}

نصائح أخرى

 (currentByte & 0x7F) | (currentByte & 0x80)

أي ما يعادل

 currentByte & (0x7F | 0x80)

التي تساوي

 currentByte & 0xFF

وهو بالضبط هو نفسه

 currentByte

تحرير: نظرت فقط إلى الجانب الأيمن من المهمة، وما زلت أعتقد أن المعادلة صحيحة.

ومع ذلك، يبدو أن الكود يريد إلقاء البايت الموقعة على نوع أكبر أثناء تفسير البايت باعتباره غير ماني.

هل هناك طريقة أسهل للإدلاء بايت بايت إلى غير موقعة في جافا؟

أعتقد أن شخصا ما يفكر كثيرا هنا. هذا ليس صحيحا.

لدي ولكن ملاحظة واحدة

  • كان المؤلف الأصلي قلقا بشأن وقت التشغيل استبدال البايت مع عدد صحيح موقعة (يفترض 32 بت) ويحاول صراحة أن تخبرنا بشيء حيال كونك "خاص"؟

إنه رمز اليسار وراءه. إلا إذا كنت تعرف أنك في وقت تشغيل مربيئ؟ ما هو نوع "العازلة" على أي حال؟

منطق bitwise المعقدة غير ضروري تماما.

for (int i = 0; i < buffer.length; i++) {
    buffer[i] = filebuffer[currentPosition + i] & 0xff;
}

يفعل الشيء نفسه. إذا تم الإعلان عن المخزن المؤقت كصفيف من البايتات، فقد تترك حتى الآن & 0xFF، ولكن لسوء الحظ، لا يظهر الإعلان.

قد يكون السبب في حيرة المطور الأصلي من قبل البايتات التي يتم توقيعها في جافا.

نتيجة للبيت والعملية لديها 1 على تلك البتات حيث تكون كلا البتان 1 في حين أن النتيجة لجهاز التسمير البسيط أو العملية على تلك البتات حيث يكون أي من بتات بوت 1.

لذلك تقييم مثال للقيمة 0x65:

  01100101 0x65
& 01111111 0x7F
===============
  01100101 0x65

  01100101 0x65
& 10000000 0x80
===============
  00000000 0x00

  01100101 0x65
| 00000000 0x00
===============
  01100101 0x65

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

اتضح، الملف الذي تم قراءته بايت من كان في تترجم بت الموقع، وطول مختلف، لذلك تم إعادة توقيعه لأداء هذه المهمة للسماح بتمديده إلى نوع Java Int، مع الاحتفاظ به :)

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