简单计算,c#和delphi中的结果不同

Shu*_*arg 8 c# delphi

问题是,为什么这些代码片段会产生不同的结果?

private void InitializeOther()
{
  double d1, d2, d3;
  int i1;

  d1 = 4.271343859532459e+18;
  d2 = 4621333065.0;
  i1 = 5;

  d3 = (i1 * d1) - Utils.Sqr(d2);
  MessageBox.Show(d3.ToString());
}
Run Code Online (Sandbox Code Playgroud)

procedure TForm1.InitializeOther;
var d1, d2, d3 : Double;
    i1 : Integer;
begin
    d1:=4.271343859532459e+18;
    d2:=4621333065.0;
    i1:=5;

    d3:=i1*d1-Sqr(d2);
    ShowMessage(FloatToStr(d3));
end;
Run Code Online (Sandbox Code Playgroud)

Delphi代码给了我816,而c#代码给了我0.使用计算器,我得到775.任何人都能给我一个详细的解释吗?

非常感谢!

dan*_*gph 12

Delphi将中间值存储为Extended(80位浮点类型).此表达式是扩展的:

i1*d1-Sqr(d2);
Run Code Online (Sandbox Code Playgroud)

C#也是如此(我不知道).额外的精确度可能会产生影响.

  • 这正是发生了什么.根据Delphi帮助文件,.NET框架只能达到双精度.Delphi默认使用Extended. (4认同)

ang*_*son 11

请注意,您在此处处于Double数据类型精度的限制,这意味着此处的计算将不准确.

例:

d1 = 4.271343859532459e+18
Run Code Online (Sandbox Code Playgroud)

可以说是相同的:

d1 = 4271343859532459000
Run Code Online (Sandbox Code Playgroud)

所以:

d1 * i1 = 21356719297662295000
Run Code Online (Sandbox Code Playgroud)

实际上,.NET中的值将更像是这样的:

2.1356719297662296E+19
Run Code Online (Sandbox Code Playgroud)

注意那里的四舍五入.因此,在这个级别,你没有得到正确的答案.


jel*_*key 5

这当然不是对这种确切情况的解释,但它将有助于解释这个问题.

每个计算机科学家应该知道的浮点运算