Tamsayı’dan Tek’e dönüşüm ne zaman hassas olabilir


27

Ben okuyordum Açık Sıkı Dönüşümler ve Seçenek Genişletme ile ilgili Microsoft'tan bir makale ı kısmına geldiğimde

Aşağıdaki dönüşümler hassasiyetini kaybedebilir:

  • Tekten Tamsayı
  • Tek-Uzun veya Uzun
  • Tek veya İkili Ondalık

Ancak, bu dönüşümler bilgi veya büyüklüğü kaybetmez.

.. ama veri türleriyle ilgili başka bir makaleye göre ,

  • Tamsayı türü -2.147.483.648 - 2.147.483.647 arasında saklayabilir ve

  • Tek tip saklayabilirsiniz

    • Pozitif sayılar için 1,401298E-45 ila 3,4028235E + 38,
    • ve negatif sayılar için -3,4028235E + 38 ila - 1,401298E-45

.. böylece Single, Integer'dan çok daha fazla sayı saklayabilir. Integer’dan Single’a böyle bir dönüşümün hangi durumda olabileceğini anlamadım. Birisi açıklayabilir mi lütfen?

Yanıtlar:


87

Tek, Tam Sayıdan çok daha fazla sayı saklayabilir

Hayır yapamaz. Hem Singleve Integer32 bit, olan iki saklamak için araçlar aynı sayı miktarı, yani 2 32 = 4294967296 farklı sayıları.

Yana aralığı içinde Singledaha net bir şekilde daha büyük olduğuna göre, (çünkü hemen açıktır Pigeonhole İlke o) muhtemelen olamaz bu aralık içinde tüm sayıları temsil eder.

Ve aralığı, Integerher ikisinin de temsil edebileceği Integerve Singletemsil edebileceği maksimum sayı miktarıyla tam olarak aynı boyutta olduğundan , ancak Singlebu aralığın dışındaki sayıları da gösterebildiği için, aralık içindeki tüm sayıları temsil edemeyeceği açıktır Integer.

Varsa bazı sayılar Integero temsil edilemez Singledönüştürme, Integeriçin Single gereken bilgileri kaybetmeden yeteneğine sahip.


3
Bunun niçin böyle olması gerektiğine dair bu büyük açıklama için +1 , soru gerçekte ne zaman olmasına rağmen ("ne durumda")
olmuştu

21
@doubleYou: 4294967296 Integers'nin (% 99.2) 4261412864'ü (% 99,2) Single" temsil edilmez ", yani "ne zaman" hemen hemen her zaman ".
Jörg W Mittag

2
Daha kesin olmak istiyorsanız Single, yalnızca 4.278.190.079 farklı sayıyı temsil edebilir. Bir Singledeğer, yalnızca depolanan üs 255 değilse ve Singlebu rakamları temsil eden 255 * 2 ^ 24 s olduğu anlamına gelir . Bunlardan iki tanesi aynı sayıyı (yani sıfır), diğerleri ise farklı sayıları temsil eder.
Tanner Swett

10
en.wikipedia.org/wiki/Single-precision_floating-point_format , IEEE754 binary32 için sınırlamaları iyi açıklar. Tamsayıları [-16777216,16777216](2 ^ 24 = anlamlı ve genişlik) tam olarak gösterilebilir. Büyük sayılar, büyüklüklerine bağlı olarak 2, 4, 8, ... en yakın katlarına yuvarlanır.
Peter Cordes

14
“Bu, her ikisinin de aynı sayıda sayıyı saklayabileceği anlamına gelir” - Bu demek değildir . Bu, yalnızca her iki türün de her sayıyı aynı sayıda saklamanın yoluna sahip olması anlamına gelir. Ve bu durum böyle değil; örneğin, Singlesıfır kaydetmenin iki yolu vardır. Bu yüzden Singleaslında ondan daha az farklı sayıları temsil edebilir Integer.
Konrad Rudolph

28

Kayan nokta tipleri (Tek ve Çift gibi) bellekte bir işaret, bir mantis ve bir üs ile gösterilir. Bilimsel gösterim olarak düşünün:

