كتابة وظيفة: GetBits قصيرة (بيانات قصيرة، الباحث ص، الباحث ن)

StackOverflow https://stackoverflow.com/questions/1061528

  •  21-08-2019
  •  | 
  •  

سؤال

وأنا أكتب وظيفة getBits باختصار (بيانات قصيرة، الباحث ص، الباحث ن)

ولقد حاولت:

public static short getBits(short data, int p, int n) {
    short bitmask = (short) ((~0 << (16 -n)) >>> p);
    short returnVal = (short) ((bitmask & data) >>> (16 - n));
    return returnVal;
}

وهذا يعمل لgetBits ((قصيرة) 0x7000، 0، 4)، ولكن إذا كان لي أن تحل محل 7 مع 8 أحصل على قيمة سالبة.

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

المحلول

وهناك عدد قليل من الأشياء لتذكر حول أنواع البيانات جافا، لجعل هذا العمل شيء.

وأفترض أنك تستخدم المتغيرات كثافة العمليات بسبب عدم وجود يلقي صريحة في التعبير الخاص بك. إذا كنت تستخدم نوع int للمتغيرات الخاصة بك: start_pos البيانات، والطول؛ يجب أن يكون مستخدما 32 بدلا من 16، منذ عام كثافة العمليات هي قيم 32-بت.

وأيضا إذا كنت تنوي استخدام أنواع بدائية صحيح مثل كثافة العمليات، قصيرة أو بايت، وتذكر أن هذه الأنواع البدائية هي متمم ثنائي التي هي الموسعة علامة، وهذا يعني أنه إذا كنت تفعل تحول الحق على الأرقام السالبة مثل ~ 0 ( تقييم إلى -1)، سيتم إلحاق تلك الموجودة في أعلى ترتيب بت (علامة بت) بدلا من الأصفار.

وعلى سبيل المثال:

1111 1111 1111 1111 1111 1111 1111 1000        
>>1
1111 1111 1111 1111 1111 1111 1111 1100 

والآن يعود لمشكلتك. الفكرة العامة هي أن تكون قادرة على القيام:

data & mask

والآن، وتوليد القناع هو صعبة بعض الشيء على أنواع البيانات الموقعة. ومن المنطقي لتوليد القناع باستخدام:

(~0 << (32 - length) >> (32 - length - start_pos))

ولكن هذا لن يعمل بالطبع بسبب تمديد علامة.

وأود أن أقترح أنه بدلا من استخدام التحول الصحيح >>، واستخدام تدوير مشغل >>> بهذه الطريقة بدلا من تلك التي يتم إلحاق على أعلى ترتيب بعض الشيء، فإن المشغل تدوير إلحاق أدنى ترتيب بعض الشيء.

وعلى سبيل المثال:

1111 1111 1111 1111 1111 1111 1111 1000        
>>>1
0111 1111 1111 1111 1111 1111 1111 1100 

وهكذا ...

mask = (~0 << 32-length >>> 32-length-start_pos)

والجواب النهائي الخاص بك سيبدو شيئا مثل:

(data & (~0 << 32-length >>> 32-length-start_pos)) >>> start_pos

والعملية تدوير الأبعد تنتقل البيانات المقنعة لالبتات أجل الدنيا.

نصائح أخرى

ولا يدري لماذا تحتاج إلى استخدام باختصار. هنا هو الحل استخدام طويل.

public static long getBits(long data, int p, int n) {
    assert p >= 0 && p < 64;
    assert n >= 0 && n < 64;
    return (data >> p) & ((1 << n) - 1);
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top