鱼C论坛

 找回密码
 立即注册
查看: 2831|回复: 15

[已解决]纠错。问题:求 1^2 + 2^3 + 3^4 + 4^5 + 5^6 的值?为啥我写的比正确答案少1?谢谢

[复制链接]
发表于 2022-8-26 12:02:36 | 显示全部楼层 |阅读模式

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

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

x
实际答案是16739.一下是我的中间代码,答案得到的是16738.哪里出错了呀?
…………………………………………完美分割线…………………………………………
        int i,temp;
        int sum=0;
        for(i=1;i<=5;i++)
        {
                temp=pow(i,i+1);
                sum+=temp;
        }
        printf("1^2+2^3+3^4+4^5+5^6=%d\n",sum);

…………………………………………完美分割线…………………………………………

感谢啄木鸟纠错,谢谢谢谢。


最佳答案
2022-8-26 12:39:09
本帖最后由 jackz007 于 2022-8-26 12:54 编辑

        问题出在 pow(5 , 6) = 15624,显然是错误的,正确值是 5 ^ 6 = 15625,整型数运算,最好避免用 pow()。
  1. #include <stdio.h>

  2. int main(void)
  3. {
  4.         int d , i , j , n                                ;
  5.         for(n = 0 , i = 1 ; i < 6 ; i ++) {
  6.                 for(d = i , j = 0 ; j < i ; j ++) d *= i ;
  7.                 n += d                                   ;
  8.         }
  9.         printf("%d\n" , n)                               ;
  10. }
