| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1521 人关注过本帖
标题:[推荐]绝对1~100的和+1!~20!之和+1/1~1/10之和的完整解法
只看楼主 加入收藏
CoolFlyTow
Rank: 1
等 级:新手上路
帖 子:33
专家分:0
注 册:2004-9-16
收藏
 问题点数:0 回复次数:14 
[推荐]绝对1~100的和+1!~20!之和+1/1~1/10之和的完整解法

这个帖子源自:http://bbs.bc-cn.net/bbs/dispbbs.asp?boardID=44&ID=6632&page=1

这是我对问题的理解:

本题最核心的——

1。精度(是指的第三部分,这一部分还是很好解决的;但是第二部分的是重点,对于C中的任何的基本数据类型都不能解决,要自己构造,并且要自己设置求解的函数)

2。数据溢出(主要是第二部分,由于是阶乘的问题,所以如果不考虑精度的话就应该用浮点型具体为什么可以看我在http://bbs.bc-cn.net/bbs/dispbbs.asp?boardid=44&star=2&replyid=30772&id=6632&skin=0&page=1的解释)

皇天不负有心人本人不愧弓虽。经过我将尽4个小时的努力:下面是我的程序和运算结果:—————————〉 这个程序只要修改

maxN控制溢出的量,和阶层n的值就可以计算任何数的阶乘。不过我没有试。哈哈哈

下面是完整的程序:运行通过了,bug因该没了,希望一起探讨!!!!

[此贴子已经被作者于2004-10-17 11:01:01编辑过]

搜索更多相关主题的帖子: 解法 之和 精度 
2004-10-17 04:41
CoolFlyTow
Rank: 1
等 级:新手上路
帖 子:33
专家分:0
注 册:2004-9-16
收藏
得分:0 

/*===================================================== 本程序求和1+2+……+100 再加1!+2!………+20! 再加1/1+1/2+……+1/10 精度(主要是指的第三部分,)和数据溢出(主要是第二部分)的问题必须被考虑,所以分三部分求解

====================================================*/ #include<limits> #include<iostream>

using namespace std; /*********************************************************** 下面是我定义的函数用于计算的(用于解决计算时丢失数据精度的问题) 在其中存储的都是——》十六《——进制数 ***********************************************************/ //////////////////////////////// const maxN=10;//如果要计算更大的数请更改

bool addMyArray(unsigned char source1[maxN],unsigned char source2[maxN])//source1+source2->source1 { unsigned int i=0; unsigned int tmp=0; unsigned char carry=0;

for(i=0;i<maxN;i++) { tmp=source1[i]+source2[i]+carry; source1[i]=static_cast<unsigned char>(tmp); carry=static_cast<unsigned char>(tmp>>numeric_limits<unsigned char>::digits); } if(carry==0) { return true; } else { return false; } }

bool addArray(unsigned char source1[maxN],unsigned int source2)//source1+source2->source1 { unsigned int i=0; unsigned int tmp=0; unsigned char carry=0;

for(i=0;i<sizeof(unsigned int)/sizeof(unsigned char);i++) { tmp=source1[i]+static_cast<unsigned char>(source2)+carry; source1[i]=static_cast<unsigned char>(tmp); carry=static_cast<unsigned char>(tmp>>numeric_limits<unsigned char>::digits); source2=static_cast<unsigned char>(source2>>numeric_limits<unsigned char>::digits); } if(carry==0) { return true; } else { for(;i<maxN&&carry!=0;i++) { tmp=source1[i]+carry; source1[i]=static_cast<unsigned char>(tmp); carry=static_cast<unsigned char>(tmp>>numeric_limits<unsigned char>::digits); } if(carry==0) return false; else ; } return true; }

//source1*source2->source1 bool mulMyArray(unsigned char source1[maxN],unsigned char source2) { unsigned int i=0; unsigned int tmp=0,tmpC=0; unsigned char carry=0,carry1=0;

for(i=0;i<maxN;i++) { tmp=source2; tmp*=source1[i]; tmp+=carry; source1[i]=static_cast<unsigned char>(tmp); carry=static_cast<unsigned char>(tmp>>numeric_limits<unsigned char>::digits); }

if(carry==0) { return true; } else { return false; } } /************************************************************************* 上面是我自定义的函数用于计算的 ***********************************************************************/

int main(void) { //定义变量 int i=0,j=0,n=20; //计算第一部分的定义 unsigned int sum1=0; //计算第二部分的定义 unsigned char sum2[maxN],tmp2[maxN];

//计算第三部分的定义 long double sum3=0,tmp3=0;

//计算所有部分的和的变量定义 struct sumAll { unsigned char Interg[maxN]; long double fraction; }All; for(i=0;i<maxN;i++) { sum2[i]=tmp2[i]=All.Interg[i]=0; } All.fraction=0;

//计算第一部分 for(i=1;i<=100;i++) sum1+=i;

//计算第二部分 cout<<"\n请输入阶乘数:\nn="; cin>>n;

if(n<=0) { cout<<"\n阶乘数n输入错误!程序默认使用n=20计算!!\n"; n=20; } else ;

tmp2[0]=1; for(i=1;i<=n;i++) { if(mulMyArray(tmp2,static_cast<unsigned char>(i))) {

if(addMyArray(sum2,tmp2)) ; else { cout<<"\n溢出!"; return 1; } } else { cout<<"\n溢出!"; return 1; } }

//计算第三部分 tmp3=1; for(i=1;i<=10;i++) { tmp3=1/static_cast<long double>(i); sum3+=tmp3; }

sum1+=static_cast<unsigned int>(sum3); sum3-=static_cast<unsigned int>(sum3); if(addArray(sum2,sum1)) { if(addMyArray(All.Interg,sum2)) All.fraction=sum3; else { cout<<"\n溢出!"; return 1; } } else { cout<<"\n溢出!"; return 1; }

cout<<"\n本程序计算1+2+……+100+1!+2!+……+"<<n<<"!+1/1+1/2+……+1/10\n整数部分是:" <<hex <<uppercase;

for(i=maxN-1;i>=0;i--) { sum1=All.Interg[i]; if(sum1!=0) cout<<sum1; else continue; }

cout<<"(十六进制)\n小数部分是"; cout<<All.fraction; cout<<"(十进制)\n\n本程序成功运行!请输入一个数字退出……\n";

cin>>n; return 0; }

