Jak przekonwertować liczbę dziesiętną na liczbę całkowitą?
Jak przekonwertować liczbę dziesiętną na liczbę całkowitą?
Odpowiedzi:
Użyj Convert.ToInt32
od mscorlib
jak 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 .
null
vs. 0
vs. ""
). 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.ToInt32
i Decimal.ToInt32
zachowuj 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.
ToEven
powinno zapobiegać dryfowaniu statystyk. Jeśli jednak operujesz przy użyciu przedmiotów podlegających opłacie lub pieniędzy, AwayFromZero
wydaje 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.Decimal
implementuje IConvertable
interfejs, 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.9
tob = 50
kiedy a = 49.5
tob = 50
kiedy a = 49.4
, a następnie b = 49
itp.
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 decimal
zapakowane w object
któ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.