각자의 종류나 기능에 대해서만 알면 될 거 같아 가볍게 써보려고 한다!
그리고 연산자이기 때문에 내가 좋아하는 수학과 많이 닮아 있는 거 같아서! ❤️
주어진 변수나 리터럴에 대해 연산을 수행하기 위한
것
(간단하게 예시를 들면 우리가 덧셈 뺄셈 등의 계산? 연산을 하기 위해 사용하는 기호들!! +, - 같은거)
(단항, 대입 제외 연산 방향 →)
(아래로 내려갈수록 우선순위가 낮아짐)
(ex. 대입 연산자 =
가 사용된 이 식 x = y = 5
을 보면,
우리는 상식적으로 y에 5 값을 넣어주고, x에 y값인 5를 넣어준다.)
** 연산자가 연산을 하는데 필요로 하는 피연산자의 개수에 따라 단항, 이항, 삼항 연산자로 불림 (우선순위는 단항이 가장 높음)
보통의 단항 연산자는 피연산자의 왼쪽에 위치하지만, 이 둘은 양쪽에 모두 위치한다. 그리고 그 위치에 따라서 연산 결과가 변화한다.
이 차이를 알아보자.
int a = 5;
int b = 0;
b = a++; //후위형
int c = 0;
c = ++a; //전위형
System.out.println("b = "+b+" a = "+a); //b = 5 a = 6
System.out.println("c = "+c+" a = "+a); //c = 6 a = 6
결과는 두 식이 같지만 실제로 연산이 수행되는 과정에서 차이가 발생한다.
또한 ++i가 더 적은 명령으로 작업을 수행하여 더 빠르다.
※ i = i+1 의 컴파일 코드
※ ++i의 컴파일 코드
또한 +
는 필요에 따라 피연산자를 형변환 하지만 증감 연산자는 형변환 없이 피연산자의 값을 변경한다.
//간단한 사용 예시
int j = 100;
j = +j;
System.out.println(j); //100
j = -j;
System.out.println(j); //-100
2진수 값 = 00001010(2) / 10(10)
-> 비트전환 2진수 값 = 11110101(2) / -11(10)
(앞이 부호 표현을 해주는 bit인듯)
다만, 피연산자의 타입이 int보다 작다면 int형을 변환한 뒤 연산을 실시해야 한다.
byte b = 10;
byte result = (byte) ~b;
//그래서 꼭 위의 코드처럼 형변환을 표시 해줘야함
System.out.println(b); // 10
System.out.println(result); // -11
boolean check = false; System.out.println(!check); => true
아래의 산술 연산자는 모두 두 개의 피연산자를 취하는 이항 연산자
이다.
이 때 이항 연산자는 피연산자의 크기가 4byte보다 작으면 int형으로 변환한 뒤 연산을 수행해야 한다!!
(출처: 자바의 정석)
ArithmeticException
오류 발생byte a = 10;
byte b = 20;
byte c = (byte) (a+b);
//형변환을 통해 int(a+b)형의 값을 다시 byte형으로 바꿔서 돌려준다.
byte a = 10;
byte b = 30;
byte c = (byte) a*b;
System.out.println(c); //44가 출력
//원래 값은 300이지만 byte의 값 범위(127)를 넘어가 자료 손실이 발생함
long a = 1000000 * 1000000;
long b = 1000000 * 1000000L;
System.out.println(a); // -727379968
System.out.println(b); //10^12
//위는 int*int로 인식이 되어 오버플로우 발생
//아래는 L이라는 long리터럴 사용했으므로 long으로 결과가 계산됨
char c1 = 'a';
// char c2 = c1+1; //char로 형변환을 해주지 않아 컴파일 에러
char c2 = 'a'+1; //얘는 리터럴이기 때문에 형변환 해주지 않아도 OK
//따라서 위의 변수 c2는 컴파일 시 'b'로 변화됨
/1000f
특이점이 있는데
System.out.pritnln(-10%8) //-2
System.out.println(10%-8) //2
첫번째 피연산자의 부호를 따라 결과값의 부호가 결정된다!
= 2진수로 표현했을 때의 각 자리를 오른쪽/왼쪽 으로 이동한다고 하여 이름 붙여짐
x << n = x*2^n의 결과와 같고
x >> n = x/2^n의 결과와 같다
=> 그러나 가독성이 그리 좋은 편은 아니기 때문에 속도가 빠른 메리트가 있어도 막 많이 사용되지는 않는 것 같다.
= 두 개의 변수 or 리터럴을 비교
하는데 사용되는 연산자
= 결과는 무조건 true or false
= 두 자료형이 서로 다르다면 큰 쪽으로 형변환을 시켜준다!
기본형
은 값이 같은지, 참조형
은 주소값을 저장하기 때문에 같은 객체를 가리키는지 확인할 수 있다!//같은지 다른지 비교 예시
float f = 0.1f;
double d = 0.1;
double d2 = (double) f;
System.out.println(10.0 == 10.0f); //true
System.out.println(0.1 == 0.1f); //false
System.out.println(d == f); //false
System.out.println(d == d2); //false
System.out.println(d2 == f); //true
위의 예제에서 의문이 들 수 있다. 왜 10.0와 10.0f는 같으면서 0.1과 0.1f는 다른지? 이건 0.1이 실수형이기 때문이다. 실수형인 double과 float는 근사값으로 저장되어 실질적으로 값이 0.1000~~149~로 저장되기 때문이다.
괄호
를 사용해 우선순위를 명확히 해주면 더 좋다.||
= OR 결합 = 한 쪽만 true여도 true를 결과로 얻음
&&
= AND 결합 = 양쪽 모두 true여야 true를 결과로 얻음
&
= AND 연산자 = 양쪽이 모두 1이어야 결과가 1
|
= OR 연산자 = 한쪽만 1이어도 결과가 1
^
= XOR 연산자 = 두 값이 서로 다를 때만 결과가 1
** 참고로 boolean형은 true가 1, false가 0이다.
int x = 3; // 011
int y = 5; // 101
System.out.println(x|y); //7(111)
System.out.println(x&y); //1(001)
System.out.println(x^y); //6(110)
세 개의 피연산자를 필요로 하기 때문에 삼항 연산자
이다.
int result = (x>0) ? x : -x; //요런식으로 작성 가능
//위의 상항 연산자는 아래의 조건문과 같다.
if(x>0) result = x;
else result = -x
= 변수에 값 or 수식의 연산결과를 저장하는데 사용!
할당 연산자
라고도 불림!// ex. op=
i += 3;
i >>= 3;
i ^= 3;
//ex. =
i = i+3;
i = i % 3;
i = i ^ 3;
3-1. 다음 연산의 결과를 적으시오.
int x = 2;
int y = 5;
char c = 'A';
System.out.println(1+x << 33); //6
System.out.println(y+=10 - x++); //13
3-7. 변환 결과값이 소수점 셋째 자리에서 반올림 된, 화씨가 섭씨로 변환되는 코드를 작성하시오.
int fahrenheit = 100;
float celcius = (int)((5/9f * (fahrenheit - 32))*100 + 0.5) / 100f; //정답!!
System.out.println("Fahrenheit:"+fahrenheit);
System.out.println("Celcius:"+celcius);
원래 소수점 둘째 자리까지 나타내려면 원래의 값에 100을 곱한 뒤 다시 100을 나눠줘야 한다.
근데 0.5는 왜 더해주는지 잘 모르겠다(반올림 해야 해서 0.5를 더해준 거 같긴 하다). float 자료형을 표시(f)해주지 않으면 값이 int형으로 자동 인식되기 때문에 실수형으로 표현하기 위해 분모 9와 나눌 때의 100에 모두 f를 주었다.
3-8. 아래 코드의 문제점을 수정해서 실행결과와 같은 결과를 얻도록 하시오.
byte a = 10;
byte b = 20;
byte c = (byte)(a + b);
char ch = 'A';
ch = (char)(ch + 2);
float f = 3 / 2f;
long l = 3000 * 3000 * 3000L;
float f2 = 0.1f;
double d = 0.1;
boolean result = (float)d==f2;
자바의 정석, 2nd Edition.
https://www.devkuma.com/docs/java/operator/
(사진) https://myeonguni.tistory.com/40