1.1 + 0.1 == 1.2(?)

Jayce·2023년 5월 29일
0

여담

목록 보기
3/9
post-thumbnail

오늘은 공부하는 도중에
MISRA-C: 2004 Rule 13.3 : Floating-point expressions shall not be tested for equality or inequality.
MISRA-C: 2004 코딩규칙 13.3 : 부동소수 표현은 같음/다름을 테스트해서는 안된다. (비교연산자 == 와 != 를 사용해서는 안된다.)를 보게되어 직접 실험해보았고,

1.1 + 0.1 == 1.2가 false라는 것에 대해 의문이 생겨 찾아보았습니다.


수학적 계산으로 보면 1.1 + 0.1 == 1.2가 맞습니다. 하지만 컴퓨터는 데이터를 ram에 저장하게 되는데 이 ram은 여러개의 bit칸으로 저장되어 1 또는 0 의 값으로 데이터를 생성하게 됩니다.
그렇기 때문에 값을 저장할 때는 2진법으로 바꾸어서 데이터를 저장하게 됩니다.

🔖정수 저장

예를 들어 10을 저장하고 싶다면

와 같은 방식으로 저장 되게 됩니다. 중요한것은 맨 앞 부분은 부호저장 공간으로 써 양수는 0 음수는 1로 저장됩니다.



🔖실수 저장

그렇다면 소수는 어떤식으로 작성해야 할지 알아보도록 하겠습니다.
예를 들어 5.125를 저장하고 싶다면 IEEE의 권장 방법에 따라

  • 5.125 => 101.001 => 1.01001 x 22
  • 1.011001 x 2^2 (5.125 2진수 버전)
    소숫점 우측부분은 mantissa라고 명칭하며 맨뒤 23칸의 bit에 저장하게 됩니다.

추후 2^2부분은 127+2 -> 10000001이 되어

파란 부분에 저장하게 됩니다. 이런 방식이 대표적으로 C언어의 float 방식입니다.

🔖순환소수

여기서 문제점은 0.1같은 소수는 0.00011001100110011...이 반복되게 되는데 숫자하나를 저장할 수있는 칸은 32개가 최대이기 때문에

와 같이 작성되고 뒤 숫자는 오버플로우를 막기위해 제거됩니다.
즉 0.1 같은 순환소누는 결국 0.1이 저장된것이아니는 0.1보다 적은 수가 저장된 것이기 때문에
1.1 + 0.1 == 1.2가 false가 나온다는 것을 이해 할 수 있었습니다.

🔖해결방법

해결 방법이라기 보다 최대한 처리하는 방법으로는

  • 돈을 예시로 1.1달러를 float가 아닌 1100센트로 저장함으로써 int함수를 사용하는 방법이 있습니다.
  • 반올림 문법을 사용합니다.
  • double 자료형 사용
    double은 칸을 64개 까지 사용할 수 있기 때문에 float에 비해 정확한 값이 나오지만 이 또한 결국은 65칸 부터는 제거되기 때문에 오차가 나옵니다. 또한 메모리 용량도 float 비해 2배로 사용하기 때문에 컴퓨터에 부담이 갑니다.

오늘은 공부를 하는 도중에 알게된 정보를 가져와 봤습니다.

😁 power through to the end 😁

profile
AI (ML/DL) 학습

0개의 댓글