[이것이자바다] Chapter 03. 연산자

kims·2023년 11월 17일
0

이것이자바다

목록 보기
3/9

3.1 부호/증감 연산자

3.1.1 부호 연산자

  • 부호 연산자는 변수의 부호를 유지하거나 변경한다.
  • + 연산자는 잘 사용되지 않고, - 연산자만 부호를 변경할 때 사용한다.
public class OperatorEx {
    public static void main(String[] args) {
        byte maxValue = Byte.MAX_VALUE;
        byte minxValue = Byte.MIN_VALUE;

        System.out.println("max : " + maxValue + ", min : " + minxValue);   // max : 127, min : -128

        // byte minusMaxValue = -maxValue;   // 컴파일 에러 발생 : possible lossy conversion from int to byte
        int minusMaxValue = -maxValue;
        System.out.println(minusMaxValue);   // -127
    }
}
  • 정수 타입(byte, short, int) 연산의 결과는 int 타입으로 반환된다.

3.1.2 증감 연산자

  • ++, -- 연산자는 변수의 값을 1 증가시키거나 1 감소시키는 연산자이다.
public class OperatorEx {
    public static void main(String[] args) {
        int x = 1;
        int y = 1;

        int result1 = ++x + 10;
        System.out.println(result1); // 12
        System.out.println(x); // 2

        int result2 = y++ + 10;
        System.out.println(result2); // 11
        System.out.println(y); // 2
    }
}
  • 증감연산자가 변수 앞에 있으면 우선 변수 1 증가 또는 1 감소 시킨 후 나머지 연산을 수행한다.
  • 증감연산자가 변수 뒤에 있으면 우선 연산 후 변수 1 증가 또는 1 감소시킨다.

3.2 산술 연산자

연산식설명
+덧셈
-뺄셈
*곱셈
/나눗셈
%나눗셈의 나머지 산출
public class OperatorEx {
    public static void main(String[] args) {
        int x = 2;
        int y = 10;

        int plus = x + y;
        int subtraction = y - x;
        int multiplication = x * y;
        int division = y / x;
        int remainder = y % x;

        System.out.println(plus);               // 12
        System.out.println(subtraction);        // 8
        System.out.println(multiplication);     // 20
        System.out.println(division);           // 5 
        System.out.println(remainder);          // 0
    }
}
  • 피연산자가 정수 타입이면 결과는 int 타입으로 반환된다.
    단, 피연산자 중 하나가 long 타입이면 연산의 결과는 long 타입으로 반환된다.
  • 피연산자 중 하나가 실수이면 연산의 결과는 실수으로 반환된다.

3.4 정확한 계산은 정수 연산으로

  • 실수 타입을 사용해 산술 연산을 하면 결과 값이 정확하지 않다.
  • 실수 연산이 필요한 경우 BigDecimal 클래스를 사용하면, 산술 연산 시 정확한 결과 값을 얻을 수 있다.
import java.math.BigDecimal;

public class OperatorEx {
    public static void main(String[] args) {
        double x = 0.722;
        double y = 5.234;

        // 예상 값 : 5.956
        System.out.println(x + y); // 5.9559999999999995

        BigDecimal bigDecimalX = new BigDecimal("0.722");
        BigDecimal bigDecimalY = new BigDecimal("5.234");
        System.out.println(bigDecimalX);                        // 0.722
        System.out.println(bigDecimalY);                        // 5.234
        System.out.println(bigDecimalX.add(bigDecimalY));       // 5.956
    }
}

💡 BigDecimal

  • float 타입은 유효자릿수가 7자리로, 소수점 이하 7자리까지만 정확한 값이며 그 이후의 값은 오차가 발생한다.
  • double 타입은 유효자릿수가 16자리로, 소수점 이하 16자리까지만 정확한 값이며 그 이후의 값은 오차가 발생한다.
  • 가장 넓은 범위의 부동소수점을 표현할 수 있는 BigDecimal 클래스를 사용하면 연산의 정밀도를 높일 수 있다.
    단, 사칙연산 시 add( ), subtract( ), multiply( ), divide( ) 메서드를 사용하여야 한다.

3.5 나눗셈 연산 후 NaN과 Infinity 처리

  • NaN(Not a Number) : 숫자가 아닌 값
  • Infinity : 무한대
  • 나눗셈 또는 나머지 연산에서 좌측 피연산자가 정수이고 우측 피연산자가 0일 경우 예외가 발생한다.
  • 좌측 피연산자가 실수이거나 우측 피연산자가 0.0 또는 0.0f이면 예외가 발생하지 않고 Infinity 또는 NaN 값이 출력된다.
  • Double.isInfinite( )Double.isNaN( )을 사용해 true값이 반환되면 변수값이 Infinity 또는 NaN이다.
public class OperatorEx {
    public static void main(String[] args) {
        int x = 5;
        int y = 0;
//        System.out.println(x / y);  // Exception in thread "main" java.lang.ArithmeticException: / by zero

        float z = 2.5f;
        System.out.println(z / y);                          // Infinity

        double zero = 0.0;
        double result = x / zero;
        System.out.println(result);                         // Infinity
        System.out.println(Double.isInfinite(result));      // true

        double result2 = x % zero;
        System.out.println(result2);                        // NaN
        System.out.println(Double.isNaN(result2));          // true
    }
}

3.6 비교 연산자

