2016-12-14 2 views
0

의 보수는 단순히 숫자의 모든 비트를 반전하여 전 -i-1 저 얻는 것을 의미누가 정수에 대한 부호 반전 패턴을 정의합니까?

~ 0 -1

~ 01,000,001는 10,111,110

~ 65 인 -66

등. 정수의 부호를 전환하려면 실제 마이너스 기호를 사용해야합니다. 실제 동작이 정의되어 있는지, 및 그의 책임 그것은의 보수 패턴을 보장한다 (다수 네거티브 반전 모든 비트를 만들고 1 추가)

int i = 65; int j = -i; 
cout << j; // -65 

뒤를 이어? 이것이 하드웨어 또는 컴파일러 작업인지는 모르겠습니다.

+5

이것은 수학적 진실입니다. 비트 네거티브 및 증가/감소는 하드웨어에 의해 수행됩니다. 일반적으로 이러한 작업을위한 단일 어셈블리 지침이 있습니다. 현대의 프로세서에는 더 높은 수준의 명령어가 있기는하지만, 어떤 컴파일러가이를 활용할 것인가 ... – qxz

+0

아무도 "책임"이 아니라, 단지 2의 보수 표현의 결과 일뿐입니다. 비트 패턴 '00000000 ... 0'은 '0'을 의미하고, 비트 패턴 '11111111 ... 1'은 '-1'을 의미한다. – Barmar

+0

산술을 구현하는 CPU 부분은 표현이 작동하는 방식을 알고 있습니다. 숫자에 '-1'을 곱하면, 결과는 보수 + add1이됩니다. – Barmar

답변

4

일반적으로 CPU 하드웨어에 의해 수행됩니다.

일부 CPU에는 숫자의 음수를 계산하는 지침이 있습니다. x86 아키텍처에서는 NEG 명령어입니다.

그렇지 않은 경우 곱셈 연산자를 사용하여 숫자에 -1을 곱하면됩니다. 그러나 많은 프로그래머는 당신이 발견 한 정체성을 활용하고, 수를 보완 한 후 1.

How to convert a positive number to negative in assembly

3

그 이유는 간단합니다 참조 추가 : 일관성을 0과 추가로.

당신은 또한이 0

유일한 비트 시퀀스, 고전 넘쳐 증가를 양보해야 1 -1 증가, particulary에 ... 특별한 경우없이 양수와 음수에 대한 동일하게 작동 할 0의 값을 생성하는 것은 모두 1 비트 시퀀스입니다. 1 씩 증가하면 모두 0이됩니다. 모두 1, 당신은 당신이 필요로이 문제를 좋아하지 않는 경우에 0 이제 우리는

-2: 11111110 = ~1 
-1: 11111111 = ~0 
0: 00000000 = ~-1 
+1: 00000001 = ~-2 

(1 각 라인을 증가, 8 개 비트 정수를 가정) 한의 예 비트 부정 : 그래서 당신 -1 특수한 경우도 처리 할 수 ​​있으며 +0과 -0을 갖습니다. 대부분의 경우, 그러한 CPU는 훨씬 느려질 것입니다. 귀하의 질문에 구현되는 방법

int i = -j; 

경우

, 그 컴파일러 및 CPU 및 최적화에 따라 달라집니다. 일반적으로 지정한 다른 작업과 함께 최적화됩니다. 이 아마 1-2 CPU가 계산 틱이 걸리므로이

int i = 0 - j; 

으로 수행되는 끝한다면 놀라지하지 않습니다 (예를 들어, 한 XOR 또는 자체 위에 레지스터로 SUB 작동 한 후, 0을 얻을 수 있습니다 0-j), 병목 현상이 거의 없습니다. 로딩 j 및 어딘가에 메모리에 i 결과를 저장 훨씬 훨씬 더 비쌀 것입니다. 사실, 일부 CPU (MIPS?)에는 항상 0 인 내장 레지스터가 있습니다. 그렇다면 네가 negation에 대한 특별한 지시를 필요로하지 않고, 보통 1 tick에서 $zero에서 j를 뺍니다. 현재 인텔 CPU는 이러한 xor 연산을 인식하고 레지스터 이름 바꾸기 최적화 (즉, 다음 명령어가 0 인 새 레지스터를 사용하도록합니다)와 함께 0 tick으로 수행합니다. amd64에는 neg이 있지만 다른 빠른 상황에서는 xor rax,rax이 유용합니다.

2

C 산술 연산은 값의 관점에서 정의됩니다. 코드 인 경우 :

int i = 65; 
int j = -i; 

컴파일러는 지시에 관계없이 비트 표현의 j-65에게 가치를 제공하는 데 필요한 어떤 CPU 방출한다.

역사적으로 모든 시스템이 2의 보수를 사용하는 것은 아닙니다. C 컴파일러는 CPU 성능에 따라 타겟 CPU에 대해 가장 효율적인 출력을 유도하는 음수 시스템을 선택합니다.

그러나 2의 보수는 산술을 수행하기위한 가장 간단한 알고리즘으로 연결되기 때문에 매우 보편적 인 선택입니다. 예를 들어 부호가있는 정수와 부호없는 정수가있는 +-*에 동일한 명령어를 사용할 수 있습니다.

+1

사이드 바 : 2s-complement 곱셈의 구현은 일반적으로 혼합 너비 피연산자를 곱할 때 1s-complement 곱하기보다 많은 리소스가 필요합니다. 이것은 하드웨어 또는 소프트웨어에서든 상관 없습니다. 예 : 8 비트 부호있는 값에 2 비트 보수의 32 비트 부호가있는 값을 곱하려면 8 비트 피연산자를 부호 확장하고 곱셈에 더 넓은 확장 된 값을 사용해야합니다. 1s 보완에서는 문제가되지 않습니다. 먼저 부호를 추출한 다음 부호없는 숫자로 값을 곱한 다음 결과의 부호를 다시 삽입하십시오. –