Jak przekonwertować liczbę dziesiętną na liczbę całkowitą?
Jak przekonwertować liczbę dziesiętną na liczbę całkowitą?
Odpowiedzi:
Użyj Convert.ToInt32od mscorlibjak w
decimal value = 3.14m;
int n = Convert.ToInt32(value);
Zobacz MSDN . Możesz także użyć Decimal.ToInt32. Ponownie zobacz MSDN . Wreszcie możesz wykonać rzut bezpośredni jak w
decimal value = 3.14m;
int n = (int) value;
który używa jawnego operatora rzutowania. Zobacz MSDN .
nullvs. 0vs. ""). Polecam nigdy nie używać Konwertuj, chyba że absolutnie potrzebujesz jego elastyczności (tj. W scenariuszach z dynamicznym typowaniem)
OverflowException. Wierzę, że @Will zapewnia lepszą odpowiedź tutaj stackoverflow.com/a/501165/39532
Convert.ToInt32i Decimal.ToInt32zachowuj się inaczej. Z MSDN: Decimal.ToInt32- Wartość zwracana jest integralną częścią wartości dziesiętnej; cyfry ułamkowe są obcinane . Convert.ToInt32- Zwracana wartość zaokrąglona do najbliższej 32-bitowej liczby całkowitej ze znakiem. Jeśli wartość znajduje się w połowie odległości między dwiema liczbami całkowitymi, zwracana jest liczba parzysta; to znaczy 4.5 jest konwertowane na 4, a 5.5 jest konwertowane na 6.
Nie możesz
Oczywiście, że można , jednak int (System.Int32) nie jest wystarczająco duży, aby pomieścić każdą możliwą wartość dziesiętną.
Oznacza to, że jeśli użyjesz miejsca dziesiętnego większego niż int.MaxValue, przepełnisz się, a jeśli miejsce dziesiętne jest mniejsze niż int.MinValue, nastąpi niedopełnienie.
Co dzieje się, gdy nie masz / przepełniasz? Jedna z dwóch rzeczy. Jeśli Twoja kompilacja nie jest zaznaczona (tzn. CLR nie ma znaczenia, jeśli tak zrobisz), aplikacja będzie kontynuowana po przekroczeniu / przekroczeniu wartości, ale wartość int nie będzie zgodna z oczekiwaniami. Może to prowadzić do sporadycznych błędów i może być trudne do naprawienia. Skończysz aplikację w nieznanym stanie, co może spowodować, że aplikacja uszkodzi wszelkie ważne dane, na których działa. Niedobrze.
Jeśli Twój zespół jest sprawdzony (właściwości-> kompilacja-> zaawansowane-> sprawdź arytmetyczne przepełnienie / niedopełnienie lub opcja / sprawdzony kompilator), Twój kod zgłosi wyjątek, gdy nastąpi niedopełnienie / przepełnienie. Jest to prawdopodobnie lepsze niż nie; jednak domyślnie dla zestawów nie jest sprawdzanie przepełnienia / niedopełnienia.
Prawdziwe pytanie brzmi: „co próbujesz zrobić?” Bez znajomości twoich wymagań nikt nie jest w stanie powiedzieć ci, co powinieneś zrobić w tym przypadku, poza oczywistym: NIE RÓB TO.
Jeśli nie przejmujesz się tym, odpowiedzi tutaj są poprawne. Powinieneś jednak przekazać swoje zrozumienie, że może dojść do przepełnienia i że nie ma to znaczenia, zawijając swój rzutowany kod w niezaznaczonym bloku
unchecked
{
// do your conversions that may underflow/overflow here
}
W ten sposób ludzie za tobą zrozumieją, że cię to nie obchodzi, a jeśli w przyszłości ktoś zmieni twoje kompilacje na / sprawdzone, twój kod nie zepsuje się nieoczekiwanie.
Jeśli wszystko, co chcesz zrobić, to upuścić ułamkową część liczby, pozostawiając część integralną, możesz użyć Math.Truncate.
decimal actual = 10.5M;
decimal expected = 10M;
Assert.AreEqual(expected, Math.Truncate(actual));
int i = (int)d;
poda ci liczbę zaokrągloną w dół.
Jeśli chcesz zaokrąglić do najbliższej liczby parzystej (tj.> .5 zaokrągli w górę), możesz użyć
int i = (int)Math.Round(d, MidpointRounding.ToEven);
Ogólnie rzecz biorąc, możesz przesyłać między wszystkimi typami liczbowymi w C #. Jeśli nie ma żadnych informacji, które zostaną utracone podczas przesyłania, możesz to zrobić domyślnie:
int i = 10;
decimal d = i;
choć nadal możesz to zrobić jawnie, jeśli chcesz:
int i = 10;
decimal d = (decimal)i;
Jeśli jednak tracisz informacje za pośrednictwem obsady, musisz to zrobić jawnie (aby pokazać, że masz świadomość, że tracisz informacje):
decimal d = 10.5M;
int i = (int)d;
Tracisz „.5”. Może to być w porządku, ale musisz wyrazić się jasno i rzucić wyraźną obsadę, aby pokazać, że możesz stracić informacje.
ToEvenpowinno zapobiegać dryfowaniu statystyk. Jeśli jednak operujesz przy użyciu przedmiotów podlegających opłacie lub pieniędzy, AwayFromZerowydaje się to właściwym wyborem.
decimal vIn = 0.0M;
int vOut = Convert.ToInt32(vIn);
Oto bardzo przydatna strona konwersji typu danych dla danych innych osób. http://www.convertdatatypes.com/Convert-decimal-to-int-in-CSharp.html
System.Decimalimplementuje IConvertableinterfejs, który ma ToInt32()członka.
Czy dzwonienie System.Decimal.ToInt32()działa dla Ciebie?
Zgrabną sztuczką do szybkiego zaokrąglania jest dodanie .5 przed rzutem dziesiętnym na liczbę całkowitą.
decimal d = 10.1m;
d += .5m;
int i = (int)d;
Wciąż odchodzi i=10, ale
decimal d = 10.5m;
d += .5m;
int i = (int)d;
By zaokrąglić w górę tak, że i=11.
Wolę za pomocą Math.round , Math.floor , Math.Ceiling lub Math.Truncate jawnie ustawić tryb zaokrąglania się odpowiednio.
Pamiętaj, że wszystkie zwracają również wartości dziesiętne - ponieważ liczba dziesiętna ma większy zakres wartości niż Int32, więc nadal będziesz musiał rzutować (i sprawdzić przepełnienie / niedopełnienie).
checked {
int i = (int)Math.Floor(d);
}
Zaokrąglanie liczby dziesiętnej do najbliższej liczby całkowitej
decimal a ;
int b = (int)(a + 0.5m);
kiedy a = 49.9tob = 50
kiedy a = 49.5tob = 50
kiedy a = 49.4, a następnie b = 49itp.
Uważam, że operator rzutowania nie działa, jeśli masz dziesiętną ramkę (tj. Wartość dziesiętną wewnątrz typu obiektu). Convert.ToInt32 (dziesiętny jako obiekt) działa dobrze w tym przypadku.
Ta sytuacja pojawia się podczas pobierania wartości IDENTITY / AUTONUMBER z bazy danych:
SqlCommand foo = new SqlCommand("INSERT INTO...; SELECT SCOPE_IDENTITY()", conn);
int ID = Convert.ToInt32(foo.ExecuteScalar()); // works
int ID = (int)foo.ExecuteScalar(); // throws InvalidCastException
SELECT SCOPE_IDENTITY()zwraca, numeric(38, 0)co tłumaczy decimal.NET. foo.ExecuteScalar()zwraca decimalzapakowane w objectktórych nie można rzutować bezpośrednio do int. (int)(decimal)foo.ExecuteScalar()lub Convert.ToInt32(foo.ExecuteScalar())działałby.
Wydaje się, że żadna odpowiedź nie dotyczy OverflowException / UnderflowException, które pochodzą z próby konwersji dziesiętnej, która jest poza zakresem int.
int intValue = (int)Math.Max(int.MinValue, Math.Min(int.MaxValue, decimalValue));
To rozwiązanie zwróci maksymalną lub minimalną wartość int, jeśli wartość dziesiętna jest poza zakresem int. Możesz zaokrąglić za pomocą Math.Round, Math.Ceiling lub Math.Floor, gdy wartość znajduje się w zakresie int.