大家好,又见面了,我是你们的朋友全栈君。
抛开高级语言的实现,取余运算和取模运算本身并不完全一致,区别在于对负整数进行取商时操作不同。虽然这样说,但是取余运算和取模运算的公式都一样。对于x和y两个整数(int),通过以下两个操作获取余数或模数:
step1、求商:int z = x / y
step2、求余数或模数:int result = x – y * z
它们的差别在于,如果z的值是负数且不为整数(如果z为整数,那么余数和模数都为0了嘛)时,该怎么取整,比如z == -1.33,那么z取整的结果是 -1 还是 -2 的区别;如果为正数则没有区别。所以我们只需要注意,x和y异号,且x不被y整除的情况。
先给出规则,如果z小于0,且z不为整数(即x没有被y整除),那么:
如果是取余:那么z朝0方向取整,即:-1.33 => -1
如果是取模:那么z朝负无穷方向取整,即:-1.33 => -2
举个例子:x = -4,y = 3,x / y = -1.33…
如果是取余:那么z = -1,result == -4 – 3 * (-1) == -1
如果是取模:那么z = -2,result == -4 – 3 * (-2) == 2
所以大家不要再把取余和取模混为一谈啦!在Java中,%是取余数,取模的操作是:Math.floorMod,我们可以看一下Java的取模操作是怎么实现的(以下为java源码,只是我加上了注释):
/**
*计算 x - z
*/
public static int floorMod(int x, int y) {
int r = x - floorDiv(x, y) * y;
return r;
}
/**
* 计算z
*/
public static int floorDiv(int x, int y) {
//这里其实是强转操作,是朝0方向取整的
int r = x / y;
if ((x ^ y) < 0 && (r * y != x)) {
//如果x和y异号且x/y不是整数(也就是x没有被y整除),那么将r-1返回
//由于r在上一步已经朝0方向取整了,将r-1就实现了朝负无穷方向取整
r--;
}
return r;
}
注:不同的语言,对于%运算符的含义可能是不一样的,比如c、c++、java 为取余,而python为取模
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/131177.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...