C++中带负数的模数

nit*_*712 21 c++ recurrence modulo

我一直在编写以下重现关系的程序:

An = 5An-1 - 2An-2  - An-3 + An-4
Run Code Online (Sandbox Code Playgroud)

输出应该是答案模数10 ^ 9 + 7 ..我为此写了一个蛮力方法如下......

long long int t1=5, t2=9, t3=11, t4=13, sum;
while(i--)
{
    sum=((5*t4) - 2*t3 - t2 +t1)%MOD;
    t1=t2;
    t2=t3;
    t3=t4;
    t4=sum;
}
printf("%lld\n", sum);
Run Code Online (Sandbox Code Playgroud)

其中MOD= 10^9 +7 每件事似乎都是真的..但我得到了一些价值的否定答案..由于这个问题,我无法找到正确的解决方案...... Plz帮助保持正确的地方Modulus

sel*_*tze 33

问题是%运算符不是"模运算符",而是具有以下相等性的"除法余数"运算符

(a/b)*b + a%b == a    (for b!=0)
Run Code Online (Sandbox Code Playgroud)

所以,如果你的整数除法向零舍入(我认为这是自C99和C++ 11以来的强制执行),-5/4将为-1而且我们有

(-5/4)*4 + -5%4 == -5
  -1  *4    -1  == -5
Run Code Online (Sandbox Code Playgroud)

为了获得正结果(对于模运算),您需要添加除数以防余数为负数或执行以下操作:

long mod(long a, long b)
{ return (a%b+b)%b; }
Run Code Online (Sandbox Code Playgroud)


Evg*_*eev 7

%在@ sellibitze和@ liquidblueocean中使用第二次的答案可能不会像往常一样慢%,因为它可以归结为减法b或无减.实际上,让我检查一下......

int main(int argc, char **argv) {
    int a = argc;    //Various tricks to prevent the
    int b = 7;       //compiler from optimising things out.
    int c[10];       //Using g++ 4.8.1
    for (int i = 0; i < 1000111000; ++i)
        c[a % b] = 3;
        //c[a < b ? a : a-b] = 3;
    return a;
}
Run Code Online (Sandbox Code Playgroud)

或者使用%其他行注释该行,我们得到:

  • %:14秒

  • ?:7秒

所以%不像我怀疑那样优化.可能是因为优化会增加开销.

因此,%出于性能原因,最好不要使用两次.

相反,正如这个答案所暗示和解释的那样,这样做:

int mod(int k, int n) {
    return ((k %= n) < 0) ? k+n : k;
}
Run Code Online (Sandbox Code Playgroud)

它需要更多的工作,如果你希望它为阴性正常工作n,但是这是几乎从来没有必要的.


ras*_*mus 5

只需用%处理负值的函数替换:

long long int mod(long long int a, long long int b) {
    long long int ret = a % b;
    if (ret < 0)
        ret += b;
    return ret;
}
Run Code Online (Sandbox Code Playgroud)

编辑:将数据类型更改为long long int.