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 — пятнадцать. Получаем:

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

Возведем 16 в степень и получим:

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

Просуммируем все и получим:

45007

Зато теперь вы знаете, как это число хранится в памяти:

0xAFCF

А теперь преобразуем его в двоичную кодировку. В двоичной это будет:

0b1010111111001111

Каждым четырём битам соответствует ровно один символ шестнадцатеричной кодировки. Очень удобно. Без всяких умножений и возведений в степень.