[此贴子已经被作者于2004-10-17 04:47:11编辑过]


2004-10-17 04:45
CoolFlyTow
Rank: 1
等 级:新手上路
帖 子:33
专家分:0
注 册:2004-9-16
收藏
得分:0 

程序运行结果:

1。

请输入阶乘数: n=20

本程序计算1+2+……+100+1!+2!+……+20!+1/1+1/2+……+1/10 整数部分是:238BA9C9FFADD5(十六进制) 小数部分是0.928968(十进制)

本程序成功运行!请输入一个数字退出……


2004-10-17 04:48
CoolFlyTow
Rank: 1
等 级:新手上路
帖 子:33
专家分:0
注 册:2004-9-16
收藏
得分:0 

2。没有修改maxN的值。

请输入阶乘数: n=50

溢出!

3。修改maxN得值为30后。

请输入阶乘数: n=50

本程序计算1+2+……+100+1!+2!+……+50!+1/1+1/2+……+1/10 整数部分是:4B712939E553E8962A72F479C353CE762B90D9CFCB172DF87EDD5(十六进制) 小数部分是0.928968(十进制)

本程序成功运行!请输入一个数字退出……

看到了吗??很完美吧!!!!


2004-10-17 04:51
jiangzhl
Rank: 1
等 级:新手上路
帖 子:3
专家分:0
注 册:2004-10-17
收藏
得分:0 
太长了
2004-10-17 11:10
liang30890136
Rank: 1
等 级:新手上路
帖 子:35
专家分:0
注 册:2004-9-29
收藏
得分:0 

太长了,不过不错,如果阶层太大了,如果小点,会爽的多!

2004-10-17 11:22
liang30890136
Rank: 1
等 级:新手上路
帖 子:35
专家分:0
注 册:2004-9-29
收藏
得分:0 
不过碰不到这么大的数吧,没多少价值吧!
2004-10-17 11:24
CoolFlyTow
Rank: 1
等 级:新手上路
帖 子:33
专家分:0
注 册:2004-9-16
收藏
得分:0 
liang30890136 嘿嘿,只不过是说明太多了,为了能让大家看懂啊,你可以不看子函数只看主函数部分啊,都有详细的说明的。

2004-10-17 11:25
CoolFlyTow
Rank: 1
等 级:新手上路
帖 子:33
专家分:0
注 册:2004-9-16
收藏
得分:0 

liang30890136你没看第一楼的文字吗?

如果不这么做,你要用什么方法不让一个较小数的数(第一、三部分之和)加上一个21C3677C82B40000H这个是我用计算器算的我还不知道有没有溢出列,反正我知道你要用浮点型的数来装第二部分。你有没有学过计算方法啊——在那里面有些东西很有用啊,我只翻过。我记得浮点型精度只有6位(double型的只有10位)表示这么大的数你说是不是将使用科学计数法啊,那样的话小数+大数必将丢失小数,那么还要计算第一、三部分干什么啊???


2004-10-17 11:37
Knocker
Rank: 8Rank: 8
等 级:贵宾
威 望:47
帖 子:10454
专家分:603
注 册:2004-6-1
收藏
得分:0 

这个是我原来写的1!+2!+3!+.....+100!,现在看看算法还可大大优化,建议去看看本论坛的mikewolf所写的10000!的算法

int main(void) { long s[23]={0},t[23],a,b,c,g=0,e,f,k=0,p=10000000; int x,y; for (f=1;f<=100;f++) { for (x=22;x>=0;t[x]=0,x--); t[22]=1; for (e=1;e<=f;e++) for(x=22;x>=0;c=t[x],c*=e,a=c/p,b=c%p,t[x]=b+g,g=a,x--); for(y=22;y>=0;c=t[y]+s[y],a=c/p,b=c%p,s[y]=b+k,k=a,y--); } printf("%ld",s[0]); for(x=1;x<=22;printf("%.7ld",s[x]),x++); getch(); }


九洲方除百尺冰,映秀又遭蛮牛耕。汽笛嘶鸣国旗半,哀伤尽处是重生。     -老K
治国就是治吏。礼义廉耻,国之四维。四维不张,国之不国。   -毛泽东
2004-10-17 12:05
快速回复:[推荐]绝对1~100的和+1!~20!之和+1/1~1/10之和的完整解法
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.027097 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved