그 이유는 간단합니다 참조 추가 : 일관성을 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
이 유용합니다.
이것은 수학적 진실입니다. 비트 네거티브 및 증가/감소는 하드웨어에 의해 수행됩니다. 일반적으로 이러한 작업을위한 단일 어셈블리 지침이 있습니다. 현대의 프로세서에는 더 높은 수준의 명령어가 있기는하지만, 어떤 컴파일러가이를 활용할 것인가 ... – qxz
아무도 "책임"이 아니라, 단지 2의 보수 표현의 결과 일뿐입니다. 비트 패턴 '00000000 ... 0'은 '0'을 의미하고, 비트 패턴 '11111111 ... 1'은 '-1'을 의미한다. – Barmar
산술을 구현하는 CPU 부분은 표현이 작동하는 방식을 알고 있습니다. 숫자에 '-1'을 곱하면, 결과는 보수 + add1이됩니다. – Barmar