Square root by hand

From Rosetta Code
Revision as of 16:34, 23 October 2020 by Hkdtam (talk | contribs) (added Raku programming solution)
Square root by hand is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

Create a program that will calculate n digits of the square root of a number.

The program should continue forever (or until the number of digits is specified) calculating and outputting each decimal digit in succession. The program should be a "spigot algorithm" generating the digits of the number sequentially from left to right providing increasing precision as the algorithm proceeds.

C#

Translation of: Visual Basic .NET

<lang csharp>using System; using static System.Math; using static System.Console; using BI = System.Numerics.BigInteger;

class Program {

   static void Main(string[] args) {
       BI i, j, k, d; i = 2; int n = -1; int n0 = -1;
       j = (BI)Floor(Sqrt((double)i)); k = j; d = j;
       DateTime st = DateTime.Now;
       if (args.Length > 0) int.TryParse(args[0], out n);
       if (n > 0) n0 = n; else n = 1;
       do {
           Write(d); i = (i - k * d) * 100; k = 20 * j;
           for (d = 1; d <= 10; d++)
               if ((k + d) * d > i) { d -= 1; break; }
           j = j * 10 + d; k += d; if (n0 > 0) n--;
       } while (n > 0);
       if (n0 > 0) WriteLine("\nTime taken for {0} digits: {1}", n0, DateTime.Now - st); }

}</lang>

Output:
14142135623730950488016887242096980785696718753769480731766797379907324784621070388503875343276415727350138462309122970249248360558507372126441214970999358314132226659275055927557999505011527820605714701095599716059702745345968620147285174186408891986095523292304843087143214508397626036279952514079896872533965463318088296406206152583523950547457502877599617298355752203375318570113543746034084988471603868999706990048150305440277903164542478230684929369186215805784631115966687130130156185689872372

Time taken for 500 digits: 00:00:00.0092331

F#

<lang fsharp> // Square Root of n 'By Hand' (n as bigint >= 1). Nigel Galloway: October 14th., 2020 let rec fN n g=match n/100I with i when i=0I->(n%100I)::g |i->fN i ((n%100I)::g) let fG n g=[9I.. -1I..0I]|>Seq.map(fun g->(g,g*(20I*n+g)))|>Seq.find(fun(_,n)->n<=g) let fL(n,g,l)=let c,n=match n with []->(g*100I,[]) |_->((List.head n)+g*100I,List.tail n)

                 let x,y=fG l c in Some(int x,(n,c-y,l*10I+x))

let sR n g l=Seq.unfold fL (fN n [],0I,0I)|>Seq.take l|>Seq.iteri(fun i n->printf "%s%d" (if i=(g+1)/2 then "." else "") n); printfn "\n"

sR 2I 1 480; sR 1089I 2 8 </lang>

Output:
1.41421356237309504880168872420969807856967187537694807317667973799073247846210703885038753432764157273501384623091229702492483605585073721264412149709993583141322266592750559275579995050115278206057147010955997160597027453459686201472851741864088919860955232923048430871432145083976260362799525140798968725339654633180882964062061525835239505474575028775996172983557522033753185701135437460340849884716038689997069900481503054402779031645424782306849293691862158057846311159666871

3.3000000

Go

Translation of: Visual Basic .NET

The original has been adjusted in a similar fashion to the Wren entry to deal with non-integer cases. <lang go>package main

import (

   "fmt"
   "math/big"

)

var one = big.NewInt(1) var ten = big.NewInt(10) var twenty = big.NewInt(20) var hundred = big.NewInt(100)

