get last 8 bits from int and covert to unsigned char - c

I am trying to get the last 8 bits from a int and copy them in an unsigned char
Ex: int 2 -> 00000000 00000000 00000000 00000011
I want to get the 00000011 and copy the bits in an unsigned char
Can anyone please help me with some information?

unsigned char bottomByte = num & 0xff;
This will mask your num with 1111 1111 - leaving only the bottom eight bits.
Code like
unsigned char bottomByte = num;
will also work fine, assuming num is positive (or unsigned) - it will leave only the bottom byte of num in the unsigned char. But for clarity you should stick to num & 0xff.

Related

C decimal to binary converter (16 bits)

I'm trying to convert a decimal number into binary (16 bits max). My function works perfectly for up to 8 bits but when I want to print numbers up to 16 bits, it stop printing characters.
I used "int" as my data type for 8 bits but since I want to store 16 bits I'm using an unsigned long int in every variable.
Here's the code:
/* Program to convert decimal to binary (16 bits) */
#include <stdio.h>
#include <string.h>
char *byte_to_binary_str(long unsigned int byte);
int main()
{
printf("%s",byte_to_binary_str(32768)); //1000000 0000000
return 0;
}
char *byte_to_binary_str(long unsigned int byte)
{
static char bit_string[17];
bit_string[0] = '\0';
long unsigned int mask;
for (mask = 2^15; mask > 0; mask >>= 1) {
/* Check if the mask bit is set */
strcat(bit_string, byte & mask ? "1" : "0");
}
return bit_string;
}
My output gives me:
0000
Process returned 0 (0x0) execution time : 0.063 s
Press any key to continue.
Anyone know why is this happening? Thanks in advance.
mask = 2^15;
does not set the value of mask to what you are expecting 2^15 is no 2 raised to the power 15. It is bitwise XOR of 2 and 15.
You need something that is 1000 0000 0000 0000 in binary. That number will be 0x8000 in hex. Hence, use:
mask = 0x8000;
You can also use something that makes sense in your algorithm.
mask = 1u << 15;

Omit leading 0 in char and append

Say I have these 8 bit chars:
01111111 00011100 01101111
I want to omit the leading 0 and append the bits from char before like so:
11111110 01110011 01111000
*note that the last char has been padded with zeros.
Any advice on how to do this would be much appreciated. cheers.
Shift the first char up 1:
num[0] << 1;
This will turn 01111111 into 11111110. Now you need to OR the LSB with the MSB of the next char. To do that you need a shifted copy of the next char:
char copy = num[1] >> 7;
This would turn 01110011 into 00000000, since it's high bit was 0. You can now OR the two:
num[0] |= num[1];
Which will give you what you want.
To do this with a sequence, you would need to loop and increase the shifts at each iteration up to 8, then reset.
Note that as chux points out, you are best off using unsigned types for stuff like this.

How do I convert and break a 2 byte integer into 2 different chars in C?

I want to convert an unsigned int and break it into 2 chars. For example: If the integer is 1, its binary representation would be 0000 0001. I want the 0000 part in one char variable and the 0001 part in another binary variable. How do I achieve this in C?
If you insist that you have a sizeof(int)==2 then:
unsigned int x = (unsigned int)2; //or any other value it happens to be
unsigned char high = (unsigned char)(x>>8);
unsigned char low = x & 0xff;
If you have eight bits total (one byte) and you are breaking it into two 4-bit values:
unsigned char x=2;// or whatever
unsigned char high = (x>>4);
unsigned char low = x & 0xf;
Shift and mask off the part of the number you want. Unsigned ints are probably four bytes, and if you wanted all four bytes, you'd just shift by 16 and 24 for the higher order bytes.
unsigned char low = myuint & 0xff;
unsigned char high = (myuint >> 8) & 0xff;
This is assuming 16 bit ints check with sizeof!! On my platform ints are 32bit so I will use a short in this code example. Mine wins the award for most disgusting in terms of pulling apart the pointer - but it also is the clearest for me to understand.
unsigned short number = 1;
unsigned char a;
a = *((unsigned char*)(&number)); // Grab char from first byte of the pointer to the int
unsigned char b;
b = *((unsigned char*)(&number) + 1); // Offset one byte from the pointer and grab second char
One method that works is as follows:
typedef union
{
unsigned char c[sizeof(int)];
int i;
} intchar__t;
intchar__t x;
x.i = 2;
Now x.c[] (an array) will reference the integer as a series of characters, although you will have byte endian issues. Those can be addressed with appropriate #define values for the platform you are programming on. This is similar to the answer that Justin Meiners provided, but a bit cleaner.
unsigned short s = 0xFFEE;
unsigned char b1 = (s >> 8)&0xFF;
unsigned char b2 = (((s << 8)>> 8) & 0xFF);
Simplest I could think of.
int i = 1 // 2 Byte integer value 0x0001
unsigned char byteLow = (i & 0x00FF);
unsinged char byteHigh = ((i & 0xFF00) >> 8);
value in byteLow is 0x01 and value in byteHigh is 0x00

