Coding(Java)/Java(이론)2021. 8. 20. 20:00
반응형

[Java] 6. 시프트, 관계, 이진논리, 일반논리, 3항, 대입연산자

 

 

여기서 다룰 연산자는 시프트연산자, 관계연산자, 이진논리연산자, 일반논리연산자, 3항연산자, 대입연산자이다. 

다음은 이 연산자들을 이용한 프로그램의 코드이다. 

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
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
package mymain;
 
public class Operation2 {
 
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        // 쉬프트연산자(이진연산자): >> << >>> <<<
        
        int n=10;        
        //오른쪽 쉬프트 : n/2^bit
        System.out.printf("n >> 0 : [%32s]\n", Integer.toBinaryString(n>>0));
        System.out.printf("n >> 2 : [%32s]\n", Integer.toBinaryString(n>>2));
 
        //왼쪽 쉬프트 : n*2^bit
        System.out.printf("n << 0 : [%32s]\n", Integer.toBinaryString(n<<0));
        System.out.printf("n << 2 : [%32s]\n", Integer.toBinaryString(n<<2));
        
        n=-1;
        System.out.printf("n >>  0 : [%32s]\n", Integer.toBinaryString(n>>0));
        // 앞에 발생된 빈 공간 4칸은 1(부호)로 채워진다
        System.out.printf("n >>  4 : [%32s]\n", Integer.toBinaryString(n>>4));
        // 앞에 발생된 빈 공간 4칸은 무조건 0으로 채워진다
        System.out.printf("n >>> 4 : [%32s]\n", Integer.toBinaryString(n>>>4));
        System.out.println();
        
        // 관계(비교)연산자:>, >=<, <=, ==(같은가?), !=(같지않은가?)
        //                  결과는 boolean (true of false)
        
        int a=3, b=3;
        System.out.printf("%d>%d => %b\n", a, b, a>b);
        System.out.printf("%d>=%d => %b\n", a, b, a>=b);
        
        System.out.printf("%d<%d => %b\n", a, b, a<b);
        System.out.printf("%d<=%d => %b\n", a, b, a<=b);
        
        System.out.printf("%d==%d => %b\n", a, b, a==b);
        System.out.printf("%d!=%d => %b\n", a, b, a!=b);
        
        
        //제어문
        if(a>b)
            System.out.printf("%d이/가 %d보다 크다\n", a, b);
        else
            System.out.printf("%d이/가 %d보다 크지 않다\n", a, b);
        System.out.println();
        
        //이진논리 연산자 : & ^ |
 
        int a0=7, b0=5;
        
        System.out.printf("%d=[%32s]\n", a0, Integer.toBinaryString(a0));
        System.out.printf("%d=[%32s]\n", b0, Integer.toBinaryString(b0));
        
        System.out.printf("&=[%32s]\n", Integer.toBinaryString(a0&b0));
        System.out.printf("|=[%32s]\n", Integer.toBinaryString(a0|b0));
        System.out.printf("^=[%32s]\n", Integer.toBinaryString(a0^b0));
        
        //실제로는 이렇게 안한다
        //16진수로 생년월일정보 기록
        int birthday=0x19990825;
        //                                          1    9    9    1    0    8    2    5
        //           0x19990825>>>16           : 0001 1001 1001 1001 0000 1000 0010 0101
        //           0x00001999(0825는 제거됨) 
        
        int year=birthday>>>16;
        
        int month=birthday>>>8&0x000000ff;
        //                                         1    9    9    1    0    8    2    5
        //           0x19990825>>>8           : 0001 1001 1001 1001 0000 1000 0010 0101
        //                                         0    0    1    9    9    9    0    8
        //           0x00199908(25는 제거됨)  : 0000 0000 0001 1001 1001 1000 0000 1000
        //       &   0x000000ff               : 0000 0000 0000 0000 0000 0000 1111 1111
        //           0x00000008               : 0000 0000 0000 0000 0000 0000 0000 1000
        
        int day=birthday&0x000000ff;
        //
        //                                         1    9    9    1    0    8    2    5
        //           0x19990825               : 0001 1001 1001 1001 0000 1000 0010 0101
        //       &   0x000000ff               : 0000 0000 0000 0000 0000 0000 1111 1111
        
        System.out.printf("년: %x(년)\n", year);
        System.out.printf("월: %02x(월)\n", month);
        System.out.printf("일: %02x(월)\n", day);
        
        // 월에 대한 부분만 수정: 08->12
        // birthday=0x19990825 => 0x19991225로 수정
        
        // 월 부분 지우기
        //birthday=birthday&0xffff00ff;
        //System.out.printf("%x\n", birthday);
        
