《C程序设计教程(第四版)——谭浩强》
题目:
例题4.4 相传古代印度国王舍罕要褒奖他聪明能干的宰相达依尔(国际象棋发明者),问他需要什么,达依尔回答说:“国王只要在国际象棋的棋盘的第一个格子里放一粒小麦,第二个格子里放两粒小麦,第三个格子里放四粒小麦,以后按照此比例每一格加一倍,一直放第64格(国际象棋的棋盘是64*64),我就感激不尽了,其他的我什么也不要。”国王想:“这能有多少,太容易了!”让人扛了一袋小麦,但不到一会就用完了,再来一袋也很快就用完了,结果全印度的粮食还完还不够,国王纳闷,怎么也算不清这笔账。
请编写程序,帮国王算算一共需要多少麦子。
解题思路:
(1)解读题目:
每一个格子放要求放的麦子
(要求:后一格麦子的数量是前一格麦子数量的一倍,且第一格麦子数量为1,第二格麦子数量为2……)
格子 麦子数 推导 规律 1 1 1(2ⁿ,n=0) 2ⁿ,n=第几个格子-1 2 2 2¹ 3 4 2² 4 8 2³ 5 16 2ⁿ(n=4) 6 32 2ⁿ(n=5) …… …… 64 2ⁿ(n=64-1)
(2)代码思路解析:
1.需要有一个数(x)表示每一项的麦子数;
int x=0;
2.需要有一个数(sum)来储存麦子数的和;
int sum=0;
3.需要一个循环,这个循环需要实现循环64次,并且x的每一项为2ⁿ,然后还要将每一项相加求出和。
代码:
//《C程序设计教程(第四版)——谭浩强》
//例题4.4 相传古代印度国王舍罕要褒奖他聪明能干的宰相达依尔(国际象棋发明者),问他需要什么,
//达依尔回答说:“国王只要在国际象棋的棋盘的第一个格子里放一粒小麦,第二个格子里放两粒小麦,第三个格子里放四粒小麦,以后按照此比例每一格加一倍,一直放第64格(国际象棋的棋盘是64*64),我就感激不尽了,其他的我什么也不要。”
//国王想:“这能有多少,太容易了!”让人扛了一袋小麦,但不到一会就用完了,再来一袋也很快就用完了,结果全印度的粮食还完还不够,国王纳闷,怎么也算不清这笔账。
//请编写程序,帮国王算算一共需要多少麦子。
#include <stdio.h>
#include <math.h>
int main()
{
double x=0;//64项中每一项的大小
double sum=0;//64项的总和
int i=0;
for(i=0;i<=63;i++)
{
x=pow(2,i);
sum=sum+x;
}
printf("第64格的麦子数为\n%22.16e\n",sum);
return 0;
}
运行结果:
结果分析:
麦子数为:1.84467441*10的19次方
代码编写过程中遇到的问题:
麦子数结果的表示:
初始代码:
//*******错误代码*******//
#include < stdio.h>
#include < math.h>
int main()
{
long long int x=0;//64项中每一项的大小
long long int sum=0;//64项的总和
int i=0;
for(i=0;i<=63;i++)
{
x=(long long int)pow(2,i);//错误1
sum=sum+x;
}
printf(“%lld\n”,sum);//错误2
返回 0;
}
错误1:
pow函数是表示指数的函数,它的返回值默认是一个double类型的数,如果需要的值是其他类型的,需要对其进行强制类型转换。
错误2:
(1)如果是longlongint类型的数,输出是用%lld;
(2)long long int类型的数的最大值:9223372036854775807
最小值:-9223372036854775808
(3)结果特别特别大的时候超越了longlongint的上限,就会产生整数溢出。
怎么解决??
将特别大的数打印出来的时候写成科学计数法的形式,即用%e来打印,但是这时,它的类型必须为double类型,e后面是什么数字,e前面的那个数的10的多少次方