자바 본 강의

연산자, 논리 연산자, 비트 연산자, 조건 연산자

우주코딩 2021. 7. 9. 20:08

*연산자 (Operator)
1. 산술 연산자 : +, -, *, / , %
   -우선 순위 () >  ++, --  >   / , * , % > +, - > =
  - 정수의 산술 연산의 최소 단위는 int 

만약 byte, short 형에 리터럴 4바이트 정수 값을 저장할 수 있다면, 허용해준다.
ㄴ 리터럴 값을 작은 크기의 변수에 저장할 수 있다면 컴파일 허락한다.
byte b = 5 + 6; // 가능

하지만... 자바의 정수 연산은 최소 단위가 4바이트다.
바이트형과 바이트 형의 연산은 불가능하다. 연산 전에 int 형으로 바꿔준다..
byte x =5;
byte y =6;
z = x;
z = y;

byte z = x + y; // 요거 불가능
x,y값이 바이트니까!

임시의 int 메모리를 준비하고 연산하면 연산 결과도 int가 된다.
%%  byte 연산의 결과는 byte 가 아니라는 것 !!!!! %%

이와 같이 short 와 short 값을 더하면 int 변수 값이 나온다.

결과 값을 담을 int 변수 ( 임시 4바이트 메모리) 를 만든다.
byte 변수는 보통 파일의 데이터를 읽을 때 사용한다.
이미지 파일이나 텍스트파일.

-데이터 타입과 연산자
데이터 타입에 따라 사용할 수 있는 연산자가 정해져 있다.

문자열의 경우 + 만 가능.
- , * 는 컴파일 오류 발생.

Boolean타입은 산술 연산자를 사용할 수 없다.

 System.out.println(true && true); ㅡ 가능
System.out.println(10 && 10); ㅡ 불가능
&& 연산자는 정수에 사용할 수 없다.

-연산의 결과 타입은 피연산자와 같다.
int i = 5;
int j = 2;
float r = i / j;

r의 값은 2.0이 된다.
int와 int의 연산 결과는 항상 int이다. 그 int 값을 r에 넣기 때문에 2.0이다.

2.5 값이 나오게하기 위해선 명시적 형변환을 해야한다.
int / int = int
(float) int / (float) int = float 

int와 int의 연산 결과는 int이다.
다른 타입이 될 수 없다.
=> 0111 1111 1111 1111 1111 1111 1111 1111 = Integer.MAX_VALUE

int x = Integer.MAX_VALUE; // 0x7fffffff = 약 +21억
int y = Integer.MAX_VALUE; // 0x7fffffff = 약 +21억
int r1 = x + y; 
0111 1111 1111 1111 1111 1111 1111 1111(x)
+ 0111 1111 1111 1111 1111 1111 1111 1111(y)
---------------------------------------------
1111 1111 1111 1111 1111 1111 1111 1110(r1)
System.out.println(r1); // int(4byte) + int(4byte) = int(4byte)
ㄴ 결과 -2

%%int와 int의 연산 결과가 int의 범위를 넘어가면 의도한 결과가 나오지 않을 수 있다.%%
ㄴ 오버플로우 값이 짤리고 음수 값이 나타날 것이다. 

그래서 int와 int의 연산 결과를 더 큰 메모리에 담는다면 해결될까?
long r2 = x + y;  
System.out.println(r2); 
 ㄴ 결과 -2

int 와 int의 연산 결과는 피연산자와 같은 4바이트 int가 된다.
그래서 8바이트 long 변수에 저장하기 전에 이미 그 결과는 int 값으로 -2가 되기 때문에 
long 변수의 값이 -2가 된다.

 int와 int 연산 결과가 int 크기를 넘어갈 것 같으면 형변환해야한다.
r2 = (long)x + (long)y;
System.out.println(r2);

-암시적 형변환
데이터 타입이 서로 같을 때만 연산 가능하다.
데이터 타입이 다를 경우 임시적 형변환이 일어나 계산해 더 큰 데이터 타입의 값을 내놓는다.

2.관계 연산자(relational operators: <, <=, >, >=)와 등위 연산자 (equality operators: ==, !=)

