2016-09-17 4 views
1

비트 시프트 연산 >>을 음의 정수로 이해하려고합니다.음수의 비트 시프트?

-2 >> 1 # -1 
-3 >> 1 # -2 
-5 >> 1 # -3 
-7 >> 1 # -4 

누군가가 어떻게 수행되는지 설명 할 수 있습니까? 나는 그것이 2의 보수와 관련이있다는 것을 알고 있지만, 나는 그것을 시프 팅 작업과 관련시킬 수 없다.

+0

부호 비트가 확장되어 결과가 음수로 유지됩니다. – martineau

답변

2

전체 설명은 음의 정수에 대한 here

2의 보수 바이너리를 제공한다 :

음수 대신 선도적 인 제로의 선도적 인 하나 기록됩니다. 따라서 두 자리에 8 비트를 사용하는 경우 숫자를 사용하면 "00000000"에서 "01111111"까지 패턴을 0에서 127까지의 정수로 처리하고 음수를 쓰려면 "1xxxxxxx"를 예약합니다. 음수 인 -x는 모든 비트가 보완 된 ( 에서 0 또는 0-1로 전환 된) 비트 (x-1)의 패턴을 사용하여 작성됩니다. -1은 보완 (1 - 1) = 보완 (0) = "11111111"이고 -10은 보완 (10-1) = 보완 (9) = 보수 ("00001001") = "11110110"입니다. 즉 음수가 인 경우 -128 ("10000000")까지 내려갑니다.

물론 파이썬은 8 비트 숫자를 사용하지 않습니다. 그러나 을 사용하여 컴퓨터에 기본으로 제공된 비트가 많았지 만 이후 이 아닌 이식 가능한 코드는 비트의 INFINITE 번호로 최근에 전환되었습니다. 따라서 숫자 -5는 "... 1111111111111111111011"이라고 쓰여진 것처럼 인 것처럼 비트 연산자에 의해 처리됩니다.

따라서 시프트 연산자에 대한 설명 :

X >> 비트와 Y 반환 X는 Y 위치만큼 우측으로 시프트. 이 은 // x 2 by y와 같습니다.

def twos_comp(val, nbits): 
    """Compute the 2's complement of int value val""" 
    if val < 0: 
     val = (1 << nbits) + val 
    else: 
     if (val & (1 << (nbits - 1))) != 0: 
      # If sign bit is set. 
      # compute negative value. 
      val = val - (1 << nbits) 
    return val 

def foo(a,b): 
    print("{0:b} >> {1:b} = {2:b} <==> {3:b} >> {4:b} = {5:b}".format(
     a,b,a>>b, 
     twos_comp(a,8),b, twos_comp(a>>b,8) 
    )) 

foo(-2, 1) 
foo(-3, 1) 
foo(-5, 1) 
foo(-7, 1) 

출력 : 위의 설명을 이해하기 위해이 같은 뭔가를 확인하실 수 있습니다에서

-10 >> 1 = -1 <==> 11111110 >> 1 = 11111111 
-11 >> 1 = -10 <==> 11111101 >> 1 = 11111110 
-101 >> 1 = -11 <==> 11111011 >> 1 = 11111101 
-111 >> 1 = -100 <==> 11111001 >> 1 = 11111100 

당신이 볼 수 있듯이, 2의 보수 번호가 기호를 확장합니다.