Showing posts with label Bits. Show all posts
Showing posts with label Bits. Show all posts

Tuesday, May 17, 2011

More bit functions

 Retrieves the number of bits set to 1 (very useful for bitboards, how many rooks do we have?)


function TBit.BitSetCount(aValue: integer): integer;
//In = EDX Out = EAX
ASM
  POPCNT EAX, EDX
END;
64 bits version...
function TBit.BitSetCount(aValue: int64): integer;
const
  M1: int64 = $5555555555555555;  // 1 zero,  1 one ...
  M2: int64 = $3333333333333333;  // 2 zeros,  2 ones ...
  M4: int64 = $0f0f0f0f0f0f0f0f;  // 4 zeros,  4 ones ...
  M8: int64 = $00ff00ff00ff00ff;  // 8 zeros,  8 ones ...
  M16: int64 = $0000ffff0000ffff; // 16 zeros, 16 ones ...
  M32: int64 = $00000000ffffffff; // 32 zeros, 32 ones

begin
  //MIT HAKMEM algorithm, see http://graphics.stanford.edu/~seander/bithacks.html
  aValue := (aValue and M1 ) + ((aValue shr  1) and M1);   //put count of each  2 bits into those  2 bits
  aValue := (aValue and M2 ) + ((aValue shr  2) and M2);   //put count of each  4 bits into those  4 bits
  aValue := (aValue and M4 ) + ((aValue shr  4) and M4);   //put count of each  8 bits into those  8 bits
  aValue := (aValue and M8 ) + ((aValue shr  8) and M8);   //put count of each 16 bits into those 16 bits
  aValue := (aValue and M16) + ((aValue shr 16) and M16);   //put count of each 32 bits into those 32 bits
  aValue := (aValue and M32) + ((aValue shr 32) and M32);   //put count of each 64 bits into those 64 bits

  Exit(aValue);
end;

Saturday, April 30, 2011

Bit functions

 I've been adding new functions to BB.Utils.Bits, some of this functions cannot be that fast with the funcionality from a high level language:


function TBit.PopFirstBitSet(var aValue: integer): integer;
//In = [EDX] Out = EAX
ASM
  PUSH ECX
  MOV ECX, [EDX]
  BSF EAX, ECX
  BTR [EDX], EAX
  POP ECX
END;
function TBit.LastBitSet(aValue: integer): integer;
//EDX
ASM
  BSR EAX, EDX
END;
function TBit.FirstBitSet(aValue: integer): integer;
//EDX
ASM
  BSF EAX, EDX
END;
function TBit.BitSetCount(aValue: integer): integer;
begin
  { TODO : optimize with array[0..65535] }
  result := 0;
  while aValue <> 0 do
  begin
    aValue := aValue and (aValue - 1);
    Inc(result);
  end;
end;
function TBit.PopLastBitSet(var aValue: integer): integer;
begin
  result := LastBitSet(aValue);
  _Clear(aValue, result);
end;