정수 값 0
과 -0
본질적으로 동일 하다는 것을 알고 있습니다. 하지만 구분이 가능한지 궁금합니다.
예를 들어, 변수가 할당되었는지 어떻게 알 수 -0
있습니까?
bool IsNegative(int num)
{
// How ?
}
int num = -0;
int additinon = 5;
num += (IsNegative(num)) ? -addition : addition;
값 -0
이 메모리에 저장되는 것과 똑같은 방식으로 저장 0
됩니까?
답변
대상 머신에 따라 다릅니다.
정수에 2의 보수 표현 을 사용하는 컴퓨터에서는 비트 수준 에서 0
와 -0
(동일한 표현을 가짐) 간에 차이 가 없습니다.
당신의 기계가 1의 보수를 사용했다면 , 당신은 확실히 할 수 있습니다
0000 0000 -> signed 0
1111 1111 -> signed −0
분명히 우리는 기본 지원을 사용 하는 것에 대해 이야기하고 있습니다 . x86 시리즈 프로세서는 부호있는 숫자의 두 가지 보완 표현을 기본 지원합니다. 다른 표현을 사용하는 것은 확실히 가능하지만 효율성이 떨어지고 더 많은 지침이 필요합니다.
(JerryCoffin도 언급했듯이 : 1의 보수가 대부분 역사적 이유로 고려 되었음에도 불구하고 부호있는 크기 표현 은 여전히 상당히 일반적이며 음수 및 양수 0에 대한 별도의 표현을 가지고 있습니다)
답변
에 대한 int
(거의 보편적 인 “2의 보수”표현)의 표현 0
과 -0
동일합니다. (예 : IEEE 754 부동 소수점과 같은 다른 숫자 표현에서는 다를 수 있습니다.)
답변
2의 보수에서 0을 나타내는 것으로 시작하겠습니다 (물론 다른 많은 시스템과 표현이 있습니다. 여기서는이 특정 시스템을 참조합니다). 8 비트, 0은 다음과 같다고 가정합니다.
0000 0000
이제 모든 비트를 뒤집고 1을 더하여 2의 보수를 얻습니다.
1111 1111 (flip)
0000 0001 (add one)
---------
0000 0000
우리는를 얻었고 0000 0000
그것은 -0의 표현이기도합니다.
그러나 1의 보수에서 부호있는 0은 0000 0000이지만 -0은 1111 1111입니다.
답변
나는 C와 C ++ 구현이 일반적으로 밀접하게 관련되어 있기 때문에이 대답을 남겨두기로 결정했지만 실제로 생각했던 것처럼 C 표준을 따르지 않습니다. 요점은 C ++ 표준이 이와 같은 경우에 어떤 일이 발생하는지 지정하지 않는다는 것입니다. 또한 2로 보완되지 않은 표현은 현실 세계에서 매우 드물고, 존재하는 곳에서도 다른 사람이 쉽게 발견 할 수있는 것으로 드러내 기보다는 많은 경우에 차이를 숨기는 경우가 많습니다.
존재하는 정수 표현에서 음수 0의 동작은 C 표준 에서처럼 C ++ 표준에서 엄격하게 정의되지 않습니다. 그러나 C 표준 (ISO / IEC 9899 : 1999)을 최상위 수준의 표준 참조로 인용합니다 [1.2].
C 표준 [6.2.6.2]에서 음의 0은 비트 연산의 결과이거나 음의 0이 이미 존재하는 연산 (예 : 음의 0을 값으로 곱하거나 나누거나 0)-단항 빼기 연산자를 예에서와 같이 일반 0 값에 적용하면 일반 0이 보장됩니다.
음의 0을 생성 할 수 있는 경우 에도 음의 0을 지원하는 시스템에서도 그럴 것이라는 보장은 없습니다.
이러한 경우가 실제로 음의 0을 생성하는지 일반 0을 생성하는지, 음의 0이 객체에 저장 될 때 일반 0이되는지는 지정되지 않습니다.
따라서 우리는 결론을 내릴 수 있습니다. 아니오,이 경우를 감지 할 수있는 신뢰할 수있는 방법이 없습니다. 2가 아닌 보완 표현이 현대 컴퓨터 시스템에서 매우 드물다는 사실이 아니더라도.
C ++ 표준은 “음의 0″이라는 용어를 언급하지 않으며, 허용되는 [3.9.1 para 7]을 제외하고는 부호있는 크기와 1의 보수 표현에 대한 세부 사항에 대해 거의 논의하지 않습니다.
답변
컴퓨터에 -0
및 +0
에 대한 고유 한 표현이 있으면 memcmp
구분할 수 있습니다.
패딩 비트가있는 경우 실제로 0이 아닌 값에 대한 여러 표현이있을 수 있습니다.
답변
C ++ 언어 사양에는 음의 0 과 같은 int가 없습니다 .
이 두 단어가 갖는 유일한 의미는 3 더하기 5 가 and에 적용된 이항 연산자 인 것처럼 단항 연산자가 -
적용됩니다 .0
+
3
5
뚜렷한 음의 0 이있는 경우 , 2의 보수 (정수 유형의 가장 일반적인 표현)는 두 가지 형태의 0을 표현할 방법이 없기 때문에 C ++ 구현에 대해 불충분 한 표현입니다.
반대로, 부동 소수점 (IEEE 이후)에는 별도의 양수 및 음수 0이 있습니다. 예를 들어 1을 1로 나눌 때 구별 할 수 있습니다. 양의 0은 양의 무한대를 생성합니다. 음수 0은 음의 무한대를 생성합니다.
그러나 int 0 (또는 임의의 int 또는 다른 유형의 다른 값)의 다른 메모리 표현이있는 경우 다음 memcmp
을 발견하는 데 사용할 수 있습니다 .
#include <string>
int main() {
int a = ...
int b = ...
if (memcmp(&a, &b, sizeof(int))) {
// a and b have different representations in memory
}
}
물론 이것이 발생하면 직접 메모리 작업 외에 두 값은 여전히 똑같은 방식으로 작동합니다.