неправильное преобразование двухбайтового массива в короткий в c - PullRequest
0 голосов
/ 22 марта 2019

Я пытаюсь преобразовать массив из 2 байтов в беззнаковое короткое число.

это код для конвертации:

short bytesToShort(char* bytesArr)
{
    short result =(short)((bytesArr[1] << 8)|bytesArr[0]);
    return result;
}

У меня есть InputFile, который хранит байты, и я читаю его байты с помощью цикла (2 байта каждый раз) и сохраняю его в char N [] arr следующим образом:

char N[3];
N[2]='\0';

while(fread(N,1,2,inputFile)==2)

когда (hex) значение N [0] = 0, вычисление является правильным, в противном случае оно неверно, например:

0x62 (N [0] = 0x0, N [1] = 0x62) вернет 98 (в коротком значении), , но 0x166 в шестнадцатеричном формате (N [0] = 0x6, N [1] = 0x16) вернет 5638 (короткое значение).

Ответы [ 2 ]

3 голосов
/ 22 марта 2019

Во-первых, обычно лучше использовать тип unsigned char для байтов необработанных двоичных данных, потому что это правильно выражает семантику того, с чем вы работаете. Тип char, хотя он может и используется слишком часто в качестве синонима "байта", лучше зарезервирован для данных, которые на самом деле носят символический характер.

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

С учетом сказанного ваша основная проблема выглядит простой. Вы сказали

166 в шестнадцатеричном формате (N [0] = 6, N [1] = 16) вернет 5638 (в коротком значении).

, но 0x166, упакованный в двухбайтовый массив с прямым порядком байтов, будет (N [0] = 0x66, N [1] = 0x1). То, что вы написали, будет соответствовать 0x1606, что в действительности соответствует десятичному 5638.

1 голос
/ 22 марта 2019

Проблема заключается в расширении знака из-за использования char. Вместо этого следует использовать unsigned char:

#include <stdio.h>

short bytesToShort(unsigned char* bytesArr)
{
    short result = (short)((bytesArr[1] << 8) | bytesArr[0]);
    return result;
}

int main()
{
    printf("%04x\n", bytesToShort("\x00\x11")); // expect 0x1100
    printf("%04x\n", bytesToShort("\x55\x11")); // expect 0x1155
    printf("%04x\n", bytesToShort("\xcc\xdd")); // expect 0xddcc

    return 0;
}

Примечание : проблема вКод не тот, который представлен ОП.Проблема в возвращении неверного результата при вводе "\xcc\xdd".Он выдаст 0xffcc там, где он должен быть 0xddcc

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...