[자바인강 2주차] 두 번째 난관, 음수의 표현
자바인강 1주차와 2주차까지는 본격적인 객체 지향 프로그래밍을 배우기 앞서서 자바의 기초가 되는 문법과 개념을 배웠다. 그런데 나는 기초의 시작부터 자주 일시정지를 누르고 상념에 빠지곤 했다. 웹 기반의 CSS나 자바스크립트를 배울 때는 그리 중요치 않았던 '비트(bit)'라는 개념 때문이었다.
비트는 binary digit의 줄임말로, 0이나 1의 값을 가진 정보를 말한다. 0,1 이 단 두 숫자만으로 컴퓨터는 모든 언어를 만들어낸다. 아니, 모든 의미를 표현한다. 어떻게 그런가? 한글은 0, 1보다는 많은 자음과 모음으로 조합된 기호이긴 하지만, 이러한 언어의 조합이 무한한 만큼 숫자도 무한하다. 물론 문자로 된 단어의 의미를 표현하기 위해서는 0, 1로 길게 늘여 써야 하겠지만 불가능한 것은 아니다. 모든 언어의 원리가 그렇듯 인간들은 기호(기표)에 의미(기의)를 붙여 의사소통을 하고, 이는 컴퓨터의 언어도 마찬가지였다. 다만 컴퓨터 언어는 아래 세 가지 구성요소가 있음을 이해해야 했다.
- 기호가 들어갈 상자
- 상자 들어갈 기호
- 상자의 순서
한 권으로 읽는 컴퓨터 구조와 프로그래밍, 53쪽
컴퓨터 언어가 0과 1로 이루어진다는 것은 상식처럼 알고 있었지만, 0과 1로 2진법을 넘어서 8진법, 16진법까지 쓰이고 또는 이것으로 문자열을 표기한다는 것은 몰랐다. 또 '상자'의 갯수에 따라 자료형을 나누어서 분류한다는 점도 흥미로운 지점이었다. 이를테면 비트 상자 8개가 모이는 이는 1바이트(byte)이고, 비트 상자가 16개가 모이면 1숏(short), 32개가 모이면 1인트(int)가 된다. 컴퓨터는 자료형의 크기에 따라서 연산하는 방법이 다르고, 대화 속도에도 차이를 보인다고 한다. 자바에서는 자료형 선언이 프로그래밍의 기본이어서 자료형의 종류를 암기할 필요가 있었다.
그런데 지난주에 println에서 장벽을 만난 것처럼, 비트 연산자 부분에서 또다시 멘붕을 경험했다. 일반 연산자가 수학에서 본 내용과 그리 다르지 않다면, 비트 연산자는 0,1로 이루어진 계산이다보니 일반적인 10진법의 계산과는 달랐다. 예를 들면 비트 연산자의 '~'은 비트를 반전시킨다.
아래와 같은 1바이트의 값이 있다.
00000101 -- 2진수의 값으로 이는 5다.
여기에 '~' 연산자를 하면,
11111010 이 된다.
'11111010'를 10진수로 바꾸면 '250'이 되어야 할 것 같다..! 하지만 답은 '-6'이란다!
어찌된 일인가? 강사님은 '음수의 보수'를 하면 '-6'이 되겠네요~ 하고 아주 간단하게 넘어간 부분인데, 맨 처음 상자 값이 음수를 표기하는 값이라고 해도 나머지 비트를 2진수로 계산하면 '-122'가 나와야 했다.
컴퓨터의 언어에는 '-'란 기호가 없다. 0,1 이라는 기표와 상자의 순서를 조합하여 음수를 표현한다. 그리하여 첫번째 상자가 0이면 양수이고, 1이면 음수다. 그런데 여기서 끝이 아니다. '00000001'은 '1'이지만, '10000001'은 '-1'이 아니다.
https://st-lab.tistory.com/189
이에 대한 설명은 아래 블로그에서 설명을 찾을 수 있었다. 위 긴 설명을 간단히 요약하면, 컴퓨터의 계산이 용이하기 위해서는 음수는 비트를 반전시킨뒤 1을 더하는 2의 보수의 방법으로 표현하는 것이 더 낫다는 것이다.
따라서 위 비트를 다시 살펴보면,
00000101 --이 것의 '~' 연산 값은
11111010 --- 이며, 이를 음수로 표현하고자 하다면 '1'을 더해야 하고, 이는 곧
11111011 --- 되며, 이는 또 곧
00000100 의 음수값이므로 '-6'이 되는 것이었다!
컴퓨터는 찰떡 같이 알아듣는 2의 보수를, 인간은 3단계를 걸쳐서 알아야 한다! 여하튼, 비트 연산자와 갑작스러운 음수의 표현에 갈길을 잃을 뻔 했던 나는 다행히 패스트캠퍼스에서는 슬랙이란 메신저를 통해서 질의응답을 할 수 있었고, 위의 내용을 익힐 수 있는 코멘트를 받을 수 있었다.
1주차에서 자료형과 연산자(비트 연산자 이후로는 순조롭게) 조건문과 반복문을 학습했다. 2주차에서부터는 본격적으로 객체 지향 프로그래밍의 기초를 다루었다. 객체 지향 프로그래밍은 1) 객체를 정의하고, 2) 각 객체의 속성을 메서드(method)로 구현하고, 3) 각 각체 간의 협력을 구현하는 것이라 한다. 객체 지향 프로그램의 이점은 C언어와 같은 절차 지향 프로그래밍과 달리 반복되는 코드를 다시 사용함으로써 생산성을 높일 수 있는 점이라 한다.
이를테면, 절차 지향 프로그래밍은
내가 아침에 일어나서, 씻고, 밥을 먹고, 버스를 타고, 학교에 도착한다. 라고 쓰는 것을,
내가 아침에 일어나서, 밥을 먹고, 버스를 타고, 씻고, 학교에 도착한다. 라고 쓰고 싶다면
내가 쓴 처음 문장을 다 살펴보고 수정하고 싶은 부분은 지우고 다시 추가해야 한다.
하지만 객체 지향 프로그래밍은
나, 아침, 일어난다, 씻는다, 밥을 먹는다, 버스를 탄다, 학교에 도착한다. 와 같은 구문을
아예 나누어 다루기 때문에 새로 쓸 필요 없이 이들 간의 관계를 구현하는 코드만 바꾸면 된다.
오케이. 객체 지향 프로그래밍의 원리를 깨달았고, 이를 대강 어떻게 구현하겠다는 것도 알겠다. 강사님이 하시는 것을 아기 걸음마마냥 따라 갔다. 클래스라는 걸 만들어서 객체를 선언하고, 그 객체들은 속성을 부여하자.. 그런데 이쯤에서 안 나오면 섭섭했나. 세 번째 장벽을 만나고야 말았다.
잠깐, 생성자(constructor)는 또 뭔데..?
#패스트캠퍼스 #내일배움카드 #국비지원 #K디지털기초역량훈련 #바이트디그리 #자바인강