취업 준비를 하며 복습한다는 마음으로, 이것을 보는 누군가에게 도움이 되었으면 하는 마음으로
Java-Tutoral을 작성해 봅니다. 입문서와 순서가 잘못되었을 수 있고, 제가 아는 정보가 틀렸을 수 있습니다.
이 글에 대한 잘못된 정보나, 오탈자 등 수정해야 할 항목 혹은 추가해야 할 항목은 댓글로 알려주시면 감사하겠습니다.
이 자료가 올라가는 저장소 :
https://github.com/hwk0911/Java-tutorial
솔직히 제목 정할 때 엄청 고민했습니다.
아 이것도 진짜 필요한 내용인데.... 아 자료형에 넣을까?? 아닌데.. 1번 강의에 넣으면 좋은데 너무 길어..
내가 썼지만 나도 재미없는걸... 그래 1.5장으로 새로 만들자! 그래서 준비한 1장의 번외 1.5장!
아.. 이거 제목을 뭘로 하지 아.. 최솟값의 절댓값... 아 아냐.. 후..
제목 결정하는데 15분 정도 소모한 것 같습니다. ㅎㅎ
우선 우리는 1장에서 Java의 자료형 (Primitive Type, Reference Type)에 대해 공부하였다.
오늘 주제는 Primitive Type을 기준으로 진행하려 한다.
자료형의 범위가 왜 음수가 양수보다 1 만큼 더 넓은지에 대해 복습하고자 한다.
먼저 결론부터 말씀드리자면, 컴퓨터에서의 음수와 양수의 범위는 같습니다.
-0, +0 중 +0을 채택하였기 때문에 더 넓어보이는 것 입니다.
물론 최대, 최소값의 절대값은 다릅니다.
bit : 0 또는 1의 값을 가질 수 있는 단위를 말한다. 전기가 흐르면 1, 전기가 흐르지 않으면 0
즉 컴퓨터에는 오직 두 가지 상태만이 존재한다. 0 or 1
컴퓨터 연산의 최소단위라 할 수 있다.
초등학생 때 읽었던 'why 시리즈 : 컴퓨터'에서는 bit를 설명할 때 전구에 비유하여 설명하였다.
전구는 꺼져있다, 켜져 있다 이 두 상황으로 표현이 가능하다. (밝기 조절이 가능한 전구는 제외한다.)
이때 꺼져있으면 0, 켜져있으면 1이라 가정하였을 때, 전구도 비트와 같은 값을 갖는다.
하지만 여기서 주의 할 점은 bit 가 0과 1을 표현하는것이 아닌 두 가지 상태를 표현하는 것 이다.
이것은 요점이 아니니 넘어가도록 하겠다. 이번 포스팅에서는 bit는 0과 1을 표현한다 가정하고 마저 작성하겠다.
1 bit 는 0 ~ 1의 표현이 가능하고, 2bit 는 0 ~ 3의 표현이 가능하다.
수학에서 배운 2진수와 똑같다! 2진수의 길이가 한칸 이면 0 ~ 1, 두칸 이면 0 ~ 3 이 표현 가능하다.
우선 Byte는 8개의 bit로 이뤄져 있다. (1Byte = 8bit)
bit 가 표현 가능한 상태의 수는 2^x (x는 bit의 수, x >= 1) 로 표현이 가능하다.
Byte 는 8개의 비트라 256개의 표현이 가능하다. (2^8 = 256)
MB, GB 도 있는데 byte를 설명한 이유는, 컴퓨터에서 사용되는 단위는 SI 접두어 + Byte로 표현하기 때문이다.
(Mega, Giga 다 SI 접두어다.)
Java 자료형의 단위는 byte로 표현이 가능하다. (boolean은 Virtual Machine Dependent 이므로 제외한다.)
원시 자료형을 나타낸 표를 다시보자.
자료형 | 키워드 | 크기 | 기본값(전역변수 한정) | 표현범위 |
논리형 | boolean | 미정 Virtual Machine Dependent |
false | true, false |
문자형(유니코드) | char | 2byte | \u0000 | 0 ~ 65,535 |
정수형 | byte | 1byte | 0 | -128 ~ 127 |
short | 2byte | 0 | -32768 ~ 32767 | |
int | 4byte | 0 | -2147483648 ~ 2147483647 |
|
long | 8byte | 0 | -9223372036854775808 ~ 9223372036854775807 |
|
실수형 | float | 4byte | 0.0 | -3.4E38 ~ +3.4E38 |
double | 8byte | 0.0 | -1.7E308 ~ +1.7E308 |
표를 살펴보면 위에 서술한 내용과 맞지않는 부분이 있다.
byte 자료형은 1byte로 이뤄져 있는데, 표현 범위는 왜 -127 ~ 128 인가?
1byte가 표현 가능한 상태의 수는 256개이다. 이 때 첫 비트는 + or - 의 상태를 나타내기 때문이다.
즉 Signed 자료형이기 때문이다. 아래 자료를 살펴보자.
0번 bit | 1번 bit | 2번 bit | 3번 bit | 4번 bit | 5번 bit | 6번 bit | 7번 bit | 결과 |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 |
0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 2 |
0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 127 |
즉 0번 bit 가 0인 경우가 양수, 1인 경우가 음수를 표현하게 된다.
그럼 이제 다음 자료를 살펴보자.
0번 bit | 1번 bit | 2번 bit | 3번 bit | 4번 bit | 5번 bit | 6번 bit | 7번 bit | 결과 |
1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | |
1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | |
1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
이 자료는 틀린 자료이다. 0번 bit로 인해 -가 붙는것은 맞다. 하지만 음수의 bit는 양수와 반대로 표현된다.
이것을 이해하기 위해 보수의 개념을 알아야 한다.
컴퓨터의 연산에 주로 사용되는 보수는 1의 보수(Ones' Complement), 2의 보수(Two's Complement) 이다.
보수는 보충해주는 수 라는 뜻으로, 컴퓨터에는 -의 개념이 없기 때문에 이런 방식을 사용한다.
1의 보수부터 살펴보자.
1의 보수는 영어로 "ones' complement"인데, 이를 직역하면 "1들의 보수"가 된다(소유격을 나타내는 ' 기호가 s뒤에 있음에 유의). 즉, 1의 보수를 다르게 표현하자면 "여러 개의 1들로만 이루어진 수(111....)에 대한보수"라고 할 수 있다.
(출처 : 위키백과)
1의 보수를 설명하기 전 왜 1의 보수를 사용하여 연산하는지를 먼저 설명하고자, 기초 논리 게이트에 대해
서술하려 한다. 컴퓨터는 논리 게이트들의 덩어리와 같다. 기초 논리 게이트는 다음과 같다.
결과는 (X, Y) Result로 표현하겠다.
AND | InputY (0) | InputY (1) | OR | InputY (0) | InputY(1) | NOT | |||
InputX (0) | (0, 0) 0 | (0, 1) 0 | InputX (0) | (0, 0) 0 | (0, 1) 1 | InputX (0) | (0) 1 | ||
InputX (1) | (1, 0) 0 | (1, 1) 1 | InputX (1) | (1, 0) 1 | (1, 1) 0 | InputX (1) | (1) 0 |
이런 기초 논리 게이트들을 조합하여 XOR, NAND, NOR를 만들 수 있다. 연산자 파트에서 다루도록 하겠다.
1의 보수를 만들때 크게 두가지의 방법이 있는데, 가장 간단한 반전시켜 얻는 방법을 알아보자.
말 그대로 모든 비트를 반전시켜주면 된다. 즉 모든 비트를 NOT게이트를 사용하여 처리해주면 된다.
15에 대한 1의보수 |
0번 bit | 1번 bit | 2번 bit | 3번 bit | 4번 bit | 5번 bit | 6번 bit | 7번 bit |
피연산자 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 |
결과 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 |
피연산자 : 15
결 과 : -15
이렇게 음수와 양수를 반전시킬 수 있다.
이렇게 1의보수를 만드는 방법과, 양수 음수의 반전을 알아봤다.
그럼 다시 돌아가서
0번 bit | 1번 bit | 2번 bit | 3번 bit | 4번 bit | 5번 bit | 6번 bit | 7번 bit | 결과 |
1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | |
1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | |
1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
의 결과가 틀렸다 얘기했는데, 바른값으로 고치면 다음과 같다.
0번 bit | 1번 bit | 2번 bit | 3번 bit | 4번 bit | 5번 bit | 6번 bit | 7번 bit | 결과 |
1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | -127 |
1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | -126 |
1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | -1 |
그래도 이상한 결과가 보인다.
1111 1111은 0000 0000을 1의 보수한 결과인데, 위의 내용으로는 1의 보수는 음수와 양수의 반전인데,
절대값이 바뀌어 버린다.
마찬가지로 0111 1111 역시 1의 보수한 결과는 -0이 나오게 된다.
프로그래밍에서 -0, +0 즉 0이 두개라는 것은 엄청난 에러를 불러오게 된다. 그래서 우리는 음수 양수를 반전할 때
2의 보수를 사용해야한다
2의 보수는 1의 보수 한 결과에 +1 해주면 2의 보수이다.
그럼 byte 기준으로 2의 보수하는 과정을 알아보자.
0번 bit | 1번 bit | 2번 bit | 3번 bit | 4번 bit | 5번 bit | 6번 bit | 7번 bit | |
피연산자 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
결과 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
피연산자 2 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 |
결과 2 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 1 |
0에 1의 보수를 실행하면 1111 1111 이 나온다고 했다. 이제 여기에 1을 더하면 2의 보수라고 얘기를 했다.
그런데 1을 더하면, 0001 0000 0000 이 나오는게 아닌가 하고 생각할 수 있다.
이것은 carry의 개념인데, 자릿수를 초과하는, 즉 "0001" 0000 0000 부분은 carry가 되어 사라지게 된다.
그로 인해 0의 보수는 0이 된 것이고, 0은 양수에 속하게 되었다.
기존의 -0 인 1000 0000 은 -128을 표현하는 수가 되었다.
따라서 양수의 범위는 '0 ~ 127'이 되었고, 음수의 범위는 '-1 ~ -128'이 되었다.
추가로 위에서는 signed 만을 다뤘는데, unsigned는 부호를 나타내는 0번 비트를
부호로 사용할지, 값으로 사용할지 선택한다. 즉 0 ~ 255의 값을 나타낼 수 있다.
3. 프로그래밍의 꽃 Java 제어문 Part 2 (반복문) (0) | 2020.02.19 |
---|---|
3. 프로그래밍의 꽃 Java 제어문 Part 1 (조건문) (0) | 2020.02.19 |
2. 자료형 보다 기본! Java의 연산자 (0) | 2020.02.19 |
1. 프로그래밍의 시작 Java의 자료형 (기본형, 참조형) (0) | 2020.02.19 |
0. Java Tutorals의 시작에 앞서 (0) | 2020.02.19 |