Sign*Mantissa*Base^Exponent

Onlar - beklediğiniz gibi - üs 2'yi kullanın. Sonsuzluğu ve NaN'i temsil etmeyi sağlayan başka tweaks'ler var ve üs, ofset (buna geri dönecek) ve mantis için bir kısa yol (buna geri dönecek) . Daha fazla ayrıntı için gösterimini ve işlemlerini kapsayan standart IEEE 754'ü arayın.

Amaçlarımız için, onu bir ikili sayı "mantis" ve ondalık ayırıcıyı nereye koyacağınızı söyleyen bir "üs" olarak düşünebiliriz.


Bekar durumunda, imza atması için 1 bit, üs için 8 ve mantis için 23 bittik.

Şimdi, şey şu ki, mantisayı en önemli basamaktan depolayacağız. Soldaki tüm sıfırların alakalı olmadığını unutmayın. İkili olarak çalıştığımızı ve en önemli rakamın 1 is olduğunu biliyoruz. Bunu bildiğimizden beri saklamak zorunda değiliz. Bu steno sayesinde, mantislerin etkili menzili 24 bittir.

※: Sakladığımız sayı sıfır değilse. Bunun için tüm bitleri sıfıra ayarlayacağız. Bununla birlikte, verdiğim açıklama uyarınca, üssün gücüyle 2 (24) (çarpık 1) ile 1 (2 çarpı gücünün gücüne) çarpacağını yorumlamaya çalışırsak. Bu nedenle, düzeltmek için sıfır üs, özel bir değerdir. Üssünde sonsuzluğu ve NaN'yi depolamak için özel değerler de vardır.

Üss ofsetine göre - özel değerlerden kaçınılması haricinde -, ofseti koymak, ondalık basamağı mantinin başlamasından önce veya bitiminden sonra, üs için bir işarete gerek duymadan yerleştirmeyi sağlar.


Bu, büyük sayılar için kayan nokta türünün, ondalık sayıyı mantisin sonunun ötesine koyacağı anlamına gelir.

Mantislerin 24 bitlik bir sayı olduğunu unutmayın. Asla 25 bitlik bir sayı göstermeyecek ... bu fazladan bit içermiyor. Bu nedenle, tek, 2 ^ 24 ve 2 ^ 24 + 1 arasında ayrım yapamaz (bunlar ilk 25 bit sayılardır ve tek olarak gösterilmeyen son bit üzerinde farklılık gösterir).

Bu nedenle, tamsayılar için bekarların aralığı -2 ^ 24 ila 2 ^ 24'tür. Ve 1 ila 2 ^ 24 eklemeye çalışmak 2 ^ 24 ile sonuçlanır (çünkü tür söz konusu olduğunda, 2 ^ 24 ve 2 ^ 24 + 1 aynı değerdedir). Çevrimiçi deneyin . Bu nedenle tamsayıdan türe dönüştürürken bilgi kaybı yaşanıyor. Bu da tek veya çift kullanan bir döngü aslında fark etmeden sonsuz bir döngü olabilir.


Bu, örtük öncü 1bit'in önemine dair mükemmel bir açıklama değildir . Önyargılı üs alanı sıfır olmayan tarafından ima edilir . Subnormals (aka denormals) da dahil+-0.0 olmak üzere0 önem derecelerinin başında gelir . 0.0Tamamen özel bir olayı düşünmeyi basitleştirebilirsin , ama 0.0aslında diğer alt normallerle aynı kodlama kurallarına uyar.
Peter Cordes

25

Bu, 'den' Integerye olan Singlehassasiyeti kaybedebileceğinin gerçek bir örneği :

SingleTip -16777216 den 16.777.216 (dahil) kadar tüm sayıları depolar, ancak bu aralığın dışında kalan tüm tamsayılar saklamak mümkün değil. Örneğin, 16777217 sayısını kaydedemez. Bu nedenle, 16777216'dan büyük herhangi bir tek sayı kaydedemez.

IntegerA Singleile geriye dönüştüğümüzde ne olacağını görmek için Windows PowerShell'i kullanabiliriz :