复制代码

        显然,正确答案是16739
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2022-8-26 12:12:09 | 显示全部楼层
我这边的执行结果就是16739
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-8-26 12:16:20 | 显示全部楼层
你这个没问题, 答案是对的
  1. #include <bits/stdc++.h>
  2. using namespace std;

  3. int main(){
  4.         int sum = 0;

  5.         for(int i = 1; i <= 5; i++){
  6.                 sum += pow(i, i + 1);
  7.         }

  8.         printf("%d", sum);
  9.        
  10.         return 0;
  11. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-8-26 12:39:09 | 显示全部楼层    本楼为最佳答案   
本帖最后由 jackz007 于 2022-8-26 12:54 编辑

        问题出在 pow(5 , 6) = 15624,显然是错误的,正确值是 5 ^ 6 = 15625,整型数运算,最好避免用 pow()。
  1. #include <stdio.h>

  2. int main(void)
  3. {
  4.         int d , i , j , n                                ;
  5.         for(n = 0 , i = 1 ; i < 6 ; i ++) {
  6.                 for(d = i , j = 0 ; j < i ; j ++) d *= i ;
  7.                 n += d                                   ;
  8.         }
  9.         printf("%d\n" , n)                               ;
  10. }
复制代码

        显然,正确答案是16739
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-8-26 12:39:35 From FishC Mobile | 显示全部楼层
代码是对的
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-8-26 13:45:19 | 显示全部楼层
  1. int i,temp;
  2. int sum=0;
  3. for(i=1;i<=5;i++)
  4. {
  5.        temp=int(pow(i,i+1));
  6.        sum+=temp;
  7. }printf("1^2+2^3+3^4+4^5+5^6=%d\n",sum);
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-8-26 13:50:12 | 显示全部楼层
jackz007 发表于 2022-8-26 12:39
问题出在 pow(5 , 6) = 15624,显然是错误的,正确值是 5 ^ 6 = 15625,整型数运算,最好避免用 po ...

pow(5 , 6) = 15624 是在哪个编译器上出现的?这是编译器的bug吗?
新版本的gcc,pow(5 , 6) = 15625
  1. $ cat main.c
  2. #include <stdio.h>
  3. #include <math.h>

  4. int main(void) {
  5.     int x = pow(5, 6);
  6.     printf("%d\n", x);
  7.     printf("%f\n", pow(5, 6));
  8.     return 0;
  9. }
  10. $ gcc -g -Wall -o main main.c
  11. $ ./main
  12. 15625
  13. 15625.000000
  14. $ gcc --version
  15. gcc (GCC) 12.1.1 20220730
  16. Copyright (C) 2022 Free Software Foundation, Inc.
  17. This is free software; see the source for copying conditions.  There is NO
  18. warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

  19. $
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-8-26 13:52:36 | 显示全部楼层
亲~如果问题已解决别忘了设置最佳答案!
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-8-26 13:57:59 | 显示全部楼层
本帖最后由 jackz007 于 2022-8-26 14:04 编辑
人造人 发表于 2022-8-26 13:50
pow(5 , 6) = 15624 是在哪个编译器上出现的?这是编译器的bug吗?
新版本的gcc,pow(5 , 6) = 15625


        编译器是 tdm-gcc
  1. D:\[00.Exerciese.2022]\C>gcc --version
  2. gcc (tdm-1) 5.1.0
  3. Copyright (C) 2015 Free Software Foundation, Inc.
  4. This is free software; see the source for copying conditions.  There is NO
  5. warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


  6. D:\[00.Exerciese.2022]\C>
复制代码

        楼主的代码用 VC 6.0 编译后的运行结果也是正确的,可能是 tdm-gcc 本身存在隐患,估计楼主的问题也同样是出在编译器上。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-8-26 14:06:30 | 显示全部楼层
jackz007 发表于 2022-8-26 13:57
编译器是 tdm-gcc

        楼主的代码用 VC 6.0 编译后的运行结果也是正确的,可能是 tdm-g ...

嗯,我感觉也是编译器的问题
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-8-26 14:12:13 | 显示全部楼层
jackz007 发表于 2022-8-26 13:57
编译器是 tdm-gcc

        楼主的代码用 VC 6.0 编译后的运行结果也是正确的,可能是 tdm-g ...

确实,我用tdm-gcc也出现了同样的问题
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-8-26 17:30:59 | 显示全部楼层
非常感谢各位啄木鸟的回答,谢谢谢谢
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-8-26 17:37:28 | 显示全部楼层
jackz007 发表于 2022-8-26 13:57
编译器是 tdm-gcc

        楼主的代码用 VC 6.0 编译后的运行结果也是正确的,可能是 tdm-g ...

感谢您的回答,我初学还有点不懂,我在同一个文件编写以下参考代码,编译运行的结果又是16739呢?
……………………………完美分割线……………………………………………
        int result;

        result=pow(1,2)+pow(2,3)+pow(3,4)+pow(4,5)+pow(5,6);

        printf("结果是:%d",result);

……………………………完美分割线……………………………………………
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-8-26 19:35:32 | 显示全部楼层
本帖最后由 jackz007 于 2022-8-26 20:36 编辑
开心多巴胺 发表于 2022-8-26 17:37
感谢您的回答,我初学还有点不懂,我在同一个文件编写以下参考代码,编译运行的结果又是16739呢?
…… ...


       看来,问题就出在当 pow() 的两个参数是常数和变量时的计算结果存在着差异:
  1. #include <stdio.h>
  2. #include <math.h>

  3. int main(void)
  4. {
  5.         int i = 5 , j = 6                              ;
  6.         printf("pow(5 , 6) = %d\n" , (int) pow(5 , 6)) ;
  7.         printf("pow(i , j) = %d\n" , (int) pow(i , j)) ;
  8. }
复制代码

        编译、运行实况:
  1. D:\[00.Exerciese.2022]\C>g++ -o x x.c

  2. D:\[00.Exerciese.2022]\C>x
  3. pow(5 , 6) = 15625
  4. pow(i , j) = 15624

  5. D:\[00.Exerciese.2022]\C>
复制代码

        下面,通过反汇编研究一下原因:
  1. 00401350  /$  55                         push    ebp
  2. 00401351  |.  89E5                       mov     ebp, esp
  3. 00401353  |.  83E4 F0                    and     esp, FFFFFFF0
  4. 00401356  |.  83EC 30                    sub     esp, 30
  5. 00401359  |.  E8 22060000                call    00401980
  6. 0040135E  |.  C74424 2C 05000000         mov     dword ptr [esp+2C], 5                     <--- i = 5
  7. 00401366  |.  C74424 28 06000000         mov     dword ptr [esp+28], 6                     <--- j = 6
  8. 0040136E  |.  C74424 04 093D0000         mov     dword ptr [esp+4], 3D09                   <--- pow(5 , 6) 的计算结果 0x3D09 = 15625
  9. 00401376  |.  C70424 24304000            mov     dword ptr [esp], 00403024                ;  ASCII "pow(5 , 6) = %d
  10. "
  11. 0040137D  |?  E8 6E080000                call    <jmp.&msvcrt.printf>                      <--- printf()
  12. 00401382  |?  DB4424 28                  fild    dword ptr [esp+28]
  13. 00401386  |?  DB4424 2C                  fild    dword ptr [esp+2C]
  14. 0040138A  |?  D9C9                       fxch    st(1)
  15. 0040138C  |.  DD5C24 08                  fstp    qword ptr [esp+8]                        ; |
  16. 00401390  |.  DD1C24                     fstp    qword ptr [esp]                          ; |
  17. 00401393  |?  E8 60080000                call    <jmp.&msvcrt.pow>
  18. 00401398  |?  D97C24 1E                  fstcw   word ptr [esp+1E]
  19. 0040139C  |.  0FB74424 1E                movzx   eax, word ptr [esp+1E]                   ; |
  20. 004013A1  |?  B4 0C                      mov     ah, 0C
  21. 004013A3  |?  66:894424 1C               mov     word ptr [esp+1C], ax
  22. 004013A8  |.  D96C24 1C                  fldcw   word ptr [esp+1C]                        ; |
  23. 004013AC  |.  DB5C24 18                  fistp   dword ptr [esp+18]                       ; |
  24. 004013B0  |.  D96C24 1E                  fldcw   word ptr [esp+1E]                        ; |
  25. 004013B4  |.  8B4424 18                  mov     eax, dword ptr [esp+18]                  ; |
  26. 004013B8  |.  894424 04                  mov     dword ptr [esp+4], eax                   ; <--- 要显示的 pow(i , j) = 0x3D08 = 15624
  27. 004013BC  |?  C70424 35304000            mov     dword ptr [esp], 00403035                ;  ASCII "pow(i , j) = %d
  28. "
  29. 004013C3  |?  E8 28080000                call    <jmp.&msvcrt.printf>                     <--- printf()
  30. 004013C8  |?  B8 00000000                mov     eax, 0
  31. 004013CD   ?  C9                         leave
  32. 004013CE   .  C3                         retn
  33. 004013CF   ?  90                         nop
复制代码

       通过反汇编发现,pow(5 , 6) 的计算结果 15625 并非实际调用 pow() 计算而来,而是以一个常数的形式存在于可执行代码中,显然,这是编译器在编译代码的时候计算出了这个结果;而 pow(i , j) 的计算结果 15624 则是通过调用 pow() 函数而来,这就是两个结果存在差异的根本原因。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-8-26 21:10:24 | 显示全部楼层
jackz007 发表于 2022-8-26 19:35
看来,问题就出在当 pow() 的两个参数是常数和变量时的计算结果存在着差异:

        编译、 ...

哇瑟,太感谢你啦,虽然有些还看不懂,但大概明白啦,请接受小白的摩拜
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-8-27 15:47:12 | 显示全部楼层
偶数幂级数得结果必然是偶数
奇数幂级数得结果必然是奇数
3奇数 + 2偶数 = 奇数
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-4-23 22:14

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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