Как получить число в десятичной позиции - PullRequest
0 голосов
/ 14 октября 2019

Я работаю над кодом C для микроконтроллера для форматирования данных GPS в одно 8-байтовое сообщение.

Мне нужно быстро его кодировать и декодировать. Я хочу сделать это так: Int32 - от -2147483648 до 2147483647.

Мы можем закодировать широту: от -89599999 до -89599999, что такое позиция от 89 ° 59,9999 'ю.ш. до 90 ° 59,9999' N
для долготы: От -179599999 до 179599999, что такое положение 179 ° 59,9999 'W до 179 ° 59,9999' E

4 байта для широты и 4 байта для долготы. Всего 8 байтов CAN сообщения.

Как это сделать без умножения и деления? Есть ли какой-нибудь способ сместить или получить число в нужной десятичной позиции.

Я хочу кодировать следующим образом:

unsigned int32 charToInt32(char val)
{
   unsigned int32 valOut;
   valOut = val - '0';
   return valOut;
}

int32 GPS_codeLongitude(char *tab, char dir)
{
   int32 deg = 0;  

   deg  = charToInt32(tab[0]) * 1000000000; 
   deg += charToInt32(tab[1]) * 100000000;
   deg += charToInt32(tab[2]) * 10000000;
   deg += charToInt32(tab[3]) * 1000000;
   deg += charToInt32(tab[4]) * 100000;
   deg += charToInt32(tab[6]) * 10000;
   deg += charToInt32(tab[7]) * 1000;
   deg += charToInt32(tab[8]) * 100;
   deg += charToInt32(tab[9]) * 10; 
   deg += charToInt32(tab[10]); 

   if(dir == 'S') deg = -deg;
   return deg;
}

int32 GPS_codeLatitude(char *tab, char dir)
{
   int32 deg = 0;  

   deg  = charToInt32(tab[0]) * 100000000; 
   deg += charToInt32(tab[1]) * 10000000;
   deg += charToInt32(tab[2]) * 1000000;
   deg += charToInt32(tab[3]) * 100000;
   deg += charToInt32(tab[5]) * 10000;
   deg += charToInt32(tab[6]) * 1000;
   deg += charToInt32(tab[7]) * 100;
   deg += charToInt32(tab[8]) * 10;
   deg += charToInt32(tab[9]) ; 

   if(dir == 'W') deg = -deg;
   return deg;
}

Ответы [ 2 ]

0 голосов
/ 14 октября 2019

Пример с использованием atoi и битовых операций:

#define CanMessageLen 8
#define NIBBLELEN 4
typedef char CanMessage[CanMessageLen];


typedef enum
{
    NORTH,
    SOUTH
} LatitudeDir;

typedef enum
{
    EAST,
    WEST
} LongitudeDir;

CanMessage* CoordinatesToMsg(char* latitude, LatitudeDir latitudedir, char* longitude , LongitudeDir longitudedir)
{
    CanMessage canMessage = { 0 };
    __int32 latitudeInt=0;
    __int32 longitudeInt = 0;

    latitudeInt = atoi(latitude);
    longitudeInt = atoi(longitude);

    if (latitudedir == SOUTH)
    {
        latitudeInt = -latitudeInt;
    }
    if (longitudedir == WEST)
    {
        longitudeInt = -longitudeInt;
    }

    for (size_t i = 0; i < 4; i++)
    {
        canMessage[i] = (char)(latitudeInt >> (8 * i) & 0xff);
        canMessage[i+4] = (char)(longitudeInt >> (8 * i) & 0xff);
    }
    return canMessage;
}

Пример -80 ° 55,9999 '150 ° 55,9999

char latitude[10] = { '0','8','0','5','5','9','9','9','9','\0'}; 
char longitude[10] = { '1','5','0','5','5','9','9','9','9','\0'}; 

CoordinatesToMsg(latitude, SOUTH,longitude, EAST);

Вывод [0x81,0xC0,0x32, 0xFB, 0xFF, 0x5C, 0xF9, 0x08] // Little Endian

0 голосов
/ 14 октября 2019

Вот один из подходов:

static void int2str(char *buf, unsigned int x)
{
    const unsigned int divs[] = { 1000000000, 100000000, 10000000, 1000000,
     100000, 10000, 1000, 100, 10 };
    for (int i = 0; i < sizeof divs / sizeof *divs; ++i)
    {
        unsigned char digit = '0';
        while (x >= divs[i])
        {
            ++digit;
            x -= divs[i];
        }
        *buf++ = digit;
    }
    *buf++ = '0' + x;
    *buf = '\0';
}

Это приведет к нулю слева, но обычно это нормально для разговоров между компьютерами. Кроме того, он не использует умножения или деления, но он очень итеративный, поэтому не совсем быстрый ...

...