Преобразование из целого числа в BCD

Я хочу преобразовать целое число (максимальное значение которого может достигать 99999999) в BCD и сохранить в массив из 4 символов. Как, например: Ввод: 12345 (Целое число) Вывод должен быть = "00012345" в BCD, который хранится в массиве из 4 символов. Здесь 0x00 0x01 0x23 0x45 хранится в формате BCD. Я пробовал следующим образом, но не работал

int decNum = 12345;
long aux;
aux = (long)decNum;
cout<<" aux = "<<aux<<endl;

char* str = (char*)& aux;
char output[4];
int len = 0;
int i = 3;
while (len < 8)
{
cout <<"str: " << len << " " << (int)str[len] << endl;
unsigned char temp = str[len]%10;
len++;
cout <<"str: " << len << " " << (int)str[len] << endl;
output[i] = ((str[len]) << 4) | temp;
i--;
len++;
}

Любая помощь будет оценена


person facebook-100001358991487    schedule 27.11.2012    source источник
comment
Я добавил набор кода для преобразования целых чисел без знака в BCD по адресу: stackoverflow.com/questions/1408361/   -  person Andrew Stern    schedule 13.01.2017


Ответы (3)


str на самом деле указывает на длинный (вероятно, 4 байта), но итерация обращается к 8 байтам. Операция str[len]%10 выглядит так, как будто вы ожидаете цифры, но там только двоичные данные. Кроме того, я подозреваю, что i становится отрицательным.

person zkar    schedule 27.11.2012

Во-первых, не используйте приведения в стиле C (например, (long)a или (char*)). Они плохо пахнут. Вместо этого изучите и используйте приведения типов в стиле C++ (например, static_cast<long>(a)), потому что они указывают, где вы делаете опасные вещи, а не просто молча работаете и вызывает неопределенное поведение.

char* str = (char*)& aux; дает вам указатель на байты aux — на самом деле это char* str = reinterpret_cast<char*>(&aux);. Он не дает вам традиционную строку с цифрами. sizeof(char) равно 1, sizeof(long) почти наверняка равно 4, поэтому в вашей переменной aux всего 4 допустимых байта. Вы продолжаете пытаться прочитать 8 из них.

Я сомневаюсь, что это делает то, что вы хотите. Если вы хотите вывести число в строку, вам придется запустить реальный код, а не просто переинтерпретировать биты в памяти.

std::string s; std::stringstream ss; ss << aux; ss >> s; создаст std::string с базовыми 10 цифрами aux в нем.

Затем вы можете посмотреть на символы в s, чтобы построить свой BCD.

Это далеко не самый быстрый метод, но, по крайней мере, он близок к вашему первоначальному подходу.

person Yakk - Adam Nevraumont    schedule 27.11.2012

Прежде всего, извините за код C, я был обманут, так как это началось как вопросы C, перенос на C++ не должен быть таким уж большим делом.

Если вы действительно хотите, чтобы он был в массиве символов, я сделаю что-то вроде следующего кода, я считаю полезным оставить результат в формате с прямым порядком байтов, поэтому я могу просто привести его к int для распечатки, однако это не так строго необходимо:

#include <stdio.h>

typedef struct
{
    char value[4];
} BCD_Number;

BCD_Number bin2bcd(int bin_number);

int main(int args, char **argv)
{
    BCD_Number bcd_result;

    bcd_result = bin2bcd(12345678);

    /* Assuming an int is 4 bytes */
    printf("result=0x%08x\n", *((int *)bcd_result.value));

}

BCD_Number bin2bcd(int bin_number)
{
    BCD_Number bcd_number;  

    for(int i = 0; i < sizeof(bcd_number.value); i++)
    {
        bcd_number.value[i] = bin_number % 10;
        bin_number /= 10;
        bcd_number.value[i] |= bin_number % 10 << 4;
        bin_number /= 10;
    }

    return bcd_number;
}
person Julio Moreno    schedule 27.11.2012