identify bits set in bitmap and print them in string - c

given a unsigned 64 bit integer.
which has multiple bits set in it.
want to process the bitmap and identify the position and return the string according to the position where bit is it.
example: unsigned integer is 12. means 1100 which implies third bit and fourth bit are set. this should print THREE FOUR
function takes unsigned int and returns string.
I looked some pieces of code and i don't see this as a dup of some other question.
char* unsigned_int_to_string(unsigned long int n)
{
unsigned int count = 0;
while(n)
{
int i, iter;
count += n & 1;
n >>= 1;
}
/*** Need help to fill this block ***/
/** should return string THREE FOUR***/
}
#include <stdio.h>
int main()
{
unsigned long int i = 12;
printf("%s", unsigned_int_to_sring(i));
return 0;
}

You could brute force it by having a lookup table which has a word representation for each bit you're interested in.
char* bit_to_word[10] = { "ONE","TWO","THREE","FOUR","FIVE","SIX","SEVEN","EIGHT","NINE","TEN" }; // and so forth...
Then in your function check every bit and if it is set, concatenate the corresponding word from your bit_to_word array. You can safely do this by using the strcat_s function.
strcat_s(number_string, BUF_SIZE, bit_to_word[i]);
One gotcha. After the first word you will want to add a space as well so you might want to keep track of that.
This code checks the first 10 bits of the number and prints out THREE FOUR for the test case. Be aware though that it doesn't do any memory cleanup.
#include <stdio.h>
#include <string.h>
#define BUF_SIZE 2048
char* bit_to_word[10] = { "ONE","TWO","THREE","FOUR","FIVE","SIX","SEVEN","EIGHT","NINE","TEN" };
char* unsigned_int_to_string(unsigned long int n)
{
char* number_string = (char*)malloc(BUF_SIZE);
memset(number_string, 0, BUF_SIZE);
int first_word = 1;
unsigned long int tester = 1;
int err;
for (unsigned long int i = 0; i < 10; i++)
{
if (tester & n)
{
if (!first_word)
{
strcat_s(number_string, BUF_SIZE, " ");
}
err = strcat_s(number_string, BUF_SIZE, bit_to_word[i]);
if (err)
{
printf("Something went wrong...\n");
}
first_word = 0;
}
tester <<= 1;
}
return number_string;
}
int main(int argc, char** argv)
{
char* res = unsigned_int_to_string(0b1100);
printf("%s\n", res);
}

