对于普通的指数幂计算,我们直接调用C语言库的pow()库函数就可以解决,但是对于将2的10000次方(2^10000),3的1000次方(3^1000)这种计算结果为几百位甚至上千位的数而言,long long数据类型并不能存储下来,所以打印到屏幕中也会出现错误。
解决这种问题的思路,请看下面一段代码:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
int main()
{
int num = 123456790;
int a = 123, b = 456, c = 789;
printf("%d\n", num); //输出结果123456790
printf("%d %d %d\n", a, b, c); //输出结果123 456 790
num = 123456790 * 2;
a = 123 * 2, b = 456 * 2, c = 790 * 2;
//这个时候c的结果本来应该为1580,但是我们需要输出的时候保证c只输出三位数,多的一位(1000)进位给b(1000进位后当作b的1)
//用代码表示的话如下:
int upnum = 0;//upnum表示进位数
upnum = c / 1000; //此时upnum表示c相当于b的进位数
c = c % 1000;
upnum = (b + upnum) / 1000; //此时upnum表示b相当于a的进位数
b = (b + upnum) % 1000;
c = c + upnum;
printf("%d\n", num); //输出结果246913580
printf("%d %d %d\n", a, b, c); //输出结果246 913 580
system("pause");
return EXIT_SUCCESS;
}
另外需要明白一个公式如下:
1234*2=1200*2+34*2
//这句话和上面的代码综合一下,就是说1234可以分为12和34两段,1234*2的结果为【12这段*2+34这段的溢出】+【34段末两位位数】;
//关键点就是1234这段乘以2,那么1234分为两段12,34。这两段都需要乘以2;
至此,我们已经将需要计算的溢出和乘方计算问题解决了,只用看代码了:
程序用一个含有1024个 无符号整数 (上限65536)的数组来存放各段数据
每一个数是一段,每一个数据可以表示9999这么大的数(便于进位)
计算一次,检查是否超过9999,如果超过,把这一段减去10000,
然后向上一个位(即上一个数)进1(这可以称为 "一万进制 ")
程序可以计算小于2的13605次方,大于0次方的任意的二的乘方,代码如下
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<time.h>
int main(void)
{
static unsigned int temp[1024];/*分段储存数据*/
unsigned int position = 1;/*记录共有几段*/
int overflow = 0; /*记录在算每一段时是否溢出*/
int x, y;//x为底数,y为指数
printf("请分别输入底数和指数,中间用空格分开\n");
scanf("%d %d", &x, &y);
long times = y; //指数
long tm_cnt = 0; //乘方次数计数
long sgn_cnt = 0; //段的位置
temp[0] = x;/*初始值为x,底数*/
unsigned int upnum = 0;//每段计算结果的的进位数(如果大于10000进位1,大于20000进位2)
int flag = 0; //标志位
if (times> 13000)
{
printf("your input is too large ");/*检查输入是否越界*/
exit(0);
}
/*开始计算,外层为乘方次数,内层为每一位计算*/
for (tm_cnt = 0; tm_cnt <times - 1; tm_cnt++)
{
for (sgn_cnt = 0; sgn_cnt <position; sgn_cnt++)
{
temp[sgn_cnt] *= x;/*相当于乘x*/
if (overflow == 1) /*检查上次是否有溢出*/
{
/*有的话,将溢出加到这一段,同时置溢出为0*/
temp[sgn_cnt] += upnum;
upnum = 0; //置零
overflow = 0;
}
if (temp[sgn_cnt]> 9999)
{
/*检查本次是否溢出,溢出的话,进位数upnum*/
//如果底数很大的话,超出了int的取值范围,这里需要加上另外一个条件限制
upnum = temp[sgn_cnt] / 10000; //进位数
temp[sgn_cnt] = temp[sgn_cnt] % 10000;
overflow = 1;
}
}
if (overflow == 1) //下次成方的时候查看段数是否足够,如果不够需要增加
{
++position;
temp[sgn_cnt]+= upnum;
overflow = 0;
if (tm_cnt == (times - 2))
{
flag = 1; //如果最后一次乘方发生溢出的话,进行说明
}
}
if (position> 1023)
{
printf("times: %d error! ", tm_cnt);
exit(1);
}
}
//输出第最后一段数字
if (flag == 1) //最后一次有溢出
{
printf("%d ", temp[sgn_cnt]);
}
else //最后一次没有溢出
{
printf("%d ", temp[sgn_cnt - 1]);
}
//倒数第二段开始,逆序全部输出
for (sgn_cnt = position - 2; sgn_cnt >= 0; sgn_cnt--)
{
if (temp[sgn_cnt] <1000)
printf("0 ");
if (temp[sgn_cnt] <100)
printf("0 ");
if (temp[sgn_cnt] <10)
printf("0 ");
printf("%d ", temp[sgn_cnt]);
if ((sgn_cnt + 1) % 15 == 0)
printf("\n ");
}
system("pause");
return EXIT_SUCCESS;
}
好了,不知道你看懂了没有。
如果还有写模糊可以参看文档 https://zhidao.baidu.com/question/166472785.html
本人也是从上面学来的 ,哈哈哈
另外推荐一个地址:
http://blog.csdn.net/yhj110911119/article/details/52409143