2014-09-10 23 views
5

'u göz ardı ederek Python'da bir "~" işlemi yapmam gerekiyor ama 2'nin tamamlayıcısı hesaba katılmıyor. Bunu XOR kullanarak yapmayı başardım, bunu yapmanın başka bir yolunu biliyor musun? (Daha verimli)Python'da "Bitwise Not", 2'nin tamamlayıcısı olan

~ zaten böyle yapıyor
a = 0b101 
b = 0b10101 

print bin(a^(2 ** a.bit_length() - 1)) #0b10 
print bin(b^(2 ** b.bit_length() - 1)) #0b1010 
+0

sorabilir miyim: Bunun yerine sayı kendisi genişliğini kullanmak yerine belirli bir genişliğe sınırlandırabilirsiniz Eğer


, o zaman (32 bit örneğini kullanarak) basit bir mesele var niye ya? 'Bin' temsilinin sizi şaşırttığı olasıdır. '~ 'bitleri ters çevirir; sadece bitlerin * sonsuz sayısını * dönüştürür, bu da metinsel olarak temsil edilmesini imkansız kılar. 'bin' böylece çalışmasını sağlamak için bazı şeylerle uğraşır, ama tüm bitlerin ters çevrildiğini gizlemek biter. – Veedrac

+0

@Veedrac 16bit vm uyguluyorum. –

+0

Bence yolların yeterince iyi, pythonun bunu yapmanın doğal bir yolu olduğunu düşünmeyin. Küçük bir değişiklik, güçler yerine bitshift kullanarak olabilir. – simonzack

cevap

4

. Zor olan kısım, Python'un sınırsız uzunluklu tam sayılara sahip olmasıdır, bu yüzden bir sayıyı ters çevirdiğinizde - en azından kavramsal olarak - sonsuz sayıda 1 ile genişletilmiş işarettir. Anlamı negatif sayılar olsun.

>>> bin(~0b101) 
'-0b110' 
>>> bin(~0b10101) 
'-0b10110' 

Bunları imzasız numaralara dönüştürmek için, kaç tane önem verdiğinize karar vermeniz gerekir. Belki 8 bitlik baytlarla çalışıyorsunuzdur.

>>> bin(~0b101 & 0xFF) 
'0b11111010' 
>>> bin(~0b10101 & 0xFF) 
'0b11101010' 

Yoksa girdi numaralarının tam bit uzunluğunu eşleştirmek istiyorsanız, çözüm makul: Sonra 1 bit byte'ın yetmeyecek ile olabilir VE onlar. Verimlilik için sol kayma için üssü değiştirebilirsin. Ve ^ yerine ~ ve & kullanmak daha net olabilir.

>>> bin(~a & ((1 << a.bit_length()) - 1)) 
'0b10' 
>>> bin(~b & ((1 << b.bit_length()) - 1)) 
'0b1010' 

(I & 0xFFFF gibi kodlanmış maske pratikte doğru çözüm olacaktır sanıyorum. Ben bit_length() tabanlı cevap için iyi bir gerçek dünya senaryosunun düşünemiyorum.)

+0

Teşekkürler, bit_length'in matematik veya string manipülasyonunu kullandığını biliyor musunuz? –

+0

'bit_length' dizelere dokunmuyor.CPython'da – simonzack

+0

'bit_length' yaklaşık olarak sabit bir zamandır ve çırpınacak derecede hızlı görünüyor, dolayısıyla yalnızca dahili bir önbelleğe alınmış değer döndürdüğünü varsayalım. – Veedrac

0

başka yolu da, (ben dahil) bazı bunu daha iyi olduğunu itiraz olsa, geçerli:

from string import maketrans 
tbl = maketrans("01","10") 

int(bin(42)[2:].translate(tbl),2) 

ilk bit sadece bir dizede 1 ve 0 bitlerini ters çevirmek için bir çeviri tablosunu kurar. , - (>0b10101042) ön 0b kapalı şeritler ve çeviri yoluyla bit ters çevirir

ikinci bit ikili gösterimi alır. Ardından, bu ikili dizeyi bir sayıya geri döndürmek için int(,2) kullanın.

val = val^0xffff 
İlgili konular