Without writing the actual code, here is the description of a simple algorithm based on a 64 element lookup table of strings. 0 = ZERO, 1 = ONE, 2 = TWO ... 63 = SIXTY THREE. This table will be a 64 element array of strings. For C, you could make a static 2D array using char[256] to hold your strings (or optimize by using the value of the largest string + 1), or you could make a dynamic using malloc in a For Loop)
You then define your output string.
You then write a For Loop, iterating through all the bits using a bit mask (using left shift) if the Bit is set you can concatenate your output string (using strcat) with a space and the contents of your lookup table for that bit position.
Here is a brief code snippet on how you will do the concatenation: (Make sure you output string has enough memory in the outputstring variable to hold the largest string. If you want to be more sophisticated and optimize mem usage, you could use malloc and realloc, but you have to deal with freeing the memory when it is no longer needed.
#include <stdio.h>
#include <string.h>
int main ()
{
char str[80];
strcpy (str,"these ");
strcat (str,"strings ");
strcat (str,"are ");
strcat (str,"concatenated.");
puts (str);
return 0;
}
In your case, bit 3 will be encountered as the first set bit and the output string will then contain "THREE", then on the next iteration bit 4 will be detected as set and the output will be appended as "THREE FOUR".
Note: Because this appears to be an academic problem I would like to point out that there exists here the classical case of complexity vs space trade off. My description above was minimum complexity at the expense of space. Meaning, you will have 64 strings with redundancy in many of these strings. For example: TWENTY TWO, THIRTY TWO, FOURTY TWO, FIFTY TWO, and SIXTY TWO, all contain the string "TWO". Space could be optimized by using half the strings: ZERO, ONE, through NINETEEN, then TWENTY, THIRTY, FORTY, FIFTY, SIXTY. However, your indexing logic will be more complicated for bits greater than TWENTY. for bit 21 you will need to concatenate TWENTY and ONE.

Related

Sorting a finite number of elements where each element takes 1 bit of memory in c

I'm trying to create a type set, that holds like so
typedef struct set
{
char *blocks;
char *numbers;
char blockNum;
};
then in order to create it I do
void createSet(set *newSet)
{
newSet->blockNum = 1;
newSet->blocks = calloc(newSet->blockNum, BYTE_SIZE);
}
I can initially get numbers from [0,127], with no duplicates
so in order to do that, I want to change the nth bit into 1, and then when I want to read the set, I look at the memory that set.blocks take, and check the position of each bit inside it, if a bit is equal to 1, then the number that is equal to the position of that bit is in the set.
here's the code for adding an item
void addItem(set *set, unsigned int item)
{
int blocksToAdd = 0;
int i = 0;
int r = (item / BYTE_SIZE);
int rem=item % BYTE_SIZE;
if (r > set->blockNum)
{
if(r!=0) {
blocksToAdd = r - (set->blockNum);
}
set->blocks = realloc(set->blocks, (set->blockNum + blocksToAdd)*BYTE_SIZE);
}
*(set->blocks+r) = (1 << rem);
}
also, I increase the memory of blocks, by adding the amount of bytes needed to get the nth amount of bits,
so far it kinda works, but when the selected number to add is 7, I get that *blocks: -128 when it supposed to be 128, I guess it happen cause the then *blocks = 1000 0000.
So, I tried working around it but I couldn't get it to work, and I'm pretty sure I'm doing something wrong.
the goal was to store numbers from [0,127] with no duplicates, in a way that each element(number) takes 1 bit of memory.
int num =*(set->blocks+r);
if(num<0) {
set->blocks = (char *)realloc(set->blocks, (set->blockNum + 1)*BYTE_SIZE);
num*=-1;
*(set->blocks+r) = num;
}
Tried doing this to get around it, but it wouldn't work
edit
I managed to fix the issue, by changing blocks from char* to unsigned char*, also allocated 16 bytes from the start since calling relloc to increase the size every time isn't efficient, so I would instead check if I can decrease the memory allocated for set after adding all the items

An issue while trying to print appended array elements in c

I was trying to make an array that contains Fibonacci numbers in C, but I got into trouble. I can't get all of the elements, and some of the elements are wrongly calculated, and I don't know where I am I going wrong.
#include <stdio.h>
int main(void){
int serie[]={1,1},sum=0,size=2;
while(size<=4000000){
serie[size]=serie[size-1]+serie[size-2];
printf("%d\n",serie[size-1]);
size+=1;
}
return 0;
}
Output:
1
2
4
6
11
17
28
45
73
118
191
309
500
809
1309
2118
3427
5545
8972
14517
23489
38006
61495
99501
160996
260497
421493
681990
1103483
1785473
2888956
4674429
7563385
12237814
19801199
32039013
51840212
83879225
135719437
219598662
355318099
574916761
930234860
1505151621
-1859580815
-354429194
2080957287
1726528093
-487481916
1239046177
751564261
1990610438
-1552792597
437817841
-1114974756
-677156915
-1792131671
1825678710
33547039
1859225749
1892772788
-542968759
1349804029
806835270
-2138327997
-1331492727
825146572
-506346155
318800417
-187545738
131254679
-56291059
74963620
18672561
93636181
112308742
205944923
318253665
524198588
842452253
1366650841
-2085864202
-719213361
1489889733
770676372
-2034401191
-1263724819
996841286
-266883533
729957753
463074220
1193031973
1656106193
-1445829130
210277063
-1235552067
-1025275004
2034140225
1008865221
-1251961850
-243096629
-1495058479
-1738155108
1061753709
-676401399
385352310
-291049089
94303221
-196745868
-102442647
-299188515
-401631162
-700819677
-1102450839
-1803270516
1389245941
-414024575
975221366
561196791
1536418157
2097614948
-660934191
--------------------------------
Process exited after 2.345 seconds with return value 3221225477
Press any key to continue . . .
I don't understand why it is giving that output.
int serie[]={1,1}
Declares an array of two elements. As the array has two elements and indices start from zero, it has valid indices - 0 and 1, ie. serie[0] is the first element and serie[1] is the second element.
int size=2;
while(..) {
serie[size]= ...
size+=1;
}
As size starts 2, the expression serie[2] = is invalid. There is no third element in the array and it writes to an unknown memory region. Executing such an action is undefined behavior. There could be some another variable there, some system variable, or memory of another program or it can spawn nasal demons. It is undefined.
If you want to store the output in an array, you need to make sure the array has enough elements to hold the input.
And a tip:
int serie[4000000];
may not work, as it will try to allocate 40000000 * sizeof(int), which assuming sizeof(int) = 4 is 15.2 megabytes of memory. Some systems don't allow to allocate that much memory on stack, so you should move to dynamic allocation.
You're having an integer overflow because the int size is ,at a certain leverl, not big enough to hold the numbers, so the number is wrapping round the size and giving false values.
Your program should be like:
#include <stdio.h>
int main(void){
long long unsigned series[100] = {1,1};
int size = 2;
while(size < 100){
series[size] = series[size-1] + series[size-2];
printf("%llu\n", series[size-1]);
size += 1;
}
return 0;
}
Although, size of long long unsigned is also limited, at a certain level, with such very big numbers in Fibonacci. So this will result in more correct numbers printed, but also will overflow at a certain level. It will overflow when the number exceeds this constant ULLONG_MAX declared in limits.h.
The problem with this code:
#include <stdio.h>
int main(void){
int serie[]={1,1},sum=0,size=2;
while(size<=4000000){
serie[size]=serie[size-1]+serie[size-2];
printf("%d\n",serie[size-1]);
size+=1;
}
return 0;
}
... is that it attempts to store a very long series of numbers (4 million) into a very short array (2 elements). Arrays are fixed in size. Changing the variable size has no effect on the size of the array serie.
The expression serie[size]=... stores numbers outside the bounds of the array every time it's executed because the only legal array index values are 0 and 1. This results in undefined behavior and to be honest you were lucky only to see weird output.
There are a couple of possible solutions. The one that changes your code the least is to simply extend the array. Note that I've made it a static rather than automatic variable, because your implementation probably won't support something of that size in its stack.
#include <stdio.h>
int serie[4000000]={1,1};
int main(void){
int size=2;
while(size<4000000){ // note strict less-than: 4000000 is not a valid index
serie[size]=serie[size-1]+serie[size-2];
printf("%d\n",serie[size-1]);
size+=1;
}
return 0;
}
The more general solution is to store the current term and the two previous terms in the series as three separate integers. It's a little more computationally expensive but doesn't have the huge memory requirement.
#include <limits.h>
#include <stdio.h>
int main(void)
{
int term0=0, term1=1, term2;
while(1)
{
if (term0 > INT_MAX - term1) break;// overflow, stop
term2 = term0 + term1;
printf("%d\n",term2);
term0 = term1;
term1 = term2;
}
return 0;
}
This also has the benefit that it won't print any numbers that have "wrapped around" as a result of exceeding the limits of what can be represented in an 'int`. Of course, you can easily choose another data type in order to get a longer sequence of valid output.
You have two problems:
You need to allocate more space in serie, as much as you are going
to use
Eventually the fib numbers will become too big to fit inside an integer, even a 64bit unsigned integer (long long unsigned), i think 90 or so is about max
See the modified code:
#include <stdio.h>
// Set maximum number of fib numbers
#define MAX_SIZE 90
int main(void) {
// Use 64 bit unsigned integer (can't be negative)
long long unsigned int serie[MAX_SIZE];
serie[0] = 1;
serie[1] = 1;
int sum = 0;
int size = 0;
printf("Fib(0): %llu\n", serie[0]);
printf("Fib(1): %llu\n", serie[1]);
for (size = 2; size < MAX_SIZE; size++) {
serie[size] = serie[size-1] + serie[size-2];
printf("Fib(%i): %llu\n", size, serie[size]);
}
return 0;
}
As you are only printing out the numbers, you don't actually have to store all of them
(only the two previous numbers), but it really doesn't matter if there's only 90.

Estimating memory scope of erlang datastructure

Being a former C programmer and current Erlang hacker one question has popped up.
How do I estimate the memory scope of my erlang datastructures?
Lets say I had an array of 1k integers in C, estimating the memory demand of this is easy, just the size of my array, times the size of an integer, 1k 32bit integers would take up 4kb or memory, and some constant amount of pointers and indexes.
In erlang however estimating the memory usage is somewhat more complicated, how much memory does an entry in erlangs array structure take up?, how do I estimate the size of a dynamically sized integer.
I have noticed that scanning over integers in array is fairly slow in erlang, scanning an array of about 1M integers takes almost a second in erlang, whereas a simple piece of c code will do it in arround 2 ms, this most likely is due to the amount of memory taken up by the datastructure.
I'm asking this, not because I'm a speed freak, but because estimating memory has, at least in my experience, been a good way of determining scalability of software.
My test code:
first the C code:
#include <cstdio>
#include <cstdlib>
#include <time.h>
#include <queue>
#include <iostream>
class DynamicArray{
protected:
int* array;
unsigned int size;
unsigned int max_size;
public:
DynamicArray() {
array = new int[1];
size = 0;
max_size = 1;
}
~DynamicArray() {
delete[] array;
}
void insert(int value) {
if (size == max_size) {
int* old_array = array;
array = new int[size * 2];
memcpy ( array, old_array, sizeof(int)*size );
for(int i = 0; i != size; i++)
array[i] = old_array[i];
max_size *= 2;
delete[] old_array;
}
array[size] = value;
size ++;
}
inline int read(unsigned idx) const {
return array[idx];
}
void print_array() {
for(int i = 0; i != size; i++)
printf("%d ", array[i]);
printf("\n ");
}
int size_of() const {
return max_size * sizeof(int);
}
};
void test_array(int test) {
printf(" %d ", test);
clock_t t1,t2;
t1=clock();
DynamicArray arr;
for(int i = 0; i != test; i++) {
//arr.print_array();
arr.insert(i);
}
int val = 0;
for(int i = 0; i != test; i++)
val += arr.read(i);
printf(" size %g MB ", (arr.size_of()/(1024*1024.0)));
t2=clock();
float diff ((float)t2-(float)t1);
std::cout<<diff/1000<< " ms" ;
printf(" %d \n", val == ((1 + test)*test)/2);
}
int main(int argc, char** argv) {
int size = atoi(argv[1]);
printf(" -- STARTING --\n");
test_array(size);
return 0;
}
and the erlang code:
-module(test).
-export([go/1]).
construct_list(Arr, Idx, Idx) ->
Arr;
construct_list(Arr, Idx, Max) ->
construct_list(array:set(Idx, Idx, Arr), Idx + 1, Max).
sum_list(_Arr, Idx, Idx, Sum) ->
Sum;
sum_list(Arr, Idx, Max, Sum) ->
sum_list(Arr, Idx + 1, Max, array:get(Idx, Arr) + Sum ).
go(Size) ->
A0 = array:new(Size),
A1 = construct_list(A0, 0, Size),
sum_list(A1, 0, Size, 0).
Timing the c code:
bash-3.2$ g++ -O3 test.cc -o test
bash-3.2$ ./test 1000000
-- STARTING --
1000000 size 4 MB 5.511 ms 0
and the erlang code:
1> f(Time), {Time, _} =timer:tc(test, go, [1000000]), Time/1000.0.
2189.418
First, an Erlang variable is always just a single word (32 or 64 bits depending on your machine). 2 or more bits of the word are used as a type tag. The remainder can hold an "immediate" value, such as a "fixnum" integer, an atom, an empty list ([]), or a Pid; or it can hold a pointer to data stored on the heap (tuple, list, "bignum" integer, float, etc.). A tuple has a header word specifying its type and length, followed by one word per element. A list cell on the uses only 2 words (its pointer already encodes the type): the head and tail elements.
For example: if A={foo,1,[]}, then A is a word pointing to a word on the heap saying "I'm a 3-tuple" followed by 3 words containing the atom foo, the fixnum 1, and the empty list, respectively. If A=[1,2], then A is a word saying "I'm a list cell pointer" pointing to the head word (containing the fixnum 1) of the first cell; and the following tail word of the cell is yet another list cell pointer, pointing to a head word containing the 2 and followed by a tail word containing the empty list. A float is represented by a header word and 8 bytes of double precision floating-point data. A bignum or a binary is a header word plus as many words as needed to hold the data. And so on. See e.g. http://stenmans.org/happi_blog/?p=176 for some more info.
To estimate size, you need to know how your data is structured in terms of tuples and lists, and you need to know the size of your integers (if too large, they will use a bignum instead of a fixnum; the limit is 28 bits incl. sign on a 32-bit machine, and 60 bits on a 64-bit machine).
Edit: https://github.com/happi/theBeamBook is a newer good resource on the internals of the BEAM Erlang virtual machine.
Is this what you want?
1> erts_debug:size([1,2]).
4
with it you can at least figure out how big a term is. The size returned is in words.
Erlang has integers as "arrays", so you cannot really estimate it in the same way as c, you can only predict how long your integers will be and calculate average amount of bytes needed to store them
check: http://www.erlang.org/doc/efficiency_guide/advanced.html and you can use erlang:memory() function to determine actual amount

If I have to represent integers and char's in a single array, what would be an acceptable way to do this in C?

Can I declare an int array, then initialize it with chars? I'm trying to print out the state of a game after each move, therefore initially the array will be full of chars, then each move an entry will be updated to an int.
I think the answer is yes, this is permitted and will work because an int is 32 bits and a char is 8 bits. I suppose that each of the chars will be offset by 24 bits in memory from each other, since the address of the n+1'th position in the array will be n+32 bits and a char will only make use of the first 8.
It's not a homework question, just something that came up while I was working on homework. Maybe I'm completely wrong and it won't even compile the way I've set everything up?
EDIT: I don't have to represent them in a single array, as per the title of this post. I just couldn't think of an easier way to do it.
You can also make an array of unions, where each element is a union of either char or int. That way you can avoid having to do some type-casting to treat one as the other and you don't need to worry about the sizes of things.
int and char are numeric types and char is guaranteed smaller than int (therefore supplying a char where an int is expected is safe), so in a nutshell yes you can do that.
Yes it would work, because a char is implicitly convertible to an int.
"I think the answer is yes, this is permitted and will work because an int is 32 bits and a char is 8 bits." this is wrong, an int is not always 32 bits. Also, sizeof(char) is 1, but not necessarily 8 bits.
As explained, char is an int compatible type.
From your explanation, you might initially start with an array of int who's values are char, Then as the game progresses, the char values will no longer be relevant, and become int values. Yes?
IMHO the problem is not putting char into an int, that works and is built into the language.
IMHO using a union to allow the same piece of space to be used to store either type, helps but is not important. Unless you are using an amazingly small microcontroller, the saving in space is not likely relevant.
I can understand why you might want to make it easy to write out the board, but I think that is a tiny part of writing a game, and it is best to keep things simple for the rest of the game, rather than focus on the first few lines of code.
Let's think about the program; consider how to print the board.
At the start it could be:
for (int i=0; i<states; ++i) {
printf("%c ", game_state[i]);
}
Then as the game progresses, some of those values will be int.
The issue to consider is "which format is needed to print the value in the 'cell'?".
The %c format prints a single char.
I presume you would like to see the int values printed differently from ordinary printed characters? For example, you want to see the int values as integers, i.e. strings of decimal (or hex) digits? That needs a '%d' format.
On my Mac I did this:
#include <stdio.h>
#define MAX_STATE (90)
int main (int argc, const char * argv[]) {
int game_state[MAX_STATE];
int state;
int states;
for (states=0; states<MAX_STATE; ++states) {
game_state[states] = states+256+32;
}
for (int i=0; i<states; ++i) {
printf("%c ", game_state[i]);
}
return 0;
}
The expression states+256+32 guarantees the output character codes are not ASCII, or even ISO-8859-1 and they are not control codes. They are just integers. The output is:
! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? # 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 [ \ ] ^ _ ` 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
I think you'd like the original character to be printed (no data conversion) when the value is the initial character (%c format), but you do want to see data conversion, from a binary number to a string of digit-characters (%d or a relative format). Yes?
So how would the program tell which is which?
You could ensure the int values are not characters (as my program did). Typically, this become a pain, because you are restricted on values, and end up using funny expressions everywhere else just to make that one job easier.
I think it is easier to use a flag which says "the value is still a char" or "the value is an int"
The small saving of space from using a union is rarely worth while, and their are advantages to having the initial state and the current move available.
So I think you end up with something like:
#include <stdio.h>
#define MAX_STATE (90)
int main (int argc, const char * argv[]) {
struct GAME { int cell_state; int move; char start_value } game_state[MAX_STATE];
enum CELL_STATE_ENUM { start_cell, move_cell };
int state;
int states;
for (states=0; (state=getchar())!= EOF && states<MAX_STATE; ++states) {
game_state[states].start_value = state;
game_state[states].cell_state = start_cell;
}
// should be some error checking ...
// ... make some moves ... this is nonsense but shows an idea
for (int i=0; i<states; ++i ) {
if (can_make_move(i)) {
game_state[states].cell_state = move_cell;
game_state[states].move = new_move(i);
}
}
// print the board
for (int i=0; i<states; ++i) {
if (game_state[i].cell_state == start_cell) {
printf("'%c' ", game_state[i].start_value);
} else if (game_state[i].cell_state == move_cell) {
printf("%d ", game_state[i].move);
} else {
fprintf(stderr, "Error, the state of the cell is broken ...\n");
}
}
return 0;
}
The move can be any convenient value, there is nothing to complicate the rest of the program.
Your intent can be made a little more clear my using int8_t or uint8_t from the stdint.h header. This way you say "I'm using a eight bit integer, and I intend for it to be a number."
It's possible and very simple. Here is an example:
int main()
{
// int array initialized with chars
int arr[5] = {'A', 'B', 'C', 'D', 'E'};
int i; // loop counter
for (i = 0; i < 5; i++) {
printf("Element %d id %d/%c\n", i, arr[i], arr[i]);
}
return 0;
}
The output is:
Element 0 is 65/A
Element 1 is 66/B
Element 2 is 67/C
Element 3 is 68/D
Element 4 is 69/E

generate a random number of length 25

eg: 1589745896214758962147852.
This is a question I have been slogging out for a while now.
What are the possible ways?
What is the best practice?
You could just call the random number generator 25 times for each digit - simple if you want this as a string.
If you don't have a random number function available there is a simple to implement one.
http://xkcd.com/221/
This is a nice question...
You can use OpennSsl BIGNUM.
This is a simple fatorial example.
#include <stdio.h>
#include <openssl/bn.h>
int main(int argc, char **argv)
{
BIGNUM *fat;
BN_ULONG a, f;
char *resp;
int i;
fat = BN_new();
for (i = 1; i < argc; i++) {
f = atoll(argv[i]);
BN_dec2bn(&fat, "1");
for (a = 2; a <= f; a++) {
BN_mul_word(fat, a);
}
resp = BN_bn2dec(fat);
printf("Fatorial of %s = %s\n", argv[i], resp);
}
return 0;
}
I just dicovered a better example:
#include <stdio.h>
#include <openssl/bn.h>
int main(int argc, char **argv)
{
BIGNUM *fat;
char *resp = NULL;
fat = BN_new();
BN_generate_prime(fat, 80, 1, NULL, NULL, NULL, NULL);
resp = BN_bn2dec(fat);
printf("Big Random Value: %s\n", resp);
}
;)
You will have to deal with a string for saving your number.
Because the signed long long min is -9223372036854775808 and max is 9223372036854775807.
1589745896214758962147852 is much more long.
Your problem is ill defined (at time of writing).
If you need exactly 25 digits then you can simply iterate 25 times getting a random number from 0 to 9 and compiling them into a string of digit characters.
If it must be a 25 digit number (i.e. 1025 <= r <= 1026-1) rather than 25 random digits then the first digit must >= 1 (no leading zeroes).
If you require these digits to represent an integer value, upon which you may perform arithmetic operations, rather than a string of digits, then you will be out of luck with C's built-in data types on any likely platform since the value will require at least 85 bits (1025/log(2)).
You can build a 85 bit representation by concatenating the bits returned from a standard random number generator into a byte array If using the standard C library rand() function check your implementation's RAND_MAX value; some implementations only generate 16 bits, so some care is needed to concatenate them since it may not be a whole word of random bits. However to arithmetically manipulate such a number you will have to create arithmetic functions to do that too (or use a "bignum" library).

Resources