微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在C#中求解模

如何解决在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 举报,一经查实,本站将立刻删除。