func sqrt(n float64, limit int) {

   if n < 0 {
       log.Fatal("Number cannot be negative")
   }
   count := 0
   for n != math.Trunc(n) {
       n *= 100
       count--
   }
   i := big.NewInt(int64(n))
   j := new(big.Int).Sqrt(i)
   count += len(j.String())
   k := new(big.Int).Set(j)
   d := new(big.Int).Set(j)
   t := new(big.Int)
   digits := 0
   var sb strings.Builder
   for digits < limit {
       sb.WriteString(d.String())
       t.Mul(k, d)
       i.Sub(i, t)
       i.Mul(i, hundred)
       k.Mul(j, twenty)
       d.Set(one)
       for d.Cmp(ten) <= 0 {
           t.Add(k, d)
           t.Mul(t, d)
           if t.Cmp(i) > 0 {
               d.Sub(d, one)
               break
           }
           d.Add(d, one)
       }
       j.Mul(j, ten)
       j.Add(j, d)
       k.Add(k, d)
       digits = digits + 1
   }
   root := strings.TrimRight(sb.String(), "0")
   if len(root) == 0 {
       root = "0"
   }
   if count > 0 {
       root = root[0:count] + "." + root[count:]
   } else if count == 0 {
       root = "0." + root
   } else {
       root = "0." + strings.Repeat("0", -count) + root
   }
   root = strings.TrimSuffix(root, ".")
   fmt.Println(root)

}

func main() {

   numbers := []float64{2, 0.2, 10.89, 625, 0.0001}
   digits := []int{500, 80, 8, 8, 8}
   for i, n := range numbers {
       fmt.Printf("First %d significant digits (at most) of the square root of %g:\n", digits[i], n)
       sqrt(n, digits[i])
       fmt.Println()
   }

}</lang>

Output:
First 500 significant digits (at most) of the square root of 2:
1.4142135623730950488016887242096980785696718753769480731766797379907324784621070388503875343276415727350138462309122970249248360558507372126441214970999358314132226659275055927557999505011527820605714701095599716059702745345968620147285174186408891986095523292304843087143214508397626036279952514079896872533965463318088296406206152583523950547457502877599617298355752203375318570113543746034084988471603868999706990048150305440277903164542478230684929369186215805784631115966687130130156185689872372

First 80 significant digits (at most) of the square root of 0.2:
0.44721359549995793928183473374625524708812367192230514485417944908210418512756097

First 8 significant digits (at most) of the square root of 10.89:
3.3

First 8 significant digits (at most) of the square root of 625:
25

First 8 significant digits (at most) of the square root of 0.0001:
0.01

Julia

Uses channels to iterate the spigot flow. <lang julia>function sqrt_spigot(number::Integer, places=0, limit=10000, bufsize=32)

   spigot = Channel{Char}(bufsize)
   """ Mark off pairs of digits, starting from the decimal point, working left. """
   function markoff(n)
       d = digits(n)
       pairs, len = Vector{BigInt}[], length(d)
       if isodd(len)
           push!(pairs, [pop!(d)])
           len -= 1
       end
       for i in len-1:-2:1
           push!(pairs, [d[i], d[i+1]])
       end
       places = length(pairs) - div(places , 2)
       return pairs
   end
   """ look at first digit(s) and find largest i such that i^2 < that number """
   function firststep!(pairs)
       curnum = evalpoly(BigInt(10), popfirst!(pairs))
       i = BigInt(findlast(x -> x * x <= curnum, 0:9) - 1)
       put!(spigot, Char('0' + i))
       return pairs, [i], curnum - i * i
   end
   """
   What is the largest number d that we can put in the units and also multiply times
   the divisor such that the result is still be less than or equal to what we have?
   """
   function nextstep!(pairs, founddigits, remain)
       divisor = evalpoly(BigInt(10), founddigits) * 2
       remwithnext = remain * 100 + evalpoly(BigInt(10), popfirst!(pairs))
       d = BigInt(findlast(x -> x * (divisor * 10 + x) <= remwithnext, 0:9) - 1)
       remain = remwithnext - (divisor * 10 + d) * d
       pushfirst!(founddigits, d)
       put!(spigot, Char('0' + d))
       return pairs, founddigits, remain
   end
   """ start the process of adding digits to the channel """
   function longhand_sqrt(n)
       p = markoff(n)
       if places <= 0 # 0 <= n < 1, such as 0.00144
           put!(spigot, '0')
           put!(spigot, '.')
           for i in places:1:-1
               put!(spigot, '0')
           end
       end
       pairs, founddigits, remain = firststep!(p)
       for _ in 1:limit
           if isempty(pairs) # more zeros for part right of decimal point
               push!(pairs, [0, 0], [0, 0], [0, 0], [0, 0])
           end
           (places -= 1) == 0 && put!(spigot, '.')
           pairs, founddigits, remain = nextstep!(pairs, founddigits, remain)
       end
   end
   @async(longhand_sqrt(number))
   # return the channel from which to take! digits.
   return spigot

