c++ आप एक बिट को कैसे सेट, साफ़ और टॉगल करते हैं?




bit-manipulation bitwise-operators (21)

सी / सी ++ में थोड़ा सा सेट, साफ़ और टॉगल कैसे करते हैं?


यहां कुछ मैक्रोज़ हैं जिनका मैं उपयोग करता हूं:

SET_FLAG(Status, Flag)            ((Status) |= (Flag))
CLEAR_FLAG(Status, Flag)          ((Status) &= ~(Flag))
INVALID_FLAGS(ulFlags, ulAllowed) ((ulFlags) & ~(ulAllowed))
TEST_FLAGS(t,ulMask, ulBit)       (((t)&(ulMask)) == (ulBit))
IS_FLAG_SET(t,ulMask)             TEST_FLAGS(t,ulMask,ulMask)
IS_FLAG_CLEAR(t,ulMask)           TEST_FLAGS(t,ulMask,0)

एक सी ++ 11 टेम्पलेटेड संस्करण (हेडर में डाला गया):

namespace bit {
    template <typename T1, typename T2> inline void set  (T1 &variable, T2 bit) {variable |=  ((T1)1 << bit);}
    template <typename T1, typename T2> inline void clear(T1 &variable, T2 bit) {variable &= ~((T1)1 << bit);}
    template <typename T1, typename T2> inline void flip (T1 &variable, T2 bit) {variable ^=  ((T1)1 << bit);}
    template <typename T1, typename T2> inline bool test (T1 &variable, T2 bit) {return variable & ((T1)1 << bit);}
}

namespace bitmask {
    template <typename T1, typename T2> inline void set  (T1 &variable, T2 bits) {variable |= bits;}
    template <typename T1, typename T2> inline void clear(T1 &variable, T2 bits) {variable &= ~bits;}
    template <typename T1, typename T2> inline void flip (T1 &variable, T2 bits) {variable ^= bits;}
    template <typename T1, typename T2> inline bool test_all(T1 &variable, T2 bits) {return ((variable & bits) == bits);}
    template <typename T1, typename T2> inline bool test_any(T1 &variable, T2 bits) {return variable & bits;}
}

परिवर्तनीय इस्तेमाल किया

int value, pos;

मूल्य - डेटा
पॉज़ - बिट की स्थिति जिसे हम सेट करना चाहते हैं, साफ़ करें या टॉगल
करें थोड़ा सेट करें

value = value | 1 << pos;

थोड़ा सा साफ़ करें

value = value & ~(1 << pos); 

थोड़ा टॉगल करें

value = value ^ 1 << pos;

मानक सी ++ लाइब्रेरी का उपयोग करना: std::bitset<N>

या Boost संस्करण: boost::dynamic_bitset

अपना खुद का रोल करने की कोई जरूरत नहीं है:

#include <bitset>
#include <iostream>

int main()
{
    std::bitset<5> x;

    x[1] = 1;
    x[2] = 0;
    // Note x[0-4]  valid

    std::cout << x << std::endl;
}
[Alpha:] > ./a.out
00010

बूस्ट संस्करण एक मानक लाइब्रेरी संकलन-समय के आकार के बिट्ससेट की तुलना में रनटाइम आकार की बिटसेट की अनुमति देता है।


अधिक सामान्य, मनमानी आकार के बिटमैप्स के लिए:

#define BITS 8
#define BIT_SET(  p, n) (p[(n)/BITS] |=  (0x80>>((n)%BITS)))
#define BIT_CLEAR(p, n) (p[(n)/BITS] &= ~(0x80>>((n)%BITS)))
#define BIT_ISSET(p, n) (p[(n)/BITS] &   (0x80>>((n)%BITS)))