        //^연산 이용해서 소거(제거)
        birthday=birthday^0x00000800;
        System.out.printf("%x\n", birthday);
        
        // birthday=0x19990825
        //         ^0x00000800
        //            19990025
        
        // 월 부분 12로 채우기
        birthday=birthday|0x00001200;
        System.out.printf("%x\n", birthday);
        System.out.println();
        
        //일반논리연산자: &&(and) ||(or)
        System.out.println("---[A && B]---");
        //                                          A      B
        System.out.printf("true  && true  => %b\n"true&&true);
        System.out.printf("true  && false => %b\n"true&&false);
        System.out.printf("false && true  => %b\n"false&&true);
        System.out.printf("false && false => %b\n\n"false&&false);
        
        System.out.println("---[A || B]---");
        //                                          A      B
        System.out.printf("true  || true  => %b\n"true||true);
        System.out.printf("true  || false => %b\n"true||false);
        System.out.printf("false || true  => %b\n"false||true);
        System.out.printf("false || false => %b\n\n"false||false);
        
        
        //사용 예
        int su=6
        if(su%2==0// 0 2 4 6 8 10 ...
            System.out.printf("[%d]은(는) 2의 배수이다.\n", su);
        else
            System.out.printf("[%d]은(는) 2의 배수가 아니다.\n", su);
        
        //su가 2와 3의 배수(6의 배수)인가?
        if((su%2==0)&&(su%3==0))
            System.out.printf("[%d]은(는) 2와 3의 배수이다.\n", su);
        else
            System.out.printf("[%d]은(는) 2와 3의 배수가 아니다.\n", su);
        
        // 윤년 구하기(1년이 366일(오차가 쌓여 1일 추가)이 되는 해)
        int year1=2000
        
        //윤년이 되는 조건
        //조건 1) 400년의 배수가 되는 해
        //조건 2) 4의 배수이면서, 100의 배수가 아닌 해
        
        //  조건 1(4배수)     조건2(100배수가 아닌 해)
        if((year1%400==0)||(year1%4==0 && year1%100!=0))
            System.out.printf("[%d]년도는 윤년\n", year1);    
        else
            System.out.printf("[%d]년도는 평년\n", year1);
        System.out.println();
        
        // 3항연산자: 연산에 참여하는 항이 3개
        // (조건)? 값1 : 값2;
        //         (참)  (거짓)
        
        //두 수중 큰 수 구하기
        int a1=10, b1=5, c1;
        
        //3항연산자가 if문 보다 처리속도가 빠르다.
        c1=(a1>b1)? a1:b1;
        
        System.out.printf(" %d, %d중 큰 수는 %d\n", a1, b1, c1);
        
        //if문 사용시
        if(a1>b1)
            c1=a1;
        else
            c1=b1;
        System.out.printf("[if] %d, %d중 큰 수는 %d\n", a1, b1, c1);
        
        //절댓값 구하기
        int n1=-100;
        int m1;
        
        m1=(n1<0)?-n1:n1;
        
        System.out.printf("|%d|=%d\n", n1, m1);
        System.out.println();
        
        // 대입연산자: =
        // 복합대입연산자: +=  -=  *=  /=  %=  >>=  <<=  &=  ^=  |=
        
        int n2=10//초기화: 변수 선언과 동시에 값을 넣는 경우
        n2=100;    //대입(치환)
        
        n2++;  // n2=n2+1 <=자신을 1씩 증가
        
        n2+=2;  //n2=n2+2; //<=자신을 2씩 증가
        System.out.println(n2);
        
        // logical error
        n2=+2;  //잘못사용한 예
        System.out.println(n);
        
        n2=10;
        n2-=5// n2=n2-5;
        n2*=2// n2=n2*2;
        n2/=3// n2=n2/3;
        n2%=2// n2=n2%2;
        
        n2=3+2-2+1-4;
        
        //단항연산자 순서
        boolean b3=!!!!!(3>2);
        n2=-(-(10));
        System.out.printf("b3=>%b\n",b3);
        System.out.printf("n2=%d\n", n2);        
 
    }
 
}
 
cs

 

1.시프트 연산자는 다음과 같이 3가지가 있다.

구분 연산자 의미
시프트 연산자 >> bit값을 오른쪽으로 이동(빈 자리는 부호값으로 대입)한다
<< bit값을 왼쪽으로 이동(빈 자리는 0으로 대입)한다.
>>> bit값을 오른쪽으로 이동(빈 자리는 0으로 대입)한다.

