c# - 将 double 与自适应近似相等进行比较

标签 c# equals approximate

我正在尝试制作一个自适应的“大约相等”方法(用 C# 编写,但问题是一般性的)接受两个 double 并返回一个 bool 值(如果它们是否“大约相等”)。自适应是指:

1.234 和 1.235 ==> 正确

但是

1.234567 和 1.234599 ==> 错误

也就是说,'about equal'的精度适应了数字的精度。

我在 How do I find if two variables are approximately equals? 找到了舍入的概念,但对于 epsilon 使用什么仍然是一个开放式的问题。

有人知道解决此类问题的最佳做法吗? 提前致谢!

编辑: 我最初的问题没有包含足够的信息来说明我想要得到什么。对此感到抱歉,我深表歉意。我想要一个程序,可以将更高的精度数处理为更高的标准,同时对更低的精度数更宽松。对的更多示例是(其中“(0)”是隐含的零):

1.077 和 1.07(0) 返回 false(因为 77 与 70 有很大不同)

1.000077 和 1.00007(0) 返回 false(因为 77 与 70 有很大不同)

1.071 和 1.07(0) 返回 true(因为 71 接近 70

1.000071 和 1.00007(0) 返回真(因为 71 接近 70)

无论实现代码如何,我假设都会有某种“容差”变量来确定什么是“非常不同”和什么是“接近”。

最佳答案

比较 float 的一种方法是比较将它们分开的浮点表示的数量。此解决方案对数字的大小无关紧要,因此您不必担心“epsilon”。

可以找到算法的描述 here (最后是 AlmostEqual2sComplement 函数)这是我的 C# 版本。

public static class DoubleComparerExtensions
{
    public static bool AlmostEquals(this double left, double right, long representationTolerance)
    {
        long leftAsBits = left.ToBits2Complement();
        long rightAsBits = right.ToBits2Complement();
        long floatingPointRepresentationsDiff = Math.Abs(leftAsBits - rightAsBits);
        return (floatingPointRepresentationsDiff <= representationTolerance);
    }

    private static unsafe long ToBits2Complement(this double value)
    {
        double* valueAsDoublePtr = &value;
        long* valueAsLongPtr = (long*)valueAsDoublePtr;
        long valueAsLong = *valueAsLongPtr;
        return valueAsLong < 0
            ? (long)(0x8000000000000000 - (ulong)valueAsLong)
            : valueAsLong;
    }
}

如果你想比较 float ,把所有的double改成float,把所有的long改成int0x80000000000000000x80000000

关于c# - 将 double 与自适应近似相等进行比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10419771/

相关文章:

c# - 在 C# 中对 dataGridView 列进行排序? (窗体)

java - equals() 和 hashCode() 的区别

python - 比较列表相似度 Python

OpenCV - 偏移量的DrawContour

c# - SignalR - 如何在集线器中执行异步任务?

c# - .NET 3.0 或更高版本的套接字圣经

java - HashCodeBuilder 的使用,以及 Java 如何以及为何为具有字段的对象计算 hashCode?

java - Java 中不可修改的集合相等性

c# - 近似字符串匹配

c# - De Bruijn 算法二进制数字计数 64 位 C#