65

我知道模数(%) 运算符计算除法的余数。如何确定需要使用模运算符的情况?

我知道我可以使用模运算符来查看一个数字是偶数还是奇数、素数还是复合数,但仅此而已。我不经常考虑余数。我确信模运算符很有用,我想学习利用它。

我只是在确定模运算符适用的位置时遇到问题。在各种编程情况下,我很难看到问题并意识到“嘿!除法的其余部分可以在这里工作!”。

4

19 回答 19

27

假设您有一个以秒为单位的经过时间,并且您想将其转换为小时、分钟和秒:

h = s / 3600;
m = (s / 60) % 60;
s = s % 60;
于 2010-04-09T16:57:48.873 回答
21
0 % 3 = 0;
1 % 3 = 1;
2 % 3 = 2;
3 % 3 = 0;

你看到它做了什么吗?在最后一步,它又回到了零。这可以用于以下情况:

  1. 检查 N 是否可以被 M 整除(例如,奇数或偶数)或 N 是否是 M 的倍数。

  2. 设置特定值的上限。在这种情况下 3。

  3. 获取数字的最后 M 位 -> N % (10^M)。
于 2010-04-09T17:08:20.693 回答
17

我将它用于进度条等,通过大循环标记进度。仅在循环中每 n 次或 count%n == 0 时报告进度。

于 2010-04-09T17:18:42.010 回答
12

我在将数字限制为某个倍数时使用过它:

temp = x - (x % 10); //Restrict x to being a multiple of 10
于 2010-04-09T16:59:42.367 回答
11
  • 包装值(如时钟)。
  • 为对称密钥算法提供有限域。
  • 位运算。

等等。

于 2010-04-09T17:08:29.743 回答
6

例子。您有 X 字节的消息,但在您的协议中,最大大小为 Y 且 Y < X。尝试编写将消息拆分为数据包的小型应用程序,您将遇到 mod :)

于 2010-04-09T16:57:02.017 回答
6

我最近看到的一个用例是当您需要反转一个数字时。所以这就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;
}
于 2017-02-14T19:46:21.580 回答
5

有很多有用的例子。

如果您需要将数字限制在一定范围内,您可以使用 mod。例如,要生成 0 到 99 之间的随机数,您可能会说:

num = MyRandFunction() % 100;
于 2010-04-09T16:57:20.037 回答
5

正如@jweyrich 所说,包装值。当我有一个有限列表并且我想在循环中迭代它时,我发现 mod 非常方便 - 就像一些 UI 元素的固定颜色列表,比如图表系列,我希望所有系列都不同,可能的程度,但是当我用完颜色时,就从头开始。这也可以与图案一起使用,这样第二次出现红色时,它就会变成虚线;第三次,点缀,等等 - 但 mod 只是用来得到红色,绿色,蓝色,红色,绿色,蓝色,永远。

于 2010-04-09T17:37:59.060 回答
4

任何时候你有除法并且想要以十进制以外的形式表示余数时,mod 运算符都是合适的。想到的事情通常是当你想用剩下的东西做一些人类可读的事情时。列出您可以放入桶中的物品数量并说“剩下 5 个”很好。

此外,如果您遇到可能会产生舍入错误的情况,则模除法很好。例如,如果您经常除以 3,您不想将 .33333 作为余数传递。通过余数和除数(即分数)是合适的。

于 2010-04-09T17:09:04.000 回答
4

模可用于将总分钟转换和拆分为“小时和分钟”:

小时 = 分钟 / 60

minutes_left = 分钟 % 60

在小时位中,我们需要去掉小数部分,这取决于您使用的语言。

然后我们可以相应地重新排列输出。

于 2014-08-02T21:51:16.123 回答
4

素数的计算

于 2010-04-09T16:57:42.130 回答
4

将线性数据结构转换为矩阵结构:其中a是线性数据的索引,并且b是每行的项目数:

row = a/b
column = a mod b

注意上面是简化的逻辑:a除法前必须偏移-1,结果必须归一化+1。

示例:(3 行,每行 4 行)

1  2  3  4    
5  6  7  8    
9 10 11 12 

