How to randomize lowest bits in a 64 bit pattern - c

I am interested in learning more about the concepts behind bit shifting and the manipulation of randomly generated bits. Below is some code that prints 20 random 64 bit patterns. "rand_bits" uses the C standard rand() to return a 64 bit pattern with all zeros except for the lowest bits, which are randomized. The number of low randomized bits is provided by the only parameter to the function.
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(64);
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;
}
/*
* Name: rand_bits
* Function: Returns a 64 bit pattern with all zeros except for the
* lowest requested bits, which are randomized.
* Parameter, "bit_cnt": How many of the lowest bits, including the
* lowest order bit (bit 0) to be randomized
* Return: A 64 bit pattern with the low bit_cnt bits randomized.
*/
uint64_t rand_bits(unsigned int bit_cnt) {
printf("int bit_cnt:", bit_cnt);
uint64_t result = rand();
uint64_t result_1 = result>>5;
// uint64_t result_1 = result>>7;
//return result;
return result_1;
}
For example, if the function is called with 24 as the argument value, it might return a
64 bit pattern, such as:
0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_​1101_0110_0101_1110_0111_1100
Currently the function rand_bits may show more than 15 random bits coming from the rand() function, but this is by NO means guaranteed.
I thought that to get the 40 bits like in the example I could right shift the bits, but that does not seem to be the concept. Does this require a bit mask of the higher order bits or a mod calculation on the random number generator?
Any suggestions of how to return a bit pattern of all zeros with its lowest bits (bit_cnt) randomized?
UPDATE:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <math.h>
const int LINE_CNT = 20;
uint64_t rand_bits( unsigned number_of_bits ){
uint64_t r = 0;
unsigned i;
for(i = 0; i <= number_of_bits / 15; i++ ){
r = (r << 15) | (rand() & 0x7fff ) ;
}
return r & ~(~0ull << number_of_bits) ;
}
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;
}
int main(void) {
int i;
/* for(i = 0; i < 64; i++)
print_bin(rand_bits(i),64);
return EXIT_SUCCESS;
*/
//I want to keep the code like this, but have the output shown in //the links.
srand(time(NULL));
for(i = 0; i < LINE_CNT; i++) {
uint64_t val64 = rand_bits(64);
print_bin(val64, 64);
}
return EXIT_SUCCESS;
}
When I keep the code in main the way I had it originally, the output is all 0s. Any suggestions of how I can keep my code the way it was in main originally and produce exactly 20 lines of 64 bits with the lowest bits randomized?

rand() generates an int in the range [0 ...RAND_MAX]. RAND_MAX is at least 32767 and certainly is 1 less than a power of 2.
So efficiently loop a few times until we have bit_cnt random bits. This trick is to minimize the loop count by taking advantage that RAND_MAX is likely greater than 32767.
#include <stdlib.h>
// Valid for 0 <= bit_cnt <= uintmax_t bit wdith
uintmax_t randomized_lowest_bits(unsigned bit_cnt) {
// Create mask, same as maximum return value
uintmax_t mask = 1;
if (bit_cnt >= CHAR_BIT * sizeof(uintmax_t)) {
mask = -1;
} else {
mask = (mask << bit_cnt) - 1;
}
uintmax_t limit = mask;
uintmax_t x = 0;
while (limit) {
// x *= (RAND_MAX +1)
// Done as below to prevent numeric overflow of `RAND_MAX + 1u` on rare machines.
// Let the compiler optimize it, likely into a fixed count left shift
#if RAND_MAX == INT_MAX
x = x * (RAND_MAX / 2 + 1) * 2;
#else
x *= RAND_MAX + 1;
#endif
// Bring in more bits
x += rand();
// Carefully divide by RAND_MAX + 1 with overflow safe guards
// Again, let the compiler optimize the code, likely into a fixed count right shift
#if RAND_MAX == INT_MAX
limit = (limit / (RAND_MAX / 2 + 1)) / 2;
#else
limit /= RAND_MAX + 1;
#endif
}
return x & mask;
}
void testR(void) {
for (int i = 0; i <= 64; i++) {
printf("%jX\n", randomized_lowest_bits(i));
}
}
Output
0
1
3
...
1192962917E96171
24833D39561F3B29
C3EC4ED846755A5B

uint64_t rand_bits(unsigned int number_of_bits)
{
uint64_t r = 0;
int i;
for(i = 0 ; i < number_of_bits/15 ; i++ )
{
r = (r<<15)|(rand()&32767u);
}
int remainder = number_of_bits-i*15;
r = (r<<remainder)|(rand()&~(~0ull<<remainder));
return r;
}
Since RAND_MAX is guaranteed to provide 15 bits, there's no point doing 1 bit a time.

