模除

red 商數 () 和 lightgreen 餘數 () 作為被除數 () 的函數時的圖像。左側是除數為正的情況，右側除數為負。從上至下分別使用了：向零取整、向下取整和歐幾里得除法。
模除（modulo 有時也稱作 modulus），又稱模數、取模、取模運算等，它得出一個數除以另一個數的餘數。給定兩個正數：被除數和除數，（通常縮寫為），得到的是使用歐幾里得除法時的餘數。所得之數被稱為的小數部份。
舉個例子：計算表達式得到，因為的商為而餘數為；而得到，因為的商為而餘數為；做除法不能整除時得到是有理數，平常使用的計算器採用了有限個數位的十進制表示法，它以小數點分隔整數部份和小數部份，比如。
雖然通常情況下模除的被除數和除數都是整數，但許多計算系統允許其他類型的數值運算，比如對浮點數取模。在所有計算系統中當被除數和除數都是正數時，結果的餘數的範圍為；而經常是未定義的，在編程語言裡可能會導致除以零錯誤。當被除數或除數為負數時，不同的編程語言對結果有不同的處理。

**各種定義**
在數學中，取模運算的結果就是歐幾里德除法的餘數。當然也有許多其他的定義方式。計算機和計算器有許多種表示和儲存數字的方法，因此在不同的硬件環境下、不同的編程語言中，取模運算有著不同的定義。
幾乎所有的計算系統中，除以得到商和餘數均滿足以下式子：
即使如此，當餘數非時，餘數的符號仍然是有歧義的：餘數非時，它的符號有兩種選擇，一個是正號而另一個是負號從數學上講，正和負只是滿足不等式的無窮多個解中的兩個。。通常情況下，在數論中總是選擇正餘數。但在編程中，選擇餘數的符號依賴於編程語言和被除數或除數的符號。在編程語言所定義的整數模除中，ISO/IEC標準Pascal
A term of the form i div j shall be an error if j is zero; otherwise, the value of i div j shall be such that
abs(i) - abs(j) 
where the value shall be zero if abs(i) ; otherwise, the sign of the value shall be positive if i and j have the same sign and negative if i and j have different signs.
A term of the form i mod j shall be an error if j is zero or negative; otherwise, the value of i mod j shall be that value of (i - (k * j)) for integral k such that 0 .
NOTE 2 — Only for i >= 0 and j > 0 does the relation (i div j) * j + i mod j = i hold.
和ALGOL 6810.2.3.3. Operations on integral operands
……
，在計算出的餘數r為負數時，返回正數作為結果ISO Pascal要求模除運算的除數n為正數。；另一些編程語言如ISO/IEC C90，當被除數或除數是負數時，C90標準並沒有做具體的規定，而是留給編譯器去定義並實現
C99 reflects almost universal processor behavior (as does the Fortran Standard). This definition truncates toward zero and the expression (-(a/b) == (-a)/b) && (-(a/b) == a/(-b)) is always true. It also means that the absolute value of the result does not depend on the signs of the operands; for example:
+10 / +3 == +3 +10 % +3 == +1 -10 / +3 == -3 -10 % +3 == -1+10 / -3 == -3 +10 % -3 == +1 -10 / -3 == +3 -10 % -3 == -1
C90
When integers are divided and the division is inexact, if both operands are positive the result of the / operator is the largest integer less than the algebraic quotient and the result of the % operator is positive. If either operand is negative, whether the result of the / operator is the largest integer less than or equal to the algebraic quotient or the smallest integer greater than or equal to the algebraic quotient is implementation-defined, as is the sign of the result of the % operator. 
If either operand is negative, the behavior may differ between C90 and C99, depending on the implementation-defined behavior of the C90 implementation.

