C# c减法即使是小数也不准确?

C# c减法即使是小数也不准确?,c#,math,C#,Math,我正在学习TDD,决定开始创建一个计算器类。 我先做了基本的,现在我在做平方根函数 我用这个方法得到根 我用几个数字测试了一下,我总能得到准确的答案。 这很容易理解 现在我遇到了一个奇怪的问题,因为对于一些数字,我得到了正确的答案,而对于一些数字,我没有 我调试了代码,发现使用减法时没有得到正确的答案 我用小数来得到最准确的结果 当我这样做时: 18 / 4.25 我目前得到:4.2352941176470588235294117647 应为的时间:4.23529411764705882352

我正在学习TDD,决定开始创建一个计算器类。 我先做了基本的,现在我在做平方根函数

我用这个方法得到根 我用几个数字测试了一下,我总能得到准确的答案。 这很容易理解

现在我遇到了一个奇怪的问题,因为对于一些数字,我得到了正确的答案,而对于一些数字,我没有

我调试了代码,发现使用减法时没有得到正确的答案

我用小数来得到最准确的结果

当我这样做时:

18 / 4.25
我目前得到:4.2352941176470588235294117647

应为的时间:4.2352941176470588235294117647059使用windows计算器

在路的尽头,这是我最接近18根的地方:

我的问题是:


我能比这个更精确吗?

浮点计算不精确。小数使精度更高,因为它们的长度为128位,但它们仍然是浮点数

比较两个浮点数不是使用==,而是:

static bool SameDecimal(decimal a, decimal b)
{
    return Math.Abs(a-b) < 1e-10;
}
此方法允许您比较两个小数。我假设1e-10对您来说是一个足够小的差异,它应该用于日常使用。4.2352941176470588235294117647包含29位数字

定义为具有28-29个有效数字。在十进制中存储一个更精确的数字是不可能的

你在哪个工程或科学领域工作,其中第30位及以上数字对整体计算的准确性具有重要意义

如果您展示了一些更实际的代码,它可能也会有所帮助。您所展示的唯一代码是18/4.25,它不能是代码中的实际表达式,因为第二个数字是双字面值,并且您不能将此表达式的结果分配给没有强制转换的十进制数


如果您需要任意精度,那么没有标准的BigRational类型,但是有一个。如果需要将分子和分母存储为两个独立的整数,可以使用它来构造BigRational类型。关于为什么还没有标准类型的一个猜测是,关于何时规范化这些有理数的决定可能会影响性能或相等性比较。

浮点算术就是这样工作的:当你说十进制时,你是指十进制类型吗?或者你用的是double还是float?@ThomasLevesque我的意思是十进制类型不是完美平方的数字的平方根是无理的。你不能指望以数字格式准确地存储它们。你说的是最接近减法的减法,但你似乎在执行除法。小数定义为有。它不能存储更多的数字。嗯,我想这比我想的要复杂得多。谢谢你提供的信息。我没有显示任何代码,因为我做了一些测试,它使用不同的数字,比如17甚至12.5。我仍然觉得我做不到,但现在我知道为什么了。另外,我对编程有点陌生,我这样做是为了好玩:如果你要这样做,你应该看看比率,而不是两个值的差,然后将比率与1进行比较。如果比率与1的绝对差值在1e-10范围内,则可能是有问题。但是,1e-20和2e-20的绝对差值为1e-20,但根据您的度量,这两个值是相等的。@并且始终使用其中一个值是不正确的。在某些情况下,它们都会产生误报/误报。您需要知道哪些类型的数字可能更准确。@Servy Fair。您能否提供一个例子,说明我的方法产生了假阳性或假阴性,但对于zmbq建议的方法,它可以正常执行?如果你的应用程序逻辑说所有的绝对值小于1E-10或任何被认为是0的值,那么你的方法会考虑不同的值,它们认为应该是相等的,通过差分方法可以被认为是相等的。当然,不同的方法仍然认为8E-11和1.5 E-10相等,尽管它可能不应该。这两种方法都存在一个问题,即即使不涉及NAN,平等也不是可传递的。如何比较浮点值取决于具体情况,没有任何规则适用于所有情况。
static bool SameDecimal(decimal a, decimal b)
{
    return Math.Abs(a-b) < 1e-10;
}