Creating duplicate bytes from a given function - c

So I have the below code which shifts a 32 bit int 6 bits to the left (s->data) then appends the last 6 bits of the int operand to the int s->data. I would like to use this code to create a function which takes an unsigned char x and copies x into the first 3 bytes of the int s->data leaving the final byte as 0. So for example, if we had x = 255 then s->data , in binary form, would be 11111111 11111111 11111111 000000000. Does anyone know how this can be achieved using the below code (dataCommand). So If i can only shift left by 6 bits and append 6 bits to the end of s->data, how can I get something of the form above?.
I know how to get say 255 from using s->data (we do dataCommand(128+64+(255/64))) followed by dataCommand(128+64+(255%64)). This is assuming s->data is 0 to begin with. So this would give 00000000 00000000 00000000 11111111. However , I would like something of the form 11111111 11111111 11111111 00000000.
I am really lost as to how to do this, so any help would be greatly appreciated. Below is the dataCommand function. Thank you. As always, it can be assumed s->data is 0 to begin with.
void dataCommand(int operand, state *s) {
printf("DATA BEFORE IS %x\n", s->data);
// shifts bits of current data fields six positions to left
s->data = s->data << 6;
// (operand & 63) masks 6 bits off the operand
// then we combine 6 bits of data with 6 bits of operand
s->data = (s->data | (operand & 63));
printf("DATA AFTER %x\n", s->data);
}

Comments in MyFunction below explain how to do this.
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
typedef struct state { int x, y, tx, ty; unsigned char tool; unsigned int start, data; bool end;} state;
void dataCommand(int operand, state *s) {
printf("DATA BEFORE IS %x\n", s->data);
// shifts bits of current data fields six positions to left
s->data = s->data << 6;
// (operand & 63) masks 6 bits off the operand
// then we combine 6 bits of data with 6 bits of operand
s->data = (s->data | (operand & 63));
printf("DATA AFTER %x\n", s->data);
}
void MyFunction(unsigned char x, state *s)
{
/* Create the target pattern that contains 0 in byte 0 and x in bytes 1,
2, and 3.
*/
uint32_t p = 0x01010100u * x;
/* For each six bits in p, or fragment thereof, in order from high bits to
low bits, shift those six bits down to the low six bits and give that
to dataCommand to insert into s->data.
*/
dataCommand(p >> 6*5, s);
dataCommand(p >> 6*4, s);
dataCommand(p >> 6*3, s);
dataCommand(p >> 6*2, s);
dataCommand(p >> 6*1, s);
dataCommand(p >> 6*0, s);
}
int main(void)
{
state s;
MyFunction(0x45, &s);
printf("data = 0x%08x.\n", s.data);
}

Related

C integer to binary conversion, splitting the result into two binary values [duplicate]

