Developer/JAVA

JAVA , 값의 치환 / 기본자료형의 wrapper Class / 언더플로우 오버플로우

단님 2024. 7. 19. 23:12
728x90
값의 치환

 

대입하는 순간 그 값이 바뀌어 버림으로 인해, 중간 보관을 위한 같은 타입의 임시 변수가 필요하다.

String cup1 = "사이다", cup2 = "콜라";

 

사이다와 콜라의 값을 바꾸어 보자.

String temp = cup1;

 

사이다의 값을 임시변수에 저장.

		cup1 = cup2;
		cup2 = temp;

 

콜라를 사이다에 , 사이다에 임시변수(콜라) 값을 대입.

 

- 결과 확인

	String cup1 = "사이다", cup2 = "콜라";
	System.out.println("cup1은 "+cup1+"cup2는 "+cup2);
	String temp = cup1;
	cup1 = cup2;
	cup2 = temp;
	System.out.println("cup1은 "+cup1+"cup2는 "+cup2);

 


기본 자료형의 Wrapper Class

 

기본 자료형을 지원해주는 클래스를 의미한다.

모든 기본자료형에는 지원해주는 클래스가 있고 , 해당 클래스 명은 기본자료형의 첫글자를 대문자로 하면 나옴.

 

 

* 정수형 자료형

byte의 wrapper class : Byte

short의 wrapper class : Short

int 의 wrapper class  : Integer

long의 wapper class : Long

	System.out.println("정수형의 값의 범위");
	System.out.println("byte = "+Byte.MIN_VALUE+"~"+Byte.MAX_VALUE);
	System.out.println("short = "+Short.MIN_VALUE+"~"+Short.MAX_VALUE);
	System.out.println("int = "+Integer.MIN_VALUE+"~"+Integer.MAX_VALUE);
	System.out.println("long = "+Long.MIN_VALUE+"~"+Long.MAX_VALUE);

 

- 결과

 

* 실수형 자료형

float 의 wrapper class : Float

double 의 wrapper class : Double

System.out.println("실수형의 값의 범위");
System.out.printf("float = %f ~ %f \n", Float.MIN_VALUE, Float.MAX_VALUE);
System.out.printf("double = %f ~ %f \n", Double.MIN_VALUE, Double.MAX_VALUE);

 

 

자료형의 오버플로우와 언더플로우

 

정수형 자료형인 short 의 자료형으로 가장 작은값과 큰값을 넣어보고 그값을 더하거나 빼보자.

 

short sMax = Short.MAX_VALUE;
short sMin = Short.MIN_VALUE;

값들을 printf를 통해 찍어서 확인해 보자.

 

	System.out.printf("sMax 는 %d , sMin 은 %d \\n", sMax,sMin);
	System.out.printf("오버 플로우 : sMax 는 %d , sMax+1 은 %d \\n", sMax, (short)(sMax+1));
	System.out.printf("언더 플로우 : sMin 는 %d , sMin-1 은 %d \\n", sMin,(short) (sMin-1));

위는 더해주거나 빼면서 short 로 변환을 일으켰다.

System.out.println("short의 연산결과 int형으로 형변환");
System.out.printf("오버 플로우 : sMax 는 %d , sMax+1 은 %d \n", sMax,(sMax+1));
System.out.printf("언더 플로우 : sMin 는 %d , sMin-1 은 %d \n", sMin,(sMin-1));
System.out.println();

위의 결과는 적혀있긴 하지만 , 일반적으로 더하거나 빼주었다.

결과를 보며 설명하겠다.

 

자바의 산술연산은 short, byte , char 타입이 자동으로 int 변환을 일으키며 연산이 수행되기 때문에,

일반적인 연산은 int 형으로 그 값을 담기 때문에 오버플로우나 언더플로우가 발생하지 않는다.

그러므로 short 형의 오버플로우와 언더플로우를 보기 위해서는 short 타입으로 강제 형변환을 한다면

그 값이 최대값의 오버플로우시 최소값으로 변경이 되고 , 

최소값의 언더플로우시 최대값으로 변경이된다.

 

이부분은 이진법연산의 자리수 변경으로 인한 값의 변경인데

이진수로 표현된 최대값은

0111 1111 1111 1111 이고 , 여기에 1을 더하면

1000 0000 0000 0000 이 된다

가장왼쪽 비트는 부호 비트로 사용되고 0은 양수를 1은 음수를 나타내게된다.

즉 , 1000 0000 0000 0000 은 -32,768 임으로 오버플로우 발생시 short 의 최소값인 -32,768 이 된다.

언더플로우는 반대로 1000 0000 0000 0000 에서 1을 뺀 결과가 되기 때문에 최대값이 되는 것이다.

 

아래의 사진을 보면 이해가 쉽다.

 

 

 

실수형의 특수 값

 

무한대 : 숫자가 매우커서 표현할 수 있는 범위를 벗어날 때 발생한다.

 

1. 실수의 오버플로우 : 양의 무한대

실수의 양수값을 나눌때 발생한다.

float f = 1234.5678f; System.out.println(f / 0); // 결과 : Infinity

 

2. 실수의 언더플로우 : 음의 무한대

실수의 음수값을 0으로 나눌때 발생한다.

 float f = -1234.5678f; System.out.println(f / 0); // 결과 : -Infinity

 

3. 무한대의 연산

무한대와 다른숫자 또는 무한대를 연산하면 그 결과 여전히 무한대 또는 NaN 이 될 수 있다.

Infinity + 1은 Infinity

Infinity - Infinity는 NaN

 

4.NaN

자바의 NaN 는 숫자가 아닌 값을 의미하고 , 실수형 현산에서 정의되지 않는 연산 결과를 나타낸다.

float zero = 0.0f;
float f = 1234.5678f;
System.out.println("0 나누기 0: " + (zero / zero)); // 결과 : NaN
System.out.println("실수형 f, by Zero test1 나머지 (f%0):" + (f % 0));  // NaN

 

*정리

 

  • 양수를 0으로 나누는 경우
    • 결과는 양의 무한대(positive infinity).
    • 예: float a = 1234.5678f; float result = a / 0;
    • 출력: Infinity
  • 음수를 0으로 나누는 경우
    • 결과는 음의 무한대(negative infinity).
    • 예: float a = -1234.5678f; float result = a / 0;
    • 출력: -Infinity
  • 0을 0으로 나누는 경우
    • 결과는 NaN(Not a Number).
    • 예: float a = 0.0f; float result = a / 0;
    • 출력: NaN
  • 나머지 연산에서 0으로 나누는 경우
    • 결과는 항상 NaN.
    • 예: float a = 1234.5678f; float result = a % 0;
    • 출력: NaN
  • 즉, 실수에서 0으로 나누거나 나머지 연산에 주의해야할 것이다.