2

I'm trying to represent the 52 cards in a deck of playing cards. I need a total of 6 bits; 2 for the suit and 4 for the rank. I thought I would use a char and have the first 2 bits be zero since I don't need them. The problem is I don't know if there's a way to initialize a char using bits.

For example, I'd like to do is:

char aceOfSpades = 00000000;

char queenOfHearts = 00011101;

I know once I've initialized char I can manipulate the bits but it would be easier if I could initialize it from the beginning as shown in my example. Thanks in advance!

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
Vindictive
  • 311
  • 7
  • 19
  • you could always use a bit field. – Captain Obvlious Feb 20 '16 at 21:46
  • create a [user-defined literal](http://en.cppreference.com/w/cpp/language/user_literal)? – Revolver_Ocelot Feb 20 '16 at 21:47
  • I'm curious why you're trying to pack the bits? Are you writing this for an old 6502 machine? If not, I'd suggest that you just use a struct with separate fields for the separate items. – Michael Burr Feb 20 '16 at 21:53
  • @MichaelBurr Ultimately I'm trying to create a poker AI. Knowing that in the future I'll want my program to play millions of poker hands. With each hand and player the poker hand evaluator will need to be called numerous times. I'm just trying to make it as efficient as possible. – Vindictive Feb 20 '16 at 22:05
  • You could also use `char queenOfHearts = (char)std::bitset<8>("00011101").to_ulong();` – Brandon Feb 20 '16 at 22:07
  • 4
    @Vindictive: That's a very nice example of premature optimisation. – Christian Hackl Feb 20 '16 at 22:11
  • the initialization values in the posted code are OCTAL because the first character is 0. What you really want is binary. To write a binary literal, prefix the literal with `0b` or `0B`. – user3629249 Feb 23 '16 at 03:06

2 Answers2

6

Yes you can:

example,

  char aceOfSpades = 0b00000000;
  char queenOfHearts = 0b00011101;
bhzag
  • 2,932
  • 7
  • 23
  • 39
  • That was easy. Thanks! – Vindictive Feb 20 '16 at 21:52
  • 8
    Be careful with compatibility. [This](http://stackoverflow.com/questions/2611764/can-i-use-a-binary-literal-in-c-or-c) says this `0b` format is a GNU extension for gcc and added to C++14. The hexadecimal `0x` format has been around since the dawn of time. If you work with it enough, you get used to where the bits are: 1, 2, 4, 8, etc. – e0k Feb 20 '16 at 21:54
  • 1
    For the boundary of two fields is aligned at bit 4 it's much more readable to use hexadecimal isn't it? And also maybe make ace 1 instead of 0? – user3528438 Feb 21 '16 at 00:47
  • Is there anyway to define the length of the bits? like i need a variable bit length some thing like 0b. – Alan Pallath Oct 25 '19 at 03:34
4

The easier way, as Captain Oblivious said in comments, is to use a bit field

struct SixBits
{
     unsigned int suit : 2;
     unsigned int rank : 4;
};

int main()
{
     struct SixBits card;
     card.suit = 0;        /*  You need to specify what the values mean */
     card.rank = 10;
}

You could try using various bit fiddling operations on a char, but that is more difficult to work with. There is also a potential problem that it is implementation-defined whether char is signed or unsigned - and, if it is signed, bitfiddling operations give undefined behaviour in some circumstances (e.g. if operating on a negative value).

Personally, I wouldn't bother with trying to pack everything into a char. I'd make the code comprehensible (e.g. use an enum to represent the sut, an int to represent rank) unless there is demonstrable need (e.g. trying to get the program to work on a machine with extremely limited memory - which is unlikely in practice with hardware less than 20 years old). Otherwise, all you are really achieving is code that is hard to maintain with few real-world advantages.

Peter
  • 35,646
  • 4
  • 32
  • 74