From what I understand, the bitwise inclusive OR operator compares every bit in the first and second operand and returns 1 if either bit is 1. Bjarne Stroustrup uses it like this (ist being an istream object):
ist.exceptions(ist.exceptions()|ios_base::bad_bit);
I haven't really worked with bits a lot in programming, should it be on my to-do list to learn? I understand that if I had an int and the value was 9, the binary would be 00001001, but that is pretty much it. I do not understand why he would use this operator in the context that he used it in.
In this case, it simply means "turn a bit on".
Just an example: I have a byte 0100 0011 serves as 8 booleans. I want to turn on 4th bit (i.e. make 4th boolean true)
By bitwise operation, it looks like this: [0100 0011] Bitwise-OR [0000 1000] and it will give you 0100 1011. Which means, it simply change 4th bit to true, regardless of its original value
You can think of it as a way to add an option to a set of existing options. An analogy would be if you're familiar with linux:
PATH = "$PATH:/somenewpath"
This says 'I want the existing path and this new path /somenewpath'
In this case he's saying 'I want the existing options in exceptions and I want the bad_bit option as well'
The std::ios::exceptions is a function which gets/sets an exception mask in the file which is used by the file object to decide in which situations it should throw an exception or not.
There exist two implementations of this function:
iostate exceptions() const; // get current bit mask
void exceptions (iostate except); // set new bit mask
The statement you've posted sets the new exception mask to the file object using ios_base::badbit flag combined with the current flags, that are currently set in the file object.
The OR bitwise operator is often used in order to create create a bitfield using already existing bitfield and a new flag. It could also be used in order to combine two flags together into a new bitfield.
Here is an example with explanation:
// Enums are usually used in order to represent
// the bitfields flags, but you can just use the
// constant integer values.
// std::ios::bad_bit is, actually, just a constant integer.
enum Flags {
A,
B,
C
};
// This function is similar to std::ios::exceptions
// in the sense that it returns a bitfield (integer,
// in which bits are manipulated directly).
Something foo() {
// Return a bitfield in which A and B flags
// are "on".
return A | B;
}
int main() {
// The actual bitfield, which is represented as a 32-bit integer
int bf = 0;
// This is what you've seen (well, somethng similar).
// So, we're assigning a new bitfield to the variable bf.
// The new bitfield consists of the flags which are enabled
// in the bitfield which foo() returns and the C flag.
bf = foo() | C;
return 0;
}
Related
I'm working on a microcontroller with only 2KB of SRAM and desperately need to conserve some memory. Trying to work out how I can put 8 0/1 values into a single byte using a bitfield but can't quite work it out.
struct Bits
{
int8_t b0:1, b1:1, b2:1, b3:1, b4:1, b5:1, b6:1, b7:1;
};
int main(){
Bits b;
b.b0 = 0;
b.b1 = 1;
cout << (int)b.b0; // outputs 0, correct
cout << (int)b.b1; // outputs -1, should be outputting 1
}
What gives?
All of your bitfield members are signed 1-bit integers. On a two's complement system, that means they can represent only either 0 or -1. Use uint8_t if you want 0 and 1:
struct Bits
{
uint8_t b0:1, b1:1, b2:1, b3:1, b4:1, b5:1, b6:1, b7:1;
};
As a word of caution - the standard doesn't really enforce an implementation scheme for bitfields. There is no guarantee that Bits will be 1 byte, and hypothetically it is entirely possible for it to be larger.
In practice however the actual implementations usually follow the obvious logic and it will "almost always" be 1 byte in size, but again, there is no requirement that it is guaranteed. Just in case you want to be sure, you could do it manually.
BTW -1 is still true but it -1 != true
As noted, these variables consist of only a sign bit, so the only available values are 0 and -1.
A more appropriate type for these bitfields would be bool. C++14 ยง9.6/4:
If the value true or false is stored into a bit-field of type bool of any size (including a one bit bit-field), the original bool value and the value of the bit-field shall compare equal.
Yes, std::uint8_t will do the job, but you might as well use the best fit. You won't need things like the cast for std::cout << (int)b.b0;.
Signed and unsigned integers are the answer.
Keep in mind that signaling is just an interpretation of bits, -1 or 1 is just the 'print' serializer interpreting the "variable type", as it was "revealed" to cout functions (look operator overloading) by compiler, the bit is the same, its value also (on/off) - since you have only 1 bit.
Don't care about that, but is a good practice to be explicit, so prefer to declare your variable with unsigned, it instructs the compiler to mount a proper code when you set or get the value to a serializer like "print" (cout).
"COUT" OPERATOR OVERLOADING:
"cout" works through a series of functions which the parameter overloading instructs the compiler which function to call. So, there are two functions, one receives an unsigned and another signed, thus they can interpret the same data differently, and you can change it, instructing the compiler to call another one using cast. See cout << myclass
Here's my issue: I need to pass back two uint32_t's via a single uint32_t (because of how the API is set up...). I can hard code whatever other values I need to reverse the operation, but the parameter passed between functions needs to stay a single uint32_t.
This would be trivial if I could just bit-shift the two 32-bit ints into a single 64-bit int (like what was explained here), but the compiler wouldn't like that. I've also seen mathematical pairing functions, but I'm not sure if that's what I need in this case.
I've thought of setting up a simple cipher: the unint32_t could be the cipher text, and I could just hard code the key. This is an example, but that seems like overkill.
Is this even possible?
It is not possible to store more than 32 bits of information using only 32 bits. This is a basic result of information theory.
If you know that you're only using the low-order 16 bits of each value, you could shift one left 16 bits and combine them that way. But there's absolutely no way to get 64 bits worth of information (or even 33 bits) into 32 bits, period.
Depending on how much trouble this is really worth, you could:
create a global array or vector of std::pair<uint32_t,uint32_t>
pass an index into the function, then your "reverse" function just looks up the result in the array.
write some code to decide which index to use when you have a pair to pass. The index needs to not be in use by anyone else, and since the array is global there may be thread-safety issues. Essentially what you are writing is a simple memory allocator.
As a special case, on a machine with 32 bit data pointers you could allocate the struct and reinterpret_cast the pointer to and from uint32_t. So you don't need any globals.
Beware that you need to know whether or not the function you pass the value into might store the value somewhere to be "decoded" later, in which case you have a more difficult resource-management problem than if the function is certain to have finished using it by the time it returns.
In the easy case, and if the code you're writing doesn't need to be re-entrant at all, then you only need to use one index at a time. That means you don't need an array, just one pair. You could pass 0 to the function regardless of the values, and have the decoder ignore its input and look in the global location.
If both special cases apply (32 bit and no retaining of the value), then you can put the pair on the stack, and use no globals and no dynamic allocation even if your code does need to be re-entrant.
None of this is really recommended, but it could solve the problem you have.
You can use an intermediate global data structure to store the pair of uint32_t on it, using your only uint32_t parameter as the index on the structure:
struct my_pair {
uint32_t a, b;
};
std::map<uint32_t, my_pair> global_pair_map;
uint32_t register_new_pair(uint32_t a, uint32_t b) {
// Add the pair of (a, b) to the map global_pair_map on a new key, and return the
// new key value.
}
void release_pair(uint32_t key) {
// Remove the key from the global_pair_map.
}
void callback(uint32_t user_data) {
my_pair& p = global_pair_map[user_data];
// Use your pair of uint32_t with p.a, and p.b.
}
void main() {
uint32_t key = register_new_pair(number1, number2);
register_callback(callback, key);
}
If there is for example a class that requires a pointer and a bool. For simplicity an int pointer will be used in examples, but the pointer type is irrelevant as long as it points to something whose size() is more than 1 .
Defining the class with { bool , int *} data members will result in the class having a size that is double the size of the pointer and a lot of wasted space
If the pointer does not point to a char (or other data of size(1)), then presumably the low bit will always be zero. The class could defined with {int *} or for convenience: union { int *, uintptr_t }
The bool is implemented by setting/clearing the low bit of the pointer as per the logical bool value and clearing the bit when you need to use the pointer.
The defined way:
struct myData
{
int * ptr;
bool flag;
};
myData x;
// initialize
x.ptr = new int;
x.flag = false;
// set flag true
x.flag = true;
// set flag false
x.flag = false;
// use ptr
*(x.ptr)=7;
// change ptr
x = y; // y is another int *
And the proposed way:
union tiny
{
int * ptr;
uintptr_t flag;
};
tiny x;
// initialize
x.ptr = new int;
// set flag true
x.flag |= 1;
// set flag false
x.flag &= ~1;
// use ptr
tiny clean=x; // note that clean will likely be optimized out
clean.flag &= ~1; // back to original value as assigned to ptr
*(clean.ptr)=7;
// change ptr
bool flag=x.flag;
x.ptr = y; // y is another int *
x.flag |= flag;
This seems to be undefined behavior, but how portable is this?
As long as you restore the pointer's low-order bit before trying to use it as a pointer, it's likely to be "reasonably" portable, as long as your system, your C++ implementation, and your code meet certain assumptions.
I can't necessarily give you a complete list of assumptions, but off the top of my head:
It assumes you're not pointing to anything whose size is 1 byte. This excludes char, unsigned char, signed char, int8_t, and uint8_t. (And that assumes CHAR_BIT == 8; on exotic systems with, say, 16-bit or 32-bit bytes, other types might be excluded.)
It assumes objects whose size is at least 2 bytes are always aligned at an even address. Note that x86 doesn't require this; you can access a 4-byte int at an odd address, but it will be slightly slower. But compilers typically arrange for objects to be stored at even addresses. Other architectures may have different requirements.
It assumes a pointer to an even address has its low-order bit set to 0.
For that last assumption, I actually have a concrete counterexample. On Cray vector systems (J90, T90, and SV1 are the ones I've used myself) a machine address points to a 64-bit word, but the C compiler under Unicos sets CHAR_BIT == 8. Byte pointers are implemented in software, with the 3-bit byte offset within a word stored in the otherwise unused high-order 3 bits of the 64-bit pointer. So a pointer to an 8-byte aligned object could have easily its low-order bit set to 1.
There have been Lisp implementations (example) that use the low-order 2 bits of pointers to store a type tag. I vaguely recall this causing serious problems during porting.
Bottom line: You can probably get away with it for most systems. Future architectures are largely unpredictable, and I can easily imagine your scheme breaking on the next Big New Thing.
Some things to consider:
Can you store the boolean values in a bit vector outside your class? (Maintaining the association between your pointer and the corresponding bit in the bit vector is left as an exercise).
Consider adding code to all pointer operations that fails with an error message if it ever sees a pointer with its low-order bit set to 1. Use #ifdef to remove the checking code in your production version. If you start running into problems on some platform, build a version of your code with the checks enabled and see what happens.
I suspect that, as your application grows (they seldom shrink), you'll want to store more than just a bool along with your pointer. If that happens, the space issue goes away, because you're already using that extra space anyway.
In "theory": it's undefined behavior as far as I know.
In "reality": it'll work on everyday x86/x64 machines, and probably ARM too?
I can't really make a statement beyond that.
It's very portable, and furthermore, you can assert when you accept the raw pointer to make sure it meets the alignment requirement. This will insure against the unfathomable future compiler that somehow messes you up.
Only reasons not to do it are the readability cost and general maintenance associated with "hacky" stuff like that. I'd shy away from it unless there's a clear gain to be made. But it is sometimes totally worth it.
Conform to those rules and it should be very portable.
I want to modify individual bits of data, (for e.g. ints or chars). I want to do this by making a pointer, say ptr. by assigning it to some int or char, and then after incrementing ptr n times, I want to access the nth bit of that data.
Something like
// If i want to change all the 8 bits in a char variable
char c="A";
T *ptr=&c; //T is the data type of pointer I want..
int index=0;
for(index;index<8;index++)
{
*ptr=1; //Something like assigning 1 to the bit pointed by ptr...
}
There no such thing as a bit pointer in C++. You need to use two things, a byte pointer and an offset to the bit. That seems to be what you are getting towards in your code. Here's how you do the individual bit operations.
// set a bit
*ptr |= 1 << index;
// clear a bit
*ptr &= ~(1 << index);
// test a bit
if (*ptr & (1 << index))
...
The smallest addressable memory unit in C and C++ is 1 byte. So You cannot have a pointer to anything less than a byte.If you want to perform bitwise operations C and C++ provide the bitwise operators for these operations.
It is impossible to have address of individual bit, but you can utilize structures with bit fields. Like in this example from Wikipedia so:
struct box_props
{
unsigned int opaque : 1;
unsigned int fill_color : 3;
unsigned int : 4; // fill to 8 bits
unsigned int show_border : 1;
unsigned int border_color : 3;
unsigned int border_style : 2;
unsigned int : 2; // fill to 16 bits
};
Then by manipulating individual fields you will change sets of bits inside unsigned int. Technically this is identical to bitwise operations, but in this case compiler will generate the code (and you have lower chances of bug).
Be advised that you have to be cautious using bit fields.
C and C++ doesn't have a "bit pointer", technically speaking, C and C++ as such, deosn't know about "bits". You could build your own type, to do this, you need two things: A pointer to some type (char, int - probably unsigned) and a bit number. You'd then use the pointer and the bit number, along with the bitwise operators, to actually access the values.
There is nothing like a pointer to a bit
If you want all bits set to 1 then c = 0xff; is what you want, if you want to set a bit under some condition:
for(index;index<8;index++)
{
if (condition) c |= 1 << index;
}
As you can see there is no need to use a pointer
You can not read a single bit from the memory, CPU always read a full cache line, which could have different sizes for different CPUs.
But from the language point of view you can use bit fields
http://publications.gbdirect.co.uk/c_book/chapter6/bitfields.html
http://en.wikipedia.org/wiki/Bit_field
I am new to C++ and have programming knowledge only in Java. Can anyone please explain the meaning of the code below:
#define DEF 134 ;
int k;
char msk;
PMSK *pm; //At the begining of class some declaration
// i is some counter(int)
if ( (nVersion >= 2004) && (nVersion < 2008))
{
k = to_bits(DEF, &msk);
if ( pm->orbits[k] & msk ) // for version >= 2004
{
x = atoi( grprs[i] );
if ( !defpair( i, x ) )
pm->orbits[k] &= 0xFF ^ msk; // turn off bit
}
}
to_bits() is method which will return an integer value and a (char) msk value (example 1000). It has bit operations involved in it.
What is pm->orbits[k]? Can we replace it in Java like pm.orbits[k]?
Also, what exactly the last line of code doing?
What is pm->orbits[k]? can we replace it in java like pm.orbits[k]?
Basically, yes. The -> operator de-references and then access a field (also known as access the field/function of the object pointed to by the pointer). However, if you had a reference type to begin with, you get the de-referencing "for free".
PMSK *pm1; // assume this has been initialized to point to something valid
PMSK &pm2; // assume this is a valid reference
PMSK pm3; // assume this is a valid declaration
pm1->orbits[0]; // accesses field orbits[0] of object pointed to by pm1
(*pm1).orbits[0]; // equivalent to above statement
pm2.orbits[0]; // it's implicitly understood that de-referencing should take place
pm3.orbits[0]; // no need to dereference
Dissecting the last line of code:
pm->orbits[k] &= 0xFF ^ msk; // turn off bit
^ is the bitwise exclusive or operator (a.k.a. xor). Basically it returns a bit value of 1 if both bits are not equal and 0 otherwise.
&= is the bitwise-and assigment operator. Equivalent to the following:
pm->orbits[k] = pm->orbits[k] & (0xFF^msk);
The bitwise and operator matches up equivalent bits and determines if both are 1. If they are, the result is 1. Otherwise, it's 0. So 100001 & 100100 = 100000 (binary numbers).
So it takes whatever's in msk, toggles the lowest 8 bits (1 -> 0 and 0 -> 1), then bitwise-ands that with the current pm->orbits[k] field. Finally, it assigns the result back to pm->orbits[k]
In Java, it's required to have an explicit check to somehow convert the results from a number to a boolean. However, in C++ it's implicitly understood that anything which isn't 0 is true.
if(1) // same as if(1!=0)
if(2) // same as if(2!=0)
if(0) // same as if(0!=0)
if(-1) // same as if(-1!=0)
Yes you can replace the code you mention. The '->' operator dereferences a pointer to a PMSK object. Java doesn't have pointers, only references, but they are used in the same way.
The last line is clearing the bits set in msk, however it's normally done like this:
pm->orbits[k] &= ~msk;
If you want to set the bits in msk, you'd use:
pm->orbits[k] |= msk;
Also, the following line will need to evaluate to a boolean expression, where as in C++ it just needs to be non-zero:
if ((pm->orbits[k] & msk) != 0)
{
...
}
What is pm->orbits[k]? can we replace
it in java like pm.orbits[k]?
Yes, pm is a pointer, and the -> notation is how to access members on a pointer.
The last line is a bitwise operation, called an exclusive or, the ^ operator is the same and does the same thing in Java.
The -> operator dereferences a pointer to select a field.
The last line of code does a bitwise exclusive or (XOR) of the msk value with 0xFF. This value is then bitwise ANDed with the pm->orbits array value at index k.
A few subjects that are going to help as you learn C++ and work with this code
Pointers in general
http://www.cplusplus.com/doc/tutorial/pointers/
C++ for Java Programmers ht
Bitwise operations in general http://vipan.com/htdocs/bitwisehelp.html
Arrays in C++
Passing by reference and value
Just about any introductory C++ text will have this info.