Chan歪歪520 发表于 2020-1-16 21:42:54

S1E6作业舍罕王的失算

本帖最后由 Chan歪歪520 于 2020-1-17 22:33 编辑

#include <stdio.h>
#include <math.h>

int main()
{
      unsigned long long sum = 0;
      unsigned long long int temp;
      unsigned long long int weight;
      int i;

      for (i=0; i < 64; i++)
      {
                temp = pow(2,i);
                sum = sum + temp;
      }

      weight = sum /25000;

      printf("should give %d wheats\n",sum);
      printf("these wheats wheigh %d kgs\n",weight);

      return 0;
}


显示pow未定义???请问是怎么回事啊?

/tmp/ccMDamyO.o: In function `main':
test2.c:(.text+0x35): undefined reference to `pow'
collect2: ld returned 1 exit status

jackz007 发表于 2020-1-16 21:52:30

本帖最后由 jackz007 于 2020-1-17 11:20 编辑

         在 Linux 系统环境下,用 gcc 编译 C / C++ 代码,如果用到了数学库,必须在编译命令中使用 -lm 选项加以声明。
         用下面的命令编译试试:
gcc -lm -o test2 test2.c
         代码中使用数学库是为了计算 2 的指数幂,其实,2 ^ 0 + a ^ 1 + 2 ^ 2 + 2 ^ 3 + ... + 2 ^ 63 = 0xffffffffffffffff,这个数值很特殊,是一个 64 位无符号整型数所能表达的极限值。

         代码中定义的变量都是 unsigned long long,但是,最后在 printf() 中所使用的格式描述符却都是 "%d","%d" 只能把变量当作 32 位变量来显示,在变量的数值超过 32 位的时候,就会出现显示不全的问题,这个显然是隐患!

         于是,我帮楼主修改了一个版本,楼主可以参考一下
#include <stdio.h>

int main(void)
{
      unsigned long long sum                              ;
      sum = 0xffffffffffffffff                              ; // 其实,代码中的循环就是为了计算出这个数值
      printf("should give %llu wheats\n" , sum)             ;
      printf("these wheats wheigh %llu kgs\n" , sum / 2500) ;
}

      编译这个代码,命令行中就可以不用出现 -lm 选项了。

徐颖科 发表于 2020-1-16 21:53:50

temp类型是不是应该是double ?

Chan歪歪520 发表于 2020-1-17 10:12:35

徐颖科 发表于 2020-1-16 21:53
temp类型是不是应该是double ?

谢谢你呀!用double 和 int 应该都可以吧~

Chan歪歪520 发表于 2020-1-17 10:33:09

jackz007 发表于 2020-1-16 21:52
在 Linux 系统环境下,用 gcc 编译 C / C++ 代码,如果用到了数学库,必须在编译命令中使用 -lm...

谢谢!
gcc 添加了 -lm选项后运行结果:
should give -1 wheats
these wheats wheigh -1323537122 kgs

结果是-1是因为溢出了嘛?

运行了您给我的参考程序:
test3.c: In function ‘main’:
test3.c:6: warning: integer constant is too large for ‘long’ type

是不是long long 也装不下这么大的数

jackz007 发表于 2020-1-17 10:59:53

本帖最后由 jackz007 于 2020-1-17 11:22 编辑

Chan歪歪520 发表于 2020-1-17 10:33
谢谢!
gcc 添加了 -lm选项后运行结果:



      先把在 printf() 中出现的所有 %d 统统改成 %llu 然后再编译运行看看。

      编译、运行一下以下代码,看看会输出多少。
#include <stdio.h>

main()
{
      printf("the size of long long is %d\n" , sizeof(long long)) ;
}

      如果是 4 ,意味着 long long 在你的程序中只是一个 32 位的整型,无法使用 64 位整型数,不具备解这道题的先决条件。如果是 8 ,意味着楼主抄写我的代码时没有抄对,0xffffffffffffffff 一共有 16 个 f(16 个 f 是 8 个字节,正好 64 位),不能多也不能少。

Chan歪歪520 发表于 2020-1-17 14:57:41

jackz007 发表于 2020-1-17 10:59
先把在 printf() 中出现的所有 %d 统统改成 %llu 然后再编译运行看看。

      编译、运行 ...

sizeof结果是8,修改成了%u结果对啦,不过会有warning
test3.c: In function ‘main’:
test3.c:6: warning: integer constant is too large for ‘long’ type
should give4294967295 wheats

是不是因为之前程序里是%d,把0xffffffffffffffff当成负数算了呀,不管是否声明了 signed 还是 unsigned。之后改成%u就是无符号十进制数形式输出。
十分感谢呀!

jackz007 发表于 2020-1-17 15:06:43

本帖最后由 jackz007 于 2020-1-17 15:09 编辑

Chan歪歪520 发表于 2020-1-17 14:57
sizeof结果是8,修改成了%u结果对啦,不过会有warning

是不是因为之前程序里是%d,把0xffffffffffffff ...

            你把 0xffffffffffffffff 写成 0xffffffffffffffffLL 再试试看,是否还有警告,格式描述符必须不折不扣的写成 %llu ,绝不可以写成 %u,这一点必须注意!!!

Chan歪歪520 发表于 2020-1-17 17:22:53

jackz007 发表于 2020-1-17 15:06
你把 0xffffffffffffffff 写成 0xffffffffffffffffLL 再试试看,是否还有警告,格式描述符 ...

写成0xffffffffffffffffLL就没有警告了,请问是为什么呀?
请问是不是long long 型常量没有严格按照 %llu或者%lld输出,输出会出错呀?

jackz007 发表于 2020-1-17 17:32:47

Chan歪歪520 发表于 2020-1-17 17:22
写成0xffffffffffffffffLL就没有警告了,请问是为什么呀?
请问是不是long long 型常量没有严格按照 %ll ...

      常量会被视为普通整型数,添加LL后缀可以声明为 64 位长整型数。

Chan歪歪520 发表于 2020-1-17 22:15:42

jackz007 发表于 2020-1-17 17:32
常量会被视为普通整型数,添加LL后缀可以声明为 64 位长整型数。

知道啦!谢谢呀!
页: [1]
查看完整版本: S1E6作业舍罕王的失算