Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed last month.
Improve this question
I need to extract bits from a byte array (little endian), and then form a new int from it.
Say my byte array is this:
[0b00011001, 0b11001001, 0b00101010, 0b11001110]
And I need to extract bits 14 to 18 (inclusive).
First I bitmask like so:
[0b00011001, 0b11000000, 0b00000010, 0b11001110] using & 0b11000000 on [1] and & 0b00000111 on [2]
Then remove first byte, and reset other bytes:
[0b11000000, 0b00000010, 0b00000000, 0b00000000]
If I form an uint 32 out of this, it results in 704. Is this correct?
Is assuming MSB = 7 and LSB = 0 correct?
As mentioned in the comments, it would be much easier to work with a union.
#include <stdio.h>
#include <stddef.h>
typedef union {
uint32_t i;
uint8_t c[4];
} u_t;
int main( void ) {
u_t u = { 0 };
// Little Endian machine
u.c[0] = 0x19; // I believe these are the hex equivalent of OP data.
u.c[1] = 0xC9;
u.c[2] = 0x2A;
u.c[3] = 0xCE;
u.i &= 0x1F << (14-1); // Mask for 5 bits, b14-b18
printf( "%08X\n", u.i );
printf( "%u\n", u.i );
printf( "%u\n", u.i >> 8 ); // my (our) mistake
printf( "%u\n", u.i >> 14 ); // Perhaps what was intended
return 0;
}
0002C000
180224
704
11
Of course, this would be much simpler just shifting the value to the right to begin with, then mask for the 5 lowest bits... C'est la guerre...
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 months ago.
Improve this question
I have binary string( only 0s or 1s) "0101011111011111000001001001110110", for Huffman encoding I want to store each char in the string as bit representation in a uint8_t array.
If I write the binary string as-is into a file it occupies 35 bytes. If we can store each binary char in the string as bit representation in uint8_t array, it can be stored in ~5 bytes.
static uint8_t out_buffer[1024];
static uint32_t bit_pos = 0;
void printbuffer()
{
printf("Just printing bits\n");
int i;
for (i = 0; i < bit_pos; i++) {
printf("%c", (out_buffer[i / 8] & 1 << (i % 8)) ? '1' : '0');
}
}
void append_to_bit_array(char* in, int len, uint8_t* buf)
{
int i;
printbuffer();
for (i = 0; i < len; i++) {
if (in[i])
{
buf[bit_pos / 8] |= 1 << (bit_pos % 8);
}
bit_pos++;
}
}
You need to first decide on what order you want to put the bits in the bytes — i.e. put the first bit in the most significant bit of the first byte, or the least? You also need to have a strategy to deal with the extra 0 to 7 bits in the last byte. Those could look like another Huffman code, and give you extraneous symbols when decoding. Either you will need a count of symbols to decode, or you will need an end symbol that you add to your set before Huffman coding, and send that symbol at the end.
Learn the bitwise operators in C noted in your tag, and use those to place each bit, one by one, into the sequence of bytes. Those are at least the shifts << and >>, and &, and or |.
For example, 1 << n gives you a one bit in position n. a |= 1 << n would set that bit in a, given that a is initialized to zero. On the decoding end, you can use & to see if a bit is set. E.g. a & (1 << n) would be non-zero if bit n in a is set.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 months ago.
Improve this question
I have a problem that I am working on it for one week and can't get a good solving method. I have to get the binary representation of an 8 bit integer in C, without using any if or while loops. I find it impossible because I have to use only bitwise operators (tips given: bit shifting and masking). Any help will be much apreciated!
Input
Output
7
00000111
127
01111111
Since I don't have a solving method I don't have any versions. I need the logic behind it!
Computing such a representation is as simple as figuring out whether bits at position 0 to 7 are on or off. A way of doing this is performing a binary AND and checking if the result is zero or not.
#include <stdlib.h>
#include <stdio.h>
#define BIT0 1 << 0
#define BIT1 1 << 1
#define BIT2 1 << 2
#define BIT3 1 << 3
#define BIT4 1 << 4
#define BIT5 1 << 5
#define BIT6 1 << 6
#define BIT7 1 << 7
int main()
{
unsigned num = 7;
unsigned representation[8] = {
!!(BIT0 & num),
!!(BIT1 & num),
!!(BIT2 & num),
!!(BIT3 & num),
!!(BIT4 & num),
!!(BIT5 & num),
!!(BIT6 & num),
!!(BIT7 & num),
};
// This loop is not part of the solution.
// It just prints the computed representation.
for (int i = 7; i >= 0; --i) {
printf("%d", representation[i]);
}
return 0;
}
prints
00000111
Demo
A useful tool in this case is to define a macro to compute the value of a specific bit, e.g.:
define BIT(pos, num) !!(1 << (pos) & (num))
which could be used to compute on the fly the value of a bit at a position e.g. bit 2 would be BIT(2, number) and this means you can easily compute representations as the one by #user3386109 in the comments:
char representation[] = {
BIT(7, number) + '0',
BIT(6, number) + '0',
BIT(5, number) + '0',
BIT(4, number) + '0',
BIT(3, number) + '0',
BIT(2, number) + '0',
BIT(1, number) + '0',
BIT(0, number) + '0',
};
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I want a function which would help me to extract few bits or bytes from a starting bit position from a byte array. The order of the byte array is LSB. The skeleton of the code is as follows:
typedef unsigned char uint8;
typedef unsigned short uint16;
uint16 ExtractBitsOrBytes(uint16 StartBit, uint8 *ByteArray, uint16 BitsWanted)
{
uint16 Result;
...
}
How can I implement this logic in C?. Any example or starting point is much appreciated.
Your problem is not fully specified: LSB refers to the order of bytes in memory for integral types spanning more than one byte. In your case you must specify how the bits are numbered in the array and composed to form the value extracted.
It would make sense to number the bits from 0, such that bit n is the bit with value 1 << (n % 8) in the byte at offset n / 8. For consistency, the bit with the lowest number should become the least significant bit of the extracted value. This convention is consistent with LSB as extracting 16 bits at offset 0 yields the value of the uint16 stored in the first 2 bytes of the array.
Here is a naive implementation with this convention:
typedef unsigned char uint8;
typedef unsigned short uint16;
uint16 ExtractBitsOrBytes(uint16 StartBit, const uint8 *ByteArray, uint16 BitsWanted) {
// assuming BitsWanted <= 16
uint16 result = 0;
uint16 i;
for (i = 0; i < BitsWanted; i++) {
result |= (uint16)((ByteArray[StartBit >> 3] >> (StartBit & 7)) & 1) << i;
StartBit++;
}
return result;
}
Note however that the convention used for monochrome bitmaps on many systems is different: the leftmost pixel corresponds to the most significant bit of the first byte, a convention inherited from choices made in the late 70s, mixing MSB and LSB, that made graphics software more complicated than it should have been.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I want to learn if this is possible:
for ex:
we have long Lvalue = 0xFF00f41a;
and also have int *p;
Can we point to last 2 byte of Lvalue
like p=&Lvalue <<16;
p pointed frist 16 bit value is it possible?
*p --> f41a;
*(p+1) --->0xFF00;
then if
p = 0xa011;
long Lvalue ---> 0xFF00a011
actually I need bit operations. I have 32 bit value but I can send only 16 bits and if I change 16 bit have to change first 16 bit last 16 bit of 32 bit value.
If you just want 16bits of the larger 32bits type, use bit mask for the task, for example, to get the lower 16 bits of value:
long value = 0xFF00f41a;
long lower = value & 0xFFFF;
To change the lower 16 bits of value, use bit operation:
lower = <some thing new>;
value = (value & 0xFFFF0000) | lower;
Don't use pointer to access part of the 32bit value, it crates undefined bahavior when you dereference it.
Following short example will work, if int is aligned on 4-bytes (which seems to be guaranteed by gcc, see Casting an int pointer to a char ptr and vice versa):
#include <stdio.h>
int main() {
int v = 0xcafe;
int *ip = &v;
char *cp = (char*) ip;
printf("%hhX\n", *cp); // FE on little-endian box
printf("%hhX\n", *(cp + 1));
*cp = 0xbe;
*(cp + 1) = 0xba;
printf("%X\n", *ip);
return 0;
}
You can guarantee alignment of int thus:
int main() {
__attribute__ ((aligned (4))) int v = 0xcafe;
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I am using the following code to check if bit number 25 value is 0 or 1:
volatile unsigned int * regAddr;
unsigned int regval;
regAddress = (unsigned int *) 0xD2009010; //This is a valid address of register
regVal = *regAddress; //The return value here is 0xFE008000
if (!(regVal & 0x4000000)) //For the mentioned return value, I thought the condition will be different then 0 and so used '!' to convert the value
the bit is 0;
else
the bit is 1;
This code isn't working properly and I cannot figure out why. Help anyone? Thanks in advance
The sure-way to get the 25th bit is:
if (!(regVal & (1 << 24) ))
Or, if you prefer:
#define BIT_25 (1 << 24) // the first-bit, shifted over 24 more times.
if (!(regVal & BIT_25 ))
Several people raise the point that "bit number 25" is ambiguous, depending on if you consider 0x01 to be the first-bit, or the zeroth-bit.Decide this yourself as is appropriate for your program.But no matter what, 0x4000000 is not right.
Take a look at shift operators:
http://www-numi.fnal.gov/offline_software/srt_public_context/WebDocs/Companion/cxx_crib/shift.html
Something like
if ((yourVal >> 25) & 0x1)
Should do what you want.
For example: Printing the whole number then the 25th and 26th bits:
#include <unistd.h>
#include <stdio.h>
int getBitValue(unsigned int num, unsigned int pos) {
return ((num >> pos) & 0x1);
}
int main() {
unsigned int num = 0xD2009010;
printf("Value = 0x%X\n", num);
write(1, "Binary: ", 8);
for (int i = (sizeof(num) * 8); i >= 0; --i) {
if (getBitValue(num, i))
write(1, "1", 1);
else
write(1, "0", 1);
}
write(1, "\n", 1);
printf("25th bit: %d\nBit at index 25 (26th): %d\n",
getBitValue(num, 24),
getBitValue(num, 25));
return 0;
}
If you are trying to test the 25th bit then 0x4000000 is not the right literal, depending on which bit you consider to be the starting bit then you are testing bit 26 or 27.
Of course instead of using hand calculated literals, the easier way you be to use a bit shift, depending what what you consider the starting bit one of these should do what you need:
if( !(regVal & (1 << 24)) )
or
if( !(regVal & (1 << 25)) )
If your code is exactly what you write, then the bit is ...; is not valid C. If that is the problem, use puts("the bit is ...");
About the condition, you should use if (!(regVal & 0x1000000)). That's the value of 1<<(25-1). (In my understandind 0x1 is first bit and so on)
I assume that the address 0xD2009010 is that of the register you are reading, that the architecture you are using has memory mapped registers (and that you are probably writing a device driver, certainly not an application unless you are writing for vxWorks or DOS ....), then if you want to test bit 25 you should test for 0x2000000 (remember that bits start from 0, so each nibble goes up by 4: 0, 4, 8, etc, after 6 0s you are at bit 24 (this would be 0x1000000). You want 25, so this is 0x2000000.