How to write 4 different functions that check if a number is a power of 2 in Pascal

2 Answers

0 votes
program PowerOfTwoDemo;

{$mode objfpc}  { for boolean and clean syntax }

uses
  SysUtils;

{ 1. Bitwise method: n > 0 and (n and (n - 1)) = 0 }
function IsPowerOfTwoBitwise(n: LongInt): Boolean;
begin
  Result := (n > 0) and ((n and (n - 1)) = 0);
end;

{ 2. Loop dividing by 2 }
function IsPowerOfTwoLoop(n: LongInt): Boolean;
begin
  if n <= 0 then
    Exit(False);

  while (n mod 2 = 0) do
    n := n div 2;

  Result := (n = 1);
end;

{ 3. Count number of 1 bits (like your Python example) }
function IsPowerOfTwoPopcount(n: LongInt): Boolean;
var
  count: Integer;
begin
  if n <= 0 then
    Exit(False);

  count := 0;
  while n > 0 do
  begin
    if (n and 1) = 1 then
      Inc(count);
    if count > 1 then
      Exit(False);
    n := n shr 1;
  end;

  Result := (count = 1);
end;

{ 4. Recursive method }
function IsPowerOfTwoRecursive(n: LongInt): Boolean;
begin
  if n = 1 then
    Exit(True);
  if (n <= 0) or (n mod 2 <> 0) then
    Exit(False);
  Result := IsPowerOfTwoRecursive(n div 2);
end;

procedure TestNumber(x: LongInt);
begin
  WriteLn('Testing ', x, ':');
  WriteLn('  bitwise:   ', BoolToStr(IsPowerOfTwoBitwise(x), 'true', 'false'));
  WriteLn('  loop:      ', BoolToStr(IsPowerOfTwoLoop(x), 'true', 'false'));
  WriteLn('  popcount:  ', BoolToStr(IsPowerOfTwoPopcount(x), 'true', 'false'));
  WriteLn('  recursive: ', BoolToStr(IsPowerOfTwoRecursive(x), 'true', 'false'));
  WriteLn;
end;

begin
  TestNumber(16);
  TestNumber(18);
end.



{
OUTPUT:

Testing 16:
  bitwise:   true
  loop:      true
  popcount:  true
  recursive: true

Testing 18:
  bitwise:   false
  loop:      false
  popcount:  false
  recursive: false
  
}


 



answered Apr 2 by avibootz
0 votes
program PowerOfTwoCheck;

uses Math;

function IsPowerOfTwoA(x: Integer): Boolean;
var
  count, n: Integer;
begin
  if x <= 0 then
    Exit(False);

  count := 0;
  n := x;

  while n > 0 do
  begin
    if (n and 1) = 1 then
      Inc(count);
    n := n shr 1;
  end;

  IsPowerOfTwoA := count = 1;
end;

function IsPowerOfTwoB(x: Integer): Boolean;
begin
  IsPowerOfTwoB := (x > 0) and ((x and (x - 1)) = 0);
end;

function IsPowerOfTwoC(x: Integer): Boolean;
begin
  if x <= 0 then
    Exit(False);

  while (x mod 2 = 0) do
    x := x div 2;

  IsPowerOfTwoC := x = 1;
end;

function IsPowerOfTwoD(x: Integer): Boolean;
var
  logv: Double;
begin
  if x <= 0 then
    Exit(False);

  logv := Ln(x) / Ln(2);
  IsPowerOfTwoD := Abs(logv - Round(logv)) < 1e-10;
end;

var
  test1, test2: Integer;

begin
  test1 := 16;  // true
  test2 := 18;  // false

  WriteLn('A: ', IsPowerOfTwoA(test1), ', ', IsPowerOfTwoA(test2));
  WriteLn('B: ', IsPowerOfTwoB(test1), ', ', IsPowerOfTwoB(test2));
  WriteLn('C: ', IsPowerOfTwoC(test1), ', ', IsPowerOfTwoC(test2));
  WriteLn('D: ', IsPowerOfTwoD(test1), ', ', IsPowerOfTwoD(test2));
end.



{
OUTPUT:

A: TRUE, FALSE
B: TRUE, FALSE
C: TRUE, FALSE
D: TRUE, FALSE
  
}


 



answered Apr 2 by avibootz

Related questions

...