end

function sqrt_spigot(str::String, lm=10000, bsiz=32)

   str = lowercase(str)
   if occursin("e", str)
       str, exdig = split(str, "e")
       extra = parse(Int, exdig)
       !occursin(".", str) && (str *= '.')
   else
       extra = 0
   end
   if occursin(".", str)
       if str[1] == '.'
           str = '0' * str
       elseif str[end] == str
           str = str * '0'
       end
       s1, s2 = split(str, ".")
       if extra < 0 # negative exponent, so rewrite call in non-exponential form
           pos = length(s1) + extra
           if pos < 0
               str = "0." * "0"^(-pos) * s1 * s2
           else
               str = s1[1:end-pos] * "." * s1[end-pos+1:end] * s2
           end
           return sqrt_spigot(str, lm, bsiz)
       end
       b1, b2, places = parse(BigInt, s1), parse(BigInt, s2), length(s2)
       if extra > 0
           b1 *= BigInt(10)^extra
           b2 *= BigInt(10)^extra
       end
       if isodd(places)
           n = b1 * BigInt(10)^(places + 1) + b2 * 10
           places += 1
       else
           n = b1 * BigInt(10)^places + b2
       end
       return sqrt_spigot(n, places, lm, bsiz)
   else
       return sqrt_spigot(parse(BigInt, str), 0, lm, bsiz)
   end

end

sqrt_spigot(number::Real; l=10000, b=32) = sqrt_spigot("$number", l, b)

function testspigotsqrt(arr)

   for num in arr
       spigot = sqrt_spigot(num)
       println("The square root of $num is:")
       for i in 1:500
           print(take!(spigot))
           i % 50 == 0 && println()
       end
       println()
   end

end

testspigotsqrt([2, 0.2, 0, 00.0001, 10.89, 144e-6, 2.0e4, 0.00000009, 1.44e+04, 1.44e-32])

</lang>

Output:
The square root of 2.0 is:
1.414213562373095048801688724209698078569671875376
94807317667973799073247846210703885038753432764157
27350138462309122970249248360558507372126441214970
99935831413222665927505592755799950501152782060571
47010955997160597027453459686201472851741864088919
86095523292304843087143214508397626036279952514079
89687253396546331808829640620615258352395054745750
28775996172983557522033753185701135437460340849884
71603868999706990048150305440277903164542478230684
92936918621580578463111596668713013015618568987237

The square root of 0.2 is:
0.447213595499957939281834733746255247088123671922
30514485417944908210418512756097988288288167575645
49939016352301547567008506535448894147727172720243
06690541773355634638375833162255329064527971316107
15227008350675700068467848281288841728650781945051
85254457752599034804881363223551817818996984742781
45945779696417728308537978819826338715403949735776
88501795082659123663538429999548496030608682300719
15336665024997630356278816001124841710487084471112
21261268564046818666396586791949270454240268349922

The square root of 0.0 is:
0.000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000

The square root of 0.0001 is:
0.010000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000

The square root of 10.89 is:
3.300000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000

The square root of 0.000144 is:
0.012000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000

The square root of 20000.0 is:
141.4213562373095048801688724209698078569671875376
94807317667973799073247846210703885038753432764157
27350138462309122970249248360558507372126441214970
99935831413222665927505592755799950501152782060571
47010955997160597027453459686201472851741864088919
86095523292304843087143214508397626036279952514079
89687253396546331808829640620615258352395054745750
28775996172983557522033753185701135437460340849884
71603868999706990048150305440277903164542478230684
92936918621580578463111596668713013015618568987237

