比较数字得到不同的结果

发布于 2025-01-06 17:15:57 字数 663 浏览 0 评论 0原文

我确信有一个简单的解释,但无法解决以下问题:

     const short amount = 30000;
     bool isGreater =
             ComparableExtensions.IsGreaterThan(amount, 29000); //returns true

     bool isGreaterThan2 = 
     amount.IsGreaterThan<short>(29000);//returns false

      public static class ComparableExtensions
      {
            public static bool IsGreaterThan<T>(this T leftValue, T rightValue) 
            where T : struct, IComparable<T>
            {
                var result = leftValue.CompareTo(rightValue) == 1;
                return result;
            }

      }

是因为我设置了“结构”约束吗?

有什么解释或建议吗?

谢谢

I am sure that there is a simple explanation but cannot work out the following:

     const short amount = 30000;
     bool isGreater =
             ComparableExtensions.IsGreaterThan(amount, 29000); //returns true

     bool isGreaterThan2 = 
     amount.IsGreaterThan<short>(29000);//returns false

      public static class ComparableExtensions
      {
            public static bool IsGreaterThan<T>(this T leftValue, T rightValue) 
            where T : struct, IComparable<T>
            {
                var result = leftValue.CompareTo(rightValue) == 1;
                return result;
            }

      }

Is it because i put a "Struct" contraint?

any explanation or suggestions?

thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

预谋 2025-01-13 17:15:57

不,您使用 leftValue.CompareTo(rightValue) == 1 时犯了错误。

相反,请说 leftValue.CompareTo(rightValue) > 0 。

您只知道 CompareTo 返回 <如果 leftValue 小于 rightValue,则为 0;如果 leftValue 等于 rightValue,则为 0代码>和<代码>>如果 leftValue 大于 rightValue,则为 0。您不仅可以检查与 1 是否相等。

此外,您在两个调用之间看到不同行为的原因是因为在第一种情况下您调用 IsGreaterThan 因为文字常量 29000 将被解释为 < code>Int32,但在第二种情况下,您明确地说 short,因此它将被解释为 Int16

No, your mistake using leftValue.CompareTo(rightValue) == 1.

Instead, say leftValue.CompareTo(rightValue) > 0.

All you know is that CompareTo returns < 0 if leftValue is less than rightValue, 0 if leftValue equals rightValue and > 0 if leftValue is greater than rightValue. You can not only check for equality with 1.

Additionally, the reason that you see different behavior between the two calls is because in the first case you are calling IsGreaterThan<int> because the literal constant 29000 will be interpreted as Int32, but in the second case you explicitly say short so it will be interpreted as Int16.

夏了南城 2025-01-13 17:15:57

查看 IComparable 的文档以及 CompareTo 方法的返回值。它指出如果 a a a a a a a a a a a a a a a a a a a a a a a a a < b,如果a == b则恰好为零,如果a > 则大于零。 b.。然而,您正在将返回值与 1 进行比较。无法保证此方法将返回 1。你应该这样做:

var result = leftValue.CompareTo(rightValue) > 0;

Look at the documentation for IComparable, and the return value of the CompareTo method. It states that it will return a value less than zero if a < b, exactly zero if a == b, and a value greater than zero if a > b. Yet you are comparing the return value to 1. There is no guarantee this method will ever return 1. You should instead do:

var result = leftValue.CompareTo(rightValue) > 0;
妄司 2025-01-13 17:15:57

当前的 short.CompareTo() 实现是这样的:

public int CompareTo(short value)
{
    return (int)(this - value);
}

int.CompareTo() 实现是这样的:

public int CompareTo(int value)
{
    if (this < value)
    {
       return -1;
    }
    if (this > value)
    {
       return 1;
    }
    return 0;
}

在第一种情况下,通用的 T 类型被推断为 Int32,因为 29000Int32 字符串文字,因此 int.CompareTo() 方法被调用。

在第二种情况下,您明确表示 Tshort,然后调用 short.CompareTo()

正如其他答案已经指出的那样, IComparable 规范并不保证始终返回:

 0 : if the numbers are equal  
-1 : if the number is lower than the other
 1 : if the number is greater than the other

而只是说它必须返回:

0            : if the numbers are equal  
a number < 0 : if the number is lower than the other
a number > 0 : if the number is greater than the other

The current short.CompareTo() implementation is something like this:

public int CompareTo(short value)
{
    return (int)(this - value);
}

while the int.CompareTo() implementation is something like this:

public int CompareTo(int value)
{
    if (this < value)
    {
       return -1;
    }
    if (this > value)
    {
       return 1;
    }
    return 0;
}

In the first case the generic T type is inferred as Int32 because 29000 is an Int32 string literal and so the int.CompareTo() method is called.

In the second case you're specifically saying that T is short and then the short.CompareTo() is called.

As other answers already pointed out, IComparable<T> specification doesn't assure to return always:

 0 : if the numbers are equal  
-1 : if the number is lower than the other
 1 : if the number is greater than the other

but just says that it must return:

0            : if the numbers are equal  
a number < 0 : if the number is lower than the other
a number > 0 : if the number is greater than the other
陌上芳菲 2025-01-13 17:15:57

编译器在第一次(静态)调用中推断泛型类型。它使用Int32Int32.CompareTo 方法返回 1 表示大于。

在第二个例子中,来自 Int16 的调用强制 TInt16Int16.CompareTo 返回两个值之间的实际差异*。在 IComparable 下合法(只需要值 > 0) - 但不同之处足以导致您的调用失败。

将第一个调用显式转换为 short 也会导致它失败。

* 不,我不知道为什么 Int16 是这样实现的。似乎是“因为它可以是”(Byte 的行为相同) - 因为您可以进行减法而不用担心溢出(因为您正在将结果转换为更广泛的类型)。对 Int32 做类似的事情需要更多的工作,我认为这不值得。

The compiler infers the generic type in the first (static) call. It uses Int32. The Int32.CompareTo method returns 1 for greater than.

In the second, your call from an Int16 forces T to be Int16. Int16.CompareTo returns the actual difference between the two values*. Legal under IComparable (which only requires a value > 0) - but different enough for your call to fail.

Explicitly casting the first call to short will cause it to fail as well.

* No, I have no idea why Int16 is implemented that way. Seems to be "because it can be"(Byte behaves the same) - since you can subtract without fear of overflow (since you're casting to a wider type for the result). It'd require more work to do something similar for Int32 which I suppose wasn't worth the effort.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文