I know that to get the number of bytes used by a variable type, you use sizeof(int) for instance. How do you get the value of the individual bytes used when you store a number with that variable type? (i.e. int x = 125.)
You have to know the number of bits (often 8) in each "byte". Then you can extract each byte in turn by ANDing the int with the appropriate mask. Imagine that an int is 32 bits, then to get 4 bytes out of the_int:
int a = (the_int >> 24) & 0xff; // high-order (leftmost) byte: bits 24-31
int b = (the_int >> 16) & 0xff; // next byte, counting from left: bits 16-23
int c = (the_int >> 8) & 0xff; // next byte, bits 8-15
int d = the_int & 0xff; // low-order byte: bits 0-7
And there you have it: each byte is in the low-order 8 bits of a, b, c, and d.
You can get the bytes by using some pointer arithmetic:
int x = 12578329; // 0xBFEE19
for (size_t i = 0; i < sizeof(x); ++i) {
// Convert to unsigned char* because a char is 1 byte in size.
// That is guaranteed by the standard.
// Note that is it NOT required to be 8 bits in size.
unsigned char byte = *((unsigned char *)&x + i);
printf("Byte %d = %u\n", i, (unsigned)byte);
}
On my machine (Intel x86-64), the output is:
Byte 0 = 25 // 0x19
Byte 1 = 238 // 0xEE
Byte 2 = 191 // 0xBF
Byte 3 = 0 // 0x00
You could make use of a union but keep in mind that the byte ordering is processor dependent and is called Endianness http://en.wikipedia.org/wiki/Endianness
#include <stdio.h>
#include <stdint.h>
union my_int {
int val;
uint8_t bytes[sizeof(int)];
};
int main(int argc, char** argv) {
union my_int mi;
int idx;
mi.val = 128;
for (idx = 0; idx < sizeof(int); idx++)
printf("byte %d = %hhu\n", idx, mi.bytes[idx]);
return 0;
}
If you want to get that information, say for:
int value = -278;
(I selected that value because it isn't very interesting for 125 - the least significant byte is 125 and the other bytes are all 0!)
You first need a pointer to that value:
int* pointer = &value;
You can now typecast that to a 'char' pointer which is only one byte, and get the individual bytes by indexing.
for (int i = 0; i < sizeof(value); i++) {
char thisbyte = *( ((char*) pointer) + i );
// do whatever processing you want.
}
Note that the order of bytes for ints and other data types depends on your system - look up 'big-endian' vs 'little-endian'.
This should work:
int x = 125;
unsigned char *bytes = (unsigned char *) (&x);
unsigned char byte0 = bytes[0];
unsigned char byte1 = bytes[1];
...
unsigned char byteN = bytes[sizeof(int) - 1];
But be aware that the byte order of integers is platform dependent.

Bit extracting in embedded c

I am working on bit extracting from given byte.I have 32-bit 0XFA73DECB in binary 1111 1010 0111 0011 1101 1110 1100 1011.Now how to extract bit no. 7 to 22? Any one help me?
The following code first extracts the bits into another int and then outputs in binary.
#include <stdio.h>
#include <stdlib.h>
unsigned int a = 0xfa73decb;
int main()
{
unsigned int Bits = 0b00000011111111111111110000000000;
unsigned int Extract = (a & Bits) >> 10;
char Bin[20];
_itoa(Extract, Bin, 2);
printf("%s\n", Bin);
while (1);
}
The _itoa (the underline is because I'm using Visual Studio and the typical itoa is deprecated) means transform the integer Extract into a string with the radix of 2 and store it into the string Bin
To dynamically reading the inputs to extract the bits,
#include <stdio.h>
#include <stdlib.h>
unsigned int a = 0xfa73decb;
int main()
{
int msb;
int lsb;
unsigned int Extract;
printf("size of unsigned int = %d\n", sizeof(unsigned int)); // sizeof int : 4 bytes (32 bits)
scanf("%d", &lsb); // as per your requirement: 10
scanf("%d", &msb); // as per your requirement: 26
msb = (8*sizeof(unsigned int)) - msb; // msb = 32 - 26 ; // 6
lsb = lsb + msb ; // lsb = 10 + 6 ; // 16
Extract = (a << msb); // shifting 6 times left
printf("After Left shift = 0x%0x\n", Extract);
Extract = Extract >> lsb; // shifting 16 times right
printf("After Right shift = 0x%0x\n", Extract);
}
Input:
10 26
Output:
size of unsigned int = 4
After Left shift = 0x9cf7b2c0
After Right shift = 0x9cf7

Set first 10 bit of int

I have a 32-bit int and I want to set the first 10 bit to a specific number.
IE
The 32-bit int is:
11101010101010110101100100010010
I want the first 10 bit to be the number 123, which is
0001111011
So the result would be
00011110111010110101100100010010
Does anyone know the easiest way I would be able to do this? I know that we have to do bit-shifting but I'm not good at it so I'm not sure
Thank you!
uint32_t result = (input & 0x3fffff) | (newval << 22);
0x3fffff masks out the highest 10 bits (it has the lowest 22 bits set). You have to shift your new value for the highest 10 bits by 22 places.
Convert inputs to unsigned 32-bit integers
uint32_t num = strtoul("11101010101010110101100100010010", 0, 2);
uint32_t firstbits = 123;
Mask off the lower 32-10 bits. Create mask by shifting a unsigned long 1 22 places left making 100_0000_0000_0000_0000_0000 then decrementing to 11_1111_1111_1111_1111_1111
uint32_t mask = (1UL << (32-10)) - 1;
num &= mask;
Or in firstbits shifted left by 32-10
num |= firstbits << (32-10);
Or in 1 line:
(num & (1UL << (32-10)) - 1) | (firstbits*1UL << (32-10))
Detail about firstbits*1UL. The type of firstbits is not defined by OP and may only be a 16-bit int. To insure code can shift and form an answer that exceeds 16 bits (the minimum width of int), multiple by 1UL to insure the value is unsigned and has at least 32 bit width.
You can "erase" bits (set them to 0) by using a bit wise and ('&'); bits that are 0 in either value will be 0 in the result.
You can set bits to 1 by using a bit wise or ('|'); bits that are 1 in either value will be 1 in the result.
So: and your number with a value where the first 10 bits are 0 and the rest are 1; then 'or' it with the first 10 bits you want put in, and 0 for the other bits. If you need to calculate that value, then a left-shift would be the way to go.
You can also take a mask and replace approach where you zero the lower bits required to hold 123 and then simply | (OR) the value with 123 to gain the final result. You can accomplish the exact same thing with shifts as shown by several other answers, or you can accomplish it with masks:
#include <stdio.h>
#ifndef BITS_PER_LONG
#define BITS_PER_LONG 64
#endif
#ifndef CHAR_BIT
#define CHAR_BIT 8
#endif
char *binpad2 (unsigned long n, size_t sz);
int main (void) {
unsigned x = 0b11101010101010110101100100010010;
unsigned mask = 0xffffff00; /* mask to zero lower 8 bits */
unsigned y = 123; /* value to replace zero bits */
unsigned masked = x & mask; /* zero the lower bits */
/* show intermediate results */
printf ("\n x : %s\n", binpad2 (x, sizeof x * CHAR_BIT));
printf ("\n & mask : %s\n", binpad2 (mask, sizeof mask * CHAR_BIT));
printf ("\n masked : %s\n", binpad2 (masked, sizeof masked * CHAR_BIT));
printf ("\n | 123 : %s\n", binpad2 (y, sizeof y * CHAR_BIT));
masked |= y; /* apply the final or with 123 */
printf ("\n final : %s\n", binpad2 (masked, sizeof masked * CHAR_BIT));
return 0;
}
/** returns pointer to binary representation of 'n' zero padded to 'sz'.
* returns pointer to string contianing binary representation of
* unsigned 64-bit (or less ) value zero padded to 'sz' digits.
*/
char *binpad2 (unsigned long n, size_t sz)
{
static char s[BITS_PER_LONG + 1] = {0};
char *p = s + BITS_PER_LONG;
register size_t i;
for (i = 0; i < sz; i++)
*--p = (n>>i & 1) ? '1' : '0';
return p;
}
Output
$ ./bin/bitsset
x : 11101010101010110101100100010010
& mask : 11111111111111111111111100000000
masked : 11101010101010110101100100000000
| 123 : 00000000000000000000000001111011
final : 11101010101010110101100101111011
How about using bit fields in C combined with a union? The following structure lets you set the whole 32-bit value, the top 10 bits or the bottom 22 bits. It isn't as versatile as a generic function but you can't easily make a mistake when using it. Be aware this and most solutions may not work on all integer sizes and look out for endianness as well.
union uu {
struct {
uint32_t bottom22 : 22;
uint32_t top10 : 10;
} bits;
uint32_t value;
};
Here is an example usage:
int main(void) {
union uu myuu;
myuu.value = 999999999;
printf("value = 0x%08x\n", myuu.value);
myuu.bits.top10 = 0;
printf("value = 0x%08x\n", myuu.value);
myuu.bits.top10 = 0xfff;
printf("value = 0x%08x\n", myuu.value);
return 0;
}
The output is:
value = 0x3b9ac9ff
value = 0x001ac9ff
value = 0xffdac9ff

allOddBits return 1

Hello the function is called allOddBits with one input so if the function identifies 1 when the odd numbered bits are then it will return 1 otherwise it return 0;
Thank you for the help in advance.
We are only allowed to use these ! ~ & ^ | + << >> bit operation not more than 12 times. This way is always returning a 1 which is not correct because when the value of 'a' doesn't have odd numbered bits equal to 1, it should not return 1.
int main(int argc, char *argv[]) {
unsigned a,c;
a= 0xAAAAAAAA; // given bits, it can be anything
c= a>>31; // Shifting 31 bits to the right and fill in 0 instead
c= ~c; // flipping the bits so it can all be 1 except for LSB
printf(": %u\n", !!c);
}
Never mind guys,.. I figured out the solution but it did take some time. I appreciate your input though.
unsigned int x = strtoul(argv[1], NULL, 10);
unsigned int a = 0x55555555; // or 0xAAAAAAAA if you count LSB as bit 0
return ((x & a) == a);

Reading n-bit elements from a data stream in C

Given a data stream in C, I need to read the nth element which is x bits wide. x can vary from 1-64. How do I do this in C? I tried some bit fiddling but could not come up with a solution.
For example, for a data stream
01101010 11010101 11111111 00000010 00000000 10000000
==== ======
if the data is 10-bit wide and the element to parse is the third element. The expected data should be 1111 000000.
The data stream is byte-addressable.
First find out what the most significant bit represents. Specifically, does it represent bit 0 or bit 7 in your bit stream.
To find the nth element, you will need to find which byte it starts on ((n*x)/8), get the appropriate bits from that byte, then get the remaining bits from the following byte or bytes.
But, which bits should be taken from the bytes depends on what the most significant bit represents.
#include <stdio.h>
#include <stdint.h>
uint64_t bit_slice(const uint8_t ds[], int start, int end){
//index start, end {x | 1 <= x <= 64 }
uint64_t s = 0;//memcpy(&s, ds, 8);
int i, n = (end - 1) / 8;
for(i = 0; i <= n; ++i)
s = (s << 8) + ds[i];
s >>= (n+1) * 8 - end;
uint64_t mask = (((uint64_t)1) << (end - start + 1))-1;//len = end - start + 1
s &= mask;
return s;
}
int main(void){
uint8_t data[8] = {
0b01101010, 0b11010101, 0b11111111, 0b00000010, 0b00000000, 0b10000000 //0b... GCC extention
};
unsigned x = bit_slice(data, 21, 30);
printf("%X\n", x);//3C0 : 11 1100 0000
return 0;
}

Resources