Task: Find first and last set bit of a long integer





Java: public class FirstLastBits {

    
    public static int mssb(int x) {
        return Integer.highestOneBit(x);
    }

    public static long mssb(long x) {
        return Long.highestOneBit(x);
    }

    public static int mssb_idx(int x) {
        return Integer.SIZE - 1 - Integer.numberOfLeadingZeros(x);
    }

    public static int mssb_idx(long x) {
        return Long.SIZE - 1 - Long.numberOfLeadingZeros(x);
    }

    public static int mssb_idx(BigInteger x) {
	return x.bitLength() - 1;
    }

    
    public static int lssb(int x) {
        return Integer.lowestOneBit(x);
    }

    public static long lssb(long x) {
        return Long.lowestOneBit(x);
    }

    public static int lssb_idx(int x) {
        return Integer.numberOfTrailingZeros(x);
    }

    public static int lssb_idx(long x) {
        return Long.numberOfTrailingZeros(x);
    }

    public static int lssb_idx(BigInteger x) {
	return x.getLowestSetBit();
    }

    public static void main(String[] args) {
        System.out.println("int:");
        int n1 = 1;
        for (int i = 0; ; i++, n1 *= 42) {
            System.out.printf("42**%d = %10d(x%08x): M x%08x(%2d) L x%03x(%2d)\n",
                              i, n1, n1,
                              mssb(n1), mssb_idx(n1),
                              lssb(n1), lssb_idx(n1));
            if (n1 >= Integer.MAX_VALUE / 42)
                break;
        }
        System.out.println();
        System.out.println("long:");
        long n2 = 1;
        for (int i = 0; ; i++, n2 *= 42) {
            System.out.printf("42**%02d = %20d(x%016x): M x%016x(%2d) L x%06x(%2d)\n",
                              i, n2, n2,
                              mssb(n2), mssb_idx(n2),
                              lssb(n2), lssb_idx(n2));
            if (n2 >= Long.MAX_VALUE / 42)
                break;
        }
	System.out.println();
	System.out.println("BigInteger:");
	BigInteger n3 = BigInteger.ONE;
	BigInteger k = BigInteger.valueOf(1302);
	for (int i = 0; i < 10; i++, n3 = n3.multiply(k)) {
	    System.out.printf("1302**%02d = %30d(x%28x): M %2d L %2d\n",
			      i, n3, n3,
			      mssb_idx(n3),
			      lssb_idx(n3));
	}
    }
}







Ada: with Ada.Text_IO;
with Ada.Integer_Text_IO;
with Ada.Unchecked_Conversion;

procedure Find_Last_Bit is

   type My_Integer is range -2**63 .. 2**63 - 1;

   procedure Find_Set_Bits (Value   : in     My_Integer;
                            MSB_Bit :    out Integer;
                            LSB_Bit :    out Integer)
   is
      type Bit_Field is array (0 .. My_Integer'Size - 1) of Boolean;
      pragma Pack (Bit_Field);
      for Bit_Field'Size use My_Integer'Size;

      function To_Field is
         new Ada.Unchecked_Conversion (My_Integer, Bit_Field);

      Field : constant Bit_Field := To_Field (Value);
   begin

      LSB_Bit := -1;
      MSB_Bit := -1;

      for Bit in Field'Range loop
         if Field (Bit) then
            LSB_Bit := Bit;
            exit;
         end if;
      end loop;

      for Bit in reverse Field'Range loop
         if Field (Bit) then
            MSB_Bit := Bit;
            exit;
         end if;
      end loop;
   end Find_Set_Bits;


   procedure Put_Result (Value : in My_Integer) is
      package My_Integer_IO is
         new Ada.Text_IO.Integer_IO (My_Integer);
      use Ada.Text_IO;
      use Ada.Integer_Text_IO;
      Use My_Integer_IO;

      LSB_Bit, MSB_Bit : Integer;
      Placeholder : String := " MSB XX LSB YY";
      Image_MSB     : String renames Placeholder ( 6 ..  7);
      Image_LSB     : String renames Placeholder (13 .. 14);
   begin
      Find_Set_Bits (Value,
                     MSB_Bit => MSB_Bit,
                     LSB_Bit => LSB_Bit);
      Put (Value, Width => 18);
      Put (Value, Width => 66, Base => 2);
      Put (Image_MSB, MSB_Bit);
      Put (Image_LSB, LSB_Bit);
      Put_Line (Placeholder);
   end Put_Result;

begin
   Put_Result (Value => 0);
   for A in 0 .. 11 loop
      Put_Result (Value => 42 ** A);
   end loop;
end Find_Last_Bit;