연산자설명
==두 값이 같은지 비교
!=두 값이 다른지 비교
>, <값이 큰지 또는 작은지 비교
>=, <=값이 크거나 같은지 또는 작거나 같은지 비교
  • 피연산자의 타입이 다를 경우 연산 전에 타입을 일치시킨다.
    단, 피연산자 중 하나가 float나 double인 경우 두 타입은 부동 소수점 방식으로 인해 값의 정밀도 차이가 발생해 비교 연산 시 실수 타입으로 강제 변환해야 한다.
  • 문자열의 경우 동등 비교 연산 시 ==!= 대신 equals( ) 또는 !equals( )를 사용한다.

3.7 논리 연산자

구분설명
&& 또는 & (논리곱)피연산자 모두가 true → true
││ 또는 │ (논리합)피연산자 중 하나만 true → true
^ (배타적 논리합)피연자 중 하나가 true 이고 나머지가 false → true
! (논리 부정)피연산자의 논리값을 바꿈 true ↔ false
  • && 연산자앞의 피연산자가 false라면 뒤의 피연산자를 평가하지 않고 바로 결과 값을 산출한다.
    반면, & 연산자는 피연산자 모두 평가 후 값을 산출하기에 && 연산자가 더 효율적으로 동작한다.
  • || 연산자앞의 피연산자가 true라면 바로 결과 값을 산출한다.
    반면, | 연산자도 피연산자 모두 평가 후 값을 산출하기에 || 연산자가 더효율적으로 동작한다.
public class OperatorEx {
    public static void main(String[] args) {
        boolean a = true;
        boolean b = false;

        System.out.println(a && b);   // false
        System.out.println(a || b);   // true
        System.out.println(a ^ b);    // true
        System.out.println(!a);       // false
        System.out.println(!b);       // true
    }
}

3.8 비트 논리 연산자

  • bit 단위로 논리 연산을 수행한다.
  • 2진수 0과 1로 저장되는 정수 타입만 피연산자가 될 수 있고, 부동 소수점 방식으로 저장되는 실수 타입은 피연산자가 될 수 없다.
  • byte, short, char 타입 피연산자를 int 타입으로 자동 변환한 후 연산을 수행한다.
    따라서, 결과도 int 타입 변수에 대입해야 한다.
구분설명
& (논리곱)두 비트가 모두 1일 경우 → 1
│ (논리합)두 비트 중 하나만 1이면 → 1
^ (배타적 논리합)두 비트 중 하나는 1이고, 다른 하나가 0인 경우 → 1
∼ (논리 부정)보수
public class OperatorEx {
    public static void main(String[] args) {
        byte x = 12;
        byte y = 27;

        System.out.println("2진수 : " + Integer.toBinaryString(x));                   // 2진수 : 1100
        System.out.println("2진수 : " + Integer.toBinaryString(y));                   // 2진수 : 11011

        int BitwiseAnd = x & y;
        System.out.println("10진수 : "  + BitwiseAnd);                                // 10진수 : 8
        System.out.println("2진수 : " + Integer.toBinaryString(BitwiseAnd));          // 2진수 : 1000

        int BitwiseOr = x | y;
        System.out.println("10진수 : " + BitwiseOr);                                  // 10진수 : 31
        System.out.println("2진수 : " + Integer.toBinaryString(BitwiseOr));           // 2진수 : 11111

        int BitwiseXor = x ^ y;
        System.out.println("10진수 : "  + BitwiseXor);                                // 10진수 : 23
        System.out.println("2진수 : " + Integer.toBinaryString(BitwiseXor));          // 2진수 : 10111

        int BitwiseComplement = ~ x;
        System.out.println("10진수 : "  + BitwiseComplement);                          // 10진수 : -13
        System.out.println("2진수 : " + Integer.toBinaryString(BitwiseComplement));    // 2진수 : 11111111111111111111111111110011
    }
}

비트논리연산자

3.9 비트 이동 연산자

  • 비트를 좌측 또는 우측으로 밀어서 이동시키는 연산을 수행한다.
구분설명
a 〈〈 b (left shift 연산)a의 각 비트를 b만큼 왼쪽으로 이동
a × 2ⁿ와 동일한 결과가 된다.
오른쪽 빈자리는 0으로 채운다.
a 〉〉 b (right shift 연산)a의 각 비트를 b만큼 오른쪽으로 이동
a / 2ⁿ와 동일한 결과가 된다.
왼쪽 빈자리는 최상위 부호 비트와 같은 값으로 채운다.
a 〉〉〉 ba의 각 비트를 b만큼 오른쪽으로 이동
왼쪽 빈자리는 0으로 채운다.

3.10 대입 연산자

  • 우측 피연산자의 값을 좌측 피연산자인 변수에 대입하거나, 정해진 연산을 수행한 후 결과를 대입할 수 있다.
public class OperatorEx {
    public static void main(String[] args) {
        int x = 2;
        int y  = x;

        System.out.println(y);                          // 2
        System.out.println( (x += 1) + ", x  : " + x);  // 3, x  : 3
        System.out.println( (x -= 1) + ", x  : " + x);  // 2, x  : 2
        System.out.println( (x *= 2) + ", x  : " + x);  // 4, x  : 4
    }
}

3.11 삼항(조건)연산자

  • 조건식이 true이면 콜론(:) 앞의 피연산자가 선택되고, false이면 콜론 뒤의 피연산자가 선택된다.
    삼항연산자

3.12 연산의 방향과 우선순위

  • 대부분의 연산자는 왼쪽에서부터 오른쪽으로 연산을 수행한다. 먼저 처리해야 할 연산은 괄호( )를 사용한다.
    반면, 대입 연산자는 오른쪽에서 왼쪽으로 연산을 수행한다.

profile
기술로 세상을 이롭게

0개의 댓글