Transmisikan Variabel Ganda ke Desimal

96

Bagaimana satu gips doubleuntuk decimalyang digunakan ketika melakukan pengembangan mata uang. Kemana perginya M?

decimal dtot = (decimal)(doubleTotal);
flo
sumber

Jawaban:

85

Anda hanya menggunakan Muntuk literal numerik, saat Anda mentransmisikannya hanya:

decimal dtot = (decimal)doubleTotal;

Perhatikan bahwa bilangan floating point tidak cocok untuk menyimpan nilai pasti, jadi jika Anda menambahkan angka terlebih dahulu dan kemudian mengubahnya menjadi DecimalAnda mungkin mendapatkan kesalahan pembulatan. Anda mungkin ingin mengonversi angka menjadi Decimalsebelum menambahkannya bersama-sama, atau pastikan bahwa angka tersebut bukan angka floating point sejak awal.

Guffa
sumber
sebagai pertanyaan lanjutan, mengapa konversi eksplisit diperlukan? Saya sudah mencobanya dan mendapatkan kesalahan bahwa tanda ganda tidak dapat secara eksplisit diubah menjadi desimal, tetapi bukankah desimal lebih presisi? (misalnya, seperti melakukan casting dari int ke double dapat tersirat.)
4
@ Kortana: Ketepatan desimal lebih tinggi, tetapi kisarannya lebih kecil. Nilai ganda mungkin berada di luar rentang untuk desimal. Lihat: stackoverflow.com/questions/7817866/…
Guffa
41

Anda dapat mengubah dua kali lipat menjadi desimal seperti ini, tanpa memerlukan Makhiran literal:

double dbl = 1.2345D;
decimal dec = (decimal) dbl;

Anda harus menggunakan Msaat mendeklarasikan nilai desimal literal baru:

decimal dec = 123.45M;

(Tanpa M, 123.45 diperlakukan sebagai ganda dan tidak akan dikompilasi.)

Chris Fulstow
sumber
28

gunakan kelas konversi default: Convert.ToDecimal(Double)

Timur Sadykov
sumber
1
Tidak, karena ini akan melempar OverflowException double vol_y = (double) Decimal.MaxValue + 10E + 28D; Console.WriteLine ("Convert.ToDecimal (vol_y) =" + Convert.ToDecimal (vol_y));
ToXinE
2
@ToXinE IMHO dalam banyak kasus, OverflowException lebih baik daripada membuat data yang salah secara diam-diam
Saya sendiri
16
Convert.ToDecimal(the double you are trying to convert);
Tom
sumber
2
Saya telah belajar bahwa kelas Convert jauh lebih fleksibel dan aman daripada cast di C #.
Tom
3
"Aman"? seperti ketika ia tidak dapat mentransmisikannya, ia melempar pengecualian pada saat run-time alih-alih kesalahan kompilator? Saya telah digigit oleh itu berkali-kali sehingga saya secara aktif menghindari Konversi ...
Peter Ritchie
8
@PeterRitchie thread agak tua tetapi ini harus dikatakan: Memanggil metode Convert secara langsung akan menjadi pendekatan yang lebih tepat. Mungkin saya hanya seorang pengoptimalan aneh tetapi satu instruksi yang kurang untuk diselesaikan adalah bonus (karena menggunakan sintaks cor eksplisit (Jenis) hanyalah kelebihan operator yang memanggil Convert).
Mike Johnson
2
@PeterRitchie: Dari perspektif desain bahasa, akan lebih baik jika programmer menggunakan salah satu dari dua metode konversi daripada mengizinkan typecast from doubleto decimal, mengingat doublenilai seperti (1000000.0 / 3.0) dalam beberapa kasus ingin memotong presisi "berlebih" yang menghasilkan 333333.333333333D, tetapi dalam kasus lain seseorang ingin mempertahankannya, menghasilkan 333333.333333333313931D. Daripada hanya mengatakan "ubah ke desimal", kode harus menentukan bagaimana konversi itu harus dilakukan.
supercat
2
@supercat yang benar-benar tampaknya tidak terkait dengan komentar pertama saya karena menggunakan Convert.ToDecimal(double)sama dengan (decimal)doubleTotal, kecuali jika doubleTotaldiubah ke jenis yang berbeda Anda mungkin akan menghindari kesalahan waktu kompilasi dan memperkenalkan kesalahan waktu proses yang lebih sulit ditemukan karena ToDecimal yang berbeda override mungkin dipanggil. Operator pemeran jauh lebih eksplisit ...
Peter Ritchie
1

Ini adalah pertanyaan lama dan saya benar-benar memanfaatkan beberapa jawaban yang ditampilkan di sini. Namun demikian, dalam skenario khusus saya, mungkin saja doublenilai yang ingin saya ubah decimalsering lebih besar dari decimal.MaxValue. Jadi, alih-alih menangani pengecualian, saya menulis metode ekstensi ini:

    public static decimal ToDecimal(this double @double) => 
        @double > (double) decimal.MaxValue ? decimal.MaxValue : (decimal) @double;

Pendekatan di atas berfungsi jika Anda tidak ingin repot menangani pengecualian luapan dan jika hal seperti itu terjadi, Anda hanya ingin mempertahankan nilai maksimal yang mungkin (kasus saya), tetapi saya sadar bahwa untuk banyak skenario lain ini bukan perilaku yang diharapkan dan mungkin penanganan pengecualian akan dibutuhkan.

taquion
sumber
1
Ini akan gagal dalam kasus berikut double _double = (double) decimal.MaxValue; Saya akan menyarankan menggunakan> = dalam perbandingan toDecimal desimal statis publik (ini _double ganda) => _double> = (double) decimal.MaxValue? decimal.MaxValue: (desimal) _double;
Martin Eyles