2009-05-13 10 views

Odpowiedz

170

Po prostu wykonaj (int)myLongValue. Zrobi dokładnie to, czego chcesz (odrzucając MSB i biorąc LSB) w kontekście unchecked (który jest domyślnym kompilatorem). To będzie rzucać OverflowException w checked kontekście, jeśli wartość nie mieści się w int:

int myIntValue = unchecked((int)myLongValue); 
+12

Dla każdego, kto miał to samo pytanie, które zrobiłem: Zauważ, że odrzucenie MSB może mieć wpływ na * znak * wyniku. Z powyższym, 'myIntValue' może skończyć się ujemnym, gdy' myLongValue' jest dodatnie ('4294967294 => -2') i na odwrót (' -4294967296 => 0'). Tak więc, na przykład, przy wdrażaniu operacji 'CompareTo', nie można szczęśliwie rzucić wyniku odjęcia jednego' long'a z innego na 'int' i zwrócić; w przypadku niektórych wartości porównanie spowoduje niepoprawny wynik. –

+18

+1 używane w 'nowym losowym (niezaznaczonym ((int) DateTime.Now.Ticks))' –

+16

@Chris: 'new Random()' używa 'Environment.TickCount' pod maską; nie ma potrzeby ręcznego wysiewu tykaniem zegara. –

25
Convert.ToInt32(myValue); 

Choć nie wiem, co będzie robić, gdy jest większa niż int.MaxValue.

+34

* "Chociaż nie wiem, co zrobi, gdy będzie większy niż int.MaxValue" * Spowoduje to 'OverflowException', którego dokładnie nie chce OP: http://msdn.microsoft.com /en-us/library/d4haekc4.aspx –

+4

Sprawdź, czy myValue> Integer.Max przed uruchomieniem konwertowania, jeśli musisz wykonać inne przetwarzanie, gdy myValue> Integer.Max. Convert.ToInt32 (myValue) przepełni się (bez wyjątku, jak sądzę) inaczej. Ta metoda działa również w VB.NET. – TamusJRoyce

+3

Chociaż (int) jest poprawny, Convert to lepsza odpowiedź. Lepiej mieć dziwne wyjątki niż dziwne dane. –

13

Czasami nie interesuje Cię faktyczna wartość, ale jej użycie jako sumy kontrolnej/hashcode. W tym przypadku, wbudowana metoda GetHashCode() jest dobrym wyborem:

int checkSumAsInt32 = checkSumAsIn64.GetHashCode(); 
+5

Minęło trochę czasu, odkąd ta odpowiedź została podana, chociaż chcę wspomnieć, że implementacja hashcode może się różnić między wersjami .NET. Może tak się nie dzieje, ale nie ma gwarancji, że wartość ta będzie taka sama dla różnych aplikacji/aplikacji. – Caramiriel

+1

Aby dodać do tego, co mówi @Caramiriel: jeśli używasz jako * tymczasowego * hashcode, podczas bieżącej sesji aplikacji, "GetHashCode" jest właściwym wyborem. Jeśli używasz * trwałej sumy kontrolnej * - wartość, która będzie taka sama, gdy uruchomisz później aplikację, nie używaj "GetHashCode", ponieważ nie ma gwarancji, że będzie on na zawsze tym samym algorytmem. – ToolmakerSteve

6

bezpieczny i najszybszym sposobem jest użycie bit maskowania przed obsadą ...

int MyInt = (int) (MyLong & 0xFFFFFFFF) 

bit maski (0xFFFFFFFF) wartość będzie zależeć od wielkości Int, ponieważ rozmiar Int zależy od komputera.

+0

Musisz zdecydować, co chcesz zrobić, gdy wynik zostanie przekroczony lub stanie się liczbą ujemną. To, co pokazujesz, nadal będzie przepełnione, IIRC, ponieważ pozwalasz, by znak przebiegł. [Jak wspomniano w innej odpowiedzi, w kontekście "niezaznaczonym" nie uzyskasz przepełnienia - ale nie musisz maskować w "niezaznaczonym", aby uniknąć przepełnienia, więc rozwiązanie jest potrzebne tylko w kontekście "sprawdzonym".] Przykład dla 16 bitów. Podpisane bity 16-bitowe (-32768, 32767). Maskowanie z 0xFFFF pozwala na wartość do 65535, powodując przepełnienie, IIRC. Można maskować, aby uniknąć znaku bitowego, 0x7FFF lub 0x7FFFFFFF, jeśli chcesz tylko pozytywne. – ToolmakerSteve

Powiązane problemy