Reputation: 83
I'm trying to fill an array of unsigned integers (32-bit) with short integers from another array (size is not fixed). I put the short ints one after the other in the output array which contains random values.
Here is my code:
#define K_LENGTH (37) // Arbitrary
void computeInput(unsigned short* input) {
unsigned int output[1000];
unsigned int i, j, gap;
j = 0;
gap = 0;
output[0] = 0;
for (i = 0; i < K_LENGTH; i++) {
output[j] |= (input[i] << gap);
if (gap) {
gap = 0;
j += 1;
output[j] = 0;
} else {
gap = 16;
}
}
// The rest of output array is set to 0
for (i = j, i < 1000, i++) {
output[i] = 0;
}
// Other stuff
}
First, the part of algorithm checking the gap value is quite ugly but I don't how to perform this efficiently. Second, I don't know how to ensure that the random values are erased/replaced by the input values.
Should I set the entire output array to 0 before computing input values? It seems inefficient.
Upvotes: 0
Views: 513
Reputation: 4433
It seems that this is a work for Mr. memcpy
.
I will try to handle your problem by using memcpy.
It's pretty sure that the copy will be efficient, since it copies the bits of one object into another, without any arithmetic at all, just bitwise.
Anyway, I can see that you are assuming a lot of non-portable issues.
For example, that unsigned int
is 32 bits, without any padding bits.
The standard only ensures that unsigned int
holds a minimun of 16 bits.
Maybe it would be a good idea to use the unsigned integer types uint_least32_t
or uint_fast32_t
defined in stdint.h
, that have at least 32 bits always. If you are lucky, the type uint32_t
will also be defined there, which has exactly 32 bits.
Upvotes: 0
Reputation: 12263
I assume you are trying to merge 16 bit unsigned integers pair-wise into an array of 32 bit unsigned integers:
#include <stdint.h>
void mergeShorts(size_t out_len, uint32_t output[out_len],
size_t in_len, const uint16_t input[in_len] ) {
size_t i;
// output must have enough entries.
assert( (in_len < SIZE_MAX) && ((in_len + 1) / 2 <= out_len) );
for ( i = 0 ; i < in_len / 2 ; i += 1 )
output[i] = ((uint32_t)input[i / 2] << 16) | (input[i / 2 + 1];
// transfer last (odd) entry
if ( (i * 2) < in_len )
output[i++] = (uint32_t)input[in_len - 1] << 16;
// zero the rest of the array
for ( ; i < out_len ; i++ )
output[i] = 0;
}
Using stdint.h
types guarantees the proper sizes for the elements of both arrays and is likely what you actually want.
If you only have fixed sizes, replace out_len
and in_len
by constants. I used output
as an argument, as the rest of code is missing. If that is not required, just make it a local again (the name output
actually implies it is expected by the caller).
Normally, one would pack this into a function as I did and call that function from computeInput
with the appropriate arguments:
mergeShorts(1000, output, K_LENGTH, input);
Upvotes: 1