यदि आप बहुत कम काम कर रहे हैं तो आप मास्क का उपयोग करना चाहेंगे जो पूरी चीज को तेज कर देगा। निम्नलिखित कार्य बहुत तेज़ हैं और अभी भी लचीले हैं (वे किसी भी आकार के बिट मैप्स में बिट ट्विडलिंग की अनुमति देते हैं)।

const unsigned char TQuickByteMask[8] =
{
   0x01, 0x02, 0x04, 0x08,
   0x10, 0x20, 0x40, 0x80,
};


/** Set bit in any sized bit mask.
 *
 * @return    none
 *
 * @param     bit    - Bit number.
 * @param     bitmap - Pointer to bitmap.
 */
void TSetBit( short bit, unsigned char *bitmap)
{
    short n, x;

    x = bit / 8;        // Index to byte.
    n = bit % 8;        // Specific bit in byte.

    bitmap[x] |= TQuickByteMask[n];        // Set bit.
}


/** Reset bit in any sized mask.
 *
 * @return  None
 *
 * @param   bit    - Bit number.
 * @param   bitmap - Pointer to bitmap.
 */
void TResetBit( short bit, unsigned char *bitmap)
{
    short n, x;

    x = bit / 8;        // Index to byte.
    n = bit % 8;        // Specific bit in byte.

    bitmap[x] &= (~TQuickByteMask[n]);    // Reset bit.
}


/** Toggle bit in any sized bit mask.
 *
 * @return   none
 *
 * @param   bit    - Bit number.
 * @param   bitmap - Pointer to bitmap.
 */
void TToggleBit( short bit, unsigned char *bitmap)
{
    short n, x;

    x = bit / 8;        // Index to byte.
    n = bit % 8;        // Specific bit in byte.

    bitmap[x] ^= TQuickByteMask[n];        // Toggle bit.
}


/** Checks specified bit.
 *
 * @return  1 if bit set else 0.
 *
 * @param   bit    - Bit number.
 * @param   bitmap - Pointer to bitmap.
 */
short TIsBitSet( short bit, const unsigned char *bitmap)
{
    short n, x;

    x = bit / 8;    // Index to byte.
    n = bit % 8;    // Specific bit in byte.

    // Test bit (logigal AND).
    if (bitmap[x] & TQuickByteMask[n])
        return 1;

    return 0;
}


/** Checks specified bit.
 *
 * @return  1 if bit reset else 0.
 *
 * @param   bit    - Bit number.
 * @param   bitmap - Pointer to bitmap.
 */
short TIsBitReset( short bit, const unsigned char *bitmap)
{
    return TIsBitSet(bit, bitmap) ^ 1;
}


/** Count number of bits set in a bitmap.
 *
 * @return   Number of bits set.
 *
 * @param    bitmap - Pointer to bitmap.
 * @param    size   - Bitmap size (in bits).
 *
 * @note    Not very efficient in terms of execution speed. If you are doing
 *        some computationally intense stuff you may need a more complex
 *        implementation which would be faster (especially for big bitmaps).
 *        See (http://graphics.stanford.edu/~seander/bithacks.html).
 */
int TCountBits( const unsigned char *bitmap, int size)
{
    int i, count = 0;

    for (i=0; i<size; i++)
        if (TIsBitSet(i, bitmap))
            count++;

    return count;
}

नोट, 16 बिट पूर्णांक में बिट 'n' सेट करने के लिए आप निम्न कार्य करते हैं:

TSetBit( n, &my_int);

यह सुनिश्चित करने के लिए आप पर निर्भर है कि बिट संख्या आपके द्वारा पास किए गए बिट मैप की सीमा के भीतर है। ध्यान दें कि छोटे एंडियन प्रोसेसर जो बाइट्स, शब्द, पासवर्ड, क्वॉर्ड्स इत्यादि के लिए स्मृति में एक-दूसरे के लिए सही ढंग से मानचित्र करते हैं (मुख्य कारण यह है कि छोटे एंडियन प्रोसेसर बड़े-एंडियन प्रोसेसर की तुलना में 'बेहतर' हैं, आह, मुझे एक लौ युद्ध आ रहा है पर...)।


