.NET'te ondalık, kayan nokta ve çift arasındaki fark nedir?


Yanıtlar:


2266

floatve doubleedilir kayan ikili noktası türleri . Başka bir deyişle, böyle bir sayıyı temsil ederler:

10001.10010110011

İkili sayı ve ikili noktanın konumu değer içinde kodlanır.

decimalBir olan kayan ondalık noktası türü . Başka bir deyişle, böyle bir sayıyı temsil ederler:

12345.65789

Yine, ondalık noktanın numarası ve konumu değer içinde kodlanır - decimalsabit nokta türü yerine hala kayan nokta türü yapan da budur .

Dikkat edilmesi gereken önemli nokta, insanların tamsayı olmayanları ondalık formda temsil etmek için kullanılması ve ondalık gösterimlerde kesin sonuçlar beklemesidir; ondalık sayıların tümü ikili kayan noktalı - 0,1 - tam olarak gösterilemez, bu nedenle ikili kayan nokta değeri kullanırsanız, 0,1'e yaklaşırsınız. Kayan ondalık noktasını kullanırken de yaklaşık tahminler alırsınız - örneğin, 1'e 3 ayırmanın sonucu tam olarak temsil edilemez.

Ne zaman kullanılacağı konusunda:

  • "Doğal olarak kesin ondalık sayılar" olan değerler için kullanılması iyidir decimal. Bu genellikle insanlar tarafından icat edilen herhangi bir kavram için uygundur: finansal değerler en açık örnektir, ancak başkaları da vardır. Örneğin dalgıçlara veya buz patencilerine verilen puanı düşünün.

  • Gerçekten ölçülemez nitelikte daha eserler olan değerler için tam Neyse, float/ doubledaha uygundur. Örneğin, bilimsel veriler genellikle bu formda temsil edilir. Burada, orijinal değerlerle başlamak için "ondalık olarak doğru" olmayacaktır, bu nedenle beklenen sonuçların "ondalık doğruluğunu" sürdürmesi önemli değildir. Kayan ikili nokta türleriyle çalışmak ondalık sayılara göre çok daha hızlıdır.


58
float/ doublegenellikle sayıları temsil etmez 101.101110, normalde 1101010 * 2^(01010010)bir üs olarak temsil edilir - bir üs
Mingwei Samuel

79
@Hazzard: Cevabın "ve ikili noktanın yeri" kısmının anlamı budur.
Jon Skeet

112
Henüz söylenmedi float, bir C # diğer anahtar kelime ve bir .Net türü değil şaşırdım . bu System.Single.. singleve doublekayan ikili nokta tipleridir.
Brett Caswell

54
@BKSpurgeon: Eh, her şeyin ikili bir tip olduğunu söyleyebileceğiniz şekilde , bu noktada oldukça işe yaramaz bir tanım haline gelir. Ondalık, tamsayı anlamlı ve ölçek olarak temsil edilen bir sayı olması ve ondalık anlamlı * 10 ^ ölçeği, float ve çift anlamlı * 2 ^ ölçeği olması gereken ondalık türdür. Ondalık olarak yazılmış bir sayı alırsınız ve ondalık noktasını, anlamlılığı ve ölçeği çözmek için bir tamsayı olacak kadar sağa taşırsınız. Float / double için ikili olarak yazılmış bir sayı ile başlarsınız.
Jon Skeet

21
Başka bir fark: float 32-bit; çift ​​64 bit; ve ondalık 128 bit.
David

1073

Hassasiyet ana farktır.

Şamandıra - 7 basamak (32 bit)

Çift -15-16 basamak (64 bit)

Ondalık -28-29 anlamlı basamak (128 bit)

Ondalık sayılar çok daha yüksek bir hassasiyete sahiptir ve genellikle yüksek derecede doğruluk gerektiren finansal uygulamalarda kullanılır. Ondalık sayılar bir çift / şamandıradan çok daha yavaştır (bazı testlerde 20X kata kadar).

Ondalık Sayılar ve Şamandıralar / Çiftler oyuncu kadrosu olmadan karşılaştırılamazken; Ondalık basamaklar ayrıca kodlama veya sondaki sıfırlara da izin verir.

float flt = 1F/3;
double dbl = 1D/3;
decimal dcm = 1M/3;
Console.WriteLine("float: {0} double: {1} decimal: {2}", flt, dbl, dcm);

