不!模算法

问题描述

所以,根据我在互联网上阅读的内容,模数可以做到这一点:

(a*b) % n = (a % n * b % n)%n;

我明白这是因为 a%n * b%n 可能比 n 大,所以我们必须再次取模 n。但我没有得到 n! mod p.来自互联网的算法:

int result = 1;
for (int i = 1 ; i <= n ; i++)
{
   result = (result * i ) % p;
}
cout<<result;
  Let's say n = 3,and p is 7.
When i = 1,result = 1 % 7,when i = 2,result = (1%7 * 2) % 7,and when i = 3,result =((1%7*2) % 7 * 3) % 7.

我真的看不出我的第一个语句和这个结果之间有什么联系。From what i see,for n = 2,n! % 7 should be (1 % 7 * 2 % 7 ) % 7,not as the algorithm would do it:(1 % 7 * 2 ) % 7. 我知道算法是正确的,但我遗漏了一些东西......有人可以帮助我吗?

解决方法

在数学上它们是相同的,但计算机表示数字的位数有限,如果超过该限制,您将得到意想不到的结果。

看下面的例子:

假设可以存储的最大值是 200,并且您想要计算 X * Y % 100

让我们为 XY 尝试一些值:

  1. X = 103 and Y = 98 ==> 3 * 98 > 296 OVERFLOW
  2. X = 103 and Y = 103 ==> 3 * 3 > 9 OK

在情况 2 中,如果在相乘之前取两者的模数,则会得到低于 200 的结果。但如果只取一个变量,则将得到 309 % 200,但 309 将成为一些扭曲的值,因为类型最多只能表示 200 个。

在第 1 种情况下,您将不得不想出另一种策略(可能是更大的类型或将乘法转换为和),因为乘法的结果会推断出 200 的限制。