자바에서 소수의 계산시에 값이 3.02 + 1.06 = 4.08 이렇게 정확하게 떨어지지 않고

3.0800003 이런식으로 나오는 경우가 있다.

 

이는 자바의 소수점 계산방식 때문이다.

 

각종 프로그래밍 언어에서는 소수를 표현할 때 IEEE 754 부동 소수점 방식으로 소수를 표현하게 되는데,

java에서도 이 방식으로 소수를 계산한다.

 

 

 

🔎부동소수점(floating point) 방식

 

실수를 컴퓨터상에서 근사하여 표현할 때

소수점의 위치를 고정하지 않고 위치를 나타내는 수를 따로 적는 방식

유효숫자를 나타내는 가수와 소수점의 위치를 풀이하는 지수로 나누어 표현

 

컴퓨터에서는 고정 소수점 방식보다 넓은 범위의 수를 나타낼 수 있어 많이 이용되지만, 근삿값으로 표현되며, 비교적 연산 속도가 느리다.

 

 

 

고정소수점과는 다르게 정수 부분과 소수 부분의 자릿수가 일정하지 않으나, 유효 숫자의 자릿수는 정해져 있다.

고정 소수점 방식 부동 소수점 방식
정확, 범위가 좁다. 정확도가 떨어짐(근사치 제공) , 범위가 넓다.

 

 

 

 

 

🔎IEEE 754 부동 소수점 방식

IEEE 754 부동소수점 표현에서 숫자는 부호부, 지수부, 가수부의 세 부분으로 구성되며,

각 부분의 역할과 사용하는 비트 수는 다음과 같다.

 

  • 부호부 (1비트) : 부호를 표시, 양수일 때는 0, 음수일 때는 1
  • 지수부 (부호가 없는 정수, 8비트) : 지수를 나타냄
  • 정규화된 가수부 (부호가 없는 정수, 23비트) : 가수, 유효숫자를 나타냄. 제일 앞의 비트는 정규화되었으므로 1이다.

 

 

 

 

−8.04 (십진법)을 IEEE 754 (32비트 단정밀도)로 표현해 보자.

  • 음수이므로, 부호부는 1이 된다.
  • 그 다음, 절댓값을 이진법으로 나타내면 -1000.00001010001111010111000010100011110101110000101이 된다. (이진기수법을 참조)
  • 지수는 3이므로, Bias를 더해야 한다. 32비트 IEEE 754 형식에서는 Bias는 127이므로 3+127 = 130이 된다. 이진법으로 변환하면 0000010이 된다.
  • 가수부는 1.00000001010001111010111000010100011110101110000101의 소수부분으로, 크기는 23bit다. 모자란 뒷 부분은 0을 채운다.

       가수부(fraction): 00000001010001111010111

 

 

부동소수점 표기: 11000001000000001010001111010111

 

 

 

 🔎BigDecimal

 

따라서 Java에서 정확한 소수 계산을 하고 싶다면 소수점을 보정해주는 BigDecimal을 사용해주자!

Bic Decimal은 숫자가 아닌 문자열 타입이므로 선언도 문자 타입으로 넣어주어야 하고, Integer처럼 사칙 연산이 불가능하다. 따라서 내부적으로 정의되어 있는 메서드를 통해 사칙 연산을 수행한다.

 

 

 

📌선언 및 초기화

BigDecimal num = new BigDecimal("value"); //value는 숫자가 아닌 문자 타입으로 넣어줘야 한다

 

 

📌BigDecimal 을 이용한 사칙연산

 

더하기 num1.add(num2);
빼기 num1.subtract(num2));
곱하기 num1.multiply(num2));
나누기 num1.divide(num2));

 

 

 

 

 

📝참고한 자료

https://ko.wikipedia.org/wiki/%EB%B6%80%EB%8F%99%EC%86%8C%EC%88%98%EC%A0%90

https://t.hi098123.com/IEEE-754

https://codetorial.net/articles/floating_point.html

https://wakestand.tistory.com/202

 

복사했습니다!