C++ int(或long-long)如何在c++;影响模量?

C++ int(或long-long)如何在c++;影响模量?,c++,long-integer,modulus,integer-overflow,C++,Long Integer,Modulus,Integer Overflow,假设我有两个长long,a和b,需要相乘,然后得到一些大k的值mod k,这样a,b和k都在long-long范围内,但不在int范围内。为了简单起见,a,b>a>>b>>k; cout如果您知道值小于ULONGLONG\u MAX/2(因此加法不会溢出),则可以一次乘以一位: unsigned long long mulmod(unsigned long long a, unsigned long unsigned long b, long long m) { unsigned lon

假设我有两个长long,a和b,需要相乘,然后得到一些大k的值mod k,这样a,b和k都在long-long范围内,但不在int范围内。为了简单起见,a,b 因此,守则将是:

long long a, b, k;
cin >> a >> b >> k;
cout << (a * b)%k << "\n";
长-长a、b、k;
cin>>a>>b>>k;

cout如果您知道值小于
ULONGLONG\u MAX/2
(因此加法不会溢出),则可以一次乘以一位:

unsigned long long mulmod(unsigned long long a, unsigned long unsigned long b, long long m) {
    unsigned long long rv = 0;
    a %= m;
    b %= m;
    while (b) {
        if (b&1) { rv += a; if (rv >= m) rv -= m; }
        a += a; if (a >= m) a -= m;
        b >>= 1; }
    return rv; }
如果您知道您正在运行gcc/x86_64,您可以尝试:

unsigned long mulmod(unsigned long a, unsigned long b, unsigned long m) {
    unsigned long rv;
    asm ("mulq %2; divq %3" : "=d"(rv), "+a"(a): "S"(b), "c"(m));
    return rv;
}
这将工作到
ULONG_MAX


如果您的数字大于此值,则需要转到多精度库,如许多编译器提供128位整数类型。例如,使用
g++
可以创建一个函数

static inline int64_t mulmod(int64_t x, int64_t y, int64_t m)
{
    return ( (__int128_t)x * y) % m;
}

旁白:如果可以的话,在进行模运算时,尽量使用无符号整数类型。整数除法的舍入行为使得在涉及有符号值时使用
%
非常尴尬。

请参见a,b