pointer offset doesnt work in memset?

Plain C, on Windows 7 & HP machine.
int main(void) {
unsigned int a = 4294967295;
unsigned int *b = &a;
printf("before val: '%u'\n", *b); // expect 4294967295, got 4294967295
memset(b+2, 0, 1);
printf("after val: '%u'\n", *b);
// little endian 4th 3rd 2nd 1st
// expect 4278255615 - 11111111 00000000 11111111 11111111
// got 4294967295 - 11111111 11111111 11111111 11111111
return 0;
}
I want to set the third byte of the integer to 0x0, but is remains the same. Any ideas? Thank you.
On my machine, int is 32 bits.
Pointer addition/subtraction does not move by only one byte - it moves by the size of the type of the object being pointed to.
That is to say (assuming 4-byte integers),
int *p = 0x00004
int *q = p+1;
assert(q == 0x00008)
Basically, it's the same as if you used the index of operator:
int *q = &p[1]
If you want to increment a pointer by one, cast it to a unsigned char *. The way you did it, you were overwriting memory that was not part of the variable a and possibly overwriting existing data for something else.
The b+2 meens in fact a displacement of two int not two bytes.
unsigned int *b = &a;
memset(b+2, 0, 1);
In fact you want to modify the third byte
unsigned int *b = &a;
memset( ((char*)b)+2, 0, 1);
int is only guaranteed to be at least two bytes, so if you want to set the third byte you should use a long int (or uint32_t). Anyway, I'd do it using the bitwise and operator
unsigned long a = 4294967293;
/* regular code */
a &= 0xFFFF00FF;

C bits shifting short ints

Why result of
include <stdio.h>
int main()
{
unsigned short int i = 0xff ;
unsigned short int j;
j= i<<2;
printf("%x n%x\n", i, j);
return 0;
}
is j = 3fc ?
if both i and j are short int - so they are 2bytes values, so j shouldnt =fc ??
thx in advance for explanations.
~
~
Shifting 0xff left two bits looks like this:
0000 0000 1111 1111
0 0 f f
0000 0011 1111 1100 -- Shifted left 2 bits.
0 3 f c
So 0x00ff << 2 = 0x03fc. Everything looks as it should be .
No, 0x3fc is correct. Note that a byte is two hex digits, so a (16-bit) short has a total of 4 hex digits.
0xff << 2 == 0xff * 4 == 0x3fc == 1020
Even if they are 2-bytes, they are allowed to hold this small value.
3FC requires only 12 bits to store so it can be stored in 2 bytes.
C++ makes no guarantee as to the number of bytes in an unsigned short int. It in fact makes almost no guarantee about the size of any type other than char which is guaranteed to be 1 byte.
In this case though it's irrelevant because 3fc can be successfully stored in only 2 bytes.
Maybe this is what you actually tried to write? (Remember an hex digit is 4 bits only, ie, half a byte)
#include <stdio.h>
int main()
{
unsigned short int i = 0xffff;
unsigned short int j;
j = i<<8;
printf("%x %x\n", i, j);
return 0;
}
This outputs ffff ff00

Resources