加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 具有相同输入的浮点错误

发布时间:2020-12-15 22:00:06 所属栏目:百科 来源:网络整理
导读:这有点奇怪.我在不同的时间为相同的代码位获得相同输入的不同输出. 这是一个非常简单的计算,只是在一个处理指南针类型的东西的类中,以度为单位得到一个给定角度的Radians. 它开始是这样的: public double Radians { get { return this.heading_degrees * Ma
这有点奇怪.我在不同的时间为相同的代码位获得相同输入的不同输出.

这是一个非常简单的计算,只是在一个处理指南针类型的东西的类中,以度为单位得到一个给定角度的Radians.
它开始是这样的:

public double Radians  
{  
    get   
    {  
        return this.heading_degrees * Math.PI / 180;  
    }  
    set  
    {  
       this.heading_degrees = value * 180 / Math.PI;  
       normalize();  
    }  
}

(heading_degrees是Compass类中的成员变量)
看起来不错吧?
除了在获得给定角度的Radians时得到不同的结果.
所以我深入挖掘并更改了代码,’get’现在看起来像这样:

get  
{  
    //double hd = heading_degrees;  
    double hd = 180.0;  
    //double pi = Math.PI;  
    double pi180 = 0.01745329251; //pi / 180;  
    double result = hd * pi180;  
    //double result = 3.14159265359;  
    return result;  
    //return heading_degrees * Math.PI / 180;  
}

正如你可以从注释掉的行中我尝试了不同的东西来尝试并深入到底.
设置double result = 3.14159265359;确实一直返回3.14159265359,
但是返回双重结果= hd * pi180;如上面的代码中没有返回一致的结果.你可以看到标题度正好是180.0现在只是用于测试并证明输入完全相同.
当我第一次点击这段代码时,我得到了这个结果:
结果= 3.1415926518
我第二次得到这个:
结果= 3.1415927410125732

我在两台计算机上尝试过这个,试图看看问题是否是环境问题,我还没有能够在不同的IDE上测试它(目前使用VS express 2012)
任何人都有任何想法,为什么会发生这种情况?
我没有在任何地方进行线程化(即使我是,如果在当前的代码迭代中,它将如何更改结果,输入设置为180.0?)
我似乎发现的一个小线索是,对代码进行少量更改(即使用Math.PI而不是3.3.14159 ……等)会在第一次更改结果.但是第二次结果似乎始终是3.1415927410125732

为极长的啰嗦道歉道歉.

其他说明:
第二次运行只是程序中调用此函数的另一个地方.调试和发布之间没有区别.
使用.net 4

更多测试:

如果获取代码是:

get{ 
double result = 180.0d * 0.01745329251d;
return result;
}

结果是一致的.更准确.

如果获取代码是:

get{
double hd = 180.0d;
double result = hd * 0.01745329251d;
return result;
}

结果不一致.

如果我做:

get{
double hd = 180.0d;
double result = (float)(hd * 0.01745329251d);
return result;
}

结果是一致的,但精度较低.

请注意,在上面的测试中,变量都是getter的本地变量!
还要注意,当我运行完整代码时,我似乎只是出现了不一致,这是关于我如何存储getter所属的对象导致这种情况的原因吗?
我想我需要再次阅读Eric Lippert对其中一个答案的回复. Eric如果你把这两个回复写成答案,我可能会把它们标记为答案.特别是因为上面的最后一个例子正在做你所说的演员.

这看起来像黄金:
Fixed point math in c#?
并且似乎回答了如何摆脱我挖出来的洞.
特别是因为我发现有很多很多类似上面的功能给我带来了同样的头痛.

解决方法

不知道为什么我的脑子直接跳到发布与调试,但即使在同一个处理器上,硬件本身也是不一致的. Is floating-point math consistent in C#? Can it be?简而言之,中间人可以在某些时候使用更高精度的值,根据事物被截断的时间产生不同的结果.

老答案:
发布与调试有所不同,请查看此内容.

Float/double precision in debug/release modes

如果您需要高度一致的结果,您可能希望小数不是双倍的.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读