Как преобразовать 24-битное целое число в 3-байтовый массив?

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

Мне нужно скрыть целое число, чтобы оно поместилось в 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, что является обратным преобразованием, которое мне также нужно сделать для отправки данных.

Любая помощь очень ценится!


person loststudent    schedule 07.12.2010    source источник


Ответы (3)


Вы можете использовать союз:

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).

person Ferruccio    schedule 07.12.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];

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

person Jim Mischel    schedule 07.12.2010
comment
Это работает нормально, пока число ‹ 255. Насколько я понимаю, это максимальное значение для 24-битного целого числа? - person loststudent; 08.12.2010
comment
@loststudent: Нет, максимальное значение для 24-битного целого числа без знака составляет (2 ^ 24) -1 или 16 777 216. Диапазон 24-битного целого числа со знаком составляет от -8 388 608 до 8 388 607. Какая часть не работает? - person Jim Mischel; 08.12.2010
comment
Просто когда int превышает 255 - person loststudent; 08.12.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

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

person zoul    schedule 07.12.2010