IEEE-754 визуелизатор float бројева
Видите тачно како се децимални број чува као IEEE-754 float — бит знака, битови експонента и битови мантисе — и зашто се бројеви попут 0.1 не чувају прецизно.
🔒 У потпуности се обрађује у вашем претраживачу — ништа што овде унесете се никада не отпрема.
Резултат
Сваки број са покретним зарезом који рачунар чува — JavaScript број, C float, Python float — кодиран је на исти начин према IEEE 754: један бит знака, блок битова експонента и блок битова мантисе (разломка). Једнострука прецизност (32 бита) користи 1 бит знака, 8 битова експонента и 23 бита мантисе; двострука прецизност (64 бита), формат иза подразумеваног типа броја у готово свим језицима, користи 1 бит знака, 11 битова експонента и 52 бита мантисе. Овај алат узима било који децимални број који унесете, кодира га у било којој ширини користећи уграђени DataView/ArrayBuffer float енкодер прегледача — исту машинерију на којој се ваш кôд заправо извршава — и боји сваки бит према томе којој области припада.
Само кодирање прати три корака и овај алат пролази кроз све њих, уместо да само приказује коначне битове. Прво, нормализација: број се записује као 1.мантиса × 2^експонент, са тачно једном цифром различитом од нуле испред бинарне тачке (бројеви сувише мали за то добијају субнормални третман, без имплицитне водеће јединице). Друго, померај експонента: пошто поље експонента мора да чува и позитивне и негативне експоненте као неозначени број, фиксни померај (127 за једноструку, 1023 за двоструку прецизност) се додаје пре него што се поље запише у бинарном облику. Треће, разломљена мантиса се проширује бит по бит класичном методом „помножи са два, узми целобројни део као следећи бит, задржи остатак“ — понавља се све док се поље мантисе не попуни, након чега преостали битови одлучују да ли се резултат заокружује навише или наниже (заокруживање ка парном, IEEE-754 подразумевано).
Управо због тога се број тако обичан као 0.1 не чува тачно. У бинарном систему, 0.1 је периодични разломак (0.0001100110011…, бесконачно), тако да ниједна коначна мантиса не може да га држи прецизно — мора да се негде заокружи. Кодирајте 0.1 као 32-битни float и прочитајте битове назад, и не добијате назад 0.1: добијате тачно 0.100000001490116119384765625. Двострука прецизност има 29 битова мантисе више на располагању, па је њена грешка заокруживања далеко мања, али ни она није нула — 0.1 као 64-битни double је тачно 0.1000000000000000055511151231257827021181583404541015625. Овај алат израчунава ту тачну сачувану вредност аритметиком великих целих бројева (без пречица са покретним зарезом), тако да јаз између онога што сте унели и онога што хардвер заправо чува никада није сакривен ни апроксимиран.
Посебне вредности добијају тачне, резервисане битне обрасце уместо нормалног кодирања: нула и негативна нула имају све нуле у битовима експонента и мантисе (разликује се само бит знака), ±Infinity има све јединице у битовима експонента и све нуле у мантиси, а NaN има све јединице у битовима експонента и бар један бит мантисе постављен. Све се овде извршава локално у вашем прегледачу — ништа што откуцате не шаље се нигде — што ово чини безбедним местом за изградњу стварне интуиције о грешкама са покретним зарезом: зашто је `0.1 + 0.2 !== 0.3` у скоро сваком програмском језику, зашто float32 текстуре у графичком коду губе прецизност коју float64 не би, и зашто финансијски кôд генерално треба потпуно да избегава бинарни покретни зарез.