How to find the Nth set bit in a 32‑bit integer with Pascal

1 Answer

0 votes
program FindNthSetBit32;

{
    findNthSetBit32:
    ----------------
    Given:
        - x : a 32-bit unsigned integer
        - n : which set bit to find (1-based index)

    Returns:
        A 32-bit mask with ONLY the Nth set bit of x turned on.
        If n is larger than the number of set bits, returns 0.

    Algorithm:
        - Count trailing zeros to locate the lowest set bit.
        - Remove that bit using x := x and (x - 1).
        - When we reach the Nth one, return 1 shl index.

    Notes:
        - Pascal does not have a built-in ctz(), so we implement
          a small efficient function that scans from LSB upward.
}

{$mode objfpc}  { Enable modern FreePascal features }

type
    UInt32 = Cardinal;

{ Count trailing zeros (ctz) for a 32-bit integer.
  Returns the index (0–31) of the lowest set bit.
  Assumes x <> 0. }
function CountTrailingZeros(x: UInt32): Integer;
var
    i: Integer;
begin
    i := 0;
    while (x and 1) = 0 do
    begin
        x := x shr 1;
        Inc(i);
    end;
    CountTrailingZeros := i;
end;

{ Find the Nth set bit (1-based) in a 32-bit integer.
  Returns a mask with ONLY that bit set, or 0 if not enough bits. }
function FindNthSetBit32(x: UInt32; n: UInt32): UInt32;
var
    index: Integer;
begin
    while x <> 0 do
    begin
        { Locate lowest set bit }
        index := CountTrailingZeros(x);

        { If this is the Nth set bit, return mask }
        Dec(n);
        if n = 0 then
        begin
            FindNthSetBit32 := UInt32(1) shl index;
            Exit;
        end;

        { Remove lowest set bit }
        x := x and (x - 1);
    end;

    { Fewer than n set bits }
    FindNthSetBit32 := 0;
end;

{ Print a 32-bit binary representation }
function ToBinary32(x: UInt32): String;
var
    i: Integer;
begin
    Result := '';
    for i := 31 downto 0 do
        Result := Result + Chr(Ord('0') + ((x shr i) and 1));
end;

var
    value: UInt32;
    n: UInt32;
    resultMask: UInt32;

begin
    value := %00001101001101101100100010100000;
    n := 4;

    resultMask := FindNthSetBit32(value, n);

    Writeln('Input value:  ', ToBinary32(value));
    Writeln('N = ', n);
    Writeln('Result mask:  ', ToBinary32(resultMask));
end.



{
run:

Input value:  00001101001101101100100010100000
N = 4
Result mask:  00000000000000000100000000000000

}

 



answered Jul 24 by avibootz
...