The square root of 9.0e-8 is:
0.000300000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000

The square root of 14400.0 is:
120.0000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000

The square root of 1.44e-32 is:
0.000000000000000120000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000

Phix

Based on https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Decimal_(base_10)
The use of string inputs helps guarantee perfect accuracy. <lang Phix>requires("0.8.2") function bcd_sub(string a,b)

   -- returns "a"-"b", coping with different lengths
   -- (assumes a>=b, which it always will be here,
   --- protected as it is by the bcd_le(b,a) call.)
   integer c = 0, d = length(a)-length(b)
   if    d<0 then a = repeat('0',-d)&a
   elsif d>0 then b = repeat('0', d)&b end if
   for i=length(a) to 1 by -1 do
       d = a[i]-b[i]-c
       c = d<0
       a[i] = d+c*10+'0'
   end for
   a = trim_head(a,"0") -- (note: "" equ "0")
   return a

end function

function bcd_xp20x(string p, integer x)

   -- returns x*(p*20+x)
   integer c = 0, d, m = 1
   p &= x+'0'
   for i=length(p) to 1 by -1 do
       d = (p[i]-'0')*m*x+c
       p[i] = remainder(d,10)+'0'
       c = floor(d/10)
       m = 2
   end for
   if c then
       p = (remainder(c,10)+'0')&p
       c = floor(c/10)
       if c then ?9/0 end if -- loop rqd?
   end if
   return p

end function

function bcd_le(string a,b)

   -- returns a<=b numerically, taking care of different lengths
   integer d = length(a)-length(b)
   if d<0 then
       a = repeat('0',-d)&a
   elsif d>0 then
       b = repeat('0',d)&b
   end if
   return a<=b

end function

function spigot_sqrt(string s, integer maxlen=50)

   -- returns the square root of a positive string number to any precision
   if find('-',s) or s="" then ?9/0 end if
   integer dot = find('.',s)
   if dot=0 then dot = length(s)+1 end if
   if remainder(dot,2)=0 then s = "0"&s end if
   dot += 1
   string res = "", p = "", c = ""
   integer i = 1
   while true do -- (until (i>length && carry=0) or > maxlen)
       if (i<=length(s) and s[i]='.')
       or (i >length(s) and dot) then
           res &= "."
           dot = 0
           i += 1
       end if
       c &= iff(i<=length(s)?s[i]:'0') &
            iff(i<length(s)?s[i+1]:'0')
       for x=9 to 0 by -1 do
           string y = bcd_xp20x(p,x)
           if bcd_le(y,c) then
               c = bcd_sub(c,y)
               res &= x+'0'
               p &= x+'0'
               exit
           end if
           if x=0 then ?9/0 end if -- (sanity check)
       end for
       i += 2
       if (c="" and i>length(s)) or length(res)>maxlen then exit end if
   end while
   return res

end function

procedure spigot_test(string s, integer maxlen=50) constant fmt = "First %d digits (at most) of the square root of %s:%s %s\n"

   string r = spigot_sqrt(s, maxlen),
          lf = iff(length(r)>10?"\n ":"")
   if length(r)>100 then
       r = join_by(r,1,100,"","\n  ")
   end if
   printf(1,fmt,{maxlen,s,lf,r})

end procedure

constant tests = {"152.2756","15241.383936",{"0.2",80},"10.89","625",

                 "0","0.0001","0.00000009",{"20000",99},{"2",500}}

papply(false,spigot_test,tests)</lang>

Output:

(the final "2" was re-joined up by hand)

First 50 digits (at most) of the square root of 152.2756: 12.34
First 50 digits (at most) of the square root of 15241.383936: 123.456
First 80 digits (at most) of the square root of 0.2:
  0.4472135954999579392818347337462552470881236719223051448541794490821041851275609
