Как преобразовать 24-разрядное целое число в 3-байтовый массив? - PullRequest
2 голосов
/ 07 декабря 2010

Эй, я совершенно не в себе, и мой мозг начинает болеть ..: (

Мне нужно скрыть целое число, чтобы оно поместилось в 3-х байтовом массиве (это 24-битное целое число?), А затем снова отправлять / получать это число из потока байтов через сокет

У меня есть:

NSMutableData* data = [NSMutableData data];

 int msg = 125;

 const void *bytes[3];

 bytes[0] = msg;
 bytes[1] = msg >> 8;
 bytes[2] = msg >> 16;

 [data appendBytes:bytes length:3];

 NSLog(@"rtn: %d", [[[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding] intValue]);

 //log brings back 0

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

Любая помощь с благодарностью!

Ответы [ 3 ]

6 голосов
/ 07 декабря 2010

Предположим, у вас есть 32-разрядное целое число. Вы хотите, чтобы младшие 24 бита были помещены в байтовый массив:

int msg = 125;
byte* bytes = // allocated some way

// Shift each byte into the low-order position and mask it off
bytes[0] = msg & 0xff;
bytes[1] = (msg >> 8) & 0xff;
bytes[2] = (msg >> 16) & 0xff;

Чтобы преобразовать 3 байта обратно в целое число:

// Shift each byte to its proper position and OR it into the integer.
int msg = ((int)bytes[2]) << 16;
msg |= ((int)bytes[1]) << 8;
msg |= bytes[0];

И, да, я полностью осознаю, что есть более оптимальные способы сделать это. Цель вышеизложенного - ясность.

1 голос
/ 07 декабря 2010

Вы можете использовать объединение:

union convert {
    int i;
    unsigned char c[3];
};

для преобразования из int в байты:

union convert cvt;
cvt.i = ...
// now you can use cvt.c[0], cvt.c[1] & cvt.c[2]

для преобразования из байтов в int:

union convert cvt;
cvt.i = 0; // to clear the high byte
cvt.c[0] = ...
cvt.c[1] = ...
cvt.c[2] = ...
// now you can use cvt.i

Примечание: использование объединений таким способом зависит от порядка байтов процессора.Пример, который я привел, будет работать в системе с прямым порядком байтов (например, x86).

0 голосов
/ 07 декабря 2010

Как насчет хитрости указателя?

int foo = 1 + 2*256 + 3*65536;
const char *bytes = (const char*) &foo;
printf("%i %i %i\n", bytes[0], bytes[1], bytes[2]); // 1 2 3

Вероятно, есть вещи, о которых нужно позаботиться, если вы собираетесь использовать это в рабочем коде, но основная идея - вменяемая.

...