不算高精度浮点和

一次做题笔记

洛谷的一道50000个浮点数之和题目

内容涉及到long double,小数转unsigned long long

第一次是这么做的

直接声明两个long double变量, 为什么不是double?
因为似乎double只有大约17位有效数字, 而long double精度更高

代码是这样的

#include <bits/stdc++.h>
using namespace std;

int main()
{
    long double a, b = 0;
    while(scanf("%Lf", &a) != EOF) {
        b += a;
    }
    printf("%.5Lf", b);
}

只通过了80%的样例, 为什么会这样呢?
说实话我也不知道, 精度的原因?

第二次, 看了题解之后是这么做的

把每次的a都乘1e6, 结果又除以1e6
P.S. 因为题目说了每个数据不超过小数后6位(我刚开始遗漏了)

我把乘1e6换成1e5, 1e7…1e16都错了部分样例

这是为什么?我还没搞懂。不是说long double精度够了吗? 把它的位数提为整数和还是小数有什么不一样吗?

我果然还是孤陋寡闻

这是我的代码

#include <bits/stdc++.h>

using namespace std;

int main()
{
    long double a, b = 0;
    while(scanf("%Lf", &a) != EOF) {
        b += a*1e6;
    }
    printf("%.5Lf", b/1e6);
}

题解中那个人的思路就是这样了, 不过他用了一种递归主函数的方法来读取数据

我觉得值得学习

#include<cstdio>
long double a,sum;//long double 保证精度没毛病
int main()
{
    if(scanf("%Lf",&a)!=EOF)
    {
        sum+=a*1000000;//去除小数部分,直接乘,变成整数
        main();//核心代码 
    }
    else printf("%.5Lf",sum/1000000);//除回来
    return 0;
}

第三种, 还是题解中别人的代码

他没用long double, 而是用了unsigned long long, 根据题目提供的数据范围, unsigned long long 刚好够用, 或许这是题目故意卡的数据

思路是: 把读取的每一个double扩大变为unsigned long long, 相加后四舍五入, 外加格式控制

这种思路或者说思维方式值得借鉴

#include <bits/stdc++.h>
using namespace std;
int BASE=1e6;
unsigned long long sum=0;
double term;
int main(int argc, char const *argv[])
{
    while(scanf("%lf",&term)!=EOF)
    {
        term*=BASE;//最多六位小数,转成整数
        sum+=(unsigned long long)term;
    }
    //要求打印5为小数,去掉最后一位
    if(sum%10>=5) sum=sum/10+1;
    else sum=sum/10;
    BASE/=10;
    //%05llu让不足五位小数的部分用0补全
    printf("%llu.%05llu\n",sum/BASE,sum%BASE);
    return 0;
}

可见,解决问题的方法可以有很多种

其实做题最重要的不是做出题目来, 而是在做题的过程中学会思考,运用所学的知识从各种方面思考解决问题,锻炼自己的思维能力。

能力比知识更重要

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值