I am reviewing a function to generate keys for a Radix Map and found the implementation of rand() to be novel to me.
Here is the function:
static int make_random(RadixMap *map)
{
size_t i = 0;
for (i = 0; i < map->max - 1; i++){
uint32_t key = (uint32_t) (rand() | (rand() << 16));<--This was interesting
check(RadixMap_add(map, key, i) == 0, "Failed to add key %u", key);
}
return i;
error:
return 0;
}
----- Type definitions --------
typedef union RMElement {
uint64_t raw;
struct {
uint32_t key;
uint32_t value;
} data;
} RMElement;
typedef struct RadixMap {
size_t max;
size_t end;
uint32_t counter;
RMElement *contents;
RMElement *temp;
} RadixMap;
from ex35 Learn C the Hard Way by Zed Shaw
The specific part I found interesting was
uint32_t key = (uint32_t) (rand() | (rand() << 16)); <-- This was interesting
It is interesting to me because it would have been possible to simply do ..
uint32_t key = rand();
As RAND_MAX (0x7FFFFFFF) is less than uint32_t MAX (0xFFFFFFFF)
The bit shifting implementation looks to have the following advantages.
- Allows for a larger random value range, 0xFFFFFFFF vs 0x7FFFFFFF
- Values (other than initial 0) are at least 5 digits decimal (65537) (0x10001)
- Reduced probability of seeing "0".
And the following disadvantage
- Increased code complexity?
Are there other reasons for using this bit shift implementation of rand()?
I've been trying to hash out the reason for using this implementation in my code review and wanted to make sure I was on the right track with my thinking.