截断除法与负数取模
在计算机中,整数a对整数b取模的结果为r = a - trunc(a/b)。显然,取模的结果依赖于trunc的定义。
主流的trunc定义有两种:向下取整(记为trunc_down)和向0取整(记为trunc_zero)。主要区别在被操作数是负数时的行为。例如trunc_down(-3.1) = -4,trunc_zero(-3.1) = -3。
当a和b都是正整数时,两种定义的取模结果都符合直觉,与小学学习的余数运算相同。但是当a和b不全为正整数时,取模运算便超出了小学学习的余数运算,两种定义的取模结果也不尽相同。
两种运算的结果示例如下。
a |
b |
trunc_down(a/b) |
a%b |
trunc_zero(a/b) |
a%b |
|---|---|---|---|---|---|
| 11 | 5 | 2 | 1 | 2 | 1 |
| 11 | -5 | -3 | -4 | -2 | 1 |
| -11 | 5 | -3 | 4 | -2 | -1 |
| -11 | -5 | 2 | -1 | 2 | -1 |
trunc_zero的规律很好记,即r = sign(a)(abs(a) % abs(b))。
对于trunc_down,当a和b同号时,规律与trunc_zero相同;当a和b异号时,r = sign(b)(abs(b) - abs(a) % abs(b))。
Python采用trunc_down模式,C/C++采用trunc_zero模式。

浙公网安备 33010602011771号