int set_nth_bit(int num, int n){

    return (num | 1 << n);
}

int clear_nth_bit(int num, int n){

    return (num & ~( 1 << n));
}

int toggle_nth_bit(int num, int n){

    return num ^ (1 << n);
}

int check_nth_bit(int num, int n){

    return num & (1 << n);
}

आप एक बिट को कैसे सेट, साफ़ और टॉगल करते हैं?

मास्क बनाने का प्रयास करते समय एक सामान्य कोडिंग पिटफॉल को संबोधित करने के लिए:
1हमेशा पर्याप्त चौड़ा नहीं होता है

numberएक व्यापक प्रकार की तुलना में क्या समस्याएं होती हैं 1?
xशिफ्ट के 1 << xलिए अपरिभाषित व्यवहार (यूबी) की ओर अग्रसर होने के लिए बहुत अच्छा हो सकता है । यहां तक ​​कि यदि xबहुत अच्छा नहीं है, तो भी ~पर्याप्त-महत्वपूर्ण-बिट्स को फ़्लिप नहीं कर सकता है।

// assume 32 bit int/unsigned
unsigned long long number = foo();

unsigned x = 40; 
number |= (1 << x);  // UB
number ^= (1 << x);  // UB
number &= ~(1 << x); // UB

x = 10;
number &= ~(1 << x); // Wrong mask, not wide enough

बीमा करने के लिए पर्याप्त चौड़ा है:

कोड उपयोग 1ullया पैडेंटिक रूप से (uintmax_t)1और संकलक अनुकूलित करने दे सकता है।

number |= (1ull << x);
number |= ((uintmax_t)1 << x);

या कास्ट - जो कोड को सही और अद्यतित रखने के लिए कोडिंग / समीक्षा / रखरखाव के मुद्दों के लिए बनाता है।

number |= (type_of_number)1 << x;

या धीरे-धीरे 1गणित के संचालन को मजबूर कर बढ़ावा दें जो कि कम से कम चौड़ा है number

number |= (number*0 + 1) << x;

सबसे अधिक कुशलता के साथ , हस्ताक्षरित लोगों की बजाय हस्ताक्षरित प्रकारों के साथ काम करने के लिए सबसे अच्छा है


बिटफील्ड दृष्टिकोण में एम्बेडेड क्षेत्र में अन्य फायदे हैं। आप एक ऐसी संरचना को परिभाषित कर सकते हैं जो सीधे किसी विशेष हार्डवेयर रजिस्टर में बिट्स पर मैप करें।

struct HwRegister {
    unsigned int errorFlag:1;  // one-bit flag field
    unsigned int Mode:3;       // three-bit mode field
    unsigned int StatusCode:4;  // four-bit status code
};

struct HwRegister CR3342_AReg;

आपको बिट पैकिंग ऑर्डर से अवगत होना चाहिए - मुझे लगता है कि यह एमएसबी पहले है, लेकिन यह कार्यान्वयन-निर्भर हो सकता है। साथ ही, सत्यापित करें कि आपके कंपाइलर हैंडलर फ़ील्ड बाइट सीमाओं को पार करते हैं।

फिर आप पहले के रूप में व्यक्तिगत मानों को पढ़, लिख सकते हैं, परीक्षण कर सकते हैं।


कभी-कभी बिट्स नाम देने के लिए एक enum का उपयोग करने लायक है:

enum ThingFlags = {
  ThingMask  = 0x0000,
  ThingFlag0 = 1 << 0,
  ThingFlag1 = 1 << 1,
  ThingError = 1 << 8,
}

फिर बाद में नामों का उपयोग करें। मैं लिखता हूँ

thingstate |= ThingFlag1;
thingstate &= ~ThingFlag0;
if (thing & ThingError) {...}

