有谁知道对位取模的更好方法吗?

Does anyone know a better way for modulo on bits?

我有 2 个大数,一个大约 4096 位,另一个 2048 位,存储在一个结构中:

 typedef uint32_t word;
 typedef struct BigNumber {
     word words[128];
 } BigNumber;

我必须对这些取模,我能想到的唯一方法是多次减去,但这需要一些时间。

有人知道更好的方法吗?

计算m%n:

modulus(m, n) {
  if (m < n) return m
  elif (m < (n<<1)) return m - n
  else return modulus((modulus(m>>1, n)<<1 + m&1), n)
}

你可以用 a 除以 b 得到整数 x。现在从 a 中减去 x 得到模数。使用任意除数,您将无法绕过除法。对于大除数,这可能比多次减法更快,但除法仍然很昂贵。

对于如此大的数字,您可能还必须手动实施除法算法。那里有一个,它同时产生 qoutient 和余数(模数),但我现在记不起它的名字了。

代码基于 @caf 我的更正。让 OP 编写 4 个辅助函数。

void BigNumber_Shift_Right(BigNumber *x);
void BigNumber_Shift_Left(BigNumber *x);
int BigNumber_Compare(const BigNumber *a, const BigNumber *b);
void BigNumber_SubtractEqual(BigNumber *a, const BigNumber *b);

void BigNumber_ModHalfSizeEqual(BigNumber *A, const BigNumber *B) {
  BigNumber X = *B;
  BigNumber AHalf = *A;
  BigNumber_Shift_Right(&AHalf);

  while (BigNumber_Compare(&X, &AHalf) <= 0) {
    BigNumber_Shift_Left(&X);
  }

  while (BigNumber_Compare(A, B) >= 0) {
    if (BigNumber_Compare(A, &X) >= 0) {
      BigNumber_SubtractEqual(A, &X); 
    }
    BigNumber_Shift_Right(&X);
  }

  // mod is in A
}