Perbedaan antara desimal, float, dan gandakan .NET?

Jawaban:

2267

floatdan doubleyang mengambang biner jenis titik . Dengan kata lain, mereka mewakili angka seperti ini:

10001.10010110011

Nomor biner dan lokasi titik biner dikodekan dalam nilai.

decimaladalah 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 decimalmasih 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/ doubleyang 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.

Jon Skeet
sumber
58
float/ doubleBiasanya tidak mewakili angka seperti 101.101110, biasanya itu digambarkan sebagai sesuatu seperti 1101010 * 2^(01010010)- eksponen
Mingwei Samuel
79
@Hazzard: Itulah arti bagian "dan lokasi titik biner" dari jawabannya.
Jon Skeet
112
Saya terkejut itu belum dikatakan, floatadalah kata kunci C # alias dan bukan tipe .Net. itu System.Single.. singledan doublemerupakan tipe titik biner mengambang.
Brett Caswell
54
@ BKSpurgeon: Ya, hanya dengan cara yang sama Anda dapat mengatakan bahwa semuanya adalah tipe biner, yang pada saat itu menjadi definisi yang tidak berguna. Desimal adalah tipe desimal di mana angka tersebut dinyatakan sebagai bilangan bulat signifikansi dan skala, sehingga hasilnya adalah skala signifikansi * 10 ^, sedangkan float dan double adalah skala signifikansi * 2 ^. Anda mengambil angka yang ditulis dalam desimal, dan memindahkan titik desimal cukup jauh ke kanan sehingga Anda memiliki bilangan bulat untuk menghitung signifikansi dan skala. Untuk float / double Anda akan mulai dengan angka yang ditulis dalam biner.
Jon Skeet
21
Perbedaan lain: float 32-bit; ganda 64-bit; dan desimal 128-bit.
David
1073

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
cgreeno
sumber
65
@Thecrocodilehunter: maaf, tapi tidak. Desimal dapat mewakili semua angka yang dapat direpresentasikan dalam notasi desimal, tetapi tidak 1/3 misalnya. 1.0m / 3.0m akan dievaluasi menjadi 0.33333333 ... dengan jumlah 3s yang besar tetapi terbatas pada akhirnya. Mengalikannya dengan 3 tidak akan menghasilkan 1,0 yang tepat.
Erik P.
50
@Thecrocodilehunter: Saya pikir Anda membingungkan akurasi dan presisi. Mereka adalah hal yang berbeda dalam konteks ini. Presisi adalah jumlah digit yang tersedia untuk mewakili suatu angka. Semakin presisi, semakin sedikit yang Anda butuhkan untuk dibulatkan. Tidak ada tipe data yang memiliki ketepatan tak terbatas.
Igby Largeman
13
@Thecrocodilehunter: Anda mengasumsikan bahwa nilai yang diukur tepat 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, floatakan mengonfigurasi 0.1dan 0.1 + 1e-8, sementara decimalakan mengonfigurasi 0.1dan 0.1 + 1e-29. Tentu, dalam kisaran tertentu , nilai-nilai tertentu dapat direpresentasikan dalam format apapun dengan nol kehilangan akurasi (misalnya floatdapat menyimpan bilangan bulat apapun hingga 1.6e7 dengan nol kehilangan akurasi) - tapi itu masih tidak terbatas akurasi.
Daniel Pryden
27
@Thecrocodilehunter: Anda melewatkan maksud saya. 0.1adalah bukan nilai khusus ! Satu-satunya hal yang membuat 0.1"lebih baik" daripada 0.10000001adalah karena manusia menyukai basis 10. Dan bahkan dengan sebuah floatnilai, jika Anda menginisialisasi dua nilai dengan 0.1cara yang sama, keduanya akan memiliki nilai yang sama . Hanya saja nilai itu tidak akan persis 0.1 - itu akan menjadi nilai terdekat dengan 0.1yang 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.0juga. Tidak ada yang sangat tepat.
Daniel Pryden
16
@Thecrocodilehunter: Anda masih tidak mengerti. Saya tidak tahu bagaimana mengatakannya dengan lebih jelas: Di C, jika Anda melakukannya double a = 0.1; double b = 0.1;maka a == b itu benar . Hanya saja adan keduanya tidak bakan sama persis 0.1. Dalam C #, jika Anda melakukannya decimal a = 1.0m / 3.0m; decimal b = 1.0m / 3.0m;maka a == bjuga akan menjadi kenyataan. Tetapi dalam kasus itu, tidak satu pun dari keduanyaa tidak bakan sama persis1/3 - keduanya akan sama 0.3333.... Dalam kedua kasus, beberapa akurasi hilang karena keterwakilan. Anda dengan keras kepala mengatakan bahwa ia decimalmemiliki ketepatan "tak terbatas", yang salah .
Daniel Pryden
84

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:

  • Hilangnya ketepatan tertentu dapat diterima dalam banyak perhitungan ilmiah karena batas praktis dari masalah fisik atau artefak yang diukur. Kehilangan presisi tidak dapat diterima dalam keuangan.
  • Desimal jauh (jauh) lebih lambat daripada float dan dobel untuk sebagian besar operasi, terutama karena operasi floating point dilakukan dalam biner, sedangkan desimal dilakukan di basis 10 (yaitu float dan dobel ditangani oleh perangkat keras FPU, seperti MMX / SSE , sedangkan desimal dihitung dalam perangkat lunak).
  • Desimal memiliki rentang nilai yang jauh lebih kecil daripada ganda, meskipun faktanya mendukung lebih banyak digit presisi. Oleh karena itu, Desimal tidak dapat digunakan untuk mewakili banyak nilai ilmiah.