PS C:\Users\tanne> [int][float]16777213
16777213
PS C:\Users\tanne> [int][float]16777214
16777214
PS C:\Users\tanne> [int][float]16777215
16777215
PS C:\Users\tanne> [int][float]16777216
16777216
PS C:\Users\tanne> [int][float]16777217
16777216
PS C:\Users\tanne> [int][float]16777218
16777218
PS C:\Users\tanne> [int][float]16777219
16777220

16777217’nin 16777216’ya yuvarlandığına ve 16777219’un 16777220’ye yuvarlandığına dikkat edin.


4
Artan büyüklükle, temsil edilebilecek en yakın floats arasındaki mesafe güçleri olarak büyümeye devam eder . en.wikipedia.org/wiki/…
Peter Cordes

12

Kayan nokta tipleri fizikteki "bilimsel gösterime" benzer. Sayı bir işaret biti, bir üs (çarpan) ve bir mantis (önemli basamaklar) olarak bölünmüştür. Böylece değerin büyüklüğü arttıkça, adım boyutu da artar.

Tek duyarlıklı kayan nokta 23 mantis bitine sahiptir, ancak "örtük 1" vardır, bu nedenle mantis etkin bir şekilde 24 bittir. Bu nedenle, 2 24'e kadar olan tüm tam sayılar tam olarak tek bir hassas kayar nokta ile gösterilebilir.

Bunun üzerinde ardışık olarak daha az sayı gösterilebilir.

  • 2 24 ile 2 25 arasında sadece çift sayılar gösterilebilir.
  • 2 ila 25 26 arasında sadece 4'ün katları gösterilebilir.
  • 2 26 ila 2 27 arasında yalnızca 8'in katları gösterilebilir.
  • 2 27'den 2 28'e sadece 16'nın katları gösterilebilir
  • 2 28'den 2 29'a sadece 32'nin katları gösterilebilir
  • 2 29'dan 2 30'a sadece 64'ün katları gösterilebilir
  • 2 30 ile 2 31 arasında yalnızca 128'in katları gösterilebilir

Böylece 2 32 olası 32 bit işaretli tamsayı değeri sadece 2 * (2 24 + 7 * 2 23 ) = 9 * 2 24 tek duyarlıklı kayan nokta ile gösterilebilir. Bu toplamın% 3,515625 kadarı.


8

Tek hassasiyetli yüzdürmeler 24 bit hassasiyete sahiptir. Bunun üzerinde herhangi bir şey en yakın 24-bit sayıya yuvarlanır. Ondalık bilimsel gösterimlerde anlaşılması daha kolay olabilir, ancak gerçek yüzerlerin ikili kullandığını unutmayın.

5 ondalık basamak hafızanız olduğunu söyleyin. 0 ile 99999 arasında herhangi bir sayıya sahip olmanıza olanak tanıyan normal imzasız bir int gibi olanları kullanmayı tercih edebilirsiniz. Daha büyük sayıları temsil edebilmek istiyorsanız, bilimsel gösterimi kullanabilir ve üstel olmak için iki rakam atayabilirsiniz. şimdi 0 ile 9,99 x 10 99 arasında bir şeyi temsil edebilirsiniz .

Ancak, tam olarak temsil edebileceğiniz en büyük sayı şuanda sadece 999'dur. 12345'i temsil etmeye çalıştıysanız, 1.23 x 10 4 veya 1.24 x 10 4 elde edebilirsiniz ancak aradaki sayıların hiçbirini temsil edemezsiniz. yeterli basamak yok.


3
Ondalık basamak kullanmak, anlaşılmasını kolaylaştıran iyi bir fikirdir, ancak son paragraf biraz yanıltıcıdır: aslında 999'dan daha büyük sayıları temsil edebilirsiniz ve örneğinizin şunu gösterdiği gibi: 12300, 1.23 x 10 <sup> 4 <sup >. Demek istediğim, bu sayıdan başlayarak boşluklar olduğu. Biraz tekrar düzeltir misin?
Fabio, Monica
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.