java Overflow(오버플로우)
Overflow(오버플로우)
변수의 선언된 데이터 유형 범위를 벗어난 값을 할당 할때 발생한다.
Java에서는 계산 결과가 최댓값을 넘거나, 최솟값보다 작을 경우
음수는 양수로, 양수는 음수로 바뀌는 문제가 발생한다.
이를 오버플로우라고 한다.
정수형의 오버플로우
오버플로우 :
자료형이 표현할 수 있는 범위 중 최댓값을 벗어날 경우 발생한다.
최댓값 초과 시 -> 해당 타입의 최솟값으로 값이 순환한다.
예시코드
public static void main(String[] args) {
int value = 10;
int maxInt = Integer.MAX_VALUE;
System.out.println(value + 1);
System.out.println(maxInt + 1);
}
아래는 언더 플로우의 예시이다.
public static void main(String[] args) {
byte b = -128;
System.out.println(--b); // 출력값 : 127
}
대표적으로 자료형의 최대값에서 1을 더하면 최소값이 되고,
최소값에서 1을 빼면 최대값이 된다.
byte타입의 경우 맨왼쪽 1bit는 부호로 사용(2의 보수법을 이용해서 표현한다).
최대값이 127인데,여기서 1을 더하면 -128이된다.
2의 보수법
음수를 2진수로 표현하는 경우 2의 보수법을 통해 표현하는데,
2진수 값을 모두 반전시켜준 후 1을 더해주는 방식이다.
맨 왼쪽의 SignBit가 0이면 양수, 1이면 음수를 나타낸다.
ex) 양수 5를 2진수로 변환하면 00000101
컴퓨터에서 -5를 2진수로 표현하려면?
1. 반전시킨다 -> 11111010
2. 1을 더한다 -> 11111011
예를 들어 -128인 경우
128의 2진수 값 10000000
1. 반전시킨다 -> 01111111
2. 1을 더한다 -> 10000000
1바이트로는 표현할 수 없음.
이때 제일 왼쪽 비트가 1이면 음수 부호이므로, 10000000는 -128이 되고, 양수 128은 1byte로 표현할 수 없다.
실수형의 오버플로우
정수와 실수는 메모리 저장 방식이 다르다.
실수형은 정수형과 달리 '2의 보수법'을 사용하지 않고, 양의 실수를 음의 실수로 변경할 시 부호 비트만 바꾼다.
실수형의 오버 플로우
값이 음의 최소 범위 또는 양의 최대 범위를 넘어갔을 때 발생하며, 값은 무한대가 된다.
public static void main(String[] args) {
float f = Float.MAX_VALUE;
f*=2.2;
System.out.println(f); // 출력값 : Infinity
}
실수형의 언더 플로우
값이 음의 최대 범위 또는 양의 최소 범위를 넘어갔을 때 발생하며, 값은 0이 된다.
public static void main(String[] args) {
float f = Float.MIN_VALUE;
f /=2; // 2로 나누면 자리수를 초과하여 Underflow 발생
System.out.println(f); // 출력값 : 0.0
}
다음은 int타입과 float 타입의 내부 구조이다.
실수의 저장형식
1. 고정 소수점 방식
고정 소수점 방식은 소수부의 자리를 정하여 고정된 자릿수의 소수를 표현한다.
따라서 제한된 자릿수로 인하여 표현 가능한 실수의 범위와 정밀한 정도가 제한적이라 잘 사용하지 않는다.
2. 부동 소수점 방식
실수를 부호부(sign), 가수부(Mantissa), 지수부(Exponent)로 나눈다.
고정 소수점으로 나타낸 상태에서 부동 소수점으로 바꾸려면
2진수를 1.xxxxx X 2^n의 형태로 변환하면 된다.
예를들어
10진수의 소수 7.625를 2진수의 고정 소수점으로 표기하면
111.101이 된다.
여기서 비트를 밀어서 1.11101 X 2^2 의 형태로 바꾸고, 소수점 이후 숫자열 전체를 가수부에 기록하고 부족한 비트는 0으로 채운다.
지수부에는 지수인 2에 bias 127을 더하고 2진수로 변환한다.
정리하면 실수7.625는 부동 소수점 방식으로 표현 시 0 10000001 11101000000000000000000가 된다.
지수부
IEEE 754 부동 소수점 표준에서 지수(exponent)는 bias를 사용하여 표현된다.
bias는 지수를 양수로 만들어 저장할 수 있도록 하는 방식이다.
실제 지수에 bias를 더해 저장한다. 저장된 값을 읽을 때는 바이어스를 빼서 실제 지수를 얻는다.
이 과정을 통해 부동 소수점 수의 지수부분이 항상 양수로 유지된다.
- 단정도(single precision, 32비트) 부동 소수점 형식의 지수는 8비트, bias는 127이다. (2^(8-1)-1)
- 배정도(double precision, 64비트) 부동 소수점 형식의 지수는 11비트, bias는 1023이다. (2^(11-1)-1)
참고
https://velog.io/@steadygo247/Java%EC%98%A4%EB%B2%84%ED%94%8C%EB%A1%9C%EC%9A%B0Overflow
[Java]오버플로우Overflow
오버플로우를 너무 잘나타내는 짤 Overflow (오버플로우) : 메모리의 표현 범위에서 벗어난 수의 값을 저장하는 경우 Underflow (언더플로우) : 메모리가 표현할 수 있는 수보다 적은 수의 값을 저장하
velog.io
https://stackoverflow.com/questions/14129017/java-and-unsigned-values
Java and unsigned values
I'm parsing unsigned bits from a DatagramSocket. I have a total of 24bits (or 3 bytes) coming in - they are: 1 unsigned 8bit integer followed by a 16bit signed integer. But java never stores anything
stackoverflow.com