How to check whether only 2 bits in a number at a specific position are on (edge‑case‑safe) with Pascal

1 Answer

0 votes
program ExactTwoBits;

{$mode objfpc}{$H+}

uses
  SysUtils;

procedure PrintBits(value: QWord; width: Integer);
var
  i: Integer;
begin
  for i := width - 1 downto 0 do
  begin
    if (value and (QWord(1) shl i)) <> 0 then
      Write('1')
    else
      Write('0');
  end;
end;

function ExactBitSet(pos1, pos2: Integer; value: QWord): Boolean;
var
  mask: QWord;
begin
  if (pos1 < 0) or (pos2 < 0) or (pos1 >= 64) or (pos2 >= 64) then
    Exit(False);

  if pos1 = pos2 then
    Exit(False);

  mask := (QWord(1) shl pos1) or (QWord(1) shl pos2);
  Result := value = mask;
end;

type
  TTest = record
    value: QWord;
    x, y: Integer;
    width: Integer;
  end;

var
  tests: array[1..11] of TTest;
  i: Integer;

begin
  { Assign test cases explicitly }
  tests[1].value := %1000010000; tests[1].x := 4; tests[1].y := 9; tests[1].width := 10;
  tests[2].value := %0010000010; tests[2].x := 1; tests[2].y := 7; tests[2].width := 10;
  tests[3].value := %0000100100; tests[3].x := 2; tests[3].y := 5; tests[3].width := 10;
  tests[4].value := %1000010000; tests[4].x := 3; tests[4].y := 9; tests[4].width := 10;
  tests[5].value := %1001010000; tests[5].x := 4; tests[5].y := 9; tests[5].width := 10;
  tests[6].value := %1111111111; tests[6].x := 4; tests[6].y := 9; tests[6].width := 10;
  tests[7].value := %0000000000; tests[7].x := 4; tests[7].y := 9; tests[7].width := 10;
  tests[8].value := %1000010000; tests[8].x := 4; tests[8].y := 8; tests[8].width := 10;
  tests[9].value := 1;            tests[9].x := 0; tests[9].y := 0; tests[9].width := 1;
  tests[10].value := 1;           tests[10].x := 0; tests[10].y := 1; tests[10].width := 1;
  tests[11].value := 0;           tests[11].x := 1; tests[11].y := 1; tests[11].width := 1;

  for i := 1 to Length(tests) do
  begin
    PrintBits(tests[i].value, tests[i].width);
    Write('  bits(', tests[i].x, ', ', tests[i].y, ')  ->  ');
    if ExactBitSet(tests[i].x, tests[i].y, tests[i].value) then
      Writeln('true')
    else
      Writeln('false');
  end;
end.


{
OUTPUT:

1000010000  bits(4, 9)  ->  true
0010000010  bits(1, 7)  ->  true
0000100100  bits(2, 5)  ->  true
1000010000  bits(3, 9)  ->  false
1001010000  bits(4, 9)  ->  false
1111111111  bits(4, 9)  ->  false
0000000000  bits(4, 9)  ->  false
1000010000  bits(4, 8)  ->  false
1  bits(0, 0)  ->  false
1  bits(0, 1)  ->  false
0  bits(1, 1)  ->  false

}

 



answered Apr 3 by avibootz

Related questions

...