Mark Jones
sumber
5
Jika Anda melakukan perhitungan keuangan, Anda benar-benar harus melempar tipe data Anda sendiri atau menemukan perpustakaan yang bagus yang sesuai dengan kebutuhan Anda. Akurasi dalam lingkungan keuangan ditentukan oleh badan standar (manusia) dan mereka memiliki aturan lokal (baik dalam waktu dan geografi) yang sangat spesifik tentang cara melakukan perhitungan. Hal-hal seperti pembulatan yang benar tidak ditangkap dalam tipe data numerik sederhana di .Net. Kemampuan untuk melakukan perhitungan hanyalah sebagian kecil dari teka-teki.
James Moore
76
+---------+----------------+---------+----------+---------------------------------------------+
| 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                               |
+---------+----------------+---------+----------+---------------------------------------------+

Lihat di sini untuk informasi lebih lanjut .

Uwe Keim
sumber
5
Anda meninggalkan perbedaan terbesar, yang merupakan basis yang digunakan untuk tipe desimal (desimal disimpan sebagai basis 10, semua tipe numerik lainnya yang terdaftar adalah basis 2).
BrainSlugs83
1
Rentang nilai untuk Single dan Double tidak digambarkan dengan benar pada gambar di atas atau posting forum sumber. Karena kita tidak dapat dengan mudah menulis teks di sini, gunakan karakter tanda sisipan: Single harus 10 ^ -45 dan 10 ^ 38, dan Double harus 10 ^ -324 dan 10 ^ 308. Juga, MSDN memiliki float dengan kisaran -3,4x10 ^ 38 hingga + 3,4x10 ^ 38. Cari MSDN untuk System.Single dan System.Double dalam hal perubahan tautan. Tunggal: msdn.microsoft.com/en-us/library/b1e65aza.aspx Ganda: msdn.microsoft.com/en-us/library/678hzkk9.aspx
deegee
2
Desimal adalah 128 bit ... berarti ia menempati 16 byte bukan 12
user1477332
51

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).

