Расшифровка двоично-десятичном (BCD), которые значение


У меня есть 3 вопроса, все они касаются двоично-десятичном (BCD), которые преобразования. Мои фрагменты кодирования, как указано ниже. Но мне не нравится мой алгоритм, потому что это занимает слишком много времени при работе с кучей данных.

Любые предложения, чтобы улучшить производительность? Пожалуйста, покажите мне эффективный и быстрый способ сделать это?

  1. Значение выражается с 4-бит двоичный код десятичные числа (BCD), которое было первоначально сохранено в буфере символов (например, указал на указатель константный беззнаковый тип char *).

    BCD*2; 1001 0111 0110 0101=9765
    "9"  "7"  "6"  "5"
    
    unsigned int BCDn( unsigned int n, const unsigned char * data )
    {
        unsigned int uResult = 0;
        unsigned char ucTmp;
        int iTmp1,iTmp2;
    
        for (unsigned int i=0;i<n;i++)
        {
            ucTmp = data[i];
            iTmp1 = (ucTmp & 0xf0) >> 4;
            iTmp2 = ucTmp & 0x0f;
            uResult += (iTmp1*10+iTmp2) * static_cast<unsigned int>(pow(100.0,static_cast<int>(n-1-i)));
        }
    
        return uResult; 
    }
    
  2. Значение выражается Н двоичное целое число (N* 8 бит). Первым битом (MSB) определяет знаком двоичное целое число; "0" означает, что это положительное целое число, а "1" на минус один. В случае отрицательного числа, остальные биты показывают состав числа, которое добавляется 1.

             MSB          LSB
        I*2; 00101101 1001100=19999
        I*2; 10101101 10011100=(-1)*(0101101 10011100 
                              =(-1)*(1010010 01100100) (after complement)
                              =-21092
    
    int SINTn(unsigned int n, const unsigned char *data)
    {   
        int nResult;
        bool bNegative = false;
    
        if ((data[0] & 0x80)!= 0)
            isNegative = true;
    
        nResult = data[0] & 0x7f;
    
        for (unsigned int i=1;i<n;i++)
            nResult = nResult * 0x100 + data[i];
    
        if (bNegative) 
            nResult = nResult - static_cast<int>(pow(2.0,static_cast<int>(n*8-1)));
    
        return nResult
    }
    
    unsigned int UINTn(unsigned int n, const unsigned char *data)
    {   
        unsigned int uResult = 0;
    
        for (unsigned int i=0;i<n;i++)
            uResult = uResult * 0x100 + data[i];
    
        return uResult;
    }
    
  3. Р*н.м

    Значение выражается в n-байт (н*8 бит) двоичное число, первый битом (MSB) определяет знак его; "0" означает позитивные и "1" означает отрицательный. Число M означает что двоичное число должно быть умножено на 10-м, чтобы получить значение.

               MSB                        LSB
        R*4.0: 00000000 00000000 00000111 10110101=1973
        R*4.2: 00000000 00000000 00000111 10110101=1973*10-2=19.73
        R*4.5: 10000000 00000000 00000111 10110101=-1973*10-5= -0.01973
        R*2.0: 10101101 10011100 =-11676
    
    double REALnm(unsigned int n, unsigned int m, const unsigned char * data)
    {   
        double dResult;
        bool bNegative = false;
    
        if ((data[0] & 0x80)!= 0)
            isNegative = true;
    
        dResult = data[0] & 0x7f;
    
        for (unsigned int i=1;i<n;i++)
            dResult = dResult * 0x100 + data[i];
    
        if (bNegative) dResult *= -1.0;
    
        dResult *= pow(10.0, (-1.0) * m);
    
        return dResult;
    }
    


Комментарии
2 ответа

она может быть много проще...

#include "seatest.h"

unsigned int BCDn( unsigned int n, const unsigned char * data )
{
unsigned int uResult = 0;
unsigned int i;

for (i=0;i<n;i++)
{
uResult = (uResult * 100) + ((data[i] >> 4) * 10 ) + ( data[i] & 0x0F);
}

return uResult;
}
void test_max_bcd_convert()
{
unsigned char bcd_data[]= { 0x97, 0x65 };

assert_int_equal(9765, BCDn(2, bcd_data));

}

void test_fixture_bcd( void )
{
test_fixture_start();
run_test(test_max_bcd_convert);
test_fixture_end();
}

void all_tests( void )
{
test_fixture_bcd();
}

int main( int argc, char** argv )
{
run_tests(all_tests);
return 0;
}

4
ответ дан 26 мая 2011 в 09:05 Источник Поделиться

Вы можете избежать военнопленных, делая что-то вроде этого:

unsigned int BCDn( unsigned int n, const unsigned char * data )
{
unsigned int uResult = 0;
unsigned char ucTmp;
int iTmp1,iTmp2;

unsigned int factor = 1;
for (unsigned int i=n-1;i>=0;i--)
{
ucTmp = data[i];
iTmp1 = (ucTmp & 0xf0) >> 4;
iTmp2 = ucTmp & 0x0f;
uResult += (iTmp1*10+iTmp2) * factor;
factor *= 100;
}

return uResult;
}

В принципе считать в обратном порядке, и тогда нужно только умножить коэффициент каждый раз. Подобные выходки должны работать для других методов.

2
ответ дан 26 мая 2011 в 02:05 Источник Поделиться