2012-08-29 26 views
9

是否有一個簡單的數學函數可用於比較數字x和y,並在x小於y時返回-1,當x大於y時返回1,重新平等嗎?比較兩個數並返回-1,0或1

如果沒有,會不會有一個優雅的解決方案(沒有任何if's)將Math.Max(x, y)的輸出轉換爲這些返回?我正在考慮自己劃分數字,例如123/123 = 1,但會引入除以0的問題。

回答

21

嘗試爲您嚴格-1,0或1的要求,還有這是保證做到這一點沒有任何單一的方法。但是,你可以使用Int32.CompareToMath.Sign組合:

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

另外,如果你滿意這是剛剛在負數,正數和0的條款中規定的正常CompareTo合同,你可以使用CompareTo在其自己的。

+0

我實際上開始懷疑我需要的返回值是不是'Int32.CompareTo'。畢竟回報。在每種情況下,您的答案提供了我需要的方法,並且是我的問題的最佳答案..如此接受:) – Daan

+0

您可以舉一個例子,其中「Int32.CompareTo()'返回除-1 | 0 | 1之外的其他東西嗎? –

+3

@ChrisGessler:不是副手 - 但它是完全合理的(給出文檔),我不想*假設它永遠不會。 –

2

這是Math.Sign()函數。

像這樣:

return Math.Sign(x-y); 
+0

嗯,downvotes:爲什麼這是錯的? – RBarryYoung

+2

我的downvote是爲你的'Math.Sign'沒有進一步解釋,現在刪除。但是用'x-y',它會在溢出時出現問題。 – hvd

2

使用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; 
} 
+3

請注意,這不保證返回-1或1. –

+0

真的......它可能會返回0. –

+2

不,我的觀點是它可以返回100或類似的東西。 –

4
x.CompareTo(y) 

直接從MSDN

+1

Upvoting這一個,因爲MSDN頁面顯示如何強制值爲-1/0/+ 1。沒有這個,'CompareTo()'實際上並沒有做OP所需要的。 – egrunin

+0

@egrunin - 我沒有在文章中看到如何將值強制爲-1/0/+ 1。如果你指向比較枚舉的轉換,'(比較)100'仍然是100,而不是1. –

+0

我沒有運行該代碼,但它*顯示*聲稱'(比較)100'將返回'Comparison.GreaterThan',(如果然後轉換爲'int')將等於1. – egrunin

0

你可以用這個代碼

var result = a.CompareTo(b); 
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)); 
} 
11

你可以做到這一點,根本不需要任何.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)); 
} 

基本上,這樣做只是SHIFT符號比特一路到第一位置。如果結果是無符號的,那麼它將是0;然後它執行相同的操作並翻轉符號位,然後將它們結合在一起,結果是枯萎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方法。

相關問題