ඔබ තනි බිට් එකක් සකසන්නේ කෙසේද, පැහැදිලි කරන්නේ සහ ටොගල් කරන්නේ කෙසේද?


2581

ඔබ ටිකක් සකසන්නේ කෙසේද, පැහැදිලි කරන්නේ සහ ටොගල් කරන්නේ කෙසේද?


65
: මෙය කියවිය graphics.stanford.edu/~seander/bithacks.html ඔබ මෙම ප්රගුණ කරන්නම් විට සහ, මේ එක කියවන්න: realtimecollisiondetection.net/blog/?p=78
ugasoft

Answers:


3611

ටිකක් සැකසීම

|ටිකක් සැකසීමට bitwise OR operator ( ) භාවිතා කරන්න .

number |= 1UL << n;

එමඟින් nතුන්වන කොටස සැකසෙනු ඇත number. nඔබ නියම කිරීමට අවශ්ය නම්, ශුන්ය විය යුතුය 1දක්වා මත එසේ වන bit සහ n-1ඔබ නියම කිරීමට අවශ්ය නම්, nවැනි ටිකක්.

වඩා පුළුල් 1ULLනම් භාවිතා කරන්න ; a හි පළලට වඩා මාරුවීම නිර්වචනය නොකළ හැසිරීම කොතැනදැයි තක්සේරු කිරීමෙන් පසුව ප්‍රවර්ධනය සිදු නොවේ . අනෙක් සියලුම උදාහරණ සඳහා ද එය අදාළ වේ.numberunsigned long1UL << n1UL << nlong

ටිකක් ඉවත් කිරීම

&ටිකක් ඉවත් කිරීමට bitwise AND operator ( ) භාවිතා කරන්න .

number &= ~(1UL << n);

nඒකෙන් ටිකක් ඉවත් වේවි number. ඔබ බිට්වේස් නොට් ක්‍රියාකරු ( ~) සමඟ බිට් ස්ට්‍රිං පෙරළා දැමිය යුතුය .

ටිකක් ටොගල් කරනවා

XOR ක්‍රියාකරු ( ^) ටිකක් ටොගල් කිරීමට භාවිතා කළ හැකිය.

number ^= 1UL << n;

ඒ අතර වමා ඇත nනමක ටිකක් number.

ටිකක් පරීක්ෂා කරනවා

ඔබ මෙය ඉල්ලා සිටියේ නැත, නමුත් මම එය එකතු කරමි.

ටිකක් පරික්ෂා කිරීම සඳහා, n අංකය දකුණට මාරු කරන්න, ඉන්පසු බිටුස් සහ එය:

bit = (number >> n) & 1U;

එමඟින් nth හි බිටු අගය numberවිචල්‍යයට ඇතුළත් bitවේ.

N වන බිට් x ට වෙනස් කිරීම

මෙම සැකසීම nඑක්කෝ වන ටිකක් 1හෝ 02 ගේ සහකාරියක් C ++ ක්රියාත්මක කිරීම පිළිබඳ පහත සඳහන් අත්පත් කළ හැක:

number ^= (-x ^ number) & (1UL << n);

ටිකක් nනම් තබා ඇත xවන 1, හා නම් ඉවත් xවේ 0. xවෙනත් වටිනාකමක් තිබේ නම් , ඔබට කුණු ලැබේ. x = !!xඑය 0 හෝ 1 දක්වා බූලියනීකරණය කරයි.

2 හි අනුපූරක නිෂේධන හැසිරීම් වලින් මෙය ස්වාධීන කිරීම සඳහා ( -11 හි අනුපූරකය හෝ සං sign ා / විශාලත්වය C ++ ක්‍රියාත්මක කිරීම මෙන් නොව සියලු බිටු සකසා ඇති තැන ), අත්සන් නොකළ නිෂේධනය භාවිතා කරන්න.

number ^= (-(unsigned long)x ^ number) & (1UL << n);

හෝ

unsigned long newbit = !!x;    // Also booleanize to force 0 or 1
number ^= (-newbit ^ number) & (1UL << n);

අතේ ගෙන යා හැකි බිට් හැසිරවීම සඳහා අත්සන් නොකළ වර්ග භාවිතා කිරීම සාමාන්‍යයෙන් හොඳ අදහසකි.

හෝ

number = (number & ~(1UL << n)) | (x << n);

(number & ~(1UL << n))nth බිට් එක ඉවත් කර th bit එක (x << n)සකසනු nඇත x.

පොදුවේ කේතය පිටපත් කිරීම / ඇලවීම නොකිරීමද හොඳ අදහසකි. එබැවින් බොහෝ අය පෙර සැකසුම් මැක්‍රෝස් ( ප්‍රජා විකිය තවදුරටත් පහළට පිළිතුරු දීම වැනි ) හෝ යම් ආකාරයක සංවර්‍ධනයක් භාවිතා කරයි.


129
බිට් සෙට් / පැහැදිලි (උදා, ඒවීආර් මයික්‍රොකොන්ට්රෝලර්) සඳහා ස්වදේශීය සහාය ඇති වේදිකාවල, සම්පාදකයින් බොහෝ විට 'මයිබයිට් | නියත, උදා: (1 << 5), හෝ const unsigned x = 5.
ආරොන්

52
bit = අංකය & (1 << x); බිට් _Bool (<stdbool.h>) වර්ගය නොමැති නම් බිට් x හි අගය බිට් බවට පත් නොකරනු ඇත. එසේ නොමැතිනම්, bit = !! (අංකය & (1 << x)); කැමැත්ත ..
ක්‍රිස් යං

23
ඇයි ඔබ අන්තිම එක වෙනස් නොකරන්නේbit = (number >> x) & 1
ආරොන්මන්

42
1යනු intවචනාර්ථයෙන්, අත්සන් කර ඇත. එබැවින් මෙහි සියලුම මෙහෙයුම් ක්‍රියාත්මක වන්නේ අත්සන් කළ අංක මත වන අතර එය ප්‍රමිතීන් විසින් මනාව අර්ථ දක්වා නොමැත. ප්‍රමිතීන් දෙදෙනෙකුගේ අනුපූරක හෝ ගණිත මාරුව සහතික නොකරන බැවින් එය භාවිතා කිරීම වඩා හොඳය 1U.
සියුවා රෙන්

50
මම කැමතියි number = number & ~(1 << n) | (x << n);n-th බිට් x ට වෙනස් කිරීමට.
ජියාස්ලි

461

සම්මත C ++ පුස්තකාලය භාවිතා කිරීම : 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

බූස්ට් අනුවාදය සම්මත පුස්තකාල සම්පාදක-කාල ප්‍රමාණයේ බිට්සෙට් සමඟ සසඳන විට ධාවන ප්‍රමාණයේ බිට්සෙට් එකකට ඉඩ දෙයි .


34
+1. Std :: bitset "C" වෙතින් භාවිතා කළ හැකි නොවේ, නමුත් කතුවරයා ඔහුගේ / ඇයගේ ප්‍රශ්නය "C ++", AFAIK සමඟ ටැග් කර ඇති පරිදි, ඔබේ පිළිතුර මෙහි හොඳම වේ ... std :: vector <bool> තවත් ක්‍රමයක්, එක් එහි වාසි සහ එහි අවාසි දන්නේ නම්
paercebal

23
@andrewdotnich: දෛශික <bool> යනු (අවාසනාවකට මෙන්) අගයන් බිටු ලෙස ගබඩා කරන විශේෂීකරණයකි. වැඩි විස්තර සඳහා gotw.ca/publications/mill09.htm බලන්න ...
Niklas

72
සමහර විට කිසිවෙකු එය සඳහන් කර නැති නිසා මෙය කාවැදී ඇත. බොහෝ කාවැද්දූ පද්ධති වලදී ඔබ වසංගතය වැනි STL වලින් වැළකී සිටියි. බොහෝ කාවැද්දූ සම්පාදකයින් අතර හඳුනා ගැනීමට ඉතා දුර්ලභ කුරුල්ලෙකු විය හැකිය.
ලුන්ඩින්

