C++64位整型相乘取模的溢出处理(一)
2015-06-08 15:43
316 查看
在ACM中做题时经常会出现输出的结果要模以一个数,如模109+7,一般来说用64位整型long long(有些编译器是__int64)来保存答案是没有什么问题的,因为109+7没有超过231-1,即32位整型int也能存得下,int * int 也不会溢出 long long,但是就是有些坑爹的题目取模的数超过int,就有可能出现两个long long类型相乘时溢出的情况,虽然两个long long相乘取模后的结果不超过long long,不过相乘时溢出可能会影响符号位,导致结果为负,再取模,结果也是负的,当然不一定溢出就会变负数。直接上代码
输出结果对1018取模,结果和计算器算的一致。
函数mul的复杂度是log(n),这里的运算次数是b的二进制数的长度,当然可以加个判断来降一丢丢运算次数。
原理类似快速幂,把b写成二进制,b的二进制中的每一个1就表示2i个a,i表示这个1是第几位的(从0开始),把这些个2i∗a加起来就是结果了,计算时对中间结果取模。
#include <iostream> using namespace std; const long long MOD = 1000000000000000000L; long long mul(long long a, long long b) { long long ans = 0, step = a % MOD; while (b) { if (b & 1L) ans += step; if (ans >= MOD) ans %= MOD; step <<= 1L; if (step >= MOD) step %= MOD; b >>= 1L; } return ans % MOD; } int main() { cout << mul(9223372036854775807L, 7346854775807L) << endl; return 0; }
输出结果对1018取模,结果和计算器算的一致。
函数mul的复杂度是log(n),这里的运算次数是b的二进制数的长度,当然可以加个判断来降一丢丢运算次数。
原理类似快速幂,把b写成二进制,b的二进制中的每一个1就表示2i个a,i表示这个1是第几位的(从0开始),把这些个2i∗a加起来就是结果了,计算时对中间结果取模。
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- 关于指针的一些事情
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- Lua教程(一):在C++中嵌入Lua脚本
- Lua教程(二):C++和Lua相互传递数据示例
- C++联合体转换成C#结构的实现方法
- C++编写简单的打靶游戏
- C++变位词问题分析
- C/C++数据对齐详细解析
- C++基于栈实现铁轨问题
- C++中引用的使用总结
- C++中调用Lua函数实例
- Lua和C++的通信流程代码实例
- C与C++之间相互调用实例方法讲解
- C++中拷贝构造函数的应用详解
- C++中引用(&)的用法与应用实例分析
- C++使用CriticalSection实现线程同步实例
- C++智能指针实例详解
- 解析C++ 浮点数的格式化输出