Sonuç:

float: 0.3333333  
double: 0.333333333333333  
decimal: 0.3333333333333333333333333333

65
@ Thecrocodilehunter: üzgünüm ama hayır. Ondalık, ondalık gösterimde temsil edilebilecek tüm sayıları temsil edebilir, ancak örneğin 1/3'ü gösteremez. 1.0m / 3.0m, sonuçta çok sayıda ancak sınırlı sayıda 3s ile 0.33333333'ü değerlendirecektir. 3 ile çarpılması tam 1.0 döndürmez.
Erik P.

50
@Thecrocodilehunter: Sanırım doğruluk ve kesinlik karıştırıyorsunuz. Bu bağlamda farklı şeylerdir. Kesinlik, bir sayıyı temsil etmek için kullanılabilir basamak sayısıdır. Daha fazla hassasiyet, daha az yuvarlamanız gerekir. Hiçbir veri türünün sonsuz hassasiyeti yoktur.
Igby Largeman

13
@Thecrocodilehunter: Ölçülmekte olan değerin tam olarak olduğunu varsayıyorsunuz 0.1- bu gerçek dünyada nadiren böyle! Herhangi bir sonlu depolama formatı, sonsuz sayıda olası değeri sınırlı sayıda bit deseni ile sınırlar. Örneğin, floatbirleşecek 0.1ve 0.1 + 1e-8, decimalbirleşecek 0.1ve 0.1 + 1e-29. Elbette, belirli bir aralıkta belirli değerler sıfır doğruluk kaybıyla herhangi bir biçimde gösterilebilir (örn. floatSıfır doğruluk kaybıyla 1.6e7'ye kadar herhangi bir tamsayıyı saklayabilir) - ancak bu yine de sonsuz doğruluk değildir .
Daniel Pryden

27
@Thecrocodilehunter: Demek istediğimi kaçırdın. 0.1olduğu değil özel bir değer ! Kılan tek şey 0.1"daha iyi" 0.10000001çünkü insanoğlu tabanın 10. Ve hatta olduğu gibi floatsizinle iki değeri başlatmak eğer değeri, 0.1aynı şekilde, her ikisi de aynı değeri olacaktır . Sadece bu değer tam olarak 0.1 olmayacak - tam olarak bir olarak gösterilebilecek en yakın değer olacaktır0.1float . Tabii ki, ikili şamandıralarla, (1.0 / 10) * 10 != 1.0ancak ondalık şamandıralarla (1.0 / 3) * 3 != 1.0da. Her ikisi de mükemmel bir şekilde kesin değildir.
Daniel Pryden

16
@Thecrocodilehunter: Hala anlamıyorsun. Artık açıkça bunu nasıl söyleyeceğimi bilmiyorum: In C, sen yoksa double a = 0.1; double b = 0.1;o zaman a == b gerçek olacak . Sadece bu ave bher ikisi de tam olarak eşit olmayacak 0.1. C # 'da yaparsanız, decimal a = 1.0m / 3.0m; decimal b = 1.0m / 3.0m;o a == bzaman da doğru olacaktır. Ama bu durumda, ne bir ane de birade tam olarak eşit 1/3- yapacaklar hem eşit 0.3333.... Her iki durumda da, temsil nedeniyle bir miktar doğruluk kaybolur. İnatla bunun decimal"sonsuz" hassasiyete sahip olduğunu söylüyorsunuz , bu yanlıştır .
Daniel Pryden

84

Ondalık yapı kesinlikle, yuvarlamaya nispeten toleranssız olan doğruluk gerektiren finansal hesaplamalara yöneliktir. Bununla birlikte, ondalık sayılar bilimsel uygulamalar için yeterli değildir, ancak birkaç nedenden dolayı:

  • Ölçülen fiziksel problemin veya artefaktın pratik sınırları nedeniyle birçok bilimsel hesaplamada belirli bir hassasiyet kaybı kabul edilebilir. Finansmanda hassasiyet kaybı kabul edilemez.
  • Ondalık, kayan nokta işlemleri ikili olarak yapıldığından, çoğu işlem için floattan çok (çok) daha yavaş ve iki kat daha yavaştır, oysa Ondalık şeyler taban 10'da yapılır (örn. Şamandıralar ve çiftler MMX / SSE gibi FPU donanımı tarafından işlenir , ondalık sayılar yazılımda hesaplanır).
  • Ondalık, daha fazla hassasiyet basamağını desteklese de, ikiliden daha az kabul edilemeyecek kadar küçük bir değer aralığına sahiptir. Bu nedenle, Ondalık birçok bilimsel değeri temsil etmek için kullanılamaz.

5
Finansal hesaplamalar yapıyorsanız, kesinlikle kendi veri türlerinizi yuvarlamanız veya tam ihtiyaçlarınıza uygun iyi bir kütüphane bulmanız gerekir. Bir finansal ortamda doğruluk, (insan) standart organları tarafından tanımlanır ve hesaplamaların nasıl yapılacağı konusunda çok özel yerelleştirilmiş (hem zaman hem de coğrafya) kuralları vardır. Doğru yuvarlama gibi şeyler .Net'teki basit sayısal veri türlerinde yakalanmaz. Hesaplamalar yapabilme, bulmacanın sadece çok küçük bir parçasıdır.
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                               |
+---------+----------------+---------+----------+---------------------------------------------+

Daha fazla bilgi için buraya bakın .


5
Ondalık tip için kullanılan temel olan en büyük farkı dışarıda bıraktınız (ondalık temel 10 olarak saklanır, listelenen diğer tüm sayısal tipler temel 2'dir).
BrainSlugs83 14:15

1
Tek ve Çift için değer aralıkları yukarıdaki resimde veya kaynak forum gönderisinde doğru olarak gösterilmemiştir. Metni buraya kolayca ekleyemeyeceğimiz için, düzeltme karakteri kullanın: Tek, 10 ^ -45 ve 10 ^ 38 ve Çift, 10 ^ -324 ve 10 ^ 308 olmalıdır. Ayrıca, MSDN'de -3.4x10 ^ 38 ila + 3.4x10 ^ 38 aralığında bir şamandıra vardır. Bağlantı değişiklikleri durumunda MSDN'de System.Single ve System.Double araması yapın. Tekli: msdn.microsoft.com/en-us/library/b1e65aza.aspx Çift Kişilik: msdn.microsoft.com/en-us/library/678hzkk9.aspx
deegee 22:15

2
Ondalık 128 bittir ... 12 değil 16 bayt kapladığı anlamına gelir
user1477332

51

Diğer cevaplarda ve yorumlarda zaten cevaplanmış tonlarca iyi (ve bazı kötü) bilgileri tekrarlamayacağım, ancak takip sorunuza bir ipucu ile cevap vereceğim:

Birisi bunlardan ne zaman yararlanır?

Sayılan değerler için ondalık kullanma

Ölçülen değerler için şamandıra / çift kullanın

Bazı örnekler:

  • para (para sayıyor muyuz veya para mı ölçüyoruz?)

  • mesafe (mesafeyi sayar mıyız veya mesafeyi ölçer miyiz? *)

  • puanlar (puanları sayar mıyız veya puanları mı ölçeriz?)

Her zaman para sayıyoruz ve asla ölçmemeliyiz. Genellikle mesafeyi ölçeriz. Sık sık skorları sayıyoruz.

* Bazı durumlarda, nominal mesafe dediğim şeyi gerçekten de 'saymak' isteyebiliriz. Örneğin, şehirlere mesafeler gösteren ülke işaretleriyle uğraşıyoruz ve bu mesafelerin asla birden fazla ondalık basamağa (xxx.x km) sahip olmadığını biliyoruz.


1
Bu cevabı gerçekten çok beğendim, özellikle de “parayı sayıyor muyuz, ölçüyor muyuz?” Sorusu. Ancak, para dışında, sadece sayılan "sayılan" bir şey düşünemiyorum. Çiftin çok az önemli basamağı olduğundan ondalık kullanan bazı uygulamalar gördüm . C # Bir olmadığından başka deyişle, ondalık kullanılabilecek dörtlü tip en.wikipedia.org/wiki/Quadruple-precision_floating-point_format
John Henckel

48

float 7 basamak hassasiyet

double yaklaşık 15 basamak hassasiyete sahiptir

decimal yaklaşık 28 basamak hassasiyete sahiptir

Daha iyi bir doğruluk istiyorsanız, şamandıra yerine çift kullanın. Modern CPU'larda her iki veri türü de neredeyse aynı performansa sahiptir. Şamandıra kullanmanın tek yararı, daha az yer kaplamasıdır. Pratik olarak sadece birçoğunuz varsa önemlidir.

Bunun ilginç olduğunu gördüm. Her Bilgisayar Bilimcisinin Kayan Nokta Aritmetiği Hakkında Bilmesi Gerekenler


1
@RogerLipscombe: double32 bitten daha büyük bir tamsayı türünün olmadığı ve double53 bitlik bir tamsayı türü (örn. bir kaç kuruş veya bir kuruşun yüzde biri gibi). Günümüzde bu tür şeyler için fazla bir kullanım yok, ancak birçok dil, 64-bit (veya bazı durumlarda 32-bit!) Tamsayı matematiğini kazanmadan çok önce çift kesinlikli kayar nokta değerleri kullanma yeteneği kazandı.
supercat

1
Cevabınız, bu veri türleri arasındaki tek farkın kesinlik olduğunu ima ediyor. İkili kayan noktalı aritmetik genellikle donanım FPU'sunda uygulanır , performans önemli bir farktır. Bu, bazı uygulamalar için önemsiz olabilir, ancak diğerleri için kritiktir.
saille

6
@supercat double muhasebe uygulamalarında asla uygun değildir. Çünkü Double yalnızca ondalık değerleri yaklaşık olarak tahmin edebilir (kendi hassasiyeti aralığında bile). Bunun nedeni, çiftin değerleri temel-2 (ikili) merkezli bir biçimde saklamasıdır.
BrainSlugs83

2
@ BrainSlugs83: Tam sayı olmayan miktarları tutmak için kayan nokta türlerinin kullanılması uygun olmaz, ancak diller için tamsayı türlerinin gösterebileceğinden daha büyük tam sayı değerlerini tam olarak temsil edebilen kayan nokta türlerine sahip olmak tarihsel olarak çok yaygındı. . Belki de en uç örnek, sadece tamsayı türleri -32768 ile +32767 arasında sınırlı olan, ancak RealIIRC birim hassasiyeti ile 1.8E + 19'a kadar değerleri temsil edebilen Turbo-87 idi . Bir muhasebe uygulamasının, Realdaha fazla sayıda peni temsil etmek için kullanması daha
akılcı

1
... bir grup 16 bitlik değer kullanarak çok duyarlıklı matematik gerçekleştirmeye çalışmak. Diğer birçok dil için fark o kadar da zor değildi, ama uzun zamandır diller için 4E9'un ötesine geçen ancak double9E15'e kadar birim doğruluğu olan bir tamsayı türüne sahip olmamaları çok yaygındı . Kullanılabilir en büyük tamsayı türünden daha büyük olan tam sayıları depolamak gerekirse double, özellikle işlemcilerin 16x16-> 32 ya da. ..
supercat

36

Kimse bundan bahsetmedi

Varsayılan ayarlarda, Floats (System.Single) ve çiftler (System.Double) hiçbir zaman taşma denetimi kullanmazken, Ondalık (System.Decimal) her zaman taşma denetimi kullanır.

Demek istediğim

decimal myNumber = decimal.MaxValue;
myNumber += 1;

OverflowException özel durumunu atar .

Ancak bunlar şunları yapmaz:

float myNumber = float.MaxValue;
myNumber += 1;

&

double myNumber = double.MaxValue;
myNumber += 1;

1
float.MaxValue+1 == float.MaxValue, aynen decimal.MaxValue+0.1D == decimal.MaxValue. Belki de böyle bir şey mi demek istediniz float.MaxValue*2?
Supercat

@supercar Ama ondalık doğru değil.MaxValue + 1 ==
ondalık.MaxValue

@supercar ondalık.MaxValue + 0.1m ==
ondalık.MaxValue

1
System.DecimalBu bütün birimlerini ayırt edemez hale gelir hemen önce bir istisna atar ancak bir uygulama çok geç olabilir mesela dolar ve sent, başa olması gerekiyordu eğer.
Supercat

28
  1. Double ve float, hem derleme hem de çalışma zamanında istisnasız tamsayı sıfıra bölünebilir.
  2. Ondalık tam sayı sıfıra bölünemez. Bunu yaparsanız derleme her zaman başarısız olur.

6
Emin olabilirler! Ayrıca Sonsuzluk, Negatif Sonsuzluk ve NaN (bir sayı değil) gibi birkaç "sihirli" değere de sahiptirler. .Parse, double.TryParse ve ondalık .TryParse (örneğin, bir dizenin sayı olup olmadığını tespit etmek için), "Infinity", "-Infinity" ve "NaN" öğelerini düzgün ayrıştıracakları için double veya float kullanmanızı öneririm. , ondalık olmayacak.
BrainSlugs83

Derleme yalnızca bir değişmezi decimalsıfıra bölmeye çalışırsanız (CS0020) başarısız olur ve aynı şey integral değişmez değerler için de geçerlidir. Ancak, çalışma zamanı ondalık değeri sıfıra bölünürse, derleme hatası değil bir istisna alırsınız.
Drew Noakes

@ BrainSlugs83 Ancak bağlama göre "Sonsuzluk" veya "NaN" ayrıştırmak istemeyebilirsiniz. Geliştirici yeterince titiz değilse kullanıcı girişi için iyi bir istismar gibi görünüyor.
Kış

28

Tamsayılar, belirtildiği gibi tam sayılardır. Noktayı .7, .42 ve .007 gibi bir şey saklayamazlar. Tam sayı olmayan sayıları depolamanız gerekiyorsa, farklı bir değişken türüne ihtiyacınız vardır. Çift tip veya şamandıra tipini kullanabilirsiniz. Tam olarak aynı şekilde yukarı değişkenlerin bu tür ayarlayın: yerine kelime kullanmanın int, yazarken doubleveya float. Bunun gibi:

float myFloat;
double myDouble;

( float"kayan nokta" nın kısaltmasıdır ve sonunda nokta olan bir sayı anlamına gelir.)

İkisi arasındaki fark, tutabilecekleri sayıların büyüklüğündedir. İçin float, numaranızda en fazla 7 hane olabilir. İçin doubles, 16 haneye kadar olabilir. Daha kesin olmak gerekirse, resmi boyut şöyledir:

float:  1.5 × 10^-45  to 3.4 × 10^38  
double: 5.0 × 10^-324 to 1.7 × 10^308

float32 bitlik bir sayıdır ve double64 bitlik bir sayıdır.

Koda ulaşmak için yeni düğmenizi çift tıklayın. Düğme kodunuza aşağıdaki üç satırı ekleyin:

double myDouble;
myDouble = 0.007;
MessageBox.Show(myDouble.ToString());

Programınızı durdurun ve kodlama penceresine dönün. Bu satırı değiştirin:

myDouble = 0.007;
myDouble = 12345678.1234567;

Programınızı çalıştırın ve çift düğmeye tıklayın. Mesaj kutusu numarayı doğru görüntüler. Yine de sonuna başka bir sayı ekleyin, C # tekrar yukarı veya aşağı yuvarlanır. Ahlaki doğruluk istiyorsanız, yuvarlamaya dikkat edin!


2
Bahsettiğiniz "bir şeyi işaretleyin" genellikle bir sayının "kesirli kısmı" olarak adlandırılır. "Kayan nokta", "sonunda nokta olan bir sayı" anlamına gelmez; bunun yerine "Kayan Nokta", "Sabit Nokta" numarasının aksine (aynı zamanda kesirli bir değer de saklayabilir) sayı türünü ayırt eder; fark, hassasiyetin sabit mi yoksa yüzer mi olduğudur. - Kayan noktalı sayılar size, hassasiyet maliyetiyle çok daha büyük bir dinamik değer aralığı (Min ve Maks) verirken, sabit noktalı sayılar size aralık maliyetinde sabit bir hassasiyet sağlar.
BrainSlugs83

16
  • şamandıra: ± 1.5 x 10 ^ -45 ila ± 3.4 x 10 ^ 38 (~ 7 anlamlı rakam
  • çift: ± 5,0 x 10 ^ -324 ila ± 1,7 x 10 ^ 308 (15-16 anlamlı rakam)
  • ondalık: ± 1,0 x 10 ^ -28 ila ± 7,9 x 10 ^ 28 (28-29 anlamlı rakam)

9
Fark sadece hassasiyetten daha fazlasıdır. - decimalaslında ondalık biçimde saklanır (taban 2'nin aksine; bu nedenle, iki sayısal sistem arasındaki dönüşüm nedeniyle rakamları kaybetmez veya yuvarlamaz); ayrıca decimalNaN, -0, ∞ veya -∞ gibi özel değerler kavramına sahip değildir.
BrainSlugs83

13

Bu benim için ilginç bir iş parçacığı oldu, çünkü bugün, decimala'dan daha az hassasiyete sahip olmakla ilgili kötü bir hata yaşadık float.

C # kodumuzda, bir Excel e-tablosundan sayısal değerleri okuyor, bunları a dönüştürüyoruz decimalve sonra decimalbir SQL Server veritabanına kaydetmek için bunu bir Hizmete geri gönderiyoruz .

Microsoft.Office.Interop.Excel.Range cell = 
object cellValue = cell.Value2;
if (cellValue != null)
{
    decimal value = 0;
    Decimal.TryParse(cellValue.ToString(), out value);
}

Şimdi, neredeyse tüm Excel değerlerimiz için, bu güzel çalıştı. Ancak bazı, çok küçük Excel değerleri decimal.TryParseiçin değeri tamamen kaybetti. Böyle bir örnek

  • hücreDeğer = 0.00006317592

  • Decimal.TryParse (cellValue.ToString (), çıkış değeri); // 0 döndürür

Çözüm, tuhaf bir şekilde, Excel değerlerini bir doubleilke ve ardından bir 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;
    
}

A'dan doubledaha az hassas olmasına rağmen decimal, bu aslında küçük sayıların hala tanınmasını sağlamıştır. Bazı nedenlerden ötürü, double.TryParseaslında bu kadar küçük sayıları alabildi, oysa decimal.TryParseonları sıfıra ayarladı.

Garip. Çok tuhaf.


3
Meraktan, cellValue.ToString () öğesinin ham değeri neydi? Decimal.TryParse ("0.00006317592", val val) çalışıyor gibi görünüyor ...
micahtan

11
-1 Beni yanlış anlamayın, eğer doğruysa, çok ilginç ama bu ayrı bir soru, kesinlikle bu sorunun cevabı değil.
weston

2
Belki Excel hücresi bir çift döndürüyor ve ToString () değeri "6.31759E-05" olduğundan, ondalık.Parse () gösterimi beğenmedi. Decimal.TryParse () dönüş değerini kontrol ettiyseniz bahse girerim, bu yanlış olurdu.
SergioL

2
@weston Yanıtlar çoğu zaman kaçırdıkları nüansları doldurarak diğer cevapları tamamlar. Bu cevap, ayrıştırma açısından bir farkı vurgular. Bu soruya çok cevap!
Robino

1
Ee ... decimal.Parse("0.00006317592")çalışıyor - başka bir şey daha var. - Muhtemelen bilimsel gösterim?
BrainSlugs83

8

Hafıza ve performansın kritik olduğu oyunlar ve gömülü sistemler gibi uygulamalar için, şamandıra genellikle daha hızlı ve bir çiftin yarısı kadar büyüklükte olduğundan sayısal seçimdir. Tamsayılar tercih edilen silahtı, ancak kayan nokta performansı modern işlemcilerde tamsayıyı geçti. Ondalık doğru çıktı!


Hemen hemen tüm modern sistemler, hatta cep telefonları, çift için donanım desteğine sahiptir; ve eğer oyununuz basit bir fiziğe sahipse, çift ve şamandıra arasında büyük bir fark göreceksiniz. (Örneğin, basit bir Asteroid klonunda hız / sürtünmenin hesaplanması, çiftler hızlanmanın şamandıradan çok daha akışkan akmasına izin verir.
Önemli

Çiftler ayrıca şamandıra boyutunun iki katıdır, yani önbellek performansınıza zarar veren iki kat daha fazla veri çiğnemeniz gerekir. Her zaman olduğu gibi ölçün ve buna göre devam edin.
yoyo

6

Ondalık, Çift ve Kayan değişken türleri değerleri saklama biçimlerinden farklıdır. Kesinlik, şamandıranın tek duyarlıklı (32 bit) kayar nokta veri türü, çiftin çift duyarlıklı (64 bit) kayar nokta veri türü ve ondalık sayı ise 128 bit kayan nokta veri türü olduğu ana farktır.

Şamandıra - 32 bit (7 basamak)

Çift - 64 bit (15-16 basamak)

Ondalık - 128 bit (28-29 anlamlı basamak)

Hakkında daha fazla ... Ondalık, Kayan Nokta ve Çift arasındaki fark


5

Tüm bu türlerle ilgili sorun, belirli bir belirsizliğin geçmesi ve bu sorunun aşağıdaki örnekte olduğu gibi küçük ondalık sayılarla oluşabilmesidir.

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

Soru: bLower değişkeni hangi değeri içerir?

Cevap: 32 bitlik bir makinede bLower TRUE içerir !!!

Double'i Ondalık olarak değiştirirsem, bLower iyi yanıt olan FALSE içerir.

Çifte, sorun şu ki 1.1'den daha düşük olan fMean-fDelta = 1.09999999999.

Dikkat: Bence aynı sayı diğer sayılar için de var olabilir, çünkü Ondalık daha yüksek hassasiyete sahip bir çifttir ve hassasiyet her zaman bir sınıra sahiptir.

Aslında, Double, Float ve Decimal COBOL'da İKİLİ ondalık sayıya karşılık gelir!

COBOL içinde uygulanan diğer sayısal türlerin .Net'te bulunmaması üzücüdür. COBOL bilmeyenler için COBOL'de sayısal türden sonra var

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) 

4

Basit bir deyişle:

  1. Ondalık, Çift ve Kayan değişken türleri değerleri saklama biçimlerinden farklıdır.
  2. Şamandıra tek duyarlıklı (32 bit) kayan nokta veri türü, çift çift ​​duyarlıklı (64 bit) kayan nokta veri türü ve ondalık sayı 128-bit olduğunda, ana farktır (bunun tek fark olmadığını unutmayın). kayan noktalı veri türü.
  3. Özet tablosu:

/==========================================================================================
    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)
/==========================================================================================
Daha okuyabilir burada , Float , Double ve ondalık ' .


Mevcut cevaplarda henüz yer almayan bu cevap ne ekliyor? BTW, "ondalık" satırındaki "veya" ifadeniz yanlış: kopyaladığınız web sayfasındaki eğik çizgi, alternatif yerine bölümü gösterir.
Mark Dickinson

1
Ve hassasiyetin ana fark olduğunu şiddetle tartışırım. Temel fark temeldir: ondalık kayan nokta ile ikili kayan nokta. Aradaki fark kılan Decimalfinansal uygulamalar için uygundur ve bu arasında karar verirken kullanmak ana kriter var Decimalve Double. DoubleÖrneğin hassasiyetin bilimsel uygulamalar için yeterli olmaması nadirdir (ve sınırlı aralığı nedeniyle bilimsel uygulamalar için Decimalgenellikle uygun değildir ).
Mark Dickinson

2

Bunların her biri arasındaki ana fark hassasiyettir.

floatbir 32-bitsayı, doublebir 64-bitsayı ve decimalbir 128-bitsayıdır.


0
  • Ondalık 128 bit (28-29 anlamlı basamak) Finansal uygulamalarda, ondalık türleri kullanmak daha iyidir, çünkü size yüksek düzeyde doğruluk sağlar ve yuvarlama hatalarından kaçınmak kolaydır Hassasiyet gerektiren tamsayı olmayan matematik için ondalık kullanın (örn. para ve para birimi)

  • Çift 64 bit (15-16 basamaklı) Çift Türler, para işlemek dışında gerçek değerler için muhtemelen en çok kullanılan veri türüdür. En kesin cevabın gerekli olmadığı tamsayı olmayan matematik için double kullanın.

  • Kayan 32 bit (7 basamaklı) Çoğunlukla grafik kütüphanelerinde kullanılır, çünkü işlem gücü için çok yüksek talepler, ayrıca yuvarlama hatalarına dayanabilecek durumlar da kullanılır.

Decimalsa'dan çok daha yavaştır double/float.

Decimalsve Floats/Doublesbir oysa döküm olmadan karşılaştırılamaz Floatsve Doubleskutu.

Decimals ayrıca kodlamaya veya sondaki sıfırlara da izin verir.


-1

Net'te (c #) Ondalık, Kayan ve İkili tanımlamak için

değerleri şöyle belirtmelisiniz:

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

ve sonuçları kontrol edin.

Ve her birinin işgal ettiği baytlar

Float - 4
Double - 8
Decimal - 12
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.