시프트 연산자 부분의 코드는 다음과 같고

        // 쉬프트연산자(이진연산자): >> << >>> <<<
        
        int n=10;        
        //오른쪽 쉬프트 : n/2^bit
        System.out.printf("n >> 0 : [%32s]\n", Integer.toBinaryString(n>>0));
        System.out.printf("n >> 2 : [%32s]\n", Integer.toBinaryString(n>>2));


        //왼쪽 쉬프트 : n*2^bit
        System.out.printf("n << 0 : [%32s]\n", Integer.toBinaryString(n<<0));
        System.out.printf("n << 2 : [%32s]\n", Integer.toBinaryString(n<<2));
        
        n=-1;
        System.out.printf("n >>  0 : [%32s]\n", Integer.toBinaryString(n>>0));
        // 앞에 발생된 빈 공간 4칸은 1(부호)로 채워진다
        System.out.printf("n >>  4 : [%32s]\n", Integer.toBinaryString(n>>4));
        // 앞에 발생된 빈 공간 4칸은 무조건 0으로 채워진다
        System.out.printf("n >>> 4 : [%32s]\n", Integer.toBinaryString(n>>>4));
        System.out.println();

위 코드의 실행결과는 다음과 같다.

n >> 0 : [                             1010]
n >> 2 : [                                10]
n << 0 : [                             1010]
n << 2 : [                          101000]
n >>  0 :  [11111111111111111111111111111111]
n >>  4 :  [11111111111111111111111111111111]
n >>> 4 : [      1111111111111111111111111111]

위의 첫 번째 줄에서 네 번째 줄은 n=10일 때이고, 나머지인 다섯 번째 줄에서 일곱 번째 줄은 n=-1일 때이다. 

n=10일 때 n>>2의 실행결과는 1010이 오른쪽으로 두 칸 이동해서 10만 출력되고, n<<2의 실행결과는 1010이 왼쪽으로 두 칸 이동해서 101000이 출력된다. 

n=-1일 때 n>>0의 실행결과는 그대로 1의 2의 보수형태이다. -1은 음수이므로 n>>4의 실행결과는 1의 2의 보수형태를 오른쪽으로 네 칸 이동하고, 그 빈 자리(4칸)에는 음의 부호를 뜻하는 1로 채워졌다. 또 n>>>4의 실행결과는 1의 2의 보수형태를 오른쪽으로 네 칸 이동하고, 그 빈 자리(4칸)은 0으로 채워졌다(표시되지 않음).

 

2. 관계연산자(비교연산자)는 변수/상수의 값을 비교할 때 사용되는 연산자이고 결과는 boolean형처럼 true 또는 false이다.

관계연산자에서 >는 크다, <는 작다, >=는 크거나 같다, ,<=는 작거나 같다, ==는 피연산자들의 값이 같다(=쓰면 안됨), !=는 피연산자들의 값이 같지 않다는 의미를 갖는다. 

 

관계연산자 부분의 코드는 다음과 같고,

        // 관계(비교)연산자:>, >=<, <=, ==(같은가?), !=(같지않은가?)
        //                  결과는 boolean (true of false)
        
        int a=3, b=3;
        System.out.printf("%d>%d => %b\n", a, b, a>b);
        System.out.printf("%d>=%d => %b\n", a, b, a>=b);
        
        System.out.printf("%d<%d => %b\n", a, b, a<b);
        System.out.printf("%d<=%d => %b\n", a, b, a<=b);
        
        System.out.printf("%d==%d => %b\n", a, b, a==b);
        System.out.printf("%d!=%d => %b\n", a, b, a!=b);
        
        
        //제어문
        if(a>b)
            System.out.printf("%d이/가 %d보다 크다\n", a, b);
        else
            System.out.printf("%d이/가 %d보다 크지 않다\n", a, b);
        System.out.println();

이 코드의 실행결과는 다음과 같다.

3>3 => false
3>=3 => true
3<3 => false
3<=3 => true
3==3 => true
3!=3 => false
3이/가 3보다 크지 않다

제어문에 있는 if는 조건에 따라 작성된 내용을 실행한다(다음에 자세하게 다루겠다).

 

3. 2진논리연산자는 다음과 같이 3가지가 있다.

구분 연산자 의미
2진논리연산자 & AND(둘 다 true이면 true 출력)
| OR(하나라도 true이면 true 출력)
^ XOR(배타적 OR, 서로 같으면 false, 다르면 true 출력)

