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;
}
Related
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);
}
How do I store different digits of an integer in any array
like 1234 to {1,2,3,4}
It can be done using char str[]="1234"; printf("%c",str[0];
but how to do it without using string and in integer itself
Here's a snippet that creates an array of digits and prints them out:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
// Print digits 1 by 1
void numToDigits (int number, int base) {
int i;
int n_digits = (int)ceil(log(number+1) / log(base));
printf("%d digits\n", n_digits);
int * digits = calloc(n_digits, sizeof(int));
for (i=0; i<n_digits; ++i) {
digits[i] = number % base;
number /= base;
}
// digits[0] is the 1's place, so print them starting from the largest index
for (i=n_digits-1; i>=0; --i) {
printf("%d", digits[i]);
}
printf("\n");
free(digits);
}
You'll likely want to modify this, but I think it exposes all the important ideas. Don't forget to add -lm when you compile to include math libraries needed for log and ceil. Also note that the printing code isn't made to work with bases larger than 10.
Here's one method, more or less:
get the log10() of the integer to determine its 'size'
take the floor() of that to get exponent (number of digits - 1)
then calculate the highest divider with (int)pow(10, exponent)
finally have a for-loop:
int value = 1234; // Your value to split up in digits.
for (int d = divider; divider > 0; divider /= 10)
{
int digit = value / d;
value = value / 10;
// Store digit in array
}
I leave the details for you to fill in.
Carson had a similar idea which nicely avoids the use of pow()
If your compiler supports variable length arrays then you can use the approach shown in the demonstration program below
#include <stdio.h>
enum { Base = 10 };
size_t size( unsigned int x )
{
size_t n = 0;
do { ++n; } while ( x /= Base );
return n;
}
int main( void )
{
unsigned int x = 0;
printf( "Enter a non-negative number: " );
scanf( "%u", &x );
size_t n = size( x );
unsigned int digits[n];
for ( size_t i = n; i != 0; x /= Base )
{
digits[--i] = x % Base;
}
for ( size_t i = 0; i < n; i++ )
{
printf( "%u", digits[i] );
}
putchar( '\n' );
}
The program output might look like
Enter a non-negative number: 123456789
123456789
If the compiler does not support variable length arrays then you will need to allocate the array dynamically as for example
unsigned int *digits = malloc( n * sizeof( unsigned int ) );
You don't need to calculate how many digits are in a given integer n at runtime. You can check your compiler's <limits.h> for the maximum number of digits an int can hold.
int n = 124343;
int digits[10]; // INT_MAX is 10-digit long on x86 and x64 (GCC and Clang)
int ndigits;
Another solution is to pre-compute (#chux) the maximum number of digits using macros:
#define INT_DIGIT10_WIDTH ((sizeof(int)*CHAR_BIT - 1)/3 + 1)
int digits[INT_DIGIT10_WIDTH];
The rest is simple:
// Digits are stored in reverse order
for (ndigits = 0; n; n /= 10)
digits[ndigits++] = n % 10;
for (int i = ndigits - 1; i > 0; --i)
printf("%d\t", digits[i]);
If you want to store them in-order:
// Digits are stored in reverse order
for (ndigits = 0; n; n /= 10)
digits[ndigits++] = n % 10;
// Reverse digits by swapping every two parallel elements
for (int i = 0, j = ndigits-1; i < j; ++i, --j) {
int tmp = digits[i];
digits[i] = digits[j];
digits[j] = tmp;
}
for (int i = 0; i < ndigits; ++i)
printf("%d\t", digits[i]);
I was writing my response when the first answer showed up. This will work just fine. The loop in the middle basically isolates each digit by removing all the ones in front of it and then dividing it down to the ones place before adding it to the array.
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.
I have an assigment to create a function that recieves a number, and return the reversed number.
E.G :
Input : 12343
Output : 34321
No loops allowed, and the input is only the number .
This is what I've tried :
long GetReverse(unsigned long n)
{
if (n < 10)
return n % 10;
else
return 10 * GetReverse(n / 10) + n % 10;
}
Though This is retuning me the same input and not reversing the number ( I know what is the problem here, I just can't think of a way to do it)
Any thoughts?
EDIT: This is the solution I came up with :
int numOfMulti(unsigned long num) {
if (num < 10)
return 1;
return 10 * numOfMulti(num / 10);
}
long GetReverse(unsigned long n)
{
if (n < 10)
return n % 10;
else
return n % 10 * numOfMulti(n) + GetReverse(n / 10) ;
}
Wasn't able to find a solution without a secondary function or static variables.
It's easy. Please try my solution. NO LOOPS, ONE PARAMETER.
long GetReverse(unsigned long n)
{
static unsigned long m = 0;
static int recursive_level = 0;
recursive_level++;
if (n < 10) {
recursive_level--;
m = m * 10 + n;
int temp = m;
if (recursive_level == 0) {
m = 0;
}
return temp;
}
m = m * 10 + (n % 10);
GetReverse(n / 10);
recursive_level--;
int temp = m;
if (recursive_level == 0) {
m = 0;
}
return temp;
}
You will need to pass 2 elements to the GetReverse function, because the last digit will have to be shifted on the left:
long GetReverse(unsigned long n, unsigned long m)
{
if (n < 10)
return 10 * m + n;
else
return GetReverse(n / 10, 10 * m + n % 10);
}
You can then call GetReverse(12343, 0) and get as expected 34321
This is silly and should not be used in real life, but complies with the requirements:
unsigned long GetReverse(unsigned long n)
{
if (n < 10)
return n;
else
return n % 10 * lround(pow(10,floor(log10(n)))) + GetReverse(n / 10);
}
Here's a solution that only takes one parameter, although you can only use the least significant 32 bits for your input:
uint64_t rev(uint64_t n)
{
uint32_t _n = n;
uint32_t _m = n >> 32;
return _n < 10
? 10 * _m + _n
: rev(_n / 10 + (uint64_t)(10 * _m + _n % 10) * 65536 * 65536)
;
}
int main(){
uint32_t n = 12345;
n = rev(n);
}
Essentially the coefficient is stored in the higher order bits of n. In many ways this is a terrible contrivance since all I'm doing is using a single parameter where there should be two parameters, and I'm relying on a (well-defined) narrowing unsigned conversion at the call site! But it does show the elegance of using the fixed width unsigned types.
How about this?
#include <stdio.h>
#include <math.h>
long GetReverse(unsigned long n){
if (n < 10){
return n;
} else {
unsigned long r = GetReverse(n / 10);
int p = snprintf(NULL, 0, "%lu", r);
return lround(pow(10, p)) * (n % 10) + r;
}
}
int main(void){
unsigned long n = 112233445566778899;
printf("%lu", GetReverse(n));
return 0;
}
To place the last digit first you need to multiply it by 10 once for each digit in the number:
#include <math.h>
long GetReverse(unsigned long n)
{
if (n < 10)
return n; // Removed the % 10 as it is not needed when n is < 10
else {
long digit = n%10;
long factor = (long) pow(10, (int)log(n));
return digit * factor + GetReverse(n / 10);
}
}
log and pow is used instead of loops to calculate the number of digits in n. Note that this may fail unless the implementation of pow is good enough. I did a test using gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-16) and that combination produced correct results for integer powers of 10 for results that fit in a long.
No loops, no variables, no additional parameters!
#include <stdio.h>
unsigned long reverse(unsigned long num)
{
if (num < 10) return num;
if (num < 100) return 10 * (num %10) + reverse(num/10);
if (num < 1000) return 100 * (num %10) + reverse(num/10);
if (num < 10000) return 1000 * (num %10) + reverse(num/10);
if (num < 100000) return 10000 * (num %10) + reverse(num/10);
if (num < 1000000) return 100000 * (num %10) + reverse(num/10);
if (num < 10000000) return 1000000 * (num %10) + reverse(num/10);
if (num < 100000000) return 10000000 * (num %10) + reverse(num/10);
return 100000000 * (num %10) + reverse(num/10);
}
int main(int argc, char **argv)
{
unsigned long num, rev;
if (argc < 2) return 1;
sscanf(argv[1], "%lu", &num);
rev = reverse(num);
printf("%lu -->> %lu\n", num, rev );
return 0;
}
Or, using a helper function (not a variable)
[note: this has quadratic complexity(on the number of digits)]
unsigned long tencount(unsigned long num)
{
if (num < 10) return 1;
return 10 * tencount( num/10);
}
unsigned long reverse2(unsigned long num)
{
if (num < 10) return num;
return tencount(num) * (num %10) + reverse2(num/10);
}
Assuming a 32bit long you could do it without loops or recursion;
long GetReverse(unsigned long n)
{
unsigned long x = ((n/1000000000) +
((n/100000000)%10)*10 +
((n/10000000)%10)*100 +
((n/1000000)%10)*1000 +
((n/100000)%10)*10000 +
((n/10000)%10)*100000 +
((n/1000)%10)*1000000 +
((n/100)%10)*10000000 +
((n/10)%10)*100000000 +
((n)%10)*1000000000);
return (x/(9*(x%10==0)+1)/
(9*(x%100==0)+1)/
(9*(x%1000==0)+1)/
(9*(x%10000==0)+1)/
(9*(x%100000==0)+1)/
(9*(x%1000000==0)+1)/
(9*(x%10000000==0)+1)/
(9*(x%100000000==0)+1)/
(9*(x%1000000000==0)+1));
}
This is a solution:
int reverse(int i) {
static int p = 0;
if (i==0) { int r = p; p = 0; return r; }
p = 10*p+i%10;
return reverse(i/10);
}
Idea is to use a second argument, but as it is used only to store the partial result a static variable can be used. To be able to reuse the function you just need to reset the static at the end of the recursion.
Becareful as such a function is not an involution means that reverse(reverse(x)) not equals to x, think about x=1000. If you want involution then you need to define it over a C-string that represent the value.
C reverse a number recursively
I have an assignment to create a function that receives a number and return the reversed number.
No loops allowed, and the input is only the number .
Add a helper recursive function. #Art
No static variable, no floating point math needed.
The below meets the goals:
1) Recursion used.
2) Function receives a number and return the reversed number
3) No loops allowed, and the input is only the number
#include <stdio.h>
#include <stdlib.h>
static unsigned reverse_helper(unsigned x, unsigned *pow10) {
if (x < 10) {
*pow10 = 10;
return x;
}
unsigned y = reverse_helper(x / 10, pow10);
y += *pow10 * (x%10);
*pow10 *= 10;
return y;
}
unsigned reverse(unsigned x) {
unsigned pow10 = 1;
unsigned y = reverse_helper(x, &pow10);
printf("%10u %10u\n", x, y);
return y;
}
int main(void) {
reverse(0);
reverse(9);
reverse(10);
reverse(99);
reverse(100);
reverse(1234);
reverse(123456789);
}
Output
0 0
1 1
9 9
10 1
99 99
100 1
1234 4321
123456789 987654321
A solution like OP's yet uses 2 recursive functions.
Recurse function with 1 parameter, no floating-point, no static variables.
// return the great power-of-10 less than n
unsigned long p10(unsigned long n) {
if (n < 10) {
return 1;
}
return p10(n/10) * 10;
}
unsigned long GetReverse(unsigned long n) {
if (n < 10) {
return n;
}
// OPs code
//return 10 * GetReverse(n / 10) + n % 10;
// v----------------v------------------- scale by 1
// | | v-----------v--- scale by a power of 10 <= n
return GetReverse(n / 10) + p10(n)*(n%10);
}
What about calling a function like char* getReverse(int n) So you could use mod and concatenation to obtain the reverse. Then in the caller method int getReverse(int n) you parse the string to int. You could use recursion and then the single line to make the parsing. No loops needed and one parameter.
Here's my completely reentrant version, with no extra variable. It works by using ldiv( num / 10 ) to get quotient and remainder, then returns the remainder multiplied by 10^(num digits in quotient) added to the reverse of the quotient (code is formatted to remove the scroll bar - normally I'd have blank lines and more braces):
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
/* unsigned long power function */
unsigned long lpow( unsigned long base, unsigned long exp )
{
unsigned long result = 1UL;
while ( exp )
{
if ( exp & 1 )
result *= base;
exp >>= 1;
base *= base;
}
return( result );
}
/* count the number of decimal digits */
unsigned long numdigits( unsigned long num )
{
return( floor( log10( num ) ) + 1 );
}
unsigned long reverse( unsigned long in )
{
ldiv_t tmp = ldiv( in, 10UL );
if ( tmp.quot == 0 )
return( tmp.rem );
return( reverse( tmp.quot ) + tmp.rem * lpow( 10, numdigits( tmp.quot ) ) );
}
unsigned long lpow() function from https://stackoverflow.com/a/101613/4756299
unsigned long numdigits() function from https://stackoverflow.com/a/1068870/4756299
Called like this:
int main( int argc, char **argv )
{
for ( int ii = 1; ii < argc; ii++ )
{
unsigned long num = strtoul( argv[ ii ], NULL, 10 );
printf( "Reverse of %lu is %lu\n", num, reverse( num ) );
}
return( 0 );
}
For starters it is unclear why the return type is declared like long while the parameter has the type unsigned long.
long GetReverse(unsigned long n);
^^^^ ^^^^^^^^^^^^^
To have a more large of integers it is better to declare the parameter and the return type like unsigned long long int.
The function can be defined by using a local static variable that will keep the calculated reversed value.
Here it is.
unsigned long long int GetReverse(unsigned long long int n)
{
const unsigned long long int Base = 10;
static unsigned long long int reversed;
unsigned long long int tmp;
reversed = Base * reversed + n % Base;
return (n /= Base ) == 0 ? tmp = reversed, reversed = n, n = tmp, n
: GetReverse(n);
}
In the demonstrative program below there is shown how the function works.
#include <stdio.h>
unsigned long long int GetReverse(unsigned long long int n)
{
const unsigned long long int Base = 10;
static unsigned long long int reversed;
unsigned long long int tmp;
reversed = Base * reversed + n % Base;
return (n /= Base ) == 0 ? tmp = reversed, reversed = n, n = tmp, n
: GetReverse(n);
}
int main(void)
{
const unsigned long long int Base = 10;
for ( unsigned long long int i = 1, n = 0; i < Base; i++ )
{
n = Base * n + i;
printf( "%llu\n", n );
printf( "%llu\n", GetReverse( n ) );
putchar( '\n' );
}
return 0;
}
The program output is
1
1
12
21
123
321
1234
4321
12345
54321
123456
654321
1234567
7654321
12345678
87654321
123456789
987654321
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) ) ;
}