Game !






1
2
3
4
5
6
7
 
    int iNumber = 10;
 
    cout << iNumber << endl;             // 10
    cout << (~iNumber) << endl;          // -11
    cout << (~iNumber) + 1 << endl;      // -10
 
cs

 






1
2
3
4
5
6
7
8
9
10
11
 
    int iNumber = 10;
 
    cout << iNumber << endl
 
    // 컴퓨터는 2의 보수 체계여서, 이 코드에서는.  
// 1의 보수를 취하고, +1 을 해서 만든 2의 보수로 표현된 수를..
// 다시 비트 반전(1의 보수)만 해서 원래 값 -11 을 표현한 것이다.
    cout << (~iNumber) << endl;    
 
    // 다시 비트 반전 (1의 보수)만 해서 나온 원래 값을 
// (대수적 계산인) -1 을 해서 만든 2의 보수로 표현된 수가 나와서 -10 을 표현한 것이다
    cout << (~iNumber) + 1 << endl;    
 
cs

 







▼ ver. 1

더보기

이진수의 음수 표현

컴퓨터에서 음수를 표기할 때 비트의 맨 앞 부분을 부호 비트로 사용하기로 약속했다.
그러나, 이 방법에는 한 가지 문제가 있다.

1 + ( -1 ) = 0 이 되어야하는데

00000001 ( 1 )
+ 10000001 ( -1 )
----------------
10000010 ( -2 )

-2 가 되어버리는 문제가 발생..


그래서 산술 연산을 할 때 사용되는 음수 표현 방식이 2의 보수 방법 이다.
부호 비트 개념은 그대로 사용함.

 


2의 보수

어떤 수를 커다란 2의 제곱수에서 빼서 얻은 이진수
> ㅎㅎ ?

2의 보수는 대부분 산술 연산에서 원래 숫자의 음수를 표현하는 것으로 사용된다.
( 내가 이해한 것을 의역한 것 )
( 원래 문장 : 2의 보수는 대부분의 산술연산에서 원래 숫자의 음수처럼 취급된다. )

 


컴퓨터에서 사용되는 2의 보수

CPU 를 구성하는 가장 중요한 요소
1. 레지스터
2. ALU ( 산술 논리 장치 ) ▶ 정수형 처리는 여기서 이루어진다.

두 개의 요소 모두 설계 상 비트수를 결정하고 만들어야 하는데
CPU 의 비트수 제한으로 인해 이진법 계산의 적용에서 비트를 벗어나면 버리게 되어있다.


컴퓨터에서는 프로그램에서 부호를 지정하는 변수를 사용할 때 2의 보수를 적용해서 쓰고있다.

ex 1. )

char chr = -3;

char 는 8비트 정수형 변수이다.
(char 는 문자를 저장하지만 문자는 결국 우리가 보기 편한 방식인 거고 문자도 숫자일 뿐이다. )
unsigned 키워드를 사용하지 않았으므로 음수를 표현할 수 있는 정수형 변수이다.

컴파일러가 -3 을 표기할 때는 다음과 같이 이진수로 바꾸어서 기계어 코드와 결합한다.
( -3 의 원래 숫자는 3 )


00000011 ( 3의 2진수 표현 )
이 이진수의 1의 보수를 구하면 ( 1의 보수는 비트 반전으로 구할 수 있다 )
11111100


3의 1의 보수 값에 다시 1을 더한다.
11111100 ( -3 )
+ 00000001 ( 1 )
----------------
11111101 ( -3 )

결과 : 11111101 를 도출할 수 있고, 11111101 는 -3 이다.


참고 :
음수의 이진수 변환까지는 컴파일러가 한다.
덧셈, 뺄셈 등, 산술 연산은 ALU에서 한다. ( ex. -3 + 4 = 1 )


ex 2. )

↓부호비트
00000001 ( 1 ) 의 2의 보수 방법으로 표현하면
11111111 ( -1 )


ex 3. )

char 는 -127 ~ 127 까지 값을 저장할 수 있는데,
만약 char chr = 128 값을 저장할 경우 ( 127 을 초과하는 수를 넣었다 )
변수에 의도하지 않은 값이 들어가게 된다. 이것을 산술 오버플로우 라고 부른다.

그런데, char chr = 128 값을 넣었는데 chr 에 -128 값이 들어가게된다. 왜 하필 -128 일까.

-128 을 2의 보수 방법으로 표현하면
10000000 ( -128 )

그런데 만약 맨 앞의 비트가 부호 비트가 아닐 경우에는
일반적인 이진수 표현으로 128 이 된다.
10000000 ( 128 )
▶ 왜 이렇게 되나묜..
8비트만 레지스터에 저장하는데, 계산했을 때 8자리에서 9자리로 넘어가버리게 되었기 때문. 이 경우에 9자리로 넘어간 최상위 비트를 버리고 8비트만 저장한다.
ex.
11111101 (-3)
+ 00000100 ( 4 )
----------------
1 00000001

여기서 1을 버린다. 결국, 00000001 을 저장


 

출처:
https://ko.wikipedia.org/wiki/2%EC%9D%98_%EB%B3%B4%EC%88%98







'Computer' 카테고리의 다른 글

컴퓨터와 프로그램 메모리  (0) 2022.05.02