Tomosius
sumber
1
Saya sangat suka jawaban ini, terutama pertanyaan "apakah kita menghitung atau mengukur uang?" Namun, selain uang, saya tidak bisa memikirkan apa pun yang "dihitung" yang bukan hanya bilangan bulat. Saya telah melihat beberapa aplikasi yang menggunakan desimal hanya karena ganda memiliki terlalu sedikit angka signifikan. Dengan kata lain, desimal dapat digunakan karena C # tidak memiliki tipe quadruple en.wikipedia.org/wiki/Quadruple-precision_floating-point_format
John Henckel
48

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

CharithJ
sumber
1
@RogerLipscombe: Saya akan mempertimbangkan yang doubletepat 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 doublesedang 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.
supercat
1
Jawaban Anda menyiratkan ketepatan adalah satu-satunya perbedaan antara tipe data ini. Mengingat aritmatika floating point biner biasanya diimplementasikan dalam FPU perangkat keras , kinerja adalah perbedaan yang signifikan. Ini mungkin tidak penting untuk beberapa aplikasi, tetapi sangat penting untuk yang lain.
berlayar
6
@supercat ganda tidak pernah layak dalam aplikasi akuntansi. Karena Double hanya dapat memperkirakan nilai desimal (bahkan dalam kisaran presisi sendiri). Ini karena penyimpanan nilai disimpan dalam format basis-2 (biner).
BrainSlugs83
2
@ BrainSlugs83: Penggunaan tipe floating-point untuk menahan jumlah non- bilangan bulat adalah tidak tepat, tetapi secara historis sangat umum bagi bahasa untuk memiliki tipe floating-point yang secara tepat dapat mewakili nilai bilangan bulat yang lebih besar daripada yang bisa mewakili tipe integer mereka . Mungkin contoh yang paling ekstrem adalah Turbo-87 yang hanya tipe integernya terbatas pada -32768 hingga +32767, tetapi RealIIRC yang bisa mewakili nilai hingga 1,8E + 19 dengan presisi unit. Saya akan berpikir itu akan jauh lebih waras untuk aplikasi akuntansi untuk digunakan Realuntuk mewakili seluruh jumlah uang daripada ...
supercat
1
... untuk itu mencoba melakukan matematika multi-presisi menggunakan banyak nilai 16-bit. Untuk sebagian besar bahasa lain perbedaannya tidak terlalu ekstrem, tetapi untuk waktu yang lama sudah sangat umum bagi bahasa untuk tidak memiliki tipe integer yang melampaui 4E9 tetapi memiliki doubletipe yang memiliki akurasi unit hingga 9E15. Jika seseorang perlu menyimpan bilangan bulat yang lebih besar dari tipe bilangan bulat terbesar yang tersedia, penggunaannya doublecenderung lebih sederhana dan lebih efisien daripada mencoba memalsukan matematika multi-presisi, terutama mengingat bahwa sementara prosesor memiliki instruksi untuk melakukan 16x16-> 32 atau. ..
supercat
36

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;
GorkemHalulu
sumber
1
float.MaxValue+1 == float.MaxValue, sama seperti decimal.MaxValue+0.1D == decimal.MaxValue. Mungkin maksudmu seperti itu float.MaxValue*2?
supercat
@supercar Tetapi tidak benar bahwa desimal.MaxValue + 1 == decimal.MaxValue
GorkemHalulu
@supercar decimal.MaxValue + 0,1m == decimal.MaxValue ok
GorkemHalulu
1
The System.Decimalmelempar pengecualian sebelum menjadi tidak dapat membedakan seluruh unit, tetapi jika aplikasi seharusnya berurusan dengan dolar misalnya dan sen, yang bisa terlambat.
supercat
28
  1. Double dan float dapat dibagi dengan integer nol tanpa pengecualian pada saat kompilasi dan run time.
  2. Desimal tidak dapat dibagi dengan bilangan bulat nol. Kompilasi akan selalu gagal jika Anda melakukannya.
