[JAVA] 산술 연산자

joyful·2021년 4월 6일
1

Java/Spring

목록 보기
21/28

📚 종류

연산연산자수식결과
덧셈A+BA와 B를 더한 값
뺄셈A-BA에서 B를 뺀 값
곱셈×A×BA와 B를 곱한 값
나눗셈/A/BA÷B의 몫
나머지A%BA÷B의 나머지

📚 특징

  • 피연산자들의 타입이 동일하지 않을 경우, 자동 타입 변환 하여 피연산자들의 타입을 일치시킨 후 연산 수행

    • 피연산자가 모두 정수 타입
      1. int 타입보다 크기가 작은 정수 타입(byte, char, short)인 경우
        → 모두 int 타입으로 변환 후 연산 수행
        byte+intint+int = int
      2. int 타입보다 크기가 큰 정수 타입(long)인 경우
        → 모두 long 타입으로 변환 후 연산 수행
        ex) int+longlong+long = long
    • 피연산자 중 실수 타입(float, double) 존재
      → 크기가 큰 실수 타입으로 변환 후 연산 수행
      ex) int+doubledouble+double = double
  • long 타입을 제외한 정수의 산술 연산은 int 타입 변수에 산출값 대입

  • 소수점 이하의 값까지 산출 결과로 얻고 싶을 경우(택1)

    • 1.0을 곱하여 실수 타입으로 만든 후 산술 연산
      ex) double result = (int1*1.0) / int2;
    • 피연산자를 실수타입으로 강제 타입 변환(캐스팅) 한 후 산술 연산
      ex) double result = (double)int1 / int2;

💻 예시1 - 숫자 연산

✅ 소스코드

public class Main {
	public static void main(String[] args) {
		int a = 5;
		int b = 2;
		int nResult;
		
		nResult = a+b;
		System.out.println("a+b = " + nResult);
		
		nResult = a-b;
		System.out.println("a-b = " + nResult);
		
		nResult = a*b;
		System.out.println("a×b = " + nResult);
		
		nResult = a/b;
		System.out.println("a÷b = " + nResult);
		
		nResult = a%b;
		System.out.println("a%b = " + nResult);
		
		double dResult = (a*1.0)/b; // 방법1
		//double dResult = (double)a/b;	// 방법2
		System.out.println("a÷b(소수점까지 출력) = " + dResult);
	}
}

✅ 실행 결과

a+b = 7
a-b = 3
a×b = 10
a÷b = 2
a%b = 1
a÷b(소수점까지 출력) = 2.5
  • char 타입
    • 정수 타입이므로 산술 연산(유니코드 값을 이용한) 가능
    • 산술 연산시 int 타입으로 변환
    • 변수 자체에 산술 적용시 int 타입으로 산출되므로 컴파일 에러 발생
      강제 타입 변환(캐스팅) 필요
      ex) char result = (char) (char1+1);

💻 예시2 - char 타입 연산

✅ 소스코드

public class Main {
	public static void main(String[] args) {
		char c1 = 'A' + 1;
		char c2 = 'B';
		//char c3 = C2 + 1;	// 컴파일 에러 발생
		char c3 = (char) (c2+1);
		
		System.out.println("c1 = " + c1);
		System.out.println("c2 = " + c2);
		System.out.println("c3 = " + c3);
	}
}

✅ 실행 결과

c1 = B
c2 = B
c3 = C

❗ 주의할 점

  1. 연산 후의 산출값이 산출 타입으로 표현 가능해야 함
    • 연산 후의 산출값이 데이터 타입의 범위를 벗어나 산출 타입으로 표현할 수 없을 경우, 오버플로우쓰레기 값 발생
    • 산술 연산 전 오버플로우 탐지 메소드 호출할 것

💻 예시

    public class Main {
	public static void main(String[] args) {
		try {
			int result = chkRange(2000000000, 2000000000);
			System.out.println(result);
		} catch(ArithmeticException e) {
			System.out.println("계산을 위하여 값을 조정해주세요");
		}
	}

	private static int chkRange(int n1, int n2) {
		if(n2 > 0) {
			if(n1 > (Integer.MAX_VALUE - n2)) {  // 최대값 초과시
				throw new ArithmeticException("오버플로우 발생");
			}
		} else {
			if(n1 < (Integer.MIN_VALUE - n2)) {  // 최소값 미만시
				throw new ArithmeticException("오버플로우 발생");
			}
		}
		return n1+n2;
	}
}

  1. 정확한 계산은 정수 사용
    • 부동소수점(실수) 타입은 이진 포맷의 가수 사용
      → 0.1을 근사치로 처리함. 즉, 정확하게 표현하지 못함