#include 
int main(void)
{
int x = -1,
y = +3;
if ((x%y > 0) 
((x+y)%y == x%y))
printf("This is a C90 translator behaving differently than C99\n");
}
Quoting from the C9X Revision Proposal, WG14/N613, that proposed this change:
The origin of this practice seems to have been a desire to map C’s division directly to the “natural” behavior of the target instruction set, whatever it may be, without requiring extra code overhead that might be necessary to check for special cases and enforce a particular behavior. However, the argument that Fortran programmers are unpleasantly surprised by this aspect of C and that there would be negligible impact on code efficiency was accepted by WG14, who agreed to require Fortran-like behavior in C99.
。在大多數系統中是未定義的，雖然有些系統定義它就等於。更多詳情參見後續章節表格。

**記號**
一些計算器有取模mod()按鈕，很多編程語言裡也有類似的函數，通常像mod(a, n)這樣。有些語言也支持在表達式內使用%、mod或Mod作為取模或取餘操作符，比如a % n或a mod n。
在一些沒有mod()函數的環境中或許可使用等價的：a - (n * int(a/n))。這裡的int()函數事實上等價於截斷函數。

**性質及恆等式**
一些取模操作，經過分解和展開可以等同於其他數學運算。這在密碼學的證明中十分有用，例如：迪菲-赫爾曼密鑰交換。- 恆等式：
*** 對所有的正數  有：
** 如果  是一個質數，且不為  的因數，此時由費馬小定理有：- 逆運算：
** .
**  表示模反元素。當且僅當  與  互質時，等式左側有定義：。- 分配律：
*** 除法定義：僅當式子右側有定義時，即 、 互質時有：，其他情況為未定義的。- 乘法逆元：.

**編程語言實現**
此外，很多計算機系統提供divmod功能，它同時產生商和餘數。例子x86架構的IDIV指令，C編程語言的div()函數，和Python的divmod()函數。

**常見錯誤**
當取模的結果與被除數符號相同時，可能會導致意想不到的錯誤。
舉個例子：如果需要判斷一個整數是否為奇數，有人可能會測試這個數除 2 的餘數是否為 1：
bool is_odd(int n) {
return n % 2 == 1;
}
但在一個取模結果與被除數符號相同的編程語言裡，這樣做是錯的。因為當被除數 n 是奇數且為負數時，  得到 −1，此時函數返回“假”。
一種正確的實現是測試取模結果是否為 0，因為餘數為 0 時沒有符號的問題：
bool is_odd(int n) {
return n % 2 != 0;
}
或者考慮餘數的符號，有兩種情況：餘數可能為 1 或 -1。
bool is_odd(int n) {
return n % 2 == 1 
n % 2 == -1;
}

**性能問題**
可以通過依次計算帶餘數的除法實現取模操作。特殊情況下，如某些硬件上，存在更快的實現。
例如：2 的 n 次冪的模，可以通過逐位與運算實現：
 x % 2n == x & (2n - 1)
例子，假定 x 為正數：
 x % 2 == x & 1
 x % 4 == x & 3
 x % 8 == x & 7
在進行位操作比取模操作效率更高的設備或軟件環境中，以上形式的取模運算速度更快。
編譯器可以自動識別出對 2 的 n 次冪取模的表達式，自動將其優化為 expression & (constant-1)。這樣可以在兼顧效率的情況下寫出更整潔的代碼。這個優化在取模結果與被除數符號一致的語言中（包括 C 語言）不能使用，除非被除數是無符號整數。這是因為如果被除數是負數，則結果也是負數，但 expression & (constant-1) 總是正數，進行這樣的優化就會導致錯誤，無符號整數則沒有這個問題。

**用途**
 取模運算可用於判斷一個數是否能被另一個數整除。對 2 取模即可判斷整數的奇偶性；從 2 到  取模則可判斷一個數是否為質數。- 進制之間的轉換。- 用於求取最大公約數的輾轉相除法使用取模運算。- 密碼學中的應用：從古老的凱撒密碼到現代常用的RSA、橢圓曲線密碼，它們的實現過程均使用了取模運算。

**參見**
 模 (消歧義)和模 (術語) —— “模數（Modulo）”這個詞的許多用法，都是 1801 年卡爾·弗里德里希·高斯引入模算數時產生的。- 模冪運算- 同餘

**腳註**

**參考文獻 ==