First 50 digits (at most) of the square root of 10.89: 3.3
First 50 digits (at most) of the square root of 625: 25
First 50 digits (at most) of the square root of 0: 0
First 50 digits (at most) of the square root of 0.0001: 0.01
First 50 digits (at most) of the square root of 0.00000009: 0.0003
First 99 digits (at most) of the square root of 20000:
  141.421356237309504880168872420969807856967187537694807317667973799073247846210703885038753432764157
First 500 digits (at most) of the square root of 2:
  1.41421356237309504880168872420969807856967187537694807317667973799073247846210703885038753432764157
  2735013846230912297024924836055850737212644121497099935831413222665927505592755799950501152782060571
  4701095599716059702745345968620147285174186408891986095523292304843087143214508397626036279952514079
  8968725339654633180882964062061525835239505474575028775996172983557522033753185701135437460340849884
  71603868999706990048150305440277903164542478230684929369186215805784631115966687130130156185689872372

stress test?: <lang Phix>include mpfr.e mpfr_set_default_prec(-100) -- 100 d.p precision mpfr pi = mpfr_init() mpfr_const_pi(pi) string ps = mpfr_sprintf("%.100Rf", pi),

      rs = spigot_sqrt(ps,102) -- (<=101 is not enough)

mpfr_set_str(pi,rs) mpfr_mul(pi,pi,pi) rs = mpfr_sprintf("%.100Rf", pi) printf(1,"Pi (builtin) vs spigot_sqrt(pi) squared:\n %s\n %s\n",{ps,rs})</lang>

Output:
Pi (builtin) vs spigot_sqrt(pi) squared:
  3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170680
  3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170680

Raku

Implemented a long division algorithm.. <lang perl6># 20201023 Raku programming solution

sub integral (Str $in) { # prepend '0' if length is odd

  given $in { .chars mod 2 ?? ('0'~$_).comb(2) !! .comb(2) }

}

sub fractional (Str $in) { # append '0' if length is odd

  given $in { .chars mod 2 ?? ($_~'0').comb(2) !! .comb(2) }

}

