У повсякденному житті ми маємо справу зі звичайними числами від 0 до 9, з яких складаємо більш значущі числа - двозначні, тризначні, чотирьох-, п'яти-, шести-, восьми-, двадцяти-і т.д. -значний. Ці числа представлені в так званому, десятковому поданні. Чому так? Тому, що для подання будь-якого числа використовується 10 цифр - від 0 до 9. Ми з дитинства знаємо цей формат, але не замислюємося про те, що він саме десятковий. Нам зручніше працювати з ним.
Однак, ми займаємося програмуванням мікроконтролерів, з якими набагато зручніше буває працювати, використовуючи інші формати числа - двійковий і шістнадцятковий. Зупинимося на них детальніше.
Як ви вже, напевно, здогадалися, їх назви утворюються від кількості цифр, використовуваних для подання цих чисел. Правильно! Двійковий формат має на увазі оперування всього двома цифрами - нулем і одиницею.
Цей формат ми зазвичай використовуємо при роботі з портами і регістрами мікроконтролера, так як цей метод уявлення числа для них - найзручніший - ми відразу бачимо який біт порту або регістра встановлений, а який скинутий. Регістри і порти зазвичай восьмирозрядні. Числа в довічним форматі теж мають довжину 8 розрядів, але іноді незначні старші нулі не заносяться.
Щоб зрозуміти, як утворюється двійковечисло розберемо наступний приклад:
Візьмемо будь-яке число. Щоб не ускладнювати, для початку, нехай це буде число 183. В довічним форматі це ж число буде виглядати як% 10110111
Знак "%" використовується для позначення двійкового числа.
Чому саме так, запитаєте ви? Тому, що в основі створення двійкового числа лежить двійка, зведена в ступінь номера позиції нуля або одиниці з двійкового числа. Можливо, написано страшно, але насправді, нічого складного. Всі вміють зводити число в ступінь, я так думаю. Формула перетворення двійкового числа в десяткове наступна:
Тобто, множення на 0 дає нуль, а множення на одиницю двійки в ступені номера позиції дає певне число. Складаємо їх і отримуємо цілий результат. Зворотне перетворення здійснюється діленням на 2.
Зазвичай шестнадцатиричное число записують у вигляді двох символів.
Повернемося до наших баранів, точніше, до числа, взятому для прикладу - 183
Як ми вже з'ясували, в двійковому форматі воно виглядає як% 10110111
Тепер, щоб отримати його у вигляді 16-ричного числа, ми знайдемо з таблиці старший напівбайт (% 1011) цього числа і молодший напівбайт (% 0111). І складемо число в 16-річному форматі - $ B7
Все просто! За допомогою цього формату зручніше записувати великі числа, так як вони займають менше місця. При програмуванні мікроконтролера ви завантажуєте програму саме в такому форматі. Він називається ще HEX-файлом.
Отже, ми познайомилися з основними форматами представлення даних - системами числення. На практиці ж бувають випадки, коли потрібні перетворення чисел в особливий формат. Він начебто і той, та не зовсім. Тобто представляється він або в двійковій, або в десяткового, або в шістнадцятковій формі, але має дещо інше смислове навантаження. Йдеться про двійковій-десятковому форматі або, по-іншому - BCD (binary-coded decimal) формат. У цій формі кожен десятковий (!) Розряд записується у вигляді довічного полубайта. Ми знаємо, що напівбайт може приймати максимум 16 значень. А нам багато і не потрібно. Нам потрібно всього 10 значень - від 0 до 9.
Виходячи з усього вищесказаного, маємо:
Число 183 в двійковій-десятковому форматі буде виглядати як
Якщо тепер перетворити отримане число назад в десятковий формат, то ми отримаємо зовсім інший результат
На практиці нам звичайно потрібні числа з двома значущими десятковими розрядами - зазвичай це годинник реального часу. Там ми оперуємо з цифрами від 0 до 59. Тобто - два значущих розряду. Ось від цього прикладу ми і будемо відштовхуватися.
Не будемо прив'язуватися до певного синтаксису, оскільки операції будуть однакові для будь-якого Basic-компілятора.
Отже, нехай у нас є чотири змінні:
BCDOUT - змінна типу Byte для зберігання результату перетворення з двійкового числа в формат BCD
BCDIN - змінна типу Byte, що містить значення, яке Ви бажаєте перевести з BCD в двійковий формат (або інший) (відразу запам'ятаємо, що це число, записане у вигляді десяткового числа, являє собою число, записане в двійковій-десятковому форматі)
BININ - змінна типу Byte, що містить двійкове значення для перетворення в BCD (ми будемо записувати його в десятковому вигляді для зручності)
BINOUT - змінна типу Byte, яка буде містити результат перетворення з BCD в двійковий формат
Змінним BININ і BCDIN дамо значення (ну, припустимо, ми прийняли по USART два ці числа):
BCDIN = 47 'Нехай 47 хвилин в двійковій-десятковому форматі
BININ = 23 'Нехай це буде 23 години
- Займемося перетворенням двійковій-десяткового формату в двійковий:
Щоб краще зрозуміти процес представимо вихідні числа в двійковому форматі. Зверніть на підсвічування напівбайтів, щоб зрозуміти, що з ними відбувається
BINOUT = BCDIN >> 4 'Зрушуємо старший напівбайт на місце молодшого і отримуємо в BCDOUT число 2 (% 00000010). Множимо його на 10. оскільки ми здобуваємо старший напівбайт, що містить десятки числа. BINOUT = BINOUT * 10 'Тепер ми маємо число 20 (% 00010100) Тепер витягаємо молодший напівбайт. Це робиться просто: виконується побітове логічне І з числом% 00001111 (або $ 0F). Побітове І з нульовим значенням поверне 0, а з одиницею - то, що було до цієї логічної операції. BCDIN = BCDIN $ 0F 'Отримаємо число% 00001111 (або 15 по іншому) - Ми прирівняли нулю старший напівбайт змінної BCDIN Тепер складемо два отриманих числа:
Всю операцію можна записати в один рядок:
BINOUT = ((BCDIN >> 4) * 10) + (BCDIN $ 0F). але краще розбити її на кілька рядків, оскільки в цьому виді операція займає більше програмної пам'яті
- Тепер зробимо перетворення з двійкового числа в двійковій-десятковий.
Так як кожен напівбайт двійковій-десяткового формату містить одну цифру, і ми знаємо, що наше двійковечисло - двозначне, то нам потрібно витягти кількість десяток і кількість одиниць, а потім скласти з них BCD-число.
Щоб витягти десятки ми просто ділимо двійковечисло на 10
Отримуємо число 2. так як молодша 3 відкидається при розподілі (ми маємо справу з целочисленной математикою).
Тепер наше число виглядає як% 00000010.
Але двійка у нас - це кількість десяток! Значить нам потрібно зрушити його в старший напівбайт:
Тепер, щоб отримати молодше число (число одиниць - 3) нам потрібно виконати операцію, звану Модуль в Picbasic. Ця операція повертає залишок від ділення, але не той, що ми звикли думати. До цього ми ділили число 23 на 10 і отримали 2. а тепер же ми отримаємо число 3 - то що залишилося від звичайного поділу на 10
Тепер сформуємо двійковій-десяткове число:
BCDOUT = BCDOUT + BININ = 32 + 3 = 35 - це число в двійковій-десятковому поданні - це не одне і те ж, що вийшло в верхньому прикладі.
Знову ж таки, все, що написано вище, можна вмістити в один рядок.
BCDOUT = ((BININ / 10) <<4 ) + ( BININ // 10 )
Але практика показує, що якщо розбити цей вислів на окремі, короткі вирази, то вони займуть набагато менше програмної пам'яті.
Ще хочеться особливо відзначити, що двійковій-десятковий формат - це не система обчислення. Це формат подання числа. Число в цьому форматі може бути записано як в двійковій, так і в шістнадцятковій, так і в десятковій системі. Просто потрібно пам'ятати, що це число означає і в який воно формі записано.