《数据结构题集》计算i!*2^i(i=0,1,2,...,n-1)的值并存入数组a[arrsize]中
这是一道难度等级为4的题目题目计算的部分很容易就实现了阶乘还有2的i次方都用递归计算,很方便只需要把i=0时候的这种特殊情况处理好就行unsigned int factorial(int n){//递归调用计算n的阶乘if(n>0)return n*factorial(n-1);elsereturn 1;}unsigned int two_power_i(int i){//计算2^iif(i
这是一道难度等级为4的题目
题目计算的部分很容易就实现了
阶乘还有2的i次方都用递归计算,很方便
只需要把i=0时候的这种特殊情况处理好就行
unsigned int factorial(int n){ //递归调用计算n的阶乘
if(n>0)
return n*factorial(n-1);
else
return 1;
}
unsigned int two_power_i(int i){ //计算2^i
if(i>0)
return 2*two_power_i(i-1);
else ;
return 1;
}
至于后半部分的出错处理方式,最大值MAXINT的问题我一开始理解的是
像Python或者是Excel函数那样,会有专门的处理错误的语句
但是百度了一圈之后,只找到了这个 C 错误处理 | 菜鸟联盟
跟我想的有点儿不太一样,看来C语言好像不支持这种操作
而且经过我的试验,通过对全局变量errno的观察,发现即使发生int类型发生溢出,errno的值不会发生改变,说明int数据溢出,并不算一种C收录进去的错误
用errno这个思路行不通
后来又想到,默认设置MAXINT为无符号32位int类型
计算出32位二进制的最大值 并初始化MAXINT为2^32-1,将计算得到的结果tmp(强制转化为64位)与MAXINT比较
如果tmp>MAXINT 那么按出错处理
尽管觉得这样不是很妥当,毕竟如果支持64位int型,为何不直接将数组扩大到64位的longlongint上去,而非要钳制在32位呢
写完了程序,感觉基本功能实现了
翻一下课后答案,里面提到,既然超出最大值,那么就不能用比大小的方式
而我恰恰是用的这个方式
改!
通过前面的试验发现,当发生溢出之后,虽然不会报错,但是很明显,原来一直递增的数组序列,会出现反而减小的情况
利用这个特点,只需要检测相邻两次的数组值,很容易就可以发现结果溢出的情况,进而检测出错误,程序对应给出相应的处理方式
在这里,计算结果是不断增大的,一旦溢出,则在计算下去没有意义,我选择结束计算
同时,利用这个方法,可以很容易的将原来32位的MAXINT 扩展为64位
下面附上完整的代码:
#include <stdio.h>
#include <errno.h>
#include <string.h>
#define arrsize 40 //定义数组大小20
//#define MAXINT 4294967295
//extern int errno ; //引用全局变量
unsigned int factorial(int n){ //递归调用计算n的阶乘
if(n>0)
return n*factorial(n-1);
else
return 1;
}
unsigned int two_power_i(int i){ //计算2^i
if(i>0)
return 2*two_power_i(i-1);
else ;
return 1;
}
int main(){
int n;
unsigned long long tmp;
unsigned long long int a[arrsize]={};
printf("a[arrsize]大小为%d Byte (%d bit)\n",sizeof(a[0]),sizeof(a[0])*8);
printf("请输入n的值:");
scanf("%d",&n);
while(n>arrsize||n<0){
printf("n的值不合法,0<=n<=%d请重新输入:",arrsize);
scanf("%d",&n);
}
for(int i=0;i<n;i++){
tmp=(unsigned long long int)factorial(i)*(unsigned long long int)two_power_i(i);
// printf("%d! = %u \n",i,factorial(i));
// printf("2^%d = %u \n",i,two_power_i(i));
// printf("sizeof(tmp)=%u\ttmp=%llu\n",sizeof(tmp),tmp);
// if(tmp>MAXINT||tmp==0){
a[i]=tmp;
if(a[i]<a[i-1]&&i>0){
printf("k!*2^k > MAXINT,将不再往后计算,程序结束!\n");
printf("MAXINT为无符号 long long类型 最大为2^64-1\n");
// printf("a[i-1]=%llu\n",a[i-1]);
return -1;
}
printf("a[%d]\t=%llu \n",i,a[i]);
}
}
运行结果:
尽管我n给到了40,但是实际在n=20的时候,结果就已经比64位二进制支持的最大结果还大,发生溢出,经过检验,结果正确,程序运行正常,对于不合理的n输入,也有相应的处理方法

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐
所有评论(0)