সি / সি ++ পরীক্ষা করুন যে এক বিট সেট করা আছে, অর্থাত্ ভেরিয়েবল


100
int temp = 0x5E; // in binary 0b1011110.

টেম্পের বিট 3 বিট শিফটিং এবং মাস্কিং ছাড়াই 1 বা 0 হয় কিনা তা পরীক্ষা করার কোনও উপায় আছে?

এটির জন্য কোনও কার্যনির্বাহী রয়েছে কিনা তা জানতে চাই, বা আমি নিজেই একটি লিখতে বাধ্য হচ্ছি।

উত্তর:


157

সি তে, আপনি যদি বিট ম্যানিপুলেশনটি গোপন করতে চান তবে আপনি ম্যাক্রো লিখতে পারেন:

#define CHECK_BIT(var,pos) ((var) & (1<<(pos)))

এবং ডান প্রান্ত থেকে n তম বিট পরীক্ষা করতে এটি এইভাবে ব্যবহার করুন :

CHECK_BIT(temp, n - 1)

সি ++ এ আপনি স্ট্যান্ড :: বিটসেট ব্যবহার করতে পারেন ।


3
আপনার যদি একটি সাধারণ সত্য মানের প্রয়োজন হয় তবে এটি হওয়া উচিত !! ((var) এবং (1 << (পোষ্ট)))।
এডুয়ার্ড - গ্যাব্রিয়েল মুন্তেণু

10
@ এডওয়ার্ড: সি তে, সব != 0কিছু সত্য, তবে কেন বিরক্ত করবেন? 1ঠিক যেমন সত্য 0.1415!
ক্রিস্টোফ

1
এবং আপনি যদি সি ++ ব্যবহার করেন তবে আপনি ম্যাক্রোর পরিবর্তে একটি টেম্পলেট লিখতে পারেন (উচিত)। :)
জাল্ফ

2
সিতে এটি ঠিক আছে। তবে সি ++ এ এই জাতীয় ম্যাক্রো এটি ভয়াবহ এবং অপব্যবহারের জন্য উন্মুক্ত। স্টাড :: বিটসেট ব্যবহার করুন
মার্টিন ইয়র্ক

5
উঃ, std::bitsetসত্যি? অবশ্যই, একক বিট পরীক্ষা করার জন্য খুব সামান্য কাজ (এবং সম্ভাব্য কয়েকটি সত্যিই দুর্দান্ত টেম্পলেট) না করে, একটি ফোলা পাত্রে ব্যবহার করুন যা অন্যথায় অব্যবহৃত প্রতিটি 'বিট' সংরক্ষণ করে (আমার বাস্তবায়নে) unsigned long। কী জায়গার অপচয়!
আন্ডারস্কোর_২

86

বিট এন (0 থেকে শুরু) সেট করা আছে কিনা তা পরীক্ষা করুন:

temp & (1 << N)

এটির জন্য কোনও বিল্টিন ফাংশন নেই।


16
এটি ০ থেকে শুরু করার জন্য +1 উল্লেখ করেছেন যেহেতু আমি সন্দেহ করি যে ওপি 1-ভিত্তিক চিন্তা করছে এবং গ্রহণযোগ্য উত্তর তাকে সমস্যার মধ্যে ফেলবে। :)
জিম বাক

হুঁ। কেন এটি 0 থেকে শুরু হচ্ছে? আমরা কখন কী পাই 1 << 0?? দুঃখিত, বিভ্রান্ত
ডানিজেল

6
ঠিক আছে বুঝেছি. আমরা 0 তম সম্ভাবনা থেকে শুরু করি, যা 1<<0কোনও শিফট ছাড়াই 1 (শিফট 0), যা1<<0 == 1
দানিজেল

27

আমি মাত্র একটি স্টাডি :: বিটসেট ব্যবহার করব যদি এটি সি ++ হয়। সহজ। সোজা সম্মুখগামী। বোকা ত্রুটির কোনও সুযোগ নেই।

typedef std::bitset<sizeof(int)> IntBits;
bool is_set = IntBits(value).test(position);

