很纳闷这两种方式不是注释那段更简便?为什么不能输出
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:48 编辑
for(i=0;i<=64;i++) 必须把红色的 = 去掉!
i 绝不可以等于 64 了还在参与运算!
两种写法完全是一回事,sum 就是 mi,mi 就是 sum,二者在本质上是完全一样的。 jackz007 发表于 2021-11-29 19:44
for(i=0;i
我是想问为什么 我mi+=pow(2,i) 不可以输出 但是新弄了个变量之后赋值给新变量才可以输出 BlackWhite_idea 发表于 2021-11-29 19:58
我是想问为什么 我mi+=pow(2,i) 不可以输出 但是新弄了个变量之后赋值给新变量才可以输出
mi 是 2 平方 i 的值(视当时 i 大小)
sum 是从一开始到最后全部的值 本帖最后由 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 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: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;
} 其实答案是 36893488147419103230
用 Python 算:sum = 0
for i in range(64):
sum += (2 << i)
print(sum)结果:36893488147419103230而 18446744073709551614 只是到 62 而已 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:27
运行了下,如我所料:
'+=' : conversion from 'double' to 'unsigned long', possible loss of data
执行...
很遗憾各位语文阅读理解不及格! 本帖最后由 小鱼儿mxkk 于 2021-11-29 21:03 编辑
,,, 小鱼儿mxkk 发表于 2021-11-29 20:53
很遗憾各位语文阅读理解不及格!
将类型 double 转变成 unsigned long 会导致部分信息流失 小鱼儿mxkk 发表于 2021-11-29 20:53
很遗憾各位语文阅读理解不及格!
难道人家问的不是为啥不能直接用mi+=pow(2,i);代替上面的语句?
其实上面大家指出的所有问题都没错,但是就是没有回答题主的问题~~~ 傻眼貓咪 发表于 2021-11-29 21:06
将类型 double 转变成 unsigned long 会导致部分信息流失
不错,而且我发现一个问题,用C语言double变量算,仍然会丢失精度,按理说是36893488147419103230,但算的是36893488147419103000,显然后三位有问题,C语言毕竟不是干这个的呀,,,, 傻眼貓咪 发表于 2021-11-29 20:35
其实答案是 36893488147419103230
用 Python 算:结果:而 18446744073709551614 只是到 62 而已
老大,1 + 2 + 4 + 8 +... + 2 ^ 63 = 0xffffffffffffffff = 18446744073709551615 也是 unsigned long long 的极限值,这恐怕是常识吧? lightninng 发表于 2021-11-29 21:09
难道人家问的不是为啥不能直接用mi+=pow(2,i);代替上面的语句?
其实上面大家指出的所有问题都没错,但 ...
这个大家不包括我好吧,,, jackz007 发表于 2021-11-29 21:11
老大,1 + 2 + 4 + 8 +... + 2 ^ 63 = 0xffffffffffffffff = 18446744073709551615 也是 unsigned ...
所以说C语言不是让你当计算器用的,,,, 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() 准? 傻眼貓咪 发表于 2021-11-29 21:18
感谢指教,确实我的错了。
而且我又发现新知识了:位元运算为什么不比 pow() 准?
从结果看,不准的应该是pow吧,2的次方怎么可能是偶数呢,盲猜是因为二进制的问题~ lightninng 发表于 2021-11-29 21:22
从结果看,不准的应该是pow吧,2的次方怎么可能是偶数呢,盲猜是因为二进制的问题~
你的说法好像也不正确,pow(2, 0) = 1(2的0次方刚好就是 1 也就是奇数)