আমি সি-তে একটি পূর্ণসংখ্যা মান থেকে কীভাবে বিট-বাই-বিট ডেটা পাব?


102

আমি দশমিক সংখ্যার বিট বের করতে চাই।

উদাহরণস্বরূপ, 7 হ'ল বাইনারি 0111, এবং আমি 0 1 1 1 টি বিলে সঞ্চিত সমস্ত বিট পেতে চাই। আমি কীভাবে এটি করতে পারি?

ঠিক আছে, একটি লুপ একটি ভাল বিকল্প নয়, আমি কি এর জন্য আরও কিছু করতে পারি?

উত্তর:


160

আপনি যদি কে-থ্রি বিটি চান তবে তা করুন

(n & ( 1 << k )) >> k

এখানে আমরা একটি মাস্ক তৈরি করি, মাস্কটিকে n তে প্রয়োগ করি এবং তারপরে ঠিক আমাদের যে বিটটি চান সেটি পেতে ডান মুখোশযুক্ত মানটি শিফট করে। আমরা আরও সম্পূর্ণরূপে এটি লিখতে পারি:

    int mask =  1 << k;
    int masked_n = n & mask;
    int thebit = masked_n >> k;

আপনি এখানে বিট-মাস্কিং সম্পর্কে আরও পড়তে পারেন ।

এখানে একটি প্রোগ্রাম:

#include <stdio.h>
#include <stdlib.h>

int *get_bits(int n, int bitswanted){
  int *bits = malloc(sizeof(int) * bitswanted);

  int k;
  for(k=0; k<bitswanted; k++){
    int mask =  1 << k;
    int masked_n = n & mask;
    int thebit = masked_n >> k;
    bits[k] = thebit;
  }

  return bits;
}

int main(){
  int n=7;

  int  bitswanted = 5;

  int *bits = get_bits(n, bitswanted);

  printf("%d = ", n);

  int i;
  for(i=bitswanted-1; i>=0;i--){
    printf("%d ", bits[i]);
  }

  printf("\n");
}

72
(n >> k) & 1সমানভাবে বৈধ এবং মাস্কের গণনার প্রয়োজন হয় না কারণ মাস্কটি অন্য উপায়ে পরিবর্তে মাস্কিংয়ের আগে স্থানান্তরিত হওয়ার কারণে স্থির থাকে।
জো

@ জো আপনি কি এটি ব্যাখ্যা করতে পারেন, সম্ভবত একটি উত্তরে দয়া করে?
ড্যান রোজনস্টার্ক

4
@ ইয়ার আমার মন্তব্যটি কিছুটা বাড়িয়েছেন এবং অনুরোধ অনুসারে একটি নতুন উত্তর যুক্ত করেছেন
জো

তথ্যের জন্য জ্ঞাত বিটগুলি ব্যবহার করার সময় (যেমন নেটওয়ার্কস প্রোটোকলগুলির জন্য, যেমন ওয়েবসকেটস), কোনওটিতে ডেটা ফেলে দেওয়াও কার্যকর structহতে পারে, কারণ আপনি একক ক্রিয়াকলাপের সাথে সমস্ত প্রয়োজনীয় ডেটা পেয়ে যান।
মাইস্ট

@ ফরেফিংগার, আপনি দয়া করে কোডটির একটি উদাহরণ আউটপুট পোস্ট করতে পারেন।
আশিস আহুজা

87

অনুরোধ হিসাবে, আমি পুরো অগ্রিম উত্তরের অগ্রণীতাদের উত্তর সম্পর্কে আমার মন্তব্য প্রসারিত করার সিদ্ধান্ত নিয়েছি। যদিও তার উত্তরটি সঠিক, এটি অযথা জটিল। তদ্ব্যতীত বর্তমান সমস্ত উত্তর intমানগুলি উপস্থাপন করতে স্বাক্ষরিত গুলি ব্যবহার করে। এটি বিপজ্জনক, কারণ নেতিবাচক মানগুলির ডান স্থানান্তর বাস্তবায়ন-সংজ্ঞায়িত (যেমন পোর্টেবল নয়) এবং বাম-স্থানান্তর অনির্ধারিত আচরণের দিকে পরিচালিত করতে পারে ( এই প্রশ্নটি দেখুন )।

কাঙ্ক্ষিত বিটটিকে নূন্যতম উল্লেখযোগ্য বিট অবস্থানে ডান স্থানান্তরিত করে, মাস্কিং দিয়ে কাজ করা যায় 1। প্রতিটি বিটের জন্য একটি নতুন মাস্ক মান গণনা করার দরকার নেই।

(n >> k) & 1

