2个数字之间的差异

Posted

技术标签:

【中文标题】2个数字之间的差异【英文标题】:Difference between 2 numbers 【发布时间】:2008-12-04 09:06:29 【问题描述】:

我需要完美的算法或 C# 函数来计算 2 个十进制数之间的差异(距离)。

例如:10025 之间的区别是 75100-25125-100-11515-500100600

是否有一个 C# 函数或一个非常优雅的算法来计算这个,或者我必须用 ifs 分别处理每个案例。

如果有这样的函数或算法,是哪一个?

【问题讨论】:

您给出的示例都是整数 - 您测试的所有数字都是这种情况还是一些浮点数?如果是这样,那么您可能必须满足于测试它们何时“足够接近” - 即检查差异是否小于某个阈值。 为什么投反对票?对于不熟悉 Math.Abs​​ 的人来说,这似乎是一个公平的问题 +1,不需要对一个完全没问题的问题投反对票 我认为短语'或者我必须用ifs单独处理每个案例。'清楚地表明这个问题是用 chhek 语言问的 【参考方案1】:

你可以这样做

public decimal FindDifference(decimal nr1, decimal nr2)

  return Math.Abs(nr1 - nr2);

【讨论】:

当然没有必要把这段代码放到一个单独的函数中,但更多的是为了澄清 (nr1 - nr2) = Int32.MinValue 时崩溃 - 问题here @cz 崩溃对于Int32.MinValue 来说非常明显。正如here 所述,发生这种情况的原因非常简单。数字数据类型的范围总是像-x(x-1)。当然,如果我尝试在相同的数据类型中容纳+xInt32.MinValue 的绝对值)来获得绝对值,那么它必然会失败:)【参考方案2】:
result = Math.Abs(value1 - value2);

【讨论】:

他想说数学。 Math 是 .Net 类,其中包含三角函数、对数函数和其他常见数学函数的静态方法 :p 不敢相信有人花了 2 年的时间来接我:) 特别小心value1-value2 等于Int32.MinValue 时,由于System.OverflowException 异常,此代码将崩溃。更多详情here. 反击自己 - Int32.MinValue 的崩溃非常明显。正如here 所述,发生这种情况的原因非常简单。数字数据类型的范围总是像-x(x-1)。当然,如果我尝试在相同的数据类型中容纳+xInt32.MinValue的绝对值)来获得绝对值,那么它必然会失败。 有符号整数范围的端点是“减一”(例如,16 位为 -32,768 和 32,767)【参考方案3】:

只是添加这个,因为这里没有人写它:

虽然你肯定可以使用

Math.Abs(number1 - number2);

这是最简单的解决方案(也是公认的答案),我想知道没有人写出 Abs 的实际作用。这是一个适用于Java、C、C# 和其他所有具有类似 C 语法的语言的解决方案

int result = number1 - number2;
if (result < 0) 
    result *= -1;

就这么简单。你也可以这样写:

int result = number1 > number2 ? number1 - number2 : number2 - number1;

最后一个编译后可能会更快;两者都有一个 if 和一个减法,但在某些情况下第一个有一个乘法,最后一个没有。为什么只在某些情况下?一些 CPU 具有“交换符号”操作,编译器识别 *= -1 所做的事情,它只是交换符号,因此它会为提供它的 CPU 发出交换符号操作,而不是乘法,并且此操作与一个 CPU 操作可以获得(通常是一个时钟周期)。

第一个代码示例实际上是在做 Abs 在大多数实现中所做的事情,以在支持的情况下使用“交换符号”,最后一个代码示例在没有“交换符号”的 CPU 上会更快,并且乘法比添加(在现代 CPU 上,它们通常同样快)。

【讨论】:

我很惊讶没有人说过这不适用于所有整数。我确定 int.MaxValue 和 int.MinValue 之间的区别不是 -1 @Aelphaeis 你的编辑是假的;除非您完全理解某个主题,否则请不要编辑帖子。当然,它适用于负整数。例如。 number1100number2-100: 100 - (-100) = 200 这是正确的。或者看到这个(-50) - (-80) = 30,也是正确的。它不适用于int.MaxValueint.MinValue 的原因是因为这两者之间的区别是4'294'967'295,但适合int 的最大数字是2'147'483'647,因此你会导致它溢出两次。 我已经意识到这一点,并且实际上进行了第二次编辑。我猜它从未被批准。 使用result = -result 而不是result *= -1。毕竟,这就是 -(否定)运算符的用途。 真的,谢谢@Mecki,我需要那个公式。【参考方案4】:

我认为这在 C# 中是不可能的,您可能需要考虑在 Assembler 中实现它

【讨论】:

不了解此解决方案背后数学原理的人不一定会知道它是否可行,尤其是当他们有可行的替代方案时。在这种情况下,不可能察觉到枯燥的幽默,所以投反对票是完全合理的。有趣与否,这是错误的信息。 使用 或 ;) 原始问题的标签表示需要幽默感。在这种情况下,所有有趣的答案都是允许的! 在这里发现枯燥的幽默并非不可能。来吧“汇编”?任何酷刑之路的邀请显然都是程序员的智慧。但我同意一些标记或表情符号总是有帮助的。 @LasseVågsætherKarlsen 不过,公平地说,发布此答案的用户是将该标签编辑到问题中的用户,而不是 OP【参考方案5】:

这就是我在企业项目中的做法:

namespace Extensions

    public class Functions
    
        public static T Difference<T>(object x1, object x2) where T : IConvertible
        
            decimal d1 = decimal.Parse(x1.ToString());
            decimal d2 = decimal.Parse(x2.ToString());

            return (T)Convert.ChangeType(Math.Abs(d1-d2), typeof(T));
        
    

和测试:

namespace MixedTests

    [TestClass]
    public class ExtensionsTests
    
        [TestMethod]
        public void Difference_int_Test()
        
            int res2 = Functions.Difference<int>(5, 7);
            int res3 = Functions.Difference<int>(-3, 0);
            int res6 = Functions.Difference<int>(-3, -9);
            int res8 = Functions.Difference<int>(3, -5);

            Assert.AreEqual(19, res2 + res3 + res6 + res8);
        

        [TestMethod]
        public void Difference_float_Test()
        
            float res2_1 = Functions.Difference<float>(5.1, 7.2);
            float res3_1 = Functions.Difference<float>(-3.1, 0);
            double res5_9 = Functions.Difference<double>(-3.1, -9);
            decimal res8_3 = Functions.Difference<decimal>(3.1, -5.2);

            Assert.AreEqual((float)2.1, res2_1);
            Assert.AreEqual((float)3.1, res3_1);
            Assert.AreEqual(5.9, res5_9);
            Assert.AreEqual((decimal)8.3, res8_3);

        
    

【讨论】:

ToString() 是昂贵的,因为它是一个 int 或 float 你正在处理。

以上是关于2个数字之间的差异的主要内容,如果未能解决你的问题,请参考以下文章

如何将一个集合分成两个子集,以使两个集合中数字之和之间的差异最小?

如何在 PHP 中比较和获取 2 个 multidim 数组之间的差异

最大化序列中数字之间的差异

C ++:2个数组之间的差异

在 PLSQL 中查找 dbms_utility.lname_array 类型的 2 个数组之间的差异

刷题日记前n个数字二进制中1的个数