4. 기본형(primitive type)
4.1 논리형 - boolean
- boolean형 변수 : true와 false 중 하나를 저장할 수 있으며 기본값(default)은 false
- boolean형 변수는 대답(yes/no), 스위치(on/off) 등의 논리구현에 주로 사용
- 1bit 만으로도 충분하지만 자바에서는 데이터를 다루는 최소단위가 byte이기 때문에 boolean의 크기가 1byte
1
2
|
boolean power = true; // power라는 boolean형 변수를 선언하고 true로 변수 초기화
boolean checked = False; //에러. 대소문자가 구분됨. true 또는 false만
|
cs |
> 자바에서는 대소문자가 구별되기 때문에 TRUE와 true는 다른 것으로 구별됨!
4.2 문자형 - char
- 문자를 저장하기 위한 변수를 선언할 때 사용됨
- char 타입의 변수는 단 하나의 문자만을 저장할 수 있음
1
|
char ch = 'A'; // 문자 'A'를 char타입의 변수 ch에 저장.
|
cs |
> 변수에 '문자'가 저장되는 것 같지만, 사실은 문자가 아닌 '문자의 유니코드(정수)'가 저장되는 것 : 변수 ch에는 65가 저장됨
- 문자 리터럴 대신 문자의 유니코드를 직접 저장하기 위해서는,
1
2
|
char ch = 'A'; // 문자 'A'를 char타입의 변수 ch에 저장
char ch = 65; // 문자의 코드를 직접 변수 ch에 저장
|
cs |
- 만일 어떤 문자의 유니코드를 알고 싶으면, char형 변수에 저장된 값을 정수형(int)으로 변환하면 됨 > 형변환
1
|
int code = (int)ch; // ch에 저장된 값을 int타입으로 변환하여 저장한다.
|
cs |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
public class CharToCode_ {
public static void main(String[] args) {
char ch = 'A'; // char ch = 65;
int code = (int)ch; // ch에 저장된 값을 int타입으로 변환하여 저장한다.
System.out.printf("%c=%d(%#X)%n", ch, code, code);
// 'A'의 유니코드 65(16진수로 0x41)
char hch = '가'; // char hch = 0xAC00;
System.out.printf("%c=%d(%#X)%n", hch, (int)hch, (int)hch);
// 문자 '가'의 유니코드는ㄴ 44032(16진수로 0xAC00)
}
}
|
cs |
A=65(0X41)
가=44032(0XAC00)
* 특수 문자 다루기
- 영문자 이외에 tab이나 backspace 등의 특수문자를 저장하는 방법
1
|
char tab = '\t'; // 변수 tab에 탭 문자를 저장
|
cs |
- tab = \t
- backspace = \b
- form feed = \f
- new line = \n
- carriage return = \r
- 역슬래쉬(₩) = \\
- 작은따옴표 = \'
- 큰따옴표 = \"
- 유니코드(16진수)문자 = \u유니코드 (예: char a='\u0041'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
public class SpecialCharEx_ {
public static void main(String[] args) {
System.out.println('\''); // '''처럼 할 수 없다.
System.out.println("abc\t123\b456"); // \b에 의해 t123이 지워진다.
System.out.println('\n'); // 개행(new line)문자 출력하고 개행
System.out.println("\"Hello\""); // 큰따옴표를 출력하려면 이렇게 한다.
System.out.println("c:\\");
}
}
|
cs |
* char타입의 표현형식
- char타입의 크기는 2byte(=16bit)임
- 1비트로 표현할 수 있는 정수의 개수 : 2^16개(65536개)
> short타입의 표현범위 : -2^15 ~ 2^15-1 (-32768~32767)
> char타입의 표현범위 : 0 ~ 2^16-1 (0~65536)
1
2
3
4
5
6
|
char ch = 'A'; // har ch = 65;
short s = 65;
System.out.println(ch); // A가 출력
System.out.println(s); // 65가
|
cs |
> println()은 변수 타입이 정수형이면 변수에 저장된 값을 10진수로 해석하여 출력하고,
문자형이면 저장된 숫자에 해당하는 유니코드 문자를 출력함
> 따라서, 값의 타입까지 알아야 올바르게 해석할 수 있음
* 인코딩과 디코딩
- 문자 인코딩(encoding) : 문자를 코드로 변환하는 것
- 문자 디코딩(decoding) : 코드를 문자로 변환하는 것
> 문자를 저장할 때는 인코딩을 해서 숫자로 변환해서 저장,
저장된 문자를 읽어올 때는 디코딩으로 숫자를 원래의 문자로 되돌림
* 아스키(ASCII)
- ASCII : 정보교환을 위한 미국 표준 코드
- 128개의 문자 집합을 제공하는 7bit 부호로 숫자 '0~9', 영문자 'A~Z'와 'a~z'가 연속적으로 배치됨 > 프로그래밍에서 활용
* 확장 아스키(ASCII)와 한글
- 확장 아스키 : 아스키의 남는 1bit를 활용하여 문자를 추가로 정의한 것
- 한글 윈도우에서 작성된 문서는 확장 완성형(CP 949)를 기본으로 사용하여 인코딩되어 저장됨
* 코드 페이지(code page, cp)
- 확장 아스키의 256개 문자를 어떤 숫자로 변환할 것인지를 적어놓은 '문자 코드표'
* 유니코드(Unicode)
- 전 세계의 모든 문자를 하나의 통일된 문자집합으로 표현한 것
- 모든 문자의 크기가 동일한 UTF-16이 문자를 다루기는 편리하지만 문서의 크기가 커지기 때문에,
UTF-8인코딩으로 작성된 웹문서의 수가 빠르게 늘고 있다.
4.3 정수형 - byte, short, int, long
- byte(1byte) < short(2byte) < int(4bye) < long(8byte)
* 정수형의 표현형식과 범위
- n비트로 표현할 수 있는 정수의 개수 : 2^n개(=2^n-1개 + 2^n-1개)
- n비트로 표현할 수 있는 부호있는 정수의 범위 : -2^n-1 ~ 2^n-1 -1
> 8비트로 표현할 수 있는 정수의 개수 : 2^8개(=2^7개 + 2^7개)
> 8비트로 표현할 수 있는 부호있는 정수의 범위 : -2^7 ~ 2^7 -1(-128~127)
종류/크기 | 1byte(=8bit) | 2byte(=16bit) | 4byte(=32bit) | 8byte(=64bit) |
정수형 | byte (-128~127) |
short (O:-32768~32767) (X:0~65535) |
int (-20억~20억) |
long (-800경~800경) |
* 정수형의 선택기준
>> 정수형 변수를 선언할 때는 int타입으로, int의 범위(약 +-20억)를 넘어서는 수를 다룰 때는 long을 사용
* 정수형의 오버플로우
- 오버플로우(overflow): 해당 타입이 표현할 수 있는 값의 범위를 넘어서는 것
> 에러가 발생하진 않지만, 예상치 못한 결과를 얻게 됨으로 애초에 충분한 크기의 타입을 선택해서 사용해야 함
- 마치 계수기를 거꾸로 돌리는 것처럼, '0000'에서 정방향으로 돌리면 '0001'이 되지만 역방향으로 돌리면 '9999'가 됨
- 정수형 타입이 표현할 수 있는 최대값에 1을 더하면 최소값이 되고, 최소값에서 11을 빼면 최대값이 됨
> 최대값 +1 → 최소값
> 최소값 -1 → 최대값
* 부호있는 정수의 오버플로우
- 부호없는 정수와 부호있는 정수는 최대값과 최소값이 다르기 때문에 오버플로우가 발생하는 시점이 다름
> 부호없는 정수는 2진수로 '0000'이 될 때 오버플로우가 발생하고,
> 부호있는 정수는 부호비트가 0에서 1이 될 때 오버플로우가 발생함
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
public class OverflowEx {
public static void main(String[] args) {
short sMin = -32768; // sMin : 최소값
short sMax = 32767; // sMax : 최대값
char cMin = 0;
char cMax = 65535;
System.out.println("sMin= " + sMin);
System.out.println("sMin-1= " + (short)(sMin-1)); // 최소값-1 = 최대값
System.out.println("Max= " + sMax);
System.out.println("Max+1= " + (short)(sMax+1)); // 최대값+1 = 최소값
System.out.println("cMin= " + (int)cMin);
System.out.println("cMin+1= " + (int)--cMin); // 최소값-1 = 최대값
System.out.println("Max= " + (int)cMax);
System.out.println("Max+1= " + (int)++cMax); // 최대값+1 = 최소값
}
}
|
cs |
sMin= -32768
sMin-1= 32767
Max= 32767
Max+1= -32768
cMin= 0
cMin+1= 65535
Max= 65535
Max+1= 0
> short smax의 Max를 MAX로 입력해서 아래에 Max들이 다 오류로 뜨는 거였음..
4.4 실수형 - float, double
*실수형의 범위와 정밀도
- float(32bit, 4byte) : 1.4x10^-45 ~ 3.4x10^38 > 정밀도 7자리
- double(64bit, 8byte) : 4.9x10^-324 ~ 1.8x10^308 > 정밀도 15자리
> 얼마나 0에 가깝게 표현할 수 있는가가 중요
Q. 실수형도 정수형처럼 오버플로우가 발생할까?
- 실수형에서는 오버플로우가 발생하면 변수의 값은 '무한대'가 됨
- 정수형에는 없는 '언더플로우'가 존재하는데, 실수형으로 표현할 수 없는 최소값보다 작은 값임 > 변수의 값은 0이 됨
- 실수형에서는 표현할 수 있는 값의 범위 뿐만 아니라 '정밀도(precision)'도 중요함
> 정수형과 달리 실수형은 오차가 발생할 수 있기 때문
- 실수형 값을 저장할 때, '보다 높은 정밀도'를 위해 float타입이 아닌 double타입의 변수를 사용
> 7자리 이상의 정밀도가 필요하다면, 변수의 타입을 double로 해야 함
> float은 연산속도의 향상이나 메모리 절약을 위해 선택
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
public class FloatEx1_ {
public static void main(String[] args) {
float f = 9.12345678901234567890f;
float f2 = 1.2345678901234567890f;
double d = 9.12345678901234567890d;
System.out.printf(" 123456789012345678901234%n");
System.out.printf("f : %f%n", f); // %f : 실수형 값 출력, 소수점 이하 6째자리까지 출력
System.out.printf("f : %24.20f%n", f); // %24.20f : 전체 24자리 중 20자리는 소수점 이하의 수 출력
System.out.printf("f2 : %24.20f%n", f2);
System.out.printf("d : %24.20f%n", d);
}
}
|
cs |
123456789012345678901234
f : 9.123457
f : 9.12345695495605500000
f2 : 1.23456788063049320000
d : 9.12345678901234600000
* 실수형의 저장형식
- 실수형은 값을 부동소수점수(floating-point)의 형태로 저장함
- 부동소수점수 : 부호(Sign), 지수(Exponent), 가수(Mantissa) > 세 부분으로 이루어짐
- 실수 표현형식의 구성요소
① S - 부호(Sign bit) : 0이면 양수, 1이면 음수
② E - 지수(Exponent) : 부호있는 정수. 지수의 범위는 -127~128(float), -1023~1024(double)
③ M - 가수(Mantissa) : 실제값을 저장하는 부분. 10진수로 7자리(float), 15자리(double)의 정밀도로 저장 가능
* 부동소수점의 오차
- 2진수로 변환된 실수를 저장할 때, 정규화 과정을 통해 1.XXX x 2^n 형태로 변환함
> 정규화된 2진 실수는 항상 '1.'으로 시작하기 때문에, '1.'을 제외한 23자리의 2진수가 가수로 저장되고 그 이후는 잘림
> 이 때 잘려나간 값들에 의해 발생할 수 있는 최대 오차는 가수의 마지막 비트의 단위와 같음
1
2
3
4
5
6
7
8
9
10
11
12
13
|
public class FloatToBinEx {
public static void main(String[] args) {
float f = 9.1234567f;
int i = Float.floatToIntBits(f);
System.out.printf("%f%n", f);
System.out.printf("%X%n", i); // 16진수로 출력
} //main의 끝
}
|
cs |
9.123457
4111F9AE // 4111F9AD의 2진수 마지막 자리 두 자리의 값이 '01'에서 '10'으로 1증가
'Java' 카테고리의 다른 글
[자바의 정석] #CH.3 연산자 operator - 3.1 연산자와 피연산자 / 3.2 단항 연산자 (0) | 2023.02.01 |
---|---|
[자바의 정석] #CH.2 변수 Variable - 2.5 형변환 (0) | 2023.01.18 |
[자바의 정석] #CH.2 변수 Variable - 2.3 진법 (0) | 2023.01.17 |
[자바의 정석] #CH.2 변수 Variable - 2.2 변수의 타입 (0) | 2023.01.16 |
[자바의 정석] #CH.2 변수 Variable - 2.1 변수와 상수 (0) | 2023.01.12 |