PTA习题4-3 求分数序列前N项和 (易犯错点讲解以及注意事项)

 			习题4-3 求分数序列前N项和 (15分)

本题要求编写程序,计算序列 2/1+3/2+5/3+8/5+… 的前N项之和。注意该序列从第2项起,每一项的分子是前一项分子与分母的和,分母是前一项的分子。

输入格式:
输入在一行中给出一个正整数N。

输出格式:
在一行中输出部分和的值,精确到小数点后两位。题目保证计算结果不超过双精度范围。

输入样例:
20

输出样例:
32.66

今天来讲解pta上的一到C语言程序设计编程题-求分数序列前N项和
其实说实话这套题思路没什么讲解可言,但是我今天讲解的是注意事项!
分享我的错误代码

#include<stdio.h>
int main()
{
    int n;
    scanf("%d",&n);
    int a=2,b=1,t,i;
//    double a=2,b=1,t,i;//为甚么这里要是double呢?
    double sum=2.0;
    if(n==1)
    {
        printf("%0.2lf",sum);
        return 0;
    }
    for(i=2;i<=n;i++)
    {
        t=a;
        a=a+b;
        b=t;
        sum+=1.0*a/b;
    }
    printf("%0.2lf",sum);
    return 0;
}

乍一看没啥问题,我也是这么觉得,哈哈哈!但是当我执行的时候发现结果如下:在这里插入图片描述

是的,n较大时会不符合结果,于是我就改变范围

#include<stdio.h>
int main()
{
    int n;
    scanf("%d",&n);
    //int a=2,b=1,t,i;
    
    long a=2,b=1,t,i;//***事实证明这句还是会导致n较大时不通过***
    
    long long a=2,b=1,t,i;//*同时事实证明这句还是会导致n较大时不*通过
    
    double sum=2.0;
    if(n==1)
    {
        printf("%0.2lf",sum);
        return 0;
    }
    for(i=2;i<=n;i++)
    {
        t=a;
        a=a+b;
        b=t;
        sum+=1.0*a/b;
    }
    printf("%0.2lf",sum);
    return 0;
}

接下来我要讲的才是重点,我在百度的时候很多人都没有给出为原因?

大家知道a是斐波那契数列随着n增大会变的非常大的!

我当时认为改变该处的范围就可以啦!但是就是不通过我就纳闷啦!long不行也就罢啦,long long 可是8个字节呀!和double差不多吧!long long 应该必须通过的;

百思不得其解!后来我查书(C语言谭浩强第五版)
long 是4个字节 -2147483648~2147483647
long long 是8个字节 -9223372036854775808~9223372036854775807
即(-2^63 )------- (2^63)-1)
double 是8个字节 2.310^-308----- 1.710^38 (1.7乘以10的38次方)

我总以为8个字节类型差不多,今天算是学到啦!double远远大于long long 的

所以int ,long 以及long long 都是不可以的,我也不知道谁出的题为什么要搞这么大?我无语啦!也许可能出题人本身不知道会这么大,认为该题就是要用double的。怎么会出现整型的呢?只不过我们喜欢一开始用的整型然后1.0*a/b吧!

我看见其他的博客,将double a=2,b=1;然后int t,a是要赋值给t的,最后发现int 不行然后换double t。最后解释(int 为什么不行)说是类型转换导致精度缺失。其实完全是没深入了解。但是不得不承认它的第一步用double a,b,是对的。

其实总的来说

最后一个测试点没有通过就是long long 太小啦!
double才可以满足n较大的情况!

所以a,b,临时变量t都必须要用double

希望我这个解释可以帮到你!

#include<stdio.h>
int main()
{
    int n;
    scanf("%d",&n);
    double a=2,b=1,t,i;
    double sum=2.0;
    if(n==1)
    {
        printf("%0.2lf",sum);
        return 0;
    }
    for(i=2;i<=n;i++)
    {
        t=a;
        a=a+b;
        b=t;
        sum+=1.0*a/b;
    }
    printf("%0.2lf",sum);
    return 0;
}

在这里插入图片描述

  • 19
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值