C ++ 'da birini diğerinin yerine kullanmanın avantajları ve dezavantajları nelerdir?
C ++ 'da birini diğerinin yerine kullanmanın avantajları ve dezavantajları nelerdir?
Yanıtlar:
Doğru cevabı öğrenmek istiyorsanız, Kayan Nokta Aritmetiği Hakkında Her Bilgisayar Bilimcisinin Bilmesi Gerekenler'i okumalısınız .
Kısacası, sunumunda daha yüksek hassasiyetedouble
izin vermesine rağmen , belirli hesaplamalar için daha büyük hatalar üretecektir . "Doğru" seçim şudur: İhtiyaç duyduğunuz kadar hassas kullanın ancak daha fazlasını kullanmayın ve doğru algoritmayı seçin .
Çoğu derleyici "katı olmayan" modda genişletilmiş kayan nokta matematiği yapar (yani donanımda mevcut olan daha geniş bir kayan nokta türü kullanın, örneğin 80 bit ve 128 bit kayan), bu da dikkate alınmalıdır. Pratikte, hızda neredeyse hiç fark göremezsiniz - zaten bunlar donanımın temelidir.
double
- çoğu durumda daha güvenlidir.
Aksini yapmak için belirli bir nedeniniz olmadıkça, double kullanın.
Belki de şaşırtıcı bir şekilde, C (ve C ++ 'da) "normal" kayan nokta türü olan çifttir ve float değildir. Günah ve günlük gibi standart matematik işlevleri , argüman olarak çiftleri alır ve döndürme iki katına çıkar. Normal bir kayan nokta değişmez değeri, 3.14 yazarken olduğu gibi programınızda , double türüne sahiptir. Yüzer değil.
Tipik modern bilgisayarlarda, çiftler en az kayan hızlar kadar hızlı veya daha hızlı olabilir, bu nedenle performans, büyük hesaplamalar için bile genellikle dikkate alınması gereken bir faktör değildir. (Ve bunların büyük hesaplamalar olması gerekir, yoksa performans aklınıza bile girmemelidir. Yeni i7 masaüstü bilgisayarım bir saniyede altı milyar ikiye katlama yapabilir.)
Sorunun bağlamı olmadığı için bu sorunun yanıtlanması imkansızdır. İşte seçimi etkileyebilecek bazı şeyler:
Float, double ve long double'ların derleyici uygulaması. C ++ standardı şu şekildedir:
Üç kayan nokta türü vardır: float, double ve long double. Double tipi, en az float kadar hassasiyet sağlar ve uzun double tipi, en az double kadar hassasiyet sağlar.
Dolayısıyla, üçü de aynı boyutta bellekte olabilir.
Bir FPU'nun varlığı. Tüm CPU'ların FPU'ları yoktur ve bazen kayan nokta türleri taklit edilir ve bazen kayan nokta türleri desteklenmez.
FPU Mimarisi. IA32'nin FPU'su dahili olarak 80bit'tir - 32 bit ve 64 bit kayan değerler, yükte 80bit'e genişletilir ve depoda azaltılır. Paralel olarak dört adet 32bit kayan veya iki adet 64bit kayan yapabilen SIMD de var. SIMD kullanımı standartta tanımlanmamıştır, bu nedenle SIMD'nin kullanılıp kullanılamayacağını belirlemek için daha karmaşık analizler yapan veya özel işlevlerin (kitaplıklar veya içsel) kullanımını gerektiren bir derleyici gerektirecektir. 80 bit dahili formatın sonucu, verilerin RAM'e ne sıklıkta kaydedildiğine bağlı olarak biraz farklı sonuçlar alabilmenizdir (dolayısıyla hassasiyeti kaybedersiniz). Bu nedenle, derleyiciler kayan nokta kodunu özellikle iyi optimize etmezler.
Bellek bant genişliği. Bir çift, bir kayan noktadan daha fazla depolama gerektiriyorsa, verileri okumak daha uzun sürecektir. Bu saf cevap. Modern bir IA32'de, her şey verilerin nereden geldiğine bağlıdır. L1 önbelleğindeyse, verilerin tek bir önbellek hattından gelmesi koşuluyla yük ihmal edilebilir. Birden fazla önbellek satırını kapsıyorsa, küçük bir ek yük vardır. L2'den geliyorsa, biraz daha uzun sürer, RAM'deyse daha uzun sürer ve nihayet, diskte ise çok büyük bir zaman. Dolayısıyla float veya double seçimi, verilerin kullanılma biçiminden daha az önemlidir. Çok sayıda sıralı veri üzerinde küçük bir hesaplama yapmak istiyorsanız, küçük bir veri türü tercih edilir. Küçük bir veri kümesi üzerinde çok fazla hesaplama yapmak, herhangi bir önemli etkiye sahip daha büyük veri türlerini kullanmanıza olanak tanır. Eğer sen' verilere çok rastgele erişilirse, veri boyutu seçimi önemsizdir - veriler sayfalara / önbellek satırlarına yüklenir. Dolayısıyla, yalnızca RAM'den bir bayt isteseniz bile, 32 bayt aktarabilirsiniz (bu, sistemin mimarisine çok bağlıdır). Tüm bunlara ek olarak, CPU / FPU süper skaler (diğer adıyla ardışık düzenlenmiş) olabilir. Bu nedenle, bir yük birkaç döngü sürse bile, CPU / FPU, yükleme süresini bir dereceye kadar gizleyen başka bir şey (örneğin bir çarpma) yapmakla meşgul olabilir.
Standart, kayan nokta değerleri için herhangi bir özel formatı zorlamaz.
Bir spesifikasyonunuz varsa, bu sizi en uygun seçeneğe yönlendirecektir. Aksi takdirde, ne kullanılacağı konusunda deneyim yaşanır.
Double daha kesindir, ancak 8 bayta kodlanmıştır. float yalnızca 4 bayttır, dolayısıyla daha az alan ve daha az hassasiyettir.
Uygulamanızda duble ve float varsa çok dikkatli olmalısınız. Geçmişte bundan dolayı bir sorun yaşadım. Kodun bir kısmı float kullanırken, kodun geri kalanı double kullanıyordu. Double'ı float'a ve ardından float'ı ikiye kopyalamak, büyük etkiye sahip olabilecek hassas hatalara neden olabilir. Benim durumumda, bir kimya fabrikasıydı ... umarım dramatik sonuçları olmamıştır :)
Sanırım bu tür bir hata yüzünden Ariane 6 roketi birkaç yıl önce patladı !!!
Bir değişken için kullanılacak tür hakkında dikkatlice düşünün
Bu, derleyicinin double'ı nasıl uyguladığına bağlıdır. Double ve float'ın aynı tür olması yasaldır (ve bazı sistemlerde geçerlidir).
Bununla birlikte, eğer gerçekten farklılarsa, asıl mesele hassasiyettir. Bir çift, boyut farkı nedeniyle çok daha yüksek bir hassasiyete sahiptir. Kullandığınız sayılar genellikle bir kayan nokta değerini aşacaksa, o zaman bir çift kullanın.
Birkaç kişi performans sorunlarından bahsetti. Bu, düşünceler listemdeki sonuncu olurdu. Doğruluk, 1 numaralı düşünceniz olmalıdır.
Uygun sonuçları elde etmek için hangi hassasiyetin gerekli olduğunu kullanın . Daha sonra kodunuzun istediğiniz kadar iyi performans göstermediğini fark ederseniz (profil oluşturmayı doğru kullandınız mı?) Bir göz atın:
Sanırım farklılıklar ne olursa olsun (herkesin işaret ettiği gibi, yüzer daha az yer kaplar ve genel olarak daha hızlıdır) ... hiç kimse double kullanarak performans sorunları yaşar mı? Çift kullan diyorum ... ve daha sonra "vay, bu gerçekten yavaş" diye karar verirseniz ... performans darboğazınızı bulun (muhtemelen iki katı kullandığınız gerçek değildir). O ZAMAN, sizin için hala çok yavaşsa, biraz hassasiyeti nerede feda edebileceğinizi görün ve şamandırayı kullanın.
Float ve double arasındaki temel fark hassasiyettir. Wikipedia'da Tek duyarlık (kayan nokta) ve Çift duyarlık hakkında daha fazla bilgi vardır .
Büyük ölçüde CPU'ya bağlıdır, en belirgin değiş tokuşlar hassasiyet ve bellek arasındadır. GB RAM ile bellek çok fazla sorun teşkil etmez, bu nedenle genellikle double
s kullanmak daha iyidir .
Performans gelince, büyük ölçüde CPU'ya bağlıdır. float
s genellikle double
32 bitlik bir makinede olduğundan daha iyi performans alır . 64 bit'te, double
(genellikle) yerel boyut olduğundan s bazen daha hızlıdır. Yine de, veri türü seçiminizden çok daha önemli olan şey, işlemcinizdeki SIMD talimatlarından yararlanıp yararlanamayacağınızdır.
double daha yüksek hassasiyete sahipken, kayan değerler daha az bellek kullanır ve daha hızlıdır. Genel olarak, yeterince doğru olmadığı bir durumunuz yoksa float kullanmalısınız.