연산자

Java

목록 보기
3/26
post-thumbnail

1. 연산

  • 연산되는 데이터는 피연산자(operand)라고 함
  • 단항 연산자 : ex) x++;
    이항 연산자 : ex) x+y;
    삼항 연산자 : ex) (sum>90) ? "A" : "B"
  • 우선순위 정리는 책에~ 외울 필요 없음

2. 단항 연산자

2-1. 부호 연산자(+,-)

  • ✅부호연산자를 사용할 때 주의할 점은 부호 연산자의 산출 타입은 int 타입이 된다는 것이다. 예를 들어 short 타입 값을 부호 연산하면 int 타입 값으로 바뀐다.
short s = 100;
short result = -s;    >> 컴파일 오류
short s = 100l
int result3 = -s;     >> OK

2-2. 증감 연산자(++,--)

  • ✅증감연산자의 위치에 따라 연산식의 결과가 다르게 나오므로 주의해야한다.
  • 단, 단독으로 있을 때는 상관 없음
    x++++x 결과 같음
    ✅내가 틀린 문제
int x = 1;
int y = 1;
int result1 = ++x + 10;       >> 연산 전에 X1 증가
int result2 = y++ + 10;       >> 연산 후에 y를 1 증가
result1 -> 12
result2 -> 11
	int x = 10;
	int z;
	
	System.out.println("-----------------");
	x++;
	++x;
	System.out.println("x=" + x);
	
	System.out.println("-----------------");
	z = x++;
	System.out.println("z="+ z);    >> z=12
	System.out.println("x=" + x);   >> x=13

2-3. 논리 부정 연산자 : !

  • '!'는 'not'이라고 읽는다

2-4. 비트 반전 연산자 : ~

  • 😺사용할 일은 잘 없다😺
  • '~'는 '틸트'라고 읽는다
  • byte, short, int, long 타입만 피연산자가 될 수 있다.
  • 비트 값을 반전(0->1, 1->0)시킨다.
  • 피연산자의 타입이 int 이사이면 연산의 결과는 int 타입이다. (int로 받는다)
  • 부호까지 반대인 새로운 값이 산출된다.
  • 비트 반전 후 1을 더하면 부호가 반대인 값을 얻을 수 있다.
byte v1 = 10;
int v2 = ~v1 + 1;     >> -10이 v2에 저장

✅Integer.to.BinaryString() : 정수값을 32비트 이진 문자열로 리턴

>>걍 이진수로 바꿔준다는 뜻임. 막 10101011100010 이런 숫자로.

3. 이항연산자

3-1. 연산자끼리의 연산

  • 피연산자들이 모두 정수 타입이고, int타입(4byte)보다 크기가 작은 타입일 경우 모두 int 타입으로 변환 후 , 연산을 수행한다. 따라서 연산의 산출 타입은 int이다.
  • 피연산자들이 모두 정수 타입이고, long 타입이 있을 경우 모두 long 타입으로 변환 후, 연산을 수행한다. 따라서 연산의 산출 타입은 long이다.
  • 피연산자 중 실수 타입(float 타입, double 타입)이 있을 경우, 크기가 큰 실수 타입으로 변환 후, 연산을 수행한다. 따라서 연산의 산출 타입은 실수 타입이다.
    ✅ 아니 이건 왜이렇게 이해가 안 가는거야
char c1 = 'A' +1;
char c2 = 'A';
char c3 = c2 + 1;    >> 컴파일 오류. 2바이트와 4바이트를 더하면 4바이트 짜리인 int로 받아야 함
char c3 = (char) (c2 +1);    >> OK

3-2. 오버플로우 탐지

  • 산술 연산을 할 때 주의할 점 : 연산 후의 산출값이 산출 타입으로 충분히 표현 가능한지 살펴봐야 함
    ✅ 쫌 복잡함.
int x = 1000000;
int y = 1000000;
int z = x + y;    >>컴파일 오류
	public static void main(String[] args) {
	
	try {
		int result = safeAdd(2000000000, 2000000000);
		System.out.println(result);
	} catch(ArithmeticException e) {
		System.out.println("오버플로우가 발생하여 정확하게 계산할 수 없음");
	}
		}

	public static int safeAdd(int left, int right) {
		if ( (right>0)) {
			if(left>(Integer.MAX_VALUE - right)) {
				throw new ArithmeticException("오버플로우 발생");
			}
		} else {
			if (left < (Integer.MIN_VALUE - right)) {
				throw new ArithmeticException("오버플로우 발생");
			}
		}
		return left + right;
	}

3-3. 정확한 계산은 정수 사용

  • 정확하게 계산해야 할 때는 부동소수점(실수) 타입을 사용하지 않는 것이 좋다.
    부동소수점 타입(float, double)은 0.1을 정확히 사용할 수 없어 근사치로 처리하기 때문이다. 정확한 계산이 필요하다면 정수 연산으로 변환한 다음 다음과 같이 계산해야한다.
int apple = 1;
double pieceUnit = 0.1;
int number = 7;
double result = apple - number * pieceUnit;
 >> 0.299999999999조각
int totalPieces = apple * 10;
int number = 7;
int temp = totalPieces = number;
double result = temp / 10.0;
 >> 0.3조각

3-4. NaN과 Infinity 연산

  • 주의 : Infinity + 2 = Infinity / NaN + 2 = NaN
    try {
    int z = x + y;
    int z = x % y;
    System.out.println("Z: " + Z);
    } catch (ArithmeticException e) {
    System.out.println("0으로 나누면 안됨");
    }

3-5. 입력값의 NaN 검사

  • 부동소수점(실수)를 입력받을 때는 반드시 NaN 검사를 해야한다.
    Double.valueOf("___")는 ____라는 '문자'를 double타입으로 변환 출력함. ∴ double로 받아야함.
  • 또한, Double.valueOf("NaN")은 error가 발생하지 않고, double타입에 저장할 수 있는NaN이 나온다.
  • NaN + 1 = NaN
  • Double.inNaN(val) 검사 필요.

3-6. 문자열 비교 연산자(==)

  • 문자열 비교는 equals() 메소드를 사용
    왜? ==번지가 같은지를 비교하는 것이기 때문.
String strVar1 = "신용권";
String strVar2 = "신용권";
String strVar3 = new String("신용권");
strVar1 == strVar2 -> true
strVar2 == strVar3 -> false
strVar1.equals(strVar2) -> true
strVar2.equals(strVar3) -> true

3-7. 문자열 연결 연산자(+)

  • 연산의 방향은 왼쪽 → 오른쪽
    String str3 = "JDK" + 3 + 3.0;           >> JDK33.0
    String str4 = 3 + 3.0 + "JDK";           >> 6.0JDK

    3-8. 논리 연산자(&&,||,&,|,^,!)

  • &&이 &보다 잘 사용됨. ||가 |보다 잘 사용됨.
    (&&와 ||는 앞에 것만 검사해서 빠르기 때문에)
    (&와 |는 잘 사용 안 됨)
  • XOP은 잘 사용 안 하니 그냥 있다는 사실만 흝어보기

3-9. 조건 연산자

0개의 댓글