(참고 : 여기에 이진수를 나타 내기 위해 'b'를 추가하겠습니다. 다른 모든 숫자는 십진수로 표시됩니다)
사물을 생각하는 한 가지 방법은 과학적 표기법과 같은 것입니다. 우리는 6.022141 * 10 ^ 23과 같은 과학적 표기법으로 표현 된 숫자를 보는 데 익숙합니다. 부동 소수점 숫자는 가수와 지수와 비슷한 형식을 사용하지만 10 대신 2의 거듭 제곱을 사용하여 내부적으로 저장됩니다.
가수와 지수를 사용하여 61.0을 1.90625 * 2 ^ 5 또는 1.11101b * 2 ^ 101b로 다시 쓸 수 있습니다. 10을 곱하고 (소수점 이동) 다음을 수행 할 수 있습니다.
(1.90625 * 2 ^ 5) * (1.25 * 2 ^ 3) = (2.3828125 * 2 ^ 8) = (1.19140625 * 2 ^ 9)
또는 가수와 지수를 바이너리로 사용하십시오.
(1.11101b * 2 ^ 101b) * (1.01b * 2 ^ 11b) = (10.0110001b * 2 ^ 1000b) = (1.00110001b * 2 ^ 1001b)
우리가 숫자를 곱하기 위해 무엇을했는지 주목하십시오. 우리는 가수를 곱하고 지수를 추가했습니다. 가수가 2보다 크게 끝나기 때문에 지수를 부딪쳐 결과를 정규화했습니다. 십진 과학 표기법으로 숫자에 대한 작업을 수행 한 후 지수를 조정하는 것과 같습니다. 각각의 경우에, 우리가 작업 한 값은 이진수로 유한 표현이되었으므로 기본 곱셈과 덧셈 연산으로 출력 된 값도 유한 표현으로 값을 생성했습니다.
이제 61을 10으로 나누는 방법을 생각해 봅시다. 가수를 1.90625와 1.25로 나눕니다. 십진수로, 이것은 짧은 숫자 인 1.525를 제공합니다. 그러나 바이너리로 변환하면 어떻게됩니까? 정수 십진수를 이진수로 변환하는 것처럼 가능한 한 항상 2의 최대 거듭 제곱을 빼는 일반적인 방법으로 수행하지만 2의 음의 거듭 제곱을 사용합니다.
1.525-1 * 2 ^ 0-> 1
0.525-1 * 2 ^ -1-> 1
0.025-0 * 2 ^ -2-> 0
0.025-0 * 2 ^ -3-> 0
0.025-0 * 2 ^ -4-> 0
0.025-0 * 2 ^ -5-> 0
0.025-1 * 2 ^ -6-> 1
0.009375-1 * 2 ^ -7-> 1
0.0015625-0 * 2 ^ -8-> 0
0.0015625-0 * 2 ^ -9-> 0
0.0015625-1 * 2 ^ -10-> 1
0.0005859375-1 * 2 ^ -11-> 1
0.00009765625 ...
어 오. 이제 우리는 곤경에 처했습니다. 1.90625 / 1.25 = 1.525는 이진수로 표현할 때 반복되는 분수입니다. 1.11101b / 1.01b = 1.10000110011 ... b 우리 기계에는 가수를 담을 비트가 너무 많기 때문에 분수를 반올림합니다. 특정 지점을 넘어 0을 가정합니다. 61을 10으로 나누면 나타나는 오류는 다음과 같습니다.
1.100001100110011001100110011001100110011 ... b * 2 ^ 10b
, 즉 :
1.100001100110011001100110b * 2 ^ 10b
이 가수의 반올림은 부동 소수점 값과 연관된 정밀도의 손실로 이어집니다. 가수가 정확하게 표현 될 수있는 경우에도 (예를 들어, 두 개의 숫자를 더할 때) 지수를 정규화 한 후 가수가 너무 많은 숫자를 필요로하는 경우 숫자 손실이 발생할 수 있습니다.
우리는 실제로 소수를 관리 가능한 크기로 반올림하고 처음 몇 자리 숫자를 줄 때 항상 이런 종류의 일을합니다. 결과를 십진수로 표현하기 때문에 자연 스럽습니다. 그러나 소수점을 반올림 한 다음 다른 기준으로 변환하면 부동 소수점 반올림으로 인해 발생하는 소수점과 같이보기 흉하게 보일 것입니다.