안녕하세요. wrong time no see. 이번 시간에는 부동 소수점 연산에서 분배 법칙이 성립하지 않는 데이터를 만들어 보고자 해요. 먼저 결론부터 보여주는 것이 속 편하겠군요.

 

 


 a가 1.5이고, b는 1.0 + 1/2^52, c는 1/2^52입니다. 이 때, a(b+c)와 ab + ac의 값이 다르게 나옵니다. 더 정확하게 말하면, ab + ac를 계산하는 과정에서 오차가 생깁니다. 결과 값으로 나온 d와 e의 비트 표현을 보겠습니다.

 

 

 어랏? 다르다는 것을 한 번에 알 수 있어요. 왜 다를까요? 하나 하나 tracing을 해 봅시다.

 

 


 먼저 b, c, b+c를 보겠습니다.

 

 

 b, c, b+c를 비트로 표현하면 요래 되는데요. 먼저, 011 1111 1111과 011 1100 1011은 52만큼 차이남을 알 수 있어요. 다음에 b+c를 보면 지수 부분이 011 1111 1111임을 알 수 있는데요. 이는 지수 부분을 맞춰준 것입니다. 2번째 실수를 보면, 1번째하고 지수가 52만큼이 차이나는데요.

 

 

 지수를 맞춰주기 위해서 이러한 과정을 거칩니다. 1.0에 2^(e-52)를 곱한 거나 1/(2^52)에 2^e를 곱한 것과 별반 다를 게 없으니까요.

 

 

 그러면 b+c가 왜 이런 값이 나오는지 이해가 될 겁니다. 지수를 맞춰주는 과정에서 1.x에서의 .x에 1/2^52가 추가된 것이기 때문입니다. 다음에 a와 b+c, a(b+c)를 보겠습니다.

 

 

 비트로 나타내면 요래 되는데요. 이건 또 어떻게 된 걸까요? 이것도 생각해 보면 그리 어렵지 않아요. 일단 1.x 부분부터 보겠습니다. 보면 a의 1.x 부분은 1 + 1/2이고 b+c의 1.x 부분은 1 + 1/2^51입니다. a의 1.x 부분과 b의 1.x 부분을 곱해 봅시다. 그러면, 1 + 1/2 + 1/(2^51) + 1/(2^52)가 나옵니다. 이 중 .x 부분은 1/2 + 1/(2^51) + 1/(2^52) 부분입니다. 여기에 1을 더한 값이 1보다는 크거나 같고, 2보단 작습니다.

 

 따라서, 이 부분만 .x 부분에 표시됩니다. 다음에 지수 부분은 a와 b+c가 모두 2^0입니다. 따라서 지수 부분은 0이 됩니다.

 

 


 ab + ac는 어떨까요? 똑같이 해 봅시다. 먼저 a, b, ab의 값을 보겠습니다.

 

 

 먼저 a는 1 + 1/2이였고 b는 (1 + 1/2^52)였습니다. 이 둘을 곱하면, 1 + 1/2 + (1/2^52) + (1/2^53)입니다. 위의 결과에서는 .x 부분이 1/2 + 1/2^51로 표시되어 있긴 합니다만, 1/2^53이 double 정밀도에서는 표현이 안 되다 보니 정확하지 않은 값이 툭 튀어나와버립니다. 여기서 게임이 끝났다고 보시면 됩니다. 다음에 a, c, ac 부분을 보겠습니다.

 

 

 a는 1.5였고, c는 1/2^52였습니다. 따라서 ac의 값은 1.5에다가 1/2^52를 곱한 값입니다. .x 부분에 1/2만 표시되어 있다는 것을 보면 알 수 있습니다. 다음에 ab, ac, ab + ac를 보겠습니다.

 

 

 ab는 1번째 줄에, ac는 2번째 줄에 있고, ab+ac는 3번째 줄에 있어요. 여기서 중요한 것은 b에 비해 c가 매우 작기 때문에, ab에 비해 ac 또한 매우 작다는 것입니다. ab의 지수와 ac의 지수가 무려 52만큼이나 차이가 남을 볼 수 있어요. 그러면 이것들을 맞추어 주어야 할 텐데요.

 

 

 그림으로 그리면 이런 상황입니다. (1 + 1/2)에다가 2^(e-52)를 곱한 꼴입니다. 이것은 (1 + 1/2)/2^52에 2^e를 곱한 것과 같습니다. 문제는, 1/2에 1/2^52를 곱한 값인 1/2^53이 double 정밀도에서는 표현이 안 됩니다. 고로, 이 과정에서도 정확하지 않는 값이 나올 수 밖에 없어요.