2011-08-28 15 views
7

Bugün "Programlama İncileri" okumaya başladım ve egzersiz yaparken "Buradaki bit vektörünü nasıl uygularsınız?" Ben çözümü bakıldığında böyle oldu: Ben de karıştı alıyorumBit Programlamada aşağıdaki programda bulunan maskeleme kullanımı Pearls

#define BITSPERWORD 32 
#define SHIFT 5 
#define MASK 0x1F 
#define N 10000000 

int a[1 + N/BITSPERWORD]; 

void set(int i) { a[i >> SHIFT] |= (1 << (i & MASK)); 

burada neler olduğunu

1 << (i & MASK) 

birisi bana açıklayabilir misiniz bu ifade doğrudur? SHIFTBITSPERWORD tam baz-2 logaritma olduğu MASK, en düşük SHIFT bitleri sahip olacak şekilde ayarlandığını

cevap

4

not edin.

nedenle (i & MASK) 32 bölme sonra kalanı alarak aynıdır i, en düşük 5 bit seçecektir ondalık sayı en düşük iki basamak alarak nasıl (sadece düşünün için, 100 ile bölünmesi sonra size kalanı verir örnek). Yani içinde bizi ilgilendiren bir kelime bit sayısını verir.

1 << (i & MASK)) şimdi bir değer yaratır (bu arada, bir ifadesi değil, bir açıklamada olan) tam olarak nerede bit ilgileniyoruz. Bu değerin |= ile bellek sözcüğüne birleştirilmesi, bit vektörünün istenen bitini ayarlayacaktır.

+0

Yanıt Henning için teşekkürler. Eğer (i & MASK) 'i (i% 32) ile değiştirirseniz bu geçerli olur mu? Geçerli ama zarif değilse, o zaman ben ve MASK'ın neden% 32'nin üzerinde tercih edildiğine dair biraz ışık tutabiliyor musunuz? Çok teşekkürler. – test123

+0

Evet - 'i & MASK' ve' i% 32', negatif olmadığından emin olduğunuzla aynı şeydir. Bitsel AND, tipik olarak geri kalan bir bölümden daha verimlidir ve bu nedenle geleneksel seçim haline gelmiştir. Ya da en azından, aptallar nerede derlerse daha verimli olurlar. Bugün bile, orta düzeyde bir derleyicinin, bu bağlamda 'i' 32 'i' ve 31 '' i yeniden yazmasını bile bekleyebilirsiniz (ya da "i" nin negatif olmadığını, bu durumda yeniden yazmanın her zaman güvenli olduğunu ya da Olumsuz bir sonucun, vardiyada tanımlanmamış davranışları tetiklemesine sebep olabilir. –

+0

Harika. Açıklama için çok teşekkürler. – test123

2

0x20 32, bu nedenle i & 0x1Fi modulo 32 alır, böylece 32 bit hiç geçiş yapmazsınız. Bu bir korunmadır, çünkü türün boyutundan kesinlikle az olmayan herhangi bir şey tarafından kaydırılması tanımlanmamış bir davranıştır.

+0

Cevrek için teşekkürler Kerrek! – test123