当分母超出 unsigned long long int 范围时如何使用模数?

How to use modulo when denominator is out of unsigned long long int bounds?

给定 1 ≤ N ≤ 1018 和 1 ≤ K ≤ 1018,我该如何操作 N % K2?当 K 接近值 102(分母)超出 unsigned long long int 的范围时 18,因此我无法存储该值K2.

你真的不需要 bigint 库,因为

  • 如果 K > 109 那么 K2 > 1018 > N, 因此N % K2 = N 不用计算K2
  • if K ⩽ 109 那么你可以使用正常的 uint64_t 计算 N % (K*K) 而不会溢出

FWIW 大多数现代编译器在 64 位模式下也有 128 位类型。 GCC、Clang 和 ICC 称之为 __int128

Is there a 128 bit integer in gcc?

那么如果 K2 大于 N 那么 N % K2 等于 N.

示例:

253 % 172 = 253 % 289 = 253

假设 64 位 unsigned long long,可以平方而不会溢出的最大值是 232 - 1 等于 0xFFFFFFFF(或 4'294' 967'295).

因此您可以简单地使用以下代码:

unsigned long long compute(unsigned long long n, unsigned long long k)
{
    if (k > 0xFFFFFFFF)
    {
        // k² is bigger than n (require more than 64 bits), so the modulo is n
        return n;
    }

     return n % (k * k);
}