본문 바로가기
언어/JAVA

[연산자] 정확한 계산, NaN과 Infinity, 비교 연산자, 논리 연산자

by 코딩맛집 2023. 1. 14.

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

산술 연산을 정확하게 계산하고 싶다면 실수 타입을 사용하지 않는 것이 좋다

public class Main {
    public static void main(String[] args) {
        int apple = 1;
        double pieceUnit = 0.1;
        int number = 7;
        
        double result = apple - number*pieceUnit;
        System.out.println("사과 1개에서 남은 양: " + result);
    }
}

//출력 : 사과 1개에서 남은 양 : 0.2999999999999999

출력된 결과를 보면 result 변수의 값은 정확히 0.3이 되지 않는다.

부동 소수점 방식을 사용하는 실수 타입에서 흔히 일어난다. 그렇기 때문에 정확한 계산이 필요하다면 정수 연산으로 변경해서 다음과 같이 계산하는 것이 좋다.

 

public class Main {
    public static void main(String[] args) {
        int apple = 1;
        int totalPieces = apple * 10;
        int number = 7;

        double result = totalPieces - number;
        System.out.println("10조각에서 남은 조각: " + result);
        System.out.println("사과 1개에서 남은 양: " + result/10.0);  
        }
}

//출력 : 10조각에서 남은 조각: 3
//       사과 1개에서 남은 양 : 0.3

 

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

/또는 % 연산에서 좌측 피연산자가 정수이고 우측 피연산자가 0일 경우 예외가 발생한다. 무한대의 값을 정수로 표현할 수 없기 때문이다.

 

하지만 좌측 피연산자가 실수이거나 우측 피연산자가 0.0f이면 예외가 발생하지 않고 연산의 결과는 Infinity 또는 NaN(Not a Number)이 된다.  Infinity 또는 NaN 상태에서 계속 연산을 수행하면 결과는 Infinity와 NaN이 되므로 데이터가 엉망이 될 수 있다. 

 

따라서 /와 % 연산의 결과를 확인하고 연산을 수행하는 것이 좋다.

Double.isInfinite()와 Double.isNaN()을 사용한다. 변수값이 Infinity 또는 NaN 일 경우 true를, 그렇지 않다면 false를 산출.

 

 

3.6 비교 연산자

동등 또는 크기를 평가해서 boolean 타입인 true/false를 산출한다. 비교 연산자는 흐름 제어문인 조건문(if), 반복문(for, while)에서 실행 흐름을 제어할 때 주로 사용된다.

구분 연산식 설명
동등 비교 == 두 피연산자의 값이 같은지를 검사
!= 두 피연산자의 값이 다른지를 검사
크기 비교 > 왼쪽 피연산자가 큰지를 검사
>= 왼쪽 피연산자가 크거나 같은지를 검사
< 왼쪽 피연산자가 작은지를 검사  
<= 왼쪽 피연산자가 작거나 같은지를 검사

피연산자의 타입이 다를 경우 비교 연산을 수행하기 전에 타입을 일치시킨다. 예를 들어 'A'==65 'A'가 int 타입으로 변환되어 65가 된 다음 65 == 65로 비교한다. 마찬가지로 3 == 3.0은 3을 double 타입인 3.0으로 변환한 다음 3.0 == 3.0으로 비교한다. 한 가지 예외는 0.1f==0.1에서 0.1f가 double 타입으로 변환되면 false가 산출된다. 그 이유는 부동 소수점 방식을 사용하는 실수 타입은 0.1을 정확히 표현할 수 없을 뿐만 아니라 float타입과 double 타입의 정밀도 차이 때문이다. 해결책은 다음과 같이 피연산자를 float타입으로 강제 타입 변환 후에 비교 연산을 하면 된다.

0.1f == (float)0.1

문자열을 비교할 때에는 동등 (==, !=)연산자 대신 equals()와 !equals()를 사용한다.

 

3.7 논리 연산자

논리 연산자는 논리곱(&&), 논리합(||), 배타적 논리합(^) 그리고 논리 부정(!) 연산을 수행한다.

논리 연산은 흐름 제어문인 조건문(if), 반복문(for, while) 등에서 주로 이용된다.

&&는 앞의 피연산자가 false라면 뒤의 피연산자를 평가하지 않고 결과를 산출한다. 그러나 &는 두 피연산자를 모두 평가해서 산출한다. 따라서 산출 결과는 같지만 &&가 더 효율적으로 동작한다. ||와 |도 마찬가지이다.