This function doesnt work correctly for some inputs, So What is the mistake ?
All Projects Codes here : link
ps: I am using input that "bits.size()%8" equal to zero
QByteArray bitsToBytes(QBitArray bits) {
QByteArray bytes;
bytes.resize(bits.count()/8);
// Convert from QBitArray to QByteArray
for(int b=0; b<bits.count(); ++b)
bytes[b/8] = ( bytes.at(b/8) | ((bits[b]?1:0)<<(b%8)));
return bytes;
}
Topro algorithm should be correct as a whole. But my concert is with the test bits[b]?1:0.
By default, operator[] ( int i ) return "the bit at index position i as a modifiable reference" while operator[] ( int i ) const return a boolean. If the first definition is chozen, you will test if a reference is true.
Try Topro algorithm with bits.testBit(b).
i think it's maybe the bits shall be left shifted (7 - (b % 8)) bits
I tried this and got the expected result.
QBitArray bits;
QByteArray bytes;
bits.resize(12);
bits.fill(true);
bits.setBit(2,false);
bytes.resize((bits.count() - 1) / 8 + 1);
for(int b=0; b<bits.count(); ++b)
bytes[b/8] = ( bytes.at(b/8) | ((bits[b]?1:0)<<(7-(b%8))));
for (int b=0;b<bytes.size();b++)
printf("%d\n",(quint8)bytes.at(b));
Consider the case, where (bits.count() % 8) != 0 , e.g. 9
Then bytes.resize(bits.count()/8); returns the wrong result.
As Topro suggested in a comment, you could use bytes.resize((bits.count() - 1) / 8 + 1)).
Related
I have an 8 byte QByteArray and I need to check a specific bit in that array, but not the same bit every time. It could be any of the 64 bits that make up that 8 byte array. Performance is priority!
My current method first grabs a specific byte from that array, then gets a specific half-byte (or nibble), and then converts to another QByteArray with binary representation using QByteArray::number(x, 2), and then finally I check the bit. This sucks and I want a better way.
I opted to load it into a QBitArray so I can quickly and easily retrieve a specific bit. I assumed its representation in memory is the same as a QByteArray or quint64, so conversion would be accepted, but conversion is not allowed.
How would I check if a specific bit (0 to 63) in a QByteArray is 1 or 0, quickly?
QBitArray wasn't designed to be convertible to anything else; its internal representation is indeed internal.
Alas, bit checking is rather easy. Modern architectures use barrel shifters, so shifting is cheap.
There are several possible bit-to-byte mappings. Let's cover all of them:
byte 0 byte 1 byte n-1 byte n
LL - [01234567] [89ABCDEF] ...
LB - [76543210] [FEDCBA98] ...
BL - ... [89ABCDEF] [01234567]
BB - ... [FEDCBA98] [76543210]
Thus:
enum class BitMapping { LL, LB, BL, BB };
bool getBit1(const QByteArray & arr, int bit, BitMapping m) {
Q_ASSERT(arr.size() >= 8);
auto byte = (m == BitMapping::LL || m == BitMapping::LB) ?
bit/8 : (7 - bit/8);
bit = (m == BitMapping::LB || m == BitMapping::BB) ?
(bit%8) : (7 - (bit%8));
return arr.at(byte) & (1<<bit);
}
If we assume that the platform has sensible support for 64-bit integers, we can leverage those:
bool getBit2(const QByteArray & arr, int bit, BitMapping m) {
Q_ASSERT(arr.size() >= 8);
auto value = *reinterpret_cast<const quint64 *>(arr.data());
if (m == BitMapping::LL || m == BitMapping::BL)
bit = (bit & 0x38) + 7 - (bit & 0x07); // reorder bits
if ((Q_BYTE_ORDER == Q_LITTLE_ENDIAN && (m == BitMapping::BL || m == BitMapping::BB)) ||
(Q_BYTE_ORDER == Q_BIG_ENDIAN && (m == BitMapping::LL || m == BitMapping::LB)))
bit = (bit & 0x07) + 0x38 - (bit & 0x38); // reorder bytes
return value & (1<<bit);
}
Any decent compiler will inline either implementation above when specialized, e.g.
bool getBit(const QByteArray & arr, int bit) {
return getBit2(arr, bit, BitMapping::LB);
}
You can also specialize it by hand for the LB case:
bool getBit1(const QByteArray & arr, int bit) {
Q_ASSERT(arr.size() >= 8);
auto byte = bit/8;
bit = bit%8;
return arr.at(byte) & (1<<bit);
}
bool getBit2(const QByteArray & arr, int bit) {
Q_ASSERT(arr.size() >= 8);
auto value = *reinterpret_cast<const quint64 *>(arr.data());
if (Q_BYTE_ORDER == Q_BIG_ENDIAN)
bit = (bit & 0x07) + 0x38 - (bit & 0x38); // reorder bytes
return value & (1<<bit);
}
Note that the Q_BYTE_ORDER check is a compile-time constant and incurs no runtime overhead.
getBit1 and getBit2 are portable to all platforms Qt runs on, and getBit2 generates a little better code than getBit1. On x86-64, the bit twiddling code from getBit2 amounts to 5 instructions:
mov $0x1,%eax
shl %cl,%eax
cltq
test %rax,(%rdi)
setne %al
retq
I guess all you need to do is traverse through bits.
1) checks for bit you wanted
if(j+(i*CHAR_BIT) == (bit-1))
2) Skips non required bytes if the passed 'bit' doesn't fit in specific byte
(((i+1)*CHAR_BIT) < (bit-1))
3) Skips all further bytes if the current bit position is greater than passed bit.
((j+(i*CHAR_BIT)) > (bit-1))
Below is the full solution.
quint8 checkBit(QByteArray bytes, int bit) {
quint8 result=0;
for(int i = 0; i < bytes.count(); ++i) {
for (int j = 0; j < CHAR_BIT; ++j) {
if(j+(i*CHAR_BIT) == (bit-1)) {
result = (bytes.at(i) & (1 << (7-j))) ? 1 : 0;
break;
}
else if(((i+1)*CHAR_BIT) < (bit-1) || ((j+(i*CHAR_BIT)) > (bit-1))) { // out of range skips
break;
}
}
}
return result;
}
Note: As the position starts from 0, so when you pass bit .. say 8 which is actually 8-1 = 7 : [0,1,2,3,4,5,6,7]
DWORD FindPattern(DWORD base, DWORD size, char *pattern, char *mask)
{
// Get length for our mask, this will allow us to loop through our array
DWORD patternLength = (DWORD)strlen(mask);
for (DWORD i = 0; i < size - patternLength; i++)
{
bool found = true;
for (DWORD j = 0; j < patternLength; j++)
{
// If we have a ? in our mask then we have true by default,
// or if the bytes match then we keep searching until finding it or not
found &= mask[j] == '?' || pattern[j] == *(char*)(base + i + j);
}
// Found = true, our entire pattern was found
// Return the memory addy so we can write to it
if (found)
{
return base + i;
}
}
return NULL;
}
Above is my FindPattern function that I use to find bytes in a given section of memory, here's how I call the function:
DWORD PATTERN = FindPattern(0xC0000000, 0x20000,"\x1F\x37\x66\xE3", "xxxx");
PrintStringBottomCentre("%02x", PATTERN);
Now, say I had an integer for example: 0xDEADBEEF
I want to convert this into a char pointer like: "\xDE\xAD\xBE\xEF", this is so that I can put it into my FindPattern function. How would I do this?
You have to be careful here. On many architectures including x86, ints are stored using little endian, meaning that the int 0xDEADBEEF is stored in memory in this order: EF BE AD DE. But the char array is stored in the order DE AD BE EF.
So the question is, are you trying to find an int 0xDEADBEEF stored in memory, or do you actually want the sequence of bytes DE AD BE EF?
If you want the int, don't use a char* array at all. Pass in your pattern and mask as DWORDs, and you can simplify that function a lot.
If you want to find the sequence of bytes, then don't store it as an int in the first place. Just get the input as a char array and pass it directly in as your pattern.
Edit: you can try something like this, which I think will give you what you want:
int a = 0xDEADBEEF;
char pattern[4];
pattern[0] = (a >> 24) & 0xFF;
pattern[1] = (a >> 16) & 0xFF;
pattern[2] = (a >> 8) & 0xFF;
pattern[3] = a & 0xFF;
The \ character in C/C++ is an escape character, so anything that follows it is translated to the escape character you want, hex conversion (\x) in your string. In order to avoid that, add another \ before it so it will be considered as a normal character.
Ex.) \\xDE\\xAD\\xBE\\xEF
So basically i need to check if a certain sequence of bits occurs in other sequence of bits(32bits).
The function shoud take 3 arguments:
n right most bits of a value.
a value
the sequence where the n bits should be checked for occurance
The function has to return the number of bit where the desired sequence started. Example chek if last 3 bits of 0x5 occur in 0xe1f4.
void bitcheck(unsigned int source, int operand,int n)
{
int i,lastbits,mask;
mask=(1<<n)-1;
lastbits=operand&mask;
for(i=0; i<32; i++)
{
if((source&(lastbits<<i))==(lastbits<<i))
printf("It start at bit number %i\n",i+n);
}
}
Your loop goes too far, I'm afraid. It could, for example 'find' the bit pattern '0001' in a value ~0, which consists of ones only.
This will do better (I hope):
void checkbit(unsigned value, unsigned pattern, unsigned n)
{
unsigned size = 8 * sizeof value;
if( 0 < n && n <= size)
{
unsigned mask = ~0U >> (size - n);
pattern &= mask;
for(int i = 0; i <= size - n; i ++, value >>= 1)
if((value & mask) == pattern)
printf("pattern found at bit position %u\n", i+n);
}
}
I take you to mean that you want to take source as a bit array, and to search it for a bit sequence specified by the n lowest-order bits of operand. It seems you would want to perform a standard mask & compare; the only (minor) complication being that you need to scan. You seem already to have that idea.
I'd write it like this:
void bitcheck(uint32_t source, uint32_t operand, unsigned int n) {
uint32_t mask = ~((~0) << n);
uint32_t needle = operand & mask;
int i;
for(i = 0; i <= (32 - n); i += 1) {
if (((source >> i) & mask) == needle) {
/* found it */
break;
}
}
}
There are some differences in the details between mine and yours, but the main functional difference is the loop bound: you must be careful to ignore cases where some of the bits you compare against the target were introduced by a shift operation, as opposed to originating in source, lest you get false positives. The way I've written the comparison makes it clearer (to me) what the bound should be.
I also use the explicit-width integer data types from stdint.h for all values where the code depends on a specific width. This is an excellent habit to acquire if you want to write code that ports cleanly.
Perhaps:
if((source&(maskbits<<i))==(lastbits<<i))
Because:
finding 10 in 11 will be true for your old code. In fact, your original condition will always return true when 'source' is made of all ones.
I was trying out the bitset class in C++ and I tried this with the number 137 as an example:
So, I converted it to binary number which gave me 10001001. Now, I wanted to cut off the MSB and store the rest bits 0001001 in another bit instance called bitarray and I was expecting to see that in the bitarray but it wasn't giving the right value. what could have been the problem? I was just trying to split the MSB from the rest of the bits in the 137 binary representation...here is the code:
bitset<8> bitarray;
bitset<8> bitsetObject(num);
int val = bitsetObject.size();
for (int i = 0; i <= (val - 1); i++)
{
if (i == 6)
break;
else
bitarray[i] = bitsetObject[i + 1];
}
If anyone knows how I could easily slice from the second element to the last element in the bitsetObject array, let me know. Thanks..
If you're just trying to make a new bitset object with the most significant set bit reset, then consider the following:
template<std::size_t N>
std::bitset<N> strip_mssb(std::bitset<N> bitarray)
{
for (std::size_t i = bitarray.size(); i--;)
if (bitarray[i])
{
bitarray.reset(i);
break;
}
return bitarray;
}
Online demo.
You set bitarray[0] equal to bitsetObject[1], which is 0 (assuming num is really 137).
You seem to expect the least bit of bitarray to be equal to 1.
this should be the final part of my integer class, and it seems to be very easy, and yet, something is wrong. is this code correct for multiplication using 2 deques?
// 0x12345 = {0x01, 0x23, 0x45}
integer operator*(integer rhs){
// long multiplication
unsigned int zeros = 0;
std::deque <uint8_t> row;
std::deque <std::deque <uint8_t> > temp;
integer out = 0;
for(std::deque <uint8_t>::reverse_iterator i = value.rbegin(); i != value.rend(); i++){
row = std::deque <uint8_t>(zeros++, 0); // zeros on the right hand side
uint8_t carry = 0;
for(std::deque <uint8_t>::reverse_iterator j = rhs.value.rbegin(); j != rhs.value.rend(); j++){
uint16_t prod = (uint16_t(*i) * uint16_t(*j)) + carry;// multiply through
row.push_front((uint8_t) prod);
carry = prod >> 8;
}
if (carry != 0)
row.push_front(carry);
out += integer(row);
}
return out;
}
it is giving me 4931550625 ^ 2 -> 24248133972899962689. assuming that the operator+ is correct, which i seems to be, is there some other explanation of why this is wrong
edit: i updated the code according to wxffles, but i think i did it wrong, since im still getting 2424..., and for 0x25 * 0x25 im getting 89 (decimal)
edit2: the correct code is posted
I think you are missing the last carry. Do you not need:
row.push_front(carry);
just before you add the row to out?