비교의 결과는 true 또는 false이다
즉, boolean값이다.
int 로 담을 수 없다!!!!

 

- 부동소수점 비교하기

float f1 = 0.1f;

float f2 = 0.1f;

System.out.println(f1 * f2 == 0.01f); 

ㄴ FALSE 값이 나온다.

 

false가 나온 이유는 부동소수점끼리 연산 할 경우

IEEE 754 명세에 따라 작업을 수행한다. 그 과정에 값의 왜곡이 발생할 수 있다.

 

위의 연산의 경우 f1 * f2 값을 출력하면 0.0100001 값이 나온다.

즉, 쓰레기 값이 붙어서 

f1 * f2 == 0.01f의 연산이 false 가 나오게 된 것이다.

 

부동소수점의 왜곡 없는 연산을 수행하기 위해 EPSILON 혹은 Float.POSITIVE_INFINITY를 사용한다.

 

극한의 작은 값은 EPSILON이라고 부른다.

 

부동 소수점을 비교할 땐 비교값에서 비교값을 빼고 그 남은 값이 사용자가 정한 극한의 값(EPSILON) 보다 작으면

같다고 치자 ~~ 이렇게 처리된다.

부동소수점 비교 시 절대 그냥 == 로 처리해선 안된다.

 

double EPSILON = 0.00001;

Math.abs((f1 + f2) - (0.1 *  0.1)) <EPSILON ); 


앱실론을 정하지 않고 결과 결과를 절대값으로 만든 후에 
Float.POSITIVE_INFINITY 를 사용한다 ( 극한의 값을 미리 정해놓음)

예시)
float r = f1 * f2 - 0.01f;
 System.out.println(Math.abs(r) <= Float.POSITIVE_INFINITY);

결과는 TRUE이다.

3.논리 연산자 (&&, ||, !(not), ^(XOR; exclusive-OR)
&&, ||, !(not), ^(XOR; exclusive-OR)
-AND 연산자 &&
두 개의 논리 값이 모두 true일 때 결과가 true가 된다.
-OR 연산자 
두 개의 논리 값 중 한 개라도 true이면 결과는 true가 된다.

-exclusive-OR(XOR)연산자 
배타적 비교 연산자라 부른다.
두 개의 값이 다를 때 true이다.
XOR 연산자를 정수 값에 대해 수행하면 비트 단위로 연산을 수행한다.

* && vs & 논리 연산자
a = false;
b = false;
r = a && (b = true);
첫번째 피연산자로 결과를 예측할 수 있다면 두 번째 피연산자는 실행하지 않는다

a =false;
b=false;
r = a & (b=true);
앞의 피연산자값에 상관없이 끝까지 실행한다.
평상시엔 되도록이면 && 나 || 같이 두개 짜리를 사용해야한다.

4. 비트 연산자 (&, |, ^, ~)

정수 값에 대해서는 &&와 ||, !을 사용할 수 없다.
비트 연산은 이미지 표현, 색 처리에 주로 사용된다.

조건연산자
 = 조건?  표현식 : 표현식;

첫 번째 표현식은 참일 때 실행
두 번째 표현식은 거짓일 때 실행

문장 (statement) 표현식 (expression)
문장 : 작업을 수행시키는 명령어이다.
표현식 : 문장을 실행한 후에 결과를 리턴한다.
statement 중에서 결과를 리턴하는 statement를 expression이라 부른다.

조건 연산자는 할당 연산자 (=)의 왼편에 변수를 선언해야 한다.
선언하지 않으면 문법오류

조건 연산자의 결과 값이 왼편의 변수 타입과 일치해야한다.
결과 값이 없거나 타입이 일치하지 않으면 문법 오류

5. 증감연산자 : 전위(prefix) / 후위(postfix)
int i =100;
컴파일 할 때 다음 문장으로 변환된다

전위 연산자 ++i; 
i = i + 1

후위 연산자 i++;
temp = i;
i = i+ 1;

리터럴에 대해 증감 연산자 적용할 수 없다.
변수에 동시에 적용할 수 없다
++y++; < - 이런 식이 안된다는 뜻

6.할당 연산자
int i =2;

i = i + 20; == i +=20;

i =2;
i *= 5;