【问题标题】:Compare two doubles with different number of decimal places in C#在 C# 中比较两个具有不同小数位数的双精度数
【发布时间】:2014-08-01 01:02:23
【问题描述】:

我想在 C# 中比较两个双精度数 ab(例如 b 有更多小数位):如果我将数字 b 舍入到 @ 的小数位数987654326@ 如果它们相同,我应该得到相同的数字。示例:

double a = 0.123;
double b = 0.1234567890;

应该是一样的。

double a = 0.123457
double b = 0.123456789

应该是一样的。

我不会写

if(Math.Abs(a-b) < eps)

因为我不知道如何计算精度eps

【问题讨论】:

  • 你在决定小数位数吗?
  • 您的示例可能设置错误。。a 已经“四舍五入”到与b 相同的小数位数,因为b 具有更高的精度...所以我'不太确定你在问什么。
  • 双精度不包括有效数字的概念。它使用了它所拥有的所有精度。考虑例如double a = 1.030;
  • @entropic 我编辑了这个问题。
  • 这似乎更像是一个关于有效数字的问题。此页面可能会有所帮助:Formatting numbers with significant figures in C#

标签: c# precision double-precision


【解决方案1】:

如果我已经理解您想要什么,您可以将小数点前的数字移动到“较小”(即具有最低有效数字的数字)是一个整数,然后比较: 即在某个班级...

static bool comp(double a, double b)
{
    while((a-(int)a)>0 && (b - (int)b)>0)
    {
        a *= 10;
        b *= 10;
    }
    a = (int)a;
    b = (int)b;
    return a == b;
}

编辑

显然在 double 上调用 (int)x 是自找麻烦,因为 double 可以存储比 int 更大的数字。这样更好:

while((a-Math.Floor(a))>0 && (b - Math.Floor(b))>0)
//...

【讨论】:

  • 我觉得这个功能不好。例如,我有 b=1.63329,当它乘以 2 乘以 10 时,我得到 b=163.32899999999998,所以 while 循环没有完成,数字最终是无穷大。
  • 公平点 - @JasonZ cmets 中的链接在本质上是相同的 - 但使用 Math.Log 可以找到您需要乘以的内容,而不会弄乱溢出等
  • 我将最大乘法数绑定为 15,因此程序可以退出 while 循环。我在几个数字上进行了测试,结果看起来不错。我将使用这个解决方案,因为它不会在未来产生一些混乱,因为我需要这个比较来进行单元测试。
  • Math.Log 方法可能更快。祝你好运。或查看相对大小。类似if (Math.Abs(x-y) &lt; Math.Abs(x)*precision ) ...见accu.org/index.php/articles/1558
【解决方案2】:

double 具有 epsilon double.Epsilon 或通过硬代码设置首选错误,例如0.00001

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-10-22
    • 2011-01-22
    • 1970-01-01
    • 2023-03-11
    • 2020-04-26
    • 1970-01-01
    • 2015-12-17
    • 1970-01-01
    相关资源
    最近更新 更多