22

数値 x と y を比較し、x が y より小さい場合は -1、x が y より大きい場合は 1、等しい場合は 0 を返す簡単な数学関数はありますか?

そうでない場合、出力をこれらの戻り値ifに変換するためのエレガントなソリューション( 'sなし)はありますか?Math.Max(x, y)123/123 = 1 など、数値を自分で割ることを考えていましたが、0 で割るという問題が発生します。

4

8 に答える 8

35

厳密な -1、0、または 1 の要件については、これを行うことが保証されている単一のメソッドはありません。Int32.CompareToただし、とを組み合わせて使用​​できますMath.Sign

int value = Math.Sign(x.CompareTo(y));

CompareToまたは、負の数、正の数、および 0 に関して記述されている通常のコントラクトに満足している場合はCompareTo、単独で使用できます。

于 2012-08-29T18:56:50.497 に答える
14

.NET 呼び出しをまったく使用せずに、1 行で実行できます。: Math.Sign と type.CompareTo はどちらも、避けたいと言った論理 if ステートメントと比較演算子を使用します。

int result = (((x - y) >> 0x1F) | (int)((uint)(-(x - y)) >> 0x1F));

関数として

//returns 0 if equal
//returns 1 if x > y
//returns -1 if x < y
public int Compare(int x, int y)
{
    return (((x - y) >> 0x1F) | (int)((uint)(-(x - y)) >> 0x1F));
}

基本的に、これが行うことは、符号ビットを最初の位置までシフトすることだけです。結果が符号なしの場合は 0 になります。次に、同じ操作を実行して符号ビットを反転し、それらをORで結合すると、結果は 1、0、または -1 になります。

結果が-1の場合

IS 12 > 15:

12 - 15 = -3            (11111111111111111111111111111101)
-3 >> 0x1F = -1         (11111111111111111111111111111111)

-(12 - 15) = 3          (00000000000000000000000000000011)
3 >> 0x1F = ((uint)0)=0 (00000000000000000000000000000000) cast to uint so 0

    11111111111111111111111111111111
OR
    00000000000000000000000000000000
=   11111111111111111111111111111111 (-1)

結果が1の場合

IS 15 > 12:

15 - 12 = 3               (00000000000000000000000000000011)
3 >> 0x1F = 0             (00000000000000000000000000000000)

-(15 - 12) = -3           (11111111111111111111111111111101)
-3 >> 0x1F = ((uint)-1)=1 (00000000000000000000000000000001) cast to uint so 1

    00000000000000000000000000000000
OR
    00000000000000000000000000000001
=   00000000000000000000000000000001 (1)

結果が0の場合

IS 15 == 15:

15 - 15 = 0               (00000000000000000000000000000000)
0 >> 0x1F = 0             (00000000000000000000000000000000)

-(15 - 15) = 0            (00000000000000000000000000000000)
0 >> 0x1F = ((uint)0)=0   (00000000000000000000000000000000) cast to uint so 1

    00000000000000000000000000000000
OR
    00000000000000000000000000000000
=   00000000000000000000000000000000 (0)

これは、Math やその他の .NET メソッドへの呼び出しを使用するよりもはるかに高速です。

于 2012-08-29T19:59:56.330 に答える
6
x.CompareTo(y)

MSDNから直接。

于 2012-08-29T18:54:56.067 に答える
3

CompareTo()関数を使用する

int i = 5;
int n = 6;

int c = i.CompareTo(n);

私は一般的にifステートメントでそれを使用します:

int x = 34;
int y = 25;

if(x.CompareTo(y) == 0)
{
  Console.WriteLine("Yes, they are equal");
}
else
{
  Console.WriteLine("No, they are not equal");
}

編集:

Int32.CompareTo()が-1 | 0 | 1以外のものを返す可能性があると主張した後、私はその可能性を自分で調査することにしました。

の反映コードは次のとおりですInt32.CompareTo()。どちらかが-1|0|1以外のものを返す方法がわかりません。

[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
public int CompareTo(int value)
{
    if (this < value)
    {
        return -1;
    }
    if (this > value)
    {
        return 1;
    }
    return 0;
}


public int CompareTo(object value)
{
    if (value == null)
    {
        return 1;
    }
    if (!(value is int))
    {
        throw new ArgumentException(Environment.GetResourceString("Arg_MustBeInt32"));
    }
    int num = (int) value;
    if (this < num)
    {
        return -1;
    }
    if (this > num)
    {
        return 1;
    }
    return 0;
}
于 2012-08-29T18:54:49.157 に答える
1

これはMath.Sign()関数です。

このような:

return Math.Sign(x-y);
于 2012-08-29T18:54:30.293 に答える
0

このコードで試すことができます

var result = a.CompareTo(b);
于 2012-08-29T18:55:42.593 に答える
0

使ってみたcompareTo()? ここを見てください: http://msdn.microsoft.com/en-us/library/y2ky8xsk.aspx

于 2012-08-29T19:06:10.897 に答える
0

整数に対してCompareToメソッドを使用します。

public int c(int x, int y)
{
  return x.CompareTo(y);
}

void Main()
{       
    Console.WriteLine(c(5,3));
    Console.WriteLine(c(3,3));
    Console.WriteLine(c(1,3));
}
于 2012-08-29T18:57:38.157 に答える