[javascript] 컴퓨터가 실수를 표기하는 방법과 한계

c0zyb1ue·2022년 8월 27일
0

javascript 공부

목록 보기
2/3

고정소수점 (Fixed-Point Number Representation)


32비트 기준, 부호비트(양수면 0, 음수면 1)과 소수점 기준으로 정수부 소수부로 나뉘어 다음과 같이 할당된 비트에 저장된다.

예를 들어 21.25라는 숫자는 이진법으로 나타내면 10101.01이고 이는 이렇게 저장된다.

양수이기 때문에 부호비트는 0이고 정수부와 소수부에 각각 숫자 10101과 01이 저장된 후 남은 공간은 0으로 채워진다.


부동소수점 (Floating-Point Number Representation)


#### 32비트 기준, 부호비트와 지수부 가수부로 나뉘어 다음과 같이 할당된 비트에 저장된다.

지수부는 정규화 시 아래와같이 n이라는 값에(음수일 때도 표현하기 위해) bias(지수편향)을 더한 후 이진수로 변환한 값이 저장된다.

R=±m×2^n 

m은 1.XXXX의 형태
n은 R을 m으로 만들 때 소수점을 이동한 칸 수
bias= 2^(지수부분의 총 비트수 - 1) - 1

32비트일 때 지수부분은 8비트, 
bias=2^(8-1)-1=127 
-> 총 저장가능한 수 2^총 비트수=256개, 0~126일 때 음수, 127일때 0, 128~255일 때 양수

가수부는 정규화된 표현식 R에서 소수점의 오른쪽 부분이다. 소수점 왼쪽은 무조건 1이기 때문에 따로 저장하지 않는다.

예를 들어 21.25, 이진법으로 10101.01가 부동소수점 방식으로 저장될 때 다음과 같이 저장되고 남은 부분은 0으로 채워진다.

1.010101x2^4으로 나타낸 후,
010101이 가수부에 해당,
n=4, bias=127
n+bias=131을 2진수로 변환한 10000011가 지수부에 해당

◾️ 부동소수점의 의의

고정 소수점의 경우는 정수부, 소수부로 나뉘기 때문에 정수부가 32bit 기준 11비트가 넘어가면 저장할 수 없다. 최대 저장가능한 정수의 크기가 2^11-1=1023이다.

부동소수점의 경우 정수 부분이 훨씬 큰 수라도 정규화한 후 지수를 저장하기 때문에 충분히 저장 가능하다.


부동 소수점 오류

자바스크립트는 배정밀도 64비트 부동소수점 방식을 따른다.

자바스크립트에서의 0.1+0.2의 결과값은 0.3이 아니다.

> 0.1+0.2
> 0.30000000000000004

이유는 0.1을 2진법으로 바꾸면 0.00011001100...으로 순환소수가 나오게 된다.

이를 정규화해서 저장해도 가수부분에 저장할 수 있는 한계는 52비트이기 때문에 0.1이 그대로 저장될 수 없다. 즉, 52번째 값은 53번째에서 반올림 한 값이 되고 결과적으로 저장되는 값은 0.1에 가까운 근사값이 된다.

- 해결책 -

다음과 같은 함수

numObj.toFixed([digits])
Math.round(x)

다음 링크를 참고
https://madplay.github.io/post/the-need-for-bigdecimal-in-java

0개의 댓글