C: Building a byte - c

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;

Related

How I can convert 1byte of data into 2bytes of data

I want to convert 1byte of array element into 2 bytes
E.g
arr[size] = {0x1F};
So, I want 0x1F will be stored in
2nd array like,
arr_2[size] = {0x01, 0x0f}
I have tried like following way...
for(i=j=0; j<2; i++){
arr_2[j] =(0xF0 & arr[i]) >> 4;
arr_2[j++]=(0x0F & arr[i]);
}
Thanks is advance..!!
In fact you are doing all correctly except the for loop statement
for(i=j=0; j<2; i++){
arr_2[j] =(0xF0 & arr[i]) >> 4;
arr_2[j++]=(0x0F & arr[i]);
}
in the body of which you are setting at least the same element of the array arr_2 twice.
It is redundant.
You could just write
arr_2[0] =(0xF0 & arr[0]) >> 4;
arr_2[1] = 0x0F & arr[0];
To build on Vlad's answer, maybe you used a loop because you really want to expand n bytes into n*2 bytes.
for ( size_t i = 0; i < n; ++i ) {
dst[ i*2+0 ] = ( src[ i ] >> 4 ) & 0xF;
dst[ i*2+1 ] = ( src[ i ] >> 0 ) & 0xF;
}
or
for ( size_t j = 0, i = 0; i < n; ++i ) {
dst[ j++ ] = ( src[ i ] >> 4 ) & 0xF;
dst[ j++ ] = ( src[ i ] >> 0 ) & 0xF;
}
You were almost there, but didn't use the proper for() syntax to increment multiple iterators.
Example:
#define SIZE 1 // for example, but the same principles
// would apply for malloc'd arrays
unsigned char arr[SIZE] = {0x1F}; // 'SIZE' bytes
unsigned char arr_2[SIZE * 2]; // You'll end up with twice as many bytes.
// ...
int i, j;
// note how we test the input iterator (i) against the input size and how
// the output iterator (j) is incremented by 2 on each iteration
for (i = 0, j = 0; i < SIZE; i++, j += 2)
{
arr_2[j] = (arr[i] & 0xF0) >> 4;
arr_2[j + 1] = arr[i] & 0x0F;
}
You don't need to maintain two index variables. Here is a solution assuming you want to store the elements in an array of twice the length of the source array:
#include <stdio.h>
#define LEN(arr) (sizeof (arr) / sizeof (arr)[0])
int main(void)
{
unsigned char arr[] = {0x1f, 0x2f, 0x3f, 0x4f};
unsigned char arr_2[2 * LEN(arr)];
size_t i;
for (i = 0; i < LEN(arr); i++) {
arr_2[2 * i] = arr[i] >> 4;
arr_2[2 * i + 1] = arr[i] & 0x0f;
}
for (i = 0; i < LEN(arr_2); i++) {
printf("%x", arr_2[i]);
}
printf("\n");
return 0;
}
Output:
1f2f3f4f

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);
}
}

How to concatenate bit by bit in 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;
}

How to retrieve value from bytes stored in a byte array?

I am trying to store 8 bytes in a byte array to store the value of a pointer.
int main() {
unsigned long a = 0;
char buf[8];
int i = 0;
int *p = &i;
a = (unsigned long)p;
while (i < 8)
{
buf[i] = (a >> (8 * i)) & 0xFF;
i++;
}
a = 0;
i = 0;
while (i < 8)
{
a = ?
i++;
}
p = (int *)a;
}
The first loop stores successive bytes of p, as casted into usigned long in a, but I don't know how to retrieve the value in the second loop. Does somebody have a clue?
This is the inverse code to yours:
a = 0;
while (i < 8)
{
a |= ((unsigned long)buf[i] & 0xff ) << (8 * i);
i++;
}

C: converting Bit position to decimal

Scenario:
[Node A] < -------- Rf-interface ------> [Node B]
question:
Node A send a payload to Node B which is 6 bytes long. In this payload there is some information regarding available slots e.g. there are in total 6 bytes * 8 bits = 48 slots. Each slot can be either ON 1 or OFF 0.
For an example, then these slot numbers 0,2,5,7 are all ON. The bit representation of the payload will be:
10100101000000000 .... till the 48th bit.
These information are then send to Node B in the payload over the RF-interface.
At Node B, I need to convert the position of each bit representation in to decimal representation in an array (for some gui representation).
back to the example:
I need to convert the payload with the bits: 10100101000000000... into active slots presentation in an array: e.g.
myArray[0] = 1;
myArray[1] = 0;
myArray[2] = 1;
myArray[3] = 0;
myArray[4] = 0;
myArray[5] = 1;
.
.
myArray[48] = x;
I am not good in bit mask, so any help wold be appreciated
Thanks for all help!
How about this?:
char *bitsToArray(char *data, int length)
{
char *rv = malloc(8*length);
int i = 0;
for(;i < length; ++i)
{
int j = 0;
for(; j < 8; ++j)
{
rv[i*8+j] = (data[i]>>j)&1;
}
}
return rv;
}
It stores the least significant bit first. If you would like it to work in opposite bit order, you can change the line rv[i*8+j] = (data[i]>>j)&1; to rv[i*8+j] = (data[i]>>(7-j))&1;
Based on your example, I'm assuming the bitmap, the given 6-byte array is:
unsigned char bitmap[6] = {0xa5, 0x00, 0x00, 0x00, 0x00, 0x00};
And the results are destined for:
int myArray[48];
I would be inclined to loop through myArray from back to front and assign each value based on a test of the lowest order bit in the bitmap, then shift right for each loop iteration.
int bmi = 5; // set bitmap index to end
int mai = 47; // set myArray index to end
int i = 0;
while (mai >= 0) {
for (i = 0; i < 8; i++) {
myArray[mai] = bitmap[bmi] & 0x01;
bitmap[bmi] >>= 1;
--mai;
}
--bmi;
}
for (mai = 0; mai < 48; mai++) printf("%d", myArray[mai]);
printf("\n");
for (int i = 0; i < buffer_size; i++) {
for (int j = 7; j >= 0; j--) { // most significant bit first
myArray[8 * i + j] = buffer[i] >> j & 1;
}
}

Resources