W naszym kodzie mamy double, który musimy przekonwertować na int.
double score = 8.6;
int i1 = Convert.ToInt32(score);
int i2 = (int)score;
Czy ktoś może mi wyjaśnić, dlaczego i1 != i2
?
Wynik, który otrzymuję jest taki: i1 = 9
i i2 = 8
.
W naszym kodzie mamy double, który musimy przekonwertować na int.
double score = 8.6;
int i1 = Convert.ToInt32(score);
int i2 = (int)score;
Czy ktoś może mi wyjaśnić, dlaczego i1 != i2
?
Wynik, który otrzymuję jest taki: i1 = 9
i i2 = 8
.
Odpowiedzi:
Ponieważ Convert.ToInt32
rundy:
Wartość zwracana: zaokrąglona do najbliższej 32-bitowej liczby całkowitej ze znakiem. Jeśli wartość jest w połowie 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.
... podczas gdy obsada się obcina :
Podczas konwertowania wartości typu double lub float na typ całkowity wartość jest obcinana.
Aktualizacja: Zobacz komentarz Jeppe Stiga Nielsena poniżej, aby poznać dodatkowe różnice (które jednak nie mają znaczenia, jeśli score
jest liczbą rzeczywistą, jak ma to miejsce w tym przypadku).
score
było 8.5
zamiast 8.6
. Zaktualizowałem odpowiedź, aby zawierała cytaty. Dzięki za wkład.
score
jest NaN
, nieskończoność lub skończona, ale poza zakresem Int32
, to Convert.ToInt32
zgłosi wyjątek. Cast zwróci an int
, ale nie będziesz wiedział, który z nich (w mojej implementacji to jest Int32.MinValue
), ponieważ jesteś w unchecked
kontekście. (Jeśli jesteś w checked
kontekście, obsada również rzuci wyjątek w tych przypadkach).
Double
typowa liczba 10000000000.6
(dziesięć miliardów przecinek sześć) jest liczbą „rzeczywistą”. Użycie rzutowania int
na to da dziwny wynik (chyba że jesteś w checked
kontekście, ale prawdopodobnie tak nie jest).
Rzutowanie zignoruje wszystko po przecinku, więc 8.6 zmieni się na 8.
Convert.ToInt32(8.6)
to bezpieczny sposób na zaokrąglenie podwójnej liczby do najbliższej liczby całkowitej, w tym przypadku 9.
W podanym przykładzie Twój dziesiętny to 8,6 . Gdyby było 8.5 lub 9.5, stwierdzenie i1 == i2 mogłoby być prawdziwe. W rzeczywistości byłoby to prawdą w przypadku wersji 8.5, a fałszem w przypadku wersji 9.5.
Wyjaśnienie:
Niezależnie od części dziesiętnej, drugie stwierdzenie, int i2 = (int)score
odrzuci część dziesiętną i po prostu zwróci część całkowitą. Dość niebezpieczna rzecz, ponieważ może dojść do utraty danych.
W przypadku pierwszego stwierdzenia mogą się wydarzyć dwie rzeczy. Jeśli część dziesiętna wynosi 5, to znaczy jest w połowie, należy podjąć decyzję. Czy zaokrąglamy w górę czy w dół? W języku C # klasa Convert implementuje zaokrąglanie bankierów. Zobacz to odpowiedź, aby uzyskać głębsze wyjaśnienie. Mówiąc najprościej, jeśli liczba jest parzysta, zaokrąglij w dół, jeśli liczba jest nieparzysta, zaokrąglij w górę.
Np. Rozważ:
double score = 8.5;
int i1 = Convert.ToInt32(score); // 8
int i2 = (int)score; // 8
score += 1;
i1 = Convert.ToInt32(score); // 10
i2 = (int)score; // 9
ToInt32 rundy. Rzutowanie na int po prostu odrzuca składnik nie będący liczbą całkowitą.
Math.Truncate(score)
jest wyraźniej wyrażony niż(int)score