C++ 中的 int(或长长)溢出如何影响模数
How does int(or long long) overflow in c++ affect modulus?
假设我有两个长长,a和b,我需要相乘,然后得到一些大k的值mod k,这样a,b和k都在长整型的范围内,而不是int。为简单起见,a、b <k。>
因此,代码将是:
long long a, b, k;
cin >> a >> b >> k;
cout << (a * b)%k << "n";
但是,由于 a 和 b 太大了,如果你像上面一样乘法,它溢出并变成负数,那么 mod k 将是一个负数并且不正确。
如何确保值 mod k 正确?
编辑:作为奖励,这在Java中是如何工作的?是否如预期的那样相同?还是需要BigInteger?
许多编译器提供 128 位积分类型。例如,使用g++
您可以创建一个函数
static inline int64_t mulmod(int64_t x, int64_t y, int64_t m)
{
return ( (__int128_t)x * y) % m;
}
旁白:如果可以的话,在做模算术时尽量坚持使用无符号整数类型。整数除法的舍入行为使得在涉及有符号值时使用%
非常尴尬。
如果您知道值小于 ULONGLONG_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
如果你的数字比这个数字大,你需要去一个多精度库,如GMP。
相关文章:
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- 为什么擦除方法会影响结束方法
- 内联如何影响模块接口中的成员函数
- 为什么返回类型的'const'限定符对标有 __forceinline/内联的函数没有影响?
- 在容量内调整矢量大小时的性能影响
- 重载运算符的范围是什么?它是否会影响作为类成员的集合的插入函数?
- 未达到的情况会影响开关外壳性能
- 循环仅对第一行正常工作.其他行不受 for 的影响
- 处理影响跨不同线程共享对象的定时回调的最佳方法是什么?
- 模板如何影响C++中隐式声明的规则?
- 命名空间信息会影响C++的可读性
- [[可能]]和[[不太可能]]影响程序汇编的简单示例?
- 如何保护非托管应用程序中的字符串不受进程转储的影响
- 检查nullptr是否100%保护内存布局不受segfault影响
- 为什么 std::set.erase(first, last) 会影响从中获取 (first, last) 的容器?
- 发布代码的 gdb 堆栈跟踪可读性如何影响 x64?
- "virtual"对C++析构函数有何影响?
- 如果我对"while"块发表评论,为什么程序会死机?其中的"yield"线有何影响?
- Qt也不例外.这对C++代码有何影响
- 基例如何影响使用递归函数的哪些行