JavaRush /Java блог /Random UA /Що всередині числа з плаваючою точкою і як воно працює
Ivan
2 рівень
Харьков

Що всередині числа з плаваючою точкою і як воно працює

Стаття з групи Random UA

Зміст:

Зображення: http://pikabu.ru/

Вступ

У перші ж дні вивчення Java я натрапив на такий цікавий вид примітивів, як числа з плаваючою точкою. Мене одразу зацікавабо їх особливості та, тим більше, спосіб запису у двійковому коді (що взаємопов'язано). На відміну від будь-якого діапазону цілих чисел, навіть у дуже малому проміжку (наприклад від 1 до 2) їх безліч. І маючи кінцевий розмір пам'яті, неможливо висловити цю множину. То як вони виражені в двійковому коді і як працюють? На жаль, пояснення у вікі і досить клювання статті на хабрі тут не дали мені повного розуміння, хоча заклали базу. Усвідомлення прийшло лише після цієї статті-розбору вранці після прочитання.

Екскурс в історію

( Почерпнув з цієї статті на Хабре ) У 60-70 рр., коли комп'ютери були великими, а програми - маленькими, ще не було єдиного стандарту обчислень, як і стандарту виразу самого числа з плаваючою точкою. Кожен комп'ютер робив це по-своєму, і помилки були у кожного свої. Але в середині 70-х компанія Intel вирішила зробити нові процесори з підтримуваною "покращеною" арифметикою і заразом стандартизувати її. Для розробки залучабо професорів Вільяма Кехена та Джона Палмера (ні, не автора книг про пиво). Не обійшлося без драм, але все ж таки новий стандарт був розроблений. Нині цей стандарт називають IEEE754

Формат запису числа з плаваючою точкою

Ще у підручниках шкільного курсу всі стикалися з незвичним способом запису дуже великих чи дуже малих чисел виду 1,2×10 3 чи 1,2E3 , що дорівнює 1,2×1000 = 1200 . Це називається спосіб запису через експоненту. У разі ми маємо справу з виразом числа за такою формулою: N=M×n p , де
  • N = 1200 - отримуване число
  • M = 1,2 - мантіса - дробова частина, без урахування порядків
  • n = 10 - основа порядку. В даному випадку і коли не йдеться про комп'ютери, підставою виступає цифра 10
  • p = 3 - ступінь основи
Досить часто підстава порядку мається на увазі, як і записують лише мантису і значення ступеня підстави, розділяючи їх буквою E . У нашому прикладі я навів рівнозначні записи 1,2×10 3 і 1,2E3 . ступенями двійки, а чи не десятки, тобто. n = 2 , вся струнка формула 1,2E3 ламається і це здорово зламало мені мозок.

Знак та ступінь

І що ми маємо? У результаті ми також маємо двійкове число, яке складається з мантиси — частина, яку зводитимемо в ступінь і саму ступінь. Крім цього, так само як прийнято і у цілих типів, у числах з плаваючою точкою є біт, який визначає знак - буде число позитивним або негативним. Як приклад пропоную розглянути тип float, що складається з 32 біт. З числами подвійної точності doubleлогіка така сама, тільки вдвічі більше біт. З 32 біт, перший старший відводиться на знак, наступні 8 біт відводяться на експоненту - ступінь, на яку зводитимемо мантису, а решта 23 біти - на мантису. Для демонстрації давайте подивимося приклад: Що всередині числа з плаваючою точкою і як воно працює - 1З першим бітом все дуже просто. Якщо значення першого біта 0, Те число, яке ми отримаємо буде позитивним . Якщо біт дорівнює 1 , то число буде негативним . Наступний блок із 8 біт - блок з експонентою. Експонента записується як звичайне восьмибітне число, а щоб отримати необхідну ступінь нам потрібно від отриманого числа відняти 127 У нашому випадку вісім біт експоненти - це 10000001 . Це відповідає числу 129 . Якщо є питання, як це порахувати, то на зображенні швидка відповідь. Розгорнутий можна отримати на будь-якому курсі булевої алгебри. Що всередині числа з плаваючою точкою і як воно працює - 21×2 7 + 0×2 6 + 0×2 5 + 0×2 4 + 0×2 3+ 0×2 2 + 0×2 1 + 1×2 0 = 1×128 + 1×1 = 128+1=129 Не складно порахувати, що максимальне число, яке ми можемо отримати з цих 8 біт 11111111 2 = 255 10 (підрядкові 2 і 10 означають двійкову та десятирічну системи обчислення) Однак, якщо використовувати тільки позитивні значення ступеня ( від 0 і до 255 ), то отримані числа будуть мати багато чисел перед комою, але не після? Щоб отримувати негативні значення ступеня, із сформованої експоненти необхідно віднімати 127 . Таким чином, діапазон ступенів буде від -127 до 128. Якщо використати наш приклад, то необхідний ступінь буде 129-127 = 2 . Поки що запам'ятовуємо це число.

Мантіса

Тепер про мантис. Вона складається з 23 біт, проте спочатку завжди мається на увазі ще одна одиниця, на яку біти не виділяються. Це зроблено з метою доцільності та економії. Те саме число можна виражати різними ступенями, додаючи до мантиси нулі перед або після коми. Найпростіше це зрозуміти з десятковою експонентою: 120 000 = 1,2 10 5 = 0,12 10 6 = 0,012 10 7 = 0,0012 10 8 і т.д. Однак, ввівши фіксоване число в голові мантиси, ми щоразу отримуватимемо нові числа. Приймемо як даність, що перед нашими 23 бітами буде ще одна з одиницею. Зазвичай цей біт від інших оброблять точкою, яка, втім, нічого не означає. Просто так зручніше 1 . 11100000000000000000000 Що всередині числа з плаваючою точкою і як воно працює - 3Тепер отриману мантису потрібно зводити на ступінь зліва направо, зменшуючи з кожним кроком ступінь на одну. Стартуємо зі значення ступеня, який ми отримали в результаті обчислення, тобто 2 (Я спеціально вибрав простий приклад, щоб не писати кожне значення ступеня двійки та в наведеній таблиці не обчислював їх, коли відповідний біт дорівнює нулю) Що всередині числа з плаваючою точкою і як воно працює - 41×2 2 + 1×2 1 + 1×2 0 + 1×2 -1 = 1×4 + 1×2 + 1×1 + 1×0,5 = 4+2+1+0,5 = 7,5 та отримали результат 7,5 , правильність можна перевірити, наприклад, за цим посиланням

Підсумки

Стандартне число з плаваючою точкою типу floatскладається з 32 біт, перший біт – знак (+ або -), наступні вісім – експонента, наступні 23 – мантиса. По знаку – якщо біт 0 – число позитивне. Якщо біт 1 – негативне. За експонентом — побітно переводимо в десяткове число (перший ліворуч біт — 128 , другий — 64 , третій — 32 , четвертий — 16 , п'ятий — 8 , шостий — 4 , сьомий — 2 , восьмий — 1 ), з отриманого отримуємо ступінь з якого стартуватимемо. По мантисі- До наявних 23 біт спереду дописуємо ще один біт зі значенням 1 і з нього починаємо зводити в отриману нами ступінь, з кожним наступним бітом декрементуючи цей ступінь. That's all folks, kids! Що всередині числа з плаваючою точкою і як воно працює - 5PS: У вигляді домашнього завдання, використовуючи цю статтю, залиште в коментарях свої версії, чому при великій кількості арифметичних операцій з числами з точкою, що плаває, виникають помилки точності
Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