BlackWhite_idea 发表于 2021-11-29 19:29:05

很纳闷这两种方式不是注释那段更简便?为什么不能输出

        int i;
        unsigned long long int mi = 0;
        unsigned long long int sum = 0;
        for(i=0;i<=64;i++)
        {
                mi = pow(2,i);
                sum += mi;
               
//                mi += pow(2,i);
        }
//        printf("舍罕王应该给予达依尔%llu粒麦子!!!",mi);
        printf("舍罕王应该给予达依尔%llu粒麦子!!!",sum);


纳闷这两种方式不是注释那段更简便?为什么不能输出

jackz007 发表于 2021-11-29 19:44:36

本帖最后由 jackz007 于 2021-11-29 19:48 编辑

       for(i=0;i<=64;i++) 必须把红色的 = 去掉!
       i 绝不可以等于 64 了还在参与运算!
       两种写法完全是一回事,sum 就是 mi,mi 就是 sum,二者在本质上是完全一样的。

BlackWhite_idea 发表于 2021-11-29 19:58:20

jackz007 发表于 2021-11-29 19:44
for(i=0;i

我是想问为什么 我mi+=pow(2,i) 不可以输出 但是新弄了个变量之后赋值给新变量才可以输出

傻眼貓咪 发表于 2021-11-29 20:19:13

BlackWhite_idea 发表于 2021-11-29 19:58
我是想问为什么 我mi+=pow(2,i) 不可以输出 但是新弄了个变量之后赋值给新变量才可以输出

mi 是 2 平方 i 的值(视当时 i 大小)
sum 是从一开始到最后全部的值

jackz007 发表于 2021-11-29 20:21:35

本帖最后由 jackz007 于 2021-11-30 09:25 编辑

BlackWhite_idea 发表于 2021-11-29 19:58
我是想问为什么 我mi+=pow(2,i) 不可以输出 但是新弄了个变量之后赋值给新变量才可以输出

      试试这个代码吧
#include <stdio.h>
#include <math.h>

int main(void)
{
      unsigned long long i , mi                        ;
      for(i = mi = 0 ; i < 64 ; i ++)
      {
                mi += (unsigned long long) pow(2 , i)      ;
      }
      printf("舍罕王应该给予达依尔%llu粒麦子!!!\n" , mi) ;
}
      编译、运行实况:
【vc】:
D:\00.Excise\C>cl x.c
用于 x86 的 Microsoft (R) C/C++ 优化编译器 19.28.29334 版
版权所有(C) Microsoft Corporation。保留所有权利。

x.c
Microsoft (R) Incremental Linker Version 14.28.29334.0
Copyright (C) Microsoft Corporation.All rights reserved.

/out:x.exe
x.obj

D:\00.Excise\C>x
舍罕王应该给予达依尔18446744073709551615粒麦子!!!

D:\00.Excise\C>
【gcc】:
D:\00.Excise\C>g++ -o x x.c

D:\00.Excise\C>x
舍罕王应该给予达依尔18446744073709551615粒麦子!!!

D:\00.Excise\C>

小鱼儿mxkk 发表于 2021-11-29 20:27:58

本帖最后由 小鱼儿mxkk 于 2021-11-29 21:16 编辑

运行了下,如我所料:
'+=' : conversion from 'double' to 'unsigned long', possible loss of data
执行 cl.exe 时出错.
编译器已经告诉你了,你在将一个double变量赋给int变量,丢失精度,出错!
值得一提的是,你两种方法都出错了,也就是说,问题不在于这两种思路,
你要知道,pow函数的返回值是double型的,double变量怎么能赋给int变量呢?
mi = pow(2,i);ormi+=pow(2,i);都错了!!!!你只有让mi定义为double变量才可以.
如下代码,再试试:
#include<stdio.h>
#include<math.h>
int main()
{   
       int i;
      double mi = 0;
      double sum = 0;
      for(i=1;i<=64;i++)
      {
             mi = pow(2,i);
            sum += mi;
               
             //   mi+=pow(2,i);
      }
      printf("舍罕王应该给予达依尔%.0lf粒麦子!!!\n",mi);
      printf("舍罕王应该给予达依尔%.0lf粒麦子!!!\n",sum);       
        return 0;
}

傻眼貓咪 发表于 2021-11-29 20:28:21

本帖最后由 傻眼貓咪 于 2021-11-29 20:29 编辑

#include <stdio.h>

int main()
{
    unsigned long long wheat = 0LL;
    for(size_t i = 0; i < 64; i++) wheat += (2<<i); // 为什么不用更简单的位元运算符呢?
    printf("舍罕王应该给予达依尔 %llu 粒麦子!!!", wheat);
    return 0;
}

傻眼貓咪 发表于 2021-11-29 20:35:13

其实答案是 36893488147419103230
用 Python 算:sum = 0
for i in range(64):
    sum += (2 << i)

print(sum)结果:36893488147419103230而 18446744073709551614 只是到 62 而已

lightninng 发表于 2021-11-29 20:49:27

BlackWhite_idea 发表于 2021-11-29 19:58
我是想问为什么 我mi+=pow(2,i) 不可以输出 但是新弄了个变量之后赋值给新变量才可以输出

仔细观察
mi=pow(2,i);
sum+=mi;
上面这段代码等价的代码应该是
sum += pow(2,i);
而不是你注释掉的
mi += pow(2,i);

小鱼儿mxkk 发表于 2021-11-29 20:53:05

小鱼儿mxkk 发表于 2021-11-29 20:27
运行了下,如我所料:
'+=' : conversion from 'double' to 'unsigned long', possible loss of data
执行...

很遗憾各位语文阅读理解不及格!

小鱼儿mxkk 发表于 2021-11-29 21:00:29

本帖最后由 小鱼儿mxkk 于 2021-11-29 21:03 编辑

,,,

傻眼貓咪 发表于 2021-11-29 21:06:41

小鱼儿mxkk 发表于 2021-11-29 20:53
很遗憾各位语文阅读理解不及格!

将类型 double 转变成 unsigned long 会导致部分信息流失

lightninng 发表于 2021-11-29 21:09:16

小鱼儿mxkk 发表于 2021-11-29 20:53
很遗憾各位语文阅读理解不及格!

难道人家问的不是为啥不能直接用mi+=pow(2,i);代替上面的语句?
其实上面大家指出的所有问题都没错,但是就是没有回答题主的问题~~~

小鱼儿mxkk 发表于 2021-11-29 21:10:07

傻眼貓咪 发表于 2021-11-29 21:06
将类型 double 转变成 unsigned long 会导致部分信息流失

不错,而且我发现一个问题,用C语言double变量算,仍然会丢失精度,按理说是36893488147419103230,但算的是36893488147419103000,显然后三位有问题,C语言毕竟不是干这个的呀,,,,

jackz007 发表于 2021-11-29 21:11:17

傻眼貓咪 发表于 2021-11-29 20:35
其实答案是 36893488147419103230
用 Python 算:结果:而 18446744073709551614 只是到 62 而已

   老大,1 + 2 + 4 + 8 +... + 2 ^ 63 = 0xffffffffffffffff = 18446744073709551615 也是 unsigned long long 的极限值,这恐怕是常识吧?

小鱼儿mxkk 发表于 2021-11-29 21:12:27

lightninng 发表于 2021-11-29 21:09
难道人家问的不是为啥不能直接用mi+=pow(2,i);代替上面的语句?
其实上面大家指出的所有问题都没错,但 ...

这个大家不包括我好吧,,,

小鱼儿mxkk 发表于 2021-11-29 21:15:09

jackz007 发表于 2021-11-29 21:11
老大,1 + 2 + 4 + 8 +... + 2 ^ 63 = 0xffffffffffffffff = 18446744073709551615 也是 unsigned ...

所以说C语言不是让你当计算器用的,,,,

傻眼貓咪 发表于 2021-11-29 21:18:23

jackz007 发表于 2021-11-29 21:11
老大,1 + 2 + 4 + 8 +... + 2 ^ 63 = 0xffffffffffffffff = 18446744073709551615 也是 unsigned ...

感谢指教,确实我的错了。

而且我又发现新知识了:#include <stdio.h>
#include <math.h>

int main()
{
    unsigned long long A = 0LL;
    unsigned long long B = 0LL;
    for(size_t i = 0; i < 64; i++) A += (2<<i);
    for(size_t i = 0; i < 64; i++) B += (unsigned long long)pow(2, i);
    printf("A: %llu\nB: %llu", A, B);
    return 0;
}A: 18446744073709551612
B: 18446744073709551615位元运算为什么不比 pow() 准?

lightninng 发表于 2021-11-29 21:22:38

傻眼貓咪 发表于 2021-11-29 21:18
感谢指教,确实我的错了。

而且我又发现新知识了:位元运算为什么不比 pow() 准?

从结果看,不准的应该是pow吧,2的次方怎么可能是偶数呢,盲猜是因为二进制的问题~

傻眼貓咪 发表于 2021-11-29 21:25:35

lightninng 发表于 2021-11-29 21:22
从结果看,不准的应该是pow吧,2的次方怎么可能是偶数呢,盲猜是因为二进制的问题~

你的说法好像也不正确,pow(2, 0) = 1(2的0次方刚好就是 1 也就是奇数)
页: [1] 2 3
查看完整版本: 很纳闷这两种方式不是注释那段更简便?为什么不能输出