对常见取模运算规则的总结。
Intro
给定整数和,在几乎所有的编程语言中,都符合以下条件:
但是,这还不足以严格地定义——其符号仍然是未知的。不同的编程语言中亦有不同的决定符号的方法,本文对这些方法稍做总结。
Truncated Division
一种常见的方法是通过:
来定义,其中把一个数的小数部分直接丢弃掉,即向0取整。注意到:
故若非0,则其符号总是和相同。
Floored Division
此时容易验证,若非0,则其符号总是和相同。
Euclidean Division
此时,总是非负的。这一定义比较符合我们的常识——数论中一般也是这样约定的。
Implement FD/ED with TD
C/C++等语言提供的%运算符是按Truncated Division定义的,但我们常常需要另外两种取模语义,因此需要对其进行转换:
int floor_div_rem(int a, int b)
{
int r = a % b;
if((r > 0 && b < 0) || (r < 0 && b > 0))
r += b;
return r;
}
int euclidean_div_rem(int a, int b)
{
int r = a % b;
if(r < 0)
{
if(b > 0)
r += b;
else
r -= b;
}
return r;
}