프로그래밍2011. 4. 14. 20:13
프로그래밍 언어에서 나머지 연산을 할 때 결과가 세 종류 이상 있다.
편의상 p = q * n + r의 표기를 따르자. p가 피제수, n이 제수, q가 몫, r이 나머지.

http://en.wikipedia.org/wiki/Modulo_operation
위키에는 truncated division, floored division, Euclidean definition 방식을 설명하고 있다. 이것이 일반적으로 사용되는 용어인지는 불확실하다. 아무튼 간략하게 요약하면,
방식 q sgn(r)
Truncated round toward zero sgn(p)
Floored round toward negative infinity sgn(n)
Euclidean \(\mathop{\mathrm{sgn}}\nolimits(n) \left\lfloor \frac{p}{\left|n\right|} \right\rfloor\) \( \geq 0 \)
 
그리고 toward positive infinity는 쓰는 경우가 있는지 모르겠다.

개인적으로는 floored division 또는 Euclidean definition 방식이 수학적으로 아름답다고 느끼지만 --- 사실 다른 사람도 그렇게 주장한다. --- 프로그래밍 언어에서는 그냥 truncated division 방식을 쓰는 경우가 많다. 자세한 것은 위키를 읽어보자.

C 언어에서 2로 나누는 것을 floored division으로 하고 싶으면, arithmetic shift를 써야 하는데, 문제는 C 언어에서 음수에 대한 >>가 implementation defined이다. 그래서 컴파일러가 >>를 어떻게 처리하는지 알아야 하는 경우가 있다.
http://stackoverflow.com/questions/1597704/verifying-that-c-c-signed-right-shift-is-arithmetic-for-a-particular-compiler
헐, 크기가 음수인 array를 만들어서 컴파일 에러를 발생시키다니 천재적인 방법인 듯. 이런 식으로도 compiler time assert가 가능하구나. 하지만 문제가 하나 있는데, __LINE__이 치환되지 않고 그냥 __LINE__으로 들어간다는 것이다. 이 문제는 글을 새로 작성했다. (http://noexists.tistory.com/183)
#define RIGHT_SHIFT_IS_ARITHMETIC \
    ( (((signed int)-1)>>1) == ((signed int)-1) )
MY_STATIC_ASSERT(RIGHT_SHIFT_IS_ARITHMETIC);
Posted by asdfzxcv