Konwersja double na int w C #


103

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.


5
Math.Truncate(score)jest wyraźniej wyrażony niż(int)score
— Lu55

3
Ale Math.Truncate zwraca podwójną lub dziesiętną, a nie int
— Sergioet

Odpowiedzi:


165

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).


6
Twój link właściwie wyjaśnia to najlepiej i nie jest tak prosty, jak round vs truncate: Type: System.Int32 wartość 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; oznacza to, że 4,5 jest konwertowane na 4, a 5,5 jest konwertowane na 6.
— ericosg

@ericosg: Tak, to maskowałoby różnicę, gdyby scorebyło 8.5zamiast 8.6. Zaktualizowałem odpowiedź, aby zawierała cytaty. Dzięki za wkład.
— Jon

5
A jeśli 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).
— Jeppe Stig Nielsen

@JeppeStigNielsen: Dzięki za wkład, zaktualizowałem odpowiedź, aby również o tym wspomnieć.
— Jon

Miły. Ale myślę, że 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).
— Jeppe Stig Nielsen

13

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.


1
Pytanie bonusowe - co się stanie, jeśli wartość double jest zbyt duża, aby wcisnąć int ? To znaczy, jeśli jest wyższy niż int.MAX_VAL ?
— Konrad Viltersten

1
@KonradViltersten Zgłasza wyjątek Wartość była za duża lub za mała dla Int32.
— Vamsi

11

możesz zaokrąglić swoją dublet i rzucić ist:

(int)Math.Round(myDouble);

4
pytanie brzmiało teraz, jak to zrobić i1 == i2. Pytanie dotyczyło tego , dlaczego nie są równi. Głosowano w dół.
— Adam

5

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

2

ToInt32 rundy. Rzutowanie na int po prostu odrzuca składnik nie będący liczbą całkowitą.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.