티스토리 뷰
class Arithmetic_3
{
public static void main(String[] args)
{
boolean a,b,c,d;
// 논리 연산자
// &(and) , |(or), !(not)
// 단축 논리연산자 (Short Circuit Logical Operator)
// &&, ||
a = (3 > 10) & (10 > 3); // 논리연산자는 무조건 두개다 검사를 하는 반면에 단축 논리연산자는 앞이 거짓(&&)이면 뒤에는 검사하지 않고, 앞이 참(||)이면 뒤에는 검사하지 않는다. => 속도가 빠름
b = (3 > 10) && (10 > 3);
c = (10 > 3) | (3 > 10);
d = (10 > 3) || (3 > 10);
System.out.println(" a = " + a);
System.out.println(" b = " + b);
System.out.println(" c = " + c);
System.out.println(" d = " + d);
}
}
논리 연산자와, 단축 논리연산자의 차이
: 논리연산자는 무조건 두개다 검사를 하는 반면에, 단축 논리연산자는 앞에 식(or)에서 false가 출력되면 계산이 멈추고 앞에 식(and)에서 true가 출력되면 계산이 멈추는 방식으로 되어 있기 때문에 논리연산자보다 단축 논리연산자가 훨씬 더 좋은 프로그램을 짤 수 있다 (시스템에 부하를 주지 않기 때문에)
class Arithmetic_4
{
public static void main(String[] args) throws Exception
{
System.out.print(" 하나의 문자를 입력하세요 !");
int yy = System.in.read(); // 1을받는다
char tt = (char)yy; // '1' 이된다. '1' == 1 => False
if ((tt >= 'a' && tt <= 'z') || (tt>= 'A' && tt <='Z'))
{
System.out.println(" 입력하신 문자는 유효합니다.");
}else{
System.out.println(" 입력하신 문자는 유효 하지 않습니다.");
}
System.out.println("Hello World!");
}
}
문자를 입력받고( System.in.read() ) 그 문자가 영어문자인지 아니면 그 외의 문자인지를 확인하는 코드
tt가 'a' 부터 'z' 에 포함되어 있거나 (or) 'A' 부터 'Z'에 포함되어 있다면 영어 문자일 것이고, 그 외로 입력받는 코드는 유효하지 않은 코드로 넘겨버리면 된다!
class Arithmetic_6
{
public static void main(String[] args)
{
int a, b, c;
a = 13;
b = 10;
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); // 서로같으면 0 다르면 1
c = ~a;
System.out.println(" ~ a = " + c); //1의 보수값이 나온다. -14 ex) a = 25라면 ~a 는 -26 +1 하고 부호 바꾸면됨
}
}
비트연산자는 간단히 비트들의 연산을 도와주는 문자다.
13을 비트로 표현하면 1101 (앞에 있는 비트 생략)
10을 비트로 표현하면 1010 (앞에 있는 비트 생략)
13 & 10 연산을 하면 비트가 두개다 1일 때만 1로 계산하여 1000이된다 즉, 8값이 출력된다.
13 | 10 연산을 하면 비트가 하나만 1일 때도 1로 계산되어 1111이 된다 즉, 15값이 출력된다.
13 ^ 10 연산을 하면 다른 비트일때만 1로 계싼되어 0111이 된다 즉, 7값이 출력된다.
~13 연산을 하면 1의 보수값이 나오므로 +1를 한 후 부호를 바꾸어 -14 값이 출력된다.
class Arithmetic_8
{
public static void main(String[] args) throws Exception
{
int ch, upper, lower;
System.out.print(" 알파벳을 입력하세요! ");
ch = System.in.read();
if(ch >='A' && ch <='Z')
{
lower = ch | 0x20;
System.out.print((char)ch + " 의 소문자 : " + (char)lower);
}else{
upper = ch & 0xDF;
System.out.println((char)ch + "의 대문자 :" + (char)upper);
}
System.out.println("Hello World");
}
}
ch 변수에 사용자가 입력하는 문자를 저장하고 그 문자가 소문자이면 대문자로 표현해주고, 대문자이면 소문자로 표현해주는 코드이다.
사용자가 'a'라는 문자를 입력했을 때 아스키 코드의 변환으로 인해 컴퓨터는 97이라는 숫자로 인식하게 되고 65라는 아스키코드를 가진 'A'를 출력하기 위해 lower 변수에 | 연산자를 이용하여 처리해준다.
같은 맥락으로 'A'라는 문자를 'a'라는 문자로 출력하기 위해 upper 변수에 & 연산자를 이용하여 처리하여 lower와 upper을 출력해준다.
class ShiftTest_1
{
public static void main(String[] args)
{
int x = 1, y = -1;
System.out.println("시프트 연산 x = 1, y = -1");
System.out.println("x << 1 = " + (x << 1));
System.out.println("y << 1 = " + (y << 1));
System.out.println("x >> 1 = " + (x >> 1));
System.out.println("y >> 1 = " + (y >> 1));
System.out.println("x >>> 1 = " + (x >>> 1));
System.out.println("x >>> 1 = " + (y >>> 1));
System.out.println("Hello World");
}
}
시프트 연산은 비트의 자리를 << / >> / >>> 에 맞춰 바꿔주는 연산자이다.
1을 비트로 바꿔보면 0001이고, 이를 x << 1 연산을 하면 0010(2)으로 변환된다.
같은 맥락으로 x >> 1 연산을 하면 0000(0)으로 변환된다.
양수의 시프트 연산은 쉽게 이해가 됐는데, 음수일때는 2의 보수형태를 지니고 있는 바람에 헷갈렸다.
-1을 비트로 바꿔보면 1111 1111 1111 1110 으로 볼 수 있고, y << 1 의 연산을 하면 1111 1111 1111 1101으로 변환되어 -2값으로 출력된다. 1111 1111 1111 1110 을 y >> 1 의 연산을 하면 부호 비트인 1이 이동되어 똑같이 1111 1111 1111 1110으로 처리되어 -1로 출력된다. 마지막으로 y >>> 1 의 연산을 하면 부호에 관계없이 오른쪽으로 0으로 채워야 하기 때문에 음수였던 값이 0(부호비트)로 바뀌어 양수로표현되고 0 | 1111 1111 1111 1111 ~~ 로 바뀌어 21억에 가까운 근사치가 출력되게 된다.
오늘은 비트연산자(Bitwise Operator)와 이동연산자(Shift Operators)을 공부했다. 헷갈리는 부분이 중간중간 있으니 유념해서 복습하도록 해야겠다.
마지막 문제는 20이라는 10진수의 3번째 비트가 무엇일까?를 출력하는 코드를 구상해봤다.
class ShiftTest_3
{
public static void main(String[] args)
{
//20이라는 10진수의 값을 2진수로 표현했을 때, 세 번째 자리에 위치한 비트를 출력해보자.
int bin = 20;
// 20의 2진수의 값 출력.
System.out.println(Integer.toBinaryString(bin));
// 10100(2) >> 2 => 101
bin = bin >> 2;
// 101 & 1 => 1 &연산자로 인해 0이면 0이 출력될 것이고, 1이면 1이 출력될 것이다.
bin = bin & 1;
System.out.println("20의 2진수인 10100의 세 번째 자리의 위치한 비트는 " + bin + " 입니다.");
}
}