rand() Function to give a 32-bit random unsigned int - c

I have some trouble coding a Function that takes 3 rand()- values and generates a 32-bit value. Specifically it has to be 15-bit from the first rand() operation; then attaching another 15-bit from the second rand() operation; and lastly attaching 2-bits from the last rand() operation;
My idea was something like this
unsigned int x = (rand()<<17 | rand()<<2 ) | rand()>>13;
However i donĀ“t think this function gives me values of the entire unsigned int range, my guess it has something to do with the fact that rand() gives you at least a value of 32767 (as far as i understand).
I hope someone can help me out.
Cheers

There are two problems with your code. First of all rand returns int and not unsigned int, and if your unsigned int is 32 bits, then bit shift left to position 17 is invalid if top bit is set. The second problem is that if rand indeed does return more than 15 bits then you're getting too many. One simple fix for both of these would be to & with 0x7fffu - that would ensure only 15 bits are set and that the resulting value is unsigned:
unsigned int x = ((rand() & 0x7fffu)<<17 | (rand() & 0x7fffu)<<2 ) | (rand() & 0x7fffu)>>13;
Another one, if you know the values are truly independent (Edit: and as Eric noticed, also a power of two), would be to use xor ^ instead of or - this would ensure that all values are still possible.
Note though that any random number generator that returns values only from 0 to 32767 is a suspect for being really bad and it is very likely that the lower-order bits are not very independent and it can be that you will end up not being able to generate all values nevertheless...

Related

Generating random 64/32/16/ and 8-bit integers in C

I'm hoping that somebody can give me an understanding of why the code works the way it does. I'm trying to wrap my head around things but am lost.
My professor has given us this code snippet which we have to use in order to generate random numbers in C. The snippet in question generates a 64-bit integer, and we have to adapt it to also generate 32-bit, 16-bit, and 8-bit integers. I'm completely lost on where to start, and I'm not necessarily asking for a solution, just on how the original snippet works, so that I can adapt it form there.
long long rand64()
{
int a, b;
long long r;
a = rand();
b = rand();
r = (long long)a;
r = (r << 31) | b;
return r;
}
Questions I have about this code are:
Why is it shifted 31 bits? I thought rand() generated a number between 0-32767 which is 16 bits, so wouldn't that be 48 bits?
Why do we say | (or) b on the second to last line?
I'm making the relatively safe assumption that, in your computer's C implementation, long long is a 64-bit data type.
The key here is that, since long long r is signed, any value with the highest bit set will be negative. Therefore, the code shifts r by 31 bits to avoid setting that bit.
The | is a logical bit operator which combines the two values by setting all of the bits in r which are set in b.
EDIT:
After reading some of the comments, I realized that my answer needs correction. rand() returns a value no more than RAND_MAX which is typically 2^31-1. Therefore, r is a 31-bit integer. If you shifted it 32 bits to the left, you'd guarantee that its 31st bit (0-up counting) would always be zero.
rand() generates a random value [0...RAND_MAX] of questionable repute - but let us set that reputation aside and assume rand() is good enough and it is a
Mersenne number (power-of-2 - 1).
Weakness to OP's code: If RAND_MAX == pow(2,31)-1, a common occurrence, then OP's rand64() only returns values [0...pow(2,62)). #Nate Eldredge
Instead, loop as many times as needed.
To find how many random bits are returned with each call, we need the log2(RAND_MAX + 1). This fortunately is easy with an awesome macro from Is there any way to compute the width of an integer type at compile-time?
#include <stdlib.h>
/* Number of bits in inttype_MAX, or in any (1<<k)-1 where 0 <= k < 2040 */
#define IMAX_BITS(m) ((m)/((m)%255+1) / 255%255*8 + 7-86/((m)%255+12))
#define RAND_MAX_BITWIDTH (IMAX_BITS(RAND_MAX))
Example: rand_ul() returns a random value in the [0...ULONG_MAX] range, be unsigned long 32-bit, 64-bit, etc.
unsigned long rand_ul(void) {
unsigned long r = 0;
for (int i=0; i<IMAX_BITS(ULONG_MAX); i += RAND_MAX_BITWIDTH) {
r <<= RAND_MAX_BITWIDTH;
r |= rand();
}
return r;
}

optimizing bitwise operations

