How to concatenate bit by bit in c? - c

I have matrix of '1' and '0' with the dimensions 8x8. I need to store the whole matrix in one unsigned long long variable bit by bit. How can i do that?
For example, let's take the matrix of '1' and '0' that is 2x2:
The matrix 2x2:
1 0
0 1
The variable must contain: 1001 in bits.
The same example, but over the matrix 8x8 and unsigned long long variable.
That's what i've tried to do:
#include <stdio.h>
int main()
{
unsigned long long result = 0;
char matrix[8][8]; // lets that the matrix is already filled by '1' and '0'
for (i=0; i<SIZE; i++)
{
for (j=0; j<SIZE; j++)
{
result = result | ((unsigned long long)(matrix[i][j] - '0'));
result <<= 1;
}
}
return 0;
}
Is it right? I implemented this nested loop in my algorithm and that didn't work properly.

Converting the text representation of an integer into its integer value can be done using strtoull().
char buf[sizeof(matrix)+1];
memcpy(buf, matrix, sizeof(matrix));
buf[sizeof(matrix)] = '\0';
result = strtoull(buf, NULL, 2);

try this
const int mx_size = 8;
int main() {
unsigned long long result = 0;
bool matrix[8][8]; // lets that the matrix is already filled by '1' and '0'
for (int i =0; i < mx_size; ++i)
matrix[i][i] = 1;
for (int i = 0; i < mx_size; i++) {
for (int j = 0; j < mx_size; j++) {
result |= (unsigned long long)matrix[i][j] << (i*mx_size + j);
}
}
return 0;
}

