정리 노트/쌍용 KDT_(자바 Spring)

23.01.30(월): 음의 2진수, 실수/정수 자료형, 가비지 컬렉터 , 자동 형 변환

우주바다 2023. 2. 7. 19:42
728x90

 오늘 수업 내용


01. 음의 정수 표현 ( 2진수 > 10진수) 
02. 실수 자료형 (정밀도, 접미사)  
03. 정수 자료형과 32비트 기반 연산 + CPU
04. 가비지 컬렉터 
05. 접미사와 형변환
06. 자동 형변환 규칙 



01. 음의 정수 표현 

더보기

* byte : 8개의 비트 (  128 64 32 16 8 4 2 1  )
* 부호비트에 주목(0이면 양수, 1이면 음수)

① -10 을 byte 기반 비트열로 나타낸다.

10 =  00001010                  // (8 + 2)
비트전환 -> 11110101  
더하기 1 -> 정답: 11110110  
----------------------------------------------------------
② -27 을 byte 기반 비트열로 나타낸다.
27 = 00011011                  // (16 + 8 + 2 + 1 )     
비트전환 -> 11100100  
더하기 1 -> 정답 :  11100101
----------------------------------------------------------
③ -31 을 byte 기반 비트열로 나타낸다.
31 =  00011111                   // (16 + 8 + 4 + 2 + 1 ) 
비트전환 -> 11100000
더하기 1 -> 정답: 11100001
----------------------------------------------------------
④ -13 을 byte 기반 비트열로 나타낸다.
13 = 00001101  // (8 + 4 + 1 )
비트전환 -> 11110010
더하기 1 -> 정답: 11110011
-----------------------------------------------------------
음의 2진수를 10진수로 나타내기
1. 1을 빼고, 비트열 반전 (양수로 변환) 한 값을 음수로 바꾸기 (음 > 양 역순 실행) 
2. ㄱㅂ님 방법 : 부호비트 제외, 0의 자리를 더하고 +1하고 음수로 바꾸기.
3. 비트 반전 후 1을 더하고 음수로 바꾸기 (양 > 음 방향도 가능) 
-----------------------------------------------------------
⑤ byte 기반의 11001010 을 10진수 정수형으로 나타낸다.
1. 11001001 => 00110110 => -(32 + 16 + 4 + 2) = -54
2. -((32 + 16 + 4  + 1) + 1) = -54
-----------------------------------------------------------
⑥ byte 기반의 11110101 을 10진수 정수형으로 나타낸다.
1. 11110100 => 00001011 => -(8 + 2 + 1) = -11
2. -((8+2)+1) =  -11
-----------------------------------------------------------
⑦ byte 기반의 10000001 을 10진수 정수형으로 나타낸다.
1. 10000000 => 011111111 => -127 
2. -((64 + 32 + 16 + 8 + 4 + 2 ) + 1 = -127
-----------------------------------------------------------
⑧ byte 기반의 10101010 을 10진수 정수형으로 나타낸다.
1. 10101001 = > 01010110 => -(64 + 16 + 4 + 2 ) =  -88
2. -((64 + 16 + 4 + 1) +1) =  -88
-----------------------------------------------------------
⑨ byte 기반의 10000101 을 10진수 정수형으로 나타낸다.
1. 10000100 => 01111011 => -(64 + 32 + 16 + 8 + 2 + 1) = -123
2. -((64 + 32 + 16 + 8 + 2) + 1) = -123
-----------------------------------------------------------
⑩ byte 기반의 11111111 을 10진수 정수형으로 나타낸다.
1. 11111110 => 00000001 => -1
2. -((0)+1) => -1 


02. 실수 자료형

완전한 표현이 불가능.
정수처럼 사이값이 고정되지 않아 , 무한대 값을 가지므로 다른 표현 방식을 사용.
어차피 0을 기준으로 양,음수 모든 영역이 무한대.
따라서 정밀도를 타협하고 표현 범위를 늘리기로 약속. 
(ex. 1.1234...어딘가의 값 요청  ->  1.1 반환) 

실수의 디폴트타입 double, 정밀도 
언어마다 다르지만, 자바는 double이 default type.
int 형이 디폴트인 논리를 따르면 float일 것 같은데 왜 double일까?
더블이 더 정밀도가 높기 때문.

이론적으로는 float는 소수점 6번째, double은 12번째까지 보장받는다고 한다.
하지만 실사용할 때는 작은 오차가 반복될 수록 커지기 때문에
생각만큼 충분하지 않을 수 있다 . ( 6자리면 충분하다 생각했던 변수가
 값이 바뀌면서 오차가 점점 커질 수 있음)

 실수의 접미사
long a = 10000000000; //(백억)  에러  
자바는 대입연산자가 있을 때 무조건 우항 값부터 본다.
정수 백억의 자리를 int만큼 먼저 만들고 담으려고 해서 오버플로우 발생.
따라서 long a = 10000000000L;  로 선언 및 초기화 해야 한다.

명시적 형변환(강제 캐스팅)도 이런 이유로 가능하다.
ex) double 의 값이 3.14일때 float로 강제 형변환 하면

