TIL/JAVA

[TIL] JAVA에서 0.1을 100번 더하면 왜 10이 아닐까? (JAVA)

Dream COM Ddulut 2024. 11. 11. 23:34

오늘 프로그래밍 1주차 강의를 듣는데 강사님께서 이런 질문을 던지셨다.

" float는 4byte만 쓰는데 어떻게 long 보다 더 넓은 범위를 표현 가능한가요?

해답은 간단하다 정수와는 다르게 실수는 '부동소수점'을 사용하기 때문이다.

 

🟡 부동소수점이란? - IEEE 754 표준 기반

부동소수점은 2진수를 사용해 소수를 표현한다.

그중  IEEE 754 표준을 따르는 단정도 부동 소수점은 32bit로 구성되며, 구조는 아래와 같다.

  • 부호비트: 1bit
  • 지수: 8bit (바이어스 127를 사용. 지수+127해서 2진수로 변환해야함)
  • 가수(유효 숫자): 23bit

 

 

🟡 2진수로 표현할 수 없는 소수

계산 방법은 따로 검색해보면 나오기도 하고, 여기서는 계산방법이 중요한게 아니기 때문에 생략하겠다.

여튼 여기에서의 핵심은 프로그램에서 소수 역시 2진수로 표현하며, 2진수로 정확하게 표현할 수 없는 소수들이 존재한다는 것이다.

 

2진수로 정확하게 표현할 수 없는 소수 중 하나가 바로 0.1이다.

0.1은 이진 부동소수점으로 표현하면 무한소수가 된다.

그리고 JAVA의 float 타입은 해당 값을 근사치로 저장한다. 

 

0.1을 IEEE 754 표준 단정도 부동소수점으로 표현하면 다음과 같은 값이 나온다(근사치임).

0.1 뒤에 작은 오차들이 있는게 보이는가?

저 오차들의 누적으로 인해 float 타입의 0.1을 100번 더해도 정확히 10이 나오지 않는다. 

코드 실행결과는 아래와 같다. 

 

 

float 타입의 0.1을 100번 더해도 정확히 10이 나오지 않는 것을 확인할 수 있다.

 

double 타입으로 해도 마찬가지다. 다만 double은 float과 다르게 단정도가 아닌 배정도 형식을 사용하기 때문에 값이 조금 다르다.

 

 

 

이렇게 JAVA에서 0.1을 100번 더해도 10이 나오지 않는 이유를 알아보았다.