模除

模除（modulo 有时也称作 modulus），又称模数、取模、取模运算等，它得出一个数除以另一个数的余数。给定两个正数：被除数formula_1和除数formula_2，formula_3（通常缩写为formula_4），得到的是使用欧几里得除法时的余数。formula_5所得之数被称为formula_1的小数部份。
举个例子：计算表达式formula_7得到formula_8，因为formula_9的商为formula_10而余数为formula_8；而formula_12得到formula_13，因为formula_14的商为formula_15而余数为formula_13；做除法不能整除时得到是有理数，平常使用的计算器采用了有限个数位的十进制表示法，它以小数点分隔整数部份和小数部份，比如formula_17。
虽然通常情况下模除的被除数formula_1和除数formula_2都是整数，但许多计算系统允许其他类型的数值运算，比如对浮点数取模。在所有计算系统中当被除数formula_1和除数formula_2都是正数时，结果的余数formula_22的范围为formula_23；而formula_24经常是未定义的，在编程语言里可能会导致除以零错误。当被除数formula_1或除数formula_2为负数时，不同的编程语言对结果有不同的处理。
各种定义.
在数学中，取模运算的结果就是欧几里德除法的余数。当然也有许多其他的定义方式。计算机和计算器有许多种表示和储存数字的方法，因此在不同的硬件环境下、不同的编程语言中，取模运算有着不同的定义。
几乎所有的计算系统中，formula_1除以formula_2得到商formula_29和余数formula_22均满足以下式子：
即使如此，当余数非formula_13时，余数的符号仍然是有歧义的：余数非formula_13时，它的符号有两种选择，一个是正号而另一个是负号。通常情况下，在数论中总是选择正余数。但在编程中，选择余数的符号依赖于编程语言和被除数formula_1或除数formula_2的符号。在编程语言所定义的整数模除中，ISO/IEC标准Pascal
A term of the form codice_1 shall be an error if codice_2 is zero; otherwise, the value of codice_1 shall be such that
where the value shall be zero if codice_5; otherwise, the sign of the value shall be positive if codice_6 and codice_2 have the same sign and negative if codice_6 and codice_2 have different signs.
A term of the form codice_10 shall be an error if codice_2 is zero or negative; otherwise, the value of codice_10 shall be that value of codice_13 for integral codice_14 such that codice_15.
NOTE 2 — Only for codice_16 and codice_17 does the relation codice_18 hold.
</ref>和ALGOL 6810.2.3.3. Operations on integral operands
</ref>，在计算出的余数codice_19为负数时，返回正数formula_35作为结果；另一些编程语言如ISO/IEC C90，当被除数formula_1或除数formula_2是负数时，C90标准并没有做具体的规定，而是留给编译器去定义并实现
C99 reflects almost universal processor behavior (as does the Fortran Standard). This definition truncates toward zero and the expression codice_20 is always true. It also means that the absolute value of the result does not depend on the signs of the operands; for example:
C90
If either operand is negative, the behavior may differ between C90 and C99, depending on the implementation-defined behavior of the C90 implementation.
int main(void)
int x = -1,
y = +3;
if ((x%y > 0) ||
</syntaxhighlight>
Quoting from the C9X Revision Proposal, WG14/N613, that proposed this change:
</ref>。在大多数系统中formula_24是未定义的，虽然有些系统定义它就等于formula_1。更多详情参见后续章节表格。
记号.
一些计算器有取模按钮，很多编程语言里也有类似的函数，通常像codice_33这样。有些语言也支持在表达式内使用codice_30、codice_35或codice_36作为取模或取余操作符，比如codice_37或codice_38。
在一些没有函数的环境中或许可使用等价的：codice_39。这里的codice_40函数事实上等价于截断函数。
性质及恒等式.
一些取模操作，经过分解和展开可以等同于其他数学运算。这在密码学的证明中十分有用，例如：迪菲-赫尔曼密钥交换。
编程语言实现.
此外，很多计算机系统提供功能，它同时产生商和余数。例子x86架构的指令，C编程语言的函数，和Python的函数。
常见错误.
当取模的结果与被除数符号相同时，可能会导致意想不到的错误。
举个例子：如果需要判断一个整数是否为奇数，有人可能会测试这个数除 2 的余数是否为 1：
<syntaxhighlight lang="c++">
bool is_odd(int n) {
</syntaxhighlight>
但在一个取模结果与被除数符号相同的编程语言里，这样做是错的。因为当被除数 是奇数且为负数时， formula_57 得到 −1，此时函数返回“假”。
一种正确的实现是测试取模结果是否为 0，因为余数为 0 时没有符号的问题：
<syntaxhighlight lang="c++">
bool is_odd(int n) {
</syntaxhighlight>
或者考虑余数的符号，有两种情况：余数可能为 1 或 -1。
<syntaxhighlight lang="c++">
bool is_odd(int n) {
</syntaxhighlight>
性能问题.
可以通过依次计算带余数的除法实现取模操作。特殊情况下，如某些硬件上，存在更快的实现。
例如：2 的 n 次幂的模，可以通过逐位与运算实现：
例子，假定 为正数：
在进行位操作比取模操作效率更高的设备或软件环境中，以上形式的取模运算速度更快。
编译器可以自动识别出对 2 的 n 次幂取模的表达式，自动将其优化为 codice_45。这样可以在兼顾效率的情况下写出更整洁的代码。这个优化在取模结果与被除数符号一致的语言中（包括 C 语言）不能使用，除非被除数是无符号整数。这是因为如果被除数是负数，则结果也是负数，但 codice_45 总是正数，进行这样的优化就会导致错误，无符号整数则没有这个问题。