सेट, स्पष्ट और परीक्षण करने के लिए। इस तरह आप अपने शेष कोड से जादू संख्या छुपाते हैं।

इसके अलावा मैं जेरेमी के समाधान का समर्थन करता हूं।


यह प्रोग्राम 0 से 1 या 1 से 0 तक किसी भी डेटा बिट को बदलना है:

{
    unsigned int data = 0x000000F0;
    int bitpos = 4;
    int bitvalue = 1;
    unsigned int bit = data;
    bit = (bit>>bitpos)&0x00000001;
    int invbitvalue = 0x00000001&(~bitvalue);
    printf("%x\n",bit);

    if (bitvalue == 0)
    {
        if (bit == 0)
            printf("%x\n", data);
        else
        {
             data = (data^(invbitvalue<<bitpos));
             printf("%x\n", data);
        }
    }
    else
    {
        if (bit == 1)
            printf("elseif %x\n", data);
        else
        {
            data = (data|(bitvalue<<bitpos));
            printf("else %x\n", data);
        }
    }
}

शुरुआत के लिए मैं एक उदाहरण के साथ थोड़ा और समझाना चाहता हूं:

उदाहरण:

value is 0x55;
bitnum : 3rd.

ऑपरेटर का उपयोग किया जाता है बिट की जांच करें:

0101 0101
&
0000 1000
___________
0000 0000 (mean 0: False). It will work fine if the third bit is 1 (then the answer will be True)

टॉगल या फ्लिप करें:

0101 0101
^
0000 1000
___________
0101 1101 (Flip the third bit without affecting other bits)

| ऑपरेटर: बिट सेट करें

0101 0101
|
0000 1000
___________
0101 1101 (set the third bit without affecting other bits)

मैं बिट सेट को संभालने और साफ़ करने के लिए हेडर फ़ाइल में परिभाषित मैक्रोज़ का उपयोग करता हूं:

/* a=target variable, b=bit number to act upon 0-n */
#define BIT_SET(a,b) ((a) |= (1ULL<<(b)))
#define BIT_CLEAR(a,b) ((a) &= ~(1ULL<<(b)))
#define BIT_FLIP(a,b) ((a) ^= (1ULL<<(b)))
#define BIT_CHECK(a,b) (!!((a) & (1ULL<<(b))))        // '!!' to make sure this returns 0 or 1

/* x=target variable, y=mask */
#define BITMASK_SET(x,y) ((x) |= (y))
#define BITMASK_CLEAR(x,y) ((x) &= (~(y)))
#define BITMASK_FLIP(x,y) ((x) ^= (y))
#define BITMASK_CHECK_ALL(x,y) (((x) & (y)) == (y))   // warning: evaluates y twice
#define BITMASK_CHECK_ANY(x,y) ((x) & (y))

यदि आप लिनक्स कर्नेल में सी प्रोग्रामिंग के साथ यह सब ऑपरेशन करना चाहते हैं तो मैं लिनक्स कर्नेल के मानक एपीआई का उपयोग करने का सुझाव देता हूं।

https://www.kernel.org/doc/htmldocs/kernel-api/ch02s03.html देखेंhttps://www.kernel.org/doc/htmldocs/kernel-api/ch02s03.html

set_bit  Atomically set a bit in memory
clear_bit  Clears a bit in memory
change_bit  Toggle a bit in memory
test_and_set_bit  Set a bit and return its old value
test_and_clear_bit  Clear a bit and return its old value
test_and_change_bit  Change a bit and return its old value
test_bit  Determine whether a bit is set

नोट: यहां पूरा ऑपरेशन एक ही चरण में होता है। इसलिए इन सभी को एसएमपी कंप्यूटरों पर भी परमाणु होने की गारंटी है और प्रोसेसर में समेकन रखने के लिए उपयोगी हैं।


इसे इस्तेमाल करो:

int ToggleNthBit ( unsigned char n, int num )
{
    if(num & (1 << n))
        num &= ~(1 << n);
    else
        num |= (1 << n);

    return num;
}

विजुअल सी 2010, और शायद कई अन्य कंपाइलर्स, में निर्मित बिट ऑपरेशंस के लिए सीधा समर्थन है। आश्चर्यजनक रूप से, यह काम करता है, आकार का () ऑपरेटर ठीक से काम करता है।

bool    IsGph[256], IsNotGph[256];

//  Initialize boolean array to detect printable characters
for(i=0; i<sizeof(IsGph); i++)  {
    IsGph[i] = isgraph((unsigned char)i);
}

तो, आपके प्रश्न के लिए, IsGph [i] = 1, या IsGph [i] = 0 सेटिंग और साफ़ करने वाले बूल को आसान बनाते हैं।

अप्राप्य पात्र खोजने के लिए ...

//  Initialize boolean array to detect UN-printable characters, 
//  then call function to toggle required bits true, while initializing a 2nd
//  boolean array as the complement of the 1st.
for(i=0; i<sizeof(IsGph); i++)  {
    if(IsGph[i])    {
         IsNotGph[i] = 0;
    }   else   {
         IsNotGph[i] = 1;
    }
}

ध्यान दें कि इस कोड के बारे में कुछ भी "विशेष" नहीं है। यह एक पूर्णांक की तरह थोड़ा व्यवहार करता है - जो तकनीकी रूप से, यह है। एक 1 बिट पूर्णांक जो केवल 2 मान, और 2 मान रख सकता है।

मैंने एक बार डुप्लिकेट ऋण रिकॉर्ड खोजने के लिए इस दृष्टिकोण का उपयोग किया, जहां 6-अंकों की ऋण संख्या का उपयोग बिट सरणी में इंडेक्स के रूप में किया गया था, जहां ऋण_नंबर आईएसएएम कुंजी था। सख्ती से तेज़, और 8 महीनों के बाद, साबित हुआ कि जिस मेनफ्रेम सिस्टम से हम डेटा प्राप्त कर रहे थे वह वास्तव में खराब हो रहा था। बिट सरणी की सादगी उनकी शुद्धता में बहुत अधिक आत्मविश्वास बनाती है - उदाहरण के लिए एक खोज दृष्टिकोण बनाम।


यहां मेरा पसंदीदा बिट अंकगणितीय मैक्रो है, जो किसी भी प्रकार के हस्ताक्षरित पूर्णांक सरणी के लिए unsigned char से size_t तक काम करता है (जो सबसे बड़ा प्रकार है जो काम करने के लिए कुशल होना चाहिए):

#define BITOP(a,b,op) \
 ((a)[(size_t)(b)/(8*sizeof *(a))] op ((size_t)1<<((size_t)(b)%(8*sizeof *(a)))))

थोड़ा सेट करने के लिए:

BITOP(array, bit, |=);

थोड़ा सा साफ़ करने के लिए:

BITOP(array, bit, &=~);

थोड़ा टॉगल करने के लिए:

BITOP(array, bit, ^=);

थोड़ा परीक्षण करने के लिए:

if (BITOP(array, bit, &)) ...

आदि।


दूसरा विकल्प बिट फ़ील्ड का उपयोग करना है:

struct bits {
    unsigned int a:1;
    unsigned int b:1;
    unsigned int c:1;
};

struct bits mybits;

एक 3-बिट फ़ील्ड को परिभाषित करता है (वास्तव में, यह तीन 1-बिट फ्लेड्स है)। बिट ऑपरेशन अब थोड़ा सा (हाहा) बन गया है:

थोड़ा सेट या साफ़ करने के लिए:

mybits.b = 1;
mybits.c = 0;

थोड़ा टॉगल करने के लिए:

mybits.a = !mybits.a;
mybits.b = ~mybits.b;
mybits.c ^= 1;  /* all work */

