프로그래밍/java

[자바 JAVA] 오버플로우/ 언더플로우 / 자동형변환 / 강제형변환

pupu91 2022. 6. 27. 20:40
반응형

 

 


오버 플로우 

 


 

  • 자료형 별 값의 최대 범위를 벗어나는 경우
  • 초과한 값을 버림처리 하고 sign bit를 반전시켜 최소값으로 순환시킴

 

byte형

최소값 -128

최대값127 

 

byte num1 = 127;
System.out.println("num1 : " + num1);		
127 : byte의 최대 저장 범위
		
num1++;				
1 증가
		
System.out.println("num1 overflow : " + num1);	
-128 : byte의 최소 저장 단위

 

 


언더 플로우

 


  • 오버플로우의 반대 개념으로 최소 범위보다 작은 수를 발생시키는 경우 발생하는 현상
byte num2 = -128;
System.out.println("num2 : " + num2);	
-128 : byte의 최소 저장 범위
		
num2--;			
1 감소
		
System.out.println("num2 underflow : " + num2);	
127 : byte의 최대 저장 범위

 

  • 이러한 오버플로우와 언더플로우가 발생한다고 하여 컴파일 에러나 런타임 에러가 발생하지 않으므로
    최대값 혹은 최소값 범위를 고려해서 코드를 작성해야 함.(디버깅 시 가장 힘든 이유 중 한가지)

 

 

 

  • 해결방법

    오버플로우를 예측하고 더 큰 자료 형으로 결과 값을 받아서 처리한다.

 

  • 이미 오버 플로우 처리 된 결과를 가지고 변수에 담기 때문에 위의 결과가 차이가 없다.
  • 계산이 처리 되기 전에 long 타입으로 자료형을 변경해 주어야 한다.(강제 형변환 이용)

 

 


형변환(casting)

 


  • 값의 자료형을 바꾸는 것 ( boolean제외)
  •  종류 : 자동 형변환, 강제 형변환

자동 형변환

 


  • 컴파일러가 자동으로 값의 범위가 작은 자료형을 값의 범위가 큰 자료형으로 변환

  • 값의 범위가 큰 자료형을 값의 범위가 작은 자료형으로 변환
  • 강제 형변환 시 데이터 손일이 발생할 수 있음

 

     다른 자료형간의 연산시

  • 낮은 자료형으로 맞출 시 : 낮은 자료형으로 강제 형변환
  • 높은 자료형으로 맞출 시 : 높은 자료형으로 자동형변환
반응형

 

 

정수끼리의 자동 형변환 

   
● 점점 더 큰 자료형으로 데이터를 옮겨도 문제 없이 자동 형변환 처리 된다.
byte bnum = 1;
short snum = bnum;
int inum = snum;
long lnum = inum; 
● 연산 시에도 자동으로 큰 쪽 자료형에 맞춰서 계산한다. 
int num1 = 10;
long num2 = 20;
● int result1 = num1 + num2;(X)
자동으로 큰 자료형인 long으로 변경 후 계산하기 때문에 int에 담을 수 없다.
long result1 = num1 + num2;
int -> long 변환을 자동 수행 후 연산한다.

 

 

 


실수끼리의 자동 형변환 
 

float fnum = 4.0f;
double dnum = fnum;
● 연산 시에도 자동으로 큰 쪽 자료형에 맞춰서 계산한다. 
//float result2 = fnum + dnum;(X)
double result2 = fnum + dnum;

 

 

 

 

정수는 실수로 자동 형변환 된다

 

  • 정수를 실수로 변경할 때 소수점 자리수가 없어도 실수 형태로 표현이 가능(자동 형변환) 
  • 정수는 실제 값을 저장하는 매커니즘을 가진 것과 달리 실수는 지수부와 가수부를 따로 나눠서 작성하기 때문에
    바이트 크기보다 훨씬 더 많은 값을 표현할 수 있음.

 

long eight = 8;
float four = eight;

float result3 = eight + four;
System.out.println("result3 : " + result3); // 실수 연산 정수 = 실수

 

 

 

 

문자형은 int형으로 자동 형변환 된다. 

 

char ch1 = 'a';
int charNumber = ch1;

System.out.println("charNumber : " + charNumber);

● char가 가지는 범위 안의 정수는 char형 변수에 기록 가능하다.
char ch2 = 65;
System.out.println("ch2 : " + ch2);

 

 

 

 

논리형은 형변환 규칙에서 제외된다.
    
  • 어느 자료형이든 boolean을 형변환해서 담을 수 없다.

강제 형변환

 


  • 바꾸려는 자료형으로 캐스트 연산자를 이용하여 형변환 함.
              ex) (바꿀자료형) 값; 
  • 자동형변환 규칙의 반대 상황에서 강제 형변환이 필요함. 
  • 큰 자료형에서 작은 자료형으로 변경 시 강제 형변환이 필요함.
  •  논리형은 강제 형변환 규칙에서도 제외됨

 

 

정수끼리의 강제 형변환 
 

long lnum = 8L;
//int inum = lnum; 데이터 손실 가능성을 컴파일러가 알려준다 (에러 발생)

● 변경하려는 자료형을 명시하여 강제 형변환 해야 한다
int inum = (int)lnum; 
short snum = (short)inum;
byte bnum = (byte)snum;

 

 

실수끼리의 강제 형변환 

    
double dnum = 8.0;
float fnum = (float)dnum;

 

 

 

 

실수를 정수로 변경 시 강제 형변환 

 

float fnum2 = 4.0f;
long lnum2 = (long)fnum2;
float는 4byte, long은 8byte임에도 자동 형변환 불가능(소수점 자리 이하 데이터 손실 가능성)

 

 

 

문자형 강제 형변환
   
  • 문자형은 int미만 크기의 변수에 저장할 때 강제 형변환이 필요
 char ch = 'a';
 byte bnum2 = (byte)ch;
 short snum2 = (short)ch;

같은 2byte인데 강제 형변환 해야하는 이유는? 부호 비트로 인한 값의 범위가 다르기 때문

 



 

● 다른 자료형끼리의 연산은 큰 자료형으로 자동 형변환 후 연산 처리 된다. 
    int inum = 10;
    long lnum = 100;

  방법 1.

   두 수의 연산 결과를 int형으로 변환 후 int 자료형 변수에 리턴 받는다. 
               int isum = (int) (inum + lnum);
 방법 2.

    long 형 값을 int로 강제 형변환 한다. 
              int isum2 = inum + (int) lnum;
 방법 3.

    결과 값을 long형 자료형으로 받는다. (자동 형변환 이용)
              long lsum = inum + lnum;

● 주의! int 미만의 연산의 처리 결과는 int형이다.
byte byteNum1 = 1;
byte byteNum2 = 2;
short shortNum1 = 3;
short shortNum2 = 4;

//byte result1 = byteNum1 + byteNum2;
int result1 = byteNum1 + byteNum2; // byte + byte => int
//short result2 = shortNum1 + shortNum2;
int result2 = shortNum1 + shortNum2; // short + short => int



 

  • 데이터 손실에 유의해서 사용해야 한다.
1. 의도하지 않은 데이터 손실 
int inum = 290;
byte bnum = (byte) inum;

System.out.println("inum : " + inum);
System.out.println("bnum : " + bnum); 비트 앞부분 손실로 예측하기 어려움

2. 의도한 데이터 손실 
double height = 173.5;
int floorHeight = (int) height;

System.out.println("height : " + height);
System.out.println("floorHeight : " + floorHeight); 소수점 절삭에 이용할 수 있다.



반응형