더 작은 그릇에 맞게 데이터를 구겨서 넣어준다.


03. int 자료형과 32비트 연산 

 

값을 담을 때,작은 값이어도 보통 int를 사용하는 이유?
연산속도가 빨라서. 그럼 왜 빠를까?

 

자바는 32비트 기반으로 연산하는 언어다.
컴퓨터는 기본적으로 32비트 기반으로 연산해왔고

현재는 64비트가 생겼지만, 자바가 생겼을 때는 없었다.

따라서 byte a =2 , byte b = 3 일 때, a+b를 하면
32 비트 기반으로 바꿔서 계산하게 된다.
00000010 + 00000011 이 아니라
00000000 000000000 00000000 00000010  + 
00000000 000000000 00000000 00000011  이렇게 계산.

int를 사용하면 이런 변환 과정이 필요 없기 때문에 빠르다.

또한 메모리도 덜 차지한다.
(변환하게 되면 원래 값과 변환값까지 담아야하므로 메모리 차지.)


결론: 대부분 int 사용, 21억이 넘을 것 같은 큰 수면 long 사용.

그럼 byte 랑 short는 언제 쓰나?
: 빠른 연산이 필요하지 않을 때. 데이터의 성격이 강할 때 (저장) 
: 속도보다 데이터 크기가 중요한 상황( mp3파일, 동영상 파일)

 

 CPU 의 특징 

cpu는 여러 작업을 각각 짧게 끊어서 빠르게 반복하도록 설계되었다.

(동시 진행처럼 보이지만 아니다! 컴퓨터는 무조건 하나의 작업만 수행.)

따라서 비용을 들여 기능을 늘리는 방식으로는 개발하지 않음.(과거 논의는 있었으나)
무조건 단일 기능을 최대한 빠르게 처리하게 함(가장 효율적인 방식)

cpu는 int형 데이터의 크기만 연산 가능(32비트) , 따라서 int가 아니라면
연산 직전에 자동변환. 이를 생략하기 위해 int를 사용한다.

 

참고) 64비트 기반 프로그램은 Program Files 에, 

32비트는 Program Files(x86)  에 설치 됨

 


04. 가비지컬렉터 

자바는 메모리에 직접 접근하는 것을 허용하지 않는다.
알아서 자리를 쓰고 청소한다. (내가 알아서 할게!)
참고: 컬렉터는 사용했던 메모리 외 나머지공간(전체영역)도 순회한다. 

(돌아다니면서 청소.) 가비지 컬렉션은 메모리 초기화, 메모리 회수 라고도 부른다.

상수와 가비지 컬렉션 

상수: 변하지 않으며, 변수처럼 담는 개념이 아님. 10은 그냥 10.

int num = 1 + 5;  // (상수 + 상수)
// 1, 5, 1+5, num.  
// 순서대로 총 4개 공간 할당(메모리에 저장)

 

이름(변수)이 없으니 재접근, 값 수정이 불가능하다.
상수도 변수처럼 메모리에 저장되지만, 주소를 저장할 필요가 없기 때문에
사용이 끝나면 소멸한다.(좀 더 정확하게는 가비지 컬렉터가 지나간 후 소멸.
이미 다른데 지우고있으면 대기하므로 엄밀히는 바로 소멸은 아님. 

마찬가지로 하드디스크에 있는 데이터는 삭제한다고 바로 없어지지 않음. 
포인터만 끊어질 뿐, 다른 데이터로 씌워지기 전까지는 남아있다.
그래서  usb복구가 가능한 것.(날아간 후 손 대지 말고
바로 복구해야하는 이유. 새로 뭔가 설치하면 그 메모리 영역 침범 가능성!

번외) char, String:

- 싱글 쿼테이션, 더블 쿼테이션.

-  아스키코드 (int), 2진수 실제 값

char  = '7' //  아스키코드 55 (int)
	 // == 00000000 00110111 (2)

String = "A"  // 아스키코드 65 (int)

새로 알게 된 것.

음의 정수는 자바의 정석으로 읽어서 이론은 알고 있었는데, 

직접 변환해보니 생각보다 헷갈렸다. 변환하는 방법이 여러 가지라서

다른 분들 방식으로도 시도하면서 비교했고

0과 1의 개수에 따라 더 연산이 빠른 방식이 있었다.

 

정수와 실수의 디폴트 타입이 int와  double인 이유를 정확히는 몰랐는데

자세히 알게 되어서 좋았다.  변수를 오른쪽 값부터 처리하고

메모리 할당도 우측부터 이뤄진다는 점도 재밌었다.

 

가비지 컬렉터는 알고 있었지만, 메모리 청소가 바로 이뤄지지 않고

포인터만 끊어지는 건 몰랐다. 여러번 usb 데이터를 날려먹어서 복구할 때,

한참 전에 지웠던 데이터들이 남아 있는 게신기했는데 이유를 알게 되어 너무 좋았다!

728x90
반응형