当值似乎落在 0.5 括号内时,我在 delphi 舍入(从 ac# 项目中使用时)和结果的一致性方面遇到了一些严重问题,即它是向上还是向下舍入???
我创建了一个执行许多操作的 delphi DLL。其中一项操作的症结是(例如)
double := Round(double1 * double2);
其中 double1 = 1.9 和 double2 = 225 (从文件中读取的值)
我的计算器上的结果显示它应该是 427.5。delphi DLL 中的结果为 427。四舍五入,根据Round()的 delphi 文档,一切都很好
这些计算的值是针对代表表单的 Delphi(我相信的类)存储的。在上面这样的情况下
property SRDairy : Double read FSRDairy write FSRDairy;
该属性属于一堆类,并像这样被序列化到 Delphi DLL 中的缓冲区(AOvrFarm 是包含要序列化的所有项目的父级,包括我的 SRDairy 一个)
procedure GetResultString(AOvrFarm: TdataV6; outputStringBuffer: PChar; var
bufLen: Integer);
var
MyStrings : TStringList;
resultString : string;
begin
MyStrings := TStringList.Create;
try
AOvrFarm.SavetoStrings(MyStrings);
resultString := MyStrings.Text;
if outputStringBuffer = nil then
begin
bufLen := Length(resultString) + 1;
end
else
begin
StrLCopy(outputStringBuffer, PChar(resultString), bufLen - 1);
end;
finally
MyStrings.Free;
end;
end;
在这个 DLL 中完成了许多其他属性、表单(类)等。最后,该文件被序列化为一个字符串,该字符串返回给调用者(c#)应用程序,并使用类似(在 delphi 中)填充 refoutputStringBuffer:
StrLCopy(outputStringBuffer, PChar(resultString), bufLen - 1);
我的问题是当我从 ac# 应用程序调用这个 DLL 时。我得到的结果不是 427,而是 428。四舍五入!!!
德尔福签名:
函数 ConvertString(fileContents: PChar; fileExt: PChar; var outputStringBuffer: PChar; var outputStringBufferSize: Integer; var errorMsgBuffer: PChar; var errorMsgBufferSize: Integer): WordBool; 标准调用;出口;
我使用我的 c# 中的 DLL,如下所示:
[DllImport("OvrFileImport.dll",
CallingConvention = CallingConvention.StdCall,
CharSet = CharSet.Ansi)]
public static extern bool
ConvertString(
string fileContents,
string fileExt,
ref string refputStringBuffer,
ref int outputStringBufferSize,
ref string errorMsgBuffer,
ref int errorMsgBufferSize);
转换字符串被调用一次以获取缓冲区大小,然后再次调用以填充缓冲区。在第二次通话中,我注意到了不同之处。当使用来自 Test Delphi 项目的相同 DLL 时,我得到 427(而不是 c# 428)。
我已经尝试针对任何 CPU 构建我的 c#,并且只是 x86,以防它是某种 cpu 64 位问题,因为我的 PC 是 64 位机器。
有没有人遇到过这种事情,如果有,他们有什么办法解决吗?
编辑 - 答案
正如 David Heffernan 所提到的,从 c# 调用 DLL 时使用的控制字与从另一个 Delphi 应用程序调用时使用的控制字不同。从 c# 调用时使用的控制字实际上是 639 美元。
不幸的是,将控制字设置为 $1372 会导致我的 c# 应用程序在调试时出现问题,即它导致本地的监视窗口显示所有变量的“由于堆栈溢出状态而无法评估”异常。我发现了一篇文章——奇怪的浮点结果,它讨论了这个问题,因此将其改为 $133F(它解决了浮点差异和 c# 调试问题)。
代码是:
begin
cw := Get8087CW;
Set8087CW($133F);
....
finally
Set8087CW(cw);