Here you have the code (a bit more
#include <stdio.h>
#include <stdint.h>
uint64_t convert(char matrix[8][8], int order, char zero)
{
uint8_t byte;
uint64_t result = 0;
for(size_t row = 0; row < 8; row++)
{
byte = 0;
for(size_t column = 0; column < 8; column++)
{
byte <<= 1;
byte |= matrix[row][column] != zero ? 1 : 0; //anything != defined zero char is 1
}
if (order)
{
result |= (uint64_t)byte << (8 * row);
}
else
{
result |= (uint64_t)byte << (56 - 8 * row);
}
}
return result;
}
int main(void) {
char matrix[8][8] =
{
{'1','0','1','0','1','0','1','0'},
{'0','1','0','1','0','1','0','1'},
{'1','1','1','0','0','0','1','1'},
{'0','0','0','1','1','1','0','0'},
{'1','1','1','1','1','0','0','0'},
{'0','0','0','0','1','1','1','1'},
{'1','1','0','0','1','1','0','0'},
{'0','0','1','1','0','0','1','1'},
};
unsigned long long result = convert(matrix, 0, '0');
for(size_t index = 0; index < 64; index ++)
printf("%1d", !!(result & (1ULL << index)));
printf("\n");
result = convert(matrix,1, '0');
for(size_t index = 0; index < 64; index ++)
printf("%1d", !!(result & (1ULL << index)));
printf("\n");
return 0;
}

Related

Right shifting unsigned variables gives strange result - C / GBDK

I'm developing a gameboy game in GBDK but I've got a problem with right-shifting (8bit) unsigned variables. The code looks like this.
#include <gb/gb.h>
#include <stdio.h>
#define GAME_OBJ_MAX_WIDTH 10
#define GAME_OBJ_MAX_HEIGHT 8
struct game_obj
{
UBYTE matrix[GAME_OBJ_MAX_WIDTH];
UBYTE width, height;
};
void draw_game_obj(struct game_obj *object)
{
for (unsigned char i = 0; i < object->width && i < GAME_OBJ_MAX_WIDTH; i++)
{
printf("BASE->%d\n", object->matrix[i]);
for (unsigned char j = 0; j < object->height && j < GAME_OBJ_MAX_HEIGHT; j++)
printf("Shift by %d->%u\n", j, object->matrix[i] >> j);
}
}
void main() {
struct game_obj racer;
racer.height = 4;
racer.width = 3;
racer.matrix[0] = 10;
racer.matrix[1] = 7;
racer.matrix[2] = 10;
draw_game_obj(&racer);
}
The output is:
BASE->10
Shift by 0->235
Shift by 1->117
Shift by 2->58
Shift by 3->29
BASE->7
Shift by 0->235
Shift by 1->117
Shift by 2->58
Shift by 3->29
BASE->10
Shift by 0->235
Shift by 1->117
Shift by 2->58
Shift by 3->29
Basically any unsigned value right shifted (even by 0) changes to 235, 117, 58 and so on... I'm trying to understand why is that.
Solution
Issue fixed by assigning object->matrix[i] to separate variable.
void draw_game_obj(struct game_obj *object)
{
for (unsigned char i = 0; i < object->width && i < GAME_OBJ_MAX_WIDTH; i++)
{
printf("BASE->%d\n", object->matrix[i]);
UBYTE u = object->matrix[i];
for (unsigned char j = 0; j < object->height && j < GAME_OBJ_MAX_HEIGHT; j++)
printf("Shift by %d->%u\n", j, u >> j);
}
}

make two big number add by array in c code

I want to construct two big number by array in c programming and make them add.
The following is my code:
void add(unsigned char* a, unsigned char* b, unsigned int len)
{
int i;
unsigned short T;
unsigned char carry = 0;
for (i = len - 1; i >= 0; --i)
{
T = (unsigned short)(a[i]) + (unsigned short)(b[i]) + (unsigned short)carry;
//T = a[i] + b[i] + carry;
if (T > 0xFF)
carry = 1;
else
carry = 0;
a[i] = (unsigned char)T;
}
}
The max value in array a and b for every element is 255.
EDIT1: The highest carry is discarded. The result is save in array a.
EDIT2: replace "Byte" with "carry".
The original code is :
Integer B1(B, SM3_BLOCK_SIZE);
++B1;
for (i = 0; i < ILen; i += v)
(Integer(I + i, v) + B1).Encode(I + i, v);
I write two new function. One is as the Above add(), The other is as following:
void add_one(unsigned char *arr, unsigned int len)
{
int i;
for (i = len-1; i >= 0; --i)
{
arr[len] += 1;
if (arr[len] != 0)
return;
}
}
If my code is rigth, the original code is as following:
add_one(B, SM3_BLOCK_SIZE);
for (i = 0; i < ILen; i += v)
add(I + i, B, SM3_BLOCK_SIZE);
There is (at least) one bug. Look at this code:
void add_one(unsigned char *arr, unsigned int len)
{
int i;
for (i = len-1; i >= 0; --i)
{
arr[len] += 1; // Indexing using len is wrong
if (arr[len] != 0) // Indexing using len is wrong
return;
}
}
You probably want to use i as index.
I assumed you know that you are implementing the add function for a bigendian positive integer.
Avoid using for (i = len-1; i >= 0; --i). You can catch a runtime error when i is unsigned and len is 0. Instead, use for (i = len; i-- > 0;).
If you need a little-endian integer than use for (int i = 0; i < len; ++i)
char add(unsigned char* a, unsigned char* b, unsigned int len)
{
unsigned short carry = 0;
//for (int i = 0; i < len; ++i) // for little-endian
for (int i = len; i-- > 0;) // for big-endian
{
carry += a[i] + b[i];
a[i] = carry & 0xFF;
carry >>= 8;
}
return carry;
}
Tests
unsigned char a[5] = {255,2,3,4,5};
unsigned char b[5] = {255,256-2,256-3,4,5};
char overflow = add(a,b,5);
printf("%d %d %d %d %d / %d",a[0],a[1],a[2],a[3],a[4] , overflow);
Output
255 1 0 8 10 / 1

Why is my C code not printing any output?

I am building a version of the Game of Life in ANSI C and I have almost all of the code written for it.
My C source file:
#include <stdio.h>
#include <stdlib.h>
#define HEIGHT 32
#define WIDTH 32
#define COMPASS 8
#define SPACE '.'
unsigned long mask = 0x80000000;
unsigned long neighbours[COMPASS] = { 0 };
unsigned long row[WIDTH] = { 0 };
unsigned long copy[WIDTH] = { 0 };
int northWest(unsigned long row, int rowNum) {
copy[rowNum - 1] = row >>= 1;
return copy[rowNum - 1];
}
int north(unsigned long row, int rowNum) {
copy[rowNum - 1] = row;
return copy[rowNum - 1];
}
int northEast(unsigned long row, int rowNum) {
copy[rowNum - 1] = row <<= 1;
return copy[rowNum - 1];
}
int west(unsigned long row, int rowNum) {
copy[rowNum] = row >>= 1;
return copy[rowNum];
}
int east(unsigned long row, int rowNum) {
copy[rowNum] = row <<= 1;
return copy[rowNum];
}
int southWest(unsigned long row, int rowNum) {
copy[rowNum + 1] = row >>= 1;
return copy[rowNum + 1];
}
int south(unsigned long row, int rowNum) {
copy[rowNum + 1] = row;
return copy[rowNum + 1];
}
int southEast(unsigned long row, int rowNum) {
copy[rowNum + 1] = row <<= 1;
return copy[rowNum + 1];
}
/*void clearRows(unsigned long row[]) {
int i;
system("clear");
for (i = 0; i < HEIGHT; ++i) {
row[i] = 0;
}
}*/
void displayBinary(unsigned long x) {
int bit;
int mask;
for (bit = 0; bit < HEIGHT; ++bit) {
mask = 1 << bit;
printf("%c", (x & mask) ? 'X' : SPACE);
}
printf("\n");
}
int main(void) {
int i, alive;
char ch;
unsigned long init32;
srand(time(NULL));
for (i = 0; i < HEIGHT; ++i) {
init32 = ((double)rand() / RAND_MAX) * 0xFFFFFFFF;
row[i] = init32;
displayBinary(row[i]);
}
do {
system("clear");
for (i = 0; i < HEIGHT; ++i) {
neighbours[0] = north(row[i], i);
neighbours[1] = south(row[i], i);
neighbours[2] = west(row[i], i);
neighbours[3] = east(row[i], i);
neighbours[4] = northWest(row[i], i);
neighbours[5] = northEast(row[i], i);
neighbours[6] = southEast(row[i], i);
neighbours[7] = southWest(row[i], i);
}
for (i = 0; i < HEIGHT; ++i) {
alive += ((mask & neighbours[i]) ? 1 : 0);
displayBinary(row[i]);
}
} while ((ch = getchar()) != 'n');
return EXIT_SUCCESS;
}
What I am aiming for here is to have random 'X' characters printed on a 32x32 board, and have the program loop as long as the user does not type 'n'. For each loop iteration, I would like each coordinate to check its neighbours and "die" if it has less than two neighbours or more than three neighbours. Otherwise, it "lives" and an 'X' is printed at that coordinate.
I understand using bitwise ANDing may not be the best way to complete this, but my professor has asked we use bitwise AND, and so therefore I cannot change that logic.
I am having trouble clearing the rows between loops. Could somebody please help me figure out how to print the updated rows for each iteration of the do loop?
Any help is much appreciated. Thank you.
In order to show what is going on, I added this define,
//#define SPACE (0x20)
#define SPACE ('.')
Then I changed both instances where you printed space,
printf("%c", 0x20);
to
printf("%c", SPACE);
And then ran your program and got a single line, with some "." and some "X", but the second pass resulted in all ".",
Looks like your calculation of adjacent nodes might be wrong.
Why does your print appear wrong?
Because your first COMPASS loop uses displayBinary() 8 times,
for (i = 0; i < COMPASS; ++i) {
init32 = ((double)rand() / RAND_MAX) * 0xFFFFFFFF;
row[i] = init32;
displayBinary(row[i]);
}
While your subsequent looks use printf (rather than calling displayBinary), 8 times to only print 8 characters,
for (i = 0; i < COMPASS; ++i) {
alive += ((mask & row[i]) ? 1 : 0);
if ((alive == 2) || (alive == 3))
printf("%c", 'X');
else
printf("%c", SPACE);
}
Your HEIGHT loop does a recalculation of neighbours[], but you should be reseting row[].
I rewrote your displayBinary function, and this displays the entire row,
void displayBinary(unsigned long x) {
//do {
// printf("%c", (x & mask) ? 'X' : SPACE);
//} while ((mask >>= 1) != 0);
int bit;
int mask;
for( bit=0; bit<32; ++bit )
{
mask = 1<<bit;
printf("%c", (x & mask) ? 'X' : SPACE);
}
printf("\n");
}

Represent Unsigned Integer in Binary

How can I represent an unsigned integer as Binary ?
To create a string representation of some integer value you can use the following code:
#include <stdlib.h>
int main(int argc, char *argv[]) {
int j;
unsigned int value = 1024+2048+4096; // some value
char mask[8*sizeof(unsigned int) + 1] = {0};
for (j = 0; j < (8*sizeof(unsigned int) + 1); j++) {
mask[j] = (value << j) & (1 << (8*sizeof(unsigned int)-1)) ? '1' : '0';
}
printf("value is b%s\n", mask);
return 0;
}
Try this:
#include<stdio.h>
int main(void) {
int a,i,k=1;
int arr[32]; \\ taken an array of size 32
for(i=0;i <32;i++)
{
arr[i] = 0; \\initialised array elements to zero
}
printf("enter a number\n");
scanf("%d",&a); \\get input from the user
for(i = 0;i < 32 ;i++)
{
if(a&k) \\bit wise and operation
{
arr[i]=1;
}
else
{
arr[i]=0;
}
k = k<<1; \\left shift by one place evry time
}
for(i = 31 ;i >= 0;i--)
{
printf("%d",arr[i]); \\print the array in reverse
}
return 0;
}

C: Building a byte

I have an array with 16 elements. I would like to evaluate these to a boolean 0 or 1 and then store this in 2 bytes so i can write to a binary file. How do I do this?
Something like this you mean?
unsigned short binary = 0, i;
for ( i = 0; i < 16; ++i )
if ( array[i] )
binary |= 1 << i;
// the i-th bit of binary is 1 if array[i] is true and 0 otherwise.
You have to use bitwise operators.
Here's an example:
int firstBit = 0x1;
int secondBit = 0x2;
int thirdBit = 0x4;
int fourthBit = 0x8;
int x = firstBit | fourthBit; /*both the 1st and 4th bit are set */
int isFirstBitSet = x & firstBit; /* Check if at least the first bit is set */
int values[16];
int i;
unsigned short word = 0;
unsigned short bit = 1;
for (i = 0; i < 16; i++)
{
if (values[i])
{
word |= bit;
}
bit <<= 1;
}
This solution avoid the use of the if inside the loop:
unsigned short binary = 0, i;
for ( i = 0; i < 16; ++i )
binary |= (array[i] != 0) << i;
Declare an array result with two bytes, then you loop through the source array:
for (int i = 0; i < 16; i++) {
// calclurate index in result array
int index = i >> 3;
// shift value in result
result[index] <<= 1;
// check array value
if (theArray[i]) {
// true, so set lowest bit in result byte
result[index]++;
}
}
Something like this.
int values[16];
int bits = 0;
for (int ii = 0; ii < 16; ++ii)
{
bits |= (!!values[ii]) << ii;
}
unsigned short output = (unsigned short)bits;
the expression (!!values[ii]) forces the value to be 0 or 1, if you know for sure that the values array already contains either a 0 or a 1 and nothing else, you can leave of the !!
You could also do this if you don't like the !! syntax.
int values[16];
int bits = 0;
for (int ii = 0; ii < 16; ++ii)
{
bits |= (values[ii] != 0) << ii;
}
unsigned short output = (unsigned short)bits;

Resources