By concatenating a sufficient number of 15 bit random sequences, then masking the unwanted bits when number_of_bits is not an exact multiple of 15:
uint64_t rand_bits( int number_of_bits )
{
uint64_t r = 0;
for( int i = 0; i <= number_of_bits / 15; i++ )
{
r = (r << 15) | (rand() & 0x7fff ) ;
}
return r & ((number_of_bits >= 64) ? ~0ull :
~(~0ull << number_of_bits) ) ;
}

Related

Converting decimal into binary in c using pointers

Write a function int* dec2bin(int N, int* n), which, given a natural number 0 ≤ N < 65535, computes and returns its representation in the binary numeral system. The program has to determine the coefficients ai ∈ {0,1}, i = 0,...,n − 1, such that N = (sum->n-1) ai2^i (n ≤ 16).
#include <stdio.h>
#include <math.h>
#include <assert.h>
int decimalToBinary(int N)
{
int B_Number = 0;
int c= 0;
int ctr=0;
while (N != 0) {
int rem = N % 2;
c = pow(10, ctr);
B_Number += rem * c;
N /= 2;
ctr++;
}
return B_Number;
}
int main()
{
int N;
scanf("%d", &N);
printf("%d", decimalToBinary(N));
return 0;
}
I know how to make a program that converts the numbers but I don't understand why the pointer is needed for and how to implement it.
Another way...
This was written to print the binary representation of a value (left-to-right). Instead of printing, you could simply assign the 0/1 (left-to-right) to a passed array (of 16 integers), then return the number of assigned integers to the calling function to print them from a loop.
int main() {
for( int i = 253; i <= 258; i++ ) {
printf( "Decimal %d: ", i );
unsigned int bitmask = 0;
bitmask = ~bitmask;
bitmask &= ~(bitmask >> 1); // High bitmask ready
// skip over leading 0's (optional)
while( bitmask && (bitmask & i) == 0 ) bitmask >>= 1;
// loop using bitmask to output 1/0, then shift mask
do {
putchar( (bitmask & i) ? '1' : '0' );
} while( (bitmask >>= 1) != 0 );
putchar( '\n' );
}
return 0;
}
Use an integer type capable of encoding the decimal number 1111_1111_1111_1111: use long long.
Do not use pow(), a floating point function for an integer problem. It may generate value just slightly smaller than the integer expected and is slow.
long long decimalToBinary_alt(int N) {
long long B_Number = 0;
long long power = 1;
while (N != 0) {
int rem = N % 2; // result: -1, 0, or 1
B_Number += rem * power;
N /= 2;
power *= 10; // Scale the power of 10 for the next iteration.
}
return B_Number;
}
Usage
printf("%lld\n", decimalToBinary(N));
Your function does not have the required parameters and return value.
int* dec2bin(int N, int* n)
{
unsigned uN = N;
for(int bit = 15; bit >= 0; bit--)
{
*(n + 15 - bit) = !!(uN & (1U << bit));
}
return n;
}

Does somedody know how to reverse digits in right order with recursion in c

I have a task to convert decemiacal number to 8-binary. from 1 to 100, i don't know how to reverse dights in right order/ i use recursive, i mean
output is: 3 4 1, what it should be 1 3 4/ How to reverse a few numbers)
#include <math.h>
#include <stdio.h>
int bit8(int n) {
int x = n;
if (n == 100) {
return 1;
}
int mass[100];
int b;
int i = 0;
printf("%d: ", n);
while (x >= 8) {
b = x % 8;
x = x / 8;
}
if (x < 8) {
printf("%d ", x);
i++;
}
bit8(n + 1);
}
int main() {
int n = 1;
bit8(n);
}
to convert decemiacal number to 8-binary
Suggest starting over.
Typical recursion first tests before maybe recursing.
To print an n-bit integer number:
void print_n_bit(unsigned value, unsigned bit_count) {
if (bit_count > 0) {
if (bit_count > 1) {
// Print the other, more significant, bits first.
print_n_bit(value >> 1, bit_count-1); // Recursive call
}
// Now print the least significant bit
putchar((value & 1) + '0');
}
}
Usage example:
int main(void) {
unsigned n = 1;
unsigned bits_to_print = 8;
print_n_bit(n, bits_to_print);
}