💻 예시

✅ 소스코드

    public class Main {
	public static void main(String[] args) {
		/*
		 * 부동소수점 타입 사용시
		 * */
		int all = 1;
		double fraction = 0.1;
		int cnt = 7;
		
		double result = all - cnt*fraction;
		
		System.out.println("부동소수점 사용하여 연산시 result = " + result);
		
		/*
		 * 정수 사용시
		 * */
		all = 1;
		int nfraction = all*10;
		cnt = 7;
		
		int calculate = nfraction - cnt;
		
		result = calculate/10.0;
		
		System.out.println("정수 사용하여 연산시 result = " + result);
	}
}

✅ 실행 결과

부동소수점 사용하여 연산시 result = 0.29999999999999993
정수 사용하여 연산시 result = 0.3

  1. 0으로 나눌 수 없음 (Infinite, NaN 문제)

    • 또는 % 연산자 사용시 좌측 피연산자가 정수 타입인 경우
      → 우측 피연산자는 0 사용 불가(ArithmeticException 예외 발생)

    • 우측 피연산자가 실수 타입인 0.0 또는 0.0f인 경우

      연산자결과
      Infinity(무한대)
      NaN(Not a Number)

      ※ 결과 값과 산술 연산시 무조건 Infinity 또는 NaN 산출되므로 다음 연산 수행하지 말 것

    • 연산 결과 확인 메소드 이용할 것

      연산자메소드결과리턴값
      Double.isInfinite()Infinitytrue
      Double.isNaN()NaNtrue

💻 예시

✅ 소스코드

    public class Main {
	public static void main(String[] args) {
		int a = 5;
		double b = 0.0;
		
		double c = a/b;
		double d = a%b;
		
		System.out.println("Infinite 확인 : " + Double.isInfinite(c));
		System.out.println("NaN 확인 : " + Double.isNaN(d));

		/*
		 * Infinite 및 NaN 연산 확인
		 * */
		System.out.println("c+2 = " + (c+2));
		System.out.println("d+2 = " + (d+2));
		
		/*
		 * 연산 수행 조건문 사용
		 * */
		if(Double.isInfinite(c) || Double.isNaN(c)) {
			System.out.println("값 산출 불가");
		} else {
			System.out.println(c+2);
		}
	}
}

✅ 실행 결과

Infinite 확인 : true
NaN 확인 : true
c+2 = Infinity
d+2 = NaN
값 산출 불가

  1. 부동소수점(실수) 입력받을 경우 반드시 NaN 검사 실행할 것
    • "NaN" 문자열은 Double.valueOf() 메소드에 의해 double 타입으로 변환되면 NaN이 됨
    • NaN 조사시 == 연산자 사용하지 말 것
      → NaN은 != 연산자를 제외한 모든 비교 연산자를 사용할 경우 false 값 리턴
      ※ 반드시 Double.isNaN() 사용

💻 예시

✅ 소스코드

    public class Main {
	public static void main(String[] args) {
		String input = "NaN";	// 사용자로부터 입력받은 값
		double val = Double.valueOf(input);  // 입력받은 값 double 타입으로 변환
		
		double sum = 1000.0;
		
		double result1 = 0.0;
		double result2 = 0.0;
		
		result1 = sum + val;	// NaN로 인해 NaN 산출
		System.out.println("NaN 검사 미실시 : " + result1);
		
		/*
		 * NaN 검사
		 * */
		
		if(Double.isNaN(val)) {
			System.out.println("NaN이 입력됨");
			val = 0.0;
		}
		
		result2 = sum + val;	// NaN로 인해 NaN 산출
		System.out.println("NaN 검사 실시 : " + result2);
	}
}

✅ 실행 결과

NaN 검사 미실시 : NaN
NaN이 입력됨
NaN 검사 실시 : 1000.0

profile
기쁘게 코딩하고 싶은 백엔드 개발자

0개의 댓글