17
Ar මාටින් එය ඉතා සත්‍යයකි. එස්ටීඑල් සහ සැකිලි වැනි නිශ්චිත කාර්ය සාධන lers ාතකයින්ට අමතරව, බොහෝ කාවැද්දූ පද්ධති සමස්ත සම්මත පුස්තකාලවලින් පවා වැළකී සිටියි. කාවැද්දූ ශාඛාවෙන් වැඩි ප්‍රමාණයක් මිස්රා වැනි ප්‍රමිතීන් වැලඳගෙන ඇති අතර ඒ සඳහා ස්ථිතික කේත විශ්ලේෂණ මෙවලම් අවශ්‍ය වේ (ඕනෑම මෘදුකාංග වෘත්තිකයන් එවැනි මෙවලම් btw භාවිතා කළ යුතුය, කාවැද්දූ පුද්ගලයින් පමණක් නොවේ). සමස්ත සම්මත පුස්තකාලය හරහා ස්ථිතික විශ්ලේෂණයන් ක්‍රියාත්මක කිරීමට වඩා සාමාන්‍යයෙන් මිනිසුන්ට කළ යුතු දේ තිබේ - එහි ප්‍රභව කේතය නිශ්චිත සම්පාදකයාට ලබා ගත හැකි නම්.
ලුන්ඩින්

38
Und ලුන්ඩින්: ඔබේ ප්‍රකාශ ඕනෑවට වඩා පුළුල් ය (එබැවින් තර්ක කිරීම නිෂ් less ල ය). තත්වයන් සත්‍ය නම් මට ඒවා සොයාගත හැකි බව මට විශ්වාසයි. මෙය මගේ ආරම්භක ලක්ෂ්‍යය වෙනස් නොකරයි. මෙම පංති දෙකම කාවැද්දූ පද්ධතිවල භාවිතය සඳහා ඉතා සුදුසු ය (ඒවා භාවිතා වන බව මම දනිමි). එස්ටීඑල් / බූස්ට් කාවැද්දූ පද්ධතිවල භාවිතා නොකිරීම පිළිබඳ ඔබේ ආරම්භක කරුණ ද වැරදිය. මට විශ්වාසයි ඒවා භාවිතා නොකරන පද්ධති සහ ඒවා භාවිතා කරන පද්ධති පවා ඒවා යුක්තිසහගත ලෙස භාවිතා කරන නමුත් ඒවා භාවිතා නොකරන බව පැවසීම නිවැරදි නොවේ (මන්ද ඒවා භාවිතා කර ඇති පද්ධති පවතින නිසා).
මාටින් යෝක්

248

අනෙක් විකල්පය වන්නේ බිට් ක්ෂේත්‍ර භාවිතා කිරීමයි:

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

මෙය ක්‍රියාත්මක වන්නේ ස්ථාවර ප්‍රමාණයේ බිට් ක්ෂේත්‍ර සමඟ පමණි. එසේ නොමැතිනම් ඔබට පෙර පෝස්ට් වල විස්තර කර ඇති බිට්-ට්විඩ්ලිං ක්‍රමවේදයන් අනුගමනය කළ යුතුය.


68
මම නිතරම සොයාගෙන ඇත්තේ බිට්ෆීල්ඩ් භාවිතා කිරීම නරක අදහසකි. බිටු වෙන් කර ඇති අනුපිළිවෙල (ඉහළ හෝ පහළ සිට) ඔබට පාලනයක් නැත, එමඟින් බිට්-ඒ-වරකට හැර ස්ථාවර / අතේ ගෙන යා හැකි ආකාරයකින් අගය අනුක්‍රමික කිරීමට නොහැකි වේ. DIY බිට් අංක ගණිතය බිට්ෆීල්ඩ්ස් සමඟ මිශ්‍ර කිරීම ද කළ නොහැකි ය, නිදසුනක් ලෙස එකවර බිටු කිහිපයක් පරීක්ෂා කරන වෙස් මුහුණක් සෑදීම. ඔබට ඇත්ත වශයෙන්ම && භාවිතා කළ හැකි අතර සම්පාදකයා එය නිවැරදිව ප්‍රශස්තිකරණය කරනු ඇතැයි බලාපොරොත්තු වේ ...
ආර් .. GitHub STOP HELPING ICE

35
බිට් ක්ෂේත්‍ර බොහෝ ආකාරවලින් නරක ය, මට ඒ ගැන පොතක් ලිවීමට හැකි විය. ඇත්ත වශයෙන්ම මට එය කිරීමට සිදු වූයේ මිස්රා-සී අනුකූලතාවය අවශ්‍ය වන ක්ෂේත්‍ර ක්ෂේත්‍ර වැඩසටහනක් සඳහා ය. MISRA-C විසින් ලේඛනගත කිරීම සඳහා ක්‍රියාත්මක කිරීම-නිර්වචනය කරන ලද සියලු හැසිරීම් බලාත්මක කරයි, එබැවින් මම බිට් ක්ෂේත්‍රවල වැරදියට සිදුවිය හැකි සෑම දෙයක් ගැනම රචනයක් ලිවීම අවසන් කළෙමි. බිට් ඇණවුම, එන්ඩියනස්, පෑඩින් බිට්ස්, පෑඩින් බයිට්, වෙනත් විවිධ පෙළගැස්වීමේ ගැටළු, බිට් ෆීල්ඩ් එකකට සහ ඉන් පිටත ව්‍යංග හා පැහැදිලි ආකාරයේ පරිවර්තනයන්, යූබී int භාවිතා නොකරන්නේ නම් සහ යනාදිය. ඒ වෙනුවට, අඩු දෝෂ සහ අතේ ගෙන යා හැකි කේත සඳහා බිට්වේස්-ක්‍රියාකරුවන් භාවිතා කරන්න. බිට් ක්ෂේත්ර සම්පූර්ණයෙන්ම අතිරික්ත වේ.
ලුන්ඩින්

44
බොහෝ භාෂා අංග මෙන්, බිට් ක්ෂේත්‍ර නිවැරදිව භාවිතා කළ හැකිය, නැතහොත් ඒවා අනිසි ලෙස භාවිතා කළ හැකිය. ඔබට කුඩා අගයන් කිහිපයක් තනි අන්තයකට ඇසුරුම් කිරීමට අවශ්‍ය නම්, බිට් ක්ෂේත්‍ර ඉතා ප්‍රයෝජනවත් වේ. අනෙක් අතට, ඔබ බිට් ක්ෂේත්‍ර සත්‍ය අන්තර්ගතයට අනුරූප වන ආකාරය ගැන උපකල්පන කිරීමට පටන් ගන්නේ නම්, ඔබ ඉල්ලන්නේ කරදරයකි.
ෆෙරුසියෝ

4
ඇන්ඩොලිත්: එය හොඳ අදහසක් නොවේ. ඔබට එය ක්‍රියාත්මක කළ හැකි නමුත් එය වෙනත් සකසනයකට හෝ වෙනත් සම්පාදකයෙකුට හෝ එකම සම්පාදකයාගේ ඊළඟ නිකුතුවට අතේ ගෙන යා නොහැක.
ෆෙරුසියෝ

3
ප්‍රවේශය සඳහා යස්කි සහ ෆෙරුසියෝ () ප්‍රමාණයට වෙනස් පිළිතුරු ලබා ගැනීම සම්පාදකයින් හරහා පමණක් නොව දෘඩාංග හරහාද ගැළපීමේ ගැටළු නිරූපණය කළ යුතුය. අපි සමහර විට මෙම ප්‍රශ්න භාෂා හෝ අර්ථකථන ධාවන වේලාවන් සමඟ විසඳා ඇති බව අපවම රවටා ගන්නා නමුත් එය සැබවින්ම පහළට එන්නේ 'එය මගේ යන්ත්‍රයේ ක්‍රියාත්මක වේද?' ඔබ කාවැද්දූ යාලුවනේ මගේ ගෞරවය (සහ අනුකම්පාව) ඇත.
කෙලී එස්. ප්‍රංශ

