2012-06-04 21 views
5

Bu yüzden bayt dizisinden 12 bit tamsayı okuyorum. Bu sayı negatif olabilir ancak bunu C# 'da kullanılabilir bir int16/int32 değişkenine nasıl dönüştürebileceğimi anlayamıyorum. Bir his var Ben biraz değişiklik veya diğer bitwise işlemleri ile bir şeyler yapmak gerekecek ama ben şimdiye kadar çok çarpıcı oldum. Birisi bana doğru yönde işaret edebilir.12 bit int 16 veya 32 bit dönüştür

var x = 0xFFF;

Bu, -1 olarak yazdırılır, ancak C# doğal olarak bir int32'ye yayınlanır ve 4095 olarak yazdırılır. Bu int16 veya int32'ye aktarılırsa, negatif değeri nasıl koruyabilirim.

cevap

13

32 bit: Koşullamalar olmadan

x = (x >> 11) == 0 ? x : -1^0xFFF | x; 
+0

Harika çalışıyor, çok teşekkürler! Burada neler olduğunu açıklayan akıl mı? ne olduğunu biliyorum >> ama tam olarak anlaşılmıyor. – Clarke76

+2

Temel olarak yalnızca işaret bitine kadar sağa kayıyor. Sıfır ise, o zaman orijinal değeri döndürürüz. Eğer 1 ise o zaman -1 (0xFFFFFFFF), alt 12 biti ('xor'), daha sonra' ya da 'bitleri açmak için orjinal değerini kapatıyoruz. Sonuç temel olarak sadece 32 bitlik değerin üst 20 biti açılmaktadır. –

+0

Evet ... her şeyi kağıda yazıyorum ve ne olduğunu tam olarak gördüm. Bu gerçekten yardımcı oldu. Bunun için son biti negatif bir bayrak olarak kullanılacaktır. Bundan sonra takip etmek kolaydı. Tekrar teşekkürler. – Clarke76

8

İşaret uzantısı, imzalı kısa zaten içeren 12 bitlik değerini x varsayarak:

x = (x << 4) >> 4; 

parantez neler anlamak için sadece destek. Bit vardiyaları, diğer aritmetik ve mantıksal operatörler gibi sola dayalıdır. Bunun nedeninin nedeni, >>'un imzalı türler için aritmetik bir sağ kaydırma olmasıdır. Bu, sıfırlar içinde en anlamlı biti kaydırmak yerine, MSB'yi gerektiği kadar çoğaltır. n bit m için bit'ten genelde

İşaret uzantısı sonra olacaktır: long için

x = (x << (m - n)) >> (m - n); 
sbyte için 8 ile sınırlı olacaktır m Bilinen nedenlerden dolayı

, 16 short için, 32 int için ve 64. Yine, parantez tamamen kozmetiktir. Çıkarma, bit vardiyalarından daha sıkı bağlanır.

0

İmzayı tespit edin ve uzatın. 16-bit:

x = (x & 0x800 ? x^0xf000 : x); 
İlgili konular