|
发表于 2022-8-26 19:35:32
|
显示全部楼层
本帖最后由 jackz007 于 2022-8-26 20:36 编辑
看来,问题就出在当 pow() 的两个参数是常数和变量时的计算结果存在着差异:
- #include <stdio.h>
- #include <math.h>
- int main(void)
- {
- int i = 5 , j = 6 ;
- printf("pow(5 , 6) = %d\n" , (int) pow(5 , 6)) ;
- printf("pow(i , j) = %d\n" , (int) pow(i , j)) ;
- }
复制代码
编译、运行实况:
- D:\[00.Exerciese.2022]\C>g++ -o x x.c
- D:\[00.Exerciese.2022]\C>x
- pow(5 , 6) = 15625
- pow(i , j) = 15624
- D:\[00.Exerciese.2022]\C>
复制代码
下面,通过反汇编研究一下原因:
- 00401350 /$ 55 push ebp
- 00401351 |. 89E5 mov ebp, esp
- 00401353 |. 83E4 F0 and esp, FFFFFFF0
- 00401356 |. 83EC 30 sub esp, 30
- 00401359 |. E8 22060000 call 00401980
- 0040135E |. C74424 2C 05000000 mov dword ptr [esp+2C], 5 <--- i = 5
- 00401366 |. C74424 28 06000000 mov dword ptr [esp+28], 6 <--- j = 6
- 0040136E |. C74424 04 093D0000 mov dword ptr [esp+4], 3D09 <--- pow(5 , 6) 的计算结果 0x3D09 = 15625
- 00401376 |. C70424 24304000 mov dword ptr [esp], 00403024 ; ASCII "pow(5 , 6) = %d
- "
- 0040137D |? E8 6E080000 call <jmp.&msvcrt.printf> <--- printf()
- 00401382 |? DB4424 28 fild dword ptr [esp+28]
- 00401386 |? DB4424 2C fild dword ptr [esp+2C]
- 0040138A |? D9C9 fxch st(1)
- 0040138C |. DD5C24 08 fstp qword ptr [esp+8] ; |
- 00401390 |. DD1C24 fstp qword ptr [esp] ; |
- 00401393 |? E8 60080000 call <jmp.&msvcrt.pow>
- 00401398 |? D97C24 1E fstcw word ptr [esp+1E]
- 0040139C |. 0FB74424 1E movzx eax, word ptr [esp+1E] ; |
- 004013A1 |? B4 0C mov ah, 0C
- 004013A3 |? 66:894424 1C mov word ptr [esp+1C], ax
- 004013A8 |. D96C24 1C fldcw word ptr [esp+1C] ; |
- 004013AC |. DB5C24 18 fistp dword ptr [esp+18] ; |
- 004013B0 |. D96C24 1E fldcw word ptr [esp+1E] ; |
- 004013B4 |. 8B4424 18 mov eax, dword ptr [esp+18] ; |
- 004013B8 |. 894424 04 mov dword ptr [esp+4], eax ; <--- 要显示的 pow(i , j) = 0x3D08 = 15624
- 004013BC |? C70424 35304000 mov dword ptr [esp], 00403035 ; ASCII "pow(i , j) = %d
- "
- 004013C3 |? E8 28080000 call <jmp.&msvcrt.printf> <--- printf()
- 004013C8 |? B8 00000000 mov eax, 0
- 004013CD ? C9 leave
- 004013CE . C3 retn
- 004013CF ? 90 nop
复制代码
通过反汇编发现,pow(5 , 6) 的计算结果 15625 并非实际调用 pow() 计算而来,而是以一个常数的形式存在于可执行代码中,显然,这是编译器在编译代码的时候计算出了这个结果;而 pow(i , j) 的计算结果 15624 则是通过调用 pow() 函数而来,这就是两个结果存在差异的根本原因。 |
|