大整数的阶乘问题

lost_guy_in_scut 2010-09-14 04:05:03
求大整数阶乘的思路
...全文
192 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
zotin 2010-09-15
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 lost_guy_in_scut 的回复:]

问问zotin,9876543210 = 12 * 10000 * 10000 + 3456 * 10000 + 7890 这个等式如何成立,囧~
[/Quote]

奇怪,写反了。可能脑子里面关于字节序的知识跑出来捣乱了。
明白了就行。
lost_guy_in_scut 2010-09-15
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 zotin 的回复:]
其实看代码也不难。
这个实现方法和做多位数乘法一样就是本位和进位这一套。不过多位数乘法以10为基,这儿以10000为基。
一个很低的数字,比如:9876543210,超出了一个32位整数的范围。
我们可以用10000为基,把数字拆开,再以一个数组来保存。
9876543210 = 12 * 10000 * 10000 + 3456 * 10000 + 7890
数组:
data[3] ……
[/Quote]
问问zotin,9876543210 = 12 * 10000 * 10000 + 3456 * 10000 + 7890 这个等式如何成立,囧~
lost_guy_in_scut 2010-09-15
  • 打赏
  • 举报
回复
哦哦。谢谢zotin的详尽解释。终于懂了~嘿嘿
harderman 2010-09-15
  • 打赏
  • 举报
回复
#include <stdio.h>
#define N 10000
int main(int argc, char **argv)
{
int data[N] = {1}; //数组用来存放每个计算得到的值
int digit, i, index, carry;
int tmp;
for (i=2, digit=0; i<=10000; i++) //循环10000次用来计算10000的阶乘
{
for(index=0, carry=0; index<=digit; index++) //内循环用来计算进位
{
tmp=data[index]*i+carry;
data[index]=tmp%10000; //除以10000表示数组data每个存储的最大值为9999
carry=tmp/10000; //计算进位的值
}
while (carry) //如果有进位,将进位的值付给数组data的下一位的值
{
data[++digit]=carry % 10000;
carry /= 10000;
}
}
printf("%d", data[digit]); //输出时从最高位开始的
for (i=digit-1; i>=0; i--)
{
printf("%04d", data[i]); // 控制数组格式!
}
return 0;
}
lost_guy_in_scut 2010-09-15
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 zotin 的回复:]
引用 7 楼 lost_guy_in_scut 的回复:

问问zotin,9876543210 = 12 * 10000 * 10000 + 3456 * 10000 + 7890 这个等式如何成立,囧~


奇怪,写反了。可能脑子里面关于字节序的知识跑出来捣乱了。
明白了就行。
[/Quote]
哈哈。恩。
S_zxing 2010-09-14
  • 打赏
  • 举报
回复
这思想很好,顶……
zotin 2010-09-14
  • 打赏
  • 举报
回复
其实看代码也不难。
这个实现方法和做多位数乘法一样就是本位和进位这一套。不过多位数乘法以10为基,这儿以10000为基。
一个很低的数字,比如:9876543210,超出了一个32位整数的范围。
我们可以用10000为基,把数字拆开,再以一个数组来保存。
9876543210 = 12 * 10000 * 10000 + 3456 * 10000 + 7890
数组:
data[3] = {12, 3456, 7890};
然后输出这个数就可以这样
for(i=0; i<=3; i++)
printf("%04d", data[i]);

下面只讨论乘数乘以10000不会溢出的情况。
在这种情况下,可以直接把乘数和数组中的每个整数相乘。
比如乘数为3。
(12 * 10000 * 10000 + 3456 * 10000 + 7890) * 3
= (12 * 10000 * 10000)*3 + (3456 * 10000)*3 + 7890*3

7890 * 3 = 23670 = 2*10000 + 3670
如何求3670和2呢?
3670 = 23670 % 10000
2 = 23670 / 10000
然后把3670放会数组最低位{..., ..., 3670}
算3456*3 = 10368,现在要加上进位上来的2
得到10370,同样得到本位0370和进位的1,再算最高位。
方法相同,略。

上面的做法相当与多位数成一位数乘法。如果要求乘数能任意大,那还需要把乘数也拆开,按多位数乘多位数的方法做。
lost_guy_in_scut 2010-09-14
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 chain2012 的回复:]
C/C++ code
#include <stdio.h>
#define N 10000
int main(int argc, char **argv)
{
int data[N] = {1};
int digit, i, index, carry;
int tmp;
for (i=2, digit=0; i<=100……
[/Quote]
谢谢你的代码,不过我想知道算法的思想。
我比较菜,看不甚懂代码。囧~~
chainyu 2010-09-14
  • 打赏
  • 举报
回复
#include <stdio.h>  
#define N 10000
int main(int argc, char **argv)
{
int data[N] = {1};
int digit, i, index, carry;
int tmp;
for (i=2, digit=0; i<=10000; i++) //计算1000!
{
for(index=0, carry=0; index<=digit; index++)
{
tmp=data[index]*i+carry;
data[index]=tmp%10000;
carry=tmp/10000;
}
while (carry)
{
data[++digit]=carry % 10000;
carry /= 10000;
}
}
printf("%d", data[digit]);
for (i=digit-1; i>=0; i--)
{
printf("%04d", data[i]); // 控制数组格式!
}
return 0;
}

64,676

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