Contoh:
float timeRemaining = 0.58f;
Mengapa f
harus ada di akhir nomor ini?
Contoh:
float timeRemaining = 0.58f;
Mengapa f
harus ada di akhir nomor ini?
double & int
.
Jawaban:
Deklarasi float Anda berisi dua bagian:
timeRemaining
bertipe float
.0.58
ke variabel ini.Masalahnya terjadi di bagian 2.
Sisi kanan dievaluasi dengan sendirinya. Menurut spesifikasi C #, angka yang mengandung titik desimal yang tidak memiliki sufiks diartikan sebagai a double
.
Jadi kita sekarang memiliki double
nilai yang ingin kita tetapkan ke tipe variabel float
. Untuk melakukan ini, harus ada konversi implisit dari double
menjadi float
. Tidak ada konversi seperti itu, karena Anda mungkin (dan dalam hal ini memang) kehilangan informasi dalam konversi tersebut.
Alasannya adalah nilai yang digunakan oleh compiler sebenarnya bukan 0,58, tetapi nilai floating-point yang paling dekat dengan 0,58, yaitu 0,57999999999999978655962351581366 ... untuk double
dan tepat 0,579999946057796478271484375 untuk float
.
Sebenarnya, f
tidak diperlukan. Anda dapat menghindari penggunaan f
sufiks dengan mentransmisikan nilai ke float
:
float timeRemaining = (float)0.58;
(float) 0.58
kerjanya? Tadi Anda mengatakan bahwa tidak ada konversi, karena informasi mungkin hilang, lalu kenapa pemeran bisa bekerja?
2.4
diartikan sebagai dobel di tempat lain. 2. Konversi penyempitan implisit (seperti dari ganda menjadi mengambang) tidak diperbolehkan. Jika Anda ingin membuat pengecualian terhadap aturan ini, Anda harus memiliki alasan yang sangat bagus. Menyimpan 1 pukulan kunci sepertinya tidak cukup baik.
Karena ada beberapa jenis numerik yang compiler dapat digunakan untuk mewakili nilai 0.58
: float
, double
dan decimal
. Kecuali Anda setuju dengan kompilator yang memilihkan satu untuk Anda, Anda harus mengerti.
Dokumentasi untuk double
menyatakan bahwa jika Anda tidak menentukan jenisnya sendiri, kompilator selalu memilih double
jenis literal numerik nyata apa pun:
Secara default, literal numerik nyata di sisi kanan operator penugasan diperlakukan sebagai ganda. Namun, jika Anda ingin bilangan bulat diperlakukan sebagai ganda, gunakan akhiran d atau D.
Menambahkan sufiks f
membuat a float
; sufiks d
menciptakan a double
; akhiran m
menciptakan a decimal
. Semua ini juga bekerja dalam huruf besar.
Namun, ini masih belum cukup untuk menjelaskan mengapa ini tidak dapat dikompilasi:
float timeRemaining = 0.58;
Setengah dari jawaban yang hilang adalah bahwa konversi dari the double
0.58
ke float
timeRemaining
berpotensi kehilangan informasi, sehingga compiler menolak untuk menerapkannya secara implisit. Jika Anda menambahkan cast eksplisit, konversi dilakukan; jika Anda menambahkan f
sufiks maka tidak diperlukan konversi. Dalam kedua kasus, kode kemudian akan dikompilasi.
int
dan satu untuk double
.
double a = 0.69f;
?
float
ke double
.
Masalahnya adalah bahwa .NET, untuk memungkinkan beberapa jenis operasi implisit dilakukan yang melibatkan float
dan double
, diperlukan baik secara eksplisit menentukan apa yang harus terjadi dalam semua skenario yang melibatkan operan campuran atau memungkinkan konversi implisit antara jenis yang akan dilakukan dalam satu arah saja; Microsoft memilih untuk mengikuti jejak Java dalam mengizinkan arah yang kadang-kadang lebih menyukai presisi, tetapi sering mengorbankan kebenaran dan umumnya menimbulkan kerumitan.
Dalam hampir semua kasus, mengambil double
nilai yang paling dekat dengan kuantitas numerik tertentu dan menugaskannya ke a float
akan menghasilkan float
nilai yang paling dekat dengan kuantitas yang sama. Ada beberapa kasus sudut, seperti nilai 9.007.199.791.611.905; float
representasi terbaik akan menjadi 9.007.200.328.482.816 (yang dihapus oleh 536.870.911), tetapi memberikan double
representasi terbaik (yaitu 9.007.199.791.611.904) untuk float
menghasilkan 9.007.199.254.740.992 (yang turun sebesar 536.870.913). Namun secara umum, mengubah double
representasi terbaik dari beberapa kuantitas menjadi float
akan menghasilkan float
representasi terbaik yang mungkin , atau salah satu dari dua representasi yang pada dasarnya sama baiknya.
Perhatikan bahwa perilaku yang diinginkan ini berlaku bahkan pada kondisi ekstrem; misalnya, float
representasi terbaik untuk kuantitas 10 ^ 308 cocok dengan float
representasi yang dicapai dengan mengubah double
representasi terbaik dari kuantitas tersebut. Demikian juga, float
representasi terbaik dari 10 ^ 309 cocok dengan float
representasi yang dicapai dengan mengubah double
representasi terbaik dari kuantitas tersebut.
Sayangnya, konversi ke arah yang tidak memerlukan pemeran eksplisit jarang seakurat itu. Mengonversi float
representasi terbaik dari suatu nilai menjadi double
jarang akan menghasilkan sesuatu yang mendekati double
representasi terbaik dari nilai tersebut, dan dalam beberapa kasus hasilnya mungkin meleset oleh ratusan lipat (mis. Mengubah float
representasi terbaik dari 10 ^ 40 menjadi double
akan menghasilkan nilai yang membandingkan lebih besar dari double
representasi terbaik 10 ^ 300.
Sayangnya, aturan konversi adalah apa adanya, jadi orang harus hidup dengan menggunakan typecast dan sufiks yang konyol saat mengonversi nilai ke arah "aman", dan berhati-hati dengan typecast implisit ke arah berbahaya yang sering kali akan menghasilkan hasil palsu.
double
.