高精度乘法
2016-05-19 21:06
225 查看
乘法的运算受限于数据类型的表示范围,比如int类型的乘法,32位的无符号整形
unsigned int 最大可表示0xffffffff。
有时问题会要求我们进行较大的数值的计算,我们除了使用表示范围较大的数据类型(事实上,这仍不可靠)外,还可以选择高精度的乘法模拟。
例如,有这么一个问题:输入一个不超过1000的正整数n,输出n!的精确结果。
显然int类型来表示这个结果会产生溢出。
下面简单讲讲高精度乘法的一般过程:高精度乘法要求我们开一个数组(假设用f[maxn]表示),用其中的每一位代表运算结果的每一位。因此,我们要对问题要求的计算结果进行分析,估算大致位数,来决定maxn的大小,就这个例子看来,最大的输出结果1000!约有2600位,故开辟一个3000维的数组足够保存结果。
进行乘法模拟,不失一般性,取一次乘法过程来模拟,被乘数已经存放在f数组中,乘数是x,算法伪代码如下
For j=1 to maxn int s ← f[j]*被乘数 + 进位; f[j] ← s % 10; //求解每一位的值 进位 ← s / 10; //求解余数
模拟的算法相当简单:就是对被乘数的每一位,都乘以乘数,并加上进位(初始化为0),并更新f数组的值。
每一遍计算完成后,f数组中保存的就是结果的每一位的值,当然,这里还可以压缩下外循环,因为每次f中保存的值的有效位数是确定的,就可以根据有效位数来决定外循环次数,不一定要每次都执行maxn遍。
模拟方法讲完了,接下来就来解决一下上面的问题,代码用C++实现:
#include<iostream> #include<cstring> #define maxn 3000 //数组开足够大,这里3000即可 using namespace std; int f[maxn]; int main(){ int n; cin >> n; //输出n! memset(f, 0, sizeof(f)); //初始化为全0 f[1] = 1; //f数组保存被乘数,即每一次的运算结果 for(int i =2; i <= n; ++i){ //计算n-1次 int c = 0; //进位初始化 for(int j = 1; j <= maxn; ++j){ //遍历每一位 int s = f[j] * i + c; f[j] = s % 10; c = s / 10; } } int beg; for(beg = maxn; beg >= 1; --beg) //忽略前导的0 if(f[beg]) break; for(int i = beg; i >= 1; --i) cout<<f[i]; return 0; }
后记:博客园的第一篇随笔,随便水一下2333
相关文章推荐
- 网页的3层结构 结构层 表示层 行为层
- 网页的3层结构 结构层 表示层 行为层
- Hibernate初体验及简单错误排除
- 利用UDPSocket模拟一次对话,只能运行依次,多次执行还在测试中.跪求大神建议....
- Hibernate初体验及简单错误排除
- 基于FS4412嵌入式系统移植(3) eMMC加载系统启动linux体验
- linux 中大小端问题 详解
- 大数加法 及 乘法
- 二叉排序树(BSTree)关于查找算法结合
- ArrayList和LikendList
- 找水王01
- 网页的3层结构 结构层 表示层 行为层
- 网页的3层结构 结构层 表示层 行为层
- 网页的3层结构 结构层 表示层 行为层
- 网页的3层结构 结构层 表示层 行为层
- 网页的3层结构 结构层 表示层 行为层
- 网页的3层结构 结构层 表示层 行为层
- 网页的3层结构 结构层 表示层 行为层
- 网页的3层结构 结构层 表示层 行为层
- 网页的3层结构 结构层 表示层 行为层