Quick way to turn a binary array into a decimal string - c

I have a binary number, stored in an array of bytes (unsigned chars), and want to turn it into a decimal string.
The "obvious" approach that i found online was, to iterate over the array, add everything up while keeping track of the base and then converting it into a string but this doesn't work for me because the whole number doesn't fit into any common datatype and therefor cannot be added up in one go.
typedef unsigned char byte;
typedef struct Bin {
int size;
byte *ptrToVal;
} Bin;
void asDecString(Bin* this) {
signed int n = 0;
for(int i = 0; i < this->size; i++) {
n += this->ptrToVal[i] << (i * 8);
printf("%u\t%u\t%u\n", this->ptrToVal[i], n, i);
}
printf("%u\n", n);
}
The second, slow approach is to store the number in a string and multiply the digits in the string.
I'm looking for a quick way to implement this in c, but because I'm completely new to the language I don't know the features that well.

Out of curiosity and interest, here's my implementation of the algorithm found at:
https://my.eng.utah.edu/~nmcdonal/Tutorials/BCDTutorial/BCDConversion.html
It outputs intermediary values as each bit is processed. The verbose block can be moved out of the loop after testing.
Try it with one or two 'hex' bytes to begin with.
#include <stdio.h>
typedef unsigned char binByte;
void toBCD( binByte *p, int size ) {
const int decSize = 50; // Arbitrary limit of 10^49.
binByte decDgt[ decSize ]; // decimal digits as binary 'nibbles'.
int curPow10 = 0;
memset( decDgt, 0, sizeof(decDgt) );
for( int i = 0; i < size; i++ ) {
binByte oneByte = p[ i ]; // Initial one byte value
for( binByte bit = 0x80; bit > 0; bit >>= 1 ) {
for( int ii = 0; ii <= curPow10; ii++ )
if( decDgt[ ii ] >= 5 ) // Algorithm step
decDgt[ ii ] += 3;
for( ii = curPow10; ii >= 0; ii-- ) {
decDgt[ ii ] <<= 1;
if( decDgt[ ii ] & 0x10 ) { // Carry high bit?
decDgt[ ii + 1 ] |= 0x1;
if( ii == curPow10 ) // new power of 10?
curPow10++;
}
decDgt[ ii ] &= 0xF; // dealing in 'nibbles'
}
decDgt[ 0 ] |= ( (oneByte & bit) != 0 ); // truth value 0 or 1
printf( "Bottom: " );
for( ii = curPow10; ii >= 0; ii-- )
putchar( decDgt[ ii ] + '0' );
putchar( '\n' );
}
}
}
void main( void ) {
binByte x[] = { 0x01, 0xFF, 0xFF, 0xFF, 0xFF };
toBCD( x, sizeof(x) );
}

For large integers; you want to break them into "small enough integers", then convert the "small enough integers" into digits.
For example, lets say you have the number 1234567890. By doing next_piece = number / 100; number = number % 100; you could split it into pieces that fit in one byte, then print the smaller pieces 12, 34, 56, 78, 90 (with nothing between them and leading zeros to ensure the piece 03 doesn't get printed as 3) so that it looks like a single larger number.
In the same way you could split it into pieces that fit in a 32-bit unsigned integer; so that each piece is from 0 to 1000000000, by doing something like next_piece = number / 1000000000; number = number % 1000000000;. For example, the number 11223344556677889900112233445566778899 could be split into 11, 223344556, 677889900, 112233445, 566778899 and then printed (with leading zeros, etc).
Of course for big integers you'd need to implement a "divide by 1000000000" that works with your data structure, that returns a uint32_t (the remainder or the next piece) and the original value divided by 1000000000.
This is where things get messy. Using an array of bytes is slow, and signed numbers are painful. To fix that you'd want something more like:
#include <stdint.h>
typedef struct AlternativeBin {
int signFlag;
int size;
uint32_t *ptrToVal;
} AlternativeBin;
It wouldn't be hard to convert from your original format into this alternative format (if you can't just use this alternative format for everything).
The division loop would look something like (untested):
// WARNING: Destructive (the input value is used to return the quotient)
uint32_t getNextPiece(AlternativeBin * value) {
uint64_t temp = 0;
int i;
// Do the division
for(i = value->size - 1; i >= 0; i--) {
temp = (temp << 32) | value->ptrToVal[i];
value->ptrToVal[i] = temp / 1000000000ULL;
temp = temp % 1000000000ULL;
}
// Reduce the size of the array to improve performance next time
while( (value->size > 0) && (value->ptrToVal[value->size - 1] == 0) ) {
value->size--;
}
return temp;
}
..which means the "printing loop" (using recursion to reverse the order of pieces) might look like (untested):
#include <stdio.h>
#include <inttypes.h>
// WARNING: Recursive and destructive (the input value is destroyed)
void printPieces(AlternativeBin * value) {
uint32_t piece;
piece = getNextPiece(value);
if( !value_became_zero(value) ) {
printPieces(value);
printf("%09" PRIu32, piece); // Print it with leading zeros
} else {
printf("%" PRIu32, piece); // No leading zeros on first piece printed
}
}
The other minor inconvenience is that you'll want to print a '-' at the start if the value is negative (untested):
// WARNING: Destructive (the input value is destroyed)
void printValue(AlternativeBin * value) {
if(value->signFlag) {
printf("-");
}
printPieces(value);
}
If you wanted you could also create a copy of the original data here (get rid of the WARNING: Destructive comment by destroying a copy and leaving the original unmodified); and convert from your original structure (bytes) into the alternative structure (with uint32_t).
Note that it would be possible to do all of this with bytes (something like your original structure) using a divisor of 100 (instead of 1000000000). It'd just be a lot slower because the expensive getNextPiece() function will need to be called about 4.5 as many times.

Related

Getting multiple strings with repeated character [duplicate]

