https://velog.io/@dorito/2022.8.20-토요일-공부기록 에서 분리한 내용입니다
참고사이트: https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
유튜브를 보는데 재밌는 영상을 봤다.
console.log(1.1 + 0.1 === 1.2); false
나온다 함
이걸 이해하기 위해서는
컴퓨터는 기본적으로 01010101101010101011100101 .... 을 대책없이 덧셈연산만을 하는 존재라는 것을 알아야한다. (컴퓨터 구조를 알아야 한다) (
AND
,OR
,XOR
연산)
가장 와닿게 알 수 있는 부분이, 마인크래프트에서의 레드스톤이다.
레드스톤은 단순히 스위치로 끄고 켤 수 있는 01만 출력할 수 있는데, 그 레드스톤으로 이런 식으로 구현이 가능하다.
심지어는 레드스톤만으로 1Hz Redstone Computer를 만든 사람도 있다...
아무튼!!!! 다시 주제로 돌아와서
일단 Floating number
는 rational number를 유한개의 수로 나타내기 위한 규약 (예: 파이)이다.
만약 8bit로 5
를 나타낸다면 -> (101)
00000101
5.125
를 나타낸다면 -> 101.0001(2) float
로 나타내는데
(fraction 부분을 mantissa 라고도 한다)
5.125 -> 101.001(2) 으로 바꿔준 후
101 = 1.01 x 10²인 것 처럼
1.01001 x 2²(2) 으로 바꿔준다.
그러면 초록색 영역(Fraction, 23bit)에 소숫점 아래 숫자(01001)를 저장하고, 노란색 영역(Exponent, 8bit)에 지수 2에다 127을 더한 만큼(10000001)을 적어준다.
0.5 (= 1/2), 0.25 (= 1/4), 0.125 (= 1/8) 인 소수 같은 경우에, 2진수로 숫자를 나타내는 컴퓨터는 편안해 하겠지만
10진법으로 0.1
은 1/10, 즉 약수 2와 5로 이뤄진 수이기 때문에 부동소수점 산술에서 10 × 0.1이 정확히 1과 같지 않게 만든다. 한마디로 근사치로 계산한다. (수치해석)
숫자를 한없이 정밀하게 표현할 수 있겠지만 숫자 하나에 32bit만큼만 할당하는 float는 오차를 감안하고 범위에 들어온 만큼 자른다.
따라서 부동소수점 오차가 발생하는 것이다.
정밀도는
float
in C++double
in C++(8bit = 1 byte)
1/3은 0.3333333... 3으로 무한으로 이어진다고 알지만
무한 소수는 모든 메모리 공간을 쓰고도 표현을 할 수가 없기 때문에
컴퓨터는 어느 순간 마지막 3을 끊고 특정값으로 설정해야 할 필요가 있다.
따라서 특정 시점으로 끊기는 그 수와 수 사이의 간격을 Machine Epsilon(머신 입실론)이라고 한다.
크롬 콘솔창을 열고 Number.EPSILON를 입력해보면
크롬의 자바스크립트 기준으로 머신 입신론 값은 2.220446049250313e-16 가 나온다.
동작 원리만 잘 알고있으면 됨!
자료형 별 나타낼 수 있는 수의 범위~
+0
-0
차이-> Negative zero by IEEE 754 representation in binary32
You can think of zero as a denormalized number (an implicit leading 0 bit) with all 0 fraction bits. Note that −0 and +0 are distinct values, though they both compare as equal.
참고하면 좋을 사이트:
IEEE Standard 754 Floating Point Numbers
위키피디아: Signed zero
https://stackoverflow.com/questions/28949774/what-is-0-0-by-ieee-floating-point-standard