Saya tahu Anda tidak dapat mengandalkan persamaan antara nilai tipe ganda atau desimal secara normal, tetapi saya bertanya-tanya apakah 0 adalah kasus khusus.
Meskipun saya dapat memahami ketidaktepatan antara 0,000000000001 dan 0,0000000000000002, 0 sendiri tampaknya cukup sulit untuk dikacaukan karena tidak ada artinya. Jika Anda tidak tepat dalam hal apa pun, itu bukan apa-apa lagi.
Tapi saya tidak tahu banyak tentang topik ini jadi bukan hak saya untuk mengatakannya.
double x = 0.0;
return (x == 0.0) ? true : false;
Akankah itu selalu benar?
Jawaban:
Hal ini aman untuk mengharapkan bahwa perbandingan akan kembali
true
jika dan hanya jika variabel ganda memiliki nilai tepat0.0
(yang pada potongan kode asli Anda, tentu saja, kasus ini). Ini konsisten dengan semantik==
operator.a == b
berarti "a
sama denganb
".Tidaklah aman (karena tidak benar ) untuk mengharapkan bahwa hasil dari beberapa kalkulasi akan menjadi nol dalam aritmatika ganda (atau lebih umum, floating point) setiap kali hasil kalkulasi yang sama dalam Matematika murni adalah nol. Ini karena ketika kalkulasi dilakukan di lapangan, kesalahan presisi floating point muncul - sebuah konsep yang tidak ada dalam aritmatika bilangan riil dalam Matematika.
sumber
Jika Anda perlu melakukan banyak perbandingan "kesetaraan", mungkin ada baiknya untuk menulis sedikit fungsi pembantu atau metode ekstensi di .NET 3.5 untuk membandingkan:
Ini dapat digunakan dengan cara berikut:
sumber
Untuk sampel sederhana Anda, pengujian itu tidak masalah. Tapi bagaimana dengan ini:
Ingatlah bahwa .1 adalah desimal berulang dalam biner dan tidak dapat direpresentasikan dengan tepat. Kemudian bandingkan dengan kode ini:
Saya biarkan Anda menjalankan pengujian untuk melihat hasil yang sebenarnya: Anda lebih mungkin mengingatnya seperti itu.
sumber
Dari entri MSDN untuk Double.Equals :
Juga, lihat Double.Epsilon .
sumber
x.Equals(y)
, maka(1/x).Equals(1/y)
, tetapi bukan itu masalahnya jikax
adalah0
dany
adalah1/Double.NegativeInfinity
. Nilai-nilai itu dinyatakan setara, meski timbal baliknya tidak.x = 0
dany = 0
, dan Anda masih akan menemukannya1/x != 1/y
.x
dany
sebagai tipedouble
? Bagaimana Anda membandingkan hasil agar laporannya tidak sama? Perhatikan bahwa 1 / 0,0 bukan NaN.1.0/0.0
gagal menjadi NaN sebagaimana mestinya, karena batasnya tidak unik. Kedua, bahwa ketidakterbatasan dibandingkan satu sama lain, tanpa memperhatikan derajat ketidakterbatasan)Masalahnya muncul saat Anda membandingkan berbagai jenis implementasi nilai floating point, misalnya membandingkan float dengan double. Tapi dengan tipe yang sama, seharusnya tidak menjadi masalah.
Masalahnya, programmer terkadang lupa bahwa implisit type cast (double to float) terjadi untuk perbandingan dan hasilnya menjadi bug.
sumber
Jika nomor itu langsung ditetapkan ke float atau double maka aman untuk menguji nol atau bilangan bulat apa pun yang dapat direpresentasikan dalam 53 bit untuk double atau 24 bit untuk float.
Atau dengan kata lain Anda selalu dapat menetapkan dan nilai integer menjadi ganda dan kemudian membandingkan kembali ganda ke integer yang sama dan dijamin itu akan sama.
Anda juga dapat memulai dengan menetapkan bilangan bulat dan membuat perbandingan sederhana terus bekerja dengan tetap menambahkan, mengurangi, atau mengalikan dengan bilangan bulat (dengan asumsi hasilnya kurang dari 24 bit untuk float abd 53 bit untuk double). Jadi, Anda dapat memperlakukan pelampung dan ganda sebagai bilangan bulat dalam kondisi terkontrol tertentu.
sumber
Tidak, ini tidak baik. Apa yang disebut nilai denormalisasi (subnormal), jika dibandingkan dengan 0,0, akan dibandingkan sebagai salah (bukan nol), tetapi bila digunakan dalam persamaan akan dinormalisasi (menjadi 0,0). Jadi, menggunakan ini sebagai mekanisme untuk menghindari pembagian-dengan-nol tidaklah aman. Sebagai gantinya, tambahkan 1.0 dan bandingkan dengan 1.0. Ini akan memastikan bahwa semua subnormal diperlakukan sebagai nol.
sumber
Coba ini, dan Anda akan menemukan bahwa == tidak dapat diandalkan untuk double / float.
double d = 0.1 + 0.2; bool b = d == 0.3;
Inilah jawaban dari Quora.
sumber
Sebenarnya, saya pikir lebih baik menggunakan kode berikut untuk membandingkan nilai ganda dengan 0,0:
Sama untuk float:
sumber