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 = 9i 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 = 9i i2 = 8.
Odpowiedzi:
Ponieważ Convert.ToInt32rundy:
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 scorejest liczbą rzeczywistą, jak ma to miejsce w tym przypadku).
scorebyło 8.5zamiast 8.6. Zaktualizowałem odpowiedź, aby zawierała cytaty. Dzięki za wkład.
scorejest NaN, nieskończoność lub skończona, ale poza zakresem Int32, to Convert.ToInt32zgł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 uncheckedkontekście. (Jeśli jesteś w checkedkontekście, obsada również rzuci wyjątek w tych przypadkach).
Doubletypowa liczba 10000000000.6(dziesięć miliardów przecinek sześć) jest liczbą „rzeczywistą”. Użycie rzutowania intna to da dziwny wynik (chyba że jesteś w checkedkontekś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