(7 - 1)/4 + 1 = 2

7 is in row 2

(7 - 1) mod 4 + 1 = 3 

7 is in column 3

模数的另一个常见用途:按位散列一个数字。假设您想将年和月存储在一个六位数字 195810 中month = 195810 mod 100。从右数第三位的所有数字都可以被 100 整除,因此在这种情况下,余数是最右边的 2 位数字是 10。提取年份195810 / 100得出 1958。

于 2016-05-25T23:43:11.490 回答
3

如果出于某种疯狂的原因需要进行整数除法并得到小数,并且您无法将整数转换为支持小数除法的数字,或者如果您需要返回小数而不是小数,则模数也非常有用.

我将%用作模运算符

例如

2/4 = 0

在哪里做这个

2/4 = 0 and 2 % 4 = 2

所以你可能真的很疯狂,假设你想让用户输入一个分子和一个除数,然后将结果显示为一个整数,然后是一个小数。

whole Number = numerator/divisor
fractionNumerator = numerator % divisor
fractionDenominator = divisor

模除法有用的另一种情况是,如果您正在增加或减少一个数字,并且您希望将数字包含在某个数字范围内,但是当您到达顶部或底部时,您不想停下来。您想分别循环到列表的底部或顶部。

想象一个函数,你正在循环一个数组。

Function increase Or Decrease(variable As Integer) As Void
    n = (n + variable) % (listString.maxIndex + 1)  
    Print listString[n]
End Function

它是 n = (n + variable) % (listString.maxIndex + 1) 的原因是允许考虑最大索引。

这些只是我不得不在我的桌面应用程序编程以及机器人和仿真环境中使用模数的一些事情。

于 2010-04-09T17:13:08.237 回答
2
  • 计算最大公约数
  • 判断一个数是否是回文数
  • 确定一个数字是否仅包含...
  • 确定有多少……一个数字由……组成
于 2010-04-09T17:49:47.427 回答
2

我见过的模数运算符的最佳用途是检查我们拥有的数组是否是原始数组的旋转版本。

A = [1,2,3,4,5,6] B = [5,6,1,2,3,4]

现在如何检查 B 是否是 A 的旋转版本?

第 1 步:如果 A 的长度与 B 的长度不同,那么它肯定不是旋转版本。

第 2 步:检查 A 在 B 中的第一个元素的索引。这里 A 的第一个元素是 1。它在 B 中的索引是 2(假设您的编程语言具有从零开始的索引)。让我们将该索引存储在变量“ Key ”中

第3步:现在如何检查B是否是A的旋转版本?

这就是模量函数摇摆不定的地方:

for (int i = 0; i< A.length; i++)
{

// here modulus function would check the proper order. Key here is 2 which we recieved from Step 2
   int j = [Key+i]%A.length;

   if (A[i] != B[j])
   {
     return false;
   }
}

return true;
于 2018-07-22T00:51:47.487 回答
2

我最喜欢的用途是迭代。

假设您有一个要递增的计数器,然后想从已知列表中获取相应的项目,但您只有n项目可供选择,并且您想重复一个循环。

var indexFromB = (counter-1)%n+1;

结果 ( counter=indexFromB) 给出n=3

`1=1`
`2=2`
`3=3`
`4=1`
`5=2`
`6=3`
...
于 2016-10-17T16:49:37.463 回答
1

这是判断一个数字是偶数还是奇数的简单方法。只需做# mod 2,如果为0则为偶数,1为奇数。

于 2017-04-18T15:53:34.747 回答
1

通常,在循环中,您希望每第 k 次迭代执行一次操作,其中 k 为 0 < k < n,假设 0 是起始索引,n 是循环的长度。

所以,你会做这样的事情:

int k = 5;
int n = 50;
for(int i = 0;i < n;++i)
{
    if(i % k == 0)  // true at 0, 5, 10, 15..
    {
        // do something
    }
}

或者,您想将某些东西保持在一定范围内。请记住,当你取一个任意数字 mod 某物时,它必须产生一个介于 0 和那个数字 - 1 之间的值。

于 2020-08-29T19:00:32.587 回答