Ubah Desimal menjadi Dua

672

Saya ingin menggunakan a Track-Baruntuk mengubah Formopacity.

Ini kode saya:

decimal trans = trackBar1.Value / 5000;
this.Opacity = trans;

Ketika saya membangun aplikasi, itu memberikan kesalahan berikut:

Tidak dapat secara implisit mengkonversi tipe decimalmenjadidouble

Saya sudah mencoba menggunakan transdan doublekemudian Controltidak berhasil. Kode ini berfungsi dengan baik di proyek VB.NET sebelumnya.

Eggs McLaren
sumber
11
Juga, Desimal tidak dapat mewakili nilai selebar Double. Desimal hanya bisa naik ke +/- 7.9228162514264337593543950335E + 28; sedangkan Double dapat naik ke +/- 1.79769313486232E + 308
TraumaPony
8
Seseorang harus menandai yang ini sebagai duplikat.
Ivan
8
@Van: Ini pertanyaan ke-4 yang ditanyakan pada SO ...
Nikolas
1
@ Nikolas: Memang. Dilacak di sini hari ini.
Juni

Jawaban:

447

Pemain eksplisit untuk doublemenyukai ini tidak perlu:

double trans = (double) trackBar1.Value / 5000.0;

Mengidentifikasi konstanta sebagai 5000.0(atau sebagai 5000d) sudah cukup:

double trans = trackBar1.Value / 5000.0;
double trans = trackBar1.Value / 5000d;
Kevin Dente
sumber
123

Jawaban yang lebih umum untuk pertanyaan umum "Desimal vs Double?": Desimal untuk perhitungan moneter untuk menjaga presisi, Double untuk perhitungan ilmiah yang tidak terpengaruh oleh perbedaan kecil. Karena Double adalah tipe yang asli dari CPU (representasi internal disimpan di basis 2 ), perhitungan yang dibuat dengan Double berkinerja lebih baik daripada Desimal (yang direpresentasikan dalam basis 10 secara internal).

huseyint
sumber
83

Kode Anda berfungsi dengan baik di VB.NET karena secara implisit melakukan gips, sementara C # memiliki yang implisit dan eksplisit.

Dalam C # konversi dari desimal ke ganda eksplisit karena Anda kehilangan keakuratan. Misalnya 1.1 tidak dapat secara akurat dinyatakan sebagai dobel, tetapi dapat sebagai desimal (lihat " Angka titik mengambang - lebih tidak akurat daripada yang Anda pikirkan " karena alasan mengapa).

Di VB konversi ditambahkan untuk Anda oleh kompiler:

decimal trans = trackBar1.Value / 5000m;
this.Opacity = (double) trans;

Itu (double)harus secara eksplisit dinyatakan dalam C #, tetapi dapat tersirat oleh kompiler VB yang lebih 'pemaaf'.

Keith
sumber
80

Mengapa Anda membaginya dengan 5000? Cukup atur nilai Minimum dan Maksimum TrackBar antara 0 dan 100 dan kemudian bagi Nilai dengan 100 untuk persentase Opacity. Minimal 20 contoh di bawah ini mencegah formulir menjadi sama sekali tidak terlihat:

private void Form1_Load(object sender, System.EventArgs e)
{
    TrackBar1.Minimum = 20;
    TrackBar1.Maximum = 100;

    TrackBar1.LargeChange = 10;
    TrackBar1.SmallChange = 1;
    TrackBar1.TickFrequency = 5;
}

private void TrackBar1_Scroll(object sender, System.EventArgs e)
{
    this.Opacity = TrackBar1.Value / 100;
}
Gordon Bell
sumber
5
Bukankah ini hanya memindahkan masalah? Daripada masalah dengan 5000, OP akan punya masalah dengan 100?
jww
62