थोड़ा सा जांचना:

if (mybits.c)  //if mybits.c is non zero the next line below will execute

यह केवल निश्चित आकार के बिट फ़ील्ड के साथ काम करता है। अन्यथा आपको पिछली पोस्ट में वर्णित बिट-ट्विडलिंग तकनीकों का सहारा लेना होगा।


snip-c.zip के bitops.h से:

/*
**  Bit set, clear, and test operations
**
**  public domain snippet by Bob Stout
*/

typedef enum {ERROR = -1, FALSE, TRUE} LOGICAL;

#define BOOL(x) (!(!(x)))

#define BitSet(arg,posn) ((arg) | (1L << (posn)))
#define BitClr(arg,posn) ((arg) & ~(1L << (posn)))
#define BitTst(arg,posn) BOOL((arg) & (1L << (posn)))
#define BitFlp(arg,posn) ((arg) ^ (1L << (posn)))

ठीक है, आइए चीजों का विश्लेषण करें ...

आम अभिव्यक्ति जो आपको इनमें से सभी में समस्याएं आ रही हैं "(1 एल << (posn))" है। यह सब एक बिट के साथ एक मुखौटा बना है और जो किसी भी पूर्णांक प्रकार के साथ काम करेगा। "Posn" तर्क उस स्थिति को निर्दिष्ट करता है जहां आप थोड़ा चाहते हैं। यदि posn == 0 है, तो यह अभिव्यक्ति मूल्यांकन करेगी:

    0000 0000 0000 0000 0000 0000 0000 0001 binary.

यदि posn == 8, तो इसका मूल्यांकन होगा

    0000 0000 0000 0000 0000 0001 0000 0000 binary.

दूसरे शब्दों में, यह बस निर्दिष्ट स्थिति में 1 के साथ 0 का क्षेत्र बनाता है। एकमात्र मुश्किल हिस्सा बिटक्लर () मैक्रो में है जहां हमें 1 के क्षेत्र में एक 0 बिट सेट करने की आवश्यकता है। यह tilde (~) ऑपरेटर द्वारा बताए गए समान अभिव्यक्ति के 1 के पूरक का उपयोग करके पूरा किया जाता है।

एक बार मास्क बनने के बाद, जैसा कि आप सुझाव देते हैं, बिटवाई और (&), या (|), और xor (^) ऑपरेटरों के उपयोग से, यह तर्क पर लागू होता है। चूंकि मुखौटा लंबा प्रकार का होता है, इसलिए मैक्रोज़ चारों के साथ-साथ चार, शॉर्ट्स, इंट, या लांग पर भी काम करेगा।

निचली पंक्ति यह है कि यह समस्याओं की एक पूरी कक्षा का एक सामान्य समाधान है। यह निश्चित रूप से संभव है, जब भी आपको आवश्यकता हो, स्पष्ट मास्क मानों के साथ इनमें से किसी भी मैक्रोज़ के समकक्ष को फिर से लिखना उचित हो, लेकिन यह क्यों? याद रखें, मैक्रो प्रतिस्थापन प्रीप्रोसेसर में होता है और इसलिए जेनरेट कोड इस तथ्य को प्रतिबिंबित करेगा कि मानकों को स्थिरता द्वारा स्थिर माना जाता है - यानी यह सामान्यीकृत मैक्रोज़ का उपयोग करने के लिए उतना ही कुशल है जितना कि आपको हर बार "पहिया को फिर से शुरू करना" थोड़ा हेरफेर करो।

असंतुष्ट? यहां कुछ टेस्ट कोड हैं - मैंने पूर्ण अनुकूलन के साथ वाटकॉम सी का उपयोग किया और _cdecl का उपयोग किए बिना परिणामस्वरूप डिस्सेप्लर जितना संभव हो उतना साफ होगा:

---- [टेस्ट.सी] ----------------------------------------- -----------------------

