2012-07-03 24 views
12

'da bit olarak bir tamsayı oluşturma Bitleri temsil eden üç bool değerine sahibim. Ben başka bir yol, belki var mı daha basit benÜç bool değerden C++

int val = 4*boolVal1 + 2*boolVal2 + boolVal3; 

sahip formu

true true true = 7 
false true false = 2 

bir tamsayı olmasını istiyorum?

+1

Sadece fyi, "doğru gerçek doğru" sonucu 7 değil mi? Aksi takdirde tüm formüller yanlıştır ... – SinisterMJ

+2

'int val = 4 * boolVal1 + 2 * boolVal2 + boolVal3;' true olarak doğru 7 true verdiğinizde true 8 –

+0

Doğru, yanlış yazdım. Düzeltmek için teşekkürler! – tzippy

cevap

27

Bunu daha net yerine çarpma ve ek bit cinsinden operatörlerini kullanmak bulabilirsiniz: çarpma ve bitshifting daha

int val = (boolVal1 << 2) | (boolVal2 << 1) | boolVal3; 
4

Diğer, ayrıca ilişkiyi belgelemek için bir enum kullanabilirsiniz. Normalde çabaya değmez, ama sadece bütünlük için ...

enum Encoding 
{ 
    Flag3 = 1,  NotFlag3 = 0, 
    Flag2 = 1 << 1, NotFlag2 = 0, 
    Flag1 = 1 << 2, NotFlag1 = 0 
}; 

int val = (boolVal1 ? Flag1 : NotFlag1) | 
      (boolVal2 ? Flag2 : NotFlag2) | 
      (boolVal3 ? Flag3 : NotFlag3); 

Neden bu konuda rahatsız olursun? Bu sadece biraz daha geneldir, bu yüzden potansiyel olarak dağıtılmış kodlara gerçek değerleri kullanarak dokunmak zorunda kalmadan Kodlama değerlerini potansiyel olarak değiştirebilirsiniz (örneğin, bazı dosya veya ağ biçimlerine göre biraz dışarıda kaldığını fark ederseniz) ayrıştırmanız gereken veriler, bunu tek bir yere ekleyebilir ve yeniden derleyebilirsiniz). Tabii ki sadece tek bir kodlama/kod çözme işlevi sağlamak daha iyidir ve eğer yeni bayraklar ekliyorsanız hala ona ihtiyacınız olacak.

Flag1 ve NotFlag1 öğesinin bulunması anlamsız görünebilir olsa da, genellikle Yapışkan ve Kayan veya Erkek ve Kadın gibi birbirini dışlayan değerler gibi bir şeye sahip olmanız söz konusudur, ve istemcileri denetlemek için belirli bir neden yoktur. !! vb Erkek olarak Sabit veya Bayan ..

+0

'NotFlag'lar burada çok yararlı değil. Flag2'nin temizlenip temizlenmediğini öğrenmek istiyorsanız, yine de '(value & Flag2) == NotFlag2' seçeneğini kontrol edersiniz. Ayrıca, '': 'çarpmadan daha yavaş kod oluşturabilir (dallanma vs. aritmetik işlem).Ayrıca, kullanışlı operatörleri aşırı bulmak '|' '&', '^' ve '~' tip korunur, böylece bu tür çeteleler için - hatta bunun için bir makro var. – krlmlr

+0

user946850 @ -, ya da birlikte İşaret olan keyfi bir miktarda ve "temizlik" terimi bu nedenle çok önemlidir olabilir, genellikle bir işlev (özellikle Cı fonksiyonları) bayrakları bir parametre kodlamak için arayanları sorun, çok dağılmış çağrı kodu ve "NotFlag" e ihtiyaç duymadan oldukça mutlu bir şekilde bayraklar için test yapın - bu, çağrılan fonksiyon (lar) ın uygulanması içinde pekiştirilen adımlar, çok daha kolay korunur. Ve evet, enumlar müşteri kodunda uygun değerler olarak kullanıldığında - ve sadece bir parametreyi kodlamak için değil - uygun operatörler sahip olmaya değer. –

5

Yoksa Horner yöntemi kullanabilirsiniz: Bu aynı zamanda daha kolay eklemek veya değişikliğe gerek kalmadan açıklamada ortasından değişkenleri kaldırmak için yapar

int val = (((boolVal1 << 1) | boolVal2) << 1) | boolVal3.

diğer tüm katsayılar. Bununla birlikte, bu, okuyucu için biraz daha az belirgin olabilir.

+1

fark muhtemeldir, ama olsun merak kadarıyla hayır - ortak derleyiciler ile - bu nedeniyle değerlendirmede sıralı sıralamayı sahip daha kötü performans gösterebilir: Herhangi/onların optimisers tüm kodu üretebilir eğer can bilmek ilginç olurdu bir CPU talimat boru hattı .... –

+0

@Tony üzerinde paralelleştirildiği edilmesi, makinenin koduna bakmak gerekirdi, ama modern derleyiciler hiçbir parantez içinde dallanma vardır fark edip oldukça temiz bu gevşemeye beklenebilir. –

2

sen de uygulama tanımlı davranış ve bit kümeleri, küçük endian sürümünü kullanabilirsiniz endianness'ın biliyorsanız:

union foo { 
     unsigned int the_int; 
     struct { 
       unsigned int bit3:1 
       unsigned int bit2:1 
       unsigned int bit1:1 
     }; 
}; 

ve sonra bunları ayarlamak için:

foo.bit1 = true; 
foo.bit2 = false; 
foo.bit3 = true; 

ve okunması:

foo.the_int; 

Büyük endian sürümü, bitleri tersine çevirir ve çok fazla dolguya sahiptir (29 bit eğer), 32 bit genişliğindedir).

İlgili konular