Bir biti nasıl ayarlar, temizler ve değiştirirsiniz?
Bir biti ayarlamak için bitsel VEYA operatörünü (|
) kullanın.
number |= 1UL << n;
Bu, sayı
nın n
inci bitini ayarlayacaktır. Eğer 1
inci biti ayarlamak istiyorsanız n
sıfır olmalı ve n
inci biti ayarlamak istiyorsanız n-1
e kadar devam etmelidir.
Eğer sayı
işaretsiz uzun
dan daha genişse 1ULL
kullanın; 1UL << n
terfisi 1UL << n
değerlendirildikten sonra gerçekleşmez, burada uzun
un genişliğinden daha fazla kaydırma yapmak tanımlanmamış bir davranıştır. Aynı durum diğer tüm örnekler için de geçerlidir.
Bir biti temizlemek için bitsel AND operatörünü (&
) kullanın.
number &= ~(1UL << n);
Bu, sayı
nın n
inci bitini temizleyecektir. Bit dizesini bitsel DEĞİL işleci (~
) ile ters çevirmeli, ardından VE yapmalısınız.
XOR operatörü (^
) bir biti değiştirmek için kullanılabilir.
number ^= 1UL << n;
Bu, sayı'nın
n`inci bitini değiştirecektir.
Bunu istemediniz ama ben de ekleyebilirim.
Bir biti kontrol etmek için n sayısını sağa kaydırın, ardından bitsel VE yapın:
bit = (number >> n) & 1U;
Bu, sayı
nın n
inci bitinin değerini bit
değişkenine koyacaktır.
ninci bitin
1ya da
0` olarak ayarlanması, 2'ye tümleyen bir C++ uygulamasında aşağıdaki şekilde gerçekleştirilebilir:
number ^= (-x ^ number) & (1UL << n);
Bit n
, x
1
ise ayarlanacak ve x
0
ise temizlenecektir. Eğer x
başka bir değere sahipse, çöp alırsınız. x = !!x` onu 0 veya 1 olarak booleanize edecektir.
Bunu 2'nin tümleyen olumsuzlama davranışından bağımsız hale getirmek için (1'in tümleyen veya işaret/büyüklük C++ uygulamasından farklı olarak -1
in tüm bitleri ayarlıdır), işaretsiz olumsuzlama kullanın.
number ^= (-(unsigned long)x ^ number) & (1UL << n);
veya
unsigned long newbit = !!x; // Also booleanize to force 0 or 1
number ^= (-newbit ^ number) & (1UL << n);
Taşınabilir bit manipülasyonu için işaretsiz tipleri kullanmak genellikle iyi bir fikirdir.
veya
number = (number & ~(1UL << n)) | (x << n);
(sayı & ~(1UL << n))`n
inci biti temizleyecek ve (x << n)
n
inci biti x
olarak ayarlayacaktır.
Ayrıca, genel olarak kodu kopyalayıp yapıştırmamak iyi bir fikirdir ve pek çok kişi önişlemci makroları (topluluk wiki cevabı daha aşağıda gibi) veya bir tür kapsülleme kullanır.
Bazen bitleri adlandırmak için bir enum
kullanmaya değer:
enum ThingFlags = {
ThingMask = 0x0000,
ThingFlag0 = 1 << 0,
ThingFlag1 = 1 << 1,
ThingError = 1 << 8,
}
Daha sonra isimleri kullanın. Yani yaz
thingstate |= ThingFlag1;
thingstate &= ~ThingFlag0;
if (thing & ThingError) {...}
ayarlamak, temizlemek ve test etmek için. Bu şekilde sihirli sayıları kodunuzun geri kalanından gizlersiniz.
Bunun dışında Jeremy'nin çözümünü destekliyorum.
Bitsel operatörleri kullanın: &
|
000b`deki son biti ayarlamak için:
foo = foo | 001b
Son biti foo
içinde kontrol etmek için:
if ( foo & 001b ) ....
foo`daki son biti temizlemek için:
foo = foo & 110b
Anlaşılır olması için XXXb
kullandım. Bitleri paketlediğiniz veri yapısına bağlı olarak muhtemelen HEX gösterimi ile çalışacaksınız.