Jak ustawić, wyczyścić i przełączyć pojedynczy bit?
Jak ustawić, wyczyścić i przełączyć bit W C / C++?
26 answers
Ustawianie bitu
Użyj operatora bitowego OR (|
), aby ustawić bit.
number |= 1UL << n;
To ustawi n
Ten bit number
.
Użyj 1ULL
, jeśli number
jest szersza niż unsigned long
; promocja 1UL << n
następuje dopiero po ocenie 1UL << n
, gdzie niezdefiniowanym zachowaniem jest przesunięcie o więcej niż szerokość long
. To samo dotyczy wszystkich pozostałych przykładów.
Wyczyszczenie bitu
Użyj operatora bitowego i (&
), aby wyczyścić trochę.
number &= ~(1UL << n);
To wyczyści n
Ten bit number
. Musisz odwrócić łańcuch bitowy operatorem bitwise NOT (~
), then I it.
Przełączanie bitów
Operator XOR (^
) może być użyty do przełączania bitów.
number ^= 1UL << n;
To przełącza n
Ten bit number
.
Sprawdzanie bitu
Nie prosiłeś o to, ale równie dobrze mogę to dodać.Aby sprawdzić bit, przesuń liczbę n w prawo, a następnie bitowo i it:
bit = (number >> n) & 1U;
To umieści wartość n
tego bitu number
W Zmiennej bit
.
Zmiana N TH bit na x
W przeciwieństwie do innych bitów w C++, bit ten nie może być używany w C++, ale może być używany w C++.]}number ^= (-x ^ number) & (1UL << n);
Bit n
zostanie ustawiony, jeśli x
jest 1
, i wyczyszczony, jeśli x
jest 0
. Jeśli x
ma jakąś inną wartość, dostajesz śmieci. x = !!x
spowoduje booleanizację do 0 lub 1.
Aby to uniezależnić od zachowania negacji dopełniacza 2 (gdzie -1
ma ustawione wszystkie bity, w przeciwieństwie do implementacji C++ dopełniacza 1 lub znaku/wielkości), użyj negacji niepodpisanej.
number ^= (-(unsigned long)x ^ number) & (1UL << n);
Lub
unsigned long newbit = !!x; // Also booleanize to force 0 or 1
number ^= (-newbit ^ number) & (1UL << n);
Ogólnie dobrym pomysłem jest używanie typów niepodpisanych do przenośnej manipulacji bitami.
Ogólnie dobrym pomysłem jest nie kopiowanie/wklejanie kodu w ogóle i tak wiele osób używa makr preprocesora (jak community wiki odpowiada dalej w dół ) lub jakiś rodzaj enkapsulacji.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-24 18:42:18
Używanie standardowej biblioteki C++ : std::bitset<N>
.
Lub wersjaBoost : boost::dynamic_bitset
.
Nie ma potrzeby kręcić własnego:
#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
Wersja Boost pozwala na użycie zestawu bitów o rozmiarze runtime w porównaniu ze standardową biblioteką w czasie kompilacji.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-16 01:18:57
Inną opcją jest użycie pól bitowych:
struct bits {
unsigned int a:1;
unsigned int b:1;
unsigned int c:1;
};
struct bits mybits;
Definiuje 3-bitowe pole (właściwie to trzy 1-bitowe feldy). Operacje bitowe stają się teraz nieco (haha) prostsze:
Aby ustawić lub wyczyścić bit:
mybits.b = 1;
mybits.c = 0;
Aby przełączyć bit:
mybits.a = !mybits.a;
mybits.b = ~mybits.b;
mybits.c ^= 1; /* all work */
Sprawdzanie bitu:
if (mybits.c) //if mybits.c is non zero the next line below will execute
To działa tylko z polami bitowymi o stałej wielkości. W przeciwnym razie musisz uciekać się do technik bit-twidling opisanych w poprzednich postach.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-29 00:40:32
Używam makr zdefiniowanych w pliku nagłówkowym do obsługi Bit set I clear:
/* 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)))
/* 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))
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-10 21:30:17
Czasem warto użyć enum
do nazwy bitów:
enum ThingFlags = {
ThingMask = 0x0000,
ThingFlag0 = 1 << 0,
ThingFlag1 = 1 << 1,
ThingError = 1 << 8,
}
Następnie używaj nazw później. Tzn. write
thingstate |= ThingFlag1;
thingstate &= ~ThingFlag0;
if (thing & ThingError) {...}
Aby ustawić, wyczyścić i przetestować. W ten sposób ukrywasz magiczne liczby przed resztą kodu.
Poza tym popieram rozwiązanie Jeremy ' ego.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-18 15:54:21
Z snip-c.zip 's 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)))
Dobrze, przeanalizujmy to...
Często spotykanym wyrażeniem, z którym masz problemy, jest "(1L
0000 0000 0000 0000 0000 0000 0000 0001 binary.
Jeśli posn = = 8, to oceni
0000 0000 0000 0000 0000 0001 0000 0000 binary.
W innych słowa, po prostu tworzy pole 0 ' S z 1 na określonym pozycji. Jedyną trudną częścią jest Makro BitClr (), w którym musimy ustawić pojedynczy bit 0 w polu 1 's. osiąga się to za pomocą 1' s dopełniacz tego samego wyrażenia oznaczonego operatorem tyldy ( ~ ).
Po utworzeniu maski zostanie zastosowana do argumentu tak, jak sugerujesz, za pomocą operatorów bitowych oraz (&), or ( | ) I xor ( ^ ). Od maski jest typu long, makra będą działać tak jak well on char 's, short' s, int ' s, lub Longa.
Najważniejsze jest to, że jest to ogólne rozwiązanie dla całej klasy problemy. Jest oczywiście możliwe, a nawet właściwe przepisanie odpowiednik dowolnego z tych makr z jawnymi wartościami maski za każdym razem, gdy potrzebuję, ale po co to robić? Pamiętaj, że podstawienie makro występuje w preprocesora i tak wygenerowany kod będzie odzwierciedlał fakt, że wartości są uważane za stałe przez kompilator - tzn. jest tak samo wydajne, aby użycie uogólnione makra, jak" odkrywać koło " za każdym razem, gdy trzeba zrobić trochę manipulacji.
Nieprzekonany? Oto kod testowy-użyłem Watcom C z pełną optymalizacją i bez użycia _cdecl, więc wynikający demontaż byłby tak czysty jak możliwe:
----[ 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 (zdemontowany) ]-----------------------------------------------
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 ]-----------------------------------------------------------------
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-07 15:07:16
Dla początkujących chciałbym wyjaśnić nieco więcej na przykładzie:
Przykład:
value is 0x55;
bitnum : 3rd.
Użyty jest operator &
Sprawdź bit:
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)
Przełącz lub Przełącz:
0101 0101
^
0000 1000
___________
0101 1101 (Flip the third bit without affecting other bits)
|
operator: Ustaw bit
0101 0101
|
0000 1000
___________
0101 1101 (set the third bit without affecting other bits)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-22 16:09:54
Użyj operatorów bitowych: &
|
Aby ustawić ostatni bit w 000b
:
foo = foo | 001b
Aby sprawdzić ostatni bit w foo
:
if ( foo & 001b ) ....
Aby wyczyścić ostatni bit w foo
:
foo = foo & 110b
Użyłem XXXb
dla jasności. Prawdopodobnie będziesz pracować z reprezentacją szesnastkową, w zależności od struktury danych, w której pakujesz bity.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-12 11:23:14
Oto moje ulubione bitowe makro arytmetyczne, które działa dla każdego typu unsigned integer array od unsigned char
do size_t
(który jest największym typem, który powinien być wydajny do pracy):
#define BITOP(a,b,op) \
((a)[(size_t)(b)/(8*sizeof *(a))] op ((size_t)1<<((size_t)(b)%(8*sizeof *(a)))))
Aby ustawić bit:
BITOP(array, bit, |=);
Aby wyczyścić bit:
BITOP(array, bit, &=~);
Aby przełączyć bit:
BITOP(array, bit, ^=);
Aby przetestować bit:
if (BITOP(array, bit, &)) ...
Itd.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-09 14:21:00
Jak to jest oznaczone "embedded" zakładam, że używasz mikrokontrolera. Wszystkie powyższe sugestie są poprawne i działają ( read-modify-write, unions, structs, etc.).
Jednak podczas debugowania opartego na oscyloskopie byłem zdumiony odkryciem, że te metody mają znaczny narzut w cyklach CPU w porównaniu do zapisu wartości bezpośrednio do rejestrów PORTnSET / PORTnCLEAR micro, co robi prawdziwą różnicę tam, gdzie są ciasne pętle / przełączanie ISR o wysokiej częstotliwości Szpilki.
Dla tych nieznanych: w moim przykładzie mikro ma ogólny rejestr stanu pinów PORTn, który odzwierciedla piny wyjściowe, więc wykonanie PORTn / = BIT_TO_SET powoduje odczyt-modyfikację-zapis do tego rejestru. Jednak rejestry PORTnSET / PORTnCLEAR przyjmują "1", co oznacza" proszę uczynić ten bit 1 "(SET) lub" proszę uczynić ten bit zero "(CLEAR), a"0" oznacza "zostaw pin w spokoju". w związku z tym otrzymujesz dwa adresy portów w zależności od tego, czy ustawiasz lub czyścisz bit (nie zawsze wygodny), ale dużo szybsza reakcja i mniejszy zmontowany kod.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-14 15:23:17
Podejście bitfield ma inne zalety w wbudowanej arenie. Można zdefiniować strukturę, która mapuje bezpośrednio na bity w określonym rejestrze sprzętowym.
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;
Musisz być świadomy kolejności pakowania bitów - myślę, że najpierw jest to MSB, ale może to być zależne od implementacji. Sprawdź również, jak pola obsługi kompilatora przekraczają granice bajtów.
Można następnie odczytywać, zapisywać, testować poszczególne wartości jak wcześniej.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-06 11:30:16
Bardziej ogólne, dla dowolnych wielkości bitmap:
#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)))
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-15 07:38:21
Sprawdzanie bitu w dowolnej lokalizacji w zmiennej dowolnego typu:
#define bit_test(x, y) ( ( ((const char*)&(x))[(y)>>3] & 0x80 >> ((y)&0x07)) >> (7-((y)&0x07) ) )
Przykładowe użycie:
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;
}
Uwagi: Jest on zaprojektowany tak, aby był szybki (biorąc pod uwagę jego elastyczność) i nie rozgałęziający się. Skutkuje to wydajnym kodem maszynowym SPARC po skompilowaniu Sun Studio 8; testowałem go również przy użyciu MSVC++ 2008 na amd64. Możliwe jest tworzenie podobnych makr do ustawiania i usuwania bitów. Kluczową różnicą tego rozwiązania w porównaniu z wieloma innymi jest to, że działa dla dowolnej lokalizacji w prawie każdym typie zmiennej.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-03 23:44:14
Jeśli robisz dużo trochę twidling może chcesz użyć masek, które sprawi, że całość szybciej. Poniższe funkcje są bardzo szybkie i wciąż elastyczne (pozwalają na przesuwanie bitów w Mapach bitowych o dowolnej wielkości).
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;
}
Uwaga, Aby ustawić bit 'n' w 16-bitowej liczbie całkowitej, wykonaj następujące czynności:
TSetBit( n, &my_int);
Do ciebie należy upewnienie się, że numer bitu mieści się w zakresie mapy bitowej, którą przekazujesz. Zauważ, że dla małych procesorów endian, które bytes, words, dwords, qwords, itd., Mapuj poprawnie do siebie w pamięci (główny powód, dla którego małe procesory endian są "lepsze" niż procesory big-endian, Ah, czuję, że nadchodzi wojna płomieniowa...).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-05 11:20:35
Ten program ma zmienić dowolny bit danych z 0 Na 1 lub 1 na 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);
}
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-22 16:07:42
Użyj tego:
int ToggleNthBit ( unsigned char n, int num )
{
if(num & (1 << n))
num &= ~(1 << n);
else
num |= (1 << n);
return num;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-22 16:06:03
Rozszerzanie na bitset
ODPOWIEDŹ:
#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;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-08 04:33:41
Jeśli chcesz wykonać tę całą operację z programowaniem w C w jądrze Linuksa to proponuję użyć standardowych API jądra Linuksa.
Zobacz 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
Uwaga: tutaj cała operacja odbywa się w jednym kroku. Więc te wszystkie są gwarantowane atomic nawet na komputerach SMP i są przydatne aby zachować spójność między procesorami.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-01 16:21:28
Visual C 2010, a być może wiele innych kompilatorów, posiada bezpośrednie wsparcie dla operacji bitowych wbudowanych. Co zaskakujące, to działa, nawet operator sizeof() działa poprawnie.
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);
}
Więc, na twoje pytanie, IsGph [i] =1 lub IsGph [i] =0 sprawiają, że ustawianie i czyszczenie boolów jest łatwe.
Aby znaleźć znaki niedrukowalne...
// 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;
}
}
Uwaga nie ma nic "specjalnego" w tym kodzie. Traktuje trochę jak liczbę całkowitą - która technicznie jest. 1-bitowa liczba całkowita, która może pomieścić 2 wartości i 2 tylko wartości.
Kiedyś użyłem tego podejścia, aby znaleźć zduplikowane rekordy pożyczek, gdzie loan_number był kluczem ISAM, używając 6-cyfrowego numeru pożyczki jako indeksu do tablicy bitów. Szybko i po 8 miesiącach okazało się, że system mainframe, z którego pobieraliśmy dane, faktycznie działał nieprawidłowo. Prostota macierzy bitowych sprawia, że zaufanie do ich poprawności jest bardzo wysokie - np. w stosunku do podejścia przeszukiwania.
Użyj jednego z operatorów zdefiniowanych tutaj .
Aby ustawić bit, użyj int x = x | 0x?;
gdzie ?
jest pozycją bitową w postaci binarnej.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-05 22:58:36
Oto kilka makr, których używam:
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)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-06 23:11:18
Jak ustawić, wyczyścić i przełączyć pojedynczy bit?
Aby rozwiązać najczęstszą pułapkę kodowania podczas próby utworzenia maski:1
nie zawsze jest wystarczająco szeroka
Jakie problemy zdarzają się, gdy number
jest typu szerszego niż 1
?x
może być zbyt duża dla zmiany 1 << x
prowadzącej do niezdefiniowanego zachowania (UB). Nawet jeśli x
nie jest zbyt wielka, ~
może nie odwrócić wystarczającej ilości najbardziej znaczących bitów.
// 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
Aby ubezpieczyć 1 jest wystarczająco szeroki:
Kod może używać 1ull
lub pedantycznie (uintmax_t)1
i pozwolić kompilatorowi na optymalizację.
number |= (1ull << x);
number |= ((uintmax_t)1 << x);
Lub cast-co sprawia, że problemy z kodowaniem/przeglądem / konserwacją utrzymują poprawny i aktualny cast.
number |= (type_of_number)1 << x;
Lub delikatnie wypromuj 1
wymuszając operację matematyczną, która jest co najmniej tak szeroka jak typ number
.
number |= (number*0 + 1) << x;
Jak w przypadku większości manipulacji bitami, najlepiej pracować z typami unsigned zamiast signed ones
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-27 18:18:48
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);
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-21 12:35:12
A C++11 template version (put in a header):
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;}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-27 20:51:05
Zmienna używana
int value, pos;
Wartość-Dane
pos-pozycja bitu, który chcemy ustawić, wyczyścić lub przełączyć
Ustaw bit
value = value | 1 << pos;
Wyczyść bit
value = value & ~(1 << pos);
Przełącz bit
value = value ^ 1 << pos;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-11 17:32:56
Wypróbuj jedną z tych funkcji w języku C, aby zmienić N bit:
char bitfield;
// Start at 0th position
void chang_n_bit(int n, int value)
{
bitfield = (bitfield | (1 << n)) & (~( (1 << n) ^ (value << n) ));
}
Lub
void chang_n_bit(int n, int value)
{
bitfield = (bitfield | (1 << n)) & ((value << n) | ((~0) ^ (1 << n)));
}
Lub
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;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-16 01:20:23