Обычно, когда кто-то говорит, что хочет преобразовать десятичную в BCD, он говорит о более чем одной десятичной цифре.
BCD часто упаковывается в две десятичные цифры на байт (потому что 0..9 помещается в 4 бита, как вы показали), но я думаю, что более естественно использовать массив байтов, по одному на десятичную цифру.
n-разрядное двоичное число без знака будет помещаться в десятичные цифры ceil (n * log_2 (10)) = ceil (n / log10 (2)). Он также будет соответствовать десятичным цифрам ceil (n / 3) = floor ((n + 2) / 3)), так как 2 ^ 3 = 8 меньше 10.
Имея это в виду, вот как я могу получить десятичные цифры без знака int:
#include <algorithm>
#include <vector>
template <class Uint>
std::vector<unsigned char> bcd(Uint x) {
std::vector<unsigned char> ret;
if (x==0) ret.push_back(0);
// skip the above line if you don't mind an empty vector for "0"
while(x>0) {
Uint d=x/10;
ret.push_back(x-(d*10)); // may be faster than x%10
x=d;
}
std::reverse(ret.begin(),ret.end());
// skip the above line if you don't mind that ret[0] is the least significant digit
return ret;
}
Конечно, если вы знаете ширину вашего типа int, вы можете предпочесть массивы фиксированной длины. Также нет никакой причины полностью изменить, если вы помните тот факт, что 0-ая цифра является наименее значимой, и наоборот только на входе / выходе. Сохранение наименее значащей цифры в качестве первой упрощает арифметические операции с цифрами в случае, если вы не используете фиксированное количество цифр.
Если вы хотите представить «0» как одну десятичную цифру «0», а не пустую цифру-строку (любая из них действительна), то вам следует специально проверить x == 0.