#define BOOL(x) (!(!(x)))

#define BitSet(arg,posn) ((arg) | (1L << (posn)))
#define BitClr(arg,posn) ((arg) & ~(1L << (posn)))
#define BitTst(arg,posn) BOOL((arg) & (1L << (posn)))
#define BitFlp(arg,posn) ((arg) ^ (1L << (posn)))

int bitmanip(int word)
{
      word = BitSet(word, 2);
      word = BitSet(word, 7);
      word = BitClr(word, 3);
      word = BitFlp(word, 9);
      return word;
}

---- [टेस्ट.ओयूटी (डिससेम्बल)] -------------------------------------- ---------

Module: C:\BINK\tst.c
Group: 'DGROUP' CONST,CONST2,_DATA,_BSS

Segment: _TEXT  BYTE   00000008 bytes  
 0000  0c 84             bitmanip_       or      al,84H    ; set bits 2 and 7
 0002  80 f4 02                          xor     ah,02H    ; flip bit 9 of EAX (bit 1 of AH)
 0005  24 f7                             and     al,0f7H
 0007  c3                                ret     

No disassembly errors

---- [फिनिस] ------------------------------------------- ----------------------


चूंकि इसे "एम्बेडेड" टैग किया गया है, मुझे लगता है कि आप एक माइक्रोकंट्रोलर का उपयोग कर रहे हैं। उपर्युक्त सभी सुझाव मान्य और काम हैं (पढ़ना-संशोधित-लेखन, संघ, structs, आदि)।

हालांकि, ऑसिलोस्कोप-आधारित डिबगिंग के झुकाव के दौरान मैं यह जानकर आश्चर्यचकित हुआ कि इन विधियों के पास सीपीयू चक्रों में काफी ऊंचा है, जो सीधे माइक्रो के पोर्टनसेट / पोर्टनक्लेयर रजिस्टरों के लिए एक मूल्य लिखने की तुलना में काफी हद तक है, जो एक वास्तविक अंतर बनाता है जहां तंग लूप / उच्च हैं -फ्रीक्वेंसी आईएसआर के टॉगलिंग पिन।

उन अपरिचित लोगों के लिए: मेरे उदाहरण में, माइक्रो में एक सामान्य पिन-स्टेट रजिस्टर पोर्टन होता है जो आउटपुट पिन को प्रतिबिंबित करता है, इसलिए पोर्टिंग | = BIT_TO_SET परिणाम उस रजिस्टर को पढ़ने-संशोधित-लिखने में परिणाम देता है। हालांकि, पोर्ट्ससेट / पोर्टनक्लेयर रजिस्टरों का अर्थ है 'कृपया इसे थोड़ा करें "(एसईटी) या" कृपया इसे थोड़ा सा करें "(साफ़ करें) और' 0 'का अर्थ" पिन को अकेला छोड़ दें "। इसलिए, आप दो पोर्ट पतों के साथ समाप्त होते हैं, भले ही आप बिट को सेट या साफ़ कर रहे हों (हमेशा सुविधाजनक नहीं) लेकिन एक बहुत तेज प्रतिक्रिया और छोटे संयोजन कोड।


एन बिट बदलने के लिए सी भाषा में इन कार्यों में से किसी एक को आज़माएं:

char bitfield;

// Start at 0th position

void chang_n_bit(int n, int value)
{
    bitfield = (bitfield | (1 << n)) & (~( (1 << n) ^ (value << n) ));
}

या

void chang_n_bit(int n, int value)
{
    bitfield = (bitfield | (1 << n)) & ((value << n) | ((~0) ^ (1 << n)));
}

या

void chang_n_bit(int n, int value)
{
    if(value)
        bitfield |= 1 << n;
    else
        bitfield &= ~0 ^ (1 << n);
}

char get_n_bit(int n)
{
    return (bitfield & (1 << n)) ? 1 : 0;
}




bitwise-operators