C++아니 빌더에서는 동일 우선 순위의 연산자가 연속 될때 오른쪽을 먼저 평가하는지 아니면 왼쪽을 먼저 평가하는지 모르지만 아래의 글이 평가 순서에 따라 도움이 될듯합니다. 프로그램에서 가끔 변수가 가질수 있는 값을 범위를 예측 가능한 경우가 있지요 그때 사용하시기 바랍니다.
결합 법칙의 경우는 왼쪽을 먼저 평가하나, 오른쪽을 먼저 평가하나, 중간을 먼저 평가하나 항상 결과가 같기 때문에 연산의 순서가 문제가 되지 않습니다.
아래의 덧셈과 뺄셈식을 보면
R = A+B+C+D-E-F-G+S
A+B……순으로 왼쪽에서 먼저 계산을 하나, S+G-F씩으로 오른쪽에서 먼저 계산하나, C+D, F-G ……씩으로 임의의 위치에서 계산을 해도 결과는 항상 동일하지요.
배부분의 컴파일러는 대체로 A+B+C……순으로 왼쪽을 먼저 평가하거나, S+G-F씩으로 오른쪽을 먼저 평가하거나 두가지 방법 중하나를 사용합니다. 물론 구현의 복잡성 때문이겠지요.
여기서는 왼쪽을 먼저 평가하는 컴파일러이며 각 변수는 최대 값 255, 최소값 -256범위의 값을 가져야 한다고 가정하고
다음과 같은 변수가 3개 있을때. 현재 A는 250의 값을 가지고 있으며, B는 50의 값을 가지고 있고, C는 -250값을 가지고 있다하면
R = A + B + C
= 250 + 50 + (-250)
앞의 부분을 평가하면서 300이 되어 버리므로 변수가 가질수 있는 최대값인 255를 넘어 버리므로 overflow가 발생합니다. 즉 평가가 되지 않는것입니다. 하지만 다음과 같이 연산순서를 바꾸면 아무런 문제가 없죠.
R = A + C + B
50 = 250 + (-250) + 50
앞쪽을 먼저 평가 했을때 결과가 0이 되어 버리므로 R = 50의 값을 가지게 됩니다.
프로그램을 만들다보면 변수의 값의 범위를 예측 할수 있는 경우가 가끔 있죠? 아마도 이런 최적화 방법과 컴파일러 수식의 결합 방향(법칙)을 알고 있다면 오류를 줄이는 한가지 길이 될것이다.
프로그래밍 언어론에 나오는 이야깁니다.
근대 가만히 생각 하니 곧 64비트 시대가 될것이고 좀더 있으면 128비트 시대가 될텐데.... 64비트만 되어도 가히 어마어마 한 수치인데 이런 최적화까지 알아야 할 필요가 있을까 싶군요....
가히 별로 도움이 안된다. 그지요...
그럼
|
다음 식과 같이
굉장히 큰수 나누기 또한 굉장히 큰수 계산을 위와같은식으로 한적이 있습니다.
Result = ( n ! * m ! ) / ( k! * p!)
n , m , k , p 가 모두 커서
foctorial 계산을 먼저 다 하면 이미 UNIT64의 범위를 초과하는 경우여서
foctorial 계산을 다 한후에 곱셈하고 나눗셈 할수가 없었죠
(문론 수학lib라던지.. 다른 방식을 이용해서 그렇게 할수도 있지만...)
그래서 분자와 분모에 공통된 인수를 제가해가면서 foctorial 연산을 한기억이....