'float' ve 'double' hassasiyeti


155

Kod

float x  = 3.141592653589793238;
double z = 3.141592653589793238;
printf("x=%f\n", x);
printf("z=%f\n", z);
printf("x=%20.18f\n", x);
printf("z=%20.18f\n", z);

çıktı verecek

x=3.141593
z=3.141593
x=3.141592741012573242
z=3.141592653589793116

üçüncü çıktı hattında 741012573242çöp ve dördüncü satırda 116çöp. Çiftlerde her zaman 16 önemli rakam var mı, şamandıralarda her zaman 7 önemli rakam var mı? Neden çiftlerin 14 önemli figürü yok?

Yanıtlar:


146

C'deki kayan nokta sayıları IEEE 754 kodlamasını kullanır.

Bu tür kodlama bir işaret, anlamlılık ve üs kullanır.

Bu kodlama nedeniyle, birçok sayının depolanmasına izin vermek için küçük değişiklikler olacaktır.

Ayrıca, anlamlı basamakların sayısı, ondalık değil ikili bir temsil olduğu için biraz değişebilir.

Tek kesinlik (kayan nokta) size 23 bit anlamlılık, 8 bit üs ve 1 işaret biti verir.

Çift kesinlik (çift) size 52 bit anlamlılık, 11 bit üs ve 1 işaret biti verir.


4
C99 yapar, daha önce derleyiciye kalmıştı.
Alan Geleynse

21
-1 Bu ifade açık bir şekilde yanlıştır: "Bu kodlama nedeniyle, değerinizde bir değişiklik olmayacağınızı asla garanti edemezsiniz."
R .. GitHub BUZA YARDIMCI DURDUR

16
@Alan: C99, IEEE kayan nokta gerektirmez; sadece önerir.
R .. GitHub BUZA YARDIMCI DURDUR

4
@Alan: R .. doğru; Ek F (IEEE-754 bağlarını belirtir) normatiftir, ancak yalnızca bir uygulama tanımlandığında geçerlidir __STDC_IEC_559__. Bu makronun tanımlanmayan bir uygulama IEEE-754'e uymamakta serbesttir.
Stephen Canon

12
@Alan: Altında IEEE 754, kolayca değerlerinde hiçbir değişiklik olmadığını garantili 0.5, 0.046875ya 0.376739501953125ondalık gösterimlerle karşı. (Bunların hepsi mantis içindeki payı uydurma ve payda uydurma payda taban-2 logaritması ile diadik gerekçelerdir.)
R. .. GitHub DURDURMAK BUZ

42

Çiftlerde her zaman 16 önemli rakam var mı, şamandıralarda her zaman 7 önemli rakam var mı?

Hayır. Çiftler her zaman 53 anlamlı bite sahiptir ve şamandıralar her zaman 24 anlamlı bite sahiptir (denormaller, sonsuzluklar ve NaN değerleri hariç, ancak bunlar farklı bir soruya konu olanlardır). Bunlar ikili biçimlerdir ve yalnızca ikili basamak (bit) cinsinden gösterimlerinin kesinliği hakkında net bir şekilde konuşabilirsiniz.

Bu, bir ikili tamsayıda kaç basamak saklanabileceği sorusuna benzer: imzasız bir 32 bit tam sayı, 32 bite kadar tam sayıları saklayabilir, bu da herhangi bir ondalık basamağa tam olarak eşleşmez: 9 ondalık basamak kaydedilebilir, ancak birçok 10 basamaklı sayı da saklanabilir.

Neden çiftlerin 14 önemli figürü yok?

Çift kullanımların kodlama 64 bit (işareti için 1 bit, üs 52 açık olarak anlamlı bit ve bir kapalı bit 11 bit) olan, çift bir şamandıra (32 bit) temsil etmek için kullanılan bit sayısıdır.


15

şamandıra: 23 bit anlamlı, 8 bit üs ve 1 işaret biti.

çift: 52 bit anlamlı, 11 bit üs ve 1 işaret biti.


11

Genellikle taban 10'da değil, üs 2'de hem üs hem de anlamlı anlamlı rakamlara dayanır. Bununla birlikte, C99 standardında söyleyebileceğimden, şamandıralar ve çiftler için belirli bir hassasiyet yoktur (1 ve 1 + 1E-5/ 1 + 1E-7ayırt edilebilir [ floatve doubletekrarlı olarak]). Bununla birlikte, önemli rakamların sayısı uygulayıcıya bırakılır (ayrıca dahili olarak hangi tabanı kullandıkları, diğer bir deyişle, bir uygulama bunu taban 3'te 18 basamağa dayanarak yapmaya karar verebilir). [1]

Bu değerleri bilmeniz gerekiyorsa, sabitler FLT_RADIXve FLT_MANT_DIG(ve DBL_MANT_DIG/ LDBL_MANT_DIG) float.h dosyasında tanımlanır.

A olarak adlandırılmasının nedeni, onu doubledepolamak için kullanılan bayt sayısının bir kayan noktalı sayının iki katı olmasıdır (ancak bu hem üs hem de anlamlılığı içerir). IEEE 754 standardı (çoğu derleyici tarafından kullanılır), anlamlılık için üsten (göreceli olarak float52 ila 12 için 23 ila 9) nispeten daha fazla bit ayırır double, bu nedenle kesinlik iki kattan fazladır.

1: Bölüm 5.2.4.2.2 ( http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf )


Tipo? C89 en fazla bir epsilonu gerektirir 1E-9için doubledeğil, 1E-7.
Rufflewind


4

IEEE 754'ün nasıl çalıştığı ve tam olarak ondalık sayıya tam olarak dönüşmediği için tam olarak çift hassasiyetli değildir. Eğer ilgileniyorsanız standarda bir göz atın.


4

C'de, toplam basamak sayısının hassasiyetinin 7 olduğu durumlarda float veri tipi kullanılır. Örneğin: - ondalık no. 12.3546987 toplam 9 hane olduğu için şamandıra içinde saklanamaz. Çıktı 12.354699 olarak gösterilecektir, yani ilk 7 hane girişte girildiği gibi gösterilecek ve 8. hane yuvarlanacaktır. Yaklaşık 1.5 x 10 ^ (- 45) ile 3.4 x 10 ^ (38) arasındadır. Bellek ayırma açısından, kayan noktalı tek duyarlıklı, 32 bit kayan noktalı bir veri türüdür.

Şamandıradan farklı olarak, çift 15 ila 16 basamak hassasiyete sahiptir. Çift aralık 5.0 × 10 ^ (- 345) ila 1.7 × 10 ^ (308) arasındadır. Bayt tahsisi açısından, çift 64 bit kayan nokta verisidir. yazın.

Sorun kullanımında ortaya çıkar. Şamandıra veya çift baskı printf'yi etkilemez, ancak tarama durumunda toplam no. yüzer basamak sayısı. girişten okunacak.

Bu nedenle, daha yüksek veri doğruluğu için şamandıra yerine çift tercih edilir.

Bu yardımcı olur umarım.

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.