2진논리연산자 부분의 코드는 다음과 같고,

        //이진논리 연산자 : & ^ |


        int a0=7, b0=5;
        
        System.out.printf("%d=[%32s]\n", a0, Integer.toBinaryString(a0));
        System.out.printf("%d=[%32s]\n", b0, Integer.toBinaryString(b0));
        
        System.out.printf("&=[%32s]\n", Integer.toBinaryString(a0&b0));
        System.out.printf("|=[%32s]\n", Integer.toBinaryString(a0|b0));
        System.out.printf("^=[%32s]\n", Integer.toBinaryString(a0^b0));
        
        //실제로는 이렇게 안한다
        //16진수로 생년월일정보 기록
        int birthday=0x19990825;
        //                                          1    9    9    1    0    8    2    5
        //           0x19990825>>>16           : 0001 1001 1001 1001 0000 1000 0010 0101
        //           0x00001999(0825는 제거됨) 
        
        int year=birthday>>>16;
        
        int month=birthday>>>8&0x000000ff;
        //                                         1    9    9    1    0    8    2    5
        //           0x19990825>>>8           : 0001 1001 1001 1001 0000 1000 0010 0101
        //                                         0    0    1    9    9    9    0    8
        //           0x00199908(25는 제거됨)  : 0000 0000 0001 1001 1001 1000 0000 1000
        //       &   0x000000ff               : 0000 0000 0000 0000 0000 0000 1111 1111
        //           0x00000008               : 0000 0000 0000 0000 0000 0000 0000 1000
        
        int day=birthday&0x000000ff;
        //
        //                                         1    9    9    1    0    8    2    5
        //           0x19990825               : 0001 1001 1001 1001 0000 1000 0010 0101
        //       &   0x000000ff               : 0000 0000 0000 0000 0000 0000 1111 1111
        
        System.out.printf("년: %x(년)\n", year);
        System.out.printf("월: %02x(월)\n", month);
        System.out.printf("일: %02x(월)\n", day);
        
        // 월에 대한 부분만 수정: 08->12
        // birthday=0x19990825 => 0x19991225로 수정
        
        // 월 부분 지우기
        //birthday=birthday&0xffff00ff;
        //System.out.printf("%x\n", birthday);
        
        //^연산 이용해서 소거(제거)
        birthday=birthday^0x00000800;
        System.out.printf("%x\n", birthday);
        
        // birthday=0x19990825
        //         ^0x00000800
        //            19990025
        
        // 월 부분 12로 채우기
        birthday=birthday|0x00001200;
        System.out.printf("%x\n", birthday);
        System.out.println();

실행결과는 다음과 같다.

7= [                             111]
5= [                             101]
&=[                             101]
|=  [                             111]
^= [                              10]
년: 1999(년)
월: 08(월)
일: 25(월)
19990025
19991225

위에서 &,|,^는 각각 7과 5에 대한 2진수를 이용해서 연산한 결과이다. 그 밑에는 2진수를 이용해서 생년월일을 처리하는 것을 다루었다. 

 

4. 일반논리연산자는 다음과 같이 3가지가 있다.

구분 연산자 의미 설명
논리연산자 && and(논리곱) 주어진 조건들이 모두 true이면 true출력
|| or(논리합) 주어진 조건들 중 하나라도 true이면 true출력
! not(부정) true는 false로, false는 true로 출력