সম্পূর্ণ প্রোগ্রাম হিসাবে, কম্পিউটিং (এবং পরবর্তীকালে মুদ্রণ) একক বিট মানগুলির একটি অ্যারে:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char** argv)
{
    unsigned
        input = 0b0111u,
        n_bits = 4u,
        *bits = (unsigned*)malloc(sizeof(unsigned) * n_bits),
        bit = 0;

    for(bit = 0; bit < n_bits; ++bit)
        bits[bit] = (input >> bit) & 1;

    for(bit = n_bits; bit--;)
        printf("%u", bits[bit]);
    printf("\n");

    free(bits);
}

ধরে নিই যে আপনি এই ক্ষেত্রে হিসাবে সমস্ত বিট গণনা করতে চান, এবং নির্দিষ্টটি নয়, লুপটি আরও পরিবর্তিত হতে পারে

for(bit = 0; bit < n_bits; ++bit, input >>= 1)
    bits[bit] = input & 1;

এটি inputজায়গায় পরিবর্তিত হয় এবং এর ফলে স্থির প্রস্থ, একক-বিট শিফট ব্যবহার করতে দেয় যা কিছু আর্কিটেকচারে আরও দক্ষ হতে পারে।


5

এটি করার একটি উপায় এখানে — আরও অনেকগুলি রয়েছে:

bool b[4];
int v = 7;  // number to dissect

for (int j = 0;  j < 4;  ++j)
   b [j] =  0 != (v & (1 << j));

লুপের ব্যবহার কেন পছন্দ হচ্ছে না তা বোঝা শক্ত তবে লুপটি আনলোল করা যথেষ্ট সহজ:

bool b[4];
int v = 7;  // number to dissect

b [0] =  0 != (v & (1 << 0));
b [1] =  0 != (v & (1 << 1));
b [2] =  0 != (v & (1 << 2));
b [3] =  0 != (v & (1 << 3));

বা শেষ চারটি বিবৃতিতে ধ্রুবক অভিব্যক্তি মূল্যায়ন:

b [0] =  0 != (v & 1);
b [1] =  0 != (v & 2);
b [2] =  0 != (v & 4);
b [3] =  0 != (v & 8);

3

এটি করার একটি খুব সহজ উপায় এখানে;

int main()
{
    int s=7,l=1;
    vector <bool> v;
    v.clear();
    while (l <= 4)
    {
        v.push_back(s%2);
        s /= 2;
        l++;
    }
    for (l=(v.size()-1); l >= 0; l--)
    {
        cout<<v[l]<<" ";
    }
    return 0;
}

1

@ প্রীতেক আপনার সহায়তার জন্য আপনাকে ধন্যবাদ আমি কোনও প্রোগ্রামে ব্যবহারের জন্য মন্তব্যগুলি দিয়ে ফাংশনটি আবার লিখেছি। আরও বিটের জন্য 8 বৃদ্ধি করুন (পূর্ণসংখ্যার জন্য 32 অবধি)।

std::vector <bool> bits_from_int (int integer)    // discern which bits of PLC codes are true
{
    std::vector <bool> bool_bits;

    // continously divide the integer by 2, if there is no remainder, the bit is 1, else it's 0
    for (int i = 0; i < 8; i++)
    {
        bool_bits.push_back (integer%2);    // remainder of dividing by 2
        integer /= 2;    // integer equals itself divided by 2
    }

    return bool_bits;
}

1

আপনি যদি কোনও লুপ না চান তবে আপনাকে এটি লিখতে হবে:

#include <stdio.h>
#include <stdbool.h>

int main(void)
{
    int num = 7;

    #if 0
        bool arr[4] = { (num&1) ?true: false, (num&2) ?true: false, (num&4) ?true: false, (num&8) ?true: false };
    #else
        #define BTB(v,i) ((v) & (1u << (i))) ? true : false
        bool arr[4] = { BTB(num,0), BTB(num,1), BTB(num,2), BTB(num,3)};
        #undef BTB
    #endif

    printf("%d %d %d %d\n", arr[3], arr[2], arr[1], arr[0]);

    return 0;
}

এখানে প্রদর্শিত হিসাবে, এটি একটি প্রাথমিককরণেও কাজ করে।


0
#include <stdio.h>

int main(void)
{
    int number = 7; /* signed */
    int vbool[8 * sizeof(int)];
    int i;
        for (i = 0; i < 8 * sizeof(int); i++)
        {
            vbool[i] = number<<i < 0;   
            printf("%d", vbool[i]);
        }
    return 0;
}

0

ব্যবহার std::bitset

int value = 123;
std::bitset<sizeof(int)> bits(value);
std::cout <<bits.to_string();

এটি একটি দরকারী পদ্ধতি, তবে উদাহরণে কিছু ভুল আছে। বিটসেট <এন>, এন বিটের সংখ্যা, সুতরাং মাপের (ইন্ট) ব্যবহার ভুল।
জেরি চৌ চৌ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.