C / C ++ जांचें कि क्या एक बिट में सेट किया गया है, यानी इंट चर


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)

C ++ में, आप std :: bitet का उपयोग कर सकते हैं ।


3
यदि आपको एक साधारण सत्य मूल्य की आवश्यकता है, तो यह होना चाहिए !! ((var) & (1 << (pos)))।
एडुआर्ड - गेब्रियल मुंटेनू

10
@ एडवर्ड: सी में, सब कुछ != 0सच है, तो परेशान क्यों? 1वास्तव में के रूप में सच है 0.1415!
क्रिस्टोफ

1
और यदि आप C ++ का उपयोग कर रहे हैं, तो आप मैक्रो के बजाय एक टेम्प्लेट लिख सकते हैं। :)
जुलफ

2
C में यह ठीक है। लेकिन इस तरह के मैक्रोज़ C ++ में। यह भयानक है और इसलिए दुरुपयोग के लिए खुला है। एसटीडी का प्रयोग करें :: बिटसेट
मार्टिन

5
ऊ, std::bitsetसचमुच? ज़रूर, एक छोटा सा काम करने के बजाय (और संभावित रूप से कुछ बहुत अच्छे टेम्पलेट) एक बिट की जांच करने के लिए, एक फूला हुआ कंटेनर का उपयोग करें जो अन्यथा अप्रयुक्त में प्रत्येक 'बिट' को संग्रहीत करता है unsigned long। एक स्थान बेकार हो जया!
अंडरस्कोर_ड

86

जांचें कि क्या बिट एन (0 से शुरू) सेट है:

temp & (1 << N)

इसके लिए कोई बिल्टइन फंक्शन नहीं है।


16
+1 का उल्लेख करने के लिए यह 0 से शुरू हो रहा है क्योंकि मुझे संदेह है कि ओपी 1-आधारित सोच रहा था और स्वीकृत उत्तर उसे परेशानी में डाल देगा। :)
जिम बक

हम्म। यह 0 से क्यों शुरू हो रहा है? हमें क्या मिलता है जब 1 << 0?? क्षमा करें, भ्रमित।
दानीजेल

6
ठीक मिल गया। हम 0 वें स्थान से शुरू करते हैं 1<<0, जो कि बिना किसी बदलाव के 1 है (शिफ्ट 0), जो है1<<0 == 1
Danijel

27

मैं बस एक std :: बिटसेट का उपयोग करूंगा यदि यह C ++ है। सरल। सीधी-सपाट। बेवकूफ त्रुटियों के लिए कोई मौका नहीं।

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
@ user21714 मुझे लगता है कि आप का मतलब है std :: बिटसेट <8 * sizeof (int)>
iNFINITEi

or std :: num_limits <int> :: अंक
Léo Lam

@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 बिट पूर्णांक रहता है।
  • मेरी जानकारी और सहमति के बिना IsBitSet (int32, int64) कॉल का पता लगाता है।
  • इच्छुक टेम्पलेट, इसलिए कोई फ़ंक्शन ओवरहेड कॉलिंग नहीं करता है।
  • const और संदर्भ, इसलिए कुछ भी नकल / नकल करने की आवश्यकता नहीं है । और हम गारंटी देते हैं कि संकलक किसी भी टाइपो को उठाएगा जो तर्कों को बदलने का प्रयास करेगा।
  • 0! = कोड को अधिक स्पष्ट और स्पष्ट बनाता है। कोड लिखने के लिए प्राथमिक बिंदु हमेशा अन्य प्रोग्रामर के साथ स्पष्ट रूप से और कुशलता से संवाद करना है, जिसमें कम कौशल भी शामिल है।
  • इस विशेष मामले पर लागू नहीं होने पर ... सामान्य रूप से, अस्थायी कार्य कई बार तर्कों के मूल्यांकन के मुद्दे से बचते हैं। कुछ #define मैक्रो के साथ एक ज्ञात समस्या।
    जैसे: #define ABS (X) (((X) <0); - (X): (X))
          ABS (i ++);

13

चयनित उत्तर जो कर रहा है वह वास्तव में गलत है। नीचे दिए गए फ़ंक्शन बिट स्थिति या 0 पर निर्भर करेगा यदि बिट वास्तव में सक्षम है। यह वह नहीं है जो पोस्टर के लिए पूछ रहा था।

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

यहाँ वही है जो पोस्टर मूल रूप से देख रहा था। नीचे फ़ंक्शन 1 या 0 पर वापस आ जाएगा यदि बिट सक्षम है और स्थिति नहीं है।

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

