Task: Isqrt (integer square root) of X








VB: Imports System
Imports System.Console
Imports BI = System.Numerics.BigInteger

Module Module1
    Function isqrt(ByVal x As BI) As BI
        Dim t As BI, q As BI = 1, r As BI = 0
        While q <= x : q <<= 2 : End While
        While q > 1 : q >>= 2 : t = x - r - q : r >>= 1
            If t >= 0 Then x = t : r += q
        End While : Return r
    End Function

    Sub Main()
        Const max As Integer = 73, smax As Integer = 65
        Dim power_width As Integer = ((BI.Pow(7, max).ToString().Length \ 3) << 2) + 3,
            isqrt_width As Integer = (power_width + 1) >> 1,
            n as Integer
        WriteLine("Integer square root for numbers 0 to {0}:", smax)
        For n = 0 To smax : Write("{0} ", (n \ 10).ToString().Replace("0", " "))
            Next : WriteLine()
        For n = 0 To smax : Write("{0} ", n Mod 10) : Next : WriteLine()
        WriteLine(New String("-"c, (smax << 1) + 1))
        For n = 0 To smax : Write("{0} ", isqrt(n)) : Next
        WriteLine(vbLf & vbLf & "Integer square roots of odd powers of 7 from 1 to {0}:", max)
        Dim s As String = String.Format("[0,2] |[1,{0}:n0] |[2,{1}:n0]",
            power_width, isqrt_width).Replace("[", "{").Replace("]", "}")
        WriteLine(s, "n", "7 ^ n", "isqrt(7 ^ n)")
        WriteLine(New String("-"c, power_width + isqrt_width + 6))
        Dim p As BI = 7 : n = 1 : While n <= max
            WriteLine(s, n, p, isqrt(p)) : n += 2 : p = p * 49
        End While
    End Sub
End Module




Ada: with Ada.Text_Io;
with Ada.Numerics.Big_Numbers.Big_Integers;
with Ada.Strings.Fixed;

procedure Integer_Square_Root is

   use Ada.Numerics.Big_Numbers.Big_Integers;
   use Ada.Text_Io;

   function Isqrt (X : Big_Integer) return Big_Integer is
      Q       : Big_Integer := 1;
      Z, T, R : Big_Integer;
   begin
      while Q <= X loop
         Q := Q * 4;
      end loop;
      Z := X;
      R := 0;
      while Q > 1 loop
         Q := Q / 4;
         T := Z - R - Q;
         R := R / 2;
         if T >= 0 then
            Z := T;
            R := R + Q;
         end if;
      end loop;
      return R;
   end Isqrt;

   function Commatize (N : Big_Integer; Width : Positive) return String is
      S     : constant String := To_String (N, Width);
      Image : String (1 .. Width + Width / 3) := (others => ' ');
      Pos   : Natural := Image'Last;
   begin
      for I in S'Range loop
         Image (Pos) := S (S'Last - I + S'First);
         exit when Image (Pos) = ' ';
         Pos := Pos - 1;
         if I mod 3 = 0 and S (S'Last - I + S'First - 1) /= ' ' then
            Image (Pos) := ''';
            Pos := Pos - 1;
         end if;
      end loop;
      return Image;
   end Commatize;

   type Mode_Kind is (Tens, Ones, Spacer, Result);
begin
   Put_Line ("Integer square roots of integers 0 .. 65:");
   for Mode in Mode_Kind loop
      for N in 0 .. 65 loop
         case Mode is
            when Tens   =>  Put ((if N / 10 = 0
                                  then "  "
                                  else Natural'Image (N / 10)));
            when Ones   =>  Put (Natural'Image (N mod 10));
            when Spacer =>  Put ("
            when Result =>  Put (To_String (Isqrt (To_Big_Integer (N))));
         end case;
      end loop;
      New_Line;
   end loop;
   New_Line;

   declare
      package Integer_Io is new Ada.Text_Io.Integer_Io (Natural);
      use Ada.Strings.Fixed;
      N    : Integer    := 1;
      P, R : Big_Integer;
   begin
      Put_Line ("|  N|" & 80 * " " & "7**N|" & 30 * " " & "isqrt (7**N)|");
      Put_Line (133 * "=");
      loop
         P := 7**N;
         R := Isqrt (P);
         Put ("|");  Integer_Io.Put (N, Width => 3);
         Put ("|");  Put (Commatize (P, Width => 63));
         Put ("|");  Put (Commatize (R, Width => 32));
         Put ("|");  New_Line;
         exit when N >= 73;
         N := N + 2;
      end loop;
      Put_Line (133 * "=");
   end;

end Integer_Square_Root;