Java - 형변환 및 사칙연산

2020. 6. 13. 15:46Java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
 
public class Ex {
 
    public static void main(String[] args) {
        /*
         * 정수형 데이터타입 표현 범위
         * byte : 1Byte(= 8bit) = 2^8 = 256가지 = -128 ~ 127 표현 가능
         * short : 2Byte(= 16bit) = 2^16 = 65536가지 = -32768 ~ 32767 표현 가능
         * int : 4Byte(= 32bit) = -21억 ~ 21억
         * long : 8Byte(= 64bit) = -922경 ~ 922경
         * 
         * 실수형 데이터타입 표현 범위
         * float : 4Byte = 소수점 38자리 정도
         * double : 8Byte = 소수점 308자리 정도
         * 
         * 
         * < 자바에서의 데이터 형변환(Type casting) >
         * - 하나의 데이터타입이 다른 데이터타입으로 변환되는 것
         * 
         * 1. 묵시적(암시적) 형변환 = 자동 형변환
         *    - 작은 데이터타입의 데이터를 큰 데이터타입으로 변환하는 것
         *    - 자바 컴파일러에 의해 자동으로 형변환이 일어남
         *    - 아무런 문제가 발생하지 않으므로, 개발자가 신경쓸 것이 없음
         * 
         * 2. 명시적 형변환 = 강제 형변환
         *    - 큰 데이터타입의 데이터를 작은 데이터타입으로 변환하는 것
         *      => 작은 데이터타입의 표현 범위보다 크므로 Overflow(넘침)가 발생할 수 있다
         *    - Overflow 가 발생할 우려 때문에 자동 형변환이 일어나지 않음
         *      => 코드 상에 오류가 발생하여 실행되지 않음
         *    - 반드시 형변환 연산자를 사용하여 작은 데이터타입으로의 강제 형변환을 수행해야함
         *      => 우변(큰데이터타입)의 앞쪽에 '(작은데이터타입이름)' 형태로 명시해야함
         *    - 명시적 형변환 후에는 Overflow 에 의해 원본 데이터와 다른 데이터가 저장될 수 있음!
         *      => 따라서, 명시적 형변환은 변환 후의 책임을 개발자에게 맡김
         *      
         * ※ 참고! 실수형(float, double)은 데이터 표현 방식 차이에 의해
         *    정수형보다 무조건 큰 타입으로 취급됨
         *    (ex. long 타입보다 float 타입이 메모리 크기는 작지만, 표현 범위는 더 크다) 
         */ 
        
        int a1 = 32768// 큰 데이터타입
        short a2 = 32767// 작은 데이터타입
        
        int b1 = 32768// 큰 데이터타입
        short b2 = 32767// 작은 데이터타입
        
        System.out.println("a1(int) : " + a1 + ", a2(short) : " + a2);
        
        // 묵시적(암시적) 형변환. 작은 데이터타입 데이터를 큰 데이터타입으로 이동(형변환)
        a1 = a2; // 작은 데이터타입 변수 a2 의 데이터를 큰 데이터타입 변수 a1 으로 전달
        // => 이 때, 작은 타입 -> 큰 타입으로 묵시적 형변환이 자동으로 일어남
        //    묵시적 형변환이 일어나더라도 원본 데이터에는 아무런 영향이 없음!
        System.out.println("묵시적 형변환 후 a1(int) : " + a1 + ", a2(short) : " + a2);
        
        System.out.println("----------------------------------------");
        System.out.println("b1(int) : " + b1 + ", b2(short) : " + b2);
        
        // 명시적 형변환. 큰 데이터타입 데이터를 작은 데이터타입으로 이동
//        b2 = b1; // 큰 데이터타입 변수 b1 의 데이터를 작은 데이터타입 변수 b2 로 전달
        // => 이 때, 큰 타입 -> 작은 타입으로 형변환이 자동으로 일어나지 않음 = 오류 발생
        //    Overflow 의 위험성 때문에 자바가 자동으로 변환해주지 못함 => 강제 형변환 필요
        b2 = (short)b1; // 우변 데이터 앞쪽에 () 기호를 쓰고 사이에 좌변의 타입을 명시함
        // => 명시적 형변환 후에는 Overflow 에 의해 원본 데이터와 다른 데이터가 저장될 수 있음!
        
        System.out.println("명시적 형변환 후 b1(int) : " + b1 + ", b2(short) : " + b2);
        
        System.out.println("----------------------------------------");
        
        // 강제 형변환 시, 원본 데이터가 손상되지 않는 경우
        // => 큰 데이터타입 데이터가 작은 데이터타입에서 충분히 표현 가능한 경우
        //    명시적 형변환이 필요하지만, 변환 후에도 원본 데이터가 유지됨
        
        int c1 = 100// 큰 데이터타입
        short c2 = 32767// 작은 데이터타입
        
        System.out.println("c1(int) : " + c1 + ", c2(short) : " + c2);
        
//        c2 = c1; // 자동 형변환 X => 강제 형변환 필요
        c2 = (short) c1; // int -> short 타입으로 강제 형변환 수행
        
        System.out.println("명시적 형변환 후 c1(int) : " + c1 + ", c2(short) : " + c2);
        
        System.out.println("==============================================");
        
        /*
         * char 타입과 byte & short 타입 간의 관계
         * - byte(1Byte) : -128 ~ 127
         * - short(2Byte) : -32768 ~ 32767
         * - char(2Byte) : 0 ~ 65535
         * - char 타입의 경우 문자 표현을 위해 양수로만 표현하므로
         *   byte 타입과 short 타입 보다 양수 표현 범위가 크다.
         *   또한, byte 타입과 short 타입은 음수 표현이 가능하다.
         *   => 따라서, char 타입과 byte 타입 & short 타입 간에는 반드시 명시적 형변환 필수!
         */
        
        byte b = 100;
        short s = 65;
        
        char ch;
        
//        ch = b; // 오류 발생! byte <-> char 명시적 형변환 필수!
        ch = (char)b;
        System.out.println(ch);
        
//        ch = s; // 오류 발생! short <-> char 명시적 형변환 필수!
        ch = (char)s;
        System.out.println(ch);
        
//        b = ch; // 오류 발생! byte <-> char 명시적 형변환 필수!
        b = (byte)ch;
        System.out.println(b);
        
//        s = ch; // 오류 발생! short <-> char 명시적 형변환 필수!
        s = (byte)ch;
        System.out.println(s);
        
        System.out.println("==============================================");
        
        // 정수형과 실수형의 관계
        // => 실수형이 정수형보다 무조건 큰 타입으로 취급되므로
        //    정수형 -> 실수형 변환은 자동 형변환, 실수형 -> 정수형 변환은 강제 형변환
        long l = 100L;
        
        // float = 4Byte, long = 8Byte 이지만, float 타입이 더 크므로 long -> float 자동 형변환
        float f = l; // 자동 형변환 가능
        System.out.println(f);
        
//        long l2 = f; // float -> long 자동 형변환 불가! 명시적 형변환 필수!
        long l2 = (long)f;
        System.out.println(l2);
        
    /*
         * 문자열의 덧셈
         * - 어떤 데이터타입이라도 문자열과 덧셈(+) 연산을 수행하게 되면
         *   무조건 문자열 결합이 일어나므로 새로운 문자열이 생성됨
         *   ex) int형정수 + 문자열 = 문자열
         */
        
        System.out.println(1 + 1); // 산술연산이므로 정수 + 정수 = 정수
        
        System.out.println(1 + "1"); // int + String = String  =>   1 + "1" = "11"
        System.out.println("1" + 1); // String + int = String  =>  "1" + 1  = "11"
        System.out.println("실수 " + 3.14); // "실수 " + 3.14 = "실수 3.14"
        
        
        // 변수를 문자열 결합에 활용할 수 있다.
        int num = 10;
        System.out.println("정수 num = " + num);
        
        
        // 2개 이상의 결합 시에는 연산 순서에 따라 다른 결과가 나타날 수 있다!
        System.out.println(1 + "1" + 1); // 1 + "1" = "11" + 1 = "111"
        
        System.out.println(1 + 1 + "1"); // 1 + 1 = 2 + "1" = "21"
 
 
    /*
         * 산술연산자(+, -, *, /, %)
         * - 일반적인 사칙연산(+, -, *, /)과 나머지 연산자(%)로 구성
         * - 나눗셈 연산자(/)는 두 피연산자 간의 나눗셈 결과 중 몫만 계산하고,
          *   나머지 연산자(%)는 두 피연산자 간의 나눗셈 결과 중 나머지만 계산함   
         */
        
        int a = 10, b = 3, c;
        
        c = a + b;
        System.out.println(a + " + " + b + " = " + c);
 
        c = a - b;
        System.out.println(a + " - " + b + " = " + c);
 
        c = a * b;
        System.out.println(a + " * " + b + " = " + c);
 
        c = a / b; // a 를 b 로 나눈 결과 중 몫(3)만 c 에 저장
        System.out.println(a + " / " + b + " = " + c);
 
        c = a % b; // a 를 b 로 나눈 결과 중 나머지(1)만 c 에 저장
        System.out.println(a + " % " + b + " = " + c);
 
 
    }
 
}
cs

데이터 타입의 형 변환과 사칙연산에 대해서 배우는 시간이었다. 형 변환 과정은 신기했고, 설명이나 책보다는 확실히 실습으로 바로바로 해보면서 배우니 나에겐 너무 잘 맞는 배움의 스타일이다. 배우는데 재미가 점점 더해지고 있다. 큰 타입에서 작은 타입으로 입력할 때 명시적으로 형 변환시켜주는 것, 큰 타입에 작은 타입을 입력할 때는 묵시적으로 자동형 변환이 된다는 것, % 연산자 기호는 나눗셈을 하고 나서의 나머지를 출력하는 연산자, 문자열의 덧셈 과정 등 간단한 것들이지만 이런 것들이 쌓여서 나중에 능숙하게 더 어려운 것들을 할 수 있게 되니 헷갈리지 않게 잘 기억해야겠다.