C++ 中涉及模运算符优先级和大括号的错误
Errors involving precedence of modulus operator and brackets with large numbers in C++
第一部分只是计算一些数学公式,在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
}
*
和%
具有相同的优先级和左右结合性。所以像 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
相同的结果。
第一部分只是计算一些数学公式,在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
}
*
和%
具有相同的优先级和左右结合性。所以像 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
相同的结果。