[c] 부호있는 정수와 부호없는 정수의 차이점은 무엇입니까?

부호있는 정수와 부호없는 정수의 차이점은 무엇입니까?



답변

아시다시피 ints는 내부적으로 바이너리에 저장됩니다. 일반적으로 int에는 32 비트가 포함되지만 일부 환경에서는 16 비트 또는 64 비트 (또는 다른 숫자, 일반적으로 2의 거듭 제곱 일 필요는 없음)를 포함 할 수 있습니다.

그러나이 예에서는 4 비트 정수를 살펴 보겠습니다. 작지만 설명 목적으로 유용합니다.

이러한 정수에는 4 비트가 있으므로 16 개의 값 중 하나를 가정 할 수 있습니다. 16은 2의 4 제곱 또는 2 x 2 x 2 x 2입니다.이 값은 무엇입니까? 답은이 정수가 있는지 여부에 따라 signed int또는를 unsigned int. 를 사용하면 unsigned int값은 절대 음수가 아닙니다. 값과 관련된 부호가 없습니다. 다음은 4 비트의 16 가지 가능한 값입니다 unsigned int.

bits  value
0000    0
0001    1
0010    2
0011    3
0100    4
0101    5
0110    6
0111    7
1000    8
1001    9
1010   10
1011   11
1100   12
1101   13
1110   14
1111   15

… 그리고 다음은 4 비트의 16 가지 가능한 값입니다 signed int.

bits  value
0000    0
0001    1
0010    2
0011    3
0100    4
0101    5
0110    6
0111    7
1000   -8
1001   -7
1010   -6
1011   -5
1100   -4
1101   -3
1110   -2
1111   -1

보시다시피 signed ints의 1경우 최상위 비트는 숫자가 음수 인 경우에만 해당됩니다. 이것이 signed ints의 경우이 비트를 “부호 비트”라고하는 이유 입니다.


답변

int그리고 unsigned int두 가지 정수 타입이다. ( int이라고도 할 수 signed int또는 단지 signed; unsigned int이라고도 할 수있다 unsigned).

이름에서 알 수 있듯이, intA는 서명 정수 유형 및 unsigned int입니다 부호없는 정수 타입. 즉 int, 음수 값을 나타낼 unsigned int수 있으며 음수가 아닌 값만 나타낼 수 있습니다.

C 언어는 이러한 유형의 범위에 몇 가지 요구 사항을 부과합니다. 범위는 .. int이상이어야 하고 범위는 .. 이상이어야합니다 . 이는 두 유형 모두 최소 16 비트 여야 함을 의미합니다. 많은 시스템에서 32 비트이거나 일부에서는 64 비트입니다. 일반적으로 대부분의 최신 시스템에서 사용되는 2의 보수 표현으로 인해 추가 음수 값이 있습니다.-32767+32767unsigned int065535int

아마도 가장 중요한 차이점은 부호있는 산술과 부호없는 산술의 동작입니다. signed의 int경우 오버플로에 정의되지 않은 동작이 있습니다. 의 경우 unsigned int오버플로가 없습니다. 유형의 범위를 벗어난 값을 생성하는 모든 작업은 래핑됩니다 UINT_MAX + 1U == 0U.

부호있는 또는 부호없는 모든 정수 유형은 무한한 수학적 정수 집합의 하위 범위를 모델링합니다. 유형의 범위 내에서 값으로 작업하는 한 모든 것이 작동합니다. 유형의 하한 또는 상한에 접근하면 불연속이 발생하고 예기치 않은 결과가 발생할 수 있습니다. 유형 부호있는 정수의 경우, 문제는 매우 큰 음과 양의 값을 초과하는 경우에만 발생 INT_MIN하고 INT_MAX. 부호없는 정수 유형의 경우 매우 큰 양수 값 과 0에서 문제가 발생 합니다 . 이것은 버그의 원인이 될 수 있습니다. 예를 들어, 이것은 무한 루프입니다.

for (unsigned int i = 10; i >= 0; i --) [
    printf("%u\n", i);
}

i항상 0보다 크거나 같기 때문 입니다 . 이것이 서명되지 않은 유형의 특성입니다. (루프 내부에서 값 i이 0이면 i--값을로 설정합니다 UINT_MAX.)


답변

때때로 우리는 주어진 정수 변수에 저장된 값이 항상 양수라는 것을 미리 알고 있습니다. 이 경우 변수를 unsigned로 선언 할 수 있습니다.unsigned int num student; . 이러한 선언을 사용하면 허용되는 정수 값 (32 비트 컴파일러의 경우) 범위가 -2147483648에서 +2147483647 범위에서 0에서 4294967295 범위로 이동합니다. 따라서 정수를 부호없는 것으로 선언하면 가능한 가장 큰 값의 크기가 거의 두 배가됩니다. 그렇지 않으면 보유 할 수있는 가치.


답변

평신도의 용어로 unsigned int는 음수가 될 수없는 정수이므로 가정 할 수있는 양의 값 범위가 더 큽니다. 부호있는 int는 음수 일 수 있지만 더 많은 음수 값을 가정 할 수있는 대가로 더 낮은 양수 범위를 갖는 정수입니다.


답변

실제로 두 가지 차이점이 있습니다.

  1. 인쇄 (예 : coutC ++ 또는 printfC) : 부호없는 정수 비트 표현은 인쇄 함수에 의해 음이 아닌 정수로 해석됩니다.
  2. ordering : 순서는 서명되거나 서명되지 않은 사양에 따라 다릅니다.

이 코드는 순서 기준을 사용하여 정수를 식별 할 수 있습니다.

char a = 0;
a--;
if (0 < a)
    printf("unsigned");
else
    printf("signed");


답변