일반논리연산자 부분의 코드는 다음과 같고, 

        //일반논리연산자: &&(and) ||(or)
        System.out.println("---[A && B]---");
        //                                          A      B
        System.out.printf("true  && true  => %b\n"true&&true);
        System.out.printf("true  && false => %b\n"true&&false);
        System.out.printf("false && true  => %b\n"false&&true);
        System.out.printf("false && false => %b\n\n"false&&false);
        
        System.out.println("---[A || B]---");
        //                                          A      B
        System.out.printf("true  || true  => %b\n"true||true);
        System.out.printf("true  || false => %b\n"true||false);
        System.out.printf("false || true  => %b\n"false||true);
        System.out.printf("false || false => %b\n\n"false||false);
        
        
        //사용 예
        int su=6
        if(su%2==0// 0 2 4 6 8 10 ...
            System.out.printf("[%d]은(는) 2의 배수이다.\n", su);
        else
            System.out.printf("[%d]은(는) 2의 배수가 아니다.\n", su);
        
        //su가 2와 3의 배수(6의 배수)인가?
        if((su%2==0)&&(su%3==0))
            System.out.printf("[%d]은(는) 2와 3의 배수이다.\n", su);
        else
            System.out.printf("[%d]은(는) 2와 3의 배수가 아니다.\n", su);
        
        // 윤년 구하기(1년이 366일(오차가 쌓여 1일 추가)이 되는 해)
        int year1=2000
        
        //윤년이 되는 조건
        //조건 1) 400년의 배수가 되는 해
        //조건 2) 4의 배수이면서, 100의 배수가 아닌 해
        
        //  조건 1(4배수)     조건2(100배수가 아닌 해)
        if((year1%400==0)||(year1%4==0 && year1%100!=0))
            System.out.printf("[%d]년도는 윤년\n", year1);    
        else
            System.out.printf("[%d]년도는 평년\n", year1);
        System.out.println();

그 실행결과는 다음과 같다.

---[A && B]---
true  && true  => true
true  && false => false
false && true  => false
false && false => false

---[A || B]---
true  || true  => true
true  || false => true
false || true  => true
false || false => false

[6]은(는) 2의 배수이다.
[6]은(는) 2와 3의 배수이다.
[2000]년도는 윤년

일반논리연산자가 배수와 윤년 구하기에 사용되었다.

 

5. 3항연산자, 대입연산자

3항연산자는 연산에 참여하는 조건이 3개로 다음과 같이 작성한다.

(조건)? 값1(참일때) : 값2(거짓일때); 

대입연산자에는 다음의 6가지가 있다.

구분 연산자 의미
대입연산자 = 연산자를 중심으로 오른쪽 변수값을 왼쪽 변수에 대입한다.
+= 왼쪽 변수에 더하면서 대입한다.
-= 왼쪽 변수에서 빼면서 대입한다.
*= 왼쪽 변수에 곱하면서 대입한다.
/= 왼쪽 변수에 나누면서 대입한다.
%= 왼쪽 변수에 나머지 값을 구하면서 대입한다.

이 부분에 해당되는 코드는 다음과 같고,

        // 3항연산자: 연산에 참여하는 항이 3개
        // (조건)? 값1 : 값2;
        //         (참)  (거짓)
        
        //두 수중 큰 수 구하기
        int a1=10, b1=5, c1;
        
        //3항연산자가 if문 보다 처리속도가 빠르다.
        c1=(a1>b1)? a1:b1;
        
        System.out.printf(" %d, %d중 큰 수는 %d\n", a1, b1, c1);
        
        //if문 사용시
        if(a1>b1)
            c1=a1;
        else
            c1=b1;
        System.out.printf("[if] %d, %d중 큰 수는 %d\n", a1, b1, c1);
        
        //절댓값 구하기
        int n1=-100;
        int m1;
        
        m1=(n1<0)?-n1:n1;
        
        System.out.printf("|%d|=%d\n", n1, m1);
        System.out.println();
        
        // 대입연산자: =
        // 복합대입연산자: +=  -=  *=  /=  %=  >>=  <<=  &=  ^=  |=
        
        int n2=10//초기화: 변수 선언과 동시에 값을 넣는 경우
        n2=100;    //대입(치환)
        
        n2++;  // n2=n2+1 <=자신을 1씩 증가
        
        n2+=2;  //n2=n2+2; //<=자신을 2씩 증가
        System.out.println(n2);
        
        // logical error
        n2=+2;  //잘못사용한 예
        System.out.println(n);
        
        n2=10;
        n2-=5// n2=n2-5;
        n2*=2// n2=n2*2;
        n2/=3// n2=n2/3;
        n2%=2// n2=n2%2;
        
        n2=3+2-2+1-4;
        
        //단항연산자 순서
        boolean b3=!!!!!(3>2);
        n2=-(-(10));
        System.out.printf("b3=>%b\n",b3);
        System.out.printf("n2=%d\n", n2);        

실행결과는 다음과 같다.

 10, 5중 큰 수는 10
[if] 10, 5중 큰 수는 10
|-100|=100

103
-1
b3=>false
n2=10

위는 3항연산자, 아래는 대입연산자에 해당되는 내용이고, 위에서 첫 번째 줄은 3항연산자, 두 번째 줄은 if문, 세 번째 줄은 3항연산자를 이용해 절댓값을 나타낸 것이다.

아래에서 103은 100을 1씩, 2씩 증가한 결과이고, -1은 대입연산자를 잘못 사용한 결과이다. 마지막 두 개는 단항연산자의 순서에 따른 실행결과를 나타낸 것이다. 

반응형

'Coding(Java) > Java(이론)' 카테고리의 다른 글

[Java] 8. switch문  (0) 2021.08.23
[Java] 7. if문  (0) 2021.08.23
[Java] 5. 단항연산자, 산술연산자  (0) 2021.08.20
[Java] 4. 자료의 입출력  (0) 2021.08.18
[Java] 3. 자료형  (0) 2021.08.17
Posted by skywalker222