xport
sumber
6
Mereka yakin bisa! Mereka juga memiliki beberapa nilai "ajaib" seperti Infinity, Negative Infinity, dan NaN (bukan angka) yang membuatnya sangat berguna untuk mendeteksi garis vertikal saat menghitung kemiringan ... Selanjutnya, jika Anda perlu memutuskan antara memanggil float .TryParse, double.TryParse, dan desimal.TryParse (untuk mendeteksi jika string adalah angka, misalnya), saya sarankan menggunakan double atau float, karena mereka akan mengurai "Infinity", "-Infinity", dan "NaN" dengan benar , sedangkan desimal tidak akan.
BrainSlugs83
Kompilasi hanya gagal jika Anda mencoba untuk membagi literal decimaldengan 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.
Drew Noakes
@ BrainSlugs83 Namun, Anda mungkin tidak ingin menguraikan "Infinity" atau "NaN" tergantung pada konteksnya. Sepertinya eksploitasi yang baik untuk input pengguna jika pengembang tidak cukup keras.
Musim dingin
28

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 doubleatau float. Seperti ini:

float myFloat;
double myDouble;

( floatkependekan 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 doubles, 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

floatadalah nomor 32-bit, dan doublemerupakan 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!

daniel
sumber
2
"Titik sesuatu" yang Anda sebutkan umumnya disebut sebagai "bagian fraksional" dari suatu angka. "Floating point" tidak berarti "angka dengan titik sesuatu pada akhirnya"; melainkan "Floating Point" yang membedakan jenis angka, dan bukan angka "Fixed Point" (yang juga dapat menyimpan nilai fraksional); perbedaannya adalah apakah presisi sudah pasti, atau mengambang. - Angka floating point memberi Anda rentang nilai dinamis yang jauh lebih besar (Min dan Max), dengan biaya presisi, sedangkan angka titik tetap memberi Anda jumlah presisi konstan dengan biaya kisaran.
BrainSlugs83
16
  • float: ± 1,5 x 10 ^ -45 hingga ± 3,4 x 10 ^ 38 (~ 7 angka signifikan
  • dua kali lipat: ± 5,0 x 10 ^ -324 hingga ± 1,7 x 10 ^ 308 (15-16 angka signifikan)
  • desimal: ± 1,0 x 10 ^ -28 hingga ± 7,9 x 10 ^ 28 (angka penting 28-29)
Mukesh Kumar
sumber
9
Perbedaannya lebih dari sekadar presisi. - decimalsebenarnya disimpan dalam format desimal (tidak seperti basis 2; sehingga tidak akan kehilangan atau angka bulat karena konversi antara dua sistem numerik); selain itu, decimaltidak memiliki konsep nilai khusus seperti NaN, -0, ∞, atau -∞.
BrainSlugs83
13

Ini adalah utas yang menarik bagi saya, karena hari ini, kami baru saja mengalami bug kecil yang tidak menyenangkan, berkenaan decimaldengan ketelitian yang kurang dari a float.

Dalam kode C # kami, kami membaca nilai numerik dari spreadsheet Excel, mengubahnya menjadi decimal, kemudian mengirimkannya decimalkembali 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.TryParsenilai 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 doublepertama, 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 doublememiliki presisi kurang dari a decimal, angka kecil yang sebenarnya dipastikan ini masih akan dikenali. Untuk beberapa alasan, double.TryParsesebenarnya bisa mengambil angka kecil seperti itu, sedangkan decimal.TryParseakan mengaturnya ke nol.

Aneh. Sangat aneh.

Mike Gledhill
sumber
3
Karena penasaran, apa nilai mentah dari cellValue.ToString ()? Desimal.TryParse ("0,00006317592", keluar val) tampaknya berfungsi ...
micahtan
11
-1 Jangan salah paham, jika benar, ini sangat menarik tetapi ini adalah pertanyaan terpisah, tentu saja itu bukan jawaban untuk pertanyaan ini.
barat
2
Mungkin karena sel Excel mengembalikan nilai dobel dan ToString () adalah "6.31759E-05" oleh karena itu desimal.Parse () tidak menyukai notasi. Saya yakin jika Anda memeriksa nilai kembalinya Decimal.TryParse () itu pasti salah.
SergioL
2
@weston Answers sering melengkapi jawaban lain dengan mengisi nuansa yang mereka lewatkan. Jawaban ini menyoroti perbedaan dalam hal parsing. Ini sangat banyak jawaban untuk pertanyaan itu!
Robino
1
Er ... decimal.Parse("0.00006317592")berfungsi - Anda mengalami sesuatu yang lain terjadi. - Notasi ilmiah mungkin?
BrainSlugs83
9

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!

yoyo
sumber
Hampir semua sistem modern, bahkan ponsel, memiliki dukungan perangkat keras untuk sistem ganda; dan jika gim Anda memiliki fisika yang bahkan sederhana, Anda akan melihat perbedaan besar antara dobel dan float. (Misalnya, menghitung kecepatan / gesekan dalam klon Asteroid sederhana, ganda memungkinkan percepatan mengalir jauh lebih lancar daripada mengapung. - Sepertinya itu tidak masalah, tapi itu benar-benar penting.)
BrainSlugs83
Doubles juga menggandakan ukuran float, artinya Anda perlu mengunyah data dua kali lebih banyak, yang merusak kinerja cache Anda. Seperti biasa, ukur dan lanjutkan sesuai itu.
yoyo
7

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

warnerl
sumber
5

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) 
schlebe
sumber
4

Dengan kata sederhana:

  1. Tipe variabel Desimal, Double, dan Float berbeda dalam cara mereka menyimpan nilai.
  2. Presisi adalah perbedaan utama (Perhatikan bahwa ini bukan perbedaan tunggal) di mana float adalah tipe data floating point presisi tunggal (32 bit), double adalah tipe data floating point presisi ganda (64 bit) dan desimal 128-bit tipe data floating point.
  3. Tabel ringkasan:

/==========================================================================================
    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 .

GntS
sumber
Apa yang ditambahkan jawaban ini yang belum tercakup dalam jawaban yang ada? BTW, Anda "atau" di baris "desimal" salah: garis miring di halaman web yang Anda salin dari menunjukkan divisi daripada alternatif.
Mark Dickinson
1
Dan saya membantah keras bahwa presisi adalah perbedaan utama. Perbedaan utama adalah basis: floating-point desimal versus floating-point biner. Perbedaan itulah yang membuat Decimalcocok untuk aplikasi keuangan, dan itu adalah kriteria utama untuk digunakan ketika memutuskan antara Decimaldan Double. Jarang Doubleketepatan tidak cukup untuk aplikasi ilmiah, misalnya (dan Decimalseringkali tidak cocok untuk aplikasi ilmiah karena jangkauannya yang terbatas).
Mark Dickinson
2

Perbedaan utama antara masing-masing adalah presisi.

floatadalah 32-bitnomor, doubleadalah 64-bitjumlah dan decimalmerupakan128-bit nomor.

pengguna3776645
sumber
0
  • 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.

Decimalsjauh lebih lambat dari pada double/float.

Decimalsdan Floats/Doublestidak bisa dibandingkan tanpa para pemain sedangkan Floatsdan Doublesbisa.

Decimals juga memungkinkan pengodean atau trailing nol.

Reza Jenabi
sumber
-1

Untuk menentukan Desimal, Float, dan Double di .Net (c #)

Anda harus menyebutkan nilai sebagai:

Decimal dec = 12M/6;
Double dbl = 11D/6;
float fl = 15F/6;

dan periksa hasilnya.

Dan Bytes ditempati oleh masing-masing

Float - 4
Double - 8
Decimal - 12
Purnima Bhatia
sumber