Mengubah ganda menjadi int di C #


103

Dalam kode kami, kami memiliki ganda yang perlu kami ubah menjadi int.

double score = 8.6;
int i1 = Convert.ToInt32(score);
int i2 = (int)score;

Adakah yang bisa menjelaskan mengapa i1 != i2?

Hasil yang saya dapatkan adalah: i1 = 9dan i2 = 8.


5
Math.Truncate(score)adalah niat yang lebih eksplisit diungkapkan daripada(int)score
Lu55

3
Tapi Math.Truncate mengembalikan ganda atau desimal, bukan int
Sergioet

Jawaban:


164

Karena Convert.ToInt32putaran:

Nilai Kembali: dibulatkan ke bilangan bulat bertanda 32-bit terdekat. Jika nilai setengah antara dua bilangan bulat, bilangan genap dikembalikan; yaitu, 4,5 diubah menjadi 4, dan 5,5 diubah menjadi 6.

... sementara pemerannya memotong :

Saat Anda mengonversi dari nilai ganda atau float menjadi tipe integral, nilainya dipotong.

Pembaruan: Lihat komentar Jeppe Stig Nielsen di bawah ini untuk perbedaan tambahan (yang bagaimanapun tidak ikut bermain jika scorebilangan real seperti yang terjadi di sini).


6
Tautan Anda benar-benar menjelaskannya dengan baik, dan itu tidak sesederhana round vs truncate: Type: System.Int32 nilai, dibulatkan ke bilangan bulat bertanda 32-bit terdekat. Jika nilai setengah antara dua bilangan bulat, bilangan genap dikembalikan; yaitu, 4,5 diubah menjadi 4, dan 5,5 diubah menjadi 6.
ericosg

@ericosg: Ya, itu akan menutupi perbedaan jika scoreada, 8.5bukan 8.6. Saya memperbarui jawabannya dengan menyertakan kutipan. Terima kasih atas masukannya.
Jon

5
Dan jika scoreada NaNatau suatu tak terhingga atau terbatas tetapi di luar kisaran Int32, maka Convert.ToInt32akan mengeluarkan pengecualian. Cast akan mengembalikan int, tetapi Anda tidak akan tahu yang mana (dalam implementasi saya Int32.MinValue) karena Anda berada dalam uncheckedkonteks. (Jika Anda berada dalam checkedkonteksnya, pemeran akan memberikan pengecualian juga dalam kasus ini.)
Jeppe Stig Nielsen

@JeppeStigNielsen: Terima kasih atas masukannya, saya memperbarui jawaban untuk menyebutkan ini juga.
Jon

Bagus. Tapi menurut saya Doublenomor jenis 10000000000.6(sepuluh miliar koma enam) adalah bilangan "nyata". Menggunakan cast ke intatas akan memberikan hasil yang aneh (kecuali Anda berada dalam checkedkonteksnya, tetapi mungkin tidak).
Jeppe Stig Nielsen

13

Pengecoran akan mengabaikan apa pun setelah koma desimal, jadi 8,6 menjadi 8.

Convert.ToInt32(8.6) adalah cara yang aman untuk memastikan penggandaan Anda dibulatkan ke bilangan bulat terdekat, dalam kasus ini 9.


1
Pertanyaan bonus - apa yang terjadi jika nilai double terlalu besar untuk didorong ke int ? Yaitu jika lebih tinggi dari int.MAX_VAL ?
Konrad Viltersten

1
@KonradVersten Melontarkan pengecualian Nilai terlalu besar atau terlalu kecil untuk Int32.
Vamsi

11

Anda dapat membulatkan double dan cast ist:

(int)Math.Round(myDouble);

4
pertanyaannya sekarang adalah bagaimana membuatnya i1 == i2. Pertanyaannya adalah mengapa mereka tidak setara. Suara negatif.
Adam

5

Dalam contoh yang diberikan, desimal Anda adalah 8,6 . Jika 8,5 atau 9,5, pernyataan i1 == i2 mungkin benar. Faktanya itu akan benar untuk 8,5, dan salah untuk 9,5.

Penjelasan:

Terlepas dari bagian desimalnya, pernyataan kedua, int i2 = (int)scoreakan membuang bagian desimal dan hanya mengembalikan Anda bagian bilangan bulat. Hal yang cukup berbahaya untuk dilakukan, karena kehilangan data dapat terjadi.

Nah, untuk pernyataan pertama, dua hal bisa terjadi. Jika bagian desimal adalah 5, yaitu setengah jalan, keputusan harus dibuat. Apakah kita membulatkan ke atas atau ke bawah? Di C #, kelas Convert mengimplementasikan pembulatan bankir. Lihat jawaban ini untuk penjelasan lebih dalam. Sederhananya, jika angkanya genap, bulatkan ke bawah, jika angkanya ganjil, bulatkan ke atas.

Misalnya Pertimbangkan:

        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 putaran. Casting ke int hanya membuang komponen non-integer.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.