I want to create a rand() range between 1 and the dynamic value of bit_cnt.
After reading more about the rand() function, I understand that out of the box rand() has a range of [0, RAND_MAX]. I also understand that RAND_MAX's value is library-dependent, but is guaranteed to be at least 32767.
I had to create a bit mask of 64 0s.
Now, I am trying to left shift the bit mask by a dynamic value of bit_cnt anded with the a randomly generated number of bits between 1 and the dynamic value of bit_cnt.
For example, when bit_cnt is 10, I want to randomize the lowest 10 bits.
Originally, I had
mask = (mask << bit_cnt) + (rand()% bit_cnt);
which caused a floating point exception. From what I am understanding, that exception occurred because the value of bit_cntbecame 0.
Therefore, I attempted to create an if statement like this:
if((rand()%bit_cnt))!=0){
mask = (mask << bit_cnt) + (rand()% bit_cnt);
}
,but the floating point exception still occurred.
Then I tried the following thinking that the value not be 0 so increase the value to at least 1:
mask = (mask << bit_cnt) + ((rand()% bit_cnt)+1);
,but the floating point exception still occurred.
Afterwards, I tried the following:
mask = (mask << bit_cnt) + (1+(rand()%(bit_cnt+1)));
and the following 20 lines of 64 bits outputted:
0000000000000000000000000000000000000000000000000000000000000010
0000000000000000000000000000000000000000000000000000000000000011
0000000000000000000000000000000000000000000000000000000000000101
0000000000000000000000000000000000000000000000000000000000001010
0000000000000000000000000000000000000000000000000000000000010011
0000000000000000000000000000000000000000000000000000000000100011
0000000000000000000000000000000000000000000000000000000001000110
0000000000000000000000000000000000000000000000000000000010000100
0000000000000000000000000000000000000000000000000000000100001001
0000000000000000000000000000000000000000000000000000001000000010
0000000000000000000000000000000000000000000000000000010000000100
0000000000000000000000000000000000000000000000000000100000000111
0000000000000000000000000000000000000000000000000001000000000101
0000000000000000000000000000000000000000000000000010000000001001
0000000000000000000000000000000000000000000000000100000000000111
0000000000000000000000000000000000000000000000001000000000001111
0000000000000000000000000000000000000000000000010000000000001010
0000000000000000000000000000000000000000000000100000000000000101
0000000000000000000000000000000000000000000001000000000000001101
0000000000000000000000000000000000000000000010000000000000001100
What was the cause of the floating point exception? Is this how to dynamic create a range of the rand() function?
I appreciate any suggestions. Thank you.
UPDATE:
I changed the if statement to be the following:
if(bit_cnt !=0)
and then performed the rest of the logic.
I received the following output:
0000000000000000000000000000000000000000000000000000000000000001
0000000000000000000000000000000000000000000000000000000000000010
0000000000000000000000000000000000000000000000000000000000000100
0000000000000000000000000000000000000000000000000000000000001000
0000000000000000000000000000000000000000000000000000000000010010
0000000000000000000000000000000000000000000000000000000000100001
0000000000000000000000000000000000000000000000000000000001000100
0000000000000000000000000000000000000000000000000000000010000110
0000000000000000000000000000000000000000000000000000000100000011
0000000000000000000000000000000000000000000000000000001000000000
0000000000000000000000000000000000000000000000000000010000001000
0000000000000000000000000000000000000000000000000000100000000111
0000000000000000000000000000000000000000000000000001000000000110
0000000000000000000000000000000000000000000000000010000000000110
0000000000000000000000000000000000000000000000000100000000001100
0000000000000000000000000000000000000000000000001000000000000010
0000000000000000000000000000000000000000000000010000000000001101
0000000000000000000000000000000000000000000000100000000000000110
0000000000000000000000000000000000000000000001000000000000010000
0000000000000000000000000000000000000000000010000000000000000100
Is there any possible way to know if the range is correct? Like is there any possible way to know by looking at the output?
const int LINE_CNT = 20;
void print_bin(uint64_t num, unsigned int bit_cnt);
uint64_t rand_bits(unsigned int bit_cnt);
int main(int argc, char *argv[]) {
int i;
srand(time(NULL));
for(i = 0; i < LINE_CNT; i++) {
uint64_t val64 = rand_bits(i);
print_bin(val64, 64);
}
return EXIT_SUCCESS;
}
void print_bin(uint64_t num, unsigned int bit_cnt) {
int top_bit_cnt;
if(bit_cnt <= 0) return;
if(bit_cnt > 64) bit_cnt = 64;
top_bit_cnt = 64;
while(top_bit_cnt > bit_cnt) {
top_bit_cnt--;
printf(" ");
}
while(bit_cnt > 0) {
bit_cnt--;
printf("%d", (num & ((uint64_t)1 << bit_cnt)) != 0);
}
printf("\n");
return;
}
uint64_t rand_bits(unsigned int bit_cnt) {
uintmax_t mask = 1;
if (bit_cnt != 0) {
mask = (mask << bit_cnt) + (rand()% bit_cnt);
}
return mask;
}
I am trying to modify the function rand_bits to return all 0 expect for the lowest bits aka bit_cnt which are randomized.
Returns a 64 bit pattern with all zeros except for the lowest requested bits, which are randomized. This allows for arbitrary length random bit patterns in a portable fashion as the C standard "rand()" function is only required to return
random numbers between 0 and 32767... effectively, a random 15 bit pattern.
Parameter, "bit_cnt": How many of the lowest bits, including the lowest order bit (bit 0) to be randomized.
UPDATE: Added Barmar's newest suggestion of mask = rand() % (1 << bit_cnt);:
0000000000000000000000000000000000000000000000000000000000000001
0000000000000000000000000000000000000000000000000000000000000001
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000010
0000000000000000000000000000000000000000000000000000000000001000
0000000000000000000000000000000000000000000000000000000000001001
0000000000000000000000000000000000000000000000000000000000000010
0000000000000000000000000000000000000000000000000000000000010101
0000000000000000000000000000000000000000000000000000000001001111
0000000000000000000000000000000000000000000000000000000010000011
0000000000000000000000000000000000000000000000000000001010101001
0000000000000000000000000000000000000000000000000000010101101100
0000000000000000000000000000000000000000000000000000101011111000
0000000000000000000000000000000000000000000000000001001010101111
0000000000000000000000000000000000000000000000000011101011000101
0000000000000000000000000000000000000000000000000001001101111101
0000000000000000000000000000000000000000000000001111000000111010
0000000000000000000000000000000000000000000000000101100000001100
0000000000000000000000000000000000000000000000100111101000111111
0000000000000000000000000000000000000000000001010101011101000110
uint64_t rand_bits(unsigned int bit_cnt) {
uintmax_t mask = 1;
if (bit_cnt != 0) {
mask = rand() % (1 << bit_cnt);
}
return mask;
}
The problem is that anything % bit_cnt will get an error if bit_cnt is 0. You need to check bit_cnt before you try to perform the modulus.
if (bit_cnt != 0) {
mask = (mask << bit_cnt) + (rand()% bit_cnt) + 1;
}
All your attempts performed the modulus and then tried to do something with the result, but that's after the error happens.
This uses the bit count to generate a mask. If you want a bit count greater than can be filled by RAND_MAX, implement another random function as I commented earlier.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
int bit_cnt = 10;
unsigned mask = 0;
int i;
int num;
srand((unsigned)time(NULL));
for(i = 0; i < bit_cnt; i++)
mask = (mask << 1) | 1;
printf ("For bit_cnt=%d, mask=0x%X\n\n", bit_cnt, mask);
for (i = 0; i < 5; i++) {
num = rand() & mask;
printf("Random number 0x%0*X\n", 1+(bit_cnt-1)/4, num);
}
}
Program output:
For bit_cnt=10, mask=0x3FF
Random number 0x327
Random number 0x39C
Random number 0x1B1
Random number 0x088
Random number 0x26E
Related
I am reviewing for an exam and have a practice problem that I'm stuck on.
I need to write the function find_sequence(unsigned int num, unsigned int patter) {}.
I have tried comparing num & (pattern << i) == (pattern << i) and other things like that but it keeps saying there is a pattern when there isn't. I see why it is doing that but I can not fix it.
The num I'm using is unsigned int a = 82937 and I'm searching for pattern unsigned int b = 0x05.
Pattern: 00000000000000000000000000000101
Original bitmap: 00000000000000010100001111111001
The code so far:
int find_sequence(unsigned int num, unsigned int pattern)
{
for (int i=0; i<32; i++)
{
if ((num & (pattern << i)) == (pattern << i))
{
return i;
}
}
return -9999;
}
int
main()
{
unsigned int a = 82937;
unsigned int b = 0x05;
printf("Pattern: ");
printBits(b);
printf("\n");
printf("Original bitmap: ");
printBits(a);
printf("\n");
int test = find_sequence(a, b);
printf("%d\n", test);
return 0;
}
Here is what I have so far. This keeps returning 3, and I see why but I do not know how to avoid it.
for (int i=0; i<32; i++)
{
if ((num & (pattern << i)) == (pattern << i))
is bad:
- it works only when pattern consists of 1 entirely
- you generate at the end of the loop pattern << 31 which is 0 when pattern is even. Condition will hold every time then.
Knowing the length of the pattern would simplify the loop above; just go until 32 - size. When not given by the API, the length can be calculated either by a clz() function or manually by looping over the bits.
Now, you can generate the mask as mask = (1u << length) - 1u (note: you have to handle the length == 32 case in a special way) and write
for (int i=0; i < (32 - length); i++)
{
if ((num & (mask << i)) == (pattern << i))
or
for (int i=0; i < (32 - length); i++)
{
if (((num >> i) & mask) == pattern)
((num & (pattern << i)) == (pattern << i)) won't give you the desire results.
Let's say you pattern is 0b101 and the value is 0b1111, then
0101 pattern
1111 value
& ----
0101 pattern
Even though the value has not the pattern 0b101, the check would return true.
You've got to create a mask where all bits of the pattern (until the most
significant bit) are 1 and the rest are 0. So for the pattern 0b101 the mask
must be b111.
So first you need to calculate the position of the most significant bit of the pattern, then create
the mask and then you can apply (bitwise AND) the mask to the value. If the
result is the same as the pattern, then you've found your pattern:
int find_sequence(unsigned int num, unsigned int pattern)
{
unsigned int copy = pattern;
// checking edge cases
if(num == 0 && pattern == 0)
return 0;
if(num == 0)
return -1;
// calculating msb of pattern
int msb = -1;
while(copy)
{
msb++;
copy >>= 1;
}
printf("msb of pattern at pos: %d\n", msb);
// creating mask
unsigned int mask = (1U << msb + 1) - 1;
int pos = 0;
while(num)
{
if((num & mask) == pattern)
return pos;
num >>= 1;
pos++;
}
return -1;
}
Using this function I get the value 14, where your 0b101 pattern is found in
a.
In this case you could make a bitmask that 0's out all the spaces you aren't looking for so in this case
Pattern: 00000000000000000000000000000101
Bitmask: 00000000000000000000000000000111
So in the case of the number you are looking at
Original: 00000000000000010100001111111001
If you and that with this bitmask you end of with
Number after &: 00000000000000000000000000000001
And compare the new number with your pattern to see if equal.
Then >> the original number
Original: 00000000000000010100001111111001
Right shifted: 00000000000000001010000111111100
And repeat the & and compare to check the next 3 numbers in the sequence.
I'm wondering if someone know effective approach to calculate bits in specified position along array?
Assuming that OP wants to count active bits
size_t countbits(uint8_t *array, int pos, size_t size)
{
uint8_t mask = 1 << pos;
uint32_t result = 0;
while(size--)
{
result += *array++ & mask;
}
return result >> pos;
}
You can just loop the array values and test for the bits with a bitwise and operator, like so:
int arr[] = {1,2,3,4,5};
// 1 - 001
// 2 - 010
// 3 - 011
// 4 - 100
// 5 - 101
int i, bitcount = 0;
for (i = 0; i < 5; ++i){
if (arr[i] & (1 << 2)){ //testing and counting the 3rd bit
bitcount++;
}
}
printf("%d", bitcount); //2
Note that i opted for 1 << 2 which tests for the 3rd bit from the right or the third least significant bit just to be easier to show. Now bitCount would now hold 2 which are the number of 3rd bits set to 1.
Take a look at the result in Ideone
In your case you would need to check for the 5th bit which can be represented as:
1 << 4
0x10000
16
And the 8th bit:
1 << 7
0x10000000
256
So adjusting this to your bits would give you:
int i, bitcount8 = 0, bitcount5 = 0;
for (i = 0; i < your_array_size_here; ++i){
if (arr[i] & 0x10000000){
bitcount8++;
}
if (arr[i] & 0x10000){
bitcount5++;
}
}
If you need to count many of them, then this solution isn't great and you'd be better off creating an array of bit counts, and calculating them with another for loop:
int i, j, bitcounts[8] = {0};
for (i = 0; i < your_array_size_here; ++i){
for (j = 0; j < 8; ++j){
//j will be catching each bit with the increasing shift lefts
if (arr[i] & (1 << j)){
bitcounts[j]++;
}
}
}
And in this case you would access the bit counts by their index:
printf("%d", bitcounts[2]); //2
Check this solution in Ideone as well
Let the bit position difference (e.g. 7 - 4 in this case) be diff.
If 2diff > n, then code can add both bits at the same time.
void count(const uint8_t *Array, size_t n, int *bit7sum, int *bit4sum) {
unsigned sum = 0;
unsigned mask = 0x90;
while (n > 0) {
n--;
sum += Array[n] & mask;
}
*bit7sum = sum >> 7;
*bit4sum = (sum >> 4) & 0x07;
}
If the processor has a fast multiply and n is still not too large, like n < pow(2,14) in this case. (Or n < pow(2,8) in the general case)
void count2(const uint8_t *Array, size_t n, int *bit7sum, int *bit4sum) {
// assume 32 bit or wider unsigned
unsigned sum = 0;
unsigned mask1 = 0x90;
unsigned m = 1 + (1u << 11); // to move bit 7 to the bit 18 place
unsigned mask2 = (1u << 18) | (1u << 4);
while (n > 0) {
n--;
sum += ((Array[n] & mask1)*m) & mask2;
}
*bit7sum = sum >> 18;
*bit4sum = ((1u << 18) - 1) & sum) >> 4);
}
Algorithm: code is using a mask, multiply, mask to separate the 2 bits. The lower bit remains in it low position while the upper bit is shifted to the upper bits. Then a parallel add occurs.
The loop avoids any branching aside from the loop itself. This can make for fast code. YMMV.
With even larger n, break it down into multiple calls to count2()
I am writing a program that simulate a transmission of characters over the network.
I have written the following function:
int getCharBit(char c, int bitNum){
return (c & (1 <<bitNum)) >> bitNum;
}
// returns the ith bit of the character c
int getShortBit(short num, int bitNum)
{
return (num & (1 <<bitNum)) >> bitNum;
}
// sets bit i in num to 1
int setShortBit(int bitNum, short *num){
return num | (1 << bitNum);
}
// count the number of bits in the short and returns the number of bits
/* input:
num - an integer
Output:
the number of bits in num
*/
int countBits(short num)
{
int sum=0;
int i;
for(i = num; i != 0; i = i >> 1){
sum += i & 1;
}
return sum;
}
I also written a function that counts the number of ones in a short integer num and a mask:
int countOnes(short int num, short int pMask){
short tempBit = num & pMask;
sum = 0;
while(tempBit > 0){
if((tempBit & 1) == 1){
sum ++;
}
tempBit >> 1;
}
return sum;
}
and a function that sets the Parity Bit:
int setParityBits(short *num)
// set parity bit p1 using mask P1_MASK by
// get the number of bits in *num and the mask P1_MASK
int numOnes = countOnes(num, P1_MASK);
// if the number of bits is odd then set the corresponding parity bit to 1 (even parity)
if ((numOnes % 2) != 0){
setShortBit(1, num);
}
// do the same for parity bits in positions 2,4,8
int numOnes2 = countOnes(num, P2_MASK);
if ((numOnes2 % 2) != 0){
setShortBit(2, num);
}
int numOnes4 = countOnes(num, P4_MASK);
if ((numOnes4 % 2) != 0){
setShortBit(4, num);
}
int numOnes8 = countOnes(num, P8_MASK);
if ((numOnes8 % 2) != 0){
setShortBit(8, num);
}
I am also given a few function that are supposed to read the input and transmit it. The problem is in one of the functions I have written.
For example, if I run the program and type hello as an input, I should get 3220 3160 3264 3264 7420 as an output, but I get 0 0 0 0 0.
I can't seem to find what I was doing wrong, Could someone please help me?
This is my function that takes in the bits of a float, and returns the distance between the next float and the given float. In it, I have assumed the float is 32 bits. My process was to extract the mantissa and exponent, increment the mantissa, increment the exponent if it overflows, reconstruct the value and subtract the distance between them.
I have a feeling I may be overcomplicating things, and the function doesn't seem to be making use of the bitwise operators used correctly, even though I have used an algorithm similar to this before. What is going wrong here? It seems straightforward enough?
unsigned int get_distance(unsigned int bitnumber)
{
unsigned int mantissa = 0xff;
for (int i = 0; i < 24; i++) {
if (((1 << i) & bitnumber) != 0) mantissa = mantissa | 1 << i;
}
mantissa = mantissa++; // increment the mantissa
unsigned int exponent = 0xff;
for (int i = 24; i < 31; i++) {
if (((1 << i) & floatbits) != 0) exponent = exponent | 1 << i;
}
if (mantissa != mantissa) exponent++; // if it overflows, increment the exponent too.
// create complete bit pattern
unsigned int final = 0xff;
for (int i = 0; i < 32; i++) {
if (i < 24) {
if (((1 << i) & mantissa) != 0) final = final | 1 << i;
}
if (i >= 24 && i < 31) {
if (((1 << i) & exponent) != 0) final = final | 1 << i;
}
if (i == 32) {
if (((1 << i) & bitnumber) != 0) final = final | 1 << i;
}
}
// get difference b/w original float and new float
unsigned int result = final - bitnumber;
return result;
}
First off, you are unnecessarily complicating the extraction of the various fields (and, you're doing so incorrectly). A much easier way to do this is:
unsigned int exponent = (bitnumber >> 23) & ((1 << 8) - 1);
unsigned int mantissa = bitnumber & ((1 << 23) - 1);
Basically, you shift bitnumber left until the LSB of your desired field is bit 0, and then bitwise-and out just the bits you want. The expression ((1 << N) - 1) is a mask consisting of N 1s in the lowest bits.
Second, the line mantissa = mantissa++; is actually undefined behavior, since the post-increment and assignment will both try to assign a value to mantissa. Instead, you just want mantissa++.
Next, the check for overflow will never pass, as mantissa != mantissa will always be false. Instead, you want to check if bit 23 or higher is set, which can be done with mantissa >= (1 << 23). I'd also recommend grouping this statement with the aforementioned increment, so you have
mantissa++;
if (mantissa >= (1 << 23))
exponent++;
Finally, reconstructing the new value is as simple as:
unsigned int final = (exponent << 23) | mantissa;
Note, however, that if exponent is too large, this will result in a different float than you expect (namely, a negative one). There are also a few other boundary cases regarding infinity/NaN and unnormalized numbers, but more than likely you won't run into them.
To actually use this, you'll need to do some pointer conversion, like this:
float value = 1.0f; // for example
unsigned int *up = (unsigned int *)&value; // NOTE: this might trigger undefined behavior
unsigned int next = next_value(*up); // next_value is a better name for your function than get_distance
float *fp = (float *)&next; // again, this may be UB
float difference = *fp - value; // this is what you want
What would be the best way to generate a random 32-bit hexadecimal value in C? In my current implementation I am generating each bit separately but the output is not completely random ... many values are repeated several times. Is it better to generate the entire random number instead of generating each bit separately?
The random number should make use of the entire 32 bit address space (0x00000000 to 0xffffffff)
file = fopen(tracefile,"wb"); // create file
for(numberofAddress = 0; numberofAddress<10000; numberofAddress++){ //create 10000 address
if(numberofAddress!=0)
fprintf(file,"\n"); //start a new line, but not on the first one
fprintf(file, "0 ");
int space;
for(space = 0; space<8; space++){ //remove any 0 from the left
hexa_address = rand() % 16;
if(hexa_address != 0){
fprintf(file,"%x", hexa_address);
space++;
break;
}
else if(hexa_address == 0 && space == 7){ //in condition of 00000000
fprintf(file,"%x", "0");
space++;
}
}
for(space; space<8; space++){ //continue generating the remaining address
hexa_address = rand() % 16;
fprintf(file,"%x", hexa_address);
}
}
x = rand() & 0xff;
x |= (rand() & 0xff) << 8;
x |= (rand() & 0xff) << 16;
x |= (rand() & 0xff) << 24;
return x;
rand() doesn't return a full random 32-bit integer. Last time I checked it returned between 0 and 2^15. (I think it's implementation dependent.) So you'll have to call it multiple times and mask it.
Do this way.It creates a bigger number than the earlier logic .If you are interested the MSB then the below logic is good .:
/** x = rand() ^ rand()<<1; **/
#include <algorithm>
#include <string.h>
#include <ctype.h>
#include <stdint.h>
#include <string>
#include <stdio.h>
int main () {
int i, n;
n = 50;
uint x,y ;
//4294967295 :UNIT_MAX
/* Intializes random number generator */
srand((unsigned) time(0));
for( i = 0 ; i < n ; i++ ) {
/**WAY 1 **/
x = rand() ^ rand()<<1;
printf("x:%u\t",x);
printf("Difference1:(4294967295 - %u) = %u\n",x,(4294967295 - x));
/**WAY 2 **/
y = rand() & 0xff;
y |= (rand() & 0xff) << 8;
y |= (rand() & 0xff) << 16;
y |= (rand() & 0xff) << 24;
printf("y:%u\t",y);
printf("Difference2:(4294967295 - %u) = %u\n",y,(4294967295 - y));
printf("Difference between two is = %u\n",(x) - (y));
}
printf("End\n");
return(0);
}
You can just create any random number that's at least 32 bit wide and format that as hex. Examples:
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
uint32_t n;
n = mrand48(); // #1
n = rand(); // #2
FILE * f = fopen("/dev/urandom", "rb");
fread(&n, sizeof(uint32_t), 1, f); // #3
// ... etc. etc. E.g. Windows Crypto API
char hex[9];
sprintf(hex, "%08X", n);
Now hex is a string containing eight random hexadecimal digits. Don't forget to seed the various pseudo random number generators (using srand48() and srand(), respectively, for #1 and #2). Since you'll essentially have to seed the PRNGs from random source with at least one 32-bit integer, you might as well tap the random source directly (unless you're using time() or something "non-random" like that).