JavaRush /Курси /Java Syntax Zero /Кодування

Кодування

Java Syntax Zero
Рівень 10 , Лекція 2
Відкрита

1. Вісімкове кодування

До речі, про кодування. Як вам відомо, у повсякденному житті ми використовуємо десяткову систему числення: всі наші числа складаються з 10 цифр: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9. Оскільки цифр 10, то й система називається десятковою.

Одначе програмісти — великі вигадники, тому придумали різні кодування з іншою кількістю цифр. Наприклад, 64, 16, 8 і 2.

З кодуванням на основі 8 цифр було найпростіше: вони просто відкинули цифри 8 і 9 і отримали вісімкове кодування (вісімкову систему числення).

І тепер ви можете задавати числові літерали у вісімковій системі. Звичайно, якщо це вам потрібно. Це простіше, ніж здається. Просто слід написати перед числом цифру 0.

Тобто будь-який цілочисловий літерал, який починається з 0, у Java вважається вісімковим.

Приклади:

Код Примітки
int x = 015; 
х дорівнює 13: 1*8+5
int x = 025; 
х дорівнює 21: 2*8+5
int x = 0123; 
х дорівнює 83: 1*64+2*8+3 == 1*82+2*81+3*80
int x = 078;
Не скомпілюється: цифри 8 у вісімковому кодуванні немає.

Навряд чи вам знадобляться вісімкові числа в коді, проте слід знати, що це таке. Адже вам доведеться читати код, написаний іншими. А як ми вже казали, програмісти — великі вигадники.

Ну й пам'ятайте, що не можна просто так писати 0 попереду числа.



2. Двійкове кодування

Двійкове кодування — це ще цікавіше. Якщо у вісімковій системі залишилися тільки цифри 0–7, то у двійковій — тільки цифри 0 і 1. Навіщо ж потрібне таке кодування?

Це пов'язане з будовою комп'ютера. Усе в комп'ютері працює на електриці, і, як виявилося, найефективніший спосіб щось у ньому зберігати й передавати — це використовувати два стани: немає струму (нуль) і є струм (одиниця).

Оце і є основою популярності двійкового кодування.

Проте в Java воно використовується не так вже й часто: Java вважається мовою високого рівня, повністю незалежною від заліза, на якому працює. Справді, чи вам не все одно, в якому вигляді зберігаються й обробляються дані в комп'ютері?

Однак за минулі десятиліття програмісти полюбили двійкове кодування (і кодування на його основі), тому в Java є оператори, які під час роботи враховують двійкову форму числа. Та й точність дійсних чисел залежить від їх подання у двійковому кодуванні.

Взагалі, краще знати про це кодування, ніж не знати.

Так само, як і у випадку з літералами у вісімковій системі, у Java є спосіб задавати літерали у двійковій формі, тобто лише за допомогою символів 0 і 1. Для того щоб Java-компілятор зрозумів, що в коді записано числовий літерал у двійковій формі, а не просто десяткове число, що складається з нулів і одиниць, до всіх двійкових літералів додається префікс 0b (b від слова binary).

Приклади:

Код Примітки
int x = 0b100; 
х дорівнює 4: 1*4+0*2+0
int x = 0b1111; 
х дорівнює 15: 1*8+1*4+1*2+1
int x = 0b1111000111; 
х дорівнює 967: 1*29+1*28+1*27+1*26+0*25+0*24+0*23+1*22+1*2+1;
int x = 0b12000;
Не скомпілюється: цифри 2 у двійковому кодуванні немає.


3. Шістнадцяткове кодування

Крім вісімкової та двійкової системи, літерали можна записувати також у шістнадцятковій системі. Це дуже популярне кодування.

Річ у тім, що, хоча двійковий запис максимально наближений до реального виду зберігання чисел, працювати з таким числом надто складно: мільйон буде містити не 7 цифр, а 20.

Тому програмісти придумали шістнадцяткову систему. Адже 16 — це 24, тому одній шістнадцятковій цифрі відповідає рівно 4 біти. Отже кожні 4 біти тепер можна записати однією шістнадцятковою цифрою.

У шістнадцяткого кодування теж є свій унікальний префікс — 0x. Приклади:

Десяткове число Двійковий запис Шістнадцятковий запис
17 0b00010001 0x11
41 0b00101001 0x29
85 0b01010101 0x55
256 0b100000000 0x100

Гаразд, скажете ви, зрозуміло, як отримати вісімкову систему: ми просто викинули цифри 8 і 9, але де взяти 6 відсутніх цифр для шістнадцяткової системи? Хотілося б їх побачити!

Тут все досить просто. Замість 6 відсутніх цифр взяли 6 перших літер латинського алфавіту: A (10), B (11), C (12), D (13), E (14), F (15).

Приклади:

