#지식 #알고리즘 우리가 쓰는 컴퓨터에서는 0.1×0.1의 결과는 0.01이 아닙니다. 어째서 그런것인지 한번 알아보겠습니다. 참고한 기술문서 IEEE 754 Floating point standard people.eecs.be... www.doc.ic.ac.... 영상제작에 도움이 된 컨버터 Binary Decimal Converter Online www.rapidtable...
대략 맞지만, 약간의 오해를 막기 위해서.. 0.1×0.1의 결과는 0.01가 되지 않는 건 float의 숫자 표현방식의 문제점입니다. 그런데 영상에서는 실수(=real number)을 이산치숫자(=digital??)로 대치해서 사용할 경우에 위험성(=실수와의 불일치)과 float의 숫자 표현방식의 위험성이 조금 모호하게 섞여 있어서 보시는 분들이 오해하실까봐 걱정이 됩니다. 현실의 정수는 ... -2, -1, 0, 1,2 ... 등으로 숫자의 간격의 최소값이 1로 고정되어 있어서 이걸 표현하기 위한 컴퓨터의 숫자가 int입니다. 컴퓨터에서 int는 -2,147,483,648 ~ 2,147,438,647 숫자를 의미하며 최소 bit의 변화가 정수 1의 변화를 뜻합니다. 따라서 현실의 정수와 컴퓨터의 int는 표현할 수 있는 값의 크기에서만 차이가 있을 뿐 기본적으로는 같습니다. 하지만 현실의 실수(=Real Number)는 좀 어렵습니다. 실수는 정수처럼 크기도 무한이지만, 0 ~ 0.1 사이에도 무한개의 실수가 있습니다. 즉 숫자 간격이 무한소입니다.(=아날로그??!!) 이런 경우 고정된 bit 갯수로 모든 실수를 표현할 방법이 마땅하지 않습니다. 그래서 컴퓨터 기술자들이 약간의 트릭을 가한 것이 float입니다. int를 구성하는 bit는 정말 단순한 2진 숫자일 뿐이지만이지만, float를 구성하는 bit는 부호+지수부+가수부로 복잡하게 구성됩니다. float의 최소bit의 변화는 지수부의 값에 따라 이진수 1000000이 될수도 이진수 0.0000001이 될 수 있습니다. 이렇게 최소bit의 크기가 가변하는(=소수점의 위치가 가변하는) 방식이라서 부동소수점이라고 부르기도 합니다. 하지만 이런 방식에는 약간의 문제가 있는데, float값과 실수값과 같지 않고(=비슷함) float를 연산(+-*/등등)의 결과도 일치하지는 않는 다는 겁니다. 실제로 0.1은 제 컴퓨터에는 float로 표현하면 0.100000001입니다. 이미 이 값은 0.1이 아닙니다. 게다가 0.01은 0.00999999978로 0.01도 아니며, 더욱 이상하게도 0.1*0.1의 연산결과는 0.0100000007입니다. 이게 현재 컴퓨터에서 쓰고 있는 float에 한계입니다. 그래서 프로그래머는 float값 == float값 같은 일을 잘 하지 않습니다(뭐 사실 0.0 == float값 은 자주 합니다만..) 또한 11.0000000001, 11.0000000002 같은 수를 사용하지 않습니다. 이 값의 중요 정보가 소숫점 작은 값에 몰려 있다면 대략 아주 위험한 일이 발생합니다. 0.1×0.1의 결과는 0.01가 되지 않는 건 float의 숫자 표현방식의 문제점입니다. 만일 숫자의 단위를 m(=1/1000)으로 정하고, 0.1*0.1을 100mili*100mili = 10mili로 표현하고 각 값을 int로 쓰면 아무런 에러가 없습니다. 즉 0.1×0.1 != 0.01 인 이유는 float의 오류이지 진법의 오류는 아닙니다.
깔끔한 설명 감사합니다. 공부하면서 머지시발? 하고 넘어갔던 부분인데 정리가 잘되어있네요. 한줄요약 사람이 1/3을 소수점으로 표현 못하듯 컴퓨터는 1/10을 소수점으로 표현할 수가 없는데, 연산 효율성을 위해 32!자리 이후를 짜르다보니 짤린거 두개를 곱한 값이 우리가 아는 값과는 다르당.
재밌게 설명해 주셔서 감사합니다~~~ 무한소수를 저렇게 말씀하시는 군요. 저도 비슷하게 말하는데.... ㅋㅋㅋㅋㅋㅋㅋㅋㅋ 그나저나, 처음 Smalltalk 에서 Fraction, 즉 Rational 형 보고서는 깜짝 놀랐습니다. 오, 이렇게 아예 분수로 계산하고 필요할 때만 소수로 변환하는 방법도 있구나 싶어서요. 물론 어차피 변환할 때 오차가 발생하기는 하지만요. ^^
영상 너무 잘봤습니다 근데 질문이있어요 dev c++로 0.1x0.1이 0.01이 아니라는걸 구했는데 컴퓨터의 계산기에서는 0.1x0.1이 0.01이라고 나옵니다 dev c++은 이진법을 쓰고 컴퓨터 계산기는 십진법을 써서 그런건가요? 왜 같은 컴퓨터인데 c++로 코딩할때랑 계산기썼을때랑 결과가 다른건가요 ㅠㅠ
게임 좌표. OpenGL 쉐이더 정밀도. 은행 등등...? 은행이야 돈문제에 이자 계산이니까 오차가 있으면 오차가 점점 쌓이죠. 그러니 빅인티저나 빅 덱시멀, 문자열 같은걸 사용하기도하고... 게임 좌표같은건 == 연산 쓰면 절대안되궁... 현재 캐릭터가 위치한 곳의 좌표 숫자가 커지면 커질수록 물리엔진의 부정확도도 올라갑니다. 쉐이더같은경우 연산최적화를 위해 lowp같은걸로 정밀도 낮추면 좌표넘길때 텍스쳐 우그러들기도하고 등등등... 등등등등.... 너무많ㅇ앙...