负数取模运算
一、引例
System.out.println("3 % 5 = " + 3 % 5);
System.out.println("-3 % 5 = " + -3 % 5);
System.out.println("3 % -5 = " + 3 % -5);
System.out.println("-3 % -5 = " + -3 % -5);
3 % 5 = 3
-3 % 5 = -3
3 % -5 = 3
-3 % -5 = -3
规律
被除数是负数,则取模后符号也为负
被除数是正数,则取模后符号也为正
结果的符号与除数的正负号无关
二、整数除法问题
向上取整(Ceiling) 向X轴正方向取整,即取比实际结果稍大的数
比如:17 / 8 == 3, 8 / 3 == 3,-9 / 4 == -2向下取整(Floor) 向X轴负方向取整,即取比实际结果稍小的数
比如:17 / 8 == 2, 8 / 3 == 2,-9 / 4 == -3向零取整(Truncate) 向原点方向取整,即直接省略小数部分,取整
比如:17 / 8 == 2, 8 / 3 == 2,-9 / 4 == -2
三、取模通用公式
a % b = r
r = a - (a/b) * b
四、计算机语言差异性
C/Java
采用Truncate除法,即向零取整Python
采用Floor除法,即向下取整
五、Truncate除法的问题
在一些题目中,数组元素可能出现负数,这样导致取模的时候,会出现取整问题的歧义
在Java中,默认Truncate除法,为避免歧义可以使用:
1、使用Math.floorMod方法进行Floor除法
2、如在前缀和计算中,用
int modulus = (sum % K + K) % k;
而不用 sum % k,避免负数干扰结果