using bitfields to store a move?

Programming Topics (Computer Chess) and technical aspects as test techniques, book building, program tuning etc

Moderator: Andres Valverde

using bitfields to store a move?

Postby wing » 01 May 2011, 00:33

Bitfields are not portable in C, i.e. the language does not define what the MSB and LSB will be. Is there a problem with that?
I want to use bitfields (UNION-ed with an unsigned integer) to store a move, and do not intend to do any masking or shifting on the fields.
I only need 24 bits, but intend to inflate this to 32-bit, so a move will be aligned with a 32-bit integer, which might be faster on some compilers/systems.
But still wonder if there might be reason for not using bitfields? any thoughts?

Code: Select all
union Move {
   struct {
      unsigned from          : 8;
      unsigned to            : 8;
      unsigned movingPiece   : 8;
      unsigned capturedPiece : 4;
      unsigned promoteTo     : 4;
   };
   unsigned int moveInt;
};
wing
 
Posts: 21
Joined: 17 Mar 2011, 10:49

Re: using bitfields to store a move?

Postby Ron Murawski » 01 May 2011, 04:42

wing wrote:Bitfields are not portable in C, i.e. the language does not define what the MSB and LSB will be. Is there a problem with that?
I want to use bitfields (UNION-ed with an unsigned integer) to store a move, and do not intend to do any masking or shifting on the fields.
I only need 24 bits, but intend to inflate this to 32-bit, so a move will be aligned with a 32-bit integer, which might be faster on some compilers/systems.
But still wonder if there might be reason for not using bitfields? any thoughts?

Code: Select all
union Move {
   struct {
      unsigned from          : 8;
      unsigned to            : 8;
      unsigned movingPiece   : 8;
      unsigned capturedPiece : 4;
      unsigned promoteTo     : 4;
   };
   unsigned int moveInt;
};


Hi Stef,

Big-endian/little-endian only matters if you intend to save binary information on one endian-type and intend to read it on an opposite-endian machine. For bitfields it is very similar except that the implementation might vary from one compiler to another. For a normal chess engine it does not matter that a bitfield starts with low bits or high bits. The compiler will keep perfect track of which bits it used within your move structure.

If you save the move structure bitfields to disk, as long as you use the same compiler to read it back into memory, then you can be assured that it will always work consistently. But saving/reading moves in GCC format and saving/reading in Microsoft compiler format might be different.

FYI, according to K&R: all bitfields are 32-bit integers, and no guarantees are made whether a bitfield can cross a word boundary. Because of the doubt of whether my code might work on one compiler but not another due to bitfields not aligning with words, that makes it a deal-breaker for me. I always mask and shift and it will work with all compilers. I have always suspected that all the major compilers can cross word boundaries, but I don't want to cause weird bugs in case there's a compiler out there that can't do it properly.

Best regards,
Ron
User avatar
Ron Murawski
 
Posts: 352
Joined: 26 Sep 2004, 21:50
Location: Schenectady, NY, USA

Re: using bitfields to store a move?

Postby Nguyen Pham » 26 May 2011, 00:45

In my case, simply use some macros (defines) and I have not to worry about portable.
Nguyen Pham
 
Posts: 36
Joined: 27 Jun 2010, 08:40

Re: using bitfields to store a move?

Postby Fermin Serrano » 09 Jun 2011, 15:43

Code: Select all
I want to use bitfields (UNION-ed with an unsigned integer) to store a move, and do not intend to do any masking or shifting on the fields.


I strongly recommed to use masking or shifting. It is faster and no need for compiler dependency. You can also define the move as int. Accesing move data is easy with macros. In C there is not direct way to compare structs, so you will need extra functions (maybe easy, but aren't macros also easy)

Also I think you can need and en-passant bit and/or castling, which is very useful for unmake moves (althought not strictely neccesary). Also in my implementation I have no need to store the moving piece.
I think you are wasting bits. For to and from square you only need 6 bits (2^6 = 64). For moving piece you only need 4 bits (3 in you not count color), the same for captured, and only 2 are needed for promotion (3 if you count color). As with this you have more bits to use, I use them to store additional information, like if the move gives check, if is a book move, or thinks like that. Removing extra information is easy with a & operation. This info is very handy when the move is from TT.

Regards,
Fermin
User avatar
Fermin Serrano
 
Posts: 72
Joined: 10 Apr 2008, 18:20
Location: Madrid (Spain)


Return to Programming and Technical Discussions

Who is online

Users browsing this forum: No registered users and 31 guests