2010-08-05 3 views
1

У меня есть целое число val.массив байтов на короткий

data[0]=0; 
data[1]=0; 
data[2]=(val>>8)%256; 
data[3]=val%256; 

Как сделать oposite? Как взять int из массива char?

+0

использовать uint8_t, определенный в 'stdint.h', если вы хотите хранить данные побайтно, а не символы. – KillianDS

+0

Вместо использования оператора modulo вы можете просто скрыть бит, используя 'val & 0xFF'. Это делает ваше намерение более ясным и (на большинстве архитектур процессоров) более эффективным. – bta

+1

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

ответ

4

Для неподписанных данных:

val = (data[2] << 8) | data[3]; 

Для подписанных данных:

val = ((data[2] << 8) & 0xff00) | (data[3] & 0xff); 
+0

это похоже на правильный ответ, но он не работает – cateof

+0

Можете ли вы дать нам точные типы данных 'data' и' val'? Возможно, вы страдаете от расширения знака. –

+1

Yup; это тоже моя догадка. Если 'data' является' signed char * ', и любой из' data [2] 'или' data [3] 'больше 127, верхние биты результата могут быть заполнены 1. – strager

-3

Просто итерацию по элементам и сделать int.Parse

+0

'Int.Parse' не является стандартным C, и он не решает проблему здесь. – bta

0

Легкий способ:

int myint = mybyte[0]<<24+mybyte[1]<<16+mybyte[2]<<8+mybyte[3]; 

Предполагая, что ' s ваш бит-порядок, и все они без знака. Возможно, вам придется указывать байты в ints, чтобы убедиться, что они не обертываются (11001100 -> 11001100,0000000 вместо 11001100).

Далеко Незнакомец путь (хотя, вероятно, быстрее) будет чем-то сомнительным юридическим с указателями:

int * myintp= mybyte; 
int myint = *myintp; 

Я не проверял это на всех, но теоретически должно работать, при условии, что длина удается, и т. д. Это, вероятно, не очень хорошая идея.

+1

Ваше литье с указателем не получится хорошо на маленькой машине. – advait

+0

Как сделать байты в ints, чтобы убедиться, что они не обертываются? – cateof

+0

@advait: И вот почему я сказал, что это плохой выбор: P @cateof: ((int) mybyte [0]) << 24 + ((int) mybyte [1]) << 16 + ... Или, чтобы быть уверенным, (((int) mybyte [0]) & 0xFF) << 24 + (((int) mybyte [1]) & 0xFF) << 16 + ... Но это, вероятно, не нужно, поэтому попробуйте его без И сначала. – zebediah49

0

mod - довольно дорогостоящая операция, особенно для сохранения 32-битного int. Вы, вероятно, просто хотите memcpy. Если вы беспокоитесь о переносимости бросить в Htonl:

#include<string.h> 

uint32_t x = 12; 
char data[4]; 
memcpy(data, &x, sizeof(x)); 

Для перехода в другую сторону, вы можете просто обратить его вспять:

memcpy(&x, data, sizeof(x)); 
0

Вы всегда можете попробовать союз:

typedef union { 
    int  i; 
    uint8_t bytes[sizeof(int)]; 
} int_u; 

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

Смежные вопросы