2022.02.25 - [Language/Java] - [Java] 변수(Variable)
2022.02.25 - [Language/Java] - [Java] 기본형(Primitive type) & 상수와 리터럴(constant & literal)
논리형(boolean)
논리형엔 자료형이 'boolean' 한가지 밖에 없다.
boolean형 변수에는 true, false 값만 저장 가능하고, 기본값(default)는 false이다.
boolean형은 대답과 스위치 등의 논리구현에 주로 사용된다.
그렇기때문에 true,false 2가지의 값으로 표현하면 되므로 1bit만으로 충분하지만,
자바에서 데이터를 다루는 최소 단위는 byte(8bit)이기에,
boolean 크기는 1byte이다.
boolean power = true;
boolean checked = false;
boolean[] powers = new boolean[4]; // 내부적으로 false값을 4개 가진 배열로 초기화되어있음.
문자형(char)
Char
문자형 역시 'char' 자료형밖에 없다.
char 타입의 크기는 2byte이다.(2^16 = 65536개의 코드를 사용 가능)
char는 단 하나의 문자만 저장할 수 있다.
char ch = 'A';
위의 문장은 변수에 '문자'가 저장되는 것 같지만, 사실은 문자가 아닌 '문자의 유니코드(정수)'가 저장된다.
컴퓨터는 숫자밖에 모르기 때문에 모든 데이터를 숫자로 변환하여 저장한다.
'A'의 유니코드는 65, 변수 ch엔 65가 저장된다.
char ch = 'A';
char ch = 65;
// 동일한 값
// 어떤 문자의 유니코드를 알고 싶으면, 정수형으로 변환해서 가져오면 됨.
int code = (int)ch; // ch에 저장된 값을 int형으로 변환하여 가져옴
유니코드는 16진수로 되어있는데, 유니코드를 알면 아래와 같이 유니코드를 직접 사용도 가능하다.
char hch = '가'; // 문자로 집어넣기
CHAR hch = 44032; // 유니코드에 해당하는 숫자로 집어넣기(10진수)
char hch = '\uAC00'; // 유니코드로 집어넣기(16진수)
특수 문자의 경우 아래와 같은 문자 리터럴을 이용한다.
특수 문자 | 문자 리터럴 |
tab | \t |
backspace | \b |
form feed | \f |
new line | \n |
carriage return | \r |
역슬래쉬(\) | \\ |
작은따옴표 | \' |
큰따옴표 | \" |
유니코드(16진수)문자 | \u유니코드 |
인코딩과 디코딩(encoding & decoding)
위의 char에서 컴퓨터는 숫자밖에 모르기때문에 문자가 숫자로 저장된다고 했었는데,
변환되는 기준이 유니코드이다.
문자를 코드(숫자)로 변환하는 것이 문자 '인코딩(encoding)'
코드(숫자)를 문자로 변환하는 것이 문자 '디코딩(decoding)' 이다.
encode는 '~을 코드화하다' 또는 '~을 암호화하다' 라는 뜻이다.
어떻게 인코딩했는지를 알아야 디코딩이 가능하다.
아스키(ASCII)
아스키는 정보교환을 위한 미국 표준 코드란 뜻이다.
128개의 문자 집합을 제공하는 7bit 부호로,
위에서 변환한 'A' = 65라는 것도 자바에서 아스키코드를 그대로 참조한 UTF-16(유니코드)를 쓰기 때문이다.
아스키는 프로그래밍에서 유용하게 활용된다.
아스키코드
십진법 | 모양 |
32 | ␠ |
33 | ! |
34 | " |
35 | # |
36 | $ |
37 | % |
38 | & |
39 | ' |
40 | ( |
41 | ) |
42 | * |
43 | + |
44 | , |
45 | - |
46 | . |
47 | / |
48 | 0 |
49 | 1 |
50 | 2 |
51 | 3 |
52 | 4 |
53 | 5 |
54 | 6 |
55 | 7 |
56 | 8 |
57 | 9 |
58 | : |
59 | ; |
60 | < |
61 | = |
62 | > |
63 | ? |
64 | @ |
65 | A |
66 | B |
67 | C |
68 | D |
69 | E |
70 | F |
71 | G |
72 | H |
73 | I |
74 | J |
75 | K |
76 | L |
77 | M |
78 | N |
79 | O |
80 | P |
81 | Q |
82 | R |
83 | S |
84 | T |
85 | U |
86 | V |
87 | W |
88 | X |
89 | Y |
90 | Z |
91 | [ |
92 | \ |
93 | ] |
94 | ^ |
95 | _ |
96 | ` |
97 | a |
98 | b |
99 | c |
100 | d |
101 | e |
102 | f |
103 | g |
104 | h |
105 | i |
106 | j |
107 | k |
108 | l |
109 | m |
110 | n |
111 | o |
112 | p |
113 | q |
114 | r |
115 | s |
116 | t |
117 | u |
118 | v |
119 | w |
120 | x |
121 | y |
122 | z |
123 | { |
124 | | |
125 | } |
126 | ~ |
유니코드(Unicode)
인터넷이 발명되면서 서로 다른 문자 인코딩을 사용하는 컴퓨터간의 문서교환에 어려움을 겪게 되었다.
이러한 어려움을 해소하고자 전 세계의 모든 문자를 하나로 통일된 문자집합으로 표현하고자 노력하였고,
그 결과가 '유니코드'이다.
유니코드는 처음엔 모든 문자를 2byte(65536)로 표현하려 했으나, 부족해서 21bit(약 200만)로 확장되었다.
유니코드는 먼저 유니코드에 포함시키고자 하는 문자들의 집합을 정의하였는데,
이것이 문자 셋(character set)이라고 한다.
그리고 이 문자 셋에 번호를 붙인 것이 유니코드 인코딩이다.
유니코드 인코딩에는 UTF-8, UTF-16, UTF 32 등 여러종류가 있지만,
자바에서는 UTF-16을 쓴다.
UTF-16은 모든 문자를 2byte의 고정크기로 표현하고,
UTF-8은 하나의 문자를 1~4byte의 가변크기로 표현한다.
두 인코딩 모두 처음 128문자가 아스키와 동일하다.(아스키를 포함하고 있다는 뜻)
모든 문자의 크기가 동일한 UTF-16이 다루기는 편리하지만,
1byte로 표현할 수 있는 영어와 숫자가 2byte로 표현되므로 문서의 크기가 커진다는 단점이 있다.(한글은 3byte)
인터넷에선 전송속도가 중요하기때문에, 인코딩방식은 알맞은 것을 택해서 쓰면 된다.
정수형(byte, sort, int, long)
정수형의 표현형식 및 범위
정수형에는 모두 4개의 자료형이 있다.
byte(1) < short(2) < int(4) < long(8)
byte부터 long까지 2배씩 크기가 증가한다는 것을 일 수 있다.
이중에서 기본 자료형(default data type)은 int이다.
정수형의 표현방식은 아래와 같다.
S | n-1 bit |
s : 부호비트( 0: 양수, 1: 음수)
n : 타입의 크기(단위: bit)
관련 범위는 아래글 참조
2022.02.25 - [Language/Java] - [Java] 기본형(Primitive type) & 상수와 리터럴(constant & literal)
정수형의 선택기준
변수를 저장하려는 정수값의 범위에 따라 선택하면 되지만,
byte 나 short 보다 int를 사용하자.
byte나 short를 사용하면 메로리를 절약할 수 있겠지만, 연산 시에 범위를 넘어서 잘못된 결과를 얻기가 쉽다.
그리고 JVM의 피연산자 스택(operand stack)이 피연산자를 4byte단위로 저장하기 때문에,
그보다 작은 값을 계산할때 변환해서 연산이 수행된다. 그러므로 int를 쓰는게 더 효율적이다.
정수형의 오버플로우
만일 4bit의 2진수의 최대값 '1111'에 1을 더하면?
'1111' +
'0001'
--------
1'0000'
1'0000'이 나오지만, 4비트를 초과한 1은 저장할 공간이 없어서 버려진다.
이렇게 해당 타입이 표현할 수 있는 값의 범위를 넘어서는 것을 오버플로우(overflow)라고 한다.
오버플로우는 에러가 발생하는 것은 아니지만, 예상했던 결과를 얻지 못한다.
반대로 0000 에서 1을 감소시키면, 해당비트로 표현할 수 있는 최대값이 나온다.
'0000' -
'0001'
---------
'1111'
그래서 정수형 타입이 표현할 수 있는 최대값에 1을 더하면 최소값이 되고 , 최소값에서 1을 빼면 최대값이 된다.
최대값+1 -> 최소값
최소값 -1 -> 최대값
부호가 있는 정수의 오버플로우
부호있는 정수는 부호비트가 0에서 1이 될 때 오버플로우가 발생한다.
부호없는 10진수 | 2진수 | 부호있는 10진수 |
0 | 0000 | 0 |
1 | 0001 | 1 |
2 | 0010 | 2 |
3 | 0011 | 3 |
4 | 0100 | 4 |
5 | 0101 | 5 |
6 | 0110 | 6 |
7 | 0111 | 7 |
8 | 1000 | -8 |
9 | 1001 | -7 |
10 | 1010 | -6 |
11 | 1011 | -5 |
12 | 1100 | -4 |
13 | 1101 | -3 |
14 | 1110 | -2 |
15 | 1111 | -1 |
0 | 0000 | 0 |
1 | 0001 | 1 |
위 테이블에서 부호비트(맨앞의 비트)가 변경될시에 오버플로우가 발생하는것을 볼 수 있다.
부호없는 정수의 경우 표현범위가 '0~15'이므로 이 값이 계속 반복,
부호있는 정수의 경우 표현범위가 '-8~7'이므로 이 값이 무한히 반복된다.
실수형(float, double)
실수형의 자료형은 float과 double이 있다.
타입 | 저장 가능한 값의 범위(양수) | 정밀도 | bit크기 | byte크기 |
float | 1.4 x 10^-45 ~ 3.4 x 10^38 | 7자리 | 32 | 4 |
double | 4.9 x 10^-324 ~ 1.8 x 10^308 | 15자리 | 64 | 8 |
양의 부호만 적어둔 것으로 '-'부호를 붙이면 음의 범위가 된다.
float타입의 표현범위는 '-3.4 x 10^38 ~ 3.4 x 10^38'이지만,
'-1.4 x 10^-45 ~ 1.4 x 10^-45' 범위의 값은 표현할 수 없다.(0은제외)
무한한 실수를 비트로 다 표현할 수가 없기때문..
실수의 오버플로우와 언더플로우
실수형에선 변수의 값이 최대값을 벗어나면 '오버플로우'가 발생하는데
오버플로우가 발생하면 변수의 값은 '무한대(infinity)'가 된다.
그리고 실수에선 언더플로우도 존재하는데,
실수형으로 표현할 수 없는 아주 작은 값, 즉 양의 최소값보다 작은 값이 되는 경우를 뜻함.
이 때 변수의 값은 0이 된다.
실수형의 정밀도와 고정소수점, 부동소수점 참조
2022.02.27 - [Language/Java] - [Java] 실수형의 정밀도, 고정소수점과 부동소수점
참조
'Java의 정석' 책
'Language > Java' 카테고리의 다른 글
[Java] 연산자(Operator) (0) | 2022.02.28 |
---|---|
[Java] 형변환(casting) (0) | 2022.02.28 |
[Java] 실수형의 정밀도, 고정소수점과 부동소수점 (0) | 2022.02.27 |
[Java]음수의 2진 표현 - 2의 보수 (0) | 2022.02.27 |
[Java] 진법 / 진법 변환(n진수 변환) /실수 진법변환 (0) | 2022.02.25 |
댓글