1
मुझे समझने में कुछ समय लगा जब तक कि आपका मतलब नहीं है। अधिक सटीक: पहला फ़ंक्शन बिट स्थिति की शक्ति पर 2 लौटाता है यदि बिट सेट है, तो अन्यथा।
lukasl1991

1
यह सटीक मुद्दा है जिसका मैंने अभी सामना किया है जबकि bool has_feature = CHECK_BIT(register, 25);गुड की तरह इसका उपयोग करते हुए यह जानने के लिए कि मैं इसे डबल-नेगेट के बिना कर सकता हूं।
जिममोइयो

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

एसटीडी :: बिटसेट का उपयोग करें

#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 बिट देगा - एलएसबी से एमएसबी तक की गिनती। इसे शिथिल करने के लिए, यह आपको दाईं से बाईं ओर गिनती की 4 बिट देगा। इसके अलावा, sizeof (int) एक इंट में वर्णों की संख्या देता है, इसलिए इसे std :: बिटसेट <sizeof (int) * CHAR_BITS> बिट्स (अस्थायी) और बिट्स [sizeof (int) * CHARBITS - 3] करने की आवश्यकता होगी MSB से LSB तक की 3 जी बिट काउंटिंग का परीक्षण करना, जो कि शायद इरादा है।
प्लास्टिक क्रिस

2
हां, लेकिन मुझे लगता है कि प्रश्नकर्ता (और Google खोजों से आने वाले लोग) के पास वह कौशल नहीं हो सकता है, और आपका उत्तर उन्हें भ्रमित कर सकता है।
प्लास्टिक क्रिस

यह उत्तर भयानक है। इसे हटा देना चाहिए।
एडम बैरी

क्या मूल्य tempको "बिग-एंडियन" बनाने के लिए प्रतिबिंबित करने की आवश्यकता नहीं है ?
jww

4

अर्थात्, _bittest आंतरिक निर्देश है।


3
लिंक "Microsoft विशिष्ट" इंगित करता है। इसका उपयोग केवल तभी करें जब आपको पोर्टेबल होने के लिए अपने कोड की आवश्यकता न हो।
मौविसील

लिंक "Microsoft विशिष्ट" इंगित करता है, लेकिन यह इंटेल C ++ कंपाइलर से लिया गया एक आंतरिक है, और इसका परिणाम बीटी निर्देश है, इसलिए आप इसे इनलाइन कोडांतरक के साथ भी कर सकते हैं। बेशक, यह इसे और अधिक पोर्टेबल नहीं बनाता है।
डेव वान डेन आइंडी

1
यह x86 आर्किटेक्चर के लिए भी विशिष्ट है। तो नहीं, निश्चित रूप से पोर्टेबल नहीं है।
jalf

मुझे यकीन है कि अन्य आर्किटेक्चर के पास समान विकल्प हैं।
डेव वान डेन आइंडी

आंतरिक का बहुत बिंदु यह है कि वे हार्डवेयर का लाभ उठाते हैं यदि यह मौजूद है, और सॉफ़्टवेयर प्रतिस्थापन का उपयोग करें यदि हार्डवेयर इसे संभाल नहीं करता है।
ग्रहण

4

मैं इसका उपयोग करता हूं:

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

जहाँ "स्थिति" को 2 ^ n (ig 1,2,4,8,16,32 ...) के रूप में परिभाषित किया गया है

रिटर्न: 1 अगर सच 0 अगर गलत है


2
मुझे लगता है कि यह C और C ++ दोनों के लिए एकमात्र सही उत्तर है। यह केवल एक ही है जो "... बिना थोड़ा शिफ्टिंग और मास्किंग" की आवश्यकता का सम्मान करता है । शायद आपको स्पष्ट रूप से 4 = 2^(3-1)बिट स्थिति 3 के लिए उपयोग करना चाहिए क्योंकि यह प्रश्न का हिस्सा था।
jww

3

मैं एक 32-बिट पूर्णांक को पढ़ने की कोशिश कर रहा था, जिसने पीडीएफ में एक ऑब्जेक्ट के लिए झंडे को परिभाषित किया था और यह मेरे लिए काम नहीं कर रहा था

क्या यह परिभाषित बदल रहा था तय:

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

ऑपरेंड और दोनों में 1 में झंडे के साथ एक पूर्णांक देता है, और यह बूलियन में ठीक से कास्टिंग नहीं कर रहा था, इसने चाल बना दी


!= 0ऐसा ही होगा। पता नहीं कैसे उत्पन्न मशीन निर्देश भिन्न हो सकते हैं।
एडम बैरी

2

