JavaRush /Java блог /Random /Двоично-десятичный код (англ. binary-coded decimal) или B...
Николай Данилов
36 уровень
Москва

Двоично-десятичный код (англ. binary-coded decimal) или BCD

Статья из группы Random
Всем добрый день! Говорю сразу, статья не претендует на научную статью, я не уверен в оптимальности решения этой задачи, данная статья больше для джунов которые впервые столкнутся с bcd форматом на работе. Сам по себе bcd формат уже мало где используется и вероятность того, что java разработчик столкнется с данным форматом близится к нулю, однако я столкнулся у себя на работе из-за использования в нашей системе древнего оборудования. Также попытаюсь объяснить что такое bcd формат: Это запись числа в десятичной системе счисления где каждый символ занимает ровно 4 бита. Таким образом получается, что в 1 байт можно записать число от 0 до 99 и все. Теперь поподробнее, допустим у нас есть число 291 в десятичной системе счисления, в двоичной системе счисления оно записывается как 0001 0010 0011, а в шестнадцатеричной системе счисления оно записывается как 123. Теперь главное не запутаться, чтобы записать число 123 в десятичной системе счисления нужно записать 0001 0010 0011. То есть если мы в памяти имеем число 291 то в bcd формате оно будет равно 123. Я покажу еще один пример: допустим у нас есть число 6842 5898 которое надо записать в память в bcd формате (зачем это может понадобиться не знаю, я показываю этот пример для наглядности). Мы раскладываем данное число на цифры 6, 8, 4, 2, 5, 8, 9, 8. Теперь запишем каждую цифру в двоичной системе счисления по отдельности: 6 = 110, 8 = 1000, 4 = 0100, 2 = 10, 5 = 0101, 8 = 1000, 9 = 1001, 8 = 1000. Теперь важный момент, в bcd Формате число записывается в 4 бита, значит во всех значениях должно быть 4 символа всегда, итого получаем: 6 = 0110, 8 = 1000, 4 = 0100, 2 = 0010, 5 = 0101, 8 = 1000, 9 = 1001, 8 = 1000. У нас поменялось значение цифры 6 и цифры 2, теперь нам надо весь этот двоичный код объединить в один: 0110 1000 0100 0010 0101 1000 1001 1000 Данное значение в обычном формате будет равно 1 749 178 520, но в bcd Формате оно равно 6842 5898. Также можно быстро переводить формат записи используя шестнадцатеричную систему счисления, просто переводим наше число из двоичной системы счисления в шестнадцатеричную систему счисления: 0110 1000 0100 0010 0101 1000 1001 1000 в двоичной системе счисления = 6842 5898 в шестнадцатеричной системе счисления. Как Вы уже скорее всего догадались если в 4 битах будет записано значение больше чем 1001 то это будет ошибкой записи. Хотя в телефонах все значения больше 1001 используют для записи символов. Мой коллега на работе переводил числа из bcd формата используя String, сначала просто в String записывал значение используя метод toHexString() класса Integer, а потом с помощью метода parseInt() того-же класса Integer переводил String в int. Мне данный способ не понравился совсем, это вылилось в следующий код:

public static int BCDToInt(int bcd, int bitUnits, int index) {
        int result = 0;
        if (bcd == 0) return result;

        int number = bcd >> index;
        result = result + ((number & 0xf) * bitUnits);

        return result + BCDToInt(number, bitUnits * 10, index + 4);
    }
    public static int BCDToInt(int bcd) {
        return BCDToInt(bcd, 1, 0);
    }
Однако в этом решении есть один момент, bcd формат записывает как правило наоборот, то есть если у меня число начинается с младшего байта, то обычно оно записывается со старшего байта. В моей программе данный нюанс обрабатывается сильно до, по этому мое решение именно такое. Вроде все, что хотел сказать, сказал. Если есть вопросы или ошибки пишите мне, с радостью поправлю или разжую. Очень надеюсь, что данная статья кому-нибудь будет полезна.
Комментарии (2)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
hidden #2766453 Уровень 3
9 февраля 2023
Вроде всё понятно, но не понятно где это применять :)