I have a small snippet of code that I have written, I am a bit unsure if sign extension has been properly implemented here
Essentially
I have an array of char* data that contains values in bytes
Now I wish to construct a 16 bit (2 byte) value from this data array
I do this by getting the byte @ address 0 and address 1 and combining them.
This part is working and I am sure of it
Now this is a 16 bit value, which I aim to store in my signed integer array. And obviously integers are 32 bits (4 bytes) thus will need to be padded with an additional 16 bits
Now my question is this
void store_data(unsigned char* data){
int param1 = 5;
int param2 = 6;
int address = array_of_ints[param2] + 50;
int value = memory[address] | (memory[address+1] << 8);
int32_t sign = value;
array_of_ints[param1] = sign;
}
Has my code been properly sign extending the value from memory
Since I am storing it as a signed 32_int I would not need to pad it with an additional 16 bits right?
Your answer depends on how memory has been defined. You suggest, in the text, that it is an
array of char; chars are typically ( but not definitively ) signed, so no, your code would have some odd values.That should be relatively easy to test; put values like { 0, 1, 0x7f, 0x80, 0x81 }; at some locations in memory, and observe the output of printing your variables.
One subtle problem is with your shift and or to make a 16bit value. Your expression:
memory[address] | (memory[address+1] << 8)by type looks like(signed char) | (signed int). What you want is(unsigned char) | (unsigned short). Most importantly you have to suppress the sign extension from memory[]. You probably want it to be unsigned.It is much preferred to use <inttypes.h> and the corresponding (int8_t, uint8_t, int16_t, ..., uint64_t) than assuming int or short sizes.