Hassasiyeti kaybetmeden bir IEEE 754 çift tipinde depolanabilen en büyük "kayan" tam sayı nedir?
Hassasiyeti kaybetmeden bir IEEE 754 çift tipinde depolanabilen en büyük "kayan" tam sayı nedir?
Yanıtlar:
Hassasiyeti kaybetmeden bir çiftte saklanabilecek en büyük / en büyük tamsayı, bir çiftin mümkün olan en büyük değeri ile aynıdır. Yani DBL_MAX
veya yaklaşık 1.8 × 10 308 (eğer çiftliğiniz bir IEEE 754 64-bit çift ise). Bu bir tamsayı. Tam olarak temsil ediliyor. Daha fazla İstediğiniz ne?
Devam et, bana en büyük tamsayının ne olduğunu sor, böylece daha küçük tamsayılar IEEE 64-bit'te iki katına çıkmadan kesilebilir. Bir IEEE 64-bit çiftinin 52 bit mantis var, bu yüzden 2 53 olduğunu düşünüyorum :
Ya da başka bir bakış açısı: önyargı üs dışına çıkarıldıktan ve işaret bitini soru ile ilgisiz olarak göz ardı ettikten sonra, bir çift tarafından depolanan değer 2'nin gücü ve 2 ile çarpılan 52 bitlik bir tamsayıdır. üs - 52 . Yani üs 52 ile size 2'den tüm değerleri saklayabilir 52 2 kadar 53 2 sonra Sonra üs 53 ile, bir sonraki numara saklayabilir - 1. 53 2 53 + 1 × 2 52-53 . Bu yüzden önce hassasiyet kaybı 2 53 + 1 ile gerçekleşir.
9007199254740992 (bu 9.007.199.254.740.992) garantisizdir :)
program
#include <math.h>
#include <stdio.h>
int main(void) {
double dbl = 0; /* I started with 9007199254000000, a little less than 2^53 */
while (dbl + 1 != dbl) dbl++;
printf("%.0f\n", dbl - 1);
printf("%.0f\n", dbl);
printf("%.0f\n", dbl + 1);
return 0;
}
Sonuç
9007199254740991 9007199254740992 9007199254740992
double dbl = 1; while (dbl + 1 != dbl) dbl *= 2; while (dbl == --dbl);
, aynı sonucu veren daha hızlı bir test olur
while (dbl == --dbl)
sonsuza dek dönecek veya hiç dönmeyecek. :) (bu durumda, hiç değil, çünkü 2 ^ N). Aşağıdan yaklaşmanız gerekecek. Gerçekten de beklenen sonuçtan bir daha az ile sonuçlanacaktır (while döngüsünde bir kontrol dbl azaldığı için). Ve bu, sol tarafın değerlendirilmesinden önce veya sonra (ki bildiğim kadarıyla tanımlanmamış) yapılırsa, yürütme sırasına bağlıdır. Eğer eskisi ise, her zaman doğru olacak ve sonsuza kadar döngü yapacak.
while (dbl + 1 != dbl) dbl++;
ki dbl + 1 != dbl
kullanılarak değerlendirebilir long double
matematik - düşünün FLT_EVAL_METHOD == 2
. Bu sonsuz bir döngü ile sonuçlanabilir.
Wikipedia, IEEE 754 bağlantısıyla aynı bağlamda şunu söylemektedir :
Tipik bir bilgisayar sisteminde, 'çift kesinlikli' (64 bit) ikili kayar nokta sayısı 53 bitlik (biri zımni), 11 bitlik bir üs ve bir işaret bitine sahiptir.
2 ^ 53 9 * 10 ^ 15'in biraz üzerindedir.
IEEE 754 çift (64-bit) ile temsil edilebilecek en büyük tamsayı, türün temsil edebileceği en büyük değerle aynıdır, çünkü bu değerin kendisi bir tamsayıdır.
Bu, 0x7FEFFFFFFFFFFFFF
aşağıdakilerden oluşan şu şekilde temsil edilir :
0x7FE
(sapma çıkarıldıktan sonra 1023'ü temsil eden 2046) yerine 0x7FF
(a NaN
veya sonsuzluğu gösteren 2047 ).0xFFFFFFFFFFFFF
52 bit olan maksimum mantis hepsi 1.İkilide, değer örtük 1'dir, ardından mantisten 52 tane, daha sonra üssünden 971 sıfır (1023 - 52 = 971) gelir.
Tam ondalık değer:
179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368
Bu yaklaşık 1.8 x 10 308'dir .
Mantis büyüklüğüne bakmanız gerekir. Bir IEEE 754 64 bit kayan nokta sayısı (52 bit, artı 1 ima edilmiş), mutlak değeri 2 ^ 53'e eşit veya daha düşük olan tam sayıları tam olarak temsil edebilir.
1.7976931348623157 × 10 ^ 308
http://en.wikipedia.org/wiki/Double_precision_floating-point_format
DECIMAL_DIG
dan <float.h>
bu en azından makul bir yaklaşım vermelidir. Bu ondalık basamaklarla uğraştığından ve gerçekten ikili olarak saklandığından, büyük olasılıkla hassasiyeti kaybetmeden biraz daha büyük bir şey saklayabilirsiniz , ancak tam olarak ne kadar zor olduğunu söyleyebilirsiniz. Sanırım bunu anlayabilmelisin FLT_RADIX
ve DBL_MANT_DIG
, ama sonuca tamamen güveneceğime emin değilim.
double
doğrudan belirli bir IEEE tipine karşılık gelen yanlış varsayımlara dayanır , ancak bu gerekli değildir ve bu cevap yazıldığında soru belirli bir IEEE tipinden de bahsetmedi.