Możesz to zrobić bez korzystania z żadnych połączeń .NET w ogóle i na 1 linii. UWAGA: Math.Sign i type.CompareTo oba używają logicznych instrukcji if i operatorów porównania, które powiedziałeś, że chciałbyś uniknąć.
int result = (((x - y) >> 0x1F) | (int)((uint)(-(x - y)) >> 0x1F));
jako funkcja
//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));
}
Zasadniczo, wszystko to robi jest SHIFT bity znak aż do pierwszej pozycji.Jeśli wynik jest niepodpisany, wówczas będzie wynosił 0; następnie wykonuje tę samą operację i odwraca bity znaków, a następnie wynik jest pomarszczony 1, 0 lub -1.
Przypadek, gdy wynik jest -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)
Przypadek, gdy wynik jest 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)
Przypadek, gdy wynik jest 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)
ta powinna być również o wiele szybciej niż przy użyciu dowolnego wywołania matematyki lub innych metod .NET.
Właściwie zaczynam się zastanawiać, czy zwracana wartość nie jest "Int32.CompareTo". w końcu wróć. W każdym przypadku twoja odpowiedź dostarcza potrzebnych mi metod i jest najlepszą odpowiedzią na moje pytanie. Tak zaakceptowana :) – Daan
Czy możesz podać przykład, w którym 'Int32.CompareTo()' zwraca coś innego niż -1 | 0 | 1? –
@ChrisGessler: Nie bez powodu - ale byłoby to całkowicie uzasadnione, aby to zrobić (biorąc pod uwagę dokumentację), i nie chciałbym * założyć *, że nigdy tego nie zrobi. –