If I want to bit shift the integer 5 by 3, so int a = 5; int b = a << 3;, the result would be 40 in decimal as 5 is 101 and 40 is 101000.
What if however, I have the following char array:
00000 00101 and by bit shifting three to the left, I want the result to be 00001 01000. So I want to accommodate for the 0's padding. What do you suggest?
If you meant an actual char array, you can use memmove() and memset():
char str[] = "0000000101";
int shift = 3;
int length = strlen(str);
memmove(str, str + shift,length - shift);
memset(str + length - shift,'0',shift);
// Result:
// "0000101000"
Access the buffer with a 16-bit pointer, use htons to take care of endian issues
char c[2] = {0, 5};
uint16_t* p16 = (uint16_t*)c;
*p16 = htons((ntohs(*p16) << 3));
Related
How to print just for example 3 last digits of a signed integer as hexadecimal number?
int num = -5;
printf("%03X\n", num);
prints FFFFFFFB
I need it to print just FFB
How about:
void printLastThreeHex(int num)
{
size_t len = 0;
char tmp[sizeof(int)*2 + 1]; // two hex chars for each byte + null char
char* str = tmp;
sprintf(tmp, "%03x", num);
len = strlen(tmp);
if (len > 3)
{
str = tmp + len - 3;
}
printf("%s\n", str);
}
I believe the best and clearest way to do this would be a bitmask to hide everything except the last few digits. In your case, this would be printf("%X\n", num & 0xfff);:
0xfffffffb
0x00000fff
-----|||
0x00000ffb
You can adapt this to work with higher bits too. So if you want to extract 0xadb from 0xdeadbeef, it would look like this:
(0xdeadbeef & 0xfff000) >> 12 // gives 0xadb
(0xdeadbeef & 0xfff000) will mask out the bits you want, leaving 0xadb000. To remove these zeroes, right shift by 12 (each hex digit can represent 4 bits, and we need to remove 3 digits, so 4*3 = 12).
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.
Suppose you have an integer a = 0x12345678 & a short b = 0xabcd
What i wanna do is replace the given nibbles in integer a with nibbles from short b
Eg: Replace 0,2,5,7th nibbles in a = 0x12345678 (where 8 = 0th nibble, 7=1st nibble, 6=2nd nibble and so on...) with nibbles from b = 0xabcd (where d = 0th nibble, c=1st nibble, b=2nd nibble & so on...)
My approach is -
Clear the bits we're going to replace from a.
like a = 0x02045070
Create the mask from the short b like mask = 0xa0b00c0d
bitwise OR them to get the result. result = a| mask i.e result = 0xa2b45c7d hence nibbles replaced.
My problem is I don't know any efficient way to create the desired mask (like in step 2) from the given short b
If you can give me an efficient way of doing so, it would be a great help to me and I thank you for that in advance ;)
Please ask if more info needed.
EDIT:
My code to solve the problem (not good enough though)
Any improvement is highly appreciated.
int index[4] = {0,1,5,7}; // Given nibbles to be replaced in integer
int s = 0x01024300; // integer mask i.e. cleared nibbles
int r = 0x0000abcd; // short (converted to int )
r = ((r & 0x0000000f) << 4*(index[0]-0)) |
((r & 0x000000f0) << 4*(index[1]-1)) |
((r & 0x00000f00) << 4*(index[2]-2)) |
((r & 0x0000f000) << 4*(index[3]-3));
s = s|r;
Nibble has 4 bits, and according to your indexing scheme, the zeroth nibble is represented by least significant bits at positions 0-3, the first nibble is represented by least significant bits at positions 4-7, and so on.
Simply shift the values the necessary amount. This will set the nibble at position set by the variable index:
size_t index = 5; //6th nibble is at index 5
size_t shift = 4 * index; //6th nibble is represented by bits 20-23
unsigned long nibble = 0xC;
unsigned long result = 0x12345678;
result = result & ~( 0xFu << shift ); //clear the 6th nibble
result = result | ( nibble << shift ); //set the 6th nibble
If you want to set more than one value, put this code in a loop. The variable index should be changed to an array of values, and variable nibble could also be an array of values, or it could contain more than one nibble, in which case you extract them one by one by shifting values to the right.
A lot depends on how your flexible you are in accepting the "nibble list" index[4] in your case.
You mentioned that you can replace anywhere from 0 to 8 nibbles. If you take your nibble bits as an 8-bit bitmap, rather than as a list, you can use the bitmap as a lookup in a 256-entry table, which maps from bitmap to a (fixed) mask with 1s in the nibble positions. For example, for the nibble list {1, 3}, you'd have the bitmap 0b00001010 which would map to the mask 0x0000F0F0.
Then you can use pdep which has intrinsics on gcc, clang, icc and MSVC on x86 to expand the bits in your short to the right position. E.g., for b == 0xab you'd have _pdep_u32(b, mask) == 0x0000a0b0.
If you aren't on a platform with pdep, you can accomplish the same thing with multiplication.
To be able to change easy the nibbles assignment, a bit-field union structure could be used:
Step 1 - create a union allowing to have nibbles access
typedef union u_nibble {
uint32_t dwValue;
uint16_t wValue;
struct sNibble {
uint32_t nib0: 4;
uint32_t nib1: 4;
uint32_t nib2: 4;
uint32_t nib3: 4;
uint32_t nib4: 4;
uint32_t nib5: 4;
uint32_t nib6: 4;
uint32_t nib7: 4;
} uNibble;
} NIBBLE;
Step 2 - assign two NIBBLE items with your integer a and short b
NIBBLE myNibbles[2];
uint32_t a = 0x12345678;
uint16_t b = 0xabcd;
myNibbles[0].dwValue = a;
myNibbles[1].wValue = b;
Step 3 - initialize nibbles of a by nibbles of b
printf("a = %08x\n",myNibbles[0].dwValue);
myNibbles[0].uNibble.nib0 = myNibbles[1].uNibble.nib0;
myNibbles[0].uNibble.nib2 = myNibbles[1].uNibble.nib1;
myNibbles[0].uNibble.nib5 = myNibbles[1].uNibble.nib2;
myNibbles[0].uNibble.nib7 = myNibbles[1].uNibble.nib3;
printf("a = %08x\n",myNibbles[0].dwValue);
Output will be:
a = 12345678
a = a2b45c7d
If I understand your goal, the fun you are having comes from the reversal of the order of your fill from the upper half to the lower half of your final number. (instead of 0, 2, 4, 6, you want 0, 2, 5, 7) It isn't any more difficult, but it does make you count where the holes are in the final number. If I understood, then you could mask with 0x0f0ff0f0 and then fill in the zeros with shifts of 16, 12, 4 and 0. For example:
#include <stdio.h>
int main (void) {
unsigned a = 0x12345678, c = 0, mask = 0x0f0ff0f0;
unsigned short b = 0xabcd;
/* mask a, fill in the holes with the bits from b */
c = (a & mask) | (((unsigned)b & 0xf000) << 16);
c |= (((unsigned)b & 0x0f00) << 12);
c |= (((unsigned)b & 0x00f0) << 4);
c |= (unsigned)b & 0x000f;
printf (" a : 0x%08x\n b : 0x%0hx\n c : 0x%08x\n", a, b, c);
return 0;
}
Example Use/Output
$ ./bin/bit_swap_nibble
a : 0x12345678
b : 0xabcd
c : 0xa2b45c7d
Let me know if I misunderstood, I'm happy to help further.
With nibble = 4 bits and unsigned int = 32 bits, a nibble inside a unsigned int can be found as follows:
x = 0x00a0b000, find 3rd nibble in x i.e locate 'b'. Note nibble index starts with 0.
Now 3rd nibble is from 12th bit to 15th bit.
3rd_nibble can be selected with n = 2^16 - 2^12. So, in n all the bits in 3rd nibble will be 1 and all the bits in other nibbles will be 0. That is, n=0x00001000
In general, suppose if you want to find a continuous sequence of 1 in binary representation in which sequence starts from Xth bit to Yth bit then formula is 2^(Y+1) - 2^X.
#include <stdio.h>
#define BUF_SIZE 33
char *int2bin(int a, char *buffer, int buf_size)
{
int i;
buffer[BUF_SIZE - 1] = '\0';
buffer += (buf_size - 1);
for(i = 31; i >= 0; i--)
{
*buffer-- = (a & 1) + '0';
a >>= 1;
}
return buffer;
}
int main()
{
unsigned int a = 0;
unsigned int b = 65535;
unsigned int b_nibble;
unsigned int b_at_a;
unsigned int a_nibble_clear;
char replace_with[8];
unsigned int ai;
char buffer[BUF_SIZE];
memset(replace_with, -1, sizeof(replace_with));
replace_with[0] = 0; //replace 0th nibble of a with 0th nibble of b
replace_with[2] = 1; //replace 2nd nibble of a with 1st nibble of b
replace_with[5] = 2; //replace 5th nibble of a with 2nd nibble of b
replace_with[7] = 3; //replace 7th nibble of a with 3rd nibble of b
int2bin(a, buffer, BUF_SIZE - 1);
printf("a = %s, %08x\n", buffer, a);
int2bin(b, buffer, BUF_SIZE - 1);
printf("b = %s, %08x\n", buffer, b);
for(ai = 0; ai < 8; ++ai)
{
if(replace_with[ai] != -1)
{
b_nibble = (b & (1LL << ((replace_with[ai] + 1)*4)) - (1LL << (replace_with[ai]*4))) >> (replace_with[ai]*4);
b_at_a = b_nibble << (ai * 4);
a_nibble_clear = (a & ~(a & (1LL << ((ai + 1) * 4)) - (1LL << (ai * 4))));
a = a_nibble_clear | b_at_a;
}
}
int2bin(a, buffer, BUF_SIZE - 1);
printf("a = %s, %08x\n", buffer, a);
return 0;
}
Output:
a = 00000000000000000000000000000000, 00000000
b = 00000000000000001111111111111111, 0000ffff
a = 11110000111100000000111100001111, f0f00f0f
I have 24bit data in 3 array a[0], a[1], a[2] and need to calculate for multiply and divide by some constant and result still in 3 array.
For example, data = 999900h store in a[0] = 99, a[1] = 99, a[2] = 00
[(999900h/64)*15000]/157286 << **process???**
result will be 3A97h store in b[0] = 00, b[1] =3A, b[2] = 97
My question is
1.) How to write code for fast calculate in the process, pointer in fast? how to use pointer in the process?
2.) It possible no use conversion process like array to integer and integer to array?
Here's the easiest "solution":
uint32_t data = 0x00999900;
unsigned char const * a = (unsigned char const *)&data;
Now you have a[0], ..., a[3]. The order depends on the endianness of your system.
The endianness-independent solution works algebraically:
uint32_t data = 0x3A97;
unsigned char b[sizeof data] = { data >> 24 & 0xFF, // b[0]
(data >> 16) & 0xFF, // b[1]
(data >> 8) & 0xFF, // b[2]
data & 0xFF // b[3]
};
You can also reconstitute a value from your array. Here's the endianness-dependent way:
uint32_t data;
unsigned char * p = (unsigned char *)&data;
p[0] = 0x00;
p[0] = 0x99;
p[0] = 0x99;
p[0] = 0x00;
// now "data" is 0x00999900
And here's the algebraic way:
uint32_t data = a[0] * 256 * 256 * 256 + a[1] * 256 * 256 + a[2] * 256 + a[3];
I like to use unions in this case:
#inlude<stdint.h>
union array_int {
char a[4];
uint32_t num;
} data = {.a = {00, 99, 99, 00}};
printf("%d", data.num);
Please take endianess into account. use htonl if you put in your bytes most significant - to least significant, but are on a little endian system. If you don't want to mess around with endianess then I suggest you use one of the suggested algebraic suggestions.
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.