Bir IEEE 754 şamandıra tam olarak temsil edemeyen ilk tam sayı hangisidir?


162

Açıklık getirmek gerekirse, IEE 754 yüzen bir dil kullanıyorsanız ve şunu beyan ederim:

float f0 = 0.f;
float f1 = 1.f;

... ve sonra onları tekrar basarsanız, tam olarak 0.0000 ve 1.0000 elde edeceğim.

Ancak IEEE 754, gerçek çizgideki tüm sayıları temsil edemez. Sıfıra yakın 'boşluklar' küçük; uzaklaştıkça boşluklar büyür.

Yani, sorum şu: tam olarak temsil edilemeyen ilk (sıfıra en yakın) tam sayı olan bir IEEE 754 şamandıra için? Şimdilik sadece 32-bit şamandıralarla gerçekten ilgileniyorum, ancak biri verirse 64-bit için cevabı duymak isterim!

Ben bu 2 hesaplanırken olarak basit olarak olacağını düşündüm bits_of_mantissa ve nerede, 1 ekleme bits_of_mantissa kaç bit standart İFŞA olduğunu. Bunu makinemdeki 32-bit şamandıralar için yaptım (MSVC ++, Win64) ve yine de iyi görünüyordu.


Vazgeçilemez bir sayı isteseniz neden bir tane eklediniz? Ve hangi numarayı kullandınız veya aldınız? Ve bu ödev mi? Ve soru başlığınız "tamsayı" diyor, sorunuz "kayan" yazıyor.
msw

5
Çünkü mantisı maksimuma çıkarmanın en yüksek rakamı vereceğini düşündüm. 2 ^ 22. Hayır, bu bir merak sorusu. Söz konusu int'in her zaman çok küçük olacağını bildiğimde bile, her zaman şamandıralara inat etmek suçlu hissettim. Üst sınırın ne olduğunu bilmek istiyorum. Anlayabildiğim kadarıyla, başlık ve soru aynı, sadece farklı ifade edildi.
Floomi



1
@KyleStrand geri döndü ^ 2. Birinin benim için neden diğerinden daha doğru göründüğünü bilmiyorum. Şimdi ikisi de “… bit sayısı…” ile karşılaştırıldığında garip görünüyor
Pascal Cuoq

Yanıtlar:


211

2 mantis ucu + 1 + 1

Üstaki +1 (mantis bitleri + 1), mantis abcdef...temsil ettiği sayıyı içeriyorsa , gerçekte 1.abcdef... × 2^eekstra örtülü bir hassasiyet sağlar.

Bu nedenle, ilk tamsayı olamaz doğru bir şekilde temsil edilebilir ve yuvarlak olacak olan:
için float, 16.777.217 (2 24 + 1).
İçin double9,007,199,254,740,993 (2, 53 + 1).

>>> 9007199254740993.0
9007199254740992

Bir beyan ettim floatve 16.777.217'ye eşitledim. Ama bunu kullanarak yazdırdığımda cout16.777.216 sonuçlandı. Kullanıyorum C++. Neden 16.777.217'yi alamıyorum?
sodiumnitrate

18
@sodiumnitrate Soru başlığını kontrol edin. 16777217 ilk tamsayı yetersiz tam olarak temsil edilme.
kennytm

Tamam teşekkürler. Kafam karıştı, bunun için üzgünüm. Yine de başka bir sorum var: 16777216'dan sonra, temsil edilebilir bir sonraki tamsayı 2 * 16777216 olmamalı mı? Benzer bir programı çalıştırdığımda, 16777126'ya 2 ekleyerek 16777218 alıyorum.
sodiumnitrate

5
Bir sonraki tamsayı gerçekten 16777218'dir, çünkü 2 şimdi son önemli ikili basamak haline gelir.
kennytm

6
C ++ 'da, bu (1 << std::numeric_limits<float>::digits) + 1ve C' de (1 << FLT_MANT_DIG) + 1. Birincisi güzel çünkü bir şablonun parçası olabilir. Yalnızca temsil edilebilir en büyük tamsayıyı istiyorsanız +1 eklemeyin.
Henry Schreiner

38

Bir n bit tamsayısı ile temsil edilebilen en büyük değer 2 n- 1'dir. Yukarıda belirtildiği gibi, a float, 24 24 hassasiyete sahiptir ve bu da 2 24'ün uymayacağı anlamına gelir .

Ancak .

Üs aralığı dahilindeki 2'nin kuvvetleri tam olarak 1.0 × 2 n olarak temsil edilebilir , böylece 2 24 sığabilir ve sonuç olarak ilk tekrar temsil edilemeyen tam sayı float2 24 +1'dir. Yukarıda not edildiği gibi. Tekrar.


1
Bu açıkça diğerinin "ekstra örtülü kesinlik biraz" kısmını açıkladı. Teşekkürler.
chappjc
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.