我知道modulus(%)运算符计算除法的余数。我如何确定需要使用模运算符的情况?
我知道我可以使用模运算符来查看一个数字是偶数还是奇数,是质数还是合数,但仅此而已。我不经常考虑余数。我相信模运算符很有用,我想学会利用它。
我只是有问题识别模运算符适用的地方。在各种编程情况下,我很难看到问题并意识到“嘿!这里可以用除法的余数!”。
想象一下,你有一个已经过去的时间,单位为秒,现在想将其转换为小时、分钟和秒:
h = s / 3600;
m = (s / 60) % 60;
s = s % 60;
0 % 3 = 0;
1 % 3 = 1;
2 % 3 = 2;
3 % 3 = 0;
你看到它做了什么吗?在最后一步它回到了零。这可以用于以下情况:
检查 N 是否可被 M 整除(例如,奇数或偶数)或 N 是否是 M 的倍数。
设定一个特定值的上限,例如 3。
我将其用于进度条等标记大循环的进度。只有在循环的第n次或count%n == 0时才报告进度。
count & 0xff == 0
(你可以使用0xf或0xff或0xfff等数字,重要的是拥有一个在二进制中是一串连续1的数字)。 - Tobia当我需要限制一个数字为某个倍数时,我会使用它:
temp = x - (x % 10); //Restrict x to being a multiple of 10
等等。
最近我看到的一个使用案例是当您需要反转数字时。例如,将123456
变为654321
。
int number = 123456;
int reversed = 0;
while ( number > 0 ) {
# The modulus here retrieves the last digit in the specified number
# In the first iteration of this loop it's going to be 6, then 5, ...
# We are multiplying reversed by 10 first, to move the number one decimal place to the left.
# For example, if we are at the second iteration of this loop,
# reversed gonna be 6, so 6 * 10 + 12345 % 10 => 60 + 5
reversed = reversed * 10 + number % 10;
number = number / 10;
}
举例来说,您有一个X字节的消息,但在您的协议中,最大大小是Y,而且Y < X。尝试编写一个将消息拆分为数据包的小应用程序,您可能会遇到模数错误问题 :)
很多情况下,它是有用的。
如果你需要限制一个数字在某个范围内,可以使用模运算。例如,要生成一个介于0和99之间的随机数,可以这样写:
num = MyRandFunction() % 100;
MyRandFunction()
范围的除数,否则会生成不均匀的结果。(想象一下你想要在0 .. RAND_MAX*2/3
范围内获取随机数字。) - kennytm正如@jweyrich所说,包装值。当我有一个有限的列表并且想要在循环中迭代它时,我发现mod非常方便 - 就像一些UI元素(如图表系列)的固定颜色列表,其中我希望所有系列尽可能不同,但当我用完颜色时,只需从头开始。这也可以与模式一起使用,例如第二次出现红色时,它是虚线; 第三次,点状等 - 但是mod仅用于永远获得红色,绿色,蓝色,红色,绿色,蓝色。