鱼C论坛

 找回密码
 立即注册
查看: 2043|回复: 50

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

[复制链接]
发表于 2021-11-29 19:29:05 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
        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);


纳闷这两种方式不是注释那段更简便?为什么不能输出
最佳答案
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>
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-11-29 19:44:36 | 显示全部楼层
本帖最后由 jackz007 于 2021-11-29 19:48 编辑

       for(i=0;i<=64;i++) 必须把红色的 = 去掉!
       i 绝不可以等于 64 了还在参与运算!
       两种写法完全是一回事,sum 就是 mi,mi 就是 sum,二者在本质上是完全一样的。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-11-29 19:58:20 | 显示全部楼层

我是想问为什么 我mi+=pow(2,i) 不可以输出 但是新弄了个变量之后赋值给新变量才可以输出
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

mi 是 2 平方 i 的值(视当时 i 大小)
sum 是从一开始到最后全部的值
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 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>
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 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);  or  mi+=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;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 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;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-11-29 20:35:13 | 显示全部楼层
其实答案是 36893488147419103230
用 Python 算:
sum = 0
for i in range(64):
    sum += (2 << i)

print(sum)
结果:
36893488147419103230
而 18446744073709551614 只是到 62 而已
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 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);
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

很遗憾各位语文阅读理解不及格!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-11-29 21:00:29 | 显示全部楼层
本帖最后由 小鱼儿mxkk 于 2021-11-29 21:03 编辑

,,,
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-11-29 21:06:41 | 显示全部楼层
小鱼儿mxkk 发表于 2021-11-29 20:53
很遗憾各位语文阅读理解不及格!

将类型 double 转变成 unsigned long 会导致部分信息流失
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-11-29 21:09:16 | 显示全部楼层
小鱼儿mxkk 发表于 2021-11-29 20:53
很遗憾各位语文阅读理解不及格!

难道人家问的不是为啥不能直接用mi+=pow(2,i);代替上面的语句?
其实上面大家指出的所有问题都没错,但是就是没有回答题主的问题~~~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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


不错,而且我发现一个问题,用C语言double变量算,仍然会丢失精度,按理说是36893488147419103230,但算的是36893488147419103000,显然后三位有问题,C语言毕竟不是干这个的呀,,,,
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 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 的极限值,这恐怕是常识吧?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

这个大家不包括我好吧,,,
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-11-29 21:15:09 | 显示全部楼层
jackz007 发表于 2021-11-29 21:11
老大,1 + 2 + 4 + 8 +... + 2 ^ 63 = 0xffffffffffffffff = 18446744073709551615 也是 unsigned ...

所以说C语言不是让你当计算器用的,,,,
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 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() 准?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-11-29 21:22:38 | 显示全部楼层
傻眼貓咪 发表于 2021-11-29 21:18
感谢指教,确实我的错了。

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

从结果看,不准的应该是pow吧,2的次方怎么可能是偶数呢,盲猜是因为二进制的问题~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

你的说法好像也不正确,pow(2, 0) = 1(2的0次方刚好就是 1 也就是奇数)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-14 01:51

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表