with Interfaces;
use Interfaces;

pragma Elaborate_All (Interfaces);

function Integer_Sqrt(N: Natural) return Natural is
  Y:  Unsigned_32 := 0;
  M:  Unsigned_32 := 16#4000_0000#;
  X1: Unsigned_32 := Unsigned_32(N);
  X2: Unsigned_32;
begin
  loop
    X2 := Y+M;
    Y := Shift_Right(Y,1);
    if X2 <= X1 then
      X1 := X1-X2;
      Y := Y+M;
    end if;
    M := Shift_Right(M,2);
    exit when M=0;
  end loop;
  return Natural(Y);
end Integer_Sqrt;
