본문 바로가기
Java

이것이 자바다 (다섯번째 정리) - 3.4 이항 연산자(3) 초반까지

by 자연송어 2021. 3. 21.

- int는 정수타입이라서 소수점까지 저장이 안됨. 나누기를 하면 소수점을 빼고 저장하게 됨. (두번째줄 왼쪽)

- int 타입을 강제로 double타입으로 만들어준 후 계산을 해서 double에 저장하는 방법 세가지 (두번째줄 오른쪽)

 

- char타입은 2바이트라서 숫자와 산술을 하면 int타입(4바이트)으로 변환되어 char타입에 저장하지 못함. (세번째줄 왼쪽)

- char타입으로 강제 변환하여 저장하면 됨(세번째줄 오른쪽).

 

		char c1 = 'A' + 1; //A(유니코드) = 65 + 1 = 66 = 'B'
		System.out.println(c1);
		//리터럴값을 산술하여 char 타입에 저장가능 //값은 B
		
		char c2 = 'A';
		//char c3 = c2 + 1; //<-불가능한 코드. 숫자와 산술하여 int타입으로 변환되기 때문에 char타입으로 저장 불가능
		
		int result = c2 + 1;
		System.out.println(result); //값은 66
		//변수(c2)를 가지고 산술할 때 int값으로 변환되기 때문에 int타입에 넣어야 함.
		
		char c3 = (char)result;
		System.out.println(c3); //값은 B, char 타입으로 강제변환하여 저장

 

 

오버플로우 : 플러스나 마이너스 연산을 하면 허용범위(-21억~+21억)를 초과하거나 아래로 떨어지는 경우가 발생할 수 있음. 이 경우 오버플로우 발생.

 

<리터럴을 사용할 경우>

- int 타입으로 저장하면 허용범위 +21억을 넘어갔을 떄 마이너스로 넘어가며 허용범위 순환이 발생하여 엉뚱한 마이너스값이 저장됨 <- 쓰레기값

- long 타입으로 저장해야 함.

 

예외처리 : 잘못된 값을 가지고 프로그램이 계속 실행하게 두지 않고 잘못된 값을 바로잡을 수 있도록 처리한 다음 정상적으로 처리 하는 것. 

 

여기서 엄청난 오류로 인해 다음으로 가지 못함.

해결과정 -> trout1.tistory.com/15

 

3.3 이항연산자(2)

부동소수점(실수) 타입을 사용하면 원하는 결과값이 나오지 않을 수 있다.
정수로 먼저 계산하고 마지막에 실수로 바꿔주는 방법으로 원하는 결과값 얻을 수 있다.

 

		/*
		int x = 1000000;
		int y = 1000000;
		
		int z = x*y;
		System.out.println(z);
		int타입으로 저장해서 값이 마이너스 이상한 값으로 나옴.*/
		
		long x = 1000000;
		long y = 1000000;
		
		long z = x*y;
		System.out.println(z); //올바른 값 
	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)) { 
				//int가 가질 수 있는 최대값에서 right를 뺀값보다 left가 더 크다면
				throw new ArithmeticException("오버플로우 발생");
			}
		} else {
			if(left<(Integer.MAX_VALUE-right)) {  
         	   //int가 가질 수 있는 최대값에서 right를 뺀값보다 left가 더 작다면
				throw new ArithmeticException("오버플로우 발생");
		}
}
		return left + right;
	}
	}
		/*double result = 7 * 0.1;
		System.out.println(result); 
		결과값은 0.7000000000000001 실수로 나옴.
		*/
		
		int apple = 1;
		double pieceUnit = 0.1; //실수가 있어서 결과값이 실수로 나옴.
		int number = 7;
		
		double result = apple - number*pieceUnit;
		
		System.out.println("사과 한개에서");
		System.out.println("07 조각을 빼면");
		System.out.println(result + "조각이 남는다.");
		
		/* 결과값은
		사과 한개에서
		07 조각을 빼면
		0.29999999999999993조각이 남는다.
		실수 연산은 가급적 피하고 정수연산을 한다.
		*/
		int apple = 1;
		
		int totalPieces = apple * 10;
		int number = 7;
		int temp = totalPieces - number;
		
		double result = temp / 10.0;
		
		System.out.println("사과 한개에서");
		System.out.println("07 조각을 빼면");
		System.out.println(result + "조각이 남는다.");
		
		/* 결과값은
		사과 한개에서
		07 조각을 빼면
		0.3조각이 남는다.
		*/

 

정수로 계산하면 예외가 발생하지만 실수로 계산하면 infinity 또는 NaN으로 결과값이 나옴.

 

		/*int x = 5;
		double y = 0.0;
		
		//double z = 5/y;
		double z = 5%y;
	
		System.out.println(z + 2); //무엇을 연산하든 같은 같이 나옴. 결과값 NaN
		
		if(Double.isInfinite(z) || Double.isNaN(z)) {
			System.out.println("값 산출 불가");
		} else {
		
		System.out.println(Double.isInfinite(z)); //결과값이 인피니트면 트루
		System.out.println(Double.isNaN(z)); //결과값이 NaN이면 트루
		
				System.out.println(z + 2);
		}*/
		
		int x = 5;
		int y = 0;
		
		try {
		int z = x/y;
		System.out.println("z=" + z);

	} catch(ArithmeticException e) { //예외가 나오면 실행
		System.out.println("0으로 나누면 안됨");
	}
}
}

Double.valueOf -> 문자열을 double타입으로 변환 시켜주는 메소드

 

		String userInput = "NaN";
		
		double val = Double.valueOf(userInput);
		
		double currentBalance = 10000.0;
		
		if(Double.isNaN(val)) {
			System.out.println("NaN이 입력되어 처리할 수 없음");
			val = 0.0; //val에 들어 있는 NaN을 0.0으로 변환
		}
		//currentBalance = currentBalance + val;  (밑에 있는 코드와 동일한 뜻)
		currentBalance += val;
		
		
		System.out.println(currentBalance);
		/*결과값은
		NaN이 입력되어 처리할 수 없음
		10000.0
		*/

str1 문자열과 숫자를 연산하면 숫자가 문자열로 자동 변환되어 저장

 

str3 문자열 + 숫자 + 숫자 = JDK33.0 (문자열과 숫자를 더한후 뒤에 오는 숫자를 문자열로 자동변환하여 저장)

str4 숫자 + 숫자 + 문자열  = 6.0JDK (숫자를 먼저 더한 후 문자열 더함)

 

3.4 이항 연산자 (3)