Soru NET'te ondalık, float ve double arasındaki fark nedir?


Arasındaki fark nedir decimal, float ve double net olarak?

Birisi bunlardan birini ne zaman kullanır?


1776
2018-03-06 11:31


Menşei


Ilginç yazı zetcode.com/lang/csharp/datatypes - GibboK
@Bargitta bu doğru değil, Orada float net olarak. Sadece System türü (yani, anahtar kelime değil) denir Single. - Balázs
İlgili: sandbox.mc.edu/~bennet/cs110/flt/dtof.html - Pacerier


Cevaplar:


float ve double Hangi yüzer ikili nokta çeşitleri. Başka bir deyişle, böyle bir sayıyı temsil ederler:

10001.10010110011

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

decimal bir yüzer ondalık nokta tipi. Başka bir deyişle, böyle bir sayıyı temsil ederler:

12345.65789

Yine, sayı ve yer ondalık Her ikisi de değer içinde kodlanmıştır - decimal Sabit nokta türü yerine hala kayan nokta tipi.

Dikkat edilmesi gereken önemli nokta, insanların ondalık olmayan bir formda tamsayıları temsil etmek için kullanılmaları ve ondalık temsillerde kesin sonuçların beklenmesidir; tüm ondalık sayılar ikili kayan noktalarda tam olarak gösterilemez - örneğin, 0.1 - bu nedenle, bir ikili kayan nokta değeri kullanırsanız, aslında 0.1 değerine yakın bir değer elde edersiniz. Yüzer bir ondalık nokta kullanıldığında da yine de yaklaşık değerler elde edersiniz - örneğin 1'e 3 bölündüğü sonucu tam olarak gösterilemez.

Ne zaman kullanılacağı ile ilgili olarak:

  • "Doğal olarak kesin ondalık" olan değerler için kullanmak iyidir decimal. Bu genellikle insanlar tarafından icat edilen herhangi bir kavram için uygundur: finansal değerler en bariz örnektir, fakat başkaları da vardır. Örneğin dalgıçlara veya buz patencilere verilen puanı dikkate alın.

  • Gerçekten ölçülemeyen daha fazla doğa eseri olan değerler için kesinlikle Neyse float/double daha uygun Örneğin, bilimsel veriler genellikle bu formda temsil edilir. Burada, orijinal değerler başlangıçta "ondalık doğru" olmayacaktır, bu nedenle beklenen sonuçların "ondalık doğruluk" seviyesini koruması önemli değildir. Kayan ikili nokta türleri ondalıktan daha çok çalışmak için daha hızlıdır.


1969
2018-03-06 11:56



float/double genellikle sayıları temsil etmiyor 101.101110normalde böyle bir şey gibi temsil edilir 1101010 * 2^(01010010) - bir üs - Mingwei Samuel
@Hazzard: Bu, "ikili noktanın yeri" nin cevabı anlamına gelir. - Jon Skeet
Şimdiye kadar söylenmemiş olmasına şaşırdım float C # alias anahtar kelimesi ve .Net türü değil. onun System.Single.. single ve double yüzer ikili nokta türleridir. - Brett Caswell
Bekle .... sonunda 1s ve 0'larda temsil edilen bir ondalık değil mi? Bilgisayarların sadece ikili biçimde çalışabileceğini sanıyordum. o zaman bir ondalık, sonunda ikili bir tür değil mi? - BKSpurgeon
@BKSpurgeon: Eh, sadece aynı şekilde söyleyebilirsiniz ki her şey ikili bir tiptir, bu noktada oldukça işe yaramaz bir tanım haline gelir. Ondalık, ondalıklı bir sayıdır, tamsayı bir anlam ve bir ölçek olarak temsil edilen bir sayıdır, sonuçta sonuç anlamlı ve * 10 ^ ölçeğindedir, oysa float ve çift anlamlı ve * 2 ^ ölçeğidir. Ondalık olarak yazılan bir sayı alırsınız ve ondalık noktayı, anlamlılık ve ölçek üzerinde çalışmak için bir tamsayıya sahip olduğunuza dek yeterince uzaklaştırın. Float / double için ikili yazılan bir sayı ile başlarsınız. - Jon Skeet


Kesinlik ana farktır.

şamandıra - 7 basamak (32 bit)

