Jef*_*ope 15 delphi 32bit-64bit delphi-xe2
我们最近开始创建64位构建的应用程序.在比较测试期间,我们发现64位构建的计算方式不同.我有一个代码示例,演示了两个版本之间的差异.
var
currPercent, currGross, currCalcValue : Currency;
begin
currGross := 1182.42;
currPercent := 1.45;
currCalcValue := (currGross * (currPercent * StrToCurr('.01')));
ShowMessage(CurrToStr(currCalcValue));
end;
Run Code Online (Sandbox Code Playgroud)
如果您在32位版本中逐步执行此操作,则使用17.1451计算currCalcValue,而使用17.145返回64位版本.
为什么64位构建不计算额外的小数位?所有变量都定义为4个十进制货币值.
Dav*_*nan 14
这是我的SSCCE基于您的代码.请注意控制台应用程序的使用.让生活更简单.
{$APPTYPE CONSOLE}
uses
SysUtils;
var
currPercent, currGross, currCalcValue : Currency;
begin
currGross := 1182.42;
currPercent := 1.45;
currCalcValue := (currGross * (currPercent * StrToCurr('.01')));
Writeln(CurrToStr(currCalcValue));
Readln;
end.
Run Code Online (Sandbox Code Playgroud)
现在看一下生成的代码.前32位:
Project3.dpr.13: currCalcValue := (currGross * (currPercent * StrToCurr('.01')));
0041C409 8D45EC lea eax,[ebp-$14]
0041C40C BADCC44100 mov edx,$0041c4dc
0041C411 E8A6A2FEFF call @UStrLAsg
0041C416 8B1504E74100 mov edx,[$0041e704]
0041C41C 8B45EC mov eax,[ebp-$14]
0041C41F E870AFFFFF call StrToCurr
0041C424 DF7DE0 fistp qword ptr [ebp-$20]
0041C427 9B wait
0041C428 DF2DD83E4200 fild qword ptr [$00423ed8]
0041C42E DF6DE0 fild qword ptr [ebp-$20]
0041C431 DEC9 fmulp st(1)
0041C433 DF2DE03E4200 fild qword ptr [$00423ee0]
0041C439 DEC9 fmulp st(1)
0041C43B D835E4C44100 fdiv dword ptr [$0041c4e4]
0041C441 DF3DE83E4200 fistp qword ptr [$00423ee8]
0041C447 9B wait
和64位:
Project3.dpr.13: currCalcValue := (currGross * (currPercent * StrToCurr('.01')));
0000000000428A0E 488D4D38 lea rcx,[rbp+$38]
0000000000428A12 488D1513010000 lea rdx,[rel $00000113]
0000000000428A19 E84213FEFF call @UStrLAsg
0000000000428A1E 488B4D38 mov rcx,[rbp+$38]
0000000000428A22 488B155F480000 mov rdx,[rel $0000485f]
0000000000428A29 E83280FFFF call StrToCurr
0000000000428A2E 4889C1 mov rcx,rax
0000000000428A31 488B0510E80000 mov rax,[rel $0000e810]
0000000000428A38 48F7E9 imul rcx
0000000000428A3B C7C110270000 mov ecx,$00002710
0000000000428A41 48F7F9 idiv rcx
0000000000428A44 488BC8 mov rcx,rax
0000000000428A47 488B0502E80000 mov rax,[rel $0000e802]
0000000000428A4E 48F7E9 imul rcx
0000000000428A51 C7C110270000 mov ecx,$00002710
0000000000428A57 48F7F9 idiv rcx
0000000000428A5A 488905F7E70000 mov [rel $0000e7f7],rax
请注意,32位代码在FPU上执行算术,但64位代码使用整数运算执行它.这是关键的区别.
在32位代码中,执行以下计算:
现在,在64位代码中,它有点不同.因为我们一直使用64位整数.它看起来像这样:
所以问题是64位编译器在每个中间步骤中除以10,000.大概是为了避免溢出,更可能是64位整数而不是浮点寄存器.
是这样做的计算:
100 * 14,500 * 11,824,200 / 10,000 / 10,000
Run Code Online (Sandbox Code Playgroud)
它会得到正确的答案.
| 归档时间: |
|
| 查看次数: |
949 次 |
| 最近记录: |