سؤال

لدي هذه أعلام البت المحتملة.

1, 2, 4, 8, 16, 64, 128, 256, 512, 2048, 4096, 16384, 32768, 65536

لذلك كل رقم يشبه بيان حقيقي/خطأ على جانب الخادم. لذا ، إذا تم تمييز العناصر الثلاثة الأولى ، وعناصر الثلاثة الأولى فقط "صواب" على جانب الخادم ، ستعود خدمة الويب إلى 7. أو إذا كانت جميع العناصر الـ 14 أعلاه صحيحة ، فلا يزال بإمكانني الحصول على رقم واحد من خدمة الويب التي هي مجموع كل هذه الأرقام.

ما هي أفضل طريقة للتعامل مع الرقم الذي أعود إليه لمعرفة العناصر التي يتم تمييزها على أنها "حقيقية"؟

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

المحلول

if (7 & 1) { // if bit 1 is set in returned number (7)

}

نصائح أخرى

استخدم مشغل إخفاء قليلا. في اللغة C:

 X & 8

صحيح ، إذا تم تعيين بت "8".

يمكنك تعداد أقنعة البت ، وحساب عددهم.

إذا كان الأمر كذلك حقًا ، فإن الكلمة بأكملها تحتوي على أجزاء ، وتريد ببساطة حساب عدد البتات التي يتم تعيينها ، فأنت تريد في جوهر "عدد السكان". إن أسرع طريقة مطلقة للحصول على عدد السكان هي تنفيذ "popcnt" الأصلي عادة في مجموعة تعليمات جهازك.

إذا كنت لا تهتم بالمساحة ، فيمكنك إعداد صفيف CountedBits [... فهرسة بواسطة قيمتك مع عدد بتات. ثم يحسب الوصول إلى ذاكرة واحدة عدد البتات.

في كثير من الأحيان تستخدم مجرد واضحة "رمز بتات البت" التي تحسب تعداد البت:

(طريقة كيرنيجان):

unsigned int v; // count the number of bits set in v
unsigned int c; // c accumulates the total bits set in v
for (c = 0; v; c++)
{
  v &= v - 1; // clear the least significant bit set
}

(ملخص بت الموازي ، 32 بت)

v = v - ((v >> 1) & 0x55555555);                    // reuse input as temporary
v = (v & 0x33333333) + ((v >> 2) & 0x33333333);     // temp
c = ((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24; // count

إذا لم تكن قد شاهدت الاختراقات التي تربطها من قبل ، فأنت في علاج.

PHP ، كونها مضحكة ، قد تفعل أشياء مضحكة مع بعض من هذا الحساب.

يعتقد أن السؤال قديم قد يساعد شخص آخر. أنا أضع الأرقام في ثنائي باعتباره أكثر وضوحًا لفهمه. لم يتم اختبار الرمز ولكن آمل أن يكون المنطق واضحًا. الرمز هو PHP محدد.

define('FLAG_A', 0b10000000000000);  
define('FLAG_B', 0b01000000000000);
define('FLAG_C', 0b00100000000000);
define('FLAG_D', 0b00010000000000);
define('FLAG_E', 0b00001000000000);
define('FLAG_F', 0b00000100000000);
define('FLAG_G', 0b00000010000000);
define('FLAG_H', 0b00000001000000);
define('FLAG_I', 0b00000000100000);
define('FLAG_J', 0b00000000010000);
define('FLAG_K', 0b00000000001000);
define('FLAG_L', 0b00000000000100);
define('FLAG_M', 0b00000000000010);
define('FLAG_N', 0b00000000000001);

function isFlagSet($Flag,$Setting,$All=false){
  $setFlags = $Flag & $Setting;
  if($setFlags and !$All) // at least one of the flags passed is set
     return true;
  else if($All and ($setFlags == $Flag)) // to check that all flags are set
     return true;
  else
     return false;
}

الاستخدام:

if(isFlagSet(FLAG_A,someSettingsVariable)) // eg: someSettingsVariable = 0b01100000000010

if(isFlagSet(FLAG_A | FLAG_F | FLAG_L,someSettingsVariable)) // to check if atleast one flag is set

if(isFlagSet(FLAG_A | FLAG_J | FLAG_M | FLAG_D,someSettingsVariable, TRUE)) // to check if all flags are set

تتمثل إحدى الطرق في حلق رقمك ، وتغييره الأيسر (أي تقسيم على 2) ومقارنة القطعة الأولى مع 1 باستخدام المعامل.

نظرًا لعدم وجود إجابة محددة مع رمز PHP ، أقوم بإضافة مثال العمل هذا:

// returns array of numbers, so for 7 returns array(1,2,4), etc..

function get_bits($decimal) {
  $scan = 1;
  $result = array();
  while ($decimal >= $scan){
    if ($decimal & $scan) $result[] = $scan;
    $scan<<=1; 
  }
  return $result;
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top