Related
I am sort of new to the language features of meta programming and I am trying to make a simple class with public static const variables that will set its values by compile time constants:
What I'm trying to achieve: I want to compute values that are the power of some exponent that are measured in number of bytes converted to number of bits with a base of 2. All calculations are in base 2.
Examples:
1 byte(s) = 8 bits: value = pow(2, 8) = 256;
2 byte(s) = 16 bits: value = pow(2, 16) = 65536
4 byte(s) = 32 bits: value = pow(2, 32) = 4294967296
8 byte(s) = 64 bits: value = pow(2, 64) = 18446744073709551616
I've tried writing a function to do the calculations to compute the values needed while trying to use constexpr or const, and I've tried using templates. I would like to use the const function, constexpr function or function template as such:
// constexpr function
constexpr std::uint64_t pow2( const std::uint32_t expInBytes, const std::uint32_t base = 2 ) {
const std::uint32_t expInBits = expInBytes * CHAR_BIT;
return static_cast<std::uint64_t>( expInBits == 0 ? 1 : base * pow2( base, expInBits - 1 ) );
}
// or function template
template<std::uint32_t expInbytes>
constexpr std::uint64_t pow2() {
const std::uint32_t base = 2;
const std::uint32_t expInBits = expInBytes * CHAR_BIT;
return (expInBits == 0 ? 1 : base * pow2<expInBytes-1>() );
}
template<>
constexpr std::uint64_t pow2<0>() {
return 0;
};
// template parameter T not used but needed to use the class as such:
// BitCombinations<>::static_member;
template<typename T = const std::uint32_t>
class BitCombinations {
public: // template // non template
static const std::uint64_t ONE_BYTE = pow2<1>(); // pow2( 1 );
static const std::uint64_t TWO_BYTES = pow2<2>(); // pow2( 2 );
static const std::uint64_t FOUR_BYTES = pow2<4>(); // pow2( 4 );
static const std::uint64_t EIGHT_BYTES = pow2<8>(); // pow2( 8 );
};
Through my efforts I've generated all sorts of compile time, run time errors ect. The latest attempt I was able to get the template version of the pow2<>() above to compile and run, however I'm not getting the correct results.
I'm not sure if my implementation of pow2 is wrong or if my syntax is wrong, or if I'm not using const or constexpr correctly and in some cases I kept getting the integral constant overflow as a compile time error from MS Visual Studio 2017 CE compiler.
I've been following these patterns for the pow2() function:
nullptr.me:C++11 constexpr : computing exp at compile time
prosepoetrycode.potterpcs.net : A simple constexpr power function (C++)
cppreference.com : math::exp2
reformatcode.com : c++ power of integer, template meta programming
I can not seem to wrap my mind around this and don't know what else to try.
Notice that your last case isn't possible currently. You can't store 2^64 in an 8 byte type, the maximum is 2^64 - 1. At least on mainstream architectures, don't know which one you are using.
I see two problems with your function template.
You multiply the result with base only once, but you decrement the bits count by 8 by doing expInBytes - 1. So, you need to multiply it eight times:
return (expInBits == 0 ? 1 : base * base * base * base * base * base * base * base * pow2<expInBytes-1>() );
The specialization for 0 returns 0, and any number multiplied with 0 is 0. :) If you think that you handled the case with expInBits == 0, think again: The only way for expInBits to be 0 is if expInBytes is 0, but that cannot be in the primary template because you have a specialization for when expInBytes is 0! That means that that branch is never taken, it literally has no effect.
Your function has the same problem described in 1), and in addition you are passing the wrong value to it when recursing (expInBits instead of expInBytes) and the order is wrong (base comes last).
In my opinion, a loop is easier to understand and less error-prone:
constexpr std::uint64_t pow2(const std::uint32_t expInBytes, const std::uint32_t base = 2) {
const std::uint32_t expInBits = expInBytes * CHAR_BIT;
std::uint64_t result = 1;
for (std::uint32_t i = 0; i < expInBits; ++i)
result *= base;
return result;
}
With the help of Rakete111 and his positive feed back; I was able to work through my problem as he pointed out a few mistakes. In return I was able to achieve some resemblance of what I wanted. To compute 2^n at compile time.
Here is the working code:
inline constexpr std::uint64_t powerOfBits( const std::uint64_t base, std::uint64_t const exponent ) {
return (exponent == 0) ? 1 : (base * powerOfBits( base, exponent - 1 ));
}
/*template<typename T = const std::uint32_t>*/
class BitCombinations {
public:
// Because I don't care for "magic numbers"
static const std::uint64_t binaryBase = std::uint64_t(2);
static const std::uint64_t eightBits = std::uint64_t( 8 );
static const std::uint64_t sixteenBits = std::uint64_t( 16 );
static const std::uint64_t thirtyTwoBits = std::uint64_t( 32 );
static const std::uint64_t sixtyFourBits = std::uint64_t( 64 );
// Now Generate Our Compile Time Constants
static const std::uint64_t ONE_BYTE = powerOfBits( binaryBase , eightBits ); //
static const std::uint64_t TWO_BYTES = powerOfBits( binaryBase , sixteenBits ); //
static const std::uint64_t FOUR_BYTES = powerOfBits( binaryBase , thirtyTwoBits ); //
// For 64bit int need to subtract 1 from the exponent otherwise you will have integral overflow
// To prevent this we just take 2^63, then in any output display we will have to append the
// string or characters `x 2` so that the user knows the value is double what they are seeing.
static const std::uint64_t EIGHT_BYTES = powerOfBits( binaryBase , sixtyFourBits - 1 );
};
int main() {
std::cout << BitCombinations::ONE_BYTE << std::endl;
std::cout << BitCombinations::TWO_BYTES << std::endl;
std::cout << BitCombinations::FOUR_BYTES << std::endl;
// Remember that 2^64 causes overflow: need to append characters to user.
std::cout << BitCombinations::EIGHT_BYTES << " x 2" << std::endl;
std::cout << std::endl;
std::cout << "\nPress any key and enter to quite." << std::endl;
char q;
std::cin >> q;
return 0;
}
Thank you so much for your help and pointing me in the right direction. I will accept your answer.
I'm working hard in order to translate many macros into (scoped, type-safe) const values. My goal is to use them, if necessary, with if constexpr.
For now I've managed to have satisfactory results with some macros using stringify macros and template functions:
#define STRINGIFY(X) #X
#define TO_STRING(X) STRINGIFY(X)
The macros above have a surprising different behaviour depending on the given parameter:
std::cout << TO_STRING(_DEBUG) << '\n';
Shows _DEBUG if (and only if) the macro _DEBUG is NOT defined, but if defined it shows the macro value (or an empty string if defined but without value).
Anyway, the macro result would always be a text literal so I'm using a constexpr function to check the result:
template <int SIZE>
constexpr bool b(const char (&definition)[SIZE])
{
return definition[0] != '_';
}
And now combining STRINGIFY and b, it is possible to create enumerations and use them in if constexpr (instead of using #ifdef chains):
enum operating_system : bool
{
iOS = b(TO_STRING(__APPLE__)),
Windows = b(TO_STRING(__MINGW32__)),
Linux = b(TO_STRING(__linux__)),
};
int main()
{
if constexpr (operating_system::Windows)
{
// Specific Windows stuff.
}
else if constexpr (operating_system::iOS)
{
// Specific iOS stuff.
}
// Platform-independent sutff.
return 0;
}
I'm not happy using a helper function to translate the literals to bool values (b function) but isn't a big deal. The real problem is that it relies on detecting the starting underscore (_) in order to detect the non-existent macros. So an existing macro with a value starting with underscore would be a false positive. Also, the real value of the macro is lost, let's see an example:
#define _DEBUG 0
#define DRIVERS _09072007
template <int SIZE>
constexpr int i(const char (&definition)[SIZE])
{
return definition[0] != '_'; // what shall I put here?...
}
enum stuff : int
{
cpp_version = i(TO_STRING(__cplusplus)),
debug_enabled = i(TO_STRING(_DEBUG)),
drivers_version = i(TO_STRING(DRIVERS)),
};
int main()
{
std::cout << "C++ version: " << stuff::cpp_version << '\n'
<< "Debug mode: " << stuff::debug_enabled << '\n'
<< "Drivers version: " << stuff::drivers_version << '\n';
return 0;
}
The code above shows:
C++ version: 1
Debug mode: 1
Divers version: 0
Expected, but not satisfactory. I need a way to translate those string literals to the real value (at compile time) and a workaround of the naive approach of the "it exists if not starts with underscore" problem that the DRIVERS macro is showing (maybe ignoring non numeric values until a numeric value is found?).
I've tried with recursive approach but indexing a string literal is not a constant expression:
constexpr int power10(int n)
{
if (n == 0)
return 1;
return 10 * power10(n - 1);
}
template <int SIZE>
constexpr int v(const char (&definition)[SIZE], int INDEX)
{
// error: 'definition' is not a constant expression
constexpr char c = definition[INDEX];
if (INDEX >= 0)
{
if constexpr (c >= '0' && c <= '9')
{
return v(definition, INDEX - 1) + (power10(SIZE - INDEX - 2) * (c - '0'));
}
else
{
return 0 + v(definition, INDEX - 1);
}
}
return 0;
}
template <int SIZE>
constexpr int f(const char (&definition)[SIZE])
{
return v(definition, SIZE - 2);
}
enum operating_system : bool
{
// error: enumerator value for 'iOS' is not an integer constant
iOS = f(TO_STRING(__APPLE__)),
// error: enumerator value for 'Windows' is not an integer constant
Windows = f(TO_STRING(__MINGW32__)),
// error: enumerator value for 'Linux' is not an integer constant
Linux = f(TO_STRING(__linux__)),
};
Is there some function like GCC's __builtin_constant_p() for Microsoft Visual Studio? As I understand, the function returns non-zero if the argument is constant, like a string literal.
In the answer here (How to have "constexpr and runtime" alias) is a nice use case of it.
EDIT:
My idea was instead of writing something like:
#include <string.h>
int foo() {
return strlen("text");
}
I could write:
#include <string.h>
// template_strlen() would be a function that gets the length of a compile-time const string via templates
#define STRLEN(a) (__builtin_constant_p(a) ? template_strlen(a) : strlen(a))
int foo() {
return STRLEN("text");
}
(I guess that is about what was written in the linked question.)
All I need for that is a variant of __builtin_constant_p().
Here is an example about how to get compile-time detection of string length (which is not the answer to the initial question but to the second one)
Please notice however that most compiler already replace strlen("bob") by 3 in the very first optimization level, so I doubt it has any use in reality.
template <typename T>
struct StrLenHelper
{
static constexpr size_t len(T) { return 0; }
};
template <size_t sel>
struct StrLenHelper<const char (&)[sel]>
{
static constexpr size_t len(const char (&a)[sel]) { return sel-1; }
};
template <>
struct StrLenHelper<const char*>
{
static size_t len(const char * a) { return strlen(a); }
};
#define StrLen(X) StrLenHelper<decltype(X)>::len(X)
Proof that it works on a recent compiler:
template <size_t A>
struct Test { enum T { value = A }; };
// Outputs "5 5 4" if your program is called "test"
int main(int a, char**b)
{
printf("%u %u %u\n", Test<StrLen("bobby")>::value, StrLen("bobby"), StrLen(b[0]));
return 0;
}
Some strange coding practice will not trigger compile-time behaviour like in constexpr const char * b = "bob";, this will call the run-time version because the type, at the time of call is const char* (constexpr is not a modifier you can select upon in a template, or I don't know how)
In Visual Studio 2012 and Visual Studio 2013 there is the _IS_LITERAL_TYPE macro which makes use of std::is_literal_type, which is documented at http://www.cplusplus.com/reference/type_traits/is_literal_type/.
The following is a relevant excerpt from the documentation of is_literal_type.
"""Trait class that identifies whether T is a literal type.
A literal type is a type that can qualify as constexpr."""
Perhaps this would suffice.
The following excerpt from the documentation for __builtin_constant_p leads me to believe it will.
"You can use the built-in function __builtin_constant_p to determine if a value is known to be constant at compile-time..."
To me the phrases "is a literal type," "constexpr," and "known to be constant at compile-time" have the same meaning. Perhaps I am mistaken.
Then again, I will be the first to admit that I am not certain.
If is_literal_type is not what you want, the following function might be of use. With it I was able to tell the difference between a char string that was defined as follows and one that was allocated on the heap.
LPCTSTR constString = _T("Hello World!");
My implementation of constant_p is as follows.
int constant_p(const void *p)
{
static bool s_init = false;
static ULONGLONG s_TextSegmentStartVirtualAddress = 0;
static ULONGLONG s_TextSegmentEndVirtualAddress = 0;
static ULONGLONG s_RDataSegmentStartVirtualAddress = 0;
static ULONGLONG s_RDataSegmentEndVirtualAddress = 0;
if (! s_init)
{
s_init = true;
PIMAGE_NT_HEADERS pNtHeaders = ::ImageNtHeader(
reinterpret_cast<PVOID>(::GetModuleHandle(NULL)));
if (! pNtHeaders)
{
return 0;
}
ULONGLONG ImageBase = pNtHeaders->OptionalHeader.ImageBase;
PIMAGE_SECTION_HEADER pSectionHeader = (PIMAGE_SECTION_HEADER)(pNtHeaders + 1);
for (WORD i = 0; i < pNtHeaders->FileHeader.NumberOfSections; ++i)
{
char *name = (char*)pSectionHeader->Name;
if (0 == ::strcmp(name, ".text"))
{
s_TextSegmentStartVirtualAddress = ImageBase
+ pSectionHeader->VirtualAddress;
s_TextSegmentEndVirtualAddress = s_TextSegmentStartVirtualAddress
+ pSectionHeader->SizeOfRawData;
}
else if (0 == ::strcmp(name, ".rdata"))
{
s_RDataSegmentStartVirtualAddress = ImageBase
+ pSectionHeader->VirtualAddress;
s_RDataSegmentEndVirtualAddress = s_RDataSegmentStartVirtualAddress
+ pSectionHeader->SizeOfRawData;
}
pSectionHeader++;
}
}
if (0 == s_TextSegmentStartVirtualAddress)
{
// Something went wrong. Give up.
return 0;
}
ULONGLONG test = reinterpret_cast<ULONGLONG>(p);
if (
s_TextSegmentStartVirtualAddress <= test
&& test <= s_TextSegmentEndVirtualAddress
)
{
return 1;
}
else if (
s_RDataSegmentStartVirtualAddress <= test
&& test <= s_RDataSegmentEndVirtualAddress
)
{
return 1;
}
return 0;
}
Note you need to include DbgHelp.h and link with DbgHelp.lib in order for this to work.
I hope one of my proposed solutions works for you. I would like to know.
int temp = 0x5E; // in binary 0b1011110.
Is there such a way to check if bit 3 in temp is 1 or 0 without bit shifting and masking.
Just want to know if there is some built in function for this, or am I forced to write one myself.
In C, if you want to hide bit manipulation, you can write a macro:
#define CHECK_BIT(var,pos) ((var) & (1<<(pos)))
and use it this way to check the nth bit from the right end:
CHECK_BIT(temp, n - 1)
In C++, you can use std::bitset.
Check if bit N (starting from 0) is set:
temp & (1 << N)
There is no builtin function for this.
I would just use a std::bitset if it's C++. Simple. Straight-forward. No chance for stupid errors.
typedef std::bitset<sizeof(int)> IntBits;
bool is_set = IntBits(value).test(position);
or how about this silliness
template<unsigned int Exp>
struct pow_2 {
static const unsigned int value = 2 * pow_2<Exp-1>::value;
};
template<>
struct pow_2<0> {
static const unsigned int value = 1;
};
template<unsigned int Pos>
bool is_bit_set(unsigned int value)
{
return (value & pow_2<Pos>::value) != 0;
}
bool result = is_bit_set<2>(value);
What the selected answer is doing is actually wrong. The below function will return the bit position or 0 depending on if the bit is actually enabled. This is not what the poster was asking for.
#define CHECK_BIT(var,pos) ((var) & (1<<(pos)))
Here is what the poster was originally looking for. The below function will return either a 1 or 0 if the bit is enabled and not the position.
#define CHECK_BIT(var,pos) (((var)>>(pos)) & 1)
Yeah, I know I don't "have" to do it this way. But I usually write:
/* Return type (8/16/32/64 int size) is specified by argument size. */
template<class TYPE> inline TYPE BIT(const TYPE & x)
{ return TYPE(1) << x; }
template<class TYPE> inline bool IsBitSet(const TYPE & x, const TYPE & y)
{ return 0 != (x & y); }
E.g.:
IsBitSet( foo, BIT(3) | BIT(6) ); // Checks if Bit 3 OR 6 is set.
Amongst other things, this approach:
Accommodates 8/16/32/64 bit integers.
Detects IsBitSet(int32,int64) calls without my knowledge & consent.
Inlined Template, so no function calling overhead.
const& references, so nothing needs to be duplicated/copied. And we are guaranteed that the compiler will pick up any typo's that attempt to change the arguments.
0!= makes the code more clear & obvious. The primary point to writing code is always to communicate clearly and efficiently with other programmers, including those of lesser skill.
While not applicable to this particular case... In general, templated functions avoid the issue of evaluating arguments multiple times. A known problem with some #define macros. E.g.: #define ABS(X) (((X)<0) ? - (X) : (X)) ABS(i++);
According to this description of bit-fields, there is a method for defining and accessing fields directly. The example in this entry goes:
struct preferences {
unsigned int likes_ice_cream : 1;
unsigned int plays_golf : 1;
unsigned int watches_tv : 1;
unsigned int reads_books : 1;
};
struct preferences fred;
fred.likes_ice_cream = 1;
fred.plays_golf = 1;
fred.watches_tv = 1;
fred.reads_books = 0;
if (fred.likes_ice_cream == 1)
/* ... */
Also, there is a warning there:
However, bit members in structs have practical drawbacks. First, the ordering of bits in memory is architecture dependent and memory padding rules varies from compiler to compiler. In addition, many popular compilers generate inefficient code for reading and writing bit members, and there are potentially severe thread safety issues relating to bit fields (especially on multiprocessor systems) due to the fact that most machines cannot manipulate arbitrary sets of bits in memory, but must instead load and store whole words.
You can use a Bitset - http://www.cppreference.com/wiki/stl/bitset/start.
Use std::bitset
#include <bitset>
#include <iostream>
int main()
{
int temp = 0x5E;
std::bitset<sizeof(int)*CHAR_BITS> bits(temp);
// 0 -> bit 1
// 2 -> bit 3
std::cout << bits[2] << std::endl;
}
i was trying to read a 32-bit integer which defined the flags for an object in PDFs and this wasn't working for me
what fixed it was changing the define:
#define CHECK_BIT(var,pos) ((var & (1 << pos)) == (1 << pos))
the operand & returns an integer with the flags that both have in 1, and it wasn't casting properly into boolean, this did the trick
I use this:
#define CHECK_BIT(var,pos) ( (((var) & (pos)) > 0 ) ? (1) : (0) )
where "pos" is defined as 2^n (i.g. 1,2,4,8,16,32 ...)
Returns:
1 if true
0 if false
There is, namely the _bittest intrinsic instruction.
#define CHECK_BIT(var,pos) ((var>>pos) & 1)
pos - Bit position strarting from 0.
returns 0 or 1.
For the low-level x86 specific solution use the x86 TEST opcode.
Your compiler should turn _bittest into this though...
The precedent answers show you how to handle bit checks, but more often then not, it is all about flags encoded in an integer, which is not well defined in any of the precedent cases.
In a typical scenario, flags are defined as integers themselves, with a bit to 1 for the specific bit it refers to. In the example hereafter, you can check if the integer has ANY flag from a list of flags (multiple error flags concatenated) or if EVERY flag is in the integer (multiple success flags concatenated).
Following an example of how to handle flags in an integer.
Live example available here:
https://rextester.com/XIKE82408
//g++ 7.4.0
#include <iostream>
#include <stdint.h>
inline bool any_flag_present(unsigned int value, unsigned int flags) {
return bool(value & flags);
}
inline bool all_flags_present(unsigned int value, unsigned int flags) {
return (value & flags) == flags;
}
enum: unsigned int {
ERROR_1 = 1U,
ERROR_2 = 2U, // or 0b10
ERROR_3 = 4U, // or 0b100
SUCCESS_1 = 8U,
SUCCESS_2 = 16U,
OTHER_FLAG = 32U,
};
int main(void)
{
unsigned int value = 0b101011; // ERROR_1, ERROR_2, SUCCESS_1, OTHER_FLAG
unsigned int all_error_flags = ERROR_1 | ERROR_2 | ERROR_3;
unsigned int all_success_flags = SUCCESS_1 | SUCCESS_2;
std::cout << "Was there at least one error: " << any_flag_present(value, all_error_flags) << std::endl;
std::cout << "Are all success flags enabled: " << all_flags_present(value, all_success_flags) << std::endl;
std::cout << "Is the other flag enabled with eror 1: " << all_flags_present(value, ERROR_1 | OTHER_FLAG) << std::endl;
return 0;
}
Why all these bit shifting operations and need for library functions? If you have the value the OP posted: 1011110 and you want to know if the bit in the 3rd position from the right is set, just do:
int temp = 0b1011110;
if( temp & 4 ) /* or (temp & 0b0100) if that's how you roll */
DoSomething();
Or something a bit prettier that may be more easily interpreted by future readers of the code:
#include <stdbool.h>
int temp = 0b1011110;
bool bThirdBitIsSet = (temp & 4) ? true : false;
if( bThirdBitIsSet )
DoSomething();
Or, with no #include needed:
int temp = 0b1011110;
_Bool bThirdBitIsSet = (temp & 4) ? 1 : 0;
if( bThirdBitIsSet )
DoSomething();
You could "simulate" shifting and masking: if((0x5e/(2*2*2))%2) ...
One approach will be checking within the following condition:
if ( (mask >> bit ) & 1)
An explanation program will be:
#include <stdio.h>
unsigned int bitCheck(unsigned int mask, int pin);
int main(void){
unsigned int mask = 6; // 6 = 0110
int pin0 = 0;
int pin1 = 1;
int pin2 = 2;
int pin3 = 3;
unsigned int bit0= bitCheck( mask, pin0);
unsigned int bit1= bitCheck( mask, pin1);
unsigned int bit2= bitCheck( mask, pin2);
unsigned int bit3= bitCheck( mask, pin3);
printf("Mask = %d ==>> 0110\n", mask);
if ( bit0 == 1 ){
printf("Pin %d is Set\n", pin0);
}else{
printf("Pin %d is not Set\n", pin0);
}
if ( bit1 == 1 ){
printf("Pin %d is Set\n", pin1);
}else{
printf("Pin %d is not Set\n", pin1);
}
if ( bit2 == 1 ){
printf("Pin %d is Set\n", pin2);
}else{
printf("Pin %d is not Set\n", pin2);
}
if ( bit3 == 1 ){
printf("Pin %d is Set\n", pin3);
}else{
printf("Pin %d is not Set\n", pin3);
}
}
unsigned int bitCheck(unsigned int mask, int bit){
if ( (mask >> bit ) & 1){
return 1;
}else{
return 0;
}
}
Output:
Mask = 6 ==>> 0110
Pin 0 is not Set
Pin 1 is Set
Pin 2 is Set
Pin 3 is not Set
if you just want a real hard coded way:
#define IS_BIT3_SET(var) ( ((var) & 0x04) == 0x04 )
note this hw dependent and assumes this bit order 7654 3210 and var is 8 bit.
#include "stdafx.h"
#define IS_BIT3_SET(var) ( ((var) & 0x04) == 0x04 )
int _tmain(int argc, _TCHAR* argv[])
{
int temp =0x5E;
printf(" %d \n", IS_BIT3_SET(temp));
temp = 0x00;
printf(" %d \n", IS_BIT3_SET(temp));
temp = 0x04;
printf(" %d \n", IS_BIT3_SET(temp));
temp = 0xfb;
printf(" %d \n", IS_BIT3_SET(temp));
scanf("waitng %d",&temp);
return 0;
}
Results in:
1
0
1
0
While it is quite late to answer now, there is a simple way one could find if Nth bit is set or not, simply using POWER and MODULUS mathematical operators.
Let us say we want to know if 'temp' has Nth bit set or not. The following boolean expression will give true if bit is set, 0 otherwise.
( temp MODULUS 2^N+1 >= 2^N )
Consider the following example:
int temp = 0x5E; // in binary 0b1011110 // BIT 0 is LSB
If I want to know if 3rd bit is set or not, I get
(94 MODULUS 16) = 14 > 2^3
So expression returns true, indicating 3rd bit is set.
Why not use something as simple as this?
uint8_t status = 255;
cout << "binary: ";
for (int i=((sizeof(status)*8)-1); i>-1; i--)
{
if ((status & (1 << i)))
{
cout << "1";
}
else
{
cout << "0";
}
}
OUTPUT: binary: 11111111
I make this:
LATGbits.LATG0=((m&0x8)>0); //to check if bit-2 of m is 1
the fastest way seems to be a lookup table for masks
In code, I sometimes see people specify constants in hex format like this:
const int has_nukes = 0x0001;
const int has_bio_weapons = 0x0002;
const int has_chem_weapons = 0x0004;
// ...
int arsenal = has_nukes | has_bio_weapons | has_chem_weapons; // all of them
if(arsenal &= has_bio_weapons){
std::cout << "BIO!!"
}
But it doesn't make sense to me to use the hex format here. Is there a way to do it directly in binary? Something like this:
const int has_nukes = 0b00000000000000000000000000000001;
const int has_bio_weapons = 0b00000000000000000000000000000010;
const int has_chem_weapons = 0b00000000000000000000000000000100;
// ...
I know the C/C++ compilers won't compile this, but there must be a workaround? Is it possible in other languages like Java?
In C++14 you will be able to use binary literals with the following syntax:
0b010101010 /* more zeros and ones */
This feature is already implemented in the latest clang and gcc. You can try it if you run those compilers with -std=c++1y option.
I'd use a bit shift operator:
const int has_nukes = 1<<0;
const int has_bio_weapons = 1<<1;
const int has_chem_weapons = 1<<2;
// ...
int dangerous_mask = has_nukes | has_bio_weapons | has_chem_weapons;
bool is_dangerous = (country->flags & dangerous_mask) == dangerous_mask;
It is even better than flood of 0's.
By the way, the next C++ version will support user defined literals. They are already included into the working draft. This allows that sort of stuff (let's hope i don't have too many errors in it):
template<char... digits>
constexpr int operator "" _b() {
return conv2bin<digits...>::value;
}
int main() {
int const v = 110110110_b;
}
conv2bin would be a template like this:
template<char... digits>
struct conv2bin;
template<char high, char... digits>
struct conv2bin<high, digits...> {
static_assert(high == '0' || high == '1', "no bin num!");
static int const value = (high - '0') * (1 << sizeof...(digits)) +
conv2bin<digits...>::value;
};
template<char high>
struct conv2bin<high> {
static_assert(high == '0' || high == '1', "no bin num!");
static int const value = (high - '0');
};
Well, what we get are binary literals that evaluate fully at compile time already, because of the "constexpr" above. The above uses a hard-coded int return type. I think one could even make it depend on the length of the binary string. It's using the following features, for anyone interested:
Generalized Constant Expressions.
Variadic Templates. A brief introduction can be found here
Static Assertions (static_assert)
User defined Literals
Actually, current GCC trunk already implements variadic templates and static assertions. Let's hope it will support the other two soon. I think C++1x will rock the house.
The C++ Standard Library is your friend:
#include <bitset>
const std::bitset <32> has_nukes( "00000000000000000000000000000001" );
GCC supports binary constants as an extension since 4.3. See the announcement (look at the section "New Languages and Language specific improvements").
You can use << if you like.
int hasNukes = 1;
int hasBioWeapons = 1 << 1;
int hasChemWeapons = 1 << 2;
This discussion may be interesting... Might have been, as the link is dead unfortunately. It described a template based approach similar to other answers here.
And also there is a thing called BOOST_BINARY.
The term you want is binary literals
Ruby has them with the syntax you give.
One alternative is to define helper macros to convert for you. I found the following code at http://bytes.com/groups/c/219656-literal-binary
/* Binary constant generator macro
* By Tom Torfs - donated to the public domain
*/
/* All macro's evaluate to compile-time constants */
/* *** helper macros *** */
/* turn a numeric literal into a hex constant
* (avoids problems with leading zeroes)
* 8-bit constants max value 0x11111111, always fits in unsigned long
*/
#define HEX_(n) 0x##n##LU
/* 8-bit conversion function */
#define B8_(x) ((x & 0x0000000FLU) ? 1:0) \
| ((x & 0x000000F0LU) ? 2:0) \
| ((x & 0x00000F00LU) ? 4:0) \
| ((x & 0x0000F000LU) ? 8:0) \
| ((x & 0x000F0000LU) ? 16:0) \
| ((x & 0x00F00000LU) ? 32:0) \
| ((x & 0x0F000000LU) ? 64:0) \
| ((x & 0xF0000000LU) ? 128:0)
/* *** user macros *** /
/* for upto 8-bit binary constants */
#define B8(d) ((unsigned char) B8_(HEX_(d)))
/* for upto 16-bit binary constants, MSB first */
#define B16(dmsb, dlsb) (((unsigned short) B8(dmsb) << 8) \
| B8(dlsb))
/* for upto 32-bit binary constants, MSB first */
#define B32(dmsb, db2, db3, dlsb) (((unsigned long) B8(dmsb) << 24) \
| ((unsigned long) B8( db2) << 16) \
| ((unsigned long) B8( db3) << 8) \
| B8(dlsb))
/* Sample usage:
* B8(01010101) = 85
* B16(10101010,01010101) = 43605
* B32(10000000,11111111,10101010,01010101) = 2164238933
*/
The next version of C++, C++0x, will introduce user defined literals. I'm not sure if binary numbers will be part of the standard but at the worst you'll be able to enable it yourself:
int operator "" _B(int i);
assert( 1010_B == 10);
I write binary literals like this:
const int has_nukes = 0x0001;
const int has_bio_weapons = 0x0002;
const int has_chem_weapons = 0x0004;
It's more compact than your suggested notation, and easier to read. For example:
const int upper_bit = 0b0001000000000000000;
versus:
const int upper_bit = 0x04000;
Did you notice that the binary version wasn't an even multiple of 4 bits? Did you think it was 0x10000?
With a little practice hex or octal are easier for a human than binary. And, in my opinion, easier to read that using shift operators. But I'll concede that my years of assembly language work may bias me on that point.
If you want to use bitset, auto, variadic templates, user-defined literals, static_assert, constexpr, and noexcept try this:
template<char... Bits>
struct __checkbits
{
static const bool valid = false;
};
template<char High, char... Bits>
struct __checkbits<High, Bits...>
{
static const bool valid = (High == '0' || High == '1')
&& __checkbits<Bits...>::valid;
};
template<char High>
struct __checkbits<High>
{
static const bool valid = (High == '0' || High == '1');
};
template<char... Bits>
inline constexpr std::bitset<sizeof...(Bits)>
operator"" bits() noexcept
{
static_assert(__checkbits<Bits...>::valid, "invalid digit in binary string");
return std::bitset<sizeof...(Bits)>((char []){Bits..., '\0'});
}
Use it like this:
int
main()
{
auto bits = 0101010101010101010101010101010101010101010101010101010101010101bits;
std::cout << bits << std::endl;
std::cout << "size = " << bits.size() << std::endl;
std::cout << "count = " << bits.count() << std::endl;
std::cout << "value = " << bits.to_ullong() << std::endl;
// This triggers the static_assert at compile-time.
auto badbits = 2101010101010101010101010101010101010101010101010101010101010101bits;
// This throws at run-time.
std::bitset<64> badbits2("2101010101010101010101010101010101010101010101010101010101010101bits");
}
Thanks to #johannes-schaub-litb
Java doesn't support binary literals either, unfortunately. However, it has enums which can be used with an EnumSet. An EnumSet represents enum values internally with bit fields, and presents a Set interface for manipulating these flags.
Alternatively, you could use bit offsets (in decimal) when defining your values:
const int HAS_NUKES = 0x1 << 0;
const int HAS_BIO_WEAPONS = 0x1 << 1;
const int HAS_CHEM_WEAPONS = 0x1 << 2;
There's no syntax for literal binary constants in C++ the way there is for hexadecimal and octal. The closest thing for what it looks like you're trying to do would probably be to learn and use bitset.
As an aside:
Especially if you're dealing with a large set, instead of going through the [minor] mental effort of writing a sequence of shift amounts, you can make each constant depend on the previously defined constant:
const int has_nukes = 1;
const int has_bio_weapons = has_nukes << 1;
const int has_chem_weapons = has_bio_weapons << 1;
const int has_nunchuks = has_chem_weapons << 1;
// ...
Looks a bit redundant, but it's less typo-prone. Also, you can simply insert a new constant in the middle without having to touch any other line except the one immediately following it:
const int has_nukes = 1;
const int has_gravity_gun = has_nukes << 1; // added
const int has_bio_weapons = has_gravity_gun << 1; // changed
const int has_chem_weapons = has_bio_weapons << 1; // unaffected from here on
const int has_nunchuks = has_chem_weapons << 1;
// ...
Compare to:
const int has_nukes = 1 << 0;
const int has_bio_weapons = 1 << 1;
const int has_chem_weapons = 1 << 2;
const int has_nunchuks = 1 << 3;
// ...
const int has_scimatar = 1 << 28;
const int has_rapier = 1 << 28; // good luck spotting this typo!
const int has_katana = 1 << 30;
And:
const int has_nukes = 1 << 0;
const int has_gravity_gun = 1 << 1; // added
const int has_bio_weapons = 1 << 2; // changed
const int has_chem_weapons = 1 << 3; // changed
const int has_nunchuks = 1 << 4; // changed
// ... // changed all the way
const int has_scimatar = 1 << 29; // changed *sigh*
const int has_rapier = 1 << 30; // changed *sigh*
const int has_katana = 1 << 31; // changed *sigh*
As an aside to my aside, it's probably equally hard to spot a typo like this:
const int has_nukes = 1;
const int has_gravity_gun = has_nukes << 1;
const int has_bio_weapons = has_gravity_gun << 1;
const int has_chem_weapons = has_gravity_gun << 1; // oops!
const int has_nunchuks = has_chem_weapons << 1;
So, I think the main advantage of this cascading syntax is when dealing with insertions and deletions of constants.
Another method:
template<unsigned int N>
class b
{
public:
static unsigned int const x = N;
typedef b_<0> _0000;
typedef b_<1> _0001;
typedef b_<2> _0010;
typedef b_<3> _0011;
typedef b_<4> _0100;
typedef b_<5> _0101;
typedef b_<6> _0110;
typedef b_<7> _0111;
typedef b_<8> _1000;
typedef b_<9> _1001;
typedef b_<10> _1010;
typedef b_<11> _1011;
typedef b_<12> _1100;
typedef b_<13> _1101;
typedef b_<14> _1110;
typedef b_<15> _1111;
private:
template<unsigned int N2>
struct b_: public b<N << 4 | N2> {};
};
typedef b<0> _0000;
typedef b<1> _0001;
typedef b<2> _0010;
typedef b<3> _0011;
typedef b<4> _0100;
typedef b<5> _0101;
typedef b<6> _0110;
typedef b<7> _0111;
typedef b<8> _1000;
typedef b<9> _1001;
typedef b<10> _1010;
typedef b<11> _1011;
typedef b<12> _1100;
typedef b<13> _1101;
typedef b<14> _1110;
typedef b<15> _1111;
Usage:
std::cout << _1101::_1001::_1101::_1101::x;
Implemented in CityLizard++ (citylizard/binary/b.hpp).
I agree that it's useful to have an option for binary literals, and they are present in many programming languages. In C, I've decided to use a macro like this:
#define bitseq(a00,a01,a02,a03,a04,a05,a06,a07,a08,a09,a10,a11,a12,a13,a14,a15, \
a16,a17,a18,a19,a20,a21,a22,a23,a24,a25,a26,a27,a28,a29,a30,a31) \
(a31|a30<< 1|a29<< 2|a28<< 3|a27<< 4|a26<< 5|a25<< 6|a24<< 7| \
a23<< 8|a22<< 9|a21<<10|a20<<11|a19<<12|a18<<13|a17<<14|a16<<15| \
a15<<16|a14<<17|a13<<18|a12<<19|a11<<20|a10<<21|a09<<22|a08<<23| \
a07<<24|a06<<25|a05<<26|a04<<27|a03<<28|a02<<29|a01<<30|(unsigned)a00<<31)
The usage is pretty much straightforward =)
One, slightly horrible way you could do it is by generating a .h file with lots of #defines...
#define b00000000 0
#define b00000001 1
#define b00000010 2
#define b00000011 3
#define b00000100 4
etc.
This might make sense for 8-bit numbers, but probably not for 16-bit or larger.
Alternatively, do this (similar to Zach Scrivena's answer):
#define bit(x) (1<<x)
int HAS_NUKES = bit(HAS_NUKES_OFFSET);
int HAS_BIO_WEAPONS = bit(HAS_BIO_WEAPONS_OFFSET);
Binary literals are part of the C++ language since C++14. It’s literals that start with 0b or 0B. Reference
Maybe less relevant to binary literals, but this just looks as if it can be solved better with a bit field.
struct DangerCollection : uint32_t {
bool has_nukes : 1;
bool has_bio_weapons : 1;
bool has_chem_weapons : 1;
// .....
};
DangerCollection arsenal{
.has_nukes = true,
.has_bio_weapons = true,
.has_chem_weapons = true,
// ...
};
if(arsenal.has_bio_weapons){
std::cout << "BIO!!"
}
You would still be able to fill it with binary data, since its binary footprint is just a uint32. This is often used in combination with a union, for compact binary serialisation:
union DangerCollectionUnion {
DangerCollection collection;
uint8_t data[sizeof(DangerCollection)];
};
DangerCollectionUnion dc;
std::memcpy(dc.data, bitsIGotFromSomewhere, sizeof(DangerCollection));
if (dc.collection.has_bio_weapons) {
// ....
In my experience less error prone and easy to understand what's going on.