0

IEEE-754 Kayan Görüntüleyici

Ondalık sayının IEEE-754 kayan noktalı sayı olarak nasıl depolandığını (işaret biti, üs bitleri ve mantis bitleri) ve 0,1 gibi sayıların neden tam olarak depolanmadığını tam olarak görün.

Buy Me a Coffee at ko-fi.com
İşleniyor... 0%
Normalleştirme
Üslü önyargının hesaplanması
Genişleyen mantis bitleri
Bitti

Sonuç

Bir bilgisayarın sakladığı her kayan nokta sayısı (bir JavaScript numarası, bir C kayan nokta, bir Python kayan nokta) IEEE 754 altında aynı şekilde kodlanır: bir işaret biti, bir üs bit bloğu ve bir mantis (kesir) bit bloğu. Tek duyarlıklı (32 bit) 1 işaret biti, 8 üs biti ve 23 mantis biti kullanır; Neredeyse her dilin varsayılan sayı türünün arkasındaki format olan çift duyarlıklı (64 bit), 1 işaret biti, 11 üs biti ve 52 mantis biti kullanır. Bu araç, yazdığınız herhangi bir ondalık sayıyı alır, tarayıcının kendi DataView/ArrayBuffer kayan kodlayıcısını (kodunuzun gerçekte çalıştığı makine) kullanarak her iki genişlikte de kodlar ve her biti ait olduğu bölgeye göre renklendirir.

Kodlamanın kendisi üç adımı takip eder ve bu araç yalnızca son parçaları göstermek yerine tüm adımların üzerinden geçer. İlk olarak, normalleştirme: sayı, ikili noktadan önce tam olarak sıfırdan farklı bir rakam olacak şekilde 1.mantissa × 2^üs olarak yeniden yazılır (bunun için çok küçük sayılar bunun yerine normalin altında muamele görür, başında 1 yoktur). İkincisi, üs sapması: üs alanının hem pozitif hem de negatif üsleri işaretsiz bir sayı olarak saklaması gerektiğinden, alan ikili olarak yazılmadan önce sabit bir önyargı (tek duyarlık için 127, çift için 1023) eklenir. Üçüncüsü, kesirli mantis klasik "ikiyle çarp, tamsayı kısmını bir sonraki bit olarak al, kalanı koru" yöntemiyle parça parça genişletilir - mantis alanı dolana kadar tekrarlanır; bu noktada kalan bitler sonucun yukarı mı yoksa aşağı mı yuvarlanacağına karar verir (yarımdan çifte yuvarlama, IEEE-754 varsayılanı).

İşte tam da bu yüzden 0,1 kadar sıradan bir sayı tam olarak saklanmıyor. İkili sistemde 0,1 tekrarlanan bir kesirdir (0,0001100110011…, sonsuza kadar), dolayısıyla hiçbir sonlu mantis onu tam olarak tutamaz; bir yerde yuvarlanması gerekir. 0.1'i 32 bitlik bir kayan nokta olarak kodlayın ve bitleri geri okuyun; 0.1'i geri alamazsınız: tam olarak 0.100000001490116119384765625 elde edersiniz. Çift duyarlıklılığın üzerinde çalışılacak 29 mantis biti daha vardır, bu nedenle yuvarlama hatası çok daha küçüktür, ancak sıfır da değildir - 64 bitlik bir çift tam olarak 0,1000000000000000055511151231257827021181583404541015625 olduğundan 0,1. Bu araç, tam olarak saklanan değeri büyük tamsayı aritmetiğiyle (kayan nokta kısayolları olmadan) hesaplar, böylece yazdığınız şey ile donanımın gerçekte sakladığı arasındaki fark hiçbir zaman gizlenmez veya yaklaşık olarak belirlenmez.

Özel değerler, normal bir kodlama yerine tam, ayrılmış bit desenleri alır: sıfır ve negatif sıfır, tamamı sıfır üs ve mantis bitlerine sahiptir (yalnızca işaret biti farklıdır), ±Infinity, tamamı sıfır mantisli hepsi bir üs bitlerine sahiptir ve NaN, en az bir mantis bit seti ile hepsi bir üs bitlerine sahiptir. Buradaki her şey tarayıcınızda yerel olarak çalışır - yazdığınız hiçbir şey herhangi bir yere yüklenmez - bu da burayı kayan nokta hatalarına yönelik gerçek sezgiler oluşturmak için güvenli bir yer haline getirir: neden hemen hemen her programlama dilinde '0,1 + 0,2 !== 0,3', grafik kodundaki float32 dokuları neden float64'ün kaybedemeyeceği hassasiyeti kaybediyor ve neden finansal kod genel olarak ikili kayan noktadan tamamen kaçınmalı?