Przydałoby się wiedzieć, czy chcesz zaokrąglić do najbliższej liczby całkowitej, czy po prostu upuścić cyfry po przecinku (tzn. Zawsze zaokrąglać w dół)
Dinah
128
szczerze mówiąc, nie widzę sensu w przeglądzie autentycznych pytań. tak, odpowiedź mogłaby być znaleziona w Google, ALE czy nie poprawiłoby to tylko jakości strony, gdyby ludzie przestali zamykać co drugie pytanie? to nie jest tak, że to pytanie jest spamem lub czymkolwiek innym, i jestem pewien, że przydałoby się wielu początkującym do c #
jay_t55
Odpowiedzi:
268
Użyj Convert.ToInt32od mscorlibjak w
decimalvalue=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
decimalvalue=3.14m;int n =(int)value;
który używa jawnego operatora rzutowania. Zobacz MSDN .
Uwaga: konwersja ma pewne zaskakujące zachowanie w przypadku niektórych konwersji ( nullvs. 0vs. ""). Polecam nigdy nie używać Konwertuj, chyba że absolutnie potrzebujesz jego elastyczności (tj. W scenariuszach z dynamicznym typowaniem)
Eamon Nerbonne,
1
-1, ponieważ to nie będzie działać dla wartości takich jak decimal.MaxValue i decimal.MinValue i spowoduje to, że OverflowException. Wierzę, że @Will zapewnia lepszą odpowiedź tutaj stackoverflow.com/a/501165/39532
mezoid
8
Bądź ostrożny, ponieważ 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.
vezucci
67
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));
Chociaż podejrzewam, że pod maską są takie same, jeśli dane wejściowe są dziesiętne, czuję się bardziej komfortowo stosując Decimal.Truncate niż Math.Truncate, ponieważ ten drugi akceptuje również liczby podwójne i dlatego można zrozumieć, że można obcinać liczby parzyste które nie są bazą 10, w przeciwieństwie do Decimal.Truncate, która jest prawdziwym obcięciem liczby 10 bazowej.
Brian
7
Niezaznaczone konteksty nie mają zastosowania do miejsc po przecinku; operacje na liczbach dziesiętnych spowodują wygenerowanie wyjątków przepełnienia niezależnie.
Dave
46
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.
Naprawdę chcesz, aby MidpointRounding.AwayFromZero, jeśli chcesz, aby> * .5 zawsze zaokrąglał w górę na podstawie mojego doświadczenia w wypróbowaniu powyższego kodu, patrząc na przykładowe wyniki tutaj: msdn.microsoft.com/en-us/library/…
Elijah Lofgren
@ElijahLofgren To trochę zależy: Jeśli robisz statystyki, 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.
Z dokumentacji : „Ten interfejs API obsługuje infrastrukturę .NET Framework i nie jest przeznaczony do używania bezpośrednio z kodu”. Dlaczego nie skorzystać z Convert.ToInt32?
H.Wolper
7
Zgrabną sztuczką do szybkiego zaokrąglania jest dodanie .5 przed rzutem dziesiętnym na liczbę całkowitą.
Po co męczyć się tym, gdy jest Math.Floor i Math.Ceiling?
Badaro,
W tym czasie byłem dość nowy w języku C # iz jakiegoś powodu nie zdawałem sobie sprawy, że te funkcje istnieją. To właściwie sztuczka, której nauczyłem się od C / C ++, która była oczywiście bardziej przydatna.
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).
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 =newSqlCommand("INSERT INTO...; SELECT SCOPE_IDENTITY()", conn);int ID =Convert.ToInt32(foo.ExecuteScalar());// worksint ID =(int)foo.ExecuteScalar();// throws InvalidCastException
Dodanie do niego więcej w celach informacyjnych: to dlatego, że można rozpakować tylko do tego samego typu oryginału. Tutaj 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.
rageit
0
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.
Odpowiedzi:
Użyj
Convert.ToInt32
odmscorlib
jak wZobacz MSDN . Możesz także użyć
Decimal.ToInt32
. Ponownie zobacz MSDN . Wreszcie możesz wykonać rzut bezpośredni jak wktóry używa jawnego operatora rzutowania. Zobacz MSDN .
źródło
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/39532Convert.ToInt32
iDecimal.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
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.
źródło
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ć
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:
choć nadal możesz to zrobić jawnie, jeśli chcesz:
Jeśli jednak tracisz informacje za pośrednictwem obsady, musisz to zrobić jawnie (aby pokazać, że masz świadomość, że tracisz informacje):
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.
źródło
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.To powinno działać dobrze.
źródło
Oto bardzo przydatna strona konwersji typu danych dla danych innych osób. http://www.convertdatatypes.com/Convert-decimal-to-int-in-CSharp.html
źródło
System.Decimal
implementujeIConvertable
interfejs, który maToInt32()
członka.Czy dzwonienie
System.Decimal.ToInt32()
działa dla Ciebie?źródło
Zgrabną sztuczką do szybkiego zaokrąglania jest dodanie .5 przed rzutem dziesiętnym na liczbę całkowitą.
Wciąż odchodzi
i=10
, aleBy zaokrąglić w górę tak, że
i=11
.źródło
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).
źródło
dziesiętny
d = 5.5
;ref: link tekstowy
źródło
Zaokrąglanie liczby dziesiętnej do najbliższej liczby całkowitej
kiedy
a = 49.9
tob = 50
kiedy
a = 49.5
tob = 50
kiedy
a = 49.4
, a następnieb = 49
itp.źródło
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:
Zobacz 4.3.2 Konwersje rozpakowywania
źródło
SELECT SCOPE_IDENTITY()
zwraca,numeric(38, 0)
co tłumaczydecimal
.NET.foo.ExecuteScalar()
zwracadecimal
zapakowane wobject
których nie można rzutować bezpośrednio doint
.(int)(decimal)foo.ExecuteScalar()
lubConvert.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.
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.
źródło