C# 如果结果不正确,加两倍

C# 如果结果不正确,加两倍,c#,.net,floating-point,double,addition,C#,.net,Floating Point,Double,Addition,我正在使用下面的代码,在某些神秘的情况下,添加的结果与预期的不一样: double _west = 9.482935905456543; double _off = 0.00000093248155508263153; double _lon = _west + _off; // check for the expected result Debug.Assert(_lon == 9.4829368379380981); // sometimes i get 9.48293685913086

我正在使用下面的代码,在某些神秘的情况下,添加的结果与预期的不一样:

double _west = 9.482935905456543;
double _off = 0.00000093248155508263153;
double _lon = _west + _off;

// check for the expected result
Debug.Assert(_lon == 9.4829368379380981);
// sometimes i get 9.48293685913086 for _lon (which is wrong)
我在应用程序中使用了一些本机DLL,我怀疑是某些DLL造成了这种“计算错误”,但我需要找出是哪一个。
谁能告诉我如何找出问题的根源吗?

double不完全准确,请尝试使用十进制


使用double和float-over-decimal的优点是性能

起初我认为这是一个舍入错误,但实际上是你的断言错了。尝试添加计算的整个结果,而不要任意四舍五入

试试这个:

using System;

class Program
{
    static void Main()
    {
        double _west = 9.482935905456543;
        double _off = 0.00000093248155508263153;
        double _lon = _west + _off;

        // check for the expected result
        Console.WriteLine(_lon == 9.48293683793809808263153);       
    }
}
但在将来,如果需要避免通常与
System.Single
System.Double
类型相关的舍入错误,最好使用
System.Decimal


尽管如此,这里的情况并非如此。通过在给定点任意舍入数字,您假设类型也将在同一点舍入,而这不是它的工作方式。浮点数存储到其最大表示容量,并且只有达到该阈值后才会进行舍入。

您正被舍入和精度问题所困扰。看见十进制可能会有所帮助。查看有关转换和舍入的详细信息

从MSDN:

将float或double转换为十进制时,源值将转换为十进制表示形式,并根据需要四舍五入到第28位小数后的最近数字。根据源值的值,可能会出现以下结果之一:

如果源值太小,无法表示为十进制,则结果将变为零

如果源值为NaN(不是数字)、无穷大或太大而无法表示为十进制,则会抛出OverflowException


问题是Double的精度只有15-16位(在您的示例中,您似乎需要更高的精度),而Decimal的精度是28-29位。如何在双精度和十进制之间进行转换?

您不能用二进制中的浮点来准确地表示十进制中的每个浮点数,这甚至与十进制数的“小”程度没有直接关系,有些数字不能很好地“适应”基数2

在大多数情况下,使用较长的位宽度会有所帮助,但并非总是如此

要以
十进制
(128位浮点)精度指定常量,请使用以下声明:

decimal _west = 9.482935905456543m;
decimal _off = 0.00000093248155508263153m;
decimal _lon = _west + _off;

我尝试使用小数,但将双精度转换为小数失败,因为小数会自动四舍五入给定值。如何避免这种情况?我在这里所说的同样适用于double:问题的根源是浮点精度设置错误。有人将浮点精度设置为24位,这会导致计算错误。使用_fpreset或_controlfp(MSVC运行时dll的)可以纠正这一点,但谁首先设置此精度仍然是个谜?另一个例子:0.8+0.4=1.20000000000000002-1
十进制
如何比
双精度
提供更好的性能?您的CPU知道如何处理
单数
双数
,但对
十进制
的所有操作都必须在内存中进行,内存速度较慢。@TT-我不知道我是怎么做到的,但我完全误解了您的答案-我道歉!删除(-1)和+1以指出性能问题!