부호있는 정수와 부호없는 정수의 차이점은 다음과 같습니다.
- 부호없는 값은 더 큰 양수 값을 보유 할 수 있으며 음수 값을 보유 할 수 없습니다.
- 부호 없음은 값의 일부로 선행 비트를 사용하는 반면 부호있는 버전은 가장 왼쪽 비트를 사용하여 숫자가 양수인지 음수인지 식별합니다.
- 부호있는 정수는 양수와 음수를 모두 보유 할 수 있습니다.
다른 차이점이 있습니까?
부호있는 정수와 부호없는 정수의 차이점은 다음과 같습니다.
다른 차이점이 있습니까?
답변:
부호없는 값은 더 큰 양수 값을 보유 할 수 있으며 음수 값을 보유 할 수 없습니다.
예.
부호 없음은 값의 일부로 선행 비트를 사용하는 반면 부호있는 버전은 가장 왼쪽 비트를 사용하여 숫자가 양수인지 음수인지 식별합니다.
부호있는 정수를 나타내는 여러 가지 방법이 있습니다. 시각화하는 가장 쉬운 방법은 가장 왼쪽 비트를 플래그 ( 부호 및 크기 )로 사용하는 것이지만, 일반적으로 2의 보수 입니다. 둘 다 대부분의 최신 마이크로 프로세서에서 사용됩니다. 부동 소수점은 부호와 크기를 사용하고 정수 산술은 2의 보수를 사용합니다.
부호있는 정수는 양수와 음수를 모두 보유 할 수 있습니다.
예
x86에서 하드웨어 수준의 차이점을 살펴 보겠습니다. 컴파일러를 작성하거나 어셈블리 언어를 사용하지 않는 한 이것은 대부분 관련이 없습니다. 그러나 알아두면 좋습니다.
첫째, x86은 부호있는 숫자 의 2의 보수 표현을 기본적으로 지원 합니다. 다른 표현을 사용할 수 있지만 더 많은 지시가 필요하며 일반적으로 프로세서 시간을 낭비합니다.
"기본 지원"이란 무엇입니까? 기본적으로 나는 부호없는 숫자에 사용되는 명령어 세트와 부호있는 숫자에 사용하는 다른 세트가 있음을 의미합니다. 부호없는 숫자는 부호있는 숫자와 동일한 레지스터에있을 수 있으며 실제로 프로세서를 걱정하지 않고 부호있는 명령어와 부호없는 명령어를 혼합 할 수 있습니다. 숫자의 서명 여부를 추적하고 적절한 지침을 사용하는 것은 컴파일러 (또는 어셈블리 프로그래머)의 책임입니다.
첫째, 2의 보수 숫자는 덧셈과 뺄셈이 부호없는 숫자와 동일하다는 특성을 가지고 있습니다. 숫자가 양수인지 음수인지는 차이가 없습니다. (그냥 가서 그래서 ADD
하고 SUB
걱정없이 숫자.)
비교할 때 차이점이 보이기 시작합니다. x86은 그것들을 구별하는 간단한 방법을 가지고 있습니다 : 위 / 아래는 부호없는 비교를 나타내며 부호있는 비교를 나타내는 것보다 크거나 작습니다. (예 : JAE
"위의 경우 점프"를 의미하며 부호가 없습니다.)
부호있는 정수와 부호없는 정수를 처리하기위한 곱셈 및 나눗셈 명령어 세트도 있습니다.
마지막으로 오버플로를 확인하려면 부호있는 숫자와 부호없는 숫자에 대해 다르게 수행하십시오.
완전성을위한 몇 가지 요점 :
이 답변은 정수 표현에 대해서만 논의합니다. 부동 소수점에 대한 다른 답변이있을 수 있습니다.
음수의 표현은 다를 수 있습니다. (지금까지 - 오늘 거의 보편적이다) 가장 일반적으로 오늘날 사용은 2의 보수 . 다른 표현으로는 하나의 보수 (quite rare)와 부호가있는 크기 (vanishly rare-아마도 박물관 조각에만 사용됨)가 있습니다. 이것은 단순히 비트를 숫자의 절대 값을 나타내는 나머지 비트와 함께 부호 표시기로 사용합니다.
2의 보수를 사용할 때 변수는 양수보다 음수의 더 큰 범위 (1 씩)를 나타낼 수 있습니다. 이는 부호 비트가 0으로 설정되지 않았기 때문에 '양수'숫자에는 0이 포함되지만 음수는 아니기 때문입니다. 이것은 가장 작은 음수의 절대 값을 표현할 수 없음을 의미합니다.
1의 보수 또는 부호있는 크기를 사용하는 경우 0을 양수 또는 음수로 나타낼 수 있습니다 (이러한 표현이 일반적으로 사용되지 않는 몇 가지 이유 중 하나임).
포인트 2를 제외한 모든 것이 정확합니다. 부호있는 정수에 대한 여러 가지 표기법이 있으며 일부 구현은 첫 번째 구현을 사용하고 다른 구현은 마지막을 사용하고 다른 구현은 완전히 다른 것을 사용합니다. 모든 것은 작업중인 플랫폼에 따라 다릅니다.
다른 사람들이 말한 것 이상으로 C에서는 부호없는 정수를 오버플로 할 수 없습니다. 동작은 모듈러스 산술로 정의됩니다. 부호있는 정수를 오버플로 할 수 있으며 이론 상으로는 (현재 주류 시스템에서는 실제로는 아니지만) 오버플로로 인해 오류가 발생할 수 있습니다 (아마도 0으로 나누기 오류와 유사).
(두 번째 질문에 대한 답변) 부호 비트 (2의 보수는 아님) 만 사용하면 -0으로 끝날 수 있습니다. 별로 예쁘지 않습니다.
C의 부호있는 정수는 숫자를 나타냅니다. 경우 a
와 b
유형 부호있는 정수의 변수, 표준은 컴파일러가 표현 할 것을 요구하지 않습니다 a+=b
에 저장소를 a
각각의 값의 산술 합 이외. 확실하게 산술 합이에 맞지 않으면 a
프로세서 가 그것을 넣을 수는 없지만 표준은 컴파일러가 값을 자르거나 줄 바꿈하거나 값을 초과하는 경우 그 문제에 대해 다른 것을 요구하지 않습니다 그들의 유형에 대한 한계. 표준에는 필요하지 않지만 C 구현에서는 부호있는 값으로 산술 오버플로를 트랩 할 수 있습니다.
C에서 부호없는 정수는 더 큰 유형으로 변환하거나 연산하는 시나리오를 제외하고는 2의 거듭 제곱 인 합동 정수의 추상 대수 고리로 동작합니다. 임의의 크기 의 정수를 32 비트 부호없는 유형으로 변환하면 해당 정수 mod 4,294,967,296에 해당하는 항목에 해당하는 멤버가 생성됩니다. 3을 2에서 빼는 이유 4,294,967,295는 3에 합한 것을 4,294,967,295에 합한 것에 더하면 2에 합당한 것을 산출하기 때문입니다.
추상 대수 고리 유형은 종종 유용한 것들입니다. 불행히도 C는 형식이 링으로 작동해야하는지 여부를 결정하는 요소로 부호를 사용합니다. 더 나쁜 것은 부호없는 값은 더 큰 유형으로 변환 될 때 링 멤버가 아니라 숫자로 처리되고, 부호없는 값은 int
산술이 수행 될 때 숫자로 변환되는 것보다 작 습니다. 경우 v
A는 uint32_t
같아지는 4,294,967,294
다음 v*=v;
확인해야합니다 v=4
. 불행히도 int
64 비트라면 무엇을 v*=v;
할 수 있는지 말하지 않습니다.
표준을 그대로 감안할 때 대수 고리와 관련된 동작을 원하는 상황에서 부호없는 유형을 사용하고 숫자를 나타내려면 부호있는 유형을 사용하는 것이 좋습니다. 불행히도 C가 그랬던 것처럼 차별화를 이끌어 냈지만, 그것이 바로 그런 것입니다.
부호없는 정수는 부호있는 정수보다 특정 트랩에서 당신을 잡을 가능성이 훨씬 큽니다. 함정은 위의 1 & 3은 정확하지만 두 유형의 정수 모두 "보유"할 수있는 범위를 벗어나는 값을 할당 할 수 있으며 자동으로 변환됩니다.
unsigned int ui = -1;
signed int si = -1;
if (ui < 0) {
printf("unsigned < 0\n");
}
if (si < 0) {
printf("signed < 0\n");
}
if (ui == si) {
printf("%d == %d\n", ui, si);
printf("%ud == %ud\n", ui, si);
}
이 값을 실행하면 두 값이 모두 -1에 할당되고 다르게 선언 된 경우에도 다음과 같은 결과가 나타납니다.
signed < 0
-1 == -1
4294967295d == 4294967295d