欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-06-07 17:14:37
...
 			习题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;
}

乍一看没啥问题,我也是这么觉得,哈哈哈!但是当我执行的时候发现结果如下:PTA习题4-3 求分数序列前N项和 (易犯错点讲解以及注意事项)

是的,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;
}

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