您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

为什么此浮点计算在不同的计算机上给出不同的结果?

为什么此浮点计算在不同的计算机上给出不同的结果?

这是来自4.1.6节的一些有趣的C#规范:

浮点运算可以比运算的结果类型更高的精度执行。例如,某些硬件体系结构支持比双精度类型具有更大范围和精度的“扩展”或“长双精度”浮点类型,并使用此更高精度类型隐式执行所有浮点运算。只有付出过高的性能代价,才能使此类硬件体系结构以较低的精度执行浮点运算,而不是要求实现同时牺牲性能和精度,而C#允许将高精度类型用于所有浮点运算。 。除了提供更精确的结果外,这几乎没有任何可测量的效果

由于对吊顶的调用,这可能是“可测量的效果”之一。正如其他人所指出的那样,采用浮点数的上限会将0.000000002的差异放大九个数量级,因为它将15.99999999转换为16,将16.00000001转换为17。两个在操作前稍有不同的数字其后相差很大。微小的差异可能是由于不同的机器在其浮点运算中可能具有或多或少的“额外精度”这一事实造成的。

一些相关的问题:

C#XNA Visual Studio:“发布”和“调试”模式之间的区别?

CLR JIT优化违反因果关系吗?

为了解决您的特定问题,即如何从float中计算宽高比:我可能会以完全不同的方式解决此问题。我会做一个这样的表:

struct Ratio
{
    public int X { get; private set; }
    public int Y { get; private set; }
    public Ratio (int x, int y) : this()
    {
        this.X = x;
        this.Y = y;
    }
    public double AsDouble() { return (double)X / (double)Y; }
}

Ratio[] commonRatios = { 
   new Ratio(16, 9),
   new Ratio(4, 3), 
   // ... and so on, maybe the few hundred most common ratios here. 
   // since you are pinning results to be less than 20, there cannot possibly
   // be more than a few hundred.
};

现在您的实现是

public string AspectRatioAsString(double ratio)      
{ 
    var results = from commonRatio in commonRatios
                  select new {
                      Ratio = commonRatio, 
                      Diff = Math.Abs(ratio - commonRatio.AsDouble())};

    var smallestResult = results.Min(x=>x.Diff);

    return String.Format("{0}:{1}", smallestResult.Ratio.X, smallestResult.Ratio.Y);
}

请注意,代码现在的读取方式非常类似于您要执行的操作:从此常用比率列表中,选择一个将给定比率与常用比率之间的差异最小化的比率。

其他 2022/1/1 18:15:11 有561人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