C ++中涉及模数运算符和带有大括号的优先级的错误

时间:2018-07-07 07:26:26

标签: c++ modulus integer-overflow largenumber

正义的第一部分计算了一些数学公式,这些数学公式存储在 ans1 ans2 ans3 中。许多站点按优先顺序将%和*赋予相同的优先级。然后我们应该在表达式中从左到右考虑它们吗?第56行和第57行之间的唯一区别是产品中术语的使用顺序以及附加的括号对。我不明白这对最终结果有何影响。

#include <iostream>

using namespace std;

#define mod 998244353

int main()
{
int ans1 = 672510887; // These are the outputs for the previous part of the program
int ans2 = 814503527;
int ans3 = 71242790;

cout << ans1%mod << endl; // Returns the same number for all three as they are lesser than mod
cout << ans2%mod << endl;
cout << ans3%mod << endl;
cout << 1LL*ans1*ans2*ans3 << endl; // 4021307808285681478
cout << 1LL * ( 1LL * ans1%mod * ans2%mod)%mod << endl; // 313818575
cout << (1LL * 672510887 * 313818575)%mod << endl; // 873911579
cout << (1LL * ((1LL * ans2 * ans3)%mod) * ans1) % mod << endl; // 414849507
cout << (1LL * ans1 * (1LL * ans2 * ans3)%mod) % mod << endl; // 935539465
cout << (1LL * ans1 * ((1LL * ans2 * ans3)%mod)) % mod << endl; // 414849507
cout <<  (5 * (3 * 4)%8)%8 << ' ' << (5 * ((3 * 4)%8))%8 << endl; // 4 4
}

1 个答案:

答案 0 :(得分:-1)

*%具有相同的优先级,并且具有左右关联。因此,像a * b%c * d这样的表达式表示((a * b) % c) * d)

// Undefined behaviour: integer overflow
cout << 1LL*ans1*ans2*ans3 << endl;

// Works out ans1 x ans2 (modulo mod) correctly
cout << 1LL * ( 1LL * ans1%mod * ans2%mod)%mod << endl;

// Works out ans1 x ans1 x ans2 (modulo mod) correctly
cout << (1LL * 672510887 * 313818575)%mod << endl;

// Works out ans1 x ans2 x ans3 (modulo mod) correctly
cout << (1LL * ((1LL * ans2 * ans3)%mod) * ans1) % mod << endl;

// Undefined behaviour due to integer overflow: ans1*ans2*ans3 occurs before the mod
cout << (1LL * ans1 * (1LL * ans2 * ans3)%mod) % mod << endl;

// Works out ans1 x ans2 x ans3 (modulo mod) correctly
cout << (1LL * ans1 * ((1LL * ans2 * ans3)%mod)) % mod << endl;

不确定最后一行的目的是什么;如上所述,(5 * (3 * 4)%8)%8的意思是(5*3*4)%8。对于这些特定值,巧合的结果与(5 * ((3*4)%8))%8相同。