q789423 发表于 2020-10-29 02:13:49

零基础小白求教S1E6课后麦子题~

求教大佬,小甲鱼指出最后得出的答案因为数据存放限制所以不是准确答案,请问可以这样写吗?

int main()
{
        int a;
      double b;
      double c;
        double sum = 0;

        for(a=0;a<64;a++)
        {
                b = pow(2,a);
                sum = sum + b;
        }
       
        c = sum/25000;
        printf("总共%.0f颗麦子\n",sum);
        printf("总共%.3f公斤麦子\n",c);
        return 0;

运行结果如图,但是我还是觉得不正确,既然第一格是1颗,总颗数的结果应该末位是1或者是个单数吧,求教大佬是什么原因,或者错在哪里,谢谢大佬~~

风过无痕1989 发表于 2020-10-29 08:18:36

系统精度问题,正确的这个数应该是:1844 6744 0737 0955 1615

吃点饭饭 发表于 2020-10-29 08:30:07

改用long double试试

风过无痕1989 发表于 2020-10-29 09:01:55

吃点饭饭 发表于 2020-10-29 08:30
改用long double试试

没有 long double 这种类型 !
使用 unsigned long long 型,DEV 运行后数值出错(太小),具体不知是我的系统问题,还是所有的DEV都是这样

sunrise085 发表于 2020-10-29 09:36:29

double运算的时候数据太大会有精度损失,只有15位有效位数,数据再长就有误差了。
这里应该用unsigned long long ,用这个类型的时候,就不要用pow函数了,因为这个函数的返回值是double,也可能会产生精度误差
#include<stdio.h>
#include<math.h>
int main()
{
    unsigned long long a;
    unsigned long long b=1;
    unsigned long long c;
    unsigned long long sum = 0;

    for(a=0;a<64;a++)
    {
      //b = pow(2,a);//用pow函数仍然可能会有精度问题,因为pow返回值是double类型建议直接每次循环乘以2
      sum = sum + b;
      b *= 2;
    }
   
    c = sum/25000;
    printf("总共%llu颗麦子\n",sum);
    printf("总共%llu公斤麦子\n",c);
    return 0;
}

风过无痕1989 发表于 2020-10-29 13:37:18

sunrise085 发表于 2020-10-29 09:36
double运算的时候数据太大会有精度损失,只有15位有效位数,数据再长就有误差了。
这里应该用unsigned lon ...

你的程序运行结果是 4294967295,数值还是太小

sunrise085 发表于 2020-10-29 14:21:19

风过无痕1989 发表于 2020-10-29 13:37
你的程序运行结果是 4294967295,数值还是太小

?????
运行结果正常啊
总共18446744073709551615颗麦子
总共737869762948382公斤麦子

q789423 发表于 2020-10-29 14:37:46

风过无痕1989 发表于 2020-10-29 08:18
系统精度问题,正确的这个数应该是:1844 6744 0737 0955 1615

如图,小甲鱼老师说不是准确的,而且我也算过,这个正好是long long 的最大值,并不是麦子的颗数吧?

q789423 发表于 2020-10-29 14:39:44

sunrise085 发表于 2020-10-29 14:21
?????
运行结果正常啊

如图,小甲鱼老师说不是准确的,而且我也算过,这个正好是long long 的最大值,并不是麦子的颗数吧?

sunrise085 发表于 2020-10-29 16:15:02

本帖最后由 sunrise085 于 2020-10-29 16:17 编辑

q789423 发表于 2020-10-29 14:39
如图,小甲鱼老师说不是准确的,而且我也算过,这个正好是long long 的最大值,并不是麦子的颗数吧?

小甲鱼说的不对哟。
unsigned long long的最大值的确是18446744073709551615
这个值是2^64-1
但是这个运算的结果是多少?你知道么?
2^0+2^1+2^2+……+2^63=2^64-1
这不就是这个结果么?
程序添加一行,打印每次循环的结果,你自己看看,有哪一步计算溢出么?
#include<stdio.h>
#include<math.h>
int main()
{
    unsigned long long a;
    unsigned long long b=1;
    unsigned long long c;
    unsigned long long sum = 0;

    for(a=0;a<64;a++)
    {
      //b = pow(2,a);//用pow函数仍然可能会有精度问题,因为pow返回值是double类型建议直接每次循环乘以2
      sum = sum + b;
      printf("b=%llu,sum=%llu\n",b,sum);
      b *= 2;
    }
   
    c = sum/25000;
    printf("总共%llu颗麦子\n",sum);
    printf("总共%llu公斤麦子\n",c);
    return 0;
}

q789423 发表于 2020-10-29 17:25:24

sunrise085 发表于 2020-10-29 16:15
小甲鱼说的不对哟。
unsigned long long的最大值的确是18446744073709551615
这个值是2^64-1


理解了,谢谢大佬,非常感谢!

风过无痕1989 发表于 2020-10-29 18:16:14

sunrise085 发表于 2020-10-29 16:15
小甲鱼说的不对哟。
unsigned long long的最大值的确是18446744073709551615
这个值是2^64-1


其实,这个题我做了很多次,都是因为32系统输出的结果太小,一直不敢吭声。

晚上,我安装一个win10,再安装一个VS2019,再来运行看看,到底输出是多少

q789423 发表于 2020-10-29 18:43:47

风过无痕1989 发表于 2020-10-29 18:16
其实,这个题我做了很多次,都是因为32系统输出的结果太小,一直不敢吭声。

晚上,我安装一个win10, ...

大佬辛苦了,非常感谢{:9_232:}

风过无痕1989 发表于 2020-10-29 22:31:42

q789423 发表于 2020-10-29 18:43
大佬辛苦了,非常感谢

刚安装完成,一个VS2015都搞2个多小时

风过无痕1989 发表于 2020-10-29 23:45:30

BV2015 装了我几个小时了,还没安装完

q789423 发表于 2020-10-30 01:49:04

风过无痕1989 发表于 2020-10-29 23:45
BV2015 装了我几个小时了,还没安装完

不好意思啊大佬,为了这么一个小问题,不用这么破费的{:9_229:}
页: [1]
查看完整版本: 零基础小白求教S1E6课后麦子题~