sub SpigotSqrt ($in) {

  my @dividends, my @fractional; # holds digital duos
  my $d = 9;    # unit  digit part of divisors & running answer
  my $D = ;   # tens+ digit part of divisors
  my $once = 0; # for printing '.' only once
  my $dividend; my $quotient = ; my $remainder;
  return "Sorry, minimum charge is $0⁺" if $in < 0;
  if $in.narrow ~~ Int {                 # integer
     @dividends = integral($in.Str)
  } else {
     given split(/\./, $in.Str) {        # floating point
        @dividends  =   integral(@_[0]);
        @fractional = fractional(@_[1]);
     }
  }
  $dividend = shift @dividends;
  loop {
     until ( $remainder = $dividend - ($D~$d) * $d ) ≥ 0 {
        $d-- # keep trying till the max divisor is found
     }
     print $d; # running answer
     $quotient ~= $d;
     unless @dividends.Bool {
        last if ( $remainder == 0 and $quotient != 0 and !@fractional.Bool );
        print '.' unless $once++ ; # happen only once
        if @fractional.Bool {      # happen only once
           @dividends.append: @fractional;
           @fractional = (); # retired
        } else {
           @dividends.append: '00';
        }
     }
     $dividend = $remainder.Str ~ shift @dividends;
     $D = 2*$quotient;
     $d = 9
  }

}

  1. `[ matches result from https://stackoverflow.com/a/28152047/3386748

for <99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999982920000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000726067> { # ] for < 25 0.0625 152.2756 13579.02468 > {

  say "The square root of $_ is";
  SpigotSqrt $_ ; print "\n";

}</lang>

Output:
The square root of 25 is
5
The square root of 0.0625 is
0.25
The square root of 152.2756 is
12.34
The square root of 13579.02468 is
116.5290722523782903561833846788464631805119729204989141878325473726703822155976113726101636833624692173783050112427274490403132495026916228339453686341013613481116569793281525666303293666139135373395664751766204609166006753350008676787108560810713189340122619853015331030735400702976991920098868235804433621649473896395145322270105611438518020713137788187701241059921153133101219142225340975562189465283743880315403123043908068827985609461380033349440281928044661628680849458194668644072518779930532625670101046028192429778354952392572052578927533919600336446165970115867463651405291843435779882540897283554569528134419570259054368204716277521872340583781499813500950876849873104131526244245476070417915^C

REXX

This REXX version also handles non-negative numbers less than unity,   and may suppress superfluous trailing zeros.

It also handles the placing of a decimal point   (if needed). <lang rexx>/*REXX program computes the square root by the old "by pen─n'─paper" (hand) method.*/ signal on halt /*handle the case of user interrupt. */ parse arg xx digs . /*obtain optional arguments from the CL*/ if xx== | xx=="," then xx= 2 /*Not specified? Then use the default.*/ if digs== | digs=="," then digs= 500 /* " " " " " " */ numeric digits digs + digs % 2 /*ensure enough decimal digits for calc*/ call sqrtHand xx, digs /*invoke the function for sqrt by hand.*/ halt: say /*pgm comes here for exact sqrt or HALT*/ exit 0 /*stick a fork in it, we're all done. */ /*──────────────────────────────────────────────────────────────────────────────────────*/ iSqrt: procedure; parse arg z; q= 1; r= 0; do while q<=z; q= q*4; end

        do while q>1; q= q%4; _= z-r-q; r= r%2; if _>=0  then do; z= _; r= r+q;  end; end
      return r                                  /*R  is the integer square root of  Z. */

/*──────────────────────────────────────────────────────────────────────────────────────*/ spit: parse arg @; call charout , @; if #<9 then s= s || @; return /*──────────────────────────────────────────────────────────────────────────────────────*/ sqrtHand: parse arg x 1 ox,##; parse value iSqrt(x) with j 1 k 1 ? /*j, k, ? ≡ iSqrt(x)*/

         if ?==0   then ?=                              /*handle the case of sqrt < 1. */
         if j*j=x  then do;  say j;  return;  end       /*have we found the exact sqrt?*/
         L= length(?)                                   /*L:  used to place dec. point.*/
         s=;                         #= 0               /*R:  partial square root.    .*/
         if L==0  then call spit .                      /*handle dec. point for X < 1. */
                 do #=1  for ##;   call spit ?          /*spit out the first digit.    */
                 if L>0  then do;  call spit .;  L= 0;  end    /*process decimal point.*/
                 if #<9  then if datatype(s,'N')  then if s*s=ox  then leave /*exact√ ?*/
                 if ?==  then ?= 0                    /*ensure   ?  is a valid digit.*/
                 x= (x - k*?) * 100;  ?= 1
                 k= j * 20
                             do while ?<=10
                             if (k + ?)*? > x  then do;  ?= ? - 1;  leave;  end
                                               else      ?= ? + 1
                             end   /*while ?≤10*/
                 j= ? + j*10
                 k= ? + k
                 end               /*#*/
          return</lang>
output   when using the default inputs:
1.41421356237309504880168872420969807856967187537694807317667973799073247846210703885038753432764157273501384623091229702492483605
5850737212644121497099935831413222665927505592755799950501152782060571470109559971605970274534596862014728517418640889198609552329
2304843087143214508397626036279952514079896872533965463318088296406206152583523950547457502877599617298355752203375318570113543746
034084988471603868999706990048150305440277903164542478230684929369186215805784631115966687130130156185689872372
output   when using the inputs of:     .2   80
.4472135954999579392818347337462552470881236719223051448541794490821041851275609
output   when using the inputs of:     10.89   80
3.3
output   when using the inputs of:     625
25

Visual Basic .NET

This is "spigot like", but not a true spigot, just an implementation of the "by hand" method of computing the square root, in this case, of two.<lang vbnet>Imports System.Math, System.Console, BI = System.Numerics.BigInteger

Module Module1

   Sub Main(ByVal args As String())
       Dim i, j, k, d As BI : i = 2
       j = CType(Floor(Sqrt(CDbl(i))), BI) : k = j : d = j
       Dim n As Integer = -1, n0 As Integer = -1,
           st As DateTime = DateTime.Now
       If args.Length > 0 Then Integer.TryParse(args(0), n)
       If n > 0 Then n0 = n Else n = 1
       Do
           Write(d) : i = (i - k * d) * 100 : k = 20 * j
           For d = 1 To 10
               If (k + d) * d > i Then d -= 1 : Exit For
           Next
           j = j * 10 + d : k += d : If n0 > 0 Then n = n - 1
       Loop While n > 0
       If n0 > 0 Then WriteLine (VbLf & "Time taken for {0} digits: {1}", n0, DateTime.Now - st)
   End Sub

End Module</lang>

Output:

Execute without any command line parameters for it to run until it crashes (due to BigInteger variables eating up available memory). Output with command line parameter of 500:

14142135623730950488016887242096980785696718753769480731766797379907324784621070388503875343276415727350138462309122970249248360558507372126441214970999358314132226659275055927557999505011527820605714701095599716059702745345968620147285174186408891986095523292304843087143214508397626036279952514079896872533965463318088296406206152583523950547457502877599617298355752203375318570113543746034084988471603868999706990048150305440277903164542478230684929369186215805784631115966687130130156185689872372
Time taken for 500 digits: 00:00:00.0263710

Wren

Translation of: Visual Basic .NET
Library: Wren-big

The original has been adjusted to deal with any non-negative number, not just integers. Where appropriate a decimal point and leading zero(s) have been added but don't count towards the required number of digits. Trailing zeros do count but have been trimmed off for display purposes. <lang ecmascript>import "/big" for BigInt

var sqrt = Fn.new { |n, limit|

   if (n < 0) Fiber.abort("Number cannot be negative.")
   var count = 0
   while (!n.isInteger) {
       n = n * 100
       count = count - 1
   }
   var i = BigInt.new(n)
   var j = i.isqrt
   count = count + j.toString.count
   var k = j
   var d = j
   var digits = 0
   var root = ""
   while (digits < limit) {
       root = root + d.toString
       i = (i - k*d) * 100
       k = j * 20
       d = BigInt.one
       while (d <= 10) {
           if ((k + d)*d > i) {
               d = d.dec
               break
           }
           d = d.inc
       }
       j = j*10 + d
       k = k + d
       digits = digits + 1
   }
   root = root.trimEnd("0")
   if (root == "") root = "0"
   if (count > 0) {
       root = root[0...count] + "." + root[count..-1]
   } else if (count == 0) {
       root = "0." + root
   } else {
       root = "0." + ("0" * (-count)) + root
   }
   if (root[-1] == ".") root = root[0..-2]
   System.print(root)

}

var numbers = [2, 0.2, 10.89, 625, 0.0001] var digits = [500, 80, 8, 8, 8] var i = 0 for (n in numbers) {

   System.print("First %(digits[i]) significant digits (at most) of the square root of %(n):")
   sqrt.call(n, digits[i]) 
   System.print()
   i = i + 1

}</lang>

Output:
First 500 significant digits (at most) of the square root of 2:
1.4142135623730950488016887242096980785696718753769480731766797379907324784621070388503875343276415727350138462309122970249248360558507372126441214970999358314132226659275055927557999505011527820605714701095599716059702745345968620147285174186408891986095523292304843087143214508397626036279952514079896872533965463318088296406206152583523950547457502877599617298355752203375318570113543746034084988471603868999706990048150305440277903164542478230684929369186215805784631115966687130130156185689872372

First 80 significant digits (at most) of the square root of 0.2:
0.44721359549995793928183473374625524708812367192230514485417944908210418512756097

First 8 significant digits (at most) of the square root of 10.89:
3.3

First 8 significant digits (at most) of the square root of 625:
25

First 8 significant digits (at most) of the square root of 0.0001:
0.01