Finding proper descendants of an integer [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I'm stuck on an basic algorithmic issue and I can't figure out how to solve it.
Basically I wanna list all numbers that are proper descendants of an integer. That is to say, if my number is 21, I want to use its binary representation (10101) and list all numbers which have at least one common bit of value 1 with 21 and are lower than 21. The result here should be 10100, 10001, 10000, 101, 100, 1.
The mathematical definition of proper descendants is as follows:
Let h be a nonnegative number less than 2^m. h = d0 + d1*2^1 + ... + dm-1*2^(m-1) where di = 0 or 1.
Let h' be another nonnegative such as h' = d0' + d1'*2^1 + ... + dm-1'*2^(m-1) where di' = 0 or 1.
h' is a descendant of h if di'<=di for 0<=i<m
I've tried many implementations in both Python and C and tried the old pen and paper technique, but all of them failed. I know it's rather simple but I can't seem to figure it out. I'm coding in C so if you find a solution that works in C that would be ideal, but I'd take anything right now.
Here is a very simple approach: enumerate all integers between n-1 and 1 and print those that are strictly included in n, ie: (i & n) == i.
void list_descendants(int n) {
printf("descendants of %d:", n);
for (int i = n; i --> 1;) {
if ((i & n) == i)
printf(" %d", i);
}
printf("\n");
}
Ok so I finally came up with a code in C that is far from good looking and probably horribly optimised but still works as intended. There are probably much simpler solutions but here is mine for knowledge purposes :
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
unsigned int pui(unsigned int a, unsigned int b)
{
if (b == 0)
return 1;
if (b == 1)
return a;
if (b % 2 == 0)
return pui(a * a, b / 2);
else
return pui(a * a, (b - 1) / 2);
}
unsigned int testBit(unsigned int h, unsigned int offset)
{
unsigned int mask = 1 << offset;
return (h & mask);
}
bool isInList(unsigned int x, unsigned int *output_size, unsigned int **output)
{
for (int i = 0; i < *output_size; i++)
{
if (*(*output + i) == x)
{
return true;
}
}
return false;
}
void listDescendants(unsigned int h, unsigned int *output_size, unsigned int **output, int *currently_processing)
{
unsigned int max_offset = 0;
unsigned int temp_h = h;
unsigned int initial_output_size = *output_size;
while (temp_h > 0)
{
max_offset++;
temp_h /= 2;
}
unsigned int h_radix2[max_offset];
for (int i = 0; i < max_offset; i++)
{
if (testBit(h, i))
{
if (h > pui(2, i) && !isInList(h - pui(2, i), output_size, output))
{
*(*output + *output_size) = h - pui(2, i);
*output_size += 1;
}
}
}
if (*currently_processing < (int)*output_size)
{
*currently_processing += 1;
listDescendants(*(*output + *currently_processing), output_size, output, currently_processing);
}
}
int main()
{
int currently_processing = -1;
unsigned int size = 0;
unsigned int *output = malloc(300 * sizeof(unsigned int));
listDescendants(21, &size, &output, &currently_processing);
printf("size = %u\n", size);
for (int i = 0; i < size; i++)
{
printf("%u ", output[i]);
}
printf("\n");
return 0;
}
You can use a recursive solution, such as the following one.
I'm a bit lazy, so I didn't put the numbers in a list but simply printed them, and I also printed 0 and the given number.
I believe you can easily adjust the code so it will do what you desire.
#include <stdio.h>
#define CHAR_BIT 8
void ProperDescendantsRecursive(unsigned int num, unsigned int bit_index)
{
if (CHAR_BIT * sizeof(unsigned int) - 1 == bit_index)
{
printf("%u\n", num);
}
else
{
unsigned int mask = 1U << bit_index;
if (num & mask)
{
/* with the bit at index bit_index is off */
ProperDescendantsRecursive(num ^ mask, bit_index + 1);
/* with the bit at index bit_index is on */
ProperDescendantsRecursive(num, bit_index + 1);
}
else
{
ProperDescendantsRecursive(num, bit_index + 1);
}
}
}
void ProperDescendants(unsigned int num)
{
ProperDescendantsRecursive(num, 0);
}
int main(void)
{
ProperDescendants(21);
return 0;
}
compiling and running results this output:
0
16
4
20
1
17
5
21

Can I compute digital sum of 2ⁿ more efficiently?

I am trying to make a recursive function in C that calculates the sum of digits in 2ⁿ, where n < 10⁷. I made something that works, but it's very slow (for n = 10⁵ it takes 19 seconds). The function must return the sum in maximum 1 second. My algorithm calculates 2ⁿ using arrays to store its digits and it's not using a recursive function.
Is there any way to compute this sum of digits without calculating 2ⁿ? Or a faster way to calculate 2ⁿ and its digits sum?
P.S.: The recursive function must get only the n parameter, i.e. int f(int n);
Late edit: I wrote a recursive solution; it is faster, but it doesn't work for n > 10⁵.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int sumOfDigits(int* num, int n) {
if (n == 0) {
int sum = 0;
for (int i = 1; i <= num[0]; ++i) {
while (num[i] > 0) {
sum += num[i] % 10;
num[i] /= 10;
}
}
return sum;
}
int carry = 0;
for (int i = 1; i <= num[0]; ++i) {
num[i] = num[i] * 2 + carry;
carry = num[i] / 1000000000;
num[i] %= 1000000000;
if (carry != 0 && i == num[0]) {
++num[0];
}
}
return sumOfDigits(num, n - 1);
}
int main (void) {
int n = 100000;
int size = (n*log10(2) + 1) / 9 + 2;
int* num = calloc(size, sizeof(int));
num[0] = 1;
num[1] = 1;
printf("\n%d", sumOfDigits(num, n));
free(num);
return 0;
}
It seems that the posted code is using an "implicit" arbitrary precision type (with "digits" in the range [0, 999999999]) to recursively calculate all the multiplication by 2, which means, for e.g. n = 100, to perform 100 times those expansive calculation.
It should be more efficient (O(log(n)) instead of O(n)) to perform each time a multiplication of the number by itself or by 2, based on whether the exponent is even or odd. E.g. 27 = 2 * (23 * 23).
Another approach would be to explicitly implement a Bing Int type, but with a binary underlying type (say a uint32_t). It would be trivial to calculate 2n, it'd be just an array of zeroes with a final power of two (again, just one non-zero bit).
Now, to get the sum of the (base 10) digits you need to transform that number in base, say 100000000 (like the OP did), and to do that, you have to implement a long subtraction between two Big Ints and a long division by 100000000, which will give you the remainder too. Use that remainder to calculate the partial sum of the digits and iterate.
The following is a minimal implementation, testable here.
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <inttypes.h>
#define D_BASE 1000000
#define MSB_MASK 1 << 31
typedef struct
{
uint32_t size;
uint32_t capacity;
uint32_t *digits;
} BigInt;
void divide_bigint(BigInt *n, uint32_t x, uint32_t *remainder);
BigInt *make_bigint_of_two_raised_to(uint32_t n)
{
BigInt *p = malloc(sizeof *p);
if (!p)
{
perror("Fatal error");
exit(1);
}
uint32_t pos = n / 32;
uint32_t remainder = n % 32;
uint32_t capacity = (remainder == 31) ? pos + 2 : pos + 1;
uint32_t *pp = calloc(capacity, sizeof *pp);
if (!pp)
{
perror("Error initializing a Big Int as a power of two");
free(p);
exit(1);
}
p->capacity = capacity;
p->size = capacity;
pp[pos] = 1u << remainder;
p->digits = pp;
return p;
}
void free_bigint(BigInt **p);
uint64_t sum_of_digits_of_two_raised_to_the_power(uint32_t n)
{
BigInt *power_of_two = make_bigint_of_two_raised_to(n);
uint32_t remainder;
uint64_t sum = 0;
while (!(power_of_two->size == 1 && power_of_two->digits[0] == 0))
{
divide_bigint(power_of_two, 1000000000, &remainder);
while (remainder)
{
sum += remainder % 10;
remainder /= 10;
}
}
free_bigint(&power_of_two);
return sum;
}
void test(uint32_t n)
{
uint64_t sum = sum_of_digits_of_two_raised_to_the_power(n);
printf("Sum of digits of 2^%d: %" PRIu64 "\n", n, sum);
}
int main(void)
{
test(5);
test(10);
test(1000);
test(10000);
test(100000);
test(1000000);
return 0;
}
void shrink_size(BigInt *n)
{
while ( n->size > 1 )
{
if ( n->digits[n->size - 1] == 0 && !(n->digits[n->size - 2] & MSB_MASK) )
--n->size;
else
break;
}
}
void divide_bigint(BigInt *n, uint32_t x, uint32_t *remainder)
{
uint64_t carry = 0;
uint32_t i = n->size;
while ( i-- > 0 )
{
carry <<= 32;
carry += n->digits[i];
if ( carry < x )
{
n->digits[i] = 0;
continue;
}
uint64_t multiplier = (carry / x);
carry -= multiplier * x;
n->digits[i] = (uint32_t)multiplier;
}
shrink_size(n);
*remainder = carry;
}
void free_bigint(BigInt **p)
{
if (p && *p)
{
free((*p)->digits);
free(*p);
*p = NULL;
}
}
2^8 = (2 * 2 * 2 * 2 * 2 * 2 * 2 * 2) = (2 * 2 * 2 * 2) * (2 * 2 * 2 * 2) = (2 * 2 * 2 * 2)^2 = ((2 * 2) * (2 * 2))^2 = ((2 * 2)^2)^2 = ((2^2)^2)^2
So, first you need to calculate log(2, n), to see how you can calculate effectively. If log(2, n) is an integer, then you can simply calculate the square of the square of the ... of the square with very few operations. If log(2, n) is not an integer, then calculate 2^((int)log(2, n)) and thus you will very effectively do a partial calculation and then do the same for the remainder until there is no longer remainder.
Unify your partial results into a number (possibly represented by an array) and calculate the sum of the digits. Calculating the sum of the digits is straight-forward. The actual calculation of the 2^n is what takes the most time.
If you do not reach the limits of a number format, then you can think about shift left, but with the domain you work with this is not really an option.