Шістнадцятковий запис Двійковий запис Десяткове число
0x1 0b00000001 1
0x9 0b00001001 9
0xA 0b00001010 10
0xB 0b00001011 11
0xC 0b00001100 12
0xD 0b00001101 13
0xE 0b00001110 14
0xF 0b00001111 15
0x1F 0b00011111 31
0xAF 0b10101111 175
0xFF 0b11111111 255
0xFFF 0b111111111111 4095


4. Як перевести число з шістнадцяткової системи в іншу

Перевести число з шістнадцяткової системи в десяткову дуже просто. Припустімо, у вас є число 0xAFCF. Скільки це буде в десятковій системі?

По-перше, у нас позиційна система числення, отже, кожен розряд збільшує значення цифри в 16 разів:

A*163 + F*162 + C*161 + F

Символу А відповідає число 10, символу C — число 12, символу F — число 15. Отримуємо:

10*163 + 15*162 + 12*161 + 15

Піднесемо 16 до степеня й отримаємо:

10*4096 + 15*256 + 12*16 + 15

Усе підсумуємо й отримаємо:

45007

Отепер ви знатимете, як це число зберігається в пам'яті:

0xAFCF

А зараз перетворімо його на двійкове число. У двійковій системі воно записується так:

0b1010111111001111

Кожним чотирьом бітам відповідає один символ шістнадцяткового кодування. Дуже зручно. Без усяких множень і піднесення до степеня.


Коментарі (45)
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ
Artem Рівень 32
28 травня 2025
я взагалі не можу врубитися з цими кодами! (
Julia Рівень 21
4 січня 2025
залишу перший комент в 2025 :)
Jaroslav Рівень 48
21 листопада 2024
Задача "Двійково-шістнадцятковий конвертер" прямо круть Вдалося вирішити її більш елегантним способом через цикл замість купи else if Upd: Пізніше вдалося навіть відмовитися від циклу на користь стандартних функцій Java
Sergey Рівень 13
4 жовтня 2024
Оооо, нарешті завдання стали складнішими, і треба трохи подумати, а не просто переписати приклад із лекції. Чим далі в ліс - тим цікавіше :))
gummer Рівень 11
9 березня 2024
Як я вже сердешно втомився витрачати СВІЙ вільний час на те, аби "намахати" ваш автоперевіряльник Я витратив практично годину на те, аби зрозуміти, ЧОМУ моє правильне рішення ваша перевірялка не приймає, і в кінцевому результаті просто копіпастнув ваш код, аби просто отримати темну матерію Далеко не вперше стикаюсь з цією проблемою
Ва Дим Рівень 28
31 березня 2024
Незнаю. нормально він працює.
Alla Voloshchuk Рівень 22
25 січня 2024
Маю зауваження стосовно запропонованого рішення для 4ї задачі: рішення пропонує використовувати if/else умову для кожного варіанта відповіді (binaryNumber.length() % 4). Як на мене таке рішення неоптімальне. Вже була пройдена тема циклів і клас String. То чому не використати набуті знання в рішенні задачі і записати ту ж умову тільки один раз у циклі while, додаючи на кожному кроці циклу ще один "0" на початок рядка? Я використала таке рішення, але система сприйняла його як неправильне.
18 лютого 2024
int a = 4 - binaryNumber.length()%4; // если не хватает 3 символов, то присваиваем это кол-во if (a!=4) { // если делиться на 4 без остатка, то проверяем это for (int b=0; b<a; b++) {binaryNumber=0+binaryNumber;} //Присваиваем 0 спереди в цикле } Вот мое решение по Вашим идеям. У меня работает.
Olexandr Рівень 47
27 листопада 2023
Так, і хочу ще добавити, що задачі не такі вже і складні... Правда четверту задачу я майже наполовину списав, тому що почав писати її через цикли і масив зі значеннями, і наглухо заплутався в перетвореннях int в String i StringBuilder objects... Але я повністю розібрався в способах кодування та які методи застосовуються. Да, заставили нагуглити те, що буде вивчатися буквально через пару лекцій... Але ж і на роботі буде так само...
Олександр Рівень 18
11 листопада 2023
людоньки, зробіть нормальний переклад! або хочаб поясніть яке слово що означає!
Vitalii Рівень 11
18 серпня 2023
дивно... то вони числа в пишуть як інти...то як рядки.... чорт ногу зломить...
Oleksandr Davydiuk Рівень 20
8 липня 2023
Щось я у правильному рішенні не знайшов перевірки: "Якщо вхідний параметр методу toHex(String) містить символи, відмінні від 0 і 1, метод повертає порожній рядок." Скопіював код до ідеї і от що в мене вийшло: Двійкове число 100112010000 дорівнює шістнадцятковому числу 900 А шіснадцяткове число 900 це в двійковому 100100000000