【问题标题】:How to use modulo when denominator is out of unsigned long long int bounds?当分母超出 unsigned long long int 范围时如何使用模?
【发布时间】:2019-08-07 16:12:58
【问题描述】:

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

【问题讨论】:

标签: c++ modulo


【解决方案1】:

如果 K2 大于 NN % 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);
}

【讨论】:

    【解决方案2】:

    你真的不需要 bigint 库,因为

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

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

    Is there a 128 bit integer in gcc?

    【讨论】:

    • 嗯,你必须采取确切的限制(如我的回答),否则在某些情况下你不会得到正确的答案(例如,如果 N 是 5 × 10^18 并且 K 是2 × 10^9)。
    • @Phil1970 条件是 N ⩽ 10¹⁸ 所以你说的永远不会发生
    猜你喜欢
    • 2017-06-29
    • 2012-01-27
    • 2016-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-05
    • 1970-01-01
    相关资源
    最近更新 更多