如何解决在C#中求解模
我在用C#解决模数时遇到麻烦。下面的例子
db.collection.aggregate([
{
$match: {
$expr: {
$gt: [
{
$arrayElemAt: [
"$plusdmi",-1
]
},{
$arrayElemAt: [
"$minusdmi",-1
]
}
]
}
}
}
])
在Wolfram Alpha上返回正确的 15 。在 c#中,当我尝试直接进行操作时:
7^-1 modulo 26
它返回不需要的 1/7 % 26
而不是所需的0.142857142857143
。
但是我不是数学大师,所以我可能缺少一些重要的东西。
解决方法
您正在寻找模逆:如果是
7**-1 modulo 26 = x
或
1 / 7 modulo 26 = x
您实际上想找出一个x
,这样
(x * 7) modulo 26 = 1
在我们的情况下,x == 15
自
15 * 7 == 105 == 26 * 4 + 1
对于小 modulo
值(如26
),您可以借助 naive 来找到答案(15
)。 for
循环:
int modulo = 26;
int div = 7;
int result = 0;
for (int i = 1; i < modulo; ++i)
if ((i * div) % modulo == 1) {
result = i;
break;
}
Console.Write(result);
通常,您可以借助Extended Euclid Algorithm获得result
。通常,在使用模算术时,我们面临着巨大的数字,这就是为什么让我展示BigInteger
的代码;如果不是您的情况,可以将BigInteger
改成旧的int
。
代码:
using System.Numerics;
...
private static (BigInteger LeftFactor,BigInteger RightFactor,BigInteger Gcd) Egcd(this BigInteger left,BigInteger right) {
BigInteger leftFactor = 0;
BigInteger rightFactor = 1;
BigInteger u = 1;
BigInteger v = 0;
BigInteger gcd = 0;
while (left != 0) {
BigInteger q = right / left;
BigInteger r = right % left;
BigInteger m = leftFactor - u * q;
BigInteger n = rightFactor - v * q;
right = left;
left = r;
leftFactor = u;
rightFactor = v;
u = m;
v = n;
gcd = right;
}
return (LeftFactor: leftFactor,RightFactor: rightFactor,Gcd: gcd);
}
反演本身将是
private static BigInteger ModInversion(BigInteger value,BigInteger modulo) {
var egcd = Egcd(value,modulo);
if (egcd.Gcd != 1)
throw new ArgumentException("Invalid modulo",nameof(modulo));
BigInteger result = egcd.LeftFactor;
if (result < 0)
result += modulo;
return result % modulo;
}
演示:
using System.Numerics;
...
BigInteger result = ModInversion(7,26);
Console.Write(result);
结果:
15
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。