I am trying obtain 9 digit numbers that all have unique digits. My first approach seems a bit too complex and would be tedious to write.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main()
{
int indx;
int num;
int d1, d2, d3, d4, d5, d6, d7, d8, d9;
for(indx = 123456789; indx <= 987654321; indx++)
{
num = indx;
d1 = num % 10;
d2 = ( num / 10 ) % 10;
d3 = ( num / 100 ) % 10;
d4 = ( num / 1000 ) % 10;
d5 = ( num / 10000 ) % 10;
d6 = ( num / 100000 ) % 10;
d7 = ( num / 1000000 ) % 10;
d8 = ( num / 10000000 ) % 10;
d9 = ( num / 100000000 ) % 10;
if( d1 != d2 && d1 != d3 && d1 != d3 && d1 != d4 && d1 != d5
&& d1 != d6 && d1 != d7 && d1 != d8 && d1 != d9 )
{
printf("%d\n", num);
}
}
}
That is just comparing the first number to the rest. I would have to do that many more to compare the other numbers. Is there a better way to do this?
This is a pretty typical example of a problem involving combinatorics.
There are exactly 9⋅8⋅7⋅6⋅5⋅4⋅3⋅2⋅1 = 9! = 362880 nine-digit decimal numbers, where each digit occurs exactly once, and zero is not used at all. This is because there are nine possibilities for the first digit, eight for the second, and so on, since each digit is used exactly once.
So, you can easily write a function, that takes in the seed, 0 ≤ seed < 362880, that returns one of the unique combinations, such that each combination corresponds to exactly one seed. For example,
unsigned int unique9(unsigned int seed)
{
unsigned char digit[9] = { 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U };
unsigned int result = 0U;
unsigned int n = 9U;
while (n) {
const unsigned int i = seed % n;
seed = seed / n;
result = 10U * result + digit[i];
digit[i] = digit[--n];
}
return result;
}
The digit array is initialized to the set of nine thus far unused digits. i indicates the index to that array, so that digit[i] is the actual digit used. Since the digit is used, it is replaced by the last digit in the array, and the size of the array n is reduced by one.
Some example results:
unique9(0U) == 198765432U
unique9(1U) == 218765439U
unique9(10U) == 291765438U
unique9(1000U) == 287915436U
unique9(362878U) == 897654321U
unique9(362879U) == 987654321U
The odd order for the results is because the digits in the digit array switch places.
Edited 20150826: If you want the indexth combination (say, in lexicographic order), you can use the following approach:
#include <stdlib.h>
#include <string.h>
#include <errno.h>
typedef unsigned long permutation_t;
int permutation(char *const buffer,
const char *const digits,
const size_t length,
permutation_t index)
{
permutation_t scale = 1;
size_t i, d;
if (!buffer || !digits || length < 1)
return errno = EINVAL;
for (i = 2; i <= length; i++) {
const permutation_t newscale = scale * (permutation_t)i;
if ((permutation_t)(newscale / (permutation_t)i) != scale)
return errno = EMSGSIZE;
scale = newscale;
}
if (index >= scale)
return errno = ENOENT;
memmove(buffer, digits, length);
buffer[length] = '\0';
for (i = 0; i < length - 1; i++) {
scale /= (permutation_t)(length - i);
d = index / scale;
index %= scale;
if (d > 0) {
const char c = buffer[i + d];
memmove(buffer + i + 1, buffer + i, d);
buffer[i] = c;
}
}
return 0;
}
If you specify digits in increasing order, and 0 <= index < length!, then buffer will be the permutation having indexth smallest value. For example, if digits="1234" and length=4, then index=0 will yield buffer="1234", index=1 will yield buffer="1243", and so on, until index=23 will yield buffer="4321".
The above implementation is definitely not optimized in any way. The initial loop is to calculate the factorial, with overflow detection. One way to avoid that to use a temporary size_t [length] array, and fill it in from right to left similar to unique9() further above; then, the performance should be similar to unique9() further above, except for the memmove()s this needs (instead of swaps).
This approach is generic. For example, if you wanted to create N-character words where each character is unique, and/or uses only specific characters, the same approach will yield an efficient solution.
First, split the task into steps.
Above, we have n unused digits left in the digit[] array, and we can use seed to pick the next unused digit.
i = seed % n; sets i to the remainder (modulus) if seed were to be divided by n. Thus, is an integer i between 0 and n-1 inclusive, 0 ≤ i < n.
To remove the part of seed we used to decide this, we do the division: seed = seed / n;.
Next, we add the digit to our result. Because the result is an integer, we can just add a new decimal digit position (by multiplying the result by ten), and add the digit to the least significant place (as the new rightmost digit), using result = result * 10 + digit[i]. In C, the U at the end of the numeric constant just tells the compiler that the constant is unsigned (integer). (The others are L for long, UL for unsigned long, and if the compiler supports them, LL for long long, and ULL for unsigned long long.)
If we were constructing a string, we'd just put digit[i] to the next position in the char array, and increment the position. (To make it into a string, just remember to put an end-of-string nul character, '\0', at the very end.)
Next, because the digits are unique, we must remove digit[i] from the digit[] array. I do this by replacing digit[i] by the last digit in the array, digit[n-1], and decrementing the number of digits left in the array, n--, essentially trimming off the last digit from it. All this is done by using digit[i] = digit[--n]; which is exactly equivalent to
digit[i] = digit[n - 1];
n = n - 1;
At this point, if n is still greater than zero, we can add another digit, simply by repeating the procedure.
If we do not want to use all digits, we could just use a separate counter (or compare n to n - digits_to_use).
For example, to construct a word using any of the 26 ASCII lowercase letters using each letter at most once, we could use
char *construct_word(char *const str, size_t len, size_t seed)
{
char letter[26] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r',
's', 't', 'u', 'v', 'w', 'x', 'y', 'z' };
size_t n = 26;
if (str == NULL || len < 1)
return NULL;
while (len > 1 && n > 0) {
const size_t i = seed % n;
seed /= n; /* seed = seed / n; */
str[len++] = letter[i];
letter[i] = letter[--n];
}
str[len] = '\0';
return str;
}
Call the function with str pointing to a character array of at least len characters, with seed being the number that identifies the combination, and it'll fill str with a string of up to 26 or len-1 characters (whichever is less) where each lowercase letter occurs at most once.
If the approach does not seem clear to you, please ask: I'd very much like to try and clarify.
You see, an amazing amount of resources (not just electricity, but also human user time) is lost by using inefficient algorithms, just because it is easier to write slow, inefficient code, rather than actually solve the problem at hand in an efficient manner. We waste money and time that way. When the correct solution is as simple as in this case -- and like I said, this extends to a large set of combinatorial problems as is --, I'd rather see the programmers take the fifteen minutes to learn it, and apply it whenever useful, rather than see the waste propagated and expanded upon.
Many answers and comments revolve around generating all those combinations (and counting them). I personally don't see much use in that, because the set is well known already. In practice, you typically want to generate e.g. small subsets -- pairs, triplets, or larger sets -- or sets of subsets that fulfill some criteria; for example, you might wish to generate ten pairs of such numbers, with each nine-digit number used twice, but not in a single pair. My seed approach allows that easily; instead of decimal representation, you work with the consecutive seed values instead (0 to 362879, inclusive).
That said, it is straightforward to generate (and print) all permutations of a given string in C:
#include <stdlib.h>
#include <stdio.h>
unsigned long permutations(char str[], size_t len)
{
if (len-->1) {
const char o = str[len];
unsigned long n = 0U;
size_t i;
for (i = 0; i <= len; i++) {
const char c = str[i];
str[i] = o;
str[len] = c;
n += permutations(str, len);
str[i] = c;
str[len] = o;
}
return n;
} else {
/* Print and count this permutation. */
puts(str);
return 1U;
}
}
int main(void)
{
char s[10] = "123456789";
unsigned long result;
result = permutations(s, 9);
fflush(stdout);
fprintf(stderr, "%lu unique permutations\n", result);
fflush(stderr);
return EXIT_SUCCESS;
}
The permutation function is recursive, but its maximum recursion depth is the string length. The total number of calls to the function is a(N), where N is the length of the string, and a(n)=n⋅a(n-1)+1 (sequence A002627), 623530 calls in this particular case. In general, a(n)≤(1-e)n!, i.e. a(n)<1.7183n!, so the number of calls is O(N!), factorial with respect to number of items permuted. The loop body is iterated one less time compared to the calls, 623529 times here.
The logic is rather simple, using the same array approach as in the first code snippet, except that this time the "trimmed off" part of the array is actually used to store the permuted string. In other words, we swap each character still left with the next character to be trimemd off (or prepended to the final string), do the recursive call, and restore the two characters. Because each modification is undone after each recursive call, the string in the buffer is the same after the call as it was before. Just as if it was never modified in the first place.
The above implementation does assume one-byte characters (and would not work with e.g. multibyte UTF-8 sequences correctly). If Unicode characters, or characters in some other multibyte character set, are to be used, then wide characters should be used instead. Other than the type change, and changing the function to print the string, no other changes are needed.
Given an array of numbers, it is possible to generate the next permutation of those numbers with a fairly simple function (let's call that function nextPermutation). If the array starts with all the numbers in sorted order, then the nextPermutation function will generate all of the possible permutations in ascending order. For example, this code
int main( void )
{
int array[] = { 1, 2, 3 };
int length = sizeof(array) / sizeof(int);
printf( "%d\n", arrayToInt(array, length) ); // show the initial array
while ( nextPermutation(array, length) )
printf( "%d\n", arrayToInt(array, length) ); // show the permutations
}
will generate this output
123
132
213
231
312
321
and if you change the array to
int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
then the code will generate and display all 362880 permutations of those nine numbers in ascending order.
The nextPermutation function has three steps
starting from the end of the array, find the first number (call it x) that is followed by a larger number
starting from the end of the array, find the first number (call it y) that is larger than x, and swap x and y
y is now where x was, and all of the numbers to the right of y are in descending order, swap them so that they are in ascending order
Let me illustrate with an example. Suppose the array has the numbers in this order
1 9 5 4 8 7 6 3 2
The first step would find the 4. Since 8 7 6 3 2 are in descending order, the 4 is the first number (starting from the end of the array) that is followed by a larger number.
The second step would find the 6, since the 6 is the first number (starting from the end of the array) that is larger than 4. After swapping 4 and 6 the array looks like this
1 9 5 6 8 7 4 3 2
Notice that all the numbers to the right of the 6 are in descending order. Swapping the 6 and the 4 didn't change the fact that the last five numbers in the array are in descending order.
The last step is to swap the numbers after the 6 so that they are all in ascending order. Since we know that the numbers are in descending order, all we need to do is swap the 8 with the 2, and the 7 with the 3. The resulting array is
1 9 5 6 2 3 4 7 8
So given any permutation of the numbers, the function will find the next permutation just by swapping a few numbers. The only exception is the last permutation which has all the numbers in reverse order, i.e. 9 8 7 6 5 4 3 2 1. In that case, step 1 fails, and the function returns 0 to indicate that there are no more permutations.
So here's the nextPermutation function
int nextPermutation( int array[], int length )
{
int i, j, temp;
// starting from the end of the array, find the first number (call it 'x')
// that is followed by a larger number
for ( i = length - 2; i >= 0; i-- )
if ( array[i] < array[i+1] )
break;
// if no such number was found (all the number are in reverse order)
// then there are no more permutations
if ( i < 0 )
return 0;
// starting from the end of the array, find the first number (call it 'y')
// that is larger than 'x', and swap 'x' and 'y'
for ( j = length - 1; j > i; j-- )
if ( array[j] > array[i] )
{
temp = array[i];
array[i] = array[j];
array[j] = temp;
break;
}
// 'y' is now where 'x' was, and all of the numbers to the right of 'y'
// are in descending order, swap them so that they are in ascending order
for ( i++, j = length - 1; j > i; i++, j-- )
{
temp = array[i];
array[i] = array[j];
array[j] = temp;
}
return 1;
}
Note that the nextPermutation function works for any array of numbers (the numbers don't need to be sequential). So for example, if the starting array is
int array[] = { 2, 3, 7, 9 };
then the nextPermutation function will find all of the permutations of 2,3,7 and 9.
Just for completeness, here's the arrayToInt function that was used in the main function. This function is only for demonstration purposes. It assumes that the array only contains single digit numbers, and doesn't bother to check for overflows. It'll work for a 9 digit number provided that an int is at least 32-bits.
int arrayToInt( int array[], int length )
{
int result = 0;
for ( int i = 0; i < length; i++ )
result = result * 10 + array[i];
return result;
}
Since there seems to be some interest in the performance of this algorithm, here are some numbers:
length= 2 perms= 2 (swaps= 1 ratio=0.500) time= 0.000msec
length= 3 perms= 6 (swaps= 7 ratio=1.167) time= 0.000msec
length= 4 perms= 24 (swaps= 34 ratio=1.417) time= 0.000msec
length= 5 perms= 120 (swaps= 182 ratio=1.517) time= 0.001msec
length= 6 perms= 720 (swaps= 1107 ratio=1.538) time= 0.004msec
length= 7 perms= 5040 (swaps= 7773 ratio=1.542) time= 0.025msec
length= 8 perms= 40320 (swaps= 62212 ratio=1.543) time= 0.198msec
length= 9 perms= 362880 (swaps= 559948 ratio=1.543) time= 1.782msec
length=10 perms= 3628800 (swaps= 5599525 ratio=1.543) time= 16.031msec
length=11 perms= 39916800 (swaps= 61594835 ratio=1.543) time= 170.862msec
length=12 perms=479001600 (swaps=739138086 ratio=1.543) time=2036.578msec
The CPU for the test was a 2.5Ghz Intel i5 processor. The algorithm generates about 200 million permutations per second, and takes less than 2 milliseconds to generate all of the permutations of 9 numbers.
Also of interest is that, on average, the algorithm only requires about 1.5 swaps per permutation. Half the time, the algorithm just swaps the last two numbers in the array. In 11 of 24 cases, the algorithm does two swaps. So it's only in 1 of 24 cases that the algorithm needs more than two swaps.
Finally, I tried the algorithm with the following two arrays
int array[] = { 1, 2, 2, 3 }; // generates 12 permutations
int array[] = { 1, 2, 2, 3, 3, 3, 4 }; // generates 420 permutations
The number of permutations is as expected and the output appeared to be correct, so it seems that the algorithm also works if the numbers are not unique.
Recursion works nicely here.
#include <stdio.h>
void uniq_digits(int places, int prefix, int mask) {
if (!places) {
printf("%d\n", prefix);
return;
}
for (int i = 0; i < 10; i++) {
if (prefix==0 && i==0) continue;
if ((1<<i)&mask) continue;
uniq_digits(places-1, prefix*10+i, mask|(1<<i));
}
}
int main(int argc, char**argv) {
uniq_digits(9, 0, 0);
return 0;
}
Here is a simple program that will print all permutations of a set of characters. You can easily convert that to generate all the numbers you need:
#include <stdio.h>
static int step(const char *str, int n, const char *set) {
char buf[n + 2];
int i, j, count;
if (*set) {
/* insert the first character from `set` in all possible
* positions in string `str` and recurse for the next
* character.
*/
for (count = 0, i = n; i >= 0; i--) {
for (j = 0; j < i; j++)
buf[j] = str[j];
buf[j++] = *set;
for (; j <= n; j++)
buf[j] = str[j - 1];
buf[j] = '\0';
count += step(buf, n + 1, set + 1);
}
} else {
printf("%s\n", str);
count = 1;
}
return count;
}
int main(int argc, char **argv) {
int total = step("", 0, argc > 1 ? argv[1] : "123456789");
printf("%d combinations\n", total);
return 0;
}
It uses recursion but not bit masks and can be used for any set of characters. It also computes the number of permutations, so you can verify that it produces factorial(n) permutations for a set of n characters.
There are many long chunks of code here. Better to think more and code less.
We would like to generate each possibility exactly once with no wasted effort. It turns out this is possible with only a constant amount of effort per digit emitted.
How would you do this without code? Get 10 cards and write the digits 0 to 9 on them. Draw a row of 9 squares on your tabletop. Pick a card. Put it in the first square, another in the second, etc. When you've picked 9, you have your first number. Now remove the last card and replace it with each possible alternative. (There's only 1 in this case.) Each time all squares are filled, you have another number. When you've done all alternatives for the last square, do it for the last 2. Repeat with the last 3, etc., until you have considered all alternatives for all boxes.
Writing a succinct program to do this is about choosing simple data structures. Use an array of characters for the row of 9 square.
Use another array for the set of cards. To remove an element from the set of size N stored in an array A[0 .. N-1], we use an old trick. Say the element you want to remove is A[I]. Save the value of A[I] off to the side. Then copy the last element A[N-1] "down," overwriting A[I]. The new set is A[0 .. N-2]. This works fine because we don't care about order in a set.
The rest is to use recursive thinking to enumerate all possible alternatives. If I know how to find all selections from a character set of size M into a string of size N, then to get an algorithm, just select each possible character for the first string position, then recur to select the rest of the N-1 characters from the remaining set of size M-1. We get a nice 12-line function:
#include <stdio.h>
// Select each element from the given set into buf[pos], then recur
// to select the rest into pos+1... until the buffer is full, when
// we print it.
void select(char *buf, int pos, int len, char *set, int n_elts) {
if (pos >= len)
printf("%.*s\n", len, buf); // print the full buffer
else
for (int i = 0; i < n_elts; i++) {
buf[pos] = set[i]; // select set[i] into buf[pos]
set[i] = set[n_elts - 1]; // remove set[i] from the set
select(buf, pos + 1, len, set, n_elts - 1); // recur to pick the rest
set[n_elts - 1] = set[i]; // undo for next iteration
set[i] = buf[pos];
}
}
int main(void) {
char buf[9], set[] = "0123456789";
select(buf, 0, 9, set, 10); // select 9 characters from a set of 10
return 0;
}
You didn't mention whether it's okay to put a zero in the first position. Suppose it isn't. Since we understand the algorithm well, it's easy to avoid selecting zero into the first position. Just skip that possibility by observing that !pos in C has the value 1 if pos is 0 and 0. If you don't like this slightly obscure idiom, try (pos == 0 ? 1 : 0) as a more readable replacement:
#include <stdio.h>
void select(char *buf, int pos, int len, char *set, int n_elts) {
if (pos >= len)
printf("%.*s\n", len, buf);
else
for (int i = !pos; i < n_elts; i++) {
buf[pos] = set[i];
set[i] = set[n_elts - 1];
select(buf, pos + 1, len, set, n_elts - 1);
set[n_elts - 1] = set[i];
set[i] = buf[pos];
}
}
int main(void) {
char buf[9], set[] = "0123456789";
select(buf, 0, 9, set, 10);
return 0;
}
You can use a mask to set flags into, the flags being wether a digit has already been seen in the number or not. Like this:
int mask = 0x0, j;
for(j= 1; j<=9; j++){
if(mask & 1<<(input%10))
return 0;
else
mask |= 1<<(input%10);
input /= 10;
}
return !(mask & 1);
The complete program:
#include <stdio.h>
int check(int input)
{
int mask = 0x0, j;
for(j= 1; j<=9; j++){
if(mask & 1<<(input%10))
return 0;
else
mask |= 1<<(input%10);
input /= 10;
}
/* At this point all digits are unique
We're not interested in zero, though */
return !(mask & 1);
}
int main()
{
int indx;
for( indx = 123456789; indx <=987654321; indx++){
if( check(indx) )
printf("%d\n",indx);
}
}
Edited...
Or you could do the same with an array:
int check2(int input)
{
int j, arr[10] = {0,0,0,0,0,0,0,0,0,0};
for(j=1; j<=9; j++) {
if( (arr[input%10]++) || (input%10 == 0) )
return 0;
input /= 10;
}
return 1;
}
Here's one approach - start with an array of unique digits, then randomly shuffle them:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
int main( void )
{
char digits[] = "123456789";
srand( time( NULL ) );
size_t i = sizeof digits - 1;
while( i )
{
size_t j = rand() % i;
char tmp = digits[--i];
digits[i] = digits[j];
digits[j] = tmp;
}
printf( "number is %s\n", digits );
return 0;
}
Some sample output:
john#marvin:~/Development/snippets$ ./nine
number is 249316578
john#marvin:~/Development/snippets$ ./nine
number is 928751643
john#marvin:~/Development/snippets$ ./nine
number is 621754893
john#marvin:~/Development/snippets$ ./nine
number is 317529864
Note that these are character strings of unique decimal digits, not numeric values; if you want the corresponding integer value, you'd need to do a conversion like
long val = strtol( digits, NULL, 10 );
Rather than 10 variables, I would make a single variable with a bit set (and testable) for each of the 10 digits. Then you only need a loop setting (and testing) the bit corresponding to each digit. Something like this:
int ok = 1;
unsigned bits = 0;
int digit;
unsigned powers10 = 1;
for (digit = 0; digit < 10; ++digit) {
unsigned bit = 1 << ((num / powers10) % 10);
if ((bits & bit) != 0) {
ok = 0;
break;
}
bits |= bit;
powers10 *= 10;
}
if (ok) {
printf("%d\n", num);
}
Complete program (discarding unnecessary #include lines):
#include <stdio.h>
int main(void)
{
int indx;
int num;
for(indx = 123456789; indx <= 987654321; indx++)
{
num = indx;
int ok = 1;
unsigned bits = 0;
int digit;
unsigned powers10 = 1;
for (digit = 0; digit < 9; ++digit) {
unsigned bit = 1 << ((num / powers10) % 10);
if ((bit == 1) || ((bits & bit) != 0)) {
ok = 0;
break;
}
bits |= bit;
powers10 *= 10;
}
if (ok) {
printf("%d\n", num);
}
}
return 0;
}
OP clarified his question as I was leaving for work, and I had not focused on the lack of zeroes being requested. (response is updated now). This produces the expected 362880 combinations.
However - there was a comment about one answer being fastest, which prompts a followup. There were (counting this one) three comparable answers. In a quick check:
#Paul Hankin's answer (which counts zeros and gives 3265920 combinations):
real 0m0.951s
user 0m0.894s
sys 0m0.056s
this one:
real 0m49.108s
user 0m49.041s
sys 0m0.031s
#George André's answer (which also produced the expected number of combinations):
real 1m27.597s
user 1m27.476s
sys 0m0.051s
Check this code.
#include<stdio.h>
//it can be done by recursion
void func(int *flag, int *num, int n){ //take 'n' to count the number of digits
int i;
if(n==9){ //if n=9 then print the number
for(i=0;i<n;i++)
printf("%d",num[i]);
printf("\n");
}
for(i=1;i<=9;i++){
//put the digits into the array one by one and send if for next level
if(flag[i-1]==0){
num[n]=i;
flag[i-1]=1;
func(flag,num,n+1);
flag[i-1]=0;
}
}
}
//here is the MAIN function
main(){
int i,flag[9],num[9];
for(i=0;i<9;i++) //take a flag to avoid repetition of digits in a number
flag[i]=0; //initialize the flags with 0
func(flag,num,0); //call the function
return 0;
}
If you have any question feel free to ask.
I recommend Nominal Animal's answer, but if you are only generating this value so you can print it out you can eliminate some of the work and at the same time get a more generic routine using the same method:
char *shuffle( char *digit, int digits, int count, unsigned int seed )
{
//optional: do some validation on digit string
// ASSERT(digits == strlen(digit));
//optional: validate seed value is reasonable
// for(unsigned int badseed=1, x=digits, y=count; y > 0; x--, y--)
// badseed *= x;
// ASSERT(seed < badseed);
char *work = digit;
while(count--)
{
int i = seed % digits;
seed /= digits--;
unsigned char selectedDigit = work[i];
work[i] = work[0];
work[0] = selectedDigit;
work++;
}
work[0] = 0;
//seed should be zero here, else the seed contained extra information
return digit;
}
This method is destructive on the digits passed in, which don't actually have to be numeric, or unique for that matter.
On the off chance that you want the output values generated in sorted increasing order that's a little more work:
char *shuffle_ordered( char *digit, int digits, int count, unsigned int seed )
{
char *work = digit;
int doneDigits = 0;
while(doneDigits < count)
{
int i = seed % digits;
seed /= digits--;
unsigned char selectedDigit = work[i];
//move completed digits plus digits preceeding selectedDigit over one place
memmove(digit+1,digit,doneDigits+i);
digit[0] = selectedDigit;
work++;
}
work[0] = 0;
//seed should be zero here, else the seed contained extra information
return digit;
}
In either case it's called like this:
for(unsigned int seed = 0; seed < 16*15*14; ++seed)
{
char work[] = "0123456789ABCDEF";
printf("seed=%d -> %s\n",shuffle_ordered(work,16,3,seed));
}
This should print out an ordered list of three digit hex values with no duplicated digits:
seed 0 -> 012
seed 1 -> 013
...
seed 3358 -> FEC
seed 3359 -> FED
I don't know what you are actually doing with these carefully crafted sequences of digits. If some poor sustaining engineer is going to have to come along behind you to fix some bug, I recommend the ordered version, as it is way easier for a human to convert seed from/to sequence value.
Here is a bit ugly but very fast solution using nested for loops.
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#define NINE_FACTORIAL 362880
int main(void) {
//array where numbers would be saved
uint32_t* unique_numbers = malloc( NINE_FACTORIAL * sizeof(uint32_t) );
if( !unique_numbers ) {
printf("Could not allocate memory for the Unique Numbers array.\n");
exit(1);
}
uint32_t n = 0;
int a,b,c,d,e,f,g,h,i;
for(a = 1; a < 10; a++) {
for(b = 1; b < 10; b++) {
if (b == a) continue;
for(c = 1; c < 10; c++) {
if(c==a || c==b) continue;
for(d = 1; d < 10; d++) {
if(d==a || d==b || d==c) continue;
for(e = 1; e < 10; e++) {
if(e==a || e==b || e==c || e==d) continue;
for(f = 1; f < 10; f++) {
if (f==a || f==b || f==c || f==d || f==e)
continue;
for(g = 1; g < 10; g++) {
if(g==a || g==b || g==c || g==d || g==e
|| g==f) continue;
for(h = 1; h < 10; h++) {
if (h==a || h==b || h==c || h==d ||
h==e || h==f || h==g) continue;
for(i = 1; i < 10; i++) {
if (i==a || i==b || i==c || i==d ||
i==e || i==f || i==g || i==h) continue;
// print the number or
// store the number in the array
unique_numbers[n++] = a * 100000000
+ b * 10000000
+ c * 1000000
+ d * 100000
+ e * 10000
+ f * 1000
+ g * 100
+ h * 10
+ i;
}
}
}
}
}
}
}
}
}
// do stuff with unique_numbers array
// n contains the number of elements
free(unique_numbers);
return 0;
}
Same thing using some macros.
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#define l_(b,n,c,p,f) { int i; for(i = 1; i < 10; i++) { \
int j,r=0; for(j=0;j<p;j++){if(i == c[j]){r=1;break;}} \
if(r) continue; c[p] = i; f } }
#define l_8(b,n,c,p) { \
int i; for(i=1; i< 10; i++) {int j, r=0; \
for(j=0; j<p; j++) {if(i == c[j]) {r = 1; break;}} \
if(r)continue; b[n++] = c[0] * 100000000 + c[1] * 10000000 \
+ c[2] * 1000000 + c[3] * 100000 + c[4] * 10000 \
+ c[5] * 1000 + c[6] * 100 + c[7] * 10 + i; } }
#define l_7(b,n,c,p) l_(b,n,c,p, l_8(b,n,c,8))
#define l_6(b,n,c,p) l_(b,n,c,p, l_7(b,n,c,7))
#define l_5(b,n,c,p) l_(b,n,c,p, l_6(b,n,c,6))
#define l_4(b,n,c,p) l_(b,n,c,p, l_5(b,n,c,5))
#define l_3(b,n,c,p) l_(b,n,c,p, l_4(b,n,c,4))
#define l_2(b,n,c,p) l_(b,n,c,p, l_3(b,n,c,3))
#define l_1(b,n,c,p) l_(b,n,c,p, l_2(b,n,c,2))
#define get_unique_numbers(b,n,c) do {int i; for(i=1; i<10; i++) { \
c[0] = i; l_1(b,n,c,1) } } while(0)
#define NINE_FACTORIAL 362880
int main(void) {
//array where numbers would be saved
uint32_t* unique_numbers = malloc( NINE_FACTORIAL * sizeof(uint32_t) );
if( !unique_numbers ) {
printf("Could not allocate memory for the Unique Numbers array.\n");
exit(1);
}
int n = 0;
int current_number[8] = {0};
get_unique_numbers(unique_numbers, n, current_number);
// do stuff with unique_numbers array
// NINE_FACTORIAL is the number of elements
free(unique_numbers);
return 0;
}
I am sure there are better ways to write those macros, but that is what I could think of.
A simple way is to create an array with nine distinct values, shuffle it, and print the shuffled array. Repeat as many times as needed. For example, using the standard rand() function as a basis for shuffling ...
#include <stdlib.h> /* for srand() and rand */
#include <time.h> /* for time() */
#include <stdio.h>
#define SIZE 10 /* size of working array. There are 10 numeric digits, so .... */
#define LENGTH 9 /* number of digits we want to output. Must not exceed SIZE */
#define NUMBER 12 /* number of LENGTH digit values we want to output */
void shuffle(char *buffer, int size)
{
int i;
char temp;
for (i=size-1; i>0; --i)
{
/* not best way to get a random value of j in [0, size-1] but
sufficient for illustrative purposes
*/
int j = rand()%size;
/* swap buffer[i] and buffer[j] */
temp = buffer[i];
buffer[i] = buffer[j];
buffer[j] = temp;
}
}
void printout(char *buffer, int length)
{
/* this assumes SIZE <= 10 and length <= SIZE */
int i;
for (i = 0; i < length; ++i)
printf("%d", (int)buffer[i]);
printf("\n");
}
int main()
{
char buffer[SIZE];
int i;
srand((unsigned)time(NULL)); /* seed for rand(), once and only once */
for (i = 0; i < SIZE; ++i) buffer[i] = (char)i; /* initialise buffer */
for (i = 0; i < NUMBER; ++i)
{
/* keep shuffling until first value in buffer is non-zero */
do shuffle(buffer, SIZE); while (buffer[0] == 0);
printout(buffer, LENGTH);
}
return 0;
}
This prints a number of lines to stdout, each with 9 unique digits. Note that this does not prevent duplicates.
EDIT: After further analysis, more recursion unrolling and only iterating on set bits resulted in significant improvement, in my testing roughly FIVE times as fast. This was tested with OUTPUT UNSET to compare algorithm speed not console output, start point is uniq_digits9 :
int counter=0;
int reps=0;
void show(int x)
{
#ifdef OUTPUT
printf("%d\n", x);
#else
counter+=x;
++reps;
#endif
}
int bit_val(unsigned int v)
{
static const int MultiplyDeBruijnBitPosition2[32] =
{
0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
};
return MultiplyDeBruijnBitPosition2[(unsigned int)(v * 0x077CB531U) >> 27];
}
void uniq_digits1(int prefix, unsigned int used) {
show(prefix*10+bit_val(~used));
}
void uniq_digits2(int prefix, unsigned int used) {
int base=prefix*10;
unsigned int unused=~used;
while (unused) {
unsigned int diff=unused & (unused-1);
unsigned int bit=unused-diff;
unused=diff;
uniq_digits1(base+bit_val(bit), used|bit);
}
}
void uniq_digits3(int prefix, unsigned int used) {
int base=prefix*10;
unsigned int unused=~used;
while (unused) {
unsigned int diff=unused & (unused-1);
unsigned int bit=unused-diff;
unused=diff;
uniq_digits2(base+bit_val(bit), used|bit);
}
}
void uniq_digits4(int prefix, unsigned int used) {
int base=prefix*10;
unsigned int unused=~used;
while (unused) {
unsigned int diff=unused & (unused-1);
unsigned int bit=unused-diff;
unused=diff;
uniq_digits3(base+bit_val(bit), used|bit);
}
}
void uniq_digits5(int prefix, unsigned int used) {
int base=prefix*10;
unsigned int unused=~used;
while (unused) {
unsigned int diff=unused & (unused-1);
unsigned int bit=unused-diff;
unused=diff;
uniq_digits4(base+bit_val(bit), used|bit);
}
}
void uniq_digits6(int prefix, unsigned int used) {
int base=prefix*10;
unsigned int unused=~used;
while (unused) {
unsigned int diff=unused & (unused-1);
unsigned int bit=unused-diff;
unused=diff;
uniq_digits5(base+bit_val(bit), used|bit);
}
}
void uniq_digits7(int prefix, unsigned int used) {
int base=prefix*10;
unsigned int unused=~used;
while (unused) {
unsigned int diff=unused & (unused-1);
unsigned int bit=unused-diff;
unused=diff;
uniq_digits6(base+bit_val(bit), used|bit);
}
}
void uniq_digits8(int prefix, unsigned int used) {
int base=prefix*10;
unsigned int unused=~used;
while (unused) {
unsigned int diff=unused & (unused-1);
unsigned int bit=unused-diff;
unused=diff;
uniq_digits7(base+bit_val(bit), used|bit);
}
}
void uniq_digits9() {
unsigned int used=~((1<<10)-1); // set all bits except 0-9
#ifndef INCLUDE_ZEROS
used |= 1;
#endif
for (int i = 1; i < 10; i++) {
unsigned int bit=1<<i;
uniq_digits8(i,used|bit);
}
}
Brief explanation:
There are 9 digits and the first cannot start with zero, so the first digit can be from 1 to 9, the rest can be 0 to 9
If we take a number, X and multiply it by 10, it shifts one place over. So, 5 becomes 50. Add a number, say 3 to make 53, and then multiply by 10 to get 520, and then add 2, and so on for all 9 digits.
Now some storage is needed to keep track of what digits were used so they aren't repeated. 10 true/false variables could be used: used_0_p, used_1_P , .... But, that is inefficient, so they can be placed in an array: used_p[10]. But then it would need to be copied every time before making a call the next place so it can reset it for the next digit, otherwise once all places are filled the first time the array would be all true and no other combinations could be calculated.
But, there is a better way. Use bits of an int as the array. X & 1 for the first, X & 2, X & 4, X & 8, etc. This sequence can be represented as (1<<X) or take the first bit and shift it over X times.
& is used to test bits, | is used to set them. In each loop we test if the bit was used (1<<i)&used and skip if it was. At the next place we shift the digits for each digit prefix*10+i and set that digit as used used|(1<<i)
Explanation of looping in the EDIT
The loop calculates Y & (Y-1) which zeroes the lowest set bit. By taking the original and subtracting the result the difference is the lowest bit. This will loop only as many times as there are bits: 3,265,920 times instead of 900,000,000 times. Switching from used to unused is just the ~ operator, and since setting is more efficient than unsetting, it made sense to flip
Going from power of two to its log2 was taken from: https://graphics.stanford.edu/~seander/bithacks.html#IntegerLog . This site also details the loop mechanism: https://graphics.stanford.edu/~seander/bithacks.html#DetermineIfPowerOf2
Moving original to the bottom:
This is too long for a comment, but This answer can be make somewhat faster by removing the zero handling from the function: ( See edit for fastest answer )
void uniq_digits(int places, int prefix, int used) {
if (!places) {
printf("%d\n", prefix);
return;
}
--places;
int base=prefix*10;
for (int i = 0; i < 10; i++)
{
if ((1<<i)&used) continue;
uniq_digits(places, base+i, used|(1<<i));
}
}
int main(int argc, char**argv) {
const int num_digits=9;
// unroll top level to avoid if for every iteration
for (int i = 1; i < 10; i++)
{
uniq_digits(num_digits-1, i, 1 << i);
}
return 0;
}
A bit late to the party, but very fast (30 ms here) ...
#include <stdio.h>
#define COUNT 9
/* this buffer is global. intentionally.
** It occupies (part of) one cache slot,
** and any reference to it is a constant
*/
char ten[COUNT+1] ;
unsigned rec(unsigned pos, unsigned mask);
int main(void)
{
unsigned res;
ten[COUNT] = 0;
res = rec(0, (1u << COUNT)-1);
fprintf(stderr, "Res=%u\n", res);
return 0;
}
/* recursive function: consume the mask of available numbers
** until none is left.
** return value is the number of generated permutations.
*/
unsigned rec(unsigned pos, unsigned mask)
{
unsigned bit, res = 0;
if (!mask) { puts(ten); return 1; }
for (bit=0; bit < COUNT; bit++) {
if (! (mask & (1u <<bit)) ) continue;
ten[pos] = '1' + bit;
res += rec(pos+1, mask & ~(1u <<bit));
}
return res;
}
iterative version that uses bits extensively
note that array can be changed to any type, and set in any order
this will "count"the digits in given order
For more explaination look at my first answer (which is less flexible but much faster) https://stackoverflow.com/a/31928246/2963099
In order to make it iterative, arrays were needed to keep state at each level
This also went though quite a bit of optimization for places the optimizer couldn't figure out
int bit_val(unsigned int v) {
static const int MultiplyDeBruijnBitPosition2[32] = {
0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
};
return MultiplyDeBruijnBitPosition2[(unsigned int)(v * 0x077CB531U) >> 27];
}
void uniq_digits(const int array[], const int length) {
unsigned int unused[length-1]; // unused prior
unsigned int combos[length-1]; // digits untried
int digit[length]; // printable digit
int mult[length]; // faster calcs
mult[length-1]=1; // start at 1
for (int i = length-2; i >= 0; --i)
mult[i]=mult[i+1]*10; // store multiplier
unused[0]=combos[0]=((1<<(length))-1); // set all bits 0-length
int depth=0; // start at top
digit[0]=0; // start at 0
while(1) {
if (combos[depth]) { // if bits left
unsigned int avail=combos[depth]; // save old
combos[depth]=avail & (avail-1); // remove lowest bit
unsigned int bit=avail-combos[depth]; // get lowest bit
digit[depth+1]=digit[depth]+mult[depth]*array[bit_val(bit)]; // get associated digit
unsigned int rest=unused[depth]&(~bit); // all remaining
depth++; // go to next digit
if (depth!=length-1) { // not at bottom
unused[depth]=combos[depth]=rest; // try remaining
} else {
show(digit[depth]+array[bit_val(rest)]); // print it
depth--; // stay on same level
}
} else {
depth--; // go back up a level
if (depth < 0)
break; // all done
}
}
}
Some timings using just 1 to 9 with 1000 reps:
15.00s Recursive (modified to count 1 to 9) from https://stackoverflow.com/a/31828305/2963099
3.53s swap recursion from https://stackoverflow.com/a/31830671/2963099
2.74s nextPermutation version (https://stackoverflow.com/a/31885811/2963099)
2.34s This Solution
1.66s unrolled recursive version in EDIT from https://stackoverflow.com/a/31928246/2963099
Make a list with 10 elements with values 0-9. Pull random elements out by rand() /w current length of list, until you have the number of digits you want.

How to generate random 64-bit unsigned integer in C

I need generate random 64-bit unsigned integers using C. I mean, the range should be 0 to 18446744073709551615. RAND_MAX is 1073741823.
I found some solutions in the links which might be possible duplicates but the answers mostly concatenates some rand() results or making some incremental arithmetic operations. So results are always 18 digits or 20 digits. I also want outcomes like 5, 11, 33387, not just 3771778641802345472.
By the way, I really don't have so much experience with the C but any approach, code samples and idea could be beneficial.
Concerning "So results are always 18 digits or 20 digits."
See #Thomas comment. If you generate random numbers long enough, code will create ones like 5, 11 and 33387. If code generates 1,000,000,000 numbers/second, it may take a year as very small numbers < 100,000 are so rare amongst all 64-bit numbers.
rand() simple returns random bits. A simplistic method pulls 1 bit at a time
uint64_t rand_uint64_slow(void) {
uint64_t r = 0;
for (int i=0; i<64; i++) {
r = r*2 + rand()%2;
}
return r;
}
Assuming RAND_MAX is some power of 2 - 1 as in OP's case 1073741823 == 0x3FFFFFFF, take advantage that 30 at least 15 bits are generated each time. The following code will call rand() 5 3 times - a tad wasteful. Instead bits shifted out could be saved for the next random number, but that brings in other issues. Leave that for another day.
uint64_t rand_uint64(void) {
uint64_t r = 0;
for (int i=0; i<64; i += 15 /*30*/) {
r = r*((uint64_t)RAND_MAX + 1) + rand();
}
return r;
}
A portable loop count method avoids the 15 /*30*/ - But see 2020 edit below.
#if RAND_MAX/256 >= 0xFFFFFFFFFFFFFF
#define LOOP_COUNT 1
#elif RAND_MAX/256 >= 0xFFFFFF
#define LOOP_COUNT 2
#elif RAND_MAX/256 >= 0x3FFFF
#define LOOP_COUNT 3
#elif RAND_MAX/256 >= 0x1FF
#define LOOP_COUNT 4
#else
#define LOOP_COUNT 5
#endif
uint64_t rand_uint64(void) {
uint64_t r = 0;
for (int i=LOOP_COUNT; i > 0; i--) {
r = r*(RAND_MAX + (uint64_t)1) + rand();
}
return r;
}
The autocorrelation effects commented here are caused by a weak rand(). C does not specify a particular method of random number generation. The above relies on rand() - or whatever base random function employed - being good.
If rand() is sub-par, then code should use other generators. Yet one can still use this approach to build up larger random numbers.
[Edit 2020]
Hallvard B. Furuseth provides as nice way to determine the number of bits in RAND_MAX when it is a Mersenne Number - a power of 2 minus 1.
#define IMAX_BITS(m) ((m)/((m)%255+1) / 255%255*8 + 7-86/((m)%255+12))
#define RAND_MAX_WIDTH IMAX_BITS(RAND_MAX)
_Static_assert((RAND_MAX & (RAND_MAX + 1u)) == 0, "RAND_MAX not a Mersenne number");
uint64_t rand64(void) {
uint64_t r = 0;
for (int i = 0; i < 64; i += RAND_MAX_WIDTH) {
r <<= RAND_MAX_WIDTH;
r ^= (unsigned) rand();
}
return r;
}
If you don't need cryptographically secure pseudo random numbers, I would suggest using MT19937-64. It is a 64 bit version of Mersenne Twister PRNG.
Please, do not combine rand() outputs and do not build upon other tricks. Use existing implementation:
http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt64.html
Iff you have a sufficiently good source of random bytes (like, say, /dev/random or /dev/urandom on a linux machine), you can simply consume 8 bytes from that source and concatenate them. If they are independent and have a linear distribution, you're set.
If you don't, you MAY get away by doing the same, but there is likely to be some artefacts in your pseudo-random generator that gives a toe-hold for all sorts of hi-jinx.
Example code assuming we have an open binary FILE *source:
/* Implementation #1, slightly more elegant than looping yourself */
uint64_t 64bitrandom()
{
uint64_t rv;
size_t count;
do {
count = fread(&rv, sizeof(rv), 1, source);
} while (count != 1);
return rv;
}
/* Implementation #2 */
uint64_t 64bitrandom()
{
uint64_t rv = 0;
int c;
for (i=0; i < sizeof(rv); i++) {
do {
c = fgetc(source)
} while (c < 0);
rv = (rv << 8) | (c & 0xff);
}
return rv;
}
If you replace "read random bytes from a randomness device" with "get bytes from a function call", all you have to do is to adjust the shifts in method #2.
You're vastly more likely to get a "number with many digits" than one with "small number of digits" (of all the numbers between 0 and 2 ** 64, roughly 95% have 19 or more decimal digits, so really that is what you will mostly get.
If you are willing to use a repetitive pseudo random sequence and you can deal with a bunch of values that will never happen (like even numbers? ... don't use just the low bits), an LCG or MCG are simple solutions. Wikipedia: Linear congruential generator can get you started (there are several more types including the commonly used Wikipedia: Mersenne Twister). And this site can generate a couple prime numbers for the modulus and the multiplier below. (caveat: this sequence will be guessable and thus it is NOT secure)
#include <stdio.h>
#include <stdint.h>
uint64_t
mcg64(void)
{
static uint64_t i = 1;
return (i = (164603309694725029ull * i) % 14738995463583502973ull);
}
int
main(int ac, char * av[])
{
for (int i = 0; i < 10; i++)
printf("%016p\n", mcg64());
}
I have tried this code here and it seems to work fine there.
#include <time.h>
#include <stdlib.h>
#include <math.h>
int main(){
srand(time(NULL));
int a = rand();
int b = rand();
int c = rand();
int d = rand();
long e = (long)a*b;
e = abs(e);
long f = (long)c*d;
f = abs(f);
long long answer = (long long)e*f;
printf("value %lld",answer);
return 0;
}
I ran a few iterations and i get the following outputs :
value 1869044101095834648
value 2104046041914393000
value 1587782446298476296
value 604955295827516250
value 41152208336759610
value 57792837533816000
If you have 32 or 16-bit random value - generate 2 or 4 randoms and combine them to one 64-bit with << and |.
uint64_t rand_uint64(void) {
// Assuming RAND_MAX is 2^31.
uint64_t r = rand();
r = r<<30 | rand();
r = r<<30 | rand();
return r;
}
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
unsigned long long int randomize(unsigned long long int uint_64);
int main(void)
{
srand(time(0));
unsigned long long int random_number = randomize(18446744073709551615);
printf("%llu\n",random_number);
random_number = randomize(123);
printf("%llu\n",random_number);
return 0;
}
unsigned long long int randomize(unsigned long long int uint_64)
{
char buffer[100] , data[100] , tmp[2];
//convert llu to string,store in buffer
sprintf(buffer, "%llu", uint_64);
//store buffer length
size_t len = strlen(buffer);
//x : store converted char to int, rand_num : random number , index of data array
int x , rand_num , index = 0;
//condition that prevents the program from generating number that is bigger input value
bool Condition = 0;
//iterate over buffer array
for( int n = 0 ; n < len ; n++ )
{
//store the first character of buffer
tmp[0] = buffer[n];
tmp[1] = '\0';
//convert it to integer,store in x
x = atoi(tmp);
if( n == 0 )
{
//if first iteration,rand_num must be less than or equal to x
rand_num = rand() % ( x + 1 );
//if generated random number does not equal to x,condition is true
if( rand_num != x )
Condition = 1;
//convert character that corrosponds to integer to integer and store it in data array;increment index
data[index] = rand_num + '0';
index++;
}
//if not first iteration,do the following
else
{
if( Condition )
{
rand_num = rand() % ( 10 );
data[index] = rand_num + '0';
index++;
}
else
{
rand_num = rand() % ( x + 1 );
if( rand_num != x )
Condition = 1;
data[index] = rand_num + '0';
index++;
}
}
}
data[index] = '\0';
char *ptr ;
//convert the data array to unsigned long long int
unsigned long long int ret = _strtoui64(data,&ptr,10);
return ret;
}

Rotating an array of bits in C

I've just started learning C and I'm having some problems with some code I want to write.
Basically I have this struct that is a bit array, with the number of bits in the array, and a pointer to a buffer of chars, that stores the bits.
My strategy for rotating the bit array is simply taking the number of rotations (mod the length to avoid full rotations) and using a simple reversal algorithm to rotate the array.
EDIT:
However, my problem is that I want to rotate the bits in the actual buffer.
I also want to be able to rotate a subsequence of bits within the entire bit array. So for 1101101, I might want to rotate (0-indexed from the left) the subsequence starting at index 2 and ending at index 5. I'm not entirely sure how to use my char buffer to do this.
Thanks for the help!
struct arrayBits{
size_t numBits;
char *buf;
}
The buf array holds 8-bit integers, not bools as I previously mentioned.
The way that I can access and set an individual bit is just by indexing into the byte that holds the bit I want (so for an array ab, ab->buf[index_of_desired_bit/8] and then performing some bitwise operations on it to change the value, for performance reasons.
EDIT: Thanks to everyone for all the suggestions. I've looked at all of them and I believe I understand the code better. Here's the code I ended up writing, however, I think there are some problems with it.
While it passes some of my basic test cases, it seems to run a little too fast on an bitarray of size 98775 bits, randomly filled. By this I mean, is there some case in which my code just outright fails and crashes? The test cases do three rotations, in a row, on the full 98775-bit array. One rotation of -98775/4 (<--this is a size_t, so wrap around?), one rotation of 98775/4, and then a final rotation of 98775/2.
Is there something I'm missing or some problem I'm not seeing?
/*Reverse a bit array*/
/*v1.1: basic bit reversal w/o temp variable*/
static void arrayReversal(bitarray_t *ba, size_t begin, size_t end){
while(begin < end)
{
bitarray_set(ba, begin, (bitarray_get(ba, begin) ^ bitarray_get(ba, end))); /*x = x ^ y*/
bitarray_set(ba, end, (bitarray_get(ba, begin) ^ bitarray_get(ba, end))); /*y = x ^ y*/
bitarray_set(ba, begin, (bitarray_get(ba, begin) ^ bitarray_get(ba, end))); /*x = x ^ y*/
begin++;
end--;
}
}
/*Main Rotation Routine*/
void bitarray_rotate(bitarray_t *ba, size_t bit_off, size_t bit_len, ssize_t bit_right_amount) {
assert(bit_off + bit_len <= ba->bit_sz);
assert(bit_off + bit_len > 0);
if(bit_off + bit_len > ba->bit_sz || bit_off + bit_len < 0)
{
printf("\nError: Indices out of bounds\n");
return;
}
/*Find index to split bitarray on*/
if(bit_len == 0) return; //Rotate only 1 bit i.e. no rotation
size_t reversal_index;
reversal_index = modulo(-bit_right_amount, bit_len);
if(reversal_index == 0) return; //No rotation to do
/*3 bit string reversals*/
assert(reversal_index - 1 + bit_off < ba->bit_sz);
/* Reverse A*/
arrayReversal(ba, bit_off, reversal_index - 1 + bit_off);
assert(reversal_index + bit_off < ba->bit_sz);
/*Reverse B*/
arrayReversal(ba, reversal_index + bit_off, (bit_off + bit_len - 1));
/*Reverse ArBr*/
arrayReversal(ba, bit_off, (bit_off + bit_len -1));
}
Well the easy way to start is to consider how to rotate the bits in a single value. Let's say that you have x, which is an N-bit value and you want to rotate it by k places. (I'm only going to look at rotating upwards/left, it is easy to convert to downwards/right). The first thing to observe is that if k=N then x is unchanged. So before rotating we want to reduce k modulo N to throw away complete rotations.
Next we should observe that during the rotation the k upper-bits will move to the bottom of the value, and the lower N-k bits will move up k places. This is the same as saying that the top k-bits move down N-k places. The reason that we phrase it this way is that C has shift operators, but not rotation.
In psuedo-C we can say:
#define N sizeof(type)*8
type rotate(type x, int k) {
type lower = x & ((1 << (N-k)) - 1);
type upper = x >> (N-k) & ((1 <<k)-1);
return upper | lower;
}
This takes care of the simple atomic case, simply replace type with char or int as appropriate. If type is unsigned then the mask on the value of upper is unnecessary.
The next thing to consider is rotating in an array of values. If you think of the above code as glueing together two halves of a value then for the more complicated case we need to glue together upper and lower parts from different places in the array. If k is small then these places are adjacent in the array, but when k>N we are rotating through more than one intermediate word.
In particular if we are rotating up k places then we are moving bits from k/N words away in the array, and the N bits can span floor(k/N) and ceil(k/N) locations away in the array. Ok, so now we're ready to put it all together. For each word in the array the new upper N-(k mod N) bits will be the lower bits of floor(k/N) words away, and the new lower (k mod N) bits will be the upper bits of ceil(k/N) words away.
In the same psuedo-C (i.e replace type with what you are using) we can say:
#define N sizeof(type)*8
#define ARR_SIZE ...
type rotate(type *x, int k,type *out) {
int r = k % N;
int upperOff = k/N;
int lowerOff = (k+N-1)/N;
for(int i=0; i<ARR_SIZE; i++) {
int lowerPos = (i + ARR_SIZE - lowerOff) % ARR_SIZE
int upperPos = (i + ARR_SIZE - upperOff) % ARR_SIZE
type lower = x[lowerPos] & ((1 << (N-k)) - 1)
type upper = x[upperPos] >> (N-k) & ((1 <<k)-1)
out[i] = upper | lower;
}
}
Anyway, that's a lot more than I was intending to write so I'll quit now. It should be easy enough to convert this to a form that works inplace on a single array, but you'll probably want to fix the types and the range of k first in order to bound the temporary storage.
If you have any more problems in this area then one place to look is bitmap sprite graphics. For example this rotation problem was used to implement scrolling many, many moons ago in 8-bit games.
I would suggest a pointer/offset to a starting point of a bit in the buffer instead of rotating. Feel free to overload any operator that might be useful, operator[] comes to mind.
A rotate(n) would simply be a offset+=n operation. But I find the purpose of your comment about -"However, my problem is that I want to rotate the actual buffer" confusing.
You dont need an extra buffer for rotate (only for output).
You should implement a function for one rotate and loop this, eg: (right-shift variation)
char *itoa2(char *s,size_t i)
{
*s=0;
do {
memmove(s+1,s,strlen(s)+1);
*s='0'+(i&1);
} while( i>>=1 );
return s;
}
size_t bitrotateOne(size_t i)
{
return i>>1 | (i&1) << (sizeof i<<3)-1;
}
...
size_t i=12,num=17;
char b[129];
while( num-- )
{
i = bitrotateOne(i);
puts( itoa2(b,i) );
}
Since your criteria is so complex, I think the easiest way to do it would be to step through each bit and set where it would be in your new array. You could speed it up for some operations by copying a whole character if it is outside the shifted bits, but I can't think of how to reliably do shifting taking into account all the variables because the start and end of the shifted sequence can be in the middle of bytes and so can the end of the entire bits. The key is to get the new bit position for a bit in the old array:
j = (i < startBit || i >= startBit + length) ? i :
((i - startBit + shiftRightCount) % length) + startBit;
Code:
#include "stdafx.h"
#include <stdlib.h>
#include <string.h>
typedef struct {
size_t numBits;
unsigned char *buf;
} ARRAYBITS;
// format is big endian, shiftint left 8 bits will shift all bytes to a lower index
ARRAYBITS rotateBits(ARRAYBITS *pOriginalBits, int startBit, int length, int shiftRightCount);
void setBit(unsigned char *buf, int bit, bool isSet);
bool checkBit(unsigned char *buf, int bit);
ARRAYBITS fromString(char *onesAndZeros);
char *toString(ARRAYBITS *pBits);
int _tmain(int argc, _TCHAR* argv[])
{
char input[1024];
ARRAYBITS bits = fromString("11110000110010101110"); // 20 bits
ARRAYBITS bitsA = rotateBits(&bits, 0, bits.numBits, 1);
ARRAYBITS bitsB = rotateBits(&bits, 0, bits.numBits, -1);
ARRAYBITS bitsC = rotateBits(&bits, 6, 8, 4);
ARRAYBITS bitsD = rotateBits(&bits, 6, 8, -2);
ARRAYBITS bitsE = rotateBits(&bits, 6, 8, 31);
ARRAYBITS bitsF = rotateBits(&bits, 6, 8, -31);
printf("Starting : %s\n", toString(&bits));
printf("All right 1: %s\n", toString(&bitsA));
printf("All left 1 : %s\n", toString(&bitsB));
printf("\n");
printf(" : ********\n");
printf("Starting : %s\n", toString(&bits));
printf("6,8,4 : %s\n", toString(&bitsC));
printf("6,8,-2 : %s\n", toString(&bitsD));
printf("6,8,31 : %s\n", toString(&bitsE));
printf("6,8,-31 : %s\n", toString(&bitsF));
gets(input);
}
ARRAYBITS rotateBits(ARRAYBITS *pOriginalBits, int startBit, int length, int shiftRightCount)
{
// 0-8 == 1, 9-16 == 2, 17-24 == 3
ARRAYBITS newBits;
int i = 0, j = 0;
int bytes = 0;
while (shiftRightCount < 0)
shiftRightCount += length;
shiftRightCount = shiftRightCount % length;
newBits.numBits = pOriginalBits->numBits;
if (pOriginalBits->numBits <= 0)
return newBits;
bytes = ((pOriginalBits->numBits -1) / 8) + 1;
newBits.buf = (unsigned char *)malloc(bytes);
memset(newBits.buf, 0, bytes);
for (i = 0; i < pOriginalBits->numBits; i++) {
j = (i < startBit || i >= startBit + length) ? i : ((i - startBit + shiftRightCount) % length) + startBit;
if (checkBit(pOriginalBits->buf, i))
{
setBit(newBits.buf, j, true);
}
}
return newBits;
}
void setBit(unsigned char *buf, int bit, bool isSet)
{
int charIndex = bit / 8;
unsigned char c = 1 << (bit & 0x07);
if (isSet)
buf[charIndex] |= c;
else
buf[charIndex] &= (c ^ 255);
}
bool checkBit(unsigned char *buf, int bit)
{
// address of char is (bit / 8), bit within char is (bit & 7)
int index = bit / 8;
int b = bit & 7;
int value = 1 << b;
return ((buf[index] & value) > 0);
}
ARRAYBITS fromString(char *onesAndZeros)
{
int i;
ARRAYBITS bits;
int charCount;
bits.numBits = strlen(onesAndZeros);
charCount = ((bits.numBits -1) / 8) + 1;
bits.buf = (unsigned char *)malloc(charCount);
memset(bits.buf, 0, charCount);
for (i = 0; i < bits.numBits; i++)
{
if (onesAndZeros[i] != '0')
setBit(bits.buf, i, true);
}
return bits;
}
char *toString(ARRAYBITS *pBits)
{
char *buf = (char *)malloc(pBits->numBits + 1);
int i;
for (i = 0; i < pBits->numBits; i++)
{
buf[i] = checkBit(pBits->buf, i) ? '1' : '0';
}
buf[i] = 0;
return buf;
}
I suggest you use bit-level operations (>>,<<,~,&,|) rather than wasting space using int. Even so, using an int array, to rotate, pass the left & right index of substring:
void rotate ( struct arrayBits a, int left , int right )
{
int i;
int first_bit;
if(*( a.buf + right ) == 1) first_bit = 1;
else first_bit = 0;
for( i = left+1 ; i <= right ; i++ )
{
*( a.buf + i )=*( a.buf + i - 1 );
}
*a.buf = first_bit;
}
Example:
If struct_array is 010101,
rotate (struct_array,0,5); => rotates whole string 1 int to right
o/p: 101010
rotate (struct_array,2,4); => rotates substring 1 int to right
o/p: 01 001 1
To reverse the bit array call the rotate() function on the substring, size_of_substring times.

Finding consecutive bit string of 1 or 0

How to find the length of the longest consecutive bit string(either 1 or 0)?
00000000 11110000 00000000 00000000 -> If it is 0 then length will be 20
11111111 11110000 11110111 11111111 -> If it is 1 then length will be 12
The following is based on the concept that if you AND a bit sequence with a shifted version of itself, you're effectively removing the trailing 1 from a row of consecutive 1's.
11101111 (x)
& 11011110 (x << 1)
----------
11001110 (x & (x << 1))
^ ^
| |
trailing 1 removed
Repeating this N times will reduce any sequence with N consecutive 1's to 0x00.
So, to count the number of consecutive 1's:
int count_consecutive_ones(int in) {
int count = 0;
while (in) {
in = (in & (in << 1));
count++;
}
return count;
}
To count the number of consecutive 0's, simply invert and the same routine.
int count_consecutive_zeros(int in) {
return count_consecutive_ones(~in);
}
Proof of concept: http://ideone.com/Z1l0D
int main(void) {
printf("%d has %d consecutive 1's\n", 0, count_consecutive_ones(0));
printf("%d has %d consecutive 0's\n", 0, count_consecutive_zeros(0));
/* 00000000 11110000 00000000 00000000 -> If it is 0 then length will be 20 */
printf("%x has %d consecutive 0's\n", 0x00F00000, count_consecutive_zeros(0x00F00000));
/* 11111111 11110000 11110111 11111111 -> If it is 1 then length will be 12 */
printf("%x has %d consecutive 1's\n", 0xFFF0F7FF, count_consecutive_ones(0xFFF0F7FF));
}
Output:
0 has 0 consecutive 1's
0 has 32 consecutive 0's
f00000 has 20 consecutive 0's
fff0f7ff has 12 consecutive 1's
One simple way would be to simply loop over the bits, and keep track of the number of bits in a row which have had the same value, and the maximum that this value has reached.
Here's a simple C function which does just this:
int num_conseq_matching_bits(int n) {
int i, max, cur, b, prevb;
prevb = n & 1; /* 0th bit */
cur = 1;
max = 1;
for(i=1; i<32; i++) {
b = (n >> i) & 1; /* get the i'th bit's value */
if(b == prevb) {
cur += 1;
if(cur > max)
max = cur;
}
else {
cur = 1; /* count self */
prevb = b;
}
}
return max;
}
You can form a look up table to do it quickly for you. The bigger the table, the faster the lookup. 2x256 entry tables can do 8 bits at a time with a little bit twiddling. Add a 1s version of the table and start adding entries. That's probably how I'd go about it.
To use the table idea, you need something like
static struct {
int lead; /* leading 0 bits */
int max; /* maximum 0 bits */
int trail; /* trailing 0 bits */
} table[256] = { ....data.... };
int mostConsecutiveBits(unsigned char *str, int length, bool count_ones) {
int max = 0; /* max seen so far */
int trail = 0; /* trailing 0s from previous bytes */
while (length-- > 0) {
int byte = *str++;
if (count_ones)
byte ^= 0xff;
if (table[byte].max > max)
max = table[byte].max;
if (trail + table[byte].lead > max)
max = trail + table[byte].lead;
if (byte)
trail = table[byte].trail;
else
trail += 8;
}
return max;
}
initializing the table is straight-forward, but depends on your bit- and byte-ordering (little endian or big endian).
Since you didn't wrote what is bit string (regular int, byte array or char string I've assumed that it's char array
int maxConsBits(char *pStr,char cChar)
{
char curChar;
int curMax = 0;
int max = 0;
while (pStr)
{
if (*pStr == cChar)
{
curMax++;
if (curMax > max)
{
max = curMax;
}
}
else
{
curMax = 0;
}
pStr++;
}
return max;
}
Posting from iPhone withbig fingers.
If ones, then invert.
Loop over the input using a leadz function. For each iteration, shift the input to the left. Continue until you reach the end of the input. Note that you need to compare the original input length with the cumulative leadz counts.
Also, as an optimization, you can early abort when the remaining input length is less than the largest leadz you have seen.
There are many fast leadz algorithms online.
I don't agree with the tables idea, because I was trying it and realized that even though "BA" in ASCII would contain 5 consecutive 0's for 'B' and 5 consecutive 0's for 'A', they will not add together for 10 consecutive 0's. As a matter of fact, there would be 5 consecutive 0's maximum. (This was in reference to a simple "counting bits in a table idea." Chris Dodd has since expounded on how a table could be used accurately.)
I would use an algorithm like this:
#include <iostream>
#include <algorithm>
using namespace std;
// Assumes Little Endian architecture
int mostConsecutiveBits(char str[], int length) {
int currentConsecutiveBits=0;
int maxConsecutiveBits=0;
char currentBit;
char lastBit=0;
char currentChar=str[0];
int charCtr,bitCtr;
for (charCtr=length-1; charCtr>=0; charCtr--) {
currentChar=str[charCtr];
for (bitCtr=0; bitCtr<8; bitCtr++) {
currentBit=currentChar & 1;
if (currentBit!=lastBit) {
maxConsecutiveBits=max(maxConsecutiveBits,currentConsecutiveBits);
currentConsecutiveBits=1;
lastBit=currentBit;
}
else {
currentConsecutiveBits++;
}
currentChar=currentChar>>1;
}
maxConsecutiveBits=max(maxConsecutiveBits,currentConsecutiveBits);
}
return maxConsecutiveBits;
}
int main (int argc, char * const argv[]) {
cout << mostConsecutiveBits("AB",2);
return 0;
}
In this algorithm, I assume the bitstream is represented as 8-bit characters. For each character, I look at the very last bit with a bitwise AND. If it's the same as the last bit, then I up the consecutive bit count, otherwise, I reset the count because the bits are no longer consecutive. I then use a bitwise shift operation to move the next bit in the character over for observation. Hope this helps!
My answer is effectively a duplicate of David Underhill's answer. :)
If you're just looking for a byte string of four bytes, you can pack these into an unsigned long and use an algorithm like this:
int CountConsecutiveOnes(unsigned long n)
{
unsigned long m = n;
int k = 0;
while (m)
{
++k;
n >>= 1;
m &= n;
}
return k;
}
For counting zeros, just taking the bitwise complement first.
If you need to count byte strings longer than four, you can just implement the operations x >>= 1 and x & y either directly on the byte strings or it may be more efficient to use strings of unsigned long so the carry checks on the implementation of x >>= 1 aren't too expensive.
It may help you....
First convert your binary number to String say bits.
It will give you max number of consecutive 1's (in java)
String[] split = bits.split("0");
Arrays.sort(split);
int maxLength = split[split.length - 1].length();
public static int maxConsecutiveOneInBinaryNumber(int number) {
int count = 0;
int max = 0;
while (number != 0) {
if ((number & 1) == 1) {
count++;
} else {
max = Math.max(count, max);
count = 0;
}
number = number >> 1;
}
return Math.max(count, max);
}
You can this code here:
https://github.com/VishalSKumar/DSFiddle/blob/master/src/main/java/com/vishalskumar/hackerrank/MaxConsecutiveOneInBinary.java

Display the binary representation of a number in C? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Is there a printf converter to print in binary format?
Still learning C and I was wondering:
Given a number, is it possible to do something like the following?
char a = 5;
printf("binary representation of a = %b",a);
> 101
Or would i have to write my own method to do the transformation to binary?
There is no direct way (i.e. using printf or another standard library function) to print it. You will have to write your own function.
/* This code has an obvious bug and another non-obvious one :) */
void printbits(unsigned char v) {
for (; v; v >>= 1) putchar('0' + (v & 1));
}
If you're using terminal, you can use control codes to print out bytes in natural order:
void printbits(unsigned char v) {
printf("%*s", (int)ceil(log2(v)) + 1, "");
for (; v; v >>= 1) printf("\x1b[2D%c",'0' + (v & 1));
}
Based on dirkgently's answer, but fixing his two bugs, and always printing a fixed number of digits:
void printbits(unsigned char v) {
int i; // for C89 compatability
for(i = 7; i >= 0; i--) putchar('0' + ((v >> i) & 1));
}
Yes (write your own), something like the following complete function.
#include <stdio.h> /* only needed for the printf() in main(). */
#include <string.h>
/* Create a string of binary digits based on the input value.
Input:
val: value to convert.
buff: buffer to write to must be >= sz+1 chars.
sz: size of buffer.
Returns address of string or NULL if not enough space provided.
*/
static char *binrep (unsigned int val, char *buff, int sz) {
char *pbuff = buff;
/* Must be able to store one character at least. */
if (sz < 1) return NULL;
/* Special case for zero to ensure some output. */
if (val == 0) {
*pbuff++ = '0';
*pbuff = '\0';
return buff;
}
/* Work from the end of the buffer back. */
pbuff += sz;
*pbuff-- = '\0';
/* For each bit (going backwards) store character. */
while (val != 0) {
if (sz-- == 0) return NULL;
*pbuff-- = ((val & 1) == 1) ? '1' : '0';
/* Get next bit. */
val >>= 1;
}
return pbuff+1;
}
Add this main to the end of it to see it in operation:
#define SZ 32
int main(int argc, char *argv[]) {
int i;
int n;
char buff[SZ+1];
/* Process all arguments, outputting their binary. */
for (i = 1; i < argc; i++) {
n = atoi (argv[i]);
printf("[%3d] %9d -> %s (from '%s')\n", i, n,
binrep(n,buff,SZ), argv[i]);
}
return 0;
}
Run it with "progname 0 7 12 52 123" to get:
[ 1] 0 -> 0 (from '0')
[ 2] 7 -> 111 (from '7')
[ 3] 12 -> 1100 (from '12')
[ 4] 52 -> 110100 (from '52')
[ 5] 123 -> 1111011 (from '123')
#include<iostream>
#include<conio.h>
#include<stdlib.h>
using namespace std;
void displayBinary(int n)
{
char bistr[1000];
itoa(n,bistr,2); //2 means binary u can convert n upto base 36
printf("%s",bistr);
}
int main()
{
int n;
cin>>n;
displayBinary(n);
getch();
return 0;
}
Use a lookup table, like:
char *table[16] = {"0000", "0001", .... "1111"};
then print each nibble like this
printf("%s%s", table[a / 0x10], table[a % 0x10]);
Surely you can use just one table, but it will be marginally faster and too big.
There is no direct format specifier for this in the C language. Although I wrote this quick python snippet to help you understand the process step by step to roll your own.
#!/usr/bin/python
dec = input("Enter a decimal number to convert: ")
base = 2
solution = ""
while dec >= base:
solution = str(dec%base) + solution
dec = dec/base
if dec > 0:
solution = str(dec) + solution
print solution
Explained:
dec = input("Enter a decimal number to convert: ") - prompt the user for numerical input (there are multiple ways to do this in C via scanf for example)
base = 2 - specify our base is 2 (binary)
solution = "" - create an empty string in which we will concatenate our solution
while dec >= base: - while our number is bigger than the base entered
solution = str(dec%base) + solution - get the modulus of the number to the base, and add it to the beginning of our string (we must add numbers right to left using division and remainder method). the str() function converts the result of the operation to a string. You cannot concatenate integers with strings in python without a type conversion.
dec = dec/base - divide the decimal number by the base in preperation to take the next modulo
if dec > 0:
solution = str(dec) + solution - if anything is left over, add it to the beginning (this will be 1, if anything)
print solution - print the final number
This code should handle your needs up to 64 bits.
char* pBinFill(long int x,char *so, char fillChar); // version with fill
char* pBin(long int x, char *so); // version without fill
#define width 64
char* pBin(long int x,char *so)
{
char s[width+1];
int i=width;
s[i--]=0x00; // terminate string
do
{ // fill in array from right to left
s[i--]=(x & 1) ? '1':'0'; // determine bit
x>>=1; // shift right 1 bit
} while( x &gt 0);
i++; // point to last valid character
sprintf(so,"%s",s+i); // stick it in the temp string string
return so;
}
char* pBinFill(long int x,char *so, char fillChar)
{ // fill in array from right to left
char s[width+1];
int i=width;
s[i--]=0x00; // terminate string
do
{
s[i--]=(x & 1) ? '1':'0';
x>>=1; // shift right 1 bit
} while( x > 0);
while(i>=0) s[i--]=fillChar; // fill with fillChar
sprintf(so,"%s",s);
return so;
}
void test()
{
char so[width+1]; // working buffer for pBin
long int val=1;
do
{
printf("%ld =\t\t%#lx =\t\t0b%s\n",val,val,pBinFill(val,so,0));
val*=11; // generate test data
} while (val < 100000000);
}
Output:
00000001 = 0x000001 = 0b00000000000000000000000000000001
00000011 = 0x00000b = 0b00000000000000000000000000001011
00000121 = 0x000079 = 0b00000000000000000000000001111001
00001331 = 0x000533 = 0b00000000000000000000010100110011
00014641 = 0x003931 = 0b00000000000000000011100100110001
00161051 = 0x02751b = 0b00000000000000100111010100011011
01771561 = 0x1b0829 = 0b00000000000110110000100000101001
19487171 = 0x12959c3 = 0b00000001001010010101100111000011
You have to write your own transformation. Only decimal, hex and octal numbers are supported with format specifiers.

Resources