I have a unsigned integer N = abcd where a,b,c,d represents bits from msb to lsb. I want get following numbers
x1 = ab0cd
x2 = ab1cd
What is the fastest way to do it using bitwise operations in C?
What I'm trying right now is as follows
unsigned int blockid1 = N>>offset;
unsigned int key1 = (blockid<<(1+offset))|(((1<<offset)-1)&N);
unsigned int key2 = (key1)|(1<<offset);
here offset is the location where I want to insert 0 and 1.
const unsigned int mask = (~0) << offset; // same as -(2**offset)
unsigned int key1 = N + (N & mask);
unsigned int key2 = key1 - mask;
Since your input is only 4 bits wide, which means there are a total of only 16 outputs, I would recommend at least testing (i.e. implementing and profiling) a look-up table.
These days, with super-fast ALUs and slow(ish) memories, look-ups are not often faster, but it's always worth testing. A small table means it won't pollute the cache very much, which might make it faster than a sequence of arithmetic instructions.
Since your outputs are pretty small too, the complete table could be represented as:
const static uint8_t keys[16][2];
32 bytes is very small, and if you do this often (i.e. many times in a row in a tight loop), the table should fit totally in cache.
You should have a look at Jasper Neumann's pages about bit permutations. It includes an online code generator. However it may be usefully complex for your specific case (permutation of one bit if we consider the 0 or 1 to be the MSB).
Note: I let you google the adresse since it has no domain name and direct IPs are not allowed by SO.

Homework - C bit puzzle - Perform % using C bit operations (no looping, conditionals, function calls, etc)

I'm completely stuck on how to do this homework problem and looking for a hint or two to keep me going. I'm limited to 20 operations (= doesn't count in this 20).
I'm supposed to fill in a function that looks like this:
/* Supposed to do x%(2^n).
For example: for x = 15 and n = 2, the result would be 3.
Additionally, if positive overflow occurs, the result should be the
maximum positive number, and if negative overflow occurs, the result
should be the most negative number.
*/
int remainder_power_of_2(int x, int n){
int twoToN = 1 << n;
/* Magic...? How can I do this without looping? We are assuming it is a
32 bit machine, and we can't use constants bigger than 8 bits
(0xFF is valid for example).
However, I can make a 32 bit number by ORing together a bunch of stuff.
Valid operations are: << >> + ~ ! | & ^
*/
return theAnswer;
}
I was thinking maybe I could shift the twoToN over left... until I somehow check (without if/else) that it is bigger than x, and then shift back to the right once... then xor it with x... and repeat? But I only have 20 operations!
Hint: In decadic system to do a modulo by power of 10, you just leave the last few digits and null the other. E.g. 12345 % 100 = 00045 = 45. Well, in computer numbers are binary. So you have to null the binary digits (bits). So look at various bit manipulation operators (&, |, ^) to do so.
Since binary is base 2, remainders mod 2^N are exactly represented by the rightmost bits of a value. For example, consider the following 32 bit integer:
00000000001101001101000110010101
This has the two's compliment value of 3461525. The remainder mod 2 is exactly the last bit (1). The remainder mod 4 (2^2) is exactly the last 2 bits (01). The remainder mod 8 (2^3) is exactly the last 3 bits (101). Generally, the remainder mod 2^N is exactly the last N bits.
In short, you need to be able to take your input number, and mask it somehow to get only the last few bits.
A tip: say you're using mod 64. The value of 64 in binary is:
00000000000000000000000001000000
The modulus you're interested in is the last 6 bits. I'll provide you a sequence of operations that can transform that number into a mask (but I'm not going to tell you what they are, you can figure them out yourself :D)
00000000000000000000000001000000 // starting value
11111111111111111111111110111111 // ???
11111111111111111111111111000000 // ???
00000000000000000000000000111111 // the mask you need
Each of those steps equates to exactly one operation that can be performed on an int type. Can you figure them out? Can you see how to simplify my steps? :D
Another hint:
00000000000000000000000001000000 // 64
11111111111111111111111111000000 // -64
Since your divisor is always power of two, it's easy.
uint32_t remainder(uint32_t number, uint32_t power)
{
power = 1 << power;
return (number & (power - 1));
}
Suppose you input number as 5 and divisor as 2
`00000000000000000000000000000101` number
AND
`00000000000000000000000000000001` divisor - 1
=
`00000000000000000000000000000001` remainder (what we expected)
Suppose you input number as 7 and divisor as 4
`00000000000000000000000000000111` number
AND
`00000000000000000000000000000011` divisor - 1
=
`00000000000000000000000000000011` remainder (what we expected)
This only works as long as divisor is a power of two (Except for divisor = 1), so use it carefully.

Combining two integers with bit-shifting

I am writing a program, I have to store the distances between pairs of numbers in a hash table.
I will be given a Range R. Let's say the range is 5.
Now I have to find distances between the following pairs:
1 2
1 3
1 4
1 5
2 3
2 4
2 5
3 4
3 5
4 5
that is, the total number of pairs is (R^2/2 -R). I want to store it in a hash table. All these are unsigned integers. So there are 32 bits. My idea was that, I take an unsigned long (64 bits).
Let's say I need to hash the distance between 1 and 5. Now
long k = 1;
k = k<<31;
k+=5;
Since I have 64 bits, I am storing the first number in the first 31 bits and the second number in the second 31 bits. This guarantees unique keys which can then be used for hashing.
But when I do this:
long k = 2;
k << 31;
k+= 2;
The value of k becomes zero.
I am not able to wrap my head around this shifting concept.
Essentially what I am trying to achieve is that,
An unsigned long has | 32bits | 32 bits |
Store |1st integer|2nd integer|
How can I achieve this to get unique keys for each pair?
I am running the code on a 64 bit AMD Opteron processor. sizeof(ulong) returns 8. So it is 64 bits. Do I need a long long in such a case?
Also I need to know if this will create unique keys? From my understanding , it does seem to create unique keys. But I would like a confirmation.
Assuming you're using C or something that follows vaguely similar rules, your problem is primarily with types.
long k = 2; // This defines `k` a a long
k << 31; // This (sort of) shifts k left, but still as a 32-bit long.
What you almost certainly want/need to do is convert k to a long long before you shift it left, so you're shifting in a 64-bit word.
unsigned long first_number = 2;
unsigned long long both_numbers = (unsigned long long)first_number << 32;
unsigned long second_number = 5;
both_numbers |= second_number;
In this case, if (for example) you print out both_numbers, in hexadecimal, you should get 0x0000000200000005.
The concept makes sense. As Oli has added, you want to shift by 32, not 31 - shifting by 31 will put it in the 31st bit, so if you shifted back to the right to try and get the first number you would end up with a bit missing, and the second number would be potentially huge because you could have put a 1 in the uppermost bit.
But if you want to do bit manipulation, I would do instead:
k = 1 << 32;
k = k|5;
It really should produce the same result though. Are you sure that long is 64 bits on your machine? This is not always the case (although it usually is, I think). If long is actually 32 bits, 2<<31 will result in 0.
How large is R? You can get away with a 32 bit sized variable if R doesn't go past 65535...

C - Need to shift an unsigned int right one place at a time.

I need to shift an unsigned int to the right more than 32 times and still get a proper answer of zero instead of the random or original number. E.g 8 >> 40 should = 0 but it returns a random number.
I understand a loop that shifts one place right at a time would solve this problem as it would fill in zeros as it went. However my current code for this doesn't work for some reason. What am I doing wrong?
unsigned int shiftR(unsigned int a, unsigned int b) {
unsigned int i=0;
while (i < b) {
a >> 1;
i++;
}
return a;
}
This gives me a compile warning that it has no effect ( a >> 1;). How come?
Thanks!
You want to use a >>= 1; or a = a >> 1; this is because a >> 1 shifts a to the right once and returns the result. It doesn't assign the result to a
I need to shift an unsigned int to the right more than 32 times and still get a proper answer of zero instead of the random or original number.
... Then do that?
unsigned int shiftR(unsigned int a, unsigned int b) {
return (b >= 32) ? 0 : a >> b;
}
Why complicate things?
As far as I remember C, you need to say a = a >> 1.
As others noted, you never re-assigned a a new value; the result of that statement was not used for anything, so the compiler strips it out. a>>=1 is what you wanted.
I'd like to add though that if you want your unsigned int to be 32-bit, then force it. Use the C99 stdint.h library and make it uint32_t - nice and unambiguous.
a loop that shifts one place right at a time
You must change a >> 1; to a >>= 1;.
E.g 8 >> 40 should = 0 but it returns a random number.
In C, it is undefined behavior to left or right shift an integer by more places than the bit width of the integer type[0]. Stepping on undefined behavior is very bad, because nothing could happen, something bad could happen immediately, something bad could happen at an unknown point in the future, or something bad could happen on a different platform or compiler.
The correct way to deal with this is to manually check if you're shifting by more than 32 places, and then manually give a result of 0.
[0]: http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html . You should read the whole page, but the specific section is "Oversized Shift Amounts".
a + 1 adds 1 with a but does not store anything anywhere, therefore the value of a is unmodified. To update the value of a with the incremented value you have to do a = a + 1 or a += 1 . similarly to shift the integer value in a by 1 and then store the shifted value in a you need to do a = a >> 1 or a >>= 1.
Because only doing a >> 1 does not modify the value of a, the compiler appropriately warns you that this statement has no effect, that means that keeping this statement or removing it does not matter, as it does not modify anything.
In your case you are shifting the value of a , b nos of times so you can simply use a >>= b instead of iterating a loop.

Resources