Reputation: 814
Given an 8-bit integer 'c8', the bit pattern must be copied into a 32-bit integer, 'c32', such that 'c32' consists of 'c8' repeated 4 times. For example,
if c8 = 1000 1110,
then c32 = 1000 1110 1000 1110 1000 1110 1000 1110
I've thought about this and came up with two methods in C. I'm not that experienced, however, and I'm unsure which method, if any, I should use in the final code.
Minimal Examples:
uint8_t c8 = 0b10001110; // for this example
// method 1
uint32_t c32 = ((c8 << 8 | c8) << 16) | (c8 << 8 | c8);
// method 2
uint16_t c16 = c8 << 8 | c8;
uint32_t _c32 = c16 << 16 | c16;
Both methods work as expected, but I'm wondering which one would be considered 'better' from an experts' perspective :-).
In the first method, I'm computing multiple shifts while in the second one I'm creating an extra variable. I'm not that experienced with low-level things (and the performance of such low-level things), and if anybody could point me in the right direction, or find a better way of doing this, I would appreciate that.
Thank you.
Upvotes: 2
Views: 744
Reputation: 133929
The best is to use memset
. A good compiler considers it as an intrinsic and optimizes it in the best way possible. I tested the following program with GCC 6.3.0, -O3
#include <stdio.h>
#include <inttypes.h>
#include <string.h>
int main(void) {
uint32_t target;
uint8_t byte;
// if we don't do this, GCC could just *fold the value as a constant*
scanf("%c", &byte);
memset(&target, byte, sizeof(target));
printf("%08" PRIX32 "\n", target);
}
What the generated machine code actually ended up doing on my platform was analogous to:
#include <stdio.h>
#include <inttypes.h>
#include <string.h>
int main(void) {
uint32_t target;
uint8_t byte;
scanf("%c", &byte);
target = 0x01010101UL * byte;
printf("%08" PRIX32 "\n", target);
}
Upvotes: 5