Çift-15-16 basamak (64 bit)

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

Ondalıkların çok daha yüksek hassasiyeti vardır ve genellikle yüksek derecede doğruluk gerektiren finansal uygulamalarda kullanılırlar. Ondalık, çift / floattan çok daha yavaş (bazı testlerde 20 katına kadar).

Float ve Çiftler, Decimals ve Floats / Doubles oyuncu kadrosuyla kıyaslanamaz. Decimals ayrıca kodlama veya takip eden 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

896
2018-03-06 11:33



@Thecrocodilehunter: Üzgünüm, ama hayır. Ondalık, ondalık gösterimde gösterilebilen tüm sayıları temsil edebilir, ancak örneğin 1/3 değil. 1.0m / 3.0m, 0.33333333'e ... sonunda büyük ama sonlu 3'ler ile değerlendirecektir. 3 ile çarparak tam 1.0 döndürmez. - Erik P.
@Thecrocodilehunter: Sanırım doğruluk ve hassasiyetle kafa karıştırıyorsunuz. Bu bağlamda farklı şeyler. Hassas, bir sayıyı temsil etmek için kullanılabilen basamak sayısıdır. Ne kadar hassas olursa, o kadar az yuvarlamanız gerekir. Hiçbir veri tipi sonsuz hassasiyete sahip değildir. - Igby Largeman
@Thecrocodilehunter: Ölçülen değerin olduğunu varsayıyorsunuz kesinlikle  0.1 - Bu gerçek dünyada nadiren böyle! herhangi Sonlu depolama formatı, sonsuz sayıda olası değeri sınırlı sayıda bit deseniyle sınırlar. Örneğin, float karışacak 0.1 ve 0.1 + 1e-8, süre decimal karışacak 0.1 ve 0.1 + 1e-29. Emin, belirli bir aralık içindekesin değerler, sıfır doğruluk kaybı ile herhangi bir formatta temsil edilebilir (ör. float 1,6e7'ye kadar herhangi bir tamsayıyı, sıfır doğruluk kaybıyla saklayabilir) - ama bu hala değil sonsuz doğruluk. - Daniel Pryden
@Thecrocodilehunter: Benim noktayı kaçırdın. 0.1 olduğu özel bir değer değil! Yapan tek şey 0.1 "daha iyi 0.10000001 Çünkü insanlar 10 ü gibi ve hatta float iki değeri ile başlatırsanız, değer 0.1 aynı yol, ikisi de aynı değerde olacak. Sadece bu değer olmayacak kesinlikle  0.1 -- Olacak en yakın değer 0.1 tam olarak temsil edilebilir float. Elbette, ikili yüzerlerle (1.0 / 10) * 10 != 1.0ama ondalık yüzer ile (1.0 / 3) * 3 != 1.0 Ya. ne olduğu kusursuzca Kesin. - Daniel Pryden
@Thecrocodilehunter: Hala anlamıyorsun. Bunu daha açık bir şekilde nasıl söyleyeceğimi bilmiyorum: C’de double a = 0.1; double b = 0.1; sonra a == b  doğru olacak. Sadece o a ve b irade her ikisi de tam olarak eşit değil 0.1. C # yaparsanız decimal a = 1.0m / 3.0m; decimal b = 1.0m / 3.0m; sonra a == b ayrıca doğru olacak. Ama bu durumda, ne arasında a ne de b irade kesinlikle eşit 1/3 - ikisi de eşit olacak 0.3333.... İçinde her ikisi de durumlarda, temsil nedeniyle bazı doğruluklar kaybedilir. İnatla bunu söylüyorsun decimal "sonsuz" hassasiyete sahip, yanlış. - Daniel Pryden


Ondalık yapı kesin bir şekilde yuvarlama ile ilgili toleranssız olan, doğruluk gerektiren finansal hesaplamalara yöneliktir. Ancak, bazı nedenlerle, bilimsel uygulamalar için ondalık rakamlar yeterli değildir:

  • Fiziksel problemin ya da ölçülmekte olan artifaktın pratik limitleri nedeniyle, birçok bilimsel hesaplamada kesin bir hassasiyet kaybı kabul edilebilir. Finansmanda hassaslık kaybı kabul edilemez.
  • Ondalık, çoğu işlem için çok fazla (çok) yavaştır ve çoğu işlem için çifterdir, çünkü esas olarak kayan nokta işlemleri ikili olarak yapılırken, Ondalık şeyler taban 10'da yapılır (yani, yüzer ve çiftler, MMX / SSE gibi FPU donanımı tarafından işlenir) ondalık değerler yazılımda hesaplanırken).
  • Ondalık, daha fazla rakam doğruluğunu desteklese de, 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.

66
2018-04-13 13:55



Finansal hesaplamalar yapıyorsanız, kesinlikle kendi veri tiplerinizi hazırlamanız veya tam ihtiyaçlarınızla eşleşen iyi bir kütüphane bulmanız gerekir. Finansal bir ortamda doğruluk (insan) standart kurumları tarafından tanımlanır ve hesaplamaların nasıl yapılacağına dair çok spesifik yerelleştirilmiş (hem zaman hem coğrafyada) kurallara sahiptirler. Doğru yuvarlama gibi şeyler .Net'deki basit sayısal veri türlerinde yakalanmaz. Hesaplama yapabilme yeteneği, bulmacanın sadece çok küçük bir kısmı. - James Moore


enter image description here

Daha fazla bilgi için bu resmin kaynağına gidebilirsiniz:

http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/921a8ffc-9829-4145-bdc9-a96c1ec174a5


54
2018-06-07 12:50



Ondalık ondalık 96 bit olduğunu iddia etmek için -1. MSDN açıkça 128 diyor. - Ben Voigt
Ve daha derine inerseniz, 102 bit kullanılır, 128 saklanır. Bunu 12 bayta sığdırmanın yolu yok. - Ben Voigt
En büyük farkı bıraktınız, ondalık türü için kullanılan taban (ondalık, temel 10 olarak saklanır, listelenen tüm diğer sayısal türler, temel 2). - BrainSlugs83
Tek ve Çift için değer aralıkları, yukarıdaki resimde veya kaynak forum gönderisinde doğru şekilde gösterilmemiştir. Buradaki metni kolayca üstesinden gelemediğimizden, karakter karakterini kullanın: Tekli 10 ^ -45 ve 10 ^ 38 olmalıdır ve Çift 10 ^ -324 ve 10 ^ 308 olmalıdır. Ayrıca, MSDN -3.4x10 ^ 38 ila + 3.4x10 ^ 38 aralığında bir kayanlığa sahiptir. Bağlantı değişiklikleri durumunda System.Single ve System.Double için MSDN araması yapın. Tek: msdn.microsoft.com/en-us/library/b1e65aza.aspx Çift: msdn.microsoft.com/en-us/library/678hzkk9.aspx - deegee


float 7 haneli hassasiyet

double yaklaşık 15 basamak hassasiyeti var

decimal yaklaşık 28 basamak hassasiyeti var

Daha iyi bir doğruluğa ihtiyacınız varsa, float yerine çift kullanın. Modern CPU'larda, her iki veri tipi de neredeyse aynı performansa sahiptir. Şamandıra kullanmanın tek faydası, daha az yer kaplıyor. Pratik olarak sadece birçoğunuz varsa önemlidir.

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


40
2017-08-29 00:06



@RogerLipscombe: Düşünürdüm double Muhasebe uygulamalarında uygun (32 temelden daha büyük bir tamsayı tipi bulunmayan) ve (temel olarak sadece bu durumlarda) double 53 bitlik bir tamsayı türü (örneğin, bütün bir sayıdaki penni veya yüzlerce sentlik bir yüzdeyi tutmak için) gibi kullanılıyordu. Günümüzde bu tür şeyler için çok fazla kullanılmamakla birlikte, birçok dil, 64-bit (ya da bazı durumlarda 32-bit!) Tam sayı matematik elde etmeden çok önce çift-duyarlıklı kayan nokta değerlerini kullanma yeteneğini kazanmıştır. - supercat
Cevabınız, kesin olan, bu veri türleri arasındaki tek farktır. Verilen ikili kayan nokta aritmetiği tipik olarak uygulanır. donanım FPUPerformans, önemli bir farktır. Bu, bazı uygulamalar için önemsiz olabilir, ancak diğerleri için önemlidir. - saille
@supercat çifte asla muhasebe uygulamalarında uygun. Çünkü Double, yalnızca ondalık değerlere yaklaşabilir (kendi hassasiyeti dahilinde bile). Bunun nedeni, değerleri base-2 (binary) -centric biçiminde çift olarak depolamasıdır. - BrainSlugs83
@ BrainSlugs83: Tutulacak kayan nokta türlerinin kullanımı olmayan tam sayı Miktarlar uygunsuz olacaktır, ancak dillerin, tamsayı türlerinin temsil edebileceğinden daha büyük tam sayı değerlerini tam olarak temsil edebilen kayan nokta türlerine sahip olması tarihsel olarak çok yaygındı. Belki de en uç örnek, sadece tamsayı türleri -32768 ile +32767 arasında sınırlı olan, ancak kimin Turbo-87 olduğuydı. Real IIRC, ünite hassasiyeti ile 1.8E + 19'a kadar olan değerleri temsil edebilir. Bir muhasebe uygulamasının kullanılması çok daha sağlıklı olacağını düşünürdüm Real daha fazla penni temsil etmek için ... - supercat
... çünkü bir çok 16-bitlik değerleri kullanarak çok-duyarlıklı matematik gerçekleştirmeye çalışmak. Diğer birçok dil için bu fark aşırı değildi, ancak uzun bir süredir dillerin 4E9'un ötesine geçen tamsayı türüne sahip olmaması çok yaygındı. double 9E15'e kadar birim doğruluğu olan tip. Biri, mevcut en büyük tamsayı türünden daha büyük olan tam sayıların saklanması gerekirse double İşlemciler 16x16 -> 32 ya da ... - supercat


Kimse bundan bahsetmedi

Varsayılan ayarlarda, Floats (System.Single) ve çiftler (System.Double) asla kullanmayacak   Ondalık (System.Decimal) her zaman kullanacakken taşma kontrolü   taşma kontrolü.

demek istediğim

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

atar OverflowException.

Ama bunlar değil:

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

&

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

29
2018-01-02 13:12



float.MaxValue+1 == float.MaxValue, tıpkı decimal.MaxValue+0.1D == decimal.MaxValue. Belki de float.MaxValue*2? - supercat
@supercar Ancak bu doğru ondalık değil.MaxValue + 1 == decimal.MaxValue - GorkemHalulu
@supercar decimal.MaxValue + 0.1m == decimal.MaxValue tamam - GorkemHalulu
System.Decimal tüm birimleri ayırt edemeden hemen önce bir istisna atar, ancak eğer bir uygulama örneğin; Dolar ve sentler, çok geç olabilir. - supercat


  1. Çift ve float, hem derleme hem de çalışma zamanında bir istisna olmaksızın tamsayı sıfır ile bölünebilir.
  2. Ondalık tamsayı sıfır ile bölünemez. Bunu yaparsanız derleme her zaman başarısız olur.

25
2017-07-29 07:21



Elbette yapabilirler! Ayrıca, Infinity, Negatif Sonsuzluk ve NaN (bir sayı değil) gibi birkaç "sihirli" değere de sahiptirler, bu da eğimleri hesaplarken dikey çizgileri saptamak için çok yararlıdır ... Ayrıca, arama floatı arasında karar vermek gerekirse .TryParse, double.TryParse ve decimal.TryParse (örneğin bir dizenin sayı olup olmadığını algılamak için), "Infinity", "-Infinity" ve "NaN" öğelerini doğru şekilde ayrıştıracağından, double veya float kullanılmasını öneririm ondalık olmaz ise. - BrainSlugs83
Derleme Yalnızca bir değişmezi bölme girişiminde bulunursanız başarısız olur decimal sıfıra (CS0020) göre, ve aynısı tümleşik değişmezler için geçerlidir. Ancak, bir çalışma zamanı ondalık değeri sıfıra bölünürse, bir derleme hatası değil bir istisna alırsınız. - Drew Noakes
@ BrainSlugs83 Ancak, içeriğe bağlı olarak "Infinity" veya "NaN" yi ayrıştırmak istemeyebilirsiniz. Geliştiricinin yeterince kuvvetli olmaması durumunda kullanıcı girişi için iyi bir istismar gibi görünüyor. - Winter