Apa perbedaan antara decimal
, float
dan double
. NET?
Kapan seseorang akan menggunakan salah satunya?
Apa perbedaan antara decimal
, float
dan double
. NET?
Kapan seseorang akan menggunakan salah satunya?
Jawaban:
float
dan double
yang mengambang biner jenis titik . Dengan kata lain, mereka mewakili angka seperti ini:
10001.10010110011
Nomor biner dan lokasi titik biner dikodekan dalam nilai.
decimal
adalah tipe titik desimal mengambang . Dengan kata lain, mereka mewakili angka seperti ini:
12345.65789
Sekali lagi, angka dan lokasi titik desimal keduanya dikodekan dalam nilai - itulah yang membuat decimal
masih menjadi tipe floating point daripada tipe fixed point.
Yang penting untuk dicatat adalah bahwa manusia digunakan untuk mewakili bukan bilangan bulat dalam bentuk desimal, dan mengharapkan hasil yang tepat dalam representasi desimal; tidak semua angka desimal persis mewakili dalam titik mengambang biner - 0,1, misalnya - jadi jika Anda menggunakan nilai titik mengambang biner Anda akan benar-benar mendapatkan perkiraan hingga 0,1. Anda masih akan mendapatkan perkiraan saat menggunakan titik desimal mengambang - hasil dari membagi 1 dengan 3 tidak dapat direpresentasikan secara tepat, misalnya.
Adapun apa yang harus digunakan saat:
Untuk nilai yang merupakan "desimal yang tepat secara alami" ada baiknya digunakan decimal
. Ini biasanya cocok untuk konsep apa pun yang ditemukan oleh manusia: nilai finansial adalah contoh yang paling jelas, tetapi ada juga yang lain. Pertimbangkan skor yang diberikan kepada penyelam atau skaters, misalnya.
Untuk nilai-nilai yang lebih artefak alam yang tidak bisa diukur dengan tepat pula, float
/ double
yang lebih tepat. Misalnya, data ilmiah biasanya diwakili dalam formulir ini. Di sini, nilai asli tidak akan "akurat desimal" untuk memulai, jadi tidak penting bagi hasil yang diharapkan untuk mempertahankan "akurasi desimal". Jenis-jenis titik biner mengambang jauh lebih cepat digunakan daripada desimal.
float
/ double
Biasanya tidak mewakili angka seperti 101.101110
, biasanya itu digambarkan sebagai sesuatu seperti 1101010 * 2^(01010010)
- eksponen
float
adalah kata kunci C # alias dan bukan tipe .Net. itu System.Single
.. single
dan double
merupakan tipe titik biner mengambang.
Presisi adalah perbedaan utama.
Float - 7 digit (32 bit)
Ganda -15-16 digit (64 bit)
Desimal -28-29 digit signifikan (128 bit)
Desimal memiliki presisi yang jauh lebih tinggi dan biasanya digunakan dalam aplikasi keuangan yang membutuhkan tingkat akurasi yang tinggi. Desimal jauh lebih lambat (hingga 20X kali dalam beberapa tes) daripada dobel / mengambang.
Desimal dan Mengapung / Ganda tidak bisa dibandingkan tanpa gips sedangkan Float dan Ganda bisa. Desimal juga memungkinkan penyandian atau trailing nol.
float flt = 1F/3;
double dbl = 1D/3;
decimal dcm = 1M/3;
Console.WriteLine("float: {0} double: {1} decimal: {2}", flt, dbl, dcm);
Hasil:
float: 0.3333333
double: 0.333333333333333
decimal: 0.3333333333333333333333333333
0.1
- itu jarang terjadi di dunia nyata! Setiap format penyimpanan terbatas akan mengonfigurasikan jumlah tak terhingga dari kemungkinan nilai ke sejumlah pola bit. Misalnya, float
akan mengonfigurasi 0.1
dan 0.1 + 1e-8
, sementara decimal
akan mengonfigurasi 0.1
dan 0.1 + 1e-29
. Tentu, dalam kisaran tertentu , nilai-nilai tertentu dapat direpresentasikan dalam format apapun dengan nol kehilangan akurasi (misalnya float
dapat menyimpan bilangan bulat apapun hingga 1.6e7 dengan nol kehilangan akurasi) - tapi itu masih tidak terbatas akurasi.
0.1
adalah bukan nilai khusus ! Satu-satunya hal yang membuat 0.1
"lebih baik" daripada 0.10000001
adalah karena manusia menyukai basis 10. Dan bahkan dengan sebuah float
nilai, jika Anda menginisialisasi dua nilai dengan 0.1
cara yang sama, keduanya akan memiliki nilai yang sama . Hanya saja nilai itu tidak akan persis 0.1
- itu akan menjadi nilai terdekat dengan 0.1
yang dapat secara tepat direpresentasikan sebagai afloat
. Tentu, dengan mengapung biner (1.0 / 10) * 10 != 1.0
, tetapi dengan mengapung desimal, (1.0 / 3) * 3 != 1.0
juga. Tidak ada yang sangat tepat.
double a = 0.1; double b = 0.1;
maka a == b
itu benar . Hanya saja a
dan keduanya tidak b
akan sama persis 0.1
. Dalam C #, jika Anda melakukannya decimal a = 1.0m / 3.0m; decimal b = 1.0m / 3.0m;
maka a == b
juga akan menjadi kenyataan. Tetapi dalam kasus itu, tidak satu pun dari keduanyaa
tidak b
akan sama persis1/3
- keduanya akan sama 0.3333...
. Dalam kedua kasus, beberapa akurasi hilang karena keterwakilan. Anda dengan keras kepala mengatakan bahwa ia decimal
memiliki ketepatan "tak terbatas", yang salah .
Struktur desimal benar-benar diarahkan pada perhitungan keuangan yang membutuhkan akurasi, yang relatif tidak toleran terhadap pembulatan. Namun, desimal tidak memadai untuk aplikasi ilmiah, karena beberapa alasan:
+---------+----------------+---------+----------+---------------------------------------------+
| C# | .Net Framework | Signed? | Bytes | Possible Values |
| Type | (System) type | | Occupied | |
+---------+----------------+---------+----------+---------------------------------------------+
| sbyte | System.Sbyte | Yes | 1 | -128 to 127 |
| short | System.Int16 | Yes | 2 | -32768 to 32767 |
| int | System.Int32 | Yes | 4 | -2147483648 to 2147483647 |
| long | System.Int64 | Yes | 8 | -9223372036854775808 to 9223372036854775807 |
| byte | System.Byte | No | 1 | 0 to 255 |
| ushort | System.Uint16 | No | 2 | 0 to 65535 |
| uint | System.UInt32 | No | 4 | 0 to 4294967295 |
| ulong | System.Uint64 | No | 8 | 0 to 18446744073709551615 |
| float | System.Single | Yes | 4 | Approximately ±1.5 x 10-45 to ±3.4 x 1038 |
| | | | | with 7 significant figures |
| double | System.Double | Yes | 8 | Approximately ±5.0 x 10-324 to ±1.7 x 10308 |
| | | | | with 15 or 16 significant figures |
| decimal | System.Decimal | Yes | 12 | Approximately ±1.0 x 10-28 to ±7.9 x 1028 |
| | | | | with 28 or 29 significant figures |
| char | System.Char | N/A | 2 | Any Unicode character (16 bit) |
| bool | System.Boolean | N/A | 1 / 2 | true or false |
+---------+----------------+---------+----------+---------------------------------------------+
Saya tidak akan mengulangi berton-ton informasi yang baik (dan beberapa buruk) sudah dijawab dalam jawaban dan komentar lain, tetapi saya akan menjawab pertanyaan tindak lanjut Anda dengan tip:
Kapan seseorang akan menggunakan salah satunya?
Gunakan desimal untuk nilai yang dihitung
Gunakan float / double untuk nilai yang diukur
Beberapa contoh:
uang (apakah kita menghitung uang atau mengukur uang?)
jarak (apakah kita menghitung jarak atau mengukur jarak? *)
skor (apakah kita menghitung skor atau mengukur skor?)
Kami selalu menghitung uang dan jangan pernah mengukurnya. Kami biasanya mengukur jarak. Kami sering menghitung skor.
* Dalam beberapa kasus, apa yang saya sebut jarak nominal , kita mungkin memang ingin 'menghitung' jarak. Misalnya, mungkin kita berurusan dengan tanda negara yang menunjukkan jarak ke kota, dan kita tahu bahwa jarak itu tidak pernah memiliki lebih dari satu angka desimal (xxx.x km).
float
7 digit presisi
double
memiliki presisi sekitar 15 digit
decimal
memiliki presisi sekitar 28 digit
Jika Anda membutuhkan akurasi yang lebih baik, gunakan double bukannya float. Dalam CPU modern kedua tipe data memiliki kinerja yang hampir sama. Satu-satunya manfaat menggunakan float adalah mereka mengambil lebih sedikit ruang. Praktis penting hanya jika Anda punya banyak dari mereka.
Saya menemukan ini menarik. Yang Harus Diketahui Setiap Ilmuwan Komputer Tentang Aritmatika Titik Apung
double
tepat dalam aplikasi akuntansi dalam kasus-kasus (dan pada dasarnya hanya kasus-kasus) di mana tidak ada tipe integer lebih besar dari 32 bit tersedia, dan double
sedang digunakan seolah-olah itu adalah tipe integer 53-bit (misalnya untuk menahan seluruh jumlah uang, atau jumlah total seratus sen). Tidak banyak digunakan untuk hal-hal seperti saat ini, tetapi banyak bahasa memperoleh kemampuan untuk menggunakan nilai floating-point presisi ganda jauh sebelum mereka memperoleh 64-bit (atau dalam beberapa kasus bahkan 32-bit!) Bilangan bulat matematika.
Real
IIRC yang bisa mewakili nilai hingga 1,8E + 19 dengan presisi unit. Saya akan berpikir itu akan jauh lebih waras untuk aplikasi akuntansi untuk digunakan Real
untuk mewakili seluruh jumlah uang daripada ...
double
tipe yang memiliki akurasi unit hingga 9E15. Jika seseorang perlu menyimpan bilangan bulat yang lebih besar dari tipe bilangan bulat terbesar yang tersedia, penggunaannya double
cenderung lebih sederhana dan lebih efisien daripada mencoba memalsukan matematika multi-presisi, terutama mengingat bahwa sementara prosesor memiliki instruksi untuk melakukan 16x16-> 32 atau. ..
Tidak ada yang menyebutkan itu
Dalam pengaturan default, Mengapung (System.Single) dan ganda (System.Double) tidak akan pernah menggunakan pengecekan overflow sementara Desimal (System.Decimal) akan selalu menggunakan pengecekan overflow.
maksudku
decimal myNumber = decimal.MaxValue;
myNumber += 1;
melempar OverflowException .
Tetapi ini tidak:
float myNumber = float.MaxValue;
myNumber += 1;
&
double myNumber = double.MaxValue;
myNumber += 1;
float.MaxValue+1 == float.MaxValue
, sama seperti decimal.MaxValue+0.1D == decimal.MaxValue
. Mungkin maksudmu seperti itu float.MaxValue*2
?
System.Decimal
melempar pengecualian sebelum menjadi tidak dapat membedakan seluruh unit, tetapi jika aplikasi seharusnya berurusan dengan dolar misalnya dan sen, yang bisa terlambat.
decimal
dengan nol (CS0020), dan hal yang sama berlaku untuk integral literal. Namun jika nilai desimal runtime dibagi dengan nol, Anda akan mendapatkan pengecualian, bukan kesalahan kompilasi.
Bilangan bulat, seperti yang disebutkan, adalah bilangan bulat. Mereka tidak dapat menyimpan titik sesuatu, seperti 0,7, 0,42, dan 0,007. Jika Anda perlu menyimpan angka yang bukan angka bulat, Anda perlu jenis variabel yang berbeda. Anda dapat menggunakan tipe ganda atau tipe float. Anda mengatur jenis variabel ini dengan cara yang persis sama: alih-alih menggunakan kata int
, Anda mengetik double
atau float
. Seperti ini:
float myFloat;
double myDouble;
( float
kependekan dari "floating point", dan hanya berarti angka dengan titik sesuatu di akhir.)
Perbedaan antara keduanya adalah dalam ukuran angka yang bisa mereka pegang. Sebab float
, Anda dapat memiliki hingga 7 digit di nomor Anda. Untuk double
s, Anda dapat memiliki hingga 16 digit. Untuk lebih tepatnya, inilah ukuran resmi:
float: 1.5 × 10^-45 to 3.4 × 10^38
double: 5.0 × 10^-324 to 1.7 × 10^308
float
adalah nomor 32-bit, dan double
merupakan nomor 64-bit.
Klik dua kali tombol baru Anda untuk mendapatkan kode. Tambahkan tiga baris berikut ke kode tombol Anda:
double myDouble;
myDouble = 0.007;
MessageBox.Show(myDouble.ToString());
Hentikan program Anda dan kembali ke jendela kode. Ubah baris ini:
myDouble = 0.007;
myDouble = 12345678.1234567;
Jalankan program Anda dan klik tombol ganda Anda. Kotak pesan dengan benar menampilkan nomornya. Tambahkan nomor lain di akhir, dan C # akan kembali membulatkan ke atas atau ke bawah. Moralnya adalah jika Anda menginginkan keakuratan, berhati-hatilah dalam pembulatan!
decimal
sebenarnya disimpan dalam format desimal (tidak seperti basis 2; sehingga tidak akan kehilangan atau angka bulat karena konversi antara dua sistem numerik); selain itu, decimal
tidak memiliki konsep nilai khusus seperti NaN, -0, ∞, atau -∞.
Ini adalah utas yang menarik bagi saya, karena hari ini, kami baru saja mengalami bug kecil yang tidak menyenangkan, berkenaan decimal
dengan ketelitian yang kurang dari a float
.
Dalam kode C # kami, kami membaca nilai numerik dari spreadsheet Excel, mengubahnya menjadi decimal
, kemudian mengirimkannya decimal
kembali ke Layanan untuk disimpan ke dalam database SQL Server .
Microsoft.Office.Interop.Excel.Range cell = …
object cellValue = cell.Value2;
if (cellValue != null)
{
decimal value = 0;
Decimal.TryParse(cellValue.ToString(), out value);
}
Sekarang, untuk hampir semua nilai Excel kami, ini bekerja dengan baik. Tetapi bagi sebagian orang, nilai Excel yang sangat kecil, menggunakan decimal.TryParse
nilai yang hilang sepenuhnya. Salah satu contohnya adalah
cellValue = 0,00006317592
Decimal.TryParse (cellValue.ToString (), nilai keluar); // akan mengembalikan 0
Solusinya, anehnya, adalah mengubah nilai Excel menjadi yang double
pertama, dan kemudian menjadi decimal
:
Microsoft.Office.Interop.Excel.Range cell = …
object cellValue = cell.Value2;
if (cellValue != null)
{
double valueDouble = 0;
double.TryParse(cellValue.ToString(), out valueDouble);
decimal value = (decimal) valueDouble;
…
}
Meskipun double
memiliki presisi kurang dari a decimal
, angka kecil yang sebenarnya dipastikan ini masih akan dikenali. Untuk beberapa alasan, double.TryParse
sebenarnya bisa mengambil angka kecil seperti itu, sedangkan decimal.TryParse
akan mengaturnya ke nol.
Aneh. Sangat aneh.
decimal.Parse("0.00006317592")
berfungsi - Anda mengalami sesuatu yang lain terjadi. - Notasi ilmiah mungkin?
Untuk aplikasi seperti game dan sistem tertanam di mana memori dan kinerja keduanya kritis, float biasanya merupakan jenis pilihan numerik karena lebih cepat dan setengah dari ukuran ganda. Bilangan bulat dulunya adalah senjata pilihan, tetapi kinerja floating point telah melampaui bilangan bulat dalam prosesor modern. Desimal benar!
Tipe variabel Desimal, Double, dan Float berbeda dalam cara mereka menyimpan nilai. Presisi adalah perbedaan utama di mana float adalah tipe data floating point presisi tunggal (32 bit), double adalah tipe data floating point presisi ganda (64 bit) dan desimal adalah tipe data floating point 128-bit.
Float - 32 bit (7 digit)
Ganda - 64 bit (15-16 digit)
Desimal - 128 bit (28-29 digit signifikan)
Lebih lanjut tentang ... perbedaan antara Desimal, Float, dan Double
Masalah dengan semua jenis ini adalah bahwa ketidaktepatan tertentu bertahan DAN bahwa masalah ini dapat terjadi dengan angka desimal kecil seperti dalam contoh berikut
Dim fMean as Double = 1.18
Dim fDelta as Double = 0.08
Dim fLimit as Double = 1.1
If fMean - fDelta < fLimit Then
bLower = True
Else
bLower = False
End If
Pertanyaan: Nilai mana yang mengandung variabel bLower?
Jawab: Pada mesin 32 bit, bLower mengandung TRUE !!!
Jika saya mengganti Double dengan Desimal, bLower berisi FALSE yang merupakan jawaban yang bagus.
Dalam dobel, masalahnya adalah fMean-fDelta = 1.09999999999 yang lebih rendah dari 1.1.
Perhatian: Saya pikir masalah yang sama pasti bisa ada untuk nomor lain karena Desimal hanya dua kali lipat dengan presisi lebih tinggi dan presisi selalu ada batasnya.
Faktanya, Dobel, Float, dan Desimal bersesuaian dengan desimal BINARY dalam COBOL!
Sangat disesalkan bahwa tipe numerik lain yang diterapkan di COBOL tidak ada di .Net. Bagi mereka yang tidak tahu COBOL, ada di COBOL tipe numerik berikut
BINARY or COMP like float or double or decimal
PACKED-DECIMAL or COMP-3 (2 digit in 1 byte)
ZONED-DECIMAL (1 digit in 1 byte)
Dengan kata sederhana:
/==========================================================================================
Type Bits Have up to Approximate Range
/==========================================================================================
float 32 7 digits -3.4 × 10 ^ (38) to +3.4 × 10 ^ (38)
double 64 15-16 digits ±5.0 × 10 ^ (-324) to ±1.7 × 10 ^ (308)
decimal 128 28-29 significant digits ±7.9 x 10 ^ (28) or (1 to 10 ^ (28)
/==========================================================================================
Anda dapat membaca lebih lanjut di sini , Float , Double , dan Desimal .
Decimal
cocok untuk aplikasi keuangan, dan itu adalah kriteria utama untuk digunakan ketika memutuskan antara Decimal
dan Double
. Jarang Double
ketepatan tidak cukup untuk aplikasi ilmiah, misalnya (dan Decimal
seringkali tidak cocok untuk aplikasi ilmiah karena jangkauannya yang terbatas).
Perbedaan utama antara masing-masing adalah presisi.
float
adalah 32-bit
nomor, double
adalah 64-bit
jumlah dan decimal
merupakan128-bit
nomor.
Desimal 128 bit (28-29 digit signifikan) Dalam hal aplikasi keuangan, lebih baik menggunakan jenis Desimal karena memberi Anda tingkat akurasi yang tinggi dan mudah untuk menghindari kesalahan pembulatan. Gunakan desimal untuk matematika non-integer di mana presisi dibutuhkan (misalnya, uang dan mata uang)
Ganda 64 bit (15-16 digit) Jenis Ganda mungkin merupakan tipe data yang paling sering digunakan untuk nilai riil, kecuali penanganan uang. Gunakan dobel untuk matematika non-integer di mana jawaban paling tepat tidak diperlukan.
Float 32 bit (7 digit) Ini digunakan sebagian besar di perpustakaan grafik karena permintaan yang sangat tinggi untuk kekuatan pemrosesan, juga digunakan situasi yang dapat menanggung kesalahan pembulatan.
Decimals
jauh lebih lambat dari pada double/float
.
Decimals
dan Floats/Doubles
tidak bisa dibandingkan tanpa para pemain sedangkan Floats
dan Doubles
bisa.
Decimals
juga memungkinkan pengodean atau trailing nol.
Anda harus menyebutkan nilai sebagai:
Decimal dec = 12M/6;
Double dbl = 11D/6;
float fl = 15F/6;
dan periksa hasilnya.
Float - 4
Double - 8
Decimal - 12