आप शिफ्टिंग और मास्किंग "अनुकरण" कर सकते हैं: यदि ((0x5e / (2 * 2 * 2))% 2 ...


हम बेतरतीब ढंग से फेरबदल करके एक सूची को सॉर्ट कर सकते हैं और यह देखने के लिए परीक्षण कर सकते हैं कि क्या यह अब "सॉर्ट किया गया" है। जैसे: जबकि (/ * Not * / /! IsSorted ()) {randomlyShuffle (); } लेकिन हम नहीं ...
मिस्टर

यह समाधान संसाधनों और unintuitive पर बेहद बेकार है। divs, muls और mods तीन सबसे महंगे कार्य हैं। तुलनात्मक परीक्षणों से, और ss और बदलाव सबसे सस्ते में से कुछ हैं - कुछ जो आप वास्तव में 5 से कम चक्रों में कर सकते हैं।
जेरिको

यह हो सकता है (और नहीं है, क्योंकि आधुनिक प्रोसेसर बिट्स और जंप का पता लगाते हैं)। ओपी ने मूल रूप से एक समाधान के लिए पूछा "बिट शिफ्टिंग और मास्किंग के बिना।" तो चलते हैं और एक मिलान लेकिन धीमी गति से जवाब के लिए और अधिक नकारात्मक अंक दे। मैं पोस्ट को सिर्फ इसलिए नहीं हटाऊंगा क्योंकि ओपी ने अपना विचार बदल दिया था।
लियोनिडस

यह मुश्किल लग रहा है। चलिए इस जवाब को मत मानिए। कभी-कभी अन्य विचारों का पता लगाना अच्छा होता है।
वियतनाम

2

निम्न-स्तर x86 विशिष्ट समाधान के लिए x86 TEST opcode का उपयोग करें ।

आपके कंपाइलर को _bittest को इस में बदलना चाहिए ...


मैं बीटी को टीईटी से अधिक पसंद करूंगा क्योंकि बीटी कार्य को बेहतर तरीके से फिट करता है।
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');:। आप का उपयोग करना चाहिए CHAR_BITसे निरंतर <climits>, वैसे भी बजाय कठिन कोडिंग 8 बिट की, हालांकि इस मामले में आप परिणाम पता 8 हो जाएगा के बाद से आप एक प्रयोग कर रहे हैंuint8_t
रयान हेनिंग

0

यदि आप बस एक वास्तविक हार्ड कोडित तरीका चाहते हैं:

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

ध्यान दें कि यह hw निर्भर है और इस बिट ऑर्डर को 32६५४ ३२१० मानता है और var and बिट है।

#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
& ऑपरेशन आंतरिक प्रतिनिधित्व पर नहीं मूल्यों पर किया जाता है।
Remo.D

हाय रेमो। डी - यकीन नहीं होता कि मैं आपकी टिप्पणी समझ रहा हूँ? मैंने कुछ 'c' कोड शामिल किए हैं जो ठीक काम करते हैं।
सिमोन

उनका कहना है कि यह हार्डवेयर पर निर्भर नहीं है - IS_BIT3_SET हमेशा 4 सबसे कम महत्वपूर्ण बिट का परीक्षण करेगा
ग्रहण

0

हालांकि अब जवाब देने में काफी देर हो चुकी है, एक सरल तरीका है जिससे यह पता लगाया जा सकता है कि Nth बिट सेट है या नहीं, बस POWER और MODULUS गणितीय ऑपरेटरों का उपयोग कर रहा है।

हम कहते हैं कि हम जानना चाहते हैं कि 'अस्थायी' में Nth बिट सेट है या नहीं। निम्नलिखित बूलियन अभिव्यक्ति सही है अगर बिट सेट है, 0 अन्यथा।

  • (अस्थायी मोड 2 ^ एन + 1> = 2 ^ एन)

निम्नलिखित उदाहरण पर विचार करें:

  • int अस्थायी = 0x5E; // बाइनरी में 0b1011110 // बीआईटी 0 एलएसबी है

अगर मैं जानना चाहता हूं कि 3rd बिट सेट है या नहीं, मुझे मिलता है

  • (94 मॉड्यूल्स 16) = 14> 2 ^ 3

तो अभिव्यक्ति सही है, यह दर्शाता है कि 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

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

स्थिति - 0 से स्ट्रेटिंग वाली बिट स्थिति।

रिटर्न 0 या 1।


-1

मैं इसे बनाता हूं:

LATGbits.LATG0 = ((मीटर और 0x8)> 0); // जाँच करने के लिए कि m का बिट -2 1 है


-2

सबसे तेज़ तरीका मास्क के लिए एक लुकअप टेबल लगता है

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.