Akan sangat membantu untuk mengetahui apakah Anda ingin membulatkan ke int terdekat atau hanya menjatuhkan angka setelah desimal (yaitu: selalu bulat ke bawah)
Dinah
128
sejujurnya saya tidak mengerti gunanya menolak pertanyaan yang sebenarnya. ya, jawabannya dapat ditemukan di google TAPI bukankah itu hanya meningkatkan kualitas situs jika orang berhenti menutup setiap pertanyaan kedua? itu bukan seperti pertanyaan ini adalah spam atau apa pun, dan aku yakin itu akan bermanfaat bagi banyak pendatang baru untuk c #
jay_t55
Jawaban:
268
Gunakan Convert.ToInt32mulai dari mscorlibpada
decimalvalue=3.14m;int n =Convert.ToInt32(value);
Lihat MSDN . Anda juga bisa menggunakan Decimal.ToInt32. Sekali lagi, lihat MSDN . Akhirnya, Anda dapat melakukan pemeran langsung seperti pada
decimalvalue=3.14m;int n =(int)value;
yang menggunakan operator pemeran eksplisit. Lihat MSDN .
Awas: Konversi memiliki beberapa perilaku mengejutkan untuk konversi tertentu ( nullvs 0vs. ""). Saya akan merekomendasikan untuk tidak pernah menggunakan Konversi kecuali Anda benar-benar membutuhkan fleksibilitasnya (yaitu dalam skenario yang diketik secara dinamis)
Eamon Nerbonne
1
-1 karena ini tidak akan bekerja untuk nilai-nilai seperti desimal.MaxValue dan desimal.MinValue dan menghasilkan OverflowException. Saya percaya bahwa @Will akan memberikan jawaban yang lebih baik di sini stackoverflow.com/a/501165/39532
mezoid
8
Hati-hati, karena Convert.ToInt32dan Decimal.ToInt32berperilaku berbeda. Dari MSDN: Decimal.ToInt32- Nilai kembali adalah bagian integral dari nilai desimal; digit fraksional terpotong . Convert.ToInt32- Nilai pengembalian dibulatkan ke bilangan bulat bertanda 32-bit terdekat. Jika nilainya setengah di antara dua bilangan bulat, bilangan genap dikembalikan; yaitu, 4,5 dikonversi menjadi 4, dan 5,5 dikonversi menjadi 6.
vezucci
67
Kamu tidak bisa
Yah, tentu saja Anda bisa , namun int (System.Int32) tidak cukup besar untuk menampung setiap kemungkinan nilai desimal.
Itu berarti jika Anda membuat desimal yang lebih besar dari int.MaxValue Anda akan overflow, dan jika desimal lebih kecil dari int.MinValue, itu akan underflow.
Apa yang terjadi ketika Anda under / overflow? Satu dari dua hal. Jika build Anda tidak dicentang (yaitu, CLR tidak peduli jika Anda melakukannya), aplikasi Anda akan berlanjut setelah nilai over / underflow, tetapi nilai di int tidak akan seperti yang Anda harapkan. Ini dapat menyebabkan bug yang terputus-putus dan mungkin sulit untuk diperbaiki. Anda akan berakhir aplikasi Anda dalam keadaan yang tidak diketahui yang dapat mengakibatkan aplikasi Anda merusak data penting apa pun yang sedang bekerja. Tidak baik.
Jika rakitan Anda dicentang (properties-> build-> advanced-> periksa aritmatika overflow / underflow atau opsi / checked compiler), kode Anda akan melempar pengecualian ketika terjadi under / overflow. Ini mungkin lebih baik daripada tidak; Namun standar untuk rakitan adalah tidak memeriksa over / underflow.
Pertanyaan sebenarnya adalah "apa yang Anda coba lakukan?" Tanpa mengetahui persyaratan Anda, tidak ada yang bisa memberi tahu Anda apa yang harus Anda lakukan dalam kasus ini, selain yang sudah jelas: JANGAN MELAKUKANNYA.
Jika Anda secara khusus TIDAK peduli, jawaban di sini valid. Namun, Anda harus mengomunikasikan pemahaman Anda bahwa overflow dapat terjadi dan itu tidak masalah dengan membungkus kode cor Anda di blok yang tidak dicentang
unchecked{// do your conversions that may underflow/overflow here}
Dengan begitu orang-orang yang datang di belakang Anda memahami bahwa Anda tidak peduli, dan jika di masa depan seseorang mengubah bangunan Anda ke / diperiksa, kode Anda tidak akan rusak secara tak terduga.
Jika semua yang ingin Anda lakukan adalah menjatuhkan bagian fraksional dari angka tersebut, meninggalkan bagian integral, Anda dapat menggunakan Math.Truncate.
decimal actual =10.5M;decimal expected =10M;Assert.AreEqual(expected,Math.Truncate(actual));
Meskipun saya menduga mereka adalah hal yang sama di bawah tenda jika inputnya adalah desimal, saya merasa lebih nyaman menggunakan Desimal. Lebih singkat daripada Matematika. yang bukan basis 10, sebagai lawan dari Desimal. Truncate, yang merupakan pemotongan benar dari nomor basis 10.
Brian
7
Konteks yang tidak diperiksa tidak berlaku untuk desimal; operasi pada desimal akan menghasilkan OverflowExceptions.
Dave
46
int i =(int)d;
akan memberi Anda nomor dibulatkan.
Jika Anda ingin membulatkan ke nomor genap terdekat (yaitu> .5 akan mengumpulkan), Anda dapat menggunakan
int i =(int)Math.Round(d,MidpointRounding.ToEven);
Secara umum Anda dapat memilih antara semua tipe numerik dalam C #. Jika tidak ada informasi yang akan hilang selama pemeran, Anda dapat melakukannya secara implisit:
int i =10;decimal d = i;
meskipun Anda masih dapat melakukannya secara eksplisit jika Anda menginginkan:
int i =10;decimal d =(decimal)i;
Namun, jika Anda akan kehilangan informasi melalui para pemain, Anda harus melakukannya secara eksplisit (untuk menunjukkan bahwa Anda sadar Anda mungkin kehilangan informasi):
decimal d =10.5M;int i =(int)d;
Di sini Anda kehilangan "0,5". Ini mungkin baik-baik saja, tetapi Anda harus eksplisit tentang hal itu dan membuat pemeran eksplisit untuk menunjukkan Anda tahu Anda mungkin kehilangan informasi.
Anda benar-benar ingin MidpointRounding.AwayFromZero jika Anda ingin> * .5 selalu berdasarkan pada pengalaman saya mencoba kode di atas melihat sampel output di sini: msdn.microsoft.com/en-us/library/…
Elijah Lofgren
@ElijahLofgren Agak tergantung: Jika Anda melakukan statistik, ToEvenharus mencegah penyimpangan statistik. Namun jika Anda beroperasi dengan barang atau uang yang dikenakan biaya, AwayFromZerosepertinya pilihan yang tepat.
Dari dokumentasi : "API ini mendukung infrastruktur .NET Framework dan tidak dimaksudkan untuk digunakan langsung dari kode Anda". Mengapa tidak menggunakan Convert.ToInt32?
H.Wolper
7
Trik yang rapi untuk pembulatan cepat adalah dengan menambahkan 0,5 sebelum Anda memasukkan desimal ke int.
Mengapa repot-repot melakukan ini ketika ada Math.Floor dan Math.Ceiling?
Badaro
Pada saat itu, saya cukup baru untuk C # dan untuk beberapa alasan saya tidak menyadari fungsi-fungsi ini ada. Sebenarnya ini adalah trik yang saya pelajari dari C / C ++, yang ternyata lebih bermanfaat.
Perhatikan bahwa mereka semua juga mengembalikan Desimal - karena Desimal memiliki rentang nilai yang lebih besar daripada Int32, jadi Anda masih perlu melakukan pengecoran (dan periksa apakah ada overflow / underflow).
Saya menemukan bahwa operator casting tidak bekerja jika Anda memiliki desimal kotak (yaitu nilai desimal di dalam jenis objek). Convert.ToInt32 (desimal sebagai objek) berfungsi dengan baik dalam kasus ini.
Situasi ini muncul ketika mengambil nilai IDENTITY / AUTONUMBER dari database:
SqlCommand foo =newSqlCommand("INSERT INTO...; SELECT SCOPE_IDENTITY()", conn);int ID =Convert.ToInt32(foo.ExecuteScalar());// worksint ID =(int)foo.ExecuteScalar();// throws InvalidCastException
Menambahkan lebih banyak untuk referensi: itu karena Anda hanya dapat membuka kotak ke jenis asli yang sama. Di sini SELECT SCOPE_IDENTITY()mengembalikan numeric(38, 0)yang diterjemahkan decimaloleh .NET. foo.ExecuteScalar()mengembalikan decimalkotak objectyang tidak dapat dicor langsung ke int. (int)(decimal)foo.ExecuteScalar()atau Convert.ToInt32(foo.ExecuteScalar())akan bekerja.
rageit
0
Tampaknya tidak ada jawaban yang berhubungan dengan OverflowException / UnderflowException yang berasal dari upaya mengubah desimal yang berada di luar kisaran int.
int intValue =(int)Math.Max(int.MinValue,Math.Min(int.MaxValue, decimalValue));
Solusi ini akan mengembalikan nilai int maksimum atau minimum yang mungkin jika nilai desimal berada di luar kisaran int. Anda mungkin ingin menambahkan beberapa pembulatan dengan Math.Round, Math.Ceiling atau Math.Floor ketika nilai berada di dalam kisaran int.
Jawaban:
Gunakan
Convert.ToInt32
mulai darimscorlib
padaLihat MSDN . Anda juga bisa menggunakan
Decimal.ToInt32
. Sekali lagi, lihat MSDN . Akhirnya, Anda dapat melakukan pemeran langsung seperti padayang menggunakan operator pemeran eksplisit. Lihat MSDN .
sumber
null
vs0
vs.""
). Saya akan merekomendasikan untuk tidak pernah menggunakan Konversi kecuali Anda benar-benar membutuhkan fleksibilitasnya (yaitu dalam skenario yang diketik secara dinamis)OverflowException
. Saya percaya bahwa @Will akan memberikan jawaban yang lebih baik di sini stackoverflow.com/a/501165/39532Convert.ToInt32
danDecimal.ToInt32
berperilaku berbeda. Dari MSDN:Decimal.ToInt32
- Nilai kembali adalah bagian integral dari nilai desimal; digit fraksional terpotong .Convert.ToInt32
- Nilai pengembalian dibulatkan ke bilangan bulat bertanda 32-bit terdekat. Jika nilainya setengah di antara dua bilangan bulat, bilangan genap dikembalikan; yaitu, 4,5 dikonversi menjadi 4, dan 5,5 dikonversi menjadi 6.Kamu tidak bisa
Yah, tentu saja Anda bisa , namun int (System.Int32) tidak cukup besar untuk menampung setiap kemungkinan nilai desimal.
Itu berarti jika Anda membuat desimal yang lebih besar dari int.MaxValue Anda akan overflow, dan jika desimal lebih kecil dari int.MinValue, itu akan underflow.
Apa yang terjadi ketika Anda under / overflow? Satu dari dua hal. Jika build Anda tidak dicentang (yaitu, CLR tidak peduli jika Anda melakukannya), aplikasi Anda akan berlanjut setelah nilai over / underflow, tetapi nilai di int tidak akan seperti yang Anda harapkan. Ini dapat menyebabkan bug yang terputus-putus dan mungkin sulit untuk diperbaiki. Anda akan berakhir aplikasi Anda dalam keadaan yang tidak diketahui yang dapat mengakibatkan aplikasi Anda merusak data penting apa pun yang sedang bekerja. Tidak baik.
Jika rakitan Anda dicentang (properties-> build-> advanced-> periksa aritmatika overflow / underflow atau opsi / checked compiler), kode Anda akan melempar pengecualian ketika terjadi under / overflow. Ini mungkin lebih baik daripada tidak; Namun standar untuk rakitan adalah tidak memeriksa over / underflow.
Pertanyaan sebenarnya adalah "apa yang Anda coba lakukan?" Tanpa mengetahui persyaratan Anda, tidak ada yang bisa memberi tahu Anda apa yang harus Anda lakukan dalam kasus ini, selain yang sudah jelas: JANGAN MELAKUKANNYA.
Jika Anda secara khusus TIDAK peduli, jawaban di sini valid. Namun, Anda harus mengomunikasikan pemahaman Anda bahwa overflow dapat terjadi dan itu tidak masalah dengan membungkus kode cor Anda di blok yang tidak dicentang
Dengan begitu orang-orang yang datang di belakang Anda memahami bahwa Anda tidak peduli, dan jika di masa depan seseorang mengubah bangunan Anda ke / diperiksa, kode Anda tidak akan rusak secara tak terduga.
Jika semua yang ingin Anda lakukan adalah menjatuhkan bagian fraksional dari angka tersebut, meninggalkan bagian integral, Anda dapat menggunakan Math.Truncate.
sumber
akan memberi Anda nomor dibulatkan.
Jika Anda ingin membulatkan ke nomor genap terdekat (yaitu> .5 akan mengumpulkan), Anda dapat menggunakan
Secara umum Anda dapat memilih antara semua tipe numerik dalam C #. Jika tidak ada informasi yang akan hilang selama pemeran, Anda dapat melakukannya secara implisit:
meskipun Anda masih dapat melakukannya secara eksplisit jika Anda menginginkan:
Namun, jika Anda akan kehilangan informasi melalui para pemain, Anda harus melakukannya secara eksplisit (untuk menunjukkan bahwa Anda sadar Anda mungkin kehilangan informasi):
Di sini Anda kehilangan "0,5". Ini mungkin baik-baik saja, tetapi Anda harus eksplisit tentang hal itu dan membuat pemeran eksplisit untuk menunjukkan Anda tahu Anda mungkin kehilangan informasi.
sumber
ToEven
harus mencegah penyimpangan statistik. Namun jika Anda beroperasi dengan barang atau uang yang dikenakan biaya,AwayFromZero
sepertinya pilihan yang tepat.Ini seharusnya bekerja dengan baik.
sumber
Berikut ini adalah halaman web tipe data konversi yang sangat berguna bagi orang lain. http://www.convertdatatypes.com/Convert-decimal-to-int-in-CSharp.html
sumber
System.Decimal
mengimplementasikanIConvertable
antarmuka, yang memilikiToInt32()
anggota.Apakah menelepon
System.Decimal.ToInt32()
bekerja untuk Anda?sumber
Trik yang rapi untuk pembulatan cepat adalah dengan menambahkan 0,5 sebelum Anda memasukkan desimal ke int.
Masih pergi
i=10
, tapiAkan mengumpulkan sehingga
i=11
.sumber
Saya lebih suka menggunakan Math.round , Math.floor , Math.Ceiling atau Math.Truncate secara eksplisit mengatur mode pembulatan yang sesuai.
Perhatikan bahwa mereka semua juga mengembalikan Desimal - karena Desimal memiliki rentang nilai yang lebih besar daripada Int32, jadi Anda masih perlu melakukan pengecoran (dan periksa apakah ada overflow / underflow).
sumber
desimal
d = 5.5
;ref: tautan teks
sumber
Membulatkan desimal ke bilangan bulat terdekat
kapan
a = 49.9
, lalub = 50
kapan
a = 49.5
, lalub = 50
kapan
a = 49.4
, lalub = 49
dll.sumber
Saya menemukan bahwa operator casting tidak bekerja jika Anda memiliki desimal kotak (yaitu nilai desimal di dalam jenis objek). Convert.ToInt32 (desimal sebagai objek) berfungsi dengan baik dalam kasus ini.
Situasi ini muncul ketika mengambil nilai IDENTITY / AUTONUMBER dari database:
Lihat 4.3.2 Konversi unboxing
sumber
SELECT SCOPE_IDENTITY()
mengembalikannumeric(38, 0)
yang diterjemahkandecimal
oleh .NET.foo.ExecuteScalar()
mengembalikandecimal
kotakobject
yang tidak dapat dicor langsung keint
.(int)(decimal)foo.ExecuteScalar()
atauConvert.ToInt32(foo.ExecuteScalar())
akan bekerja.Tampaknya tidak ada jawaban yang berhubungan dengan OverflowException / UnderflowException yang berasal dari upaya mengubah desimal yang berada di luar kisaran int.
Solusi ini akan mengembalikan nilai int maksimum atau minimum yang mungkin jika nilai desimal berada di luar kisaran int. Anda mungkin ingin menambahkan beberapa pembulatan dengan Math.Round, Math.Ceiling atau Math.Floor ketika nilai berada di dalam kisaran int.
sumber