বা এই নির্বিকারতা সম্পর্কে কি

template<unsigned int Exp>
struct pow_2 {
    static const unsigned int value = 2 * pow_2<Exp-1>::value;
};

template<>
struct pow_2<0> {
    static const unsigned int value = 1;
};

template<unsigned int Pos>
bool is_bit_set(unsigned int value)
{
    return (value & pow_2<Pos>::value) != 0;
} 

bool result = is_bit_set<2>(value);

4
@ ব্যবহারকারী21714 আমি অনুমান করছি আপনার মানে স্টাড :: বিটসেট <8 * সাইজ অফ (
ইনট্রি

বা স্টাড :: সংখ্যাসূচক_লিট <int> :: সংখ্যা
লাম

@INFINITEi std::bitset<CHAR_BIT * sizeof(int)>আরও বেশি সঠিক হতে হবে
Xeverous

13

হ্যাঁ, আমি জানি আমি এইভাবে " করণীয় " করব না । তবে আমি সাধারণত লিখি:

    /* Return type (8/16/32/64 int size) is specified by argument size. */
template<class TYPE> inline TYPE BIT(const TYPE & x)
{ return TYPE(1) << x; }

template<class TYPE> inline bool IsBitSet(const TYPE & x, const TYPE & y)
{ return 0 != (x & y); }

উদাহরণ:

IsBitSet( foo, BIT(3) | BIT(6) );  // Checks if Bit 3 OR 6 is set.

অন্যান্য বিষয়ের মধ্যে, এই পদ্ধতির:

  • 8/16/32/64 বিট পূর্ণসংখ্যার সমন্বয় করে।
  • আমার জ্ঞান ও সম্মতি ছাড়াই ইসবিটসেট (ইনট 32, ইন্ট 64) কলগুলি সনাক্ত করে।
  • ইনলাইনড টেম্পলেট, সুতরাং ওভারহেড কল কোন ফাংশন।
  • const & রেফারেন্স, তাই কিছুই চাহিদা সদৃশ করা / অনুলিপি করা হয়েছে। এবং আমরা গ্যারান্টিযুক্ত যে সংকলকটি আর্গুমেন্টগুলি পরিবর্তনের জন্য যে কোনও টাইপও চেষ্টা করবে।
  • 0! = কোডটিকে আরও স্পষ্ট এবং সুস্পষ্ট করে তোলে। কোড রচনার প্রাথমিক পয়েন্ট হ'ল কম প্রোগ্রাম সহ অন্যান্য প্রোগ্রামারদের সাথে পরিষ্কার এবং দক্ষতার সাথে যোগাযোগ করা always
  • যদিও এই বিশেষ ক্ষেত্রে প্রযোজ্য নয় ... সাধারণভাবে, টেম্পলেটযুক্ত ফাংশনগুলি একাধিকবার আর্গুমেন্টগুলি মূল্যায়নের বিষয়টি এড়িয়ে চলে। কিছু # ডেফাইন ম্যাক্রোগুলির সাথে একটি পরিচিত সমস্যা।
    উদাঃ # ডিফাইন এবিএস (এক্স) (((এক্স) <0)? - (এক্স): (এক্স))
          এবিএস (আই ++);

13

নির্বাচিত উত্তরটি যা করছে তা আসলে ভুল। নীচের ফাংশনটি বিট অবস্থানটি 0 বা ফিরে আসবে যদি বিটটি আসলে সক্ষম করা থাকে তার উপর নির্ভর করে। পোস্টারটি যা চেয়েছিল এটি এটি নয়।

#define CHECK_BIT(var,pos) ((var) & (1<<(pos)))

পোস্টারটি মূলত যা খুঁজছিল তা এখানে। বিট সক্ষম থাকলে এবং অবস্থানটি না থাকলে নীচের ফাংশনটি 1 বা 0 প্রদান করবে।

#define CHECK_BIT(var,pos) (((var)>>(pos)) & 1)

1
আপনার অর্থ কী বোঝা গেল ততক্ষণ পর্যন্ত এটি কিছুটা সময় নিয়েছে। আরও নির্ভুল: প্রথম ফাংশনটি বিটটি সেট করা থাকলে বিট পজিশনে পাওয়ার হিসাবে 2 প্রদান করে, অন্যথায় 0।
lukasl1991

1
bool has_feature = CHECK_BIT(register, 25);ডাবল-নেগেট ছাড়াই এটি করতে পারি জেনে রাখা ভাল এর মতো ব্যবহার করার সময় আমি ঠিক এটির সমস্যার মুখোমুখি হয়েছি ।
Jimmio92

11

বিট-ফিল্ডগুলির এই বর্ণনা অনুসারে , সরাসরি ক্ষেত্রগুলি সংজ্ঞায়িত এবং অ্যাক্সেসের জন্য একটি পদ্ধতি রয়েছে। এই এন্ট্রি উদাহরণটি যায়:

struct preferences {
    unsigned int likes_ice_cream : 1;
    unsigned int plays_golf : 1;
    unsigned int watches_tv : 1;
    unsigned int reads_books : 1;
}; 

struct preferences fred;

fred.likes_ice_cream = 1;
fred.plays_golf = 1;
fred.watches_tv = 1;
fred.reads_books = 0;

if (fred.likes_ice_cream == 1)
    /* ... */

এছাড়াও, সেখানে একটি সতর্কতা রয়েছে:

তবে স্ট্রটে বিট সদস্যদের ব্যবহারিক ঘাটতি রয়েছে। প্রথমত, মেমরিতে বিটের ক্রম হ'ল আর্কিটেকচার নির্ভর এবং মেমরি প্যাডিং বিধিগুলি সংকলক থেকে সংকলক পর্যন্ত পরিবর্তিত হয়। এছাড়াও, অনেক জনপ্রিয় সংকলক বিট সদস্যদের পড়ার জন্য এবং লেখার জন্য অযোগ্য কোড তৈরি করে এবং বিট ক্ষেত্রগুলি সম্পর্কিত বিশেষত গুরুতর থ্রেড সুরক্ষা সমস্যা রয়েছে (বিশেষত মাল্টিপ্রসেসর সিস্টেমে) বেশিরভাগ মেশিনগুলি মেমরির বিটগুলির স্বেচ্ছাসেবক সেটগুলি পরিচালনা করতে পারে না বলে, তবে এর পরিবর্তে পুরো শব্দ লোড এবং সংরক্ষণ করতে হবে।



5

Std :: বিটসেট ব্যবহার করুন

#include <bitset>
#include <iostream>

int main()
{
    int temp = 0x5E;
    std::bitset<sizeof(int)*CHAR_BITS>   bits(temp);

    // 0 -> bit 1
    // 2 -> bit 3
    std::cout << bits[2] << std::endl;
}

1
এখানে উল্লেখযোগ্য কয়েকটি বিষয় - বিটস [3] আপনাকে চতুর্থ বিট দেবে - এলএসবি থেকে এমএসবিতে গণনা করবে। এটিকে আলগাভাবে রাখার জন্য, এটি আপনাকে ডান থেকে বামে 4 বিট গণনা দেবে। এছাড়াও, সাইজফ (ইনট) একটি ইনট্রে অক্ষরের সংখ্যা দেয়, সুতরাং এটি স্ট্যান্ড :: বিটসেট <মাপের (আকার) (বিআরসি)> বিটস (অস্থায়ী), এবং বিটস [আকারের (ইনট) * চর_বিটস - 3] হওয়া দরকার এমএসবি থেকে এলএসবি-তে তৃতীয় বিট গণনা পরীক্ষা করার জন্য এটি সম্ভবত উদ্দেশ্য।
প্লাস্টিক chris

2
হ্যাঁ, তবে আমি মনে করি যে প্রশ্নকারী (এবং গুগল অনুসন্ধানগুলি থেকে আসা লোকেরা) এর দক্ষতা না থাকতে পারে এবং আপনার উত্তর এগুলি বিভ্রান্ত করতে পারে।
প্লাস্টিকের খ্রিস্ট

এই উত্তরটি ভয়ানক। এটি মুছে ফেলা উচিত।
অ্যাডাম বুড়ি

মানটিকে temp"বিগ-এন্ডিয়ান" হিসাবে প্রতিফলিত করার দরকার নেই?
jww

4

নেই, যথা _bittest স্বকীয় নির্দেশ।


3
লিঙ্কটি "মাইক্রোসফ্ট স্পেসিফিক" নির্দেশ করে। আপনার কোডটি পোর্টেবল হওয়ার দরকার নেই তবেই এটি ব্যবহার করুন।
mouviciel

লিঙ্কটি "মাইক্রোসফ্ট স্পেসিফিক" নির্দেশ করে, তবে এটি একটি অভ্যন্তরীণ ইনটেল সি ++ সংকলক থেকে নেওয়া হয়েছে এবং এটি বিটি নির্দেশের ফলস্বরূপ, আপনি এটি ইনলাইন এসেম্বলারের সাহায্যেও করতে পারেন। অবশ্যই, এটি এটিকে আরও বহনযোগ্য করে তোলে না।
ডেভ ভ্যান ডেন এঁয়েডে

1
এটি x86 আর্কিটেকচারের ক্ষেত্রেও নির্দিষ্ট। সুতরাং না, অবশ্যই পোর্টেবল নয় not
জাল্ফ

আমি নিশ্চিত অন্যান্য আর্কিটেকচারেও একই বিকল্প রয়েছে।
ডেভ ভ্যান ডেন এয়েণ্ডে

অন্তর্নিহিতগুলির মূল বিষয়টি হ'ল তারা উপস্থিত থাকলে হার্ডওয়্যারটির সুবিধা গ্রহণ করে এবং হার্ডওয়্যার যদি এটি পরিচালনা না করে তবে একটি সফ্টওয়্যার প্রতিস্থাপন ব্যবহার করে।
সূর্যগ্রহণ

4

আমি এটি ব্যবহার:

#define CHECK_BIT(var,pos) ( (((var) & (pos)) > 0 ) ? (1) : (0) )

যেখানে "পজ" 2 ^ n হিসাবে নির্ধারিত হয়েছে (আইজি 1,2,4,8,16,32 ...)

রিটার্ন দেয়: 1 টি সত্য হলে 0 টি মিথ্যা হলে


2
আমি মনে করি এটি সি এবং সি ++ উভয়েরই একমাত্র সঠিক উত্তর। এটিই কেবলমাত্র "... বিট শিফটিং এবং মাস্কিং ছাড়াই" প্রয়োজনীয়তার সম্মান করে । আপনি সম্ভবত 4 = 2^(3-1)বিট পজিশন 3 ব্যবহারের জন্য স্পষ্টভাবে বলতে হবে কারণ এটি প্রশ্নের অংশ ছিল।
jww

3

আমি একটি 32-বিট পূর্ণসংখ্যা পড়ার চেষ্টা করছিলাম যা পিডিএফগুলিতে কোনও বস্তুর পতাকা চিহ্নিত করেছিল এবং এটি আমার পক্ষে কাজ করছে না

এটি সংজ্ঞায়িত করে কী পরিবর্তন করছিল:

#define CHECK_BIT(var,pos) ((var & (1 << pos)) == (1 << pos))

অপারেন্ড এবং & তে উভয় যে পতাকা রয়েছে তার সাথে একটি পূর্ণসংখ্যা ফেরত দেয় এবং এটি বুলিয়ানে সঠিকভাবে কাস্টিং করা হয়নি, এই কৌশলটি করেছিল


!= 0একই কাজ করবে। জেনারেট হওয়া মেশিনের নির্দেশাবলী কীভাবে আলাদা হতে পারে তা জানেন না।
অ্যাডাম বুড়ি

2

আপনি স্থানান্তর এবং মাস্কিংকে "অনুকরণ" করতে পারেন: যদি (0x5e / (2 * 2 * 2))% 2) ...


আমরা এলোমেলোভাবে এলোমেলো করে এবং এটি এখন "সাজানো" আছে কিনা তা পরীক্ষা করে কোনও তালিকা বাছাই করতে পারি। উদাহরণস্বরূপ: যখন (/ * নয় * /! #Sortted ()) {এলোমেলোভাবে শাফল (); } তবে আমরা তা করি না ...
মিঃ রেই

এই সমাধানটি সংস্থানসমূহ এবং অনিচ্ছুক ক্ষেত্রে চূড়ান্তভাবে অপচয়যোগ্য। ডিভিডস, মুলস এবং মোডগুলি তিনটি ব্যয়বহুল ফাংশন। তুলনা পরীক্ষার দ্বারা, এবংগুলি এবং শিফটগুলি সস্তার মধ্যে অন্যতম - আপনি সম্ভবত কয়েকটি 5 টিরও কম চক্রের মধ্যে সম্পন্ন হতে পারেন।
riেরিকো

এটি হতে পারে (এবং তা নয়, কারণ আধুনিক প্রসেসরগুলি বিট এবং জাম্পকে ঘৃণা করে)। ওপি মূলত "বিট শিফটিং এবং মাস্কিং ছাড়াই" সমাধানের জন্য স্পষ্টভাবে জিজ্ঞাসা করেছিল । সুতরাং এগিয়ে যান এবং একটি মিল কিন্তু ধীর উত্তরের জন্য আরও নেতিবাচক পয়েন্ট দিন। ওপি তার মন বদলেছে বলেই আমি পোস্টটি মুছব না।
লিওনিডাস

এটি দেখতে জটিল দেখাচ্ছে। আসুন এই উত্তরটি ভোট দেওয়া উচিত নয়। কখনও কখনও অন্যান্য মতামতগুলি অন্বেষণ করা ভাল।
ভিয়েতনাম

2

নিম্ন-স্তরের x86 নির্দিষ্ট সমাধানের জন্য x86 টিএসটি অপকোড ব্যবহার করুন ।

আপনার সংকলকটি যদিও এর মধ্যে সবচেয়ে ভাল হওয়া উচিত ...


আমি বিটিটিকে টেস্টের চেয়ে বেশি পছন্দ করবো কারণ বিটি আরও ভালভাবে টাস্কটি ফিট করে।
u_Ltd।

1

এত সহজ কিছু কেন ব্যবহার করবেন না?

uint8_t status = 255;
cout << "binary: ";

for (int i=((sizeof(status)*8)-1); i>-1; i--)
{
  if ((status & (1 << i)))
  {
    cout << "1";
  } 
  else
  {
    cout << "0";
  }
}

আউটপুট: বাইনারি: 11111111


অন্যথায় যদি একটি তিন সঙ্গে সহজে করা সম্ভব: std::cout << (((status & (1 << i)) ? '1' : '0');। 8 বিটকে হার্ড কোডিংয়ের পরিবর্তে আপনার CHAR_BITধ্রুবকটি ব্যবহার করা উচিত <climits>, যদিও আপনি জানেন যে ফলটি যাইহোক 8 হবে আপনি যেহেতু একটি ব্যবহার করছেনuint8_t
রায়ান হেইনিং

0

আপনি যদি কেবল একটি আসল হার্ড কোডেড উপায় চান:

 #define IS_BIT3_SET(var) ( ((var) & 0x04) == 0x04 )

এই এইচডব্লিউ নির্ভরশীল নোট করুন এবং এই বিট অর্ডারটি 7654 3210 ধরে এবং ভেরটি 8 বিট হিসাবে ধরেছে।

#include "stdafx.h"
#define IS_BIT3_SET(var) ( ((var) & 0x04) == 0x04 )
int _tmain(int argc, _TCHAR* argv[])
{
    int temp =0x5E;
    printf(" %d \n", IS_BIT3_SET(temp));
    temp = 0x00;
    printf(" %d \n", IS_BIT3_SET(temp));
    temp = 0x04;
    printf(" %d \n", IS_BIT3_SET(temp));
    temp = 0xfb;
    printf(" %d \n", IS_BIT3_SET(temp));
    scanf("waitng %d",&temp);

    return 0;
}

ফলাফল স্বরূপ:

1 0 1 0


1
অভ্যন্তরীণ উপস্থাপনায় নয় মানগুলিতে & অপারেশন করা হয়।
রেমো.ডি

হাই রেমো.ডি - নিশ্চিত না আমি আপনার মন্তব্যটি বুঝতে পেরেছি? আমি কিছু 'সি' কোড অন্তর্ভুক্ত করেছি যা ঠিক কাজ করে।
সাইমন

তার বিন্দু এটি হার্ডওয়্যার-নির্ভরশীল নয় হয় - IS_BIT3_SET সবসময় 4 র্থ অন্তত গুরুত্বপূর্ণ বিট পরীক্ষা হবে
অন্ধকার

0

এখনই উত্তর দিতে দেরি হয়ে গেলেও, এনটি বিট সেট করা আছে কিনা সে সম্পর্কে সহজ উপায় খুঁজে পাওয়া যায়, কেবল শক্তি এবং মডেলাস গাণিতিক অপারেটর ব্যবহার করে।

আসুন আমরা বলি যে আমরা জানতে চাই যে 'টেম্প' এর এনথ বিট সেট আছে কি না। অন্যথায় 0 বিট সেট করা থাকলে নীচের বুলিয়ান এক্সপ্রেশনটি সত্য দেয়।

  • (অস্থায়ী মডুলাস 2 ^ এন + 1> = 2 ^ এন)

নিম্নলিখিত উদাহরণ বিবেচনা করুন:

  • int temp = 0x5E; // ইন বাইনারি 0 বি 1011110 // বিআইটি 0 হ'ল এলএসবি

যদি আমি জানতে চাই যে ২ য় বিট সেট করা আছে কি না, আমি পাই

  • (94 মডেল 16) = 14> 2 ^ 3

সুতরাং এক্সপ্রেশন সত্য ফিরে আসে, তৃতীয় বিট সেট করা ইঙ্গিত করে।


0

একটি পদ্ধতির নিম্নলিখিত শর্তের মধ্যে পরীক্ষা করা হবে:

if ( (mask >> bit ) & 1)

একটি ব্যাখ্যা প্রোগ্রাম হবে:

#include <stdio.h>

unsigned int bitCheck(unsigned int mask, int pin);

int main(void){
   unsigned int mask = 6;  // 6 = 0110
   int pin0 = 0;
   int pin1 = 1;
   int pin2 = 2;
   int pin3 = 3;
   unsigned int bit0= bitCheck( mask, pin0);
   unsigned int bit1= bitCheck( mask, pin1);
   unsigned int bit2= bitCheck( mask, pin2);
   unsigned int bit3= bitCheck( mask, pin3);

   printf("Mask = %d ==>>  0110\n", mask);

   if ( bit0 == 1 ){
      printf("Pin %d is Set\n", pin0);
   }else{
      printf("Pin %d is not Set\n", pin0);
   }

    if ( bit1 == 1 ){
      printf("Pin %d is Set\n", pin1);
   }else{
      printf("Pin %d is not Set\n", pin1);
   }

   if ( bit2 == 1 ){
      printf("Pin %d is Set\n", pin2);
   }else{
      printf("Pin %d is not Set\n", pin2);
   }

   if ( bit3 == 1 ){
      printf("Pin %d is Set\n", pin3);
   }else{
      printf("Pin %d is not Set\n", pin3);
   }
}

unsigned int bitCheck(unsigned int mask, int bit){
   if ( (mask >> bit ) & 1){
      return 1;
   }else{
      return 0;
   }
}

আউটপুট:

Mask = 6 ==>>  0110
Pin 0 is not Set
Pin 1 is Set
Pin 2 is Set
Pin 3 is not Set


-1

আমি এটি তৈরি:

LATGbits.LATG0 = ((M & 0x8)> 0); // মিটের বিট -2 1 হয় কিনা তা পরীক্ষা করতে


-2

দ্রুততম উপায়টি মাস্কগুলির জন্য একটি টেবিল হিসাবে মনে হচ্ছে

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.