182

බිට් සෙට් හැසිරවීමට සහ පැහැදිලි කිරීමට මම ශීර්ෂ ගොනුවක අර්ථ දක්වා ඇති මැක්‍රෝස් භාවිතා කරමි:

/* 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))

17
අහ්, මෙය අවුරුදු 5 ක් පැරණි තනතුරක් බව මට වැටහී ඇති නමුත් එම කිසිදු මැක්‍රෝස් වල තර්ක අනුපිටපතක් නොමැත, ඩෑන්
රොබට් කෙලී

11
BITMASK_CHECK(x,y) ((x) & (y))විය යුතුය ((x) & (y)) == (y). (හිටපු වසං එසේ එය multibit පිළිබඳ නිවැරදි සත්ය ප්රතිඵලය නැවත 5එදිරිව 3සියලු gravediggers කිරීමට) / * ආයුබෝවන්:) * /
brigadir

7
1(uintmax_t)1කවුරුහරි මෙම මැක්‍රෝස් longවිශාල හෝ විශාල වර්ගයක භාවිතා කිරීමට උත්සාහ කරන්නේ නම් හෝ ඊට සමාන විය යුතුය
MM

2
BITMASK_CHECK_ALL(x,y)ක්‍රියාත්මක කළ හැකිය!~((~(y))|(x))
Handy999

3
@ හැන්ඩි 999 ඩි මෝගන්ගේ නීතිය ක්‍රියාත්මක කිරීමෙන් හා නැවත ලබා ගැනීමට කටයුතු කිරීමෙන් පසුව එය ක්‍රියාත්මක වන්නේ මන්දැයි බැලීමට ටිකක් පහසුය!(~(x) & (y))
ටාවියන් බාන්ස්

114

එය භාවිතා සමහර වටී enumකිරීමට නම් මෙම බිටු:

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

පසුව නම් භාවිතා කරන්න . එනම් ලියන්න

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

සැකසීමට, පැහැදිලි කිරීමට සහ පරීක්ෂා කිරීමට. මේ ආකාරයෙන් ඔබ ඔබේ කේතයේ ඉතිරි කොටස් වලින් මැජික් අංක සඟවයි.

ඒ හැර මම ජෙරමිගේ විසඳුම අනුමත කරමි.


1
විකල්පයක් ලෙස ඔබට clearbits()ඒ වෙනුවට ශ්‍රිතයක් කළ හැකිය &= ~. ඔබ මේ සඳහා enum එකක් භාවිතා කරන්නේ ඇයි? සැඟවුණු අත්තනෝමතික වටිනාකමක් ඇති අද්විතීය විචල්‍යයන් රාශියක් නිර්මාණය කිරීම සඳහා ඒවා යැයි මම සිතුවෙමි, නමුත් ඔබ එක් එක් සඳහා නිශ්චිත අගයක් පවරයි. ඉතින් ඒවා විචල්‍යයන් ලෙස අර්ථ දැක්වීමට එරෙහිව ලැබෙන ප්‍රයෝජනය කුමක්ද?
endolith

4
ndendolith: enumආශ්‍රිත නියත කට්ටල සඳහා s භාවිතය c ක්‍රමලේඛනය කිරීමේදී බොහෝ back තට දිව යයි. නවීන සම්පාදකයින් සමඟ ඇති එකම වාසිය const shortහෝ ඊට වඩා පැහැදිලිවම ඒවා එකට කාණ්ඩගත වී ඇති බවට මම සැක කරමි . බිට්මාස්ක් හැර වෙනත් දෙයක් සඳහා ඔබට ඒවා අවශ්‍ය වූ විට ඔබට ස්වයංක්‍රීය අංකනය ලැබේ. ඇත්ත වශයෙන්ම c ++ වලදී, ඒවා එකිනෙකට වෙනස් වර්ගද සාදයි, එමඟින් ඔබට අමතර ස්ථිතික දෝෂ පරීක්ෂාවක් ලබා දේ.
dmckee --- හිටපු උපපරිපාලක පූස් පැටවා

බිටු වල ඇති විය හැකි එක් එක් අගයන් සඳහා නියතයක් නිර්වචනය නොකළහොත් ඔබ නිර්වචනය නොකළ එනුම් නියතයන්ට ඇතුල් වේ. උදාහරණයක් ලෙස එහි enum ThingFlagsවටිනාකම ThingError|ThingFlag1කුමක්ද?
ලුයිස් කොලරාඩෝ

6
ඔබ මෙම ක්‍රමය භාවිතා කරන්නේ නම් කරුණාකර මතක තබා ගන්න එනුම් නියතයන් සැමවිටම අත්සන් කරන ලද ආකාරයේ බව int. ව්‍යාජ සංඛ්‍යා පූර්ණ ප්‍රවර්ධනය හෝ අත්සන් කළ වර්ග මත බිට්වේස් මෙහෙයුම් හේතුවෙන් මෙය සියලු ආකාරයේ සියුම් දෝෂ ඇති කළ හැකිය. thingstate = ThingFlag1 >> 1උදාහරණයක් ලෙස ක්‍රියාත්මක කිරීම-නිර්වචනය කළ හැසිරීම ඉල්ලා සිටී. thingstate = (ThingFlag1 >> x) << yනිර්වචනය නොකළ හැසිරීමට ඉඩ දිය හැකිය. සහ යනාදි. ආරක්ෂිත වීමට, සෑම විටම අත්සන් නොකළ වර්ගයකට දමන්න.
ලුන්ඩින්

1
Und ලුන්ඩින්: සී ++ 11 වන විට, ඔබට ගණනය කිරීමේ යටි වර්ගය සැකසිය හැකිය, උදා: enum My16Bits: unsigned short { ... };
අයිකන් ඩ්‍රම්

47

සිට 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)))

හරි, අපි දේවල් විශ්ලේෂණය කරමු ...

මේ සියල්ලෙහිම ඔබට ගැටළු ඇති බව පෙනෙන පොදු ප්‍රකාශනය වන්නේ "(1L << (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 ක් සැකසිය යුතුය. ටිල්ඩ් (~) ක්‍රියාකරු විසින් දැක්වෙන එකම ප්‍රකාශනයේ 1 හි අනුපූරකය භාවිතා කිරීමෙන් මෙය සිදු වේ.

වෙස්මුහුණ නිර්මාණය කළ පසු එය ඔබ යෝජනා කරන ආකාරයටම බිට්වේස් සහ (&), හෝ (|) සහ xor (^) ක්‍රියාකරුවන් භාවිතා කරයි. වෙස් මුහුණ දිගු වන බැවින්, මැක්‍රෝස් චාර්, ෂෝට්ස්, ඉන්ටර්ස් හෝ ලෝන්ග්ස් මතද ක්‍රියා කරයි.

අවසාන කරුණ නම් මෙය සමස්ත පන්තියේ ගැටලුවලට පොදු විසඳුමකි. ඇත්ත වශයෙන්ම, ඔබට අවශ්‍ය සෑම අවස්ථාවකම පැහැදිලි ආවරණ අගයන් සහිත මෙම මැක්‍රෝස් වලින් එකකට සමාන ප්‍රමාණයක් නැවත ලිවීම කළ හැකි නමුත් සුදුසු වන්නේ ඇයි? මතක තබා ගන්න, සාර්ව ආදේශනය සිදුවන්නේ පූර්ව සකසනය තුළ වන අතර එම නිසා ජනනය කරන ලද කේතය මඟින් සම්පාදකයා විසින් අගයන් නියත ලෙස සලකනු ලැබේ යන කාරණය පිළිබිඹු කරයි - එනම් ඔබට අවශ්‍ය සෑම අවස්ථාවකම “රෝදය ප්‍රතිනිර්මාණය කිරීම” සඳහා සාමාන්‍යකරණය කරන ලද මැක්‍රෝස් භාවිතා කිරීම කාර්යක්ෂම වේ. ටිකක් හැසිරවීම කරන්න.

එකඟ නොවන්නේද? මෙන්න පරීක්ෂණ කේත කිහිපයක් - මම සම්පූර්ණ ප්‍රශස්තිකරණයෙන් හා _cdecl භාවිතා නොකර වොට්කොම් සී භාවිතා කළෙමි.

---- [TEST.C] ----------------------------------------- -----------------------

#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;
}

---- [TEST.OUT (විසුරුවා හරින ලද)] -------------------------------------- ---------

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

---- [finis] ------------------------------------------- ----------------------


3
මේ පිළිබඳ කරුණු 2 ක්: (1) ඔබේ මැක්‍රෝස් පරීක්ෂා කර බැලීමේදී, මැක්‍රෝස් ඇත්ත වශයෙන්ම ආග් තුළ බිටු සකස් කර ඇති බව පැහැදිලි යැයි සමහරු වැරදියට විශ්වාස කළ හැකිය, කෙසේ වෙතත් පැවරුමක් නැත; (2) ඔබේ test.c සම්පූර්ණ නැත; ඔබ තවත් නඩු පැවරුවහොත් ඔබට ගැටලුවක් ඇති වේ යැයි මම සැක කරමි (පා
ඩෑන්

19
-1 මෙය අමුතු අපැහැදිලි කිරීමකි. මැක්‍රෝස් පිටුපස භාෂා වාක්‍ය ඛණ්ඩය සඟවා සී භාෂාව නැවත ප්‍රතිනිර්මාණය නොකරන්න, එය ඉතා නරක පුරුද්දකි. එවිට සමහර අමුතුකම්: පළමුව, 1L අත්සන් කර ඇති අතර, එයින් අදහස් වන්නේ සියලුම බිට් මෙහෙයුම් අත්සන් කරන ලද වර්ගයක් මත සිදු කරනු ඇති බවයි. මෙම මැක්‍රෝස් වෙත ලබා දුන් සෑම දෙයක්ම දිගු අත්සන් කළ පරිදි නැවත පැමිණේ. හොඳ නැහැ. දෙවනුව, මෙය කුඩා CPU මත ඉතා අකාර්යක්ෂම ලෙස ක්‍රියා කරනු ඇති අතර එය මෙහෙයුම් මට්ටමින් පැවතිය හැකි දිගු කාලයක් බලාත්මක වේ. තෙවනුව, ක්‍රියාකාරීත්වයට සමාන මැක්‍රෝස් සියලු නපුරේ මුල වේ: ඔබට කිසිදු ආකාරයක ආරක්ෂාවක් නොමැත. එසේම, පැවරුමක් පිළිබඳ පෙර අදහස් දැක්වීම ඉතා වලංගු නොවේ.
ලුන්ඩින්

2
නම් මෙය අසමත් වන argකියන්නේ long long. 1Lහැකි පුළුල්ම වර්ගය විය යුතුය, එබැවින් (uintmax_t)1. (ඔබට පැන යා හැකිය 1ull)
එම්.එම්.

ඔබ කේත ප්‍රමාණය සඳහා ප්‍රශස්තිකරණය කළාද? ඉන්ටෙල් ප්‍රධාන ධාරාවේ CPU වල, මෙම ශ්‍රිතය නැවත පැමිණි පසු AX හෝ EAX කියවන විට ඔබට අර්ධ-ලේඛණ කුටි ලැබෙනු ඇත, මන්ද එය EAX හි බිටු 8 සංරචක ලියන බැවිනි. (සම්පූර්ණ ලේඛනයෙන් වෙන් වෙන් වශයෙන් අර්ධ ලේඛණ නැවත නම් නොකරන AMD CPUs හෝ වෙනත් අය සඳහා එය හොඳයි. හැස්වෙල් / ස්කයිලේක් AL වෙන් වෙන් වශයෙන් නම් නොකරන්න, නමුත් ඔවුන් AH ලෙස නම් කරයි. ).
පීටර් කෝඩ්ස්

37

බිට්වේස් ක්‍රියාකරුවන් භාවිතා කරන්න: & |

අවසාන බිට් එක සැකසීමට 000b:

foo = foo | 001b

අන්තිම බිට් පරීක්ෂා කිරීමට foo:

if ( foo & 001b ) ....

අවසාන බිට් ඉවත් කිරීමට foo:

foo = foo & 110b

මම XXXbපැහැදිලිකම සඳහා භාවිතා කළෙමි . ඔබ බිටු ඇසුරුම් කරන දත්ත ව්‍යුහය මත පදනම්ව, ඔබ බොහෝ විට HEX නිරූපණය සමඟ වැඩ කරනු ඇත.


7
සී හි ද්විමය අංකනයක් නොමැත ද්විමය නිඛිල නියතයන් යනු සම්මත නොවන දිගුවකි.
ලුන්ඩින්

ටිකක් ටොගල් කිරීමට XOR භාවිතා කරන්න:foo = foo ^ MY_MASK
පීටර් එල්

පැහැදිලි කිරීම සඳහා වෙස් මුහුණක් පෙරළීමට NOT භාවිතා කරන්න:foo = foo & ~MY_MASK
පීටර් එල්

33

ආරම්භකයා සඳහා මම උදාහරණයක් සමඟ තව ටිකක් පැහැදිලි කිරීමට කැමතියි:

උදාහරණයක්:

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)

26

මෙන්න මගේ ප්‍රියතම බිට් අංක ගණිත සාර්ව, ඕනෑම වර්ගයක අත්සන් නොකල පූර්ණ සංඛ්‍යා අරාව දක්වා 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, &)) ...

ආදිය.


5
කියවීම හොඳ නමුත් සිදුවිය හැකි අතුරු ආබාධ පිළිබඳව යමෙකු දැනුවත් විය යුතුය. BITOP(array, bit++, |=);ලූපයක් භාවිතා කිරීම බොහෝ විට අමතන්නාට අවශ්‍ය දේ නොකරයි.
ෆොරයිඩ්

ඇත්ත වශයෙන්ම. = ඔබ කැමති විය හැකි) එක් ප්රභේද්යයක්, මැක්රෝස් 2 බවට වෙන් කිරීම 1 ස්ථානය බවට ටිකක් විතැන් කිරීම සඳහා අරාව මූලද්රව්යය වන අතර අනෙකුත් බැලීම සඳහා, අල වේ BITCELL(a,b) |= BITMASK(a,b);දෙකම ගනිත් ( aවිශාලත්වය තීරණය කිරීම සඳහා තර්කයක් ලෙස, නමුත් අග ඇගයීමට නැහැ aසිට එය දිස්වන්නේ sizeof).
ආර් .. GitHub STOP HELPING ICE

1
AnswerR .. මෙම පිළිතුර ඇත්තෙන්ම පැරණි ය, නමුත් මම බොහෝ විට මේ අවස්ථාවේ දී සාර්වයකට වඩා ශ්‍රිතයකට වැඩි කැමැත්තක් දක්වන්නෙමි.
පීසී ලුඩයිට්

සුළු: 3 වන (size_t)කාස්ට් පමණක් සමහර ආරක්ෂා කිරීම සඳහා එහි ඇති බව පෙනේ නිලකුණු ගණිත සමග %. එහෙම කරන්න පුළුවන් (unsigned).
chux - මොනිකා නැවත ස්ථාපනය කරන්න

මෙම (size_t)(b)/(8*sizeof *(a))අනවශ්ය තෝරාගැනුමෙන් ඔබහට නැරඹුමෙහි පුළුල අඩු කර හැකි bඅංශයේ පෙර. ඉතා විශාල බිටු අරා සමඟ ගැටළුවක් පමණි. තවමත් සිත්ගන්නා සාර්ව.
chux - මොනිකා නැවත ස්ථාපනය කරන්න

25

මෙය "කාවැද්දූ" ලෙස ටැග් කර ඇති බැවින් මම හිතන්නේ ඔබ මයික්‍රොකොන්ට්රෝලර් භාවිතා කරන බවයි. ඉහත යෝජනා සියල්ලම වලංගු සහ වැඩ (කියවීම-වෙනස් කිරීම-ලිවීම, වෘත්තීය සමිති, ව්‍යුහයන් ආදිය).

කෙසේ වෙතත්, ඔසිලෝස්කෝප් මත පදනම් වූ නිදොස්කරණයක දී, මෙම ක්‍රමවලට සීපීයූ චක්‍රවල සැලකිය යුතු පොදු කාර්යයක් ඇති බව දැනගැනීමෙන් මම පුදුමයට පත් වූ අතර, මයික්‍රෝ හි PORTnSET / PORTnCLEAR ලේඛනයට සෘජුවම අගයක් ලිවීමට සාපේක්ෂව එය තද ලූප / ඉහළ ඇති සැබෑ වෙනසක් ඇති කරයි. අයිඑස්ආර් හි ටොගල් පයින්.

නුහුරු අය සඳහා: මගේ උදාහරණයේ දී, මයික්‍රෝ සතුව සාමාන්‍ය පින්-රාජ්‍ය ලේඛනයක් PORTn ඇත, එය ප්‍රතිදාන පයින් පිළිබිඹු කරයි, එබැවින් PORTn | = BIT_TO_SET ප්‍රති results ල මඟින් එම ලේඛනයට කියවීම-වෙනස් කිරීම-ලිවීම සිදු කරයි. කෙසේ වෙතත්, PORTnSET / PORTnCLEAR රෙජිස්ටාර් '1' යන්නෙන් අදහස් කරන්නේ "කරුණාකර මෙම බිට් 1 සාදන්න" (SET) හෝ "කරුණාකර මෙම බිට් ශුන්‍ය කරන්න" (CLEAR) සහ '0' යන්නෙන් අදහස් කරන්නේ "පින් එක තනිවම තබන්න" යන්නයි. එබැවින්, ඔබ බිට් සැකසීම හෝ ඉවත් කිරීම (සෑම විටම පහසු නොවේ) මත පදනම්ව වරාය ලිපින දෙකකින් අවසන් වේ, නමුත් වඩා වේගවත් ප්‍රතික්‍රියාවක් සහ එකලස් කරන ලද කුඩා කේතයක්.


කෝඩ්වාරියර් හි සී භාවිතා කරමින් මයික්‍රෝ කෝල්ඩ්ෆයර් MCF52259 විය. විසුරුවා හරින / asm දෙස බැලීම ප්‍රයෝජනවත් ව්‍යායාමයක් වන අතර එය මූලික ක්‍රියාන්විතය පවා කිරීමට CPU විසින් ගත යුතු සියලු පියවර පෙන්වයි. <br> අපි කාලානුරූපී ලූපවල වෙනත් CPU-hoging උපදෙස් ද දුටුවෙමු - var% = max_val කිරීමෙන් විචල්‍යයක් සීමා කිරීම සෑම වාරයකදීම CPU චක්‍ර රාශියක් වැය වන අතර (var> max_val) var- = max_val භාවිතා කරන්නේ නම් පමණි උපදෙස් කිහිපයක්. <br> තවත් උපක්‍රම කිහිපයක් සඳහා හොඳ මඟ පෙන්වීමක් මෙහි ඇත: codeproject.com/Articles/6154/…
John U

ඊටත් වඩා වැදගත් වන්නේ, උපකාරක මතක සිතියම්ගත කළ I / O ලේඛණ පරමාණුක යාවත්කාලීන කිරීම් සඳහා යාන්ත්‍රණයක් සපයයි. අනුක්‍රමය බාධා කළහොත් කියවීම / වෙනස් කිරීම / ලිවීම ඉතා නරක ලෙස සිදුවිය හැකිය.
බෙන් වොයිග්ට්

1
සියලුම වරාය රෙජිස්ටර් ලෙස අර්ථ දැක්විය හැකි බව මතක තබා ගන්න volatile, එම නිසා එවැනි රෙජිස්ටාර් සම්බන්ධ කේත පිළිබඳ ප්‍රශස්තිකරණ සිදු කිරීමට සම්පාදකයාට නොහැකි වේ. එමනිසා, එවැනි කේතයක් විසුරුවා හැර එය එකලස් කිරීමේ මට්ටමට පත් වූයේ කෙසේදැයි බැලීම හොඳ පුරුද්දකි.
ලුන්ඩින්

24

බිට්ෆීල්ඩ් ප්‍රවේශය කාවැද්දූ පිටියේ වෙනත් වාසි ඇත. විශේෂිත දෘඩාංග ලේඛනයක බිටු මත කෙලින්ම සිතියම් ගත කරන ව්‍යුහයක් ඔබට අර්ථ දැක්විය හැකිය.

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;

බිට් ඇසුරුම් අනුපිළිවෙල ගැන ඔබ දැනුවත් විය යුතුයි - මම හිතන්නේ එය පළමුව MSB, නමුත් මෙය ක්‍රියාත්මක කිරීම මත රඳා පවතී. තවද, ඔබේ සම්පාදක හසුරුවන්නන් බයිට් සීමාවන් ඉක්මවා යන ආකාරය තහවුරු කරන්න.

ඔබට පෙර මෙන් තනි අගයන් කියවීමට, ලිවීමට, පරීක්ෂා කිරීමට හැකිය.


2
බිට්-ෆීල්ඩ්ස් පිළිබඳ බොහෝ දේ ක්‍රියාත්මක කිරීම-අර්ථ දක්වා ඇත. ඔබේ විශේෂිත සම්පාදකයා ඒවා ක්‍රියාත්මක කරන්නේ කෙසේද යන්න පිළිබඳ සියලු තොරතුරු සොයා ගැනීමට ඔබ කළමනාකරණය කළත්, ඒවා ඔබේ කේතයේ භාවිතා කිරීමෙන් එය අතේ ගෙන යා නොහැකි වනු ඇත.
ලුන්ඩින්

1
Und ලුන්ඩින් - ඇත්ත, නමුත් කාවැද්දූ පද්ධති බිට්-ෆිඩ්ලිං (විශේෂයෙන් දෘඩාංග ලේඛනයේ, මගේ පිළිතුරට සම්බන්ධ වන්නේ එයයි) කෙසේ හෝ ප්‍රයෝජනවත් ලෙස අතේ ගෙන යා නොහැක.
රොඩි

1
සමහර විට සම්පූර්ණයෙන්ම වෙනස් CPU අතර නොවේ. නමුත් ඔබට බොහෝ විට අවශ්‍ය වන්නේ එය සම්පාදකයින් අතර සහ විවිධ ව්‍යාපෘති අතර අතේ ගෙන යා හැකි වීමයි. දත්ත ප්‍රොටොකෝලය කේතන කිරීම / විකේතනය කිරීම වැනි දෘඩාංග හා සම්බන්ධ නොවන "බිට්-ෆිඩ්ලිං" කාවැදී ඇත.
ලුන්ඩින්

... ඔබ කාවැද්දූ ක්‍රමලේඛන කරමින් බිට් ක්ෂේත්‍ර භාවිතා කිරීමේ පුරුද්දක් ඇති කර ගන්නේ නම්, ඔබේ X86 කේතය වේගයෙන් ක්‍රියාත්මක වන අතර සිහින් ද වේ. මිණුම් ලකුණ තලා දැමීමට ඔබට සම්පූර්ණ යන්ත්‍රය ඇති සරල මිණුම් සලකුණු වල නොව, වැඩසටහන් සඳහා සම්පත් සඳහා තරඟ කරන සැබෑ ලෝකයේ බහු කාර්ය පරිසරයන් තුළ. වාසි CISC - එහි මුල් සැලසුම් ඉලක්කය වූයේ බස් රථවලට වඩා වේගයෙන් සහ මන්දගාමී මතකයට වඩා CPU සඳහා සෑදීමයි.

20

අත්තනෝමතික ආකාරයේ විචල්‍යයක අත්තනෝමතික ස්ථානයක ටිකක් පරීක්ෂා කරන්න:

#define bit_test(x, y)  ( ( ((const char*)&(x))[(y)>>3] & 0x80 >> ((y)&0x07)) >> (7-((y)&0x07) ) )

නියැදි භාවිතය:

int main(void)
{
    unsigned char arr[8] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF };

    for (int ix = 0; ix < 64; ++ix)
        printf("bit %d is %d\n", ix, bit_test(arr, ix));

    return 0;
}

සටහන්: මෙය සැලසුම් කර ඇත්තේ වේගවත් (එහි නම්යතාවය අනුව) සහ ශාඛා නොවන ලෙසය. සන් ස්ටුඩියෝ 8 සම්පාදනය කිරීමේදී එය කාර්යක්ෂම SPARC යන්ත්‍ර කේතයක් ලබා දෙයි; මම එය amd64 හි MSVC ++ 2008 භාවිතා කර පරීක්ෂා කර ඇත්තෙමි. බිටු සැකසීම සහ ඉවත් කිරීම සඳහා සමාන මැක්‍රෝස් සෑදිය හැකිය. මෙහි ඇති වෙනත් බොහෝ අය සමඟ සසඳන විට මෙම විසඳුමේ ඇති ප්‍රධාන වෙනස නම් එය ඕනෑම ආකාරයක විචල්‍යයක ඕනෑම ස්ථානයකට වැඩ කිරීමයි.


20

වඩාත් සාමාන්‍ය, අත්තනෝමතික ප්‍රමාණයේ බිට්මැප් සඳහා:

#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)))

2
CHAR_BITදැනටමත් නිර්වචනය කර ඇති අතර limits.h, ඔබට ඔබේම දෑ ඇතුළත් කිරීමට අවශ්‍ය නැත BITS(ඇත්ත වශයෙන්ම ඔබ එසේ කිරීමෙන් ඔබේ කේතය නරක අතට හැරේ)
එම්.එම්.

14

මෙම වැඩසටහන ඕනෑම දත්ත බිට් එකක් 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);
        }
    }
}

14

ඔබ බොහෝ විකෘති කිරීම් කරන්නේ නම්, ඔබට වෙස්මුහුණු භාවිතා කිරීමට අවශ්‍ය විය හැකි අතර එමඟින් සියල්ල වේගවත් වේ. පහත දැක්වෙන කාර්යයන් ඉතා වේගවත් වන අතර ඒවා තවමත් නම්‍යශීලී වේ (ඒවා ඕනෑම ප්‍රමාණයක බිට් සිතියම්වල බිටු විකෘති කිරීමට ඉඩ දෙයි).

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 නිඛිලයකින් බිට් 'එන්' සැකසීමට ඔබ පහත සඳහන් දේ කරයි:

TSetBit( n, &my_int);

ඔබ සමත් වන බිට් සිතියමේ පරාසය තුළ බිට් අංකය ඇති බව සහතික කිරීම ඔබ සතු ය. කුඩා එන්ඩියන් ප්‍රොසෙසර සඳහා බයිට්, වචන, ඩෝවර්ඩ්, qwords යනාදිය මතකයේ නිවැරදිව සිතියම් ගත කරන්න (කුඩා එන්ඩියන් ප්‍රොසෙසර විශාල-එන්ඩියන් ප්‍රොසෙසරවලට වඩා 'හොඳ' වීමට ප්‍රධාන හේතුව, අහ්, මට ගිනි යුද්ධයක් එනවා දැනේ මත...).


2
තනි ක්‍රියාකරුවෙකු සමඟ ක්‍රියාත්මක කළ හැකි ශ්‍රිතයක් සඳහා වගුවක් භාවිතා නොකරන්න. TQuickByteMask [n] (1 << n) ට සමාන වේ. එසේම, ඔබේ තර්ක කෙටියෙන් කිරීම ඉතා නරක අදහසකි. / සහ% ඇත්ත වශයෙන්ම බෙදීමක් වනු ඇත, එය බිට්ෂිෆ්ට් / බිට්වයිස් නොවන අතර, 2 බලයකින් අත්සන් කළ බෙදීම බිට්වේස් ලෙස ක්‍රියාත්මක කළ නොහැකි බැවිනි. ඔබ තර්ක වර්ගය අත්සන් නොකළ int බවට පත් කළ යුතුය!
ආර් .. GitHub STOP HELPING ICE

මෙහි ඇති තේරුම කුමක්ද? එය කේතය මන්දගාමී හා කියවීමට අපහසු කරයිද? මට එයින් එක වාසියක් දැකිය නොහැක. 1u << n සී ක්‍රමලේඛකයින් සඳහා කියවීම පහසු වන අතර එය තනි ඔරලෝසු ටික් CPU උපදෙස් වලට පරිවර්තනය කළ හැකිය. අනෙක් අතට, ඔබේ අංශය කිනිතුල්ලන් 10 ක් පමණ හෝ කිනිතුල්ලන් 100 ක් තරම් නරක දෙයකට පරිවර්තනය කරනු ඇත. බිට්මැප් විශේෂාංගය සම්බන්ධයෙන් ගත් කල, වේගය ප්‍රශස්ත කිරීම සඳහා එක් එක් බිට් දර්ශකය බයිට් දර්ශකයකට පරිවර්ථනය කිරීමේ විමසුම් වගුවක් තිබීම වඩාත් අර්ථවත් වනු ඇත.
ලුන්ඩින්

2
ලොකු / කුඩා එන්ඩියන් සම්බන්ධයෙන් ගත් කල, විශාල එන්ඩියන් පූර්ණ සංඛ්‍යා සහ අමු දත්ත (උදාහරණයක් ලෙස නූල්) එකම ආකාරයකින් සිතියම් ගත කරයි: මුළු බිට්මැප් එක පුරාම වමේ සිට දකුණට msb සිට lsb දක්වා. කුඩා එන්ඩියන් 7-0, 15-8, 23-18, 31-24 ලෙස පූර්ණ සංඛ්‍යා වමේ සිට දකුණට සිතියම් ගත කරන නමුත් අමු දත්ත තවමත් වමේ සිට දකුණට msb සිට lsb දක්වා ඇත. ඔබගේ විශේෂිත ඇල්ගොරිතම සඳහා එන්ඩියන් කොතරම් හොඳද යන්න මට සම්පූර්ණයෙන්ම ඔබ්බෙන් වූවක් බව පෙනේ.
ලුන්ඩින්

2
ඔබගේ plattform පැරණි ක්ෂුද්ර mcu ගේ වගේ, කාර්යක්ෂමව පැටවීමට නම් කළ හැකි, නමුත් ඇත්ත නම් නියැදිය අංශයේ absolutly අකාර්යක්ෂම @R .. ඒ මේසය ප්රයෝජනවත් විය හැකි
jeb

12

මෙය භාවිතා කරන්න:

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

    return num;
}

5
හොඳයි, එය අකාර්යක්ෂම අතු භාවිතා කරයි.
asdf

3
dasdf සම්පාදකයාගේ කාර්යය වන්නේ වඩාත් කාර්යක්ෂම ද්විමය ප්‍රතිදානය කිරීමයි, ක්‍රමලේඛකයාගේ කාර්යය වන්නේ පැහැදිලි කේතයක් ලිවීමයි
MM

3
මෙය යම් ප්‍රමාණයක් පරීක්ෂා කිරීම, සැකසීම සහ පිරිසිදු කිරීම පිළිබඳ හොඳ නිරූපණයකි. කෙසේ වෙතත් එය ටිකක් ටොගල් කිරීම සඳහා ඉතා නරක ප්‍රවේශයකි.
බෙන් වොයිග්ට්

10

bitsetපිළිතුර පුළුල් කිරීම :

#include <iostream>
#include <bitset>
#include <string>

using namespace std;
int main() {
  bitset<8> byte(std::string("10010011");

  // Set Bit
  byte.set(3); // 10010111

  // Clear Bit
  byte.reset(2); // 10010101

  // Toggle Bit
  byte.flip(7); // 00010101

  cout << byte << endl;

  return 0;
}

10

ඔබට ලිනක්ස් කර්නලයේ සී ක්‍රමලේඛනය සමඟ මේ සියල්ල සිදු කිරීමට අවශ්‍ය නම් ලිනක්ස් කර්නලයේ සම්මත ඒපීඅයි භාවිතා කිරීමට මම යෝජනා කරමි.

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

සටහන: මෙන්න සම්පූර්ණ මෙහෙයුම එකම පියවරකින් සිදු වේ. එබැවින් මේ සියල්ල SMP පරිගණකවල පවා පරමාණුක බවට සහතික වී ඇති අතර ප්‍රොසෙසර හරහා සහජීවනය පවත්වා ගැනීමට ප්‍රයෝජනවත් වේ.


9

දෘශ්‍ය සී 2010 සහ තවත් බොහෝ සම්පාදකයින්ට බූලියන් මෙහෙයුම් සඳහා support ජු සහය ඇත. බූලියන් මෙන් මඳක් විය හැකි අගයන් දෙකක් ඇත, එබැවින් අපට ඒ වෙනුවට බූලියන් භාවිතා කළ හැකිය - ඒවා එක බිට් එකකට වඩා වැඩි ඉඩක් ගත්තද මෙම නිරූපණයේ මතකය. මෙය ක්‍රියා කරයි, sizeof()ක්‍රියාකරු පවා නිසි ලෙස ක්‍රියා කරයි.

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;
    }
}

මෙම කේතය පිළිබඳ "විශේෂ" කිසිවක් නොමැති බව සලකන්න. එය පූර්ණ සංඛ්‍යාවක් මෙන් සලකයි - තාක්‍ෂණිකව එය එයයි. අගයන් 2 ක් සහ අගයන් 2 ක් පමණක් තබා ගත හැකි බිට් 1 නිඛිලයක්.

මම වරක් මෙම ප්‍රවේශය භාවිතා කළේ අනුපිටපත් ණය වාර්තා සොයා ගැනීමටය, එහිදී ණය_ අංකය ISAM යතුර වන අතර ඉලක්කම් 6 ක ණය අංකය බිට් අරාවෙහි දර්ශකයක් ලෙස භාවිතා කරයි. ඉතා වේගයෙන් හා මාස 8 කට පසු, අප විසින් දත්ත ලබා ගන්නා ප්‍රධාන රාමු පද්ධතිය ඇත්ත වශයෙන්ම අක්‍රීය බව ඔප්පු විය. බිට් අරා වල සරල බව නිසා ඒවායේ නිරවද්‍යතාවය පිළිබඳ විශ්වාසය ඉතා ඉහළ මට්ටමක පවතී - උදාහරණයක් ලෙස සෙවීමේ ප්‍රවේශයකට එදිරිව.


std :: බිට්සෙට් ඇත්ත වශයෙන්ම බොහෝ සම්පාදකයින් විසින් බිටු ලෙස ක්‍රියාත්මක කරනු ලැබේ
ගැලිනෙට්

ඇගලිනෙට්, එකඟ විය. ශීර්ෂ ගොනුව #include <bitset> මේ සම්බන්ධයෙන් හොඳ සම්පතක්. එසේම, වෙනස් කිරීමට ඔබට දෛශිකයේ ප්‍රමාණය අවශ්‍ය වූ විට විශේෂ පන්තියේ දෛශික <bool>. සී ++ එස්ටීඑල්, ​​2 වන සංස්කරණය, නිකොලායි එම්. ජොසුටිස් පිළිවෙලින් පිටු 650 සහ 281 පිටු වලින් ආවරණය කරයි. C ++ 11 std :: bitset සඳහා නව හැකියාවන් කිහිපයක් එක් කරයි, මට විශේෂ උනන්දුවක් වන්නේ අනුපිළිවෙලට නැති බහාලුම්වල හැෂ් ශ්‍රිතයකි. හිස ඔසවා තැබීමට ස්තූතියි! මම මගේ මොළයේ කැක්කුම ඉවත් කිරීමට යන්නෙමි. දැනටමත් ඕනෑ තරම් කුණු කසළ වෙබයේ ඇත. මට එයට එකතු කිරීමට අවශ්‍ය නැත.

3
මෙය එක් එක් සඳහා අවම වශයෙන් සම්පූර්ණ බයිට් ගබඩාවක් භාවිතා කරයි bool. සමහර විට intක්‍රියාත්මක කිරීමට භාවිතා කරන C89 සැකසුම් සඳහා බයිට් 4 ක් පවාbool
MM

AttMattMcNabb, ඔබ නිවැරදිය. C ++ හි බූලියන් ක්‍රියාත්මක කිරීමට අවශ්‍ය int වර්ගයේ ප්‍රමාණය ප්‍රමිතියෙන් නියම කර නොමැත. මෙම පිළිතුර කලකට පෙර වැරදී ඇති බව මට වැටහුණි, නමුත් මිනිසුන්ට එය ප්‍රයෝජනවත් යැයි පෙනෙන බැවින් එය මෙහි තැබීමට තීරණය කළෙමි. බිටු භාවිතා කිරීමට කැමති අයට ගැලිනෙට්ගේ අදහස් දැක්වීම මගේ බිට් පුස්තකාලය මෙන් ම වඩාත් ප්‍රයෝජනවත් වේ ... stackoverflow.com/a/16534995/1899861

2
Ock රොකට් රෝයි: මෙය “බිට් මෙහෙයුම්” සඳහා උදාහරණයක් යැයි කියන වාක්‍යය වෙනස් කිරීම වටී.
බෙන් වොයිග්ට්

6

මෙහි අර්ථ දක්වා ඇති පරිදි එක් ක්‍රියාකරුවෙකු භාවිතා කරන්න .

ටිකක් කිරීම සඳහා, භාවිත int x = x | 0x?;එහිදී ?ද්විමය ස්වරූපයෙන් ටිකක් ස්ථාවරය වේ.


2
0xයනු ද්විමය නොව ෂඩාස්රාකාරයේ වචනාර්ථය සඳහා උපසර්ගයයි.
බෙන් වොයිග්ට්

6


num = 55බිට්වේස් මෙහෙයුම් සිදු කිරීම සඳහා මුලින්ම සංඛ්‍යා කිහිපයක් සිතමු (සැකසීම, ලබා ගැනීම, පැහැදිලි කිරීම, ටොගල් කිරීම).
n = 4බිට්වේස් මෙහෙයුම් සිදු කිරීම සඳහා 0 පදනම් වූ බිට් පිහිටීම.

ටිකක් ලබා ගන්නේ කෙසේද?

  1. අංක nthනිවැරදි මාරුව ලබා ගැනීමට num, nවේලාවන්. ඉන්පසු &1 සමඟ bitwise AND කරන්න.
bit = (num >> n) & 1;

එය ක්‍රියාත්මක වන්නේ කෙසේද?

       0011 0111 (55 in decimal)
    >>         4 (right shift 4 times)
-----------------
       0000 0011
     & 0000 0001 (1 in decimal)
-----------------
    => 0000 0001 (final result)

ටිකක් සකස් කරන්නේ කෙසේද?

  1. විශේෂිත අංකයක් සැකසීමට. වම් මාරුව 1 nවතාවක්. ඉන්පසු බිට්වේස් හෝ |මෙහෙයුම සිදු කරන්න num.
num |= (1 << n);    // Equivalent to; num = (1 << n) | num;

එය ක්‍රියාත්මක වන්නේ කෙසේද?

       0000 0001 (1 in decimal)
    <<         4 (left shift 4 times)
-----------------
       0001 0000
     | 0011 0111 (55 in decimal)
-----------------
    => 0001 0000 (final result)

ටිකක් ඉවත් කරන්නේ කෙසේද?

  1. වම් මාරුව 1, nවාර ගණන එනම් 1 << n.
  2. ඉහත ප්‍රති .ලය සමඟ බිට්වේස් අනුපූරකය සිදු කරන්න. එවිට n වන බිට් සැකසෙන්නේ නැති අතර ඉතිරි බිට් සැකසෙනු ඇත ~ (1 << n).
  3. අවසාන වශයෙන්, &ඉහත ප්‍රති result ලය සමඟ බිට්වේස් සහ ක්‍රියාකාරිත්වය සිදු කරන්න num. ඉහත පියවර තුන එකට ලිවිය හැකිය num & (~ (1 << n));

ටිකක් ඉවත් කිරීමට පියවර

num &= (~(1 << n));    // Equivalent to; num = num & (~(1 << n));

එය ක්‍රියාත්මක වන්නේ කෙසේද?

       0000 0001 (1 in decimal)
    <<         4 (left shift 4 times)
-----------------
     ~ 0001 0000
-----------------
       1110 1111
     & 0011 0111 (55 in decimal)
-----------------
    => 0010 0111 (final result)

ටිකක් ටොගල් කරන්නේ කෙසේද?

ටිකක් ටොගල් කිරීමට අපි බිට්වයිස් එක්ස්ඕආර් ^ක්‍රියාකරු භාවිතා කරමු . ඔපෙරන්ඩ් දෙකෙහිම අනුරූප බිට් වෙනස් නම් බිට්වයිස් එක්ස්ඕආර් ක්‍රියාකරු 1 ට තක්සේරු කරයි, එසේ නොමැතිනම් 0 දක්වා තක්සේරු කරයි.

එයින් අදහස් කරන්නේ ටිකක් ටොගල කිරීම, ඔබට ටොගල් කිරීමට අවශ්‍ය බිට් එක සමඟ අපි XOR මෙහෙයුම කළ යුතු අතර 1 යි.

num ^= (1 << n);    // Equivalent to; num = num ^ (1 << n);

එය ක්‍රියාත්මක වන්නේ කෙසේද?

  • ටොගල් කිරීමට බිට් 0 නම් , 0 ^ 1 => 1.
  • ටොගල් කිරීමට බිට් 1 නම් , 1 ^ 1 => 0.
       0000 0001 (1 in decimal)
    <<         4 (left shift 4 times)
-----------------
       0001 0000
     ^ 0011 0111 (55 in decimal)
-----------------
    => 0010 0111 (final result)

නිර්දේශිත කියවීම - බිට්වේස් ක්‍රියාකරු අභ්‍යාස


සවිස්තරාත්මක පැහැදිලි කිරීම සඳහා ස්තූතියි. මෙහි BIT මැජික් සඳහා ප්රායෝගිකව ප්රශ්නය සඳහා වන සම්බන්ධයක් ලින්ක්
චන්ද්රා Shekhar

5

මෙන්න මම භාවිතා කරන මැක්‍රෝස් කිහිපයක්:

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)

5

විචල්යය භාවිතා කරයි

int value, pos;

අගය - දත්ත
පොස් - සැකසීමට, පැහැදිලි කිරීමට හෝ ටොගල් කිරීමට අප උනන්දු වන බිට් එකේ පිහිටීම.

ටිකක් සකසන්න:

value = value | 1 << pos;

ටිකක් ඉවත් කරන්න:

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

ටිකක් ටොගල කරන්න:

value = value ^ 1 << pos;

5
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);
}

ආපසු පැමිණීමේ වර්ගය විය check_nth_bitහැකිය bool.
Xeverous

ඔව්, එය ඇමතුම්කරුවන්ගේ අභිප්‍රාය මත රඳා පවතී
සාසාද් හිසේන් ඛාන්

4

ඔබ තනි බිට් එකක් සකසන්නේ කෙසේද, පැහැදිලි කරන්නේ සහ ටොගල් කරන්නේ කෙසේද?

වෙස්මුහුණ සෑදීමට උත්සාහ කරන විට පොදු කේතීකරණ අනතුරකට මුහුණ දීම:
1සෑම විටම ප්‍රමාණවත් නොවේ

numberවඩා පුළුල් වර්ගයක් වන විට සිදුවන ගැටළු මොනවාද 1?
xමාරුව සඳහා මහත් විය හැක 1 << xතුඩු නිර්වචනය නොකළ හැසිරීම (UB). පවා නම් 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

1 රක්ෂණය කිරීම ප්‍රමාණවත් තරම් පුළුල් ය:

කේතයට භාවිතා කළ හැකි 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;

බොහෝ බිටු හැසිරවීම් වලදී මෙන්, අත්සන් කළ ඒවාට වඩා අත්සන් නොකළ වර්ග සමඟ වැඩ කිරීම වඩාත් සුදුසුය


පැරණි ප්‍රශ්නයක් දෙස සිත්ගන්නාසුලු බැල්මක්! වත් number |= (type_of_number)1 << x;හෝ number |= (number*0 + 1) << x;දැකීමක් වත්, අත්සන් වර්ගය ලකුණ ටිකක් පිහිටුවීමට ... ඇත්ත වශයෙන් අත්පත් number |= (1ull << x);. ස්ථානය අනුව එය කිරීමට අතේ ගෙන යා හැකි ක්‍රමයක් තිබේද?
chqrlie

1
qchqrlie IMO, සං bit ා බිට් සැකසීම සහ මාරුවීම් සමඟ UB හෝ IDB අවදානමට ලක්වීම වළක්වා ගත හැකි හොඳම ක්‍රමය නම් අත්සන් නොකළ වර්ග භාවිතා කිරීමයි . ඉහළ අතේ ගෙන යා හැකි මාරුව අත්සන් කළ කේතය පිළිගත නොහැකි තරම් තදින් බැඳී ඇත.
chux - මොනිකා නැවත ස්ථාපනය කරන්න

3

සී ++ 11 සැකසූ අනුවාදයක් (ශීර්ෂ පා put යක් තුළ තබා ඇත):

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;}
}

මෙම කේතය කැඩී ඇත. (එසේම, ;ඔබේ ක්‍රියාකාරී අර්ථ දැක්වීම් වලින් පසුව ඔබ සතුව ඇත්තේ ඇයි ?)
මෙල්පොමීන්

@melpomene කේතය කැඩී නැත, මම එය පරීක්ෂා කළෙමි. ඔබ අදහස් කරන්නේ එය සම්පාදනය නොවන බව හෝ ප්‍රති result ලය වැරදියි කියාද? අමතර ';' මට මතක නැහැ, ඒවා ඇත්ත වශයෙන්ම ඉවත් කළ හැකිය.
ජොකීම් එල්. ක්‍රිස්ටියන්සන්

(variable & bits == bits)?
melpomene

නොදැනීම ගැන ස්තූතියි, එය එසේ විය යුතුව තිබුණි((variable & bits) == bits)
ජොකීම් එල්. ක්‍රිස්ටියන්සන්

std::bitsetc ++ 11 හි භාවිතා කරන්න
pqnet

0

මෙම වැඩසටහන පදනම් වී ඇත්තේ @ ජෙරමිගේ ඉහත විසඳුමෙන්. යමෙකු ඉක්මනින් සෙල්ලම් කිරීමට කැමති නම්.

public class BitwiseOperations {

    public static void main(String args[]) {

        setABit(0, 4); // set the 4th bit, 0000 -> 1000 [8]
        clearABit(16, 5); // clear the 5th bit, 10000 -> 00000 [0]
        toggleABit(8, 4); // toggle the 4th bit, 1000 -> 0000 [0]
        checkABit(8,4); // check the 4th bit 1000 -> true 
    }

    public static void setABit(int input, int n) {
        input = input | ( 1 << n-1);
        System.out.println(input);
    }


    public static void clearABit(int input, int n) {
        input = input & ~(1 << n-1);
        System.out.println(input);
    }

    public static void toggleABit(int input, int n) {
        input = input ^ (1 << n-1);
        System.out.println(input);
    }

    public static void checkABit(int input, int n) {
        boolean isSet = ((input >> n-1) & 1) == 1; 
        System.out.println(isSet);
    }
}


Output :
8
0
0
true

-2

N බිටු වෙනස් කිරීමට C භාෂාවෙන් මෙම ශ්‍රිත වලින් එකක් උත්සාහ කරන්න:

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;
}

value << nනිර්වචනය නොකළ හැසිරීමට හේතු විය හැක
MM
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.