부동소수점 오차

매니·2022년 8월 25일
0

부동소수점의 문제에 대해서는 어느정도 알고 있었지만 CS50 수업도중 RAM 관련 얘기가 나와 작성해보고자 합니다.

1.1 + 0.1 == 1.2
> false

해당 수식은 파이썬 입니다.

너무나도 당연하게 1.1 + 0.1 == 1.2 라고 생각했지만 컴퓨터의 세계에서 이는 틀린 말입니다.

왜냐하면 컴퓨터는 숫자를 저장할때 2진법으로 저장하기 때문입니다.

2진법

이진법의 원리에 대해서 설명하는 글이 아니기때문에 어떻게 변환하는 지는 생략하겠습니다.

이진법은 0과 1로 이루어진 숫자 표시 방법이며,

10은 1010
8은 10101000 이런식으로 저장합니다.

그렇다면 1.1은 어떻게 저장할까요?

float를 기준으로,
부호비트(1bit) = 양수면 0, 음수면 1 저장
지수비트(8bit) = 지수 + 127 (127을 저장하는 이유는 뒤에 설명)
가수비트(23bit) = 맨앞의 1을 제외, 24번째 bit에서 반올림

하여 저장합니다.

즉, 만약 6.8이라는 숫자를 저장하고 싶다면
0.8을 빼고 6만 2진수로 변경해줍니다.

110을 따로 빼주고 0.8은 계속 2를 곱해줘서 1.0보다 크면 1 1.0보다 작으면 0을 넣어줍니다.

0.8 x 2 = 1.6 -> 1
0.6 x 2 = 1.2 -> 1
0.2 x 2 = 0.4 -> 0
0.4 x 2 = 0.8 -> 0
0.8 x 2 = 1.6 -> 1
0.6 x 2 = 1.2 -> 1

무언가 반복되는 느낌이 들지 않나요?
1100이 계속 반복됩니다.

6.8을 2진법으로 바꾸면 1.10110011001100 ... x 22

이것을 컴퓨터에 저장하기엔 저장 공간의 부족으로 일정공간 저장하다가 잘라버립니다.

그러니, 1.1이라는 숫자를 저장한다고 보여도 실제로는 비슷한 숫자를 저장하는 거죠.

그렇기때문에

1.1 + 0.1 == 1.2
> false

해당 수식이 성립하는 겁니다.

그렇다면 이것은 어떻게 해결하는게 좋을까요?

해결

  1. 정수로 변환해서 저장하기
  2. 반올림해서 사용하기
  3. 그냥 부동소수점으로 연산하는 일이 없도록 하기.. float 사용금지..

작은 내생각..

아직 공부하는 입장인지라 이 문제는 금융권에서 가장 크게 다가올 것 같은데, 이자율 2.1%를 21%로 저장하고 나중에 또 빼낼땐 2.1%라고 빼내야되는데 이건 어떻게 하지..?

정말 머리가 아프다.

결론, 되도록 소수점을 쓰지않도록 하자.. float..

profile
성장중 🔥

0개의 댓글