부동소수점수란?
- 자바를 포함한 대부분의 시스템에서 실수를 저장하는데 부동소수점 방식을 사용합니다. 부동소수점수는 부호(Sign), 지수(Exponent), 기수(Mantissa) 세 부분으로 이루어지며 모든 수를 ±M x 2^E의 형식으로 저장합니다.
자바에서는 flaot형 32bit, double형 64bit의 저장공간을 가집니다.
ex) - 예를 들어 10진수 9.1234567(10)를 float형식으로 저장한다고 하면 9.1234567(10) = 1001.000111111001101011011011...(2)로 변환합니다. 그리고 2진수 1001.000111111...을 1.xx로 시작하는 형식이 되도록 소수점을 당겨옵니다. 그러면 앞으로 3칸 당겨왔으니까 1.00100011111100110101101... x 2^3이 되겠죠. 이러한 형식으로 바꾸는 것을 정규화라고 하고
3을 지수부(E)에 00100011111100110 101101을 가수부(M)에 저장합니다. 소수점 앞의 1은 실수는 항상 1.으로 시작하기 때문에 제외합니다. 가수부는 해당하는 부분을 저장공간만큼 잘라 그대로 저장합니다. 여기서 지수부는 부호있는 정수를 저장하는 방식으로 저장해야 합니다. 0.01101과 같은 숫자는 1.101 x 2^(-2)과 같은 형식으로 저장해야 할테니 말이죠. 그래서 저는 당연히 정수형을 저장할 때처럼 2의 보수법을 사용하는 줄 알았더니 기저법(offset - binary)라는 방식을 사용하더군요.
부호있는 정수를 표현하는 방법
2진 체계에서 부호있는 정수를 표현하는 방법은
- 부호화 절대값
- 1의 보수법
- 2의 보수법
- 기저법(offset - binary)
이 있으며 여기서 가장 효과적인 방법은 2의 보수법과 기저법입니다. 2의 보수법은 1의 보수법을 취한 뒤(비트 반전) 1을 더해서 n bit로 -2^(n-1) ~ 2^(n-1) 범위의 숫자를 표현하는 방식입니다. 기저법은 저장할 때 기저값을 더했다가 읽어올 때 빼오는 형식입니다. 위의 3을 저장하려면 기저값인 127을 더해 130을 2진수로 10000010을 저장하게 됩니다. 반대로 읽어올 때는 127을 빼 3을 읽어옵니다.
기저법을 사용하게 되면 부호와 지수를 모두 고려하여 비교하는 것이 아니라, 단순히 비트 패턴을 비교함으로써 빠르게 비교연산을 수행할 수 있고, 부동소수점 수의 덧셈과 뺄셈 연산에서 특정한 비트 연산이 필요한데, offset binary 방식은 이러한 연산을 간편하게 수행할 수 있게 합니다. 이러한 이유 때문에 지수를 저장하고 읽어올 때 기저법을 사용합니다.
틀린 부분이 있으면 지적해주시면 감사하겠습니다.
'개발 > Java' 카테고리의 다른 글
[Java] 지네릭스(generics) (0) | 2024.05.25 |
---|---|
[Java] 인터페이스(Interface) (0) | 2024.05.15 |
[Java] 오토 박싱 & 오토 언박싱 (1) | 2024.02.27 |
[Java] hashCode와 equals 오버라이드(hashCode는 주소값이 아니다.) (1) | 2023.12.16 |