Anda memiliki dua masalah. Pertama, Opacitymembutuhkan nilai ganda, bukan nilai desimal. Kompiler memberi tahu Anda bahwa meskipun ada konversi antara desimal dan dobel, itu adalah konversi eksplisit yang harus Anda tentukan agar dapat berfungsi. Yang kedua adalah TrackBar.Valuenilai integer dan membagi sebuah int dengan sebuah int menghasilkan sebuah int, apa pun jenis variabel yang Anda tetapkan. Dalam hal ini ada gips implisit dari int ke desimal atau dobel - karena tidak ada kehilangan presisi ketika Anda melakukan gips - sehingga kompiler tidak mengeluh, tetapi nilai yang Anda dapatkan selalu 0, mungkin, karenatrackBar.Valueselalu kurang dari 5000. Solusinya adalah mengubah kode Anda untuk menggunakan ganda (tipe asli untuk Opacity) dan melakukan aritmatika floating point dengan secara eksplisit membuat konstanta ganda - yang akan memiliki efek mempromosikan aritmatika - atau casting trackBar.Valueuntuk menggandakan , yang akan melakukan hal yang sama - atau keduanya. Oh, dan Anda tidak perlu variabel antara kecuali digunakan di tempat lain. Dugaan saya adalah kompiler akan mengoptimalkannya.

trackBar.Opacity = (double)trackBar.Value / 5000.0;
tvanfosson
sumber
58

Menurut pendapat saya, diinginkan untuk sejelas mungkin. Ini menambah kejelasan kode dan membantu sesama programmer yang akhirnya membacanya.

Selain (atau bukannya) menambahkan .0ke nomor, Anda dapat menggunakan decimal.ToDouble().

Berikut ini beberapa contohnya:

// Example 1
double transperancy = trackBar1.Value/5000;
this.Opacity = decimal.ToDouble(transperancy);

// Example 2 - with inline temp
this.Opacity = decimal.ToDouble(trackBar1.Value/5000);
andnil
sumber
57

Kedengarannya seperti this.Opacitynilai ganda, dan kompiler tidak suka Anda mencoba menjejalkan nilai desimal ke dalamnya.

Ryan Fox
sumber
50

The Opacity properti adalah tipe ganda:

double trans = trackBar1.Value / 5000.0;
this.Opacity = trans;

atau hanya:

this.Opacity = trackBar1.Value / 5000.0;

atau:

this.Opacity = trackBar1.Value / 5000d;

Perhatikan bahwa saya menggunakan 5000.0(atau 5000d) untuk memaksa pembagian ganda karena trackBar1.Valuemerupakan bilangan bulat dan akan melakukan pembagian bilangan bulat dan hasilnya akan menjadi bilangan bulat.

Darin Dimitrov
sumber
49

Anda harus menggunakan 5000.0bukan 5000.

Dina
sumber
47

Dengan asumsi Anda menggunakan WinForms, Form.Opacityadalah tipe double, jadi Anda harus menggunakan:

double trans = trackBar1.Value / 5000.0;
this.Opacity = trans;

Kecuali Anda membutuhkan nilai di tempat lain, lebih mudah untuk menulis:

this.Opacity = trackBar1.Value / 5000.0;

Alasan kontrol tidak berfungsi ketika Anda mengubah kode menjadi sekadar ganda adalah karena Anda memiliki:

double trans = trackbar1.Value / 5000;

yang diartikan 5000sebagai bilangan bulat, dan karenatrackbar1.Value juga bilangan bulat transnilai Anda selalu nol. Dengan secara eksplisit menjadikan angka sebagai nilai titik apung dengan menambahkan .0kompiler sekarang dapat mengartikannya sebagai dobel dan melakukan perhitungan yang tepat.

ChrisF
sumber
41

Solusi terbaik adalah:

this.Opacity = decimal.ToDouble(trackBar1.Value/5000);
Danny Fox
sumber
41

Karena Opacitymerupakan nilai ganda, saya hanya akan menggunakan ganda dari awal dan tidak dilemparkan sama sekali, tetapi pastikan untuk menggunakan ganda saat membaginya sehingga Anda tidak kehilangan presisi apa pun

Opacity = trackBar1.Value / 5000.0;
Darryl
sumber
36
this.Opacity = trackBar1.Value / 5000d;
Kolappan N
sumber
0

Coba ini:

Opacity = decimal.ToDouble(trackBar1.Value / 5000.0);```
pengguna12828597
sumber
0

Kamu bisa menggunakan Opacity = decimal.ToDouble(trackBar1.Value / 5000);

Lê Phi
sumber