Trouble printing decimal to binary number properly

I'm trying to write code to print the binary representation of a number. This was my attempt:
#include <stdio.h>
void getBinary(int num);
int main(void) {
int num = 2;
getBinary(num);
return 0;
}
void getBinary(int num) {
int mask = 1 << 31, i;
int temp;
for (i = 31; i >= 0; i--) {
temp = num & mask;
if (temp > 0)
printf("1");
else
printf("0");
mask = mask >> 1;
}
printf("\n");
}
And this doesn't work. If i make num = 2 my output will be ...0011. This is the answer I was given:
void getBinary(int);
int main()
{
int num=0;
printf("Enter an integer number :");
scanf("%d",&num);
printf("\nBinary value of %d is =",num);
getBinary(num);
return 0;
}
/*Function definition : getBinary()*/
void getBinary(int n)
{
int loop;
/*loop=15 , for 16 bits value, 15th bit to 0th bit*/
for(loop=15; loop>=0; loop--)
{
if( (1 << loop) & n)
printf("1");
else
printf("0");
}
}
and this will give the correct output. Why? What is different between my code and this. Aren't they doing the same thing with the solution doing it in fewer steps?
#include <stdio.h>
void getBinary(int num);
int main(void) {
unsigned int num = 2;
getBinary(num);
return 0;
}
void getBinary(int num) {
unsigned int mask = 1 << 31;
int i;
unsigned int temp;
for (i = 31; i >= 0; i--) {
temp = num & mask;
if (temp > 0)
printf("1");
else
printf("0");
mask = mask >> 1;
}
printf("\n");
}
For those curious, this is the correct answer. Just make the mask unsigned.
You have some problems in the code:
1 << 31 invokes undefined behavior because of signed arithmetic overflow. On your platform it most likely produces the value INT_MIN, that has the expected bit configuration but is negative.
temp > 0 might fail incorrectly if num < 0, because the sign bit will make temp negative too.
shifting mask to the right when its value is negative has an implementation defined result: On your platform it duplicates the sign bit, therefore mask will not have a single bit as expected, but all bits set above the current one. This explains the observed behavior.
You should use type unsigned int in function getBinary for num, temp and mask to get correct behavior.
Here is a corrected version of your code:
#include <stdio.h>
void getBinary(unsigned int num);
int main(void) {
unsigned int num = 2;
getBinary(num);
return 0;
}
void getBinary(unsigned int num) {
unsigned int mask = 1U << 31;
unsigned int temp;
for (int i = 31; i >= 0; i--) {
temp = num & mask;
if (temp != 0)
printf("1");
else
printf("0");
mask = mask >> 1;
}
printf("\n");
}
The proposed solution only prints 16 bits, which may or may not have been the specification. If the int type is larger than 16 bits, the bit shift will not overflow and everything is fine. If int has 16 bits, 1 << 15 invokes undefined behavior, so the solution is not strictly correct, but will function on most current platforms.
Here is a simpler solution:
void getBinary(unsigned int num) {
for (int shift = 32; shift-- > 0;) {
putchar('0' + ((num >> shift) & 1));
}
putchar("\n");
}
Initialize shift to 16 to print only the low order 16 bits.

Resources