I'm trying to do simple bit operations on a 'char' variable;
I would like to define 5 constants.
const int a = 0;
const int b = 1;
const int c = 2;
const int d = 3;
const int e = 4;
When I try to set more than one bit of the char, all bits apparently up to the set bit a read as set...here is code I use to set and read bits of the char var:
char var = 0;
var |= c;
var|= d;
BOOL set = false;
if(var & b)
set = true; // reads true
if(var & c)
set = true; // also reads true
if(var & d)
set = true; // also reads true
I read an incomplete thread that says that the operation to set bits may be different for x86...the system I'm using...is that the case here?
You're cutting into your other "bits"' space. Examining a couple gives us:
b = 1 = 0001
c = 2 = 0010
d = 3 = 0011 //uh oh, it's b and c put together (ORed)
To get around this, make each one represent a new bit position:
const int a = 0; //or 0x0
const int b = 1; //or 0x1
const int c = 2; //or 0x2 or 1 << 1
const int d = 4; //or 0x4 or 1 << 2
const int e = 8; //or 0x8 or 1 << 3
You should consider not using 0 if there's a possibility of no bits being set meaning something different, too. The main application for this is to set and check flags, and no flags set definitely shows independence.
Change your definitions to because they way you have defined it some of them has more than one bit set
const int a = 1 << 0;
const int b = 1 << 1;
const int c = 1 << 2;
const int d = 1 << 3;
const int e = 1 << 4;
This way it is evident that each constant only has 1 bit set.
If you want to learn all about the various bit hacks...
Related
I am learning C++ and I wonder if it is possible to decompose a structure object into a sequence of bits?
// The task is this! I have a structure
struct test {
// It contains an array
private:
int arr [8];
public:
void init () {
for (int i = 0; i <8; i ++) {
arr [i] = 5;
}
}
};
int main () {
// at some point this array is initialized
test h;
h.init ();
// without referring to the arr field and its elements, we must convert the structure to this format
// we know that int is stored there, and these are 32 bits -> 00000000 00000000 00000000 00000101. 00000000 00000000 00000000 00000101. - and there are 8 such pieces by number
// elements in the array
return -1;
}
Well, we know the size of the array too. We need to convert the structure object to a sequence of bits:
00000000000000000000000000000101000000000000000000000000000001010000000000000000000000000000010100000000000000000000000000000101000000000000000000000000000001010000000000000000000000000000010100000000000000000000000000000000010100000000000000000000000000000101
The standard answer for converting number into bit strings is to you std::bitset. I will use a more low level approach. And use a bit mask and & operation to mask out single bits and then assign the corresdponding characters to the resulting string.
Masking woks with the bit and operator and on the locical AND operation
Bit Mask AND
0 0 0
0 1 0
1 0 0
1 1 1
You see, 0 and 1 is 0. And 1 and 1 is 1.
That allows us to access a bit in a byte.
Byte: 10101010
Mask: 00001111
--------------
00001010
And this mecahnism we will use.
But, I cannot imagine that this is homework, because of the dirty reintepret_cast that would be needed, by accessing the struct from outside.
Anyway. Let me present this solution to you.
I find it utmost ugly.
#include <iostream>
#include <bitset>
// The task is this! I have a structure
struct test {
// It contains an array
private:
int arr[8];
public:
void init() {
for (int i = 0; i < 8; i++) {
arr[i] = 5;
}
}
};
// Convert an int to a string with the bit representaion of the int
std::string intToBits(int value) {
// Here we will store the result
std::string result{};
// We want to mask the bit from MSB to LSB
unsigned int mask = 1<<31;
// Now we will work on 4 bytes with 8bits each
for (unsigned int byteNumber = 0; byteNumber < 4; ++byteNumber) {
for (unsigned int bitNumber = 0; bitNumber < 8; ++bitNumber) {
// Mask out bit and store the resulting 1 or 0 in the string
result += (value & mask) ? '1' : '0';
// Next mask
mask >>= 1;
}
// Add a space between bytes
result += ' ';
}
// At the end, we do want to have a point
result.back() = '.';
return result;
}
int main() {
// At some point this array is initialized
test h;
h.init();
// Now do dirty, ugly, and none compliant type cast
int* test = reinterpret_cast<int*>(&h);
// Convert all bytes and show result
for (unsigned int k = 0; k < 8; ++k)
std::cout << intToBits(test[k]) << ' ';
return 0;
}
Here we have a function fire() which accepts two arguments:
A capital letter (char) in the range of 'A' .. 'A'+BS_GRID_ROWS-1 that indicates the row in your grid to attack.
An integer (int) in the range of 1 .. BS_GRID_COLS that indicates the column of your grid to attack.
The return code will be:
0 if there is only open water.
The bit BS_SHIP_HIT will be set, or both BS_SHIP_HIT and BS_SHIP_SANK will be set. In addition, the ship that was hit will be indicated in the lowest four bits of the return code. You may use BS_SHIP_MASK to help extract the number for the ship type.
semi-pseudocode interpretation:
//r is A ... (A + BS_GRID_ROWS - 1)
//c is 1 ... BS_GRID_COLS
fire(char r, int c) {
//some set of commands
if(miss) {
return 0;
else if(sink) {
return hit + sunk + size;
else if(hit) {
return hit;
else {
return miss;
}
}
I am uncertain of exactly how I might go about extracting these individual values (hit, sunk, size) from the return value.
The actual .h file and it's relevant const values are seen here:
#ifndef BATTLESHIP
#define BATTLESHIP
const int BS_SHIP_HIT = 0x10; // Ship is hit, or
const int BS_SHIP_SANK = 0x20; // sank (must also | BS_SHIP_HIT)
const int BS_CARRIER = 1;
const int BS_BATTLESHIP= 2;
const int BS_CRUISER = 3;
const int BS_DESTROYER = 4;
const int BS_SUBMARINE = 5;
const int BS_SHIP_COUNT = 5;
const int BS_SHIP_MASK = 0x0F;
const int BS_CARRIER_SIZE = 5;
const int BS_BATTLESHIP_SIZE= 4;
const int BS_CRUISER_SIZE = 3;
const int BS_DESTROYER_SIZE = 2;
const int BS_SUBMARINE_SIZE = 3;
const int BS_MODE_NEW_GAME = 1;
const int BS_MODE_CONTINUE_GAME = 2;
const int BS_GRID_ROWS = 10; // letters A to J
const int BS_GRID_COLS = 10; // numbers 1 to 10
const int MaxPlayerCount = 65; // Maximum size for following arrays
extern int userIncoming(char, int);
extern int userBattle(int, int);
extern int incomingStub(char, int);
extern int battleStub(int, int);
extern int (*fire[])(char, int);
extern int (*battleship[])(int, int);
extern char const *playerName[];
#endif
Something like this perhaps?
int result = fire(r, c);
if (result & BS_SHIP_HIT)
{
std::cout << "Ship of size " << result & BS_SHIP_MASK << " hit\n";
}
If the BS_SHIP_HIT bit is set in result, the the result of result & BIT_SHIP_HIT will be equal to BS_SHIP_HIT otherwise the result will be zero (which is equivalent to false).
The result of result & BS_SHIP_MASK will be the low four bits in result.
Or lets look at it using the actual bits:
BS_SHIP_HIT is equal to the binary value 00010000 and BS_SHIT_MASK equal 00001111. Lets assume that fire returns 00010101 (BS_SHIP_HIT set and size 5), then the if condition will be
00010000
& 00010101
----------
= 00010000
Then for the printing, the expression will be
00010101
& 00001111
----------
= 00000101
Anyway have any idea how to do this?
Let's say i have
char x[] = "ABCD";
and i want to put it into an int, so i'll have
int y = 'ABCD';
I can only put individual chars, such as int y = x[0]; The purpose is to find the decimal representation, but i want the decimal representation of "ABCD" not just "A".
Finally i would use sprintf(dest, "%.2u", value); to get the decimal representation of the char.
EDIT:
I dont understand why, but for "ABCD" this code works
//unrolled bit ops
const char* x = "ABCD";
uint32_t y = 0;
y |= (uint32_t(x[0]) << 24); //MSB
y |= (uint32_t(x[1]) << 16);
y |= (uint32_t(x[2]) << 8);
y |= (uint32_t(x[3]) /*<< 0*/);
however, per instance if i use "(¸þ¶" i dont get the same result.
EDIT2 **:
I've tried your last edit Sam, but it still doesnt work. The value i'm getting is "4294967294" as opposed to "683212470" the correct value.
I also did this
int h1 = '(';
int h2 = '¸';
int h3 = 'þ';
int h4 = '¶';
Output:
40
-72
-2
-74
I googled for the complete ascii table, and i found out that for "þ" the value is "254". I suppose it has something to do with this... i also tried with usigned but no good results.
edit3: If i replace const char *x = "(¸þ¶" with int x[] = {40, 184, 254, 182}; (decimal representation of each character, it works. I can understand where things go wrong, but i have no idea how to fix it.
You need to assure int alignment for that char array for a proper cast or do a memcpy into that int.
Also take care of the integer's endianness! Furthermore, usage of C99 integer types such as uint32_t, will also help to make your code portable.
See this question for how to convert the bits:
strict aliasing and alignment
EDIT:
What R. Martinho Fernandes means, might be this (not tested):
//unrolled bit ops
const char* x = "ABCD";
uint32_t y = 0;
y |= (uint32_t(uint8_t(x[0])) << 24); //MSB
y |= (uint32_t(uint8_t(x[1])) << 16);
y |= (uint32_t(uint8_t(x[2])) << 8);
y |= (uint32_t(uint8_t(x[3])) /*<< 0*/);
Above example avoids specific code for any endianness
EDIT 2:
For dynamic char arrays (assuming leading zero chars if less than 4 have to be converted):
const char* x = "ABC";
size_t nChars = 3;
assert(0 < nChars && nChars <= sizeof(uint32_t));
uint32_t y = 0;
int shift = (nChars*8)-8;
for(size_t i = 0;i < nChars;++i)
{
y |= (uint32_t(uint8_t(x[i])) << shift);
shift -= 8;
}
I have created a sample program if this is what you want.
Include the needed headers (stdio.h, stdlib.h, math.h, string.h)
unsigned long convertToInt(char *x);
void main() {
char x[] = "ABCD";
unsigned long y = 0;
y = convertToInt(x);
printf("Numeric value = %lu\n", y);
}
unsigned long convertToInt(char *x) {
unsigned long num = 0, i, n;`
char hex_c;
for(i = 0; i< strlen(x); i++) {
hex_c = x[i];
if (hex_c >= '0' && hex_c <= '9') {
n = hex_c - '0';
} else if (hex_c >= 'A' && hex_c <= 'F') {
n = 10 + hex_c - 'A';
} else if (hex_c >= 'a' && hex_c <= 'f') {
n = 10 + hex_c - 'a';
} else {
printf("Wrong input");
return 0;
}
num += n * (pow(16, (strlen(x) - i - 1)));
}
return num;
}
Hello I have a struct here that is 7 bytes and I'd like to write it to a 64 bit integer. Next, I'd like to extract out this struct later from the 64 bit integer.
Any ideas on this?
#include "stdafx.h"
struct myStruct
{
unsigned char a;
unsigned char b;
unsigned char b;
unsigned int someNumber;
};
int _tmain(int argc, _TCHAR* argv[])
{
myStruct * m = new myStruct();
m->a = 11;
m->b = 8;
m->c = 12;
m->someNumber = 30;
printf("\n%s\t\t%i\t%i\t%i\t%i\n\n", "struct", m->a, m->b, m->c, m->someNumber);
unsigned long num = 0;
// todo: use bitwise operations from m into num (total of 7 bytes)
printf("%s\t\t%i\n\n", "ulong", num);
m = new myStruct();
// todo: use bitwise operations from num into m;
printf("%s\t\t%i\t%i\t%i\t%i\n\n", "struct", m->a, m->b, m->c, m->someNumber);
return 0;
}
You should to do something like this:
class structured_uint64
{
uint64_t data;
public:
structured_uint64(uint64_t x = 0):data(x) {}
operator uint64_t&() { return data; }
unsigned uint8_t low_byte(size_t n) const { return data >> (n * 8); }
void low_byte(size_t n, uint8_t val) {
uint64_t mask = static_cast<uint64_t>(0xff) << (8 * n);
data = (data & ~mask) | (static_cast<uint64_t>(val) << (8 * n));
}
unsigned uint32_t hi_word() const { return (data >> 24); }
// et cetera
};
(there is, of course, lots of room for variation on the details of the interface and where among the 64 bits the constituents are placed)
Using different types to alias the same portion of memory is a generally bad idea. The thing is, it's very valuable for the optimizer to be able to use reasoning like:
"Okay, I've read a uint64_t at the start of this block, and nowhere in the middle does the program write to any uint64_ts, therefore the value must be unchanged!"
which means it will get the wrong answer if you tried to change the value of the uint64_t object through a uint32_t reference. And as this is very dependent what optimizations are possible and done, it is actually pretty easy to never run across the problem in test cases, but see it in the real program you're trying to write -- and you'll spend forever trying to find the bug because you convinced yourself it's not this problem.
So, you really should do the insertion/extraction of the fields with bit twiddling (or intrinsics, if profiling shows that this is a performance issue and there are useful ones available) rather than trying to set up a clever struct.
If you really know what you're doing, you can make the aliasing work, I believe. But it should only be done if you really know what you're doing, and that includes knowing relevant rules from the standard inside and out (which I don't, and so I can't advise you on how to make it work). And even then you probably shouldn't do it.
Also, if you intend your integral types to be a specific size, you should really use the correct types. For example, never use unsigned int for an integer that is supposed to be exactly 32 bits. Instead use uint32_t. Not only is it self-documenting, but you won't run into a nasty surprise when you try to build your program in an environment where unsigned int is not 32 bits.
Use a union. Each element of a union occupies the same address space. The struct is one element, the unsigned long long is another.
#include <stdio.h>
union data
{
struct
{
unsigned char a;
unsigned char b;
unsigned char c;
unsigned int d;
} e;
unsigned long long f;
};
int main()
{
data dat;
dat.f = 0xFFFFFFFFFFFFFFFF;
dat.e.a = 1;
dat.e.b = 2;
dat.e.c = 3;
dat.e.d = 4;
printf("f=%016llX\n",dat.f);
printf("%02X %02X %02X %08X\n",dat.e.a,dat.e.b,dat.e.c,dat.e.d);
return 0;
}
Output, but note one byte of the original unsigned long long remains. Compilers like to align data such as 4-byte integers on addresses divisible by 4, so three bytes, then a pad byte so the integer is at offset 4 and the struct has a total size of 8.
f=00000004FF030201
01 02 03 00000004
This can be controlled in compiler-dependent fashion. Below is for Microsoft C++:
#include <stdio.h>
#pragma pack(push,1)
union data
{
struct
{
unsigned char a;
unsigned char b;
unsigned char c;
unsigned int d;
} e;
unsigned long long f;
};
#pragma pack(pop)
int main()
{
data dat;
dat.f = 0xFFFFFFFFFFFFFFFF;
dat.e.a = 1;
dat.e.b = 2;
dat.e.c = 3;
dat.e.d = 4;
printf("f=%016llX\n",dat.f);
printf("%02X %02X %02X %08X\n",dat.e.a,dat.e.b,dat.e.c,dat.e.d);
return 0;
}
Note the struct occupies seven bytes now and the highest byte of the unsigned long long is now unchanged:
f=FF00000004030201
01 02 03 00000004
Got it.
static unsigned long long compress(char a, char b, char c, unsigned int someNumber)
{
unsigned long long x = 0;
x = x | a;
x = x << 8;
x = x | b;
x = x << 8;
x = x | c;
x = x << 32;
x = x | someNumber;
return x;
}
myStruct * decompress(unsigned long long x)
{
printBinary(x);
myStruct * m = new myStruct();
m->someNumber = x | 4294967296;
x = x >> 32;
m->c = x | 256;
x = x >> 8;
m->b = x | 256;
x = x >> 8;
m->a = x | 256;
return m;
}
I was looking at an example of reading bits from a byte and the implementation looked simple and easy to understand. I was wondering if anyone has a similar example of how to insert bits into a byte or byte array, that is easier to understand and also implement like the example below.
Here is the example I found of reading bits from a byte:
static int GetBits3(byte b, int offset, int count)
{
return (b >> offset) & ((1 << count) - 1);
}
Here is what I'm trying to do. This is my current implementation, I'm just a little confused with the bit-masking/shifting, etc., so I'm trying to find out if there is an easier way to do what I'm doing
BYTE Msg[2];
Msg_Id = 3;
Msg_Event = 1;
Msg_Ready = 2;
Msg[0] = ( ( Msg_Event << 4 ) & 0xF0 ) | ( Msg_Id & 0x0F ) ;
Msg[1] = Msg_Ready & 0x0F; //MsgReady & Unused
If you are using consecutive integer constant values like in the example above, you should shift the bits with these constants when putting them inside a byte. Otherwise they overlap: in your example, Msg_Id equals Msg_Event & Msg_Ready. These can be used like
Msg[0] = ( 1 << Msg_Event ) | ( 1 << Msg_Id); // sets the 2nd and 4th bits
(Note that bits within a byte are indexed from 0.) The other approach would be using powers of 2 as constant values:
Msg_Id = 4; // equals 1 << 2
Msg_Event = 1; // equals 1 << 0
Msg_Ready = 2; // equals 1 << 1
Note that in your code above, masking with 0x0F or 0xF0 is not really needed: (Msg_Id & 0x0F) == Msg_Id and ((Msg_Event << 4) & 0xF0) == (Msg_Event << 4).
You could use a bit field. For instance :
struct Msg
{
unsigned MsgEvent : 1; // 1 bit
unsigned MsgReady : 1; // 1 bit
};
You could then use a union to manipulate either the bitfield or the byte, something like this :
struct MsgBitField {
unsigned MsgEvent : 1; // 1 bit
unsigned MsgReady : 1; // 1 bit
};
union ByteAsBitField {
unsigned char Byte;
MsgBitField Message;
};
int main() {
ByteAsBitField MyByte;
MyByte.Byte = 0;
MyByte.Message.MsgEvent = true;
}