defmodule Arbitrary do
  def pow(_,0), do: 1
  def pow(b,e) when e > 0, do: pow(b,e,1)

  defp pow(b,1,acc), do: acc * b
  defp pow(b,p,acc) when rem(p,2)==0, do: pow(b*b,div(p,2),acc)
  defp pow(b,p,acc), do: pow(b,p-1,acc*b)

  def test do
    s = pow(5,pow(4,pow(3,2))) |> to_string
    l = String.length(s)
    prefix = String.slice(s,0,20)
    suffix = String.slice(s,-20,20)
    IO.puts "Length: #{l}\nPrefix:#{prefix}\nSuffix:#{suffix}"
  end
end
Arbitrary.test


(let* ((integer-width (* 65536 16)) ; raise bignum limit from 65536 bits to avoid overflow error
       (answer (number-to-string (expt 5 (expt 4 (expt 3 2)))))
       (length (length answer)))
  (message "%s has %d digits"
	   (if (> length 40)
	       (format "%s...%s"
		       (substring answer 0 20)
		       (substring answer (- length 20) length))
	     answer)
	   length))


module module_rational

  implicit none
  private
  public :: rational
  public :: rational_simplify
  public :: assignment (=)
  public :: operator (//)
  public :: operator (+)
  public :: operator (-)
  public :: operator (*)
  public :: operator (/)
  public :: operator (<)
  public :: operator (<=)
  public :: operator (>)
  public :: operator (>=)
  public :: operator (==)
  public :: operator (/=)
  public :: abs
  public :: int
  public :: modulo
  type rational
    integer :: numerator
    integer :: denominator
  end type rational
  interface assignment (=)
    module procedure assign_rational_int, assign_rational_real
  end interface
  interface operator (//)
    module procedure make_rational
  end interface
  interface operator (+)
    module procedure rational_add
  end interface
  interface operator (-)
    module procedure rational_minus, rational_subtract
  end interface
  interface operator (*)
    module procedure rational_multiply
  end interface
  interface operator (/)
    module procedure rational_divide
  end interface
  interface operator (<)
    module procedure rational_lt
  end interface
  interface operator (<=)
    module procedure rational_le
  end interface
  interface operator (>)
    module procedure rational_gt
  end interface
  interface operator (>=)
    module procedure rational_ge
  end interface
  interface operator (==)
    module procedure rational_eq
  end interface
  interface operator (/=)
    module procedure rational_ne
  end interface
  interface abs
    module procedure rational_abs
  end interface
  interface int
    module procedure rational_int
  end interface
  interface modulo
    module procedure rational_modulo
  end interface

contains

  recursive function gcd (i, j) result (res)
    integer, intent (in) :: i
    integer, intent (in) :: j
    integer :: res
    if (j == 0) then
      res = i
    else
      res = gcd (j, modulo (i, j))
    end if
  end function gcd

  function rational_simplify (r) result (res)
    type (rational), intent (in) :: r
    type (rational) :: res
    integer :: g
    g = gcd (r % numerator, r % denominator)
    res = r % numerator / g // r % denominator / g
  end function rational_simplify

  function make_rational (numerator, denominator) result (res)
    integer, intent (in) :: numerator
    integer, intent (in) :: denominator
    type (rational) :: res
    res = rational (numerator, denominator)
  end function make_rational

  subroutine assign_rational_int (res, i)
    type (rational), intent (out), volatile :: res
    integer, intent (in) :: i
    res = i // 1
  end subroutine assign_rational_int

  subroutine assign_rational_real (res, x)
    type (rational), intent(out), volatile :: res
    real, intent (in) :: x
    integer :: x_floor
    real :: x_frac
    x_floor = floor (x)
    x_frac = x - x_floor
    if (x_frac == 0) then
      res = x_floor // 1
    else
      res = (x_floor // 1) + (1 // floor (1 / x_frac))
    end if
  end subroutine assign_rational_real

  function rational_add (r, s) result (res)
    type (rational), intent (in) :: r
    type (rational), intent (in) :: s
    type (rational) :: res
    res = r % numerator * s % denominator + r % denominator * s % numerator // &
        & r % denominator * s % denominator
  end function rational_add

  function rational_minus (r) result (res)
    type (rational), intent (in) :: r
    type (rational) :: res
    res = - r % numerator // r % denominator
  end function rational_minus

  function rational_subtract (r, s) result (res)
    type (rational), intent (in) :: r
    type (rational), intent (in) :: s
    type (rational) :: res
    res = r % numerator * s % denominator - r % denominator * s % numerator // &
        & r % denominator * s % denominator
  end function rational_subtract

  function rational_multiply (r, s) result (res)
    type (rational), intent (in) :: r
    type (rational), intent (in) :: s
    type (rational) :: res
    res = r % numerator * s % numerator // r % denominator * s % denominator
  end function rational_multiply

  function rational_divide (r, s) result (res)
    type (rational), intent (in) :: r
    type (rational), intent (in) :: s
    type (rational) :: res
    res = r % numerator * s % denominator // r % denominator * s % numerator
  end function rational_divide

  function rational_lt (r, s) result (res)
    type (rational), intent (in) :: r
    type (rational), intent (in) :: s
    type (rational) :: r_simple
    type (rational) :: s_simple
    logical :: res
    r_simple = rational_simplify (r)
    s_simple = rational_simplify (s)
    res = r_simple % numerator * s_simple % denominator < &
        & s_simple % numerator * r_simple % denominator
  end function rational_lt

  function rational_le (r, s) result (res)
    type (rational), intent (in) :: r
    type (rational), intent (in) :: s
    type (rational) :: r_simple
    type (rational) :: s_simple
    logical :: res
    r_simple = rational_simplify (r)
    s_simple = rational_simplify (s)
    res = r_simple % numerator * s_simple % denominator <= &
        & s_simple % numerator * r_simple % denominator
  end function rational_le

  function rational_gt (r, s) result (res)
    type (rational), intent (in) :: r
    type (rational), intent (in) :: s
    type (rational) :: r_simple
    type (rational) :: s_simple
    logical :: res
    r_simple = rational_simplify (r)
    s_simple = rational_simplify (s)
    res = r_simple % numerator * s_simple % denominator > &
        & s_simple % numerator * r_simple % denominator
  end function rational_gt

  function rational_ge (r, s) result (res)
    type (rational), intent (in) :: r
    type (rational), intent (in) :: s
    type (rational) :: r_simple
    type (rational) :: s_simple
    logical :: res
    r_simple = rational_simplify (r)
    s_simple = rational_simplify (s)
    res = r_simple % numerator * s_simple % denominator >= &
        & s_simple % numerator * r_simple % denominator
  end function rational_ge

  function rational_eq (r, s) result (res)
    type (rational), intent (in) :: r
    type (rational), intent (in) :: s
    logical :: res
    res = r % numerator * s % denominator == s % numerator * r % denominator
  end function rational_eq

  function rational_ne (r, s) result (res)
    type (rational), intent (in) :: r
    type (rational), intent (in) :: s
    logical :: res
    res = r % numerator * s % denominator /= s % numerator * r % denominator
  end function rational_ne

  function rational_abs (r) result (res)
    type (rational), intent (in) :: r
    type (rational) :: res
    res = sign (r % numerator, r % denominator) // r % denominator
  end function rational_abs

  function rational_int (r) result (res)
    type (rational), intent (in) :: r
    integer :: res
    res = r % numerator / r % denominator
  end function rational_int

  function rational_modulo (r) result (res)
    type (rational), intent (in) :: r
    integer :: res
    res = modulo (r % numerator, r % denominator)
  end function rational_modulo

end module module_rational


numeric digits 20
say agm(1, 1/rxcalcsqrt(2,16))

::routine agm
  use strict arg a, g
  numeric digits 20

  a1 = a
  g1 = g

  loop while abs(a1 - g1) >= 1e-14
      temp = (a1 + g1)/2
      g1 = rxcalcsqrt(a1*g1,16)
      a1 = temp
  end
  return a1+0

::requires rxmath LIBRARY


Program ArithmeticGeometricMean;

uses
  gmp;

procedure agm (in1, in2: mpf_t; var out1, out2: mpf_t);
begin
  mpf_add (out1, in1, in2);
  mpf_div_ui (out1, out1, 2);
  mpf_mul (out2, in1, in2);
  mpf_sqrt (out2, out2);
end;

const
  nl = chr(13)+chr(10);
var
  x0, y0, resA, resB: mpf_t;
  i: integer;
begin
  mpf_set_default_prec (65568);

  mpf_init_set_ui (y0, 1);
  mpf_init_set_d (x0, 0.5);
  mpf_sqrt (x0, x0);
  mpf_init (resA);
  mpf_init (resB);

  for i := 0 to 6 do
  begin
    agm(x0, y0, resA, resB);
    agm(resA, resB, x0, y0);
  end;
  mp_printf ('%.20000Ff'+nl, @x0);
  mp_printf ('%.20000Ff'+nl+nl, @y0);
end.


#!/usr/bin/env stack
-- stack --resolver lts-7.0 --install-ghc runghc --package Rasterific --package JuicyPixels

import Codec.Picture( PixelRGBA8( .. ), writePng )
import Graphics.Rasterific
import Graphics.Rasterific.Texture
import Graphics.Rasterific.Transformations

archimedeanPoint a b t = V2 x y
  where r = a + b * t
        x = r * cos t
        y = r * sin t

main :: IO ()
main = do
  let white = PixelRGBA8 255 255 255 255
      drawColor = PixelRGBA8 0xFF 0x53 0x73 255
      size = 800
      points = map (archimedeanPoint 0 10) [0, 0.01 .. 60]
      hSize = fromIntegral size / 2
      img = renderDrawing size size white $
            withTransformation (translate $ V2 hSize hSize) $
            withTexture (uniformTexture drawColor) $
            stroke 4 JoinRound (CapRound, CapRound) $
            polyline points

  writePng "SpiralHaskell.png" img


require'plot'
'aspect 1' plot (*^)j.0.01*i.1400


import java.awt.*;
import static java.lang.Math.*;
import javax.swing.*;

public class ArchimedeanSpiral extends JPanel {

    public ArchimedeanSpiral() {
        setPreferredSize(new Dimension(640, 640));
        setBackground(Color.white);
    }

    void drawGrid(Graphics2D g) {
        g.setColor(new Color(0xEEEEEE));
        g.setStroke(new BasicStroke(2));

        double angle = toRadians(45);

        int w = getWidth();
        int center = w / 2;
        int margin = 10;
        int numRings = 8;

        int spacing = (w - 2 * margin) / (numRings * 2);

        for (int i = 0; i < numRings; i++) {
            int pos = margin + i * spacing;
            int size = w - (2 * margin + i * 2 * spacing);
            g.drawOval(pos, pos, size, size);

            double ia = i * angle;
            int x2 = center + (int) (cos(ia) * (w - 2 * margin) / 2);
            int y2 = center - (int) (sin(ia) * (w - 2 * margin) / 2);

            g.drawLine(center, center, x2, y2);
        }
    }

    void drawSpiral(Graphics2D g) {
        g.setStroke(new BasicStroke(2));
        g.setColor(Color.orange);

        double degrees = toRadians(0.1);
        double center = getWidth() / 2;
        double end = 360 * 2 * 10 * degrees;
        double a = 0;
        double b = 20;
        double c = 1;

        for (double theta = 0; theta < end; theta += degrees) {
            double r = a + b * pow(theta, 1 / c);
            double x = r * cos(theta);
            double y = r * sin(theta);
            plot(g, (int) (center + x), (int) (center - y));
        }
    }

    void plot(Graphics2D g, int x, int y) {
        g.drawOval(x, y, 1, 1);
    }

    @Override
    public void paintComponent(Graphics gg) {
        super.paintComponent(gg);
        Graphics2D g = (Graphics2D) gg;
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);

        drawGrid(g);
        drawSpiral(g);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            JFrame f = new JFrame();
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.setTitle("Archimedean Spiral");
            f.setResizable(false);
            f.add(new ArchimedeanSpiral(), BorderLayout.CENTER);
            f.pack();
            f.setLocationRelativeTo(null);
            f.setVisible(true);
        });
    }
}


-module(arbitrary).
-compile([export_all]).

pow(B,E) when E > 0 ->
    pow(B,E,1).

pow(_,0,_) -> 0;
pow(B,1,Acc) -> Acc * B;
pow(B,P,Acc) when P rem 2 == 0 ->
    pow(B*B,P div 2, Acc);
pow(B,P,Acc) ->
    pow(B,P-1,Acc*B).

test() ->
    I = pow(5,pow(4,pow(3,2))),
    S = integer_to_list(I),
    L = length(S),
    Prefix = lists:sublist(S,20),
    Suffix = lists:sublist(S,L-19,20),
    io:format("Length: ~b~nPrefix:~s~nSuffix:~s~n",[L,Prefix,Suffix]).


let () =
    let answer = 5I **(int (4I ** (int (3I ** 2))))
    let sans = answer.ToString()
    printfn "Length = %d, digits %s ... %s" sans.Length (sans.Substring(0,20)) (sans.Substring(sans.Length-20))
;;
Length = 183231, digits 62060698786608744707 ... 92256259918212890625


function agm(atom a, atom g, atom tolerance=1.0e-15)
    while abs(a-g)>tolerance do
        {a,g} = {(a + g)/2,sqrt(a*g)}
        printf(1,"%0.15g\n",a)
    end while
    return a
end function
?agm(1,1/sqrt(2))   -- (rounds to 10 d.p.)


<title>Archimedean spiral</title>

Archimedean spiral

<canvas id="canvId" width="640" height="640" style="border: 2px outset;"></canvas>


def spiral($zero; $turns; $step):

  def pi: 1 | atan * 4;
  def p2: (. * 100 | round) / 100;

  def svg:
    400 as $width
    | 400 as $height
    | 2 as $swidth # stroke
    | "blue" as $stroke
    | (range($zero; $turns * 2 * pi; $step) as $theta
       | (((($theta)|cos) * 2 * $theta + ($width/2)) |p2) as $x
       | (((($theta)|sin) * 2 * $theta + ($height/2))|p2) as $y
       | if $theta == $zero
         then "<path fill='transparent' style='stroke:\($stroke); stroke-width:\($swidth)' d='M \($x) \($y)"
         else " L \($x) \($y)"
         end),
      "' />";

  "<svg width='100%' height='100%'
        xmlns='http://www.w3.org/2000/svg'>",
        svg,
  "</svg>" ;

spiral(0; 10; 0.025)


using UnicodePlots

spiral(θ, a=0, b=1) = @. b * θ * cos(θ + a), b * θ * sin(θ + a)

x, y = spiral(1:0.1:10)
println(lineplot(x, y))


// version 1.1.0

import java.awt.*
import javax.swing.*

class ArchimedeanSpiral : JPanel() {
    init {
        preferredSize = Dimension(640, 640)
        background = Color.white
    }

    private fun drawGrid(g: Graphics2D) {
        g.color = Color(0xEEEEEE)
        g.stroke = BasicStroke(2f)
        val angle = Math.toRadians(45.0)
        val w = width
        val center = w / 2
        val margin = 10
        val numRings = 8
        val spacing = (w - 2 * margin) / (numRings * 2)

        for (i in 0 until numRings) {
            val pos = margin + i * spacing
            val size = w - (2 * margin + i * 2 * spacing)
            g.drawOval(pos, pos, size, size)
            val ia = i * angle
            val x2 = center + (Math.cos(ia) * (w - 2 * margin) / 2).toInt()
            val y2 = center - (Math.sin(ia) * (w - 2 * margin) / 2).toInt()
            g.drawLine(center, center, x2, y2)
        }
    }

    private fun drawSpiral(g: Graphics2D) {
        g.stroke = BasicStroke(2f)
        g.color = Color.magenta
        val degrees = Math.toRadians(0.1)
        val center = width / 2
        val end = 360 * 2 * 10 * degrees
        val a = 0.0
        val b = 20.0
        val c = 1.0
        var theta = 0.0
        while (theta < end) {
            val r = a + b * Math.pow(theta, 1.0 / c)
            val x = r * Math.cos(theta)
            val y = r * Math.sin(theta)
            plot(g, (center + x).toInt(), (center - y).toInt())
            theta += degrees
        }
    }

    private fun plot(g: Graphics2D, x: Int, y: Int) {
        g.drawOval(x, y, 1, 1)
    }

    override fun paintComponent(gg: Graphics) {
        super.paintComponent(gg)
        val g = gg as Graphics2D
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)
        drawGrid(g)
        drawSpiral(g)
    }
}

fun main(args: Array<String>) {
    SwingUtilities.invokeLater {
        val f = JFrame()
        f.defaultCloseOperation = JFrame.EXIT_ON_CLOSE
        f.title = "Archimedean Spiral"
        f.isResizable = false
        f.add(ArchimedeanSpiral(), BorderLayout.CENTER)
        f.pack()
        f.setLocationRelativeTo(null)
        f.isVisible = true
    }
}


USING: formatting kernel math.functions math.parser sequences ;
IN: rosettacode.bignums

: test-bignums ( -- )
    5 4 3 2 ^ ^ ^ number>string
    [ 20 head ] [ 20 tail* ] [ length ] tri
    "5^4^3^2 is %s...%s and has %d digits\n" printf ;


388c388
< CREATE big_string 256 CHARS ALLOT
---
> CREATE big_string 500000 CHARS ALLOT
394c394
<   big_string 256 CHARS + bighld ! ;  \ Haydon p 67
---
>   big_string 500000 CHARS + bighld ! ;  \ Haydon p 67
403c403
<   big_string 256 CHARS +     \ One past end of string
---
>   big_string 500000 CHARS +  \ One past end of string


program bignum
    use fmzm
    implicit none
    type(im) :: a
    integer :: n

    call fm_set(50)
    a = to_im(5)**(to_im(4)**(to_im(3)**to_im(2)))
    n = to_int(floor(log10(to_fm(a))))
    call im_print(a / to_im(10)**(n - 19))
    call im_print(mod(a, to_im(10)**20))
end program


#Include once "gmp.bi"
Dim Shared As Zstring * 100000000 outtext

Function  Power(number As String,n As Uinteger) As String'automate precision
    #define dp 3321921
    Dim As __mpf_struct _number,FloatAnswer
    Dim As Ulongint ln=Len(number)*(n)*4
    If ln>dp Then ln=dp
    mpf_init2(@FloatAnswer,ln)
    mpf_init2(@_number,ln)
    mpf_set_str(@_number,number,10)
    mpf_pow_ui(@Floatanswer,@_number,n)
    gmp_sprintf( @outtext,"%." & Str(n) & "Ff",@FloatAnswer )
    Var outtxt=Trim(outtext)
    If Instr(outtxt,".") Then outtxt= Rtrim(outtxt,"0"):outtxt=Rtrim(outtxt,".")
    Return Trim(outtxt)
End Function

Extern gmp_version Alias "__gmp_version" As Zstring Ptr
Print "GMP version ";*gmp_version
Print

var ans=power("5",(4^(3^2)))
Print Left(ans,20) + " ... "+Right(ans,20)
Print "Number of digits ";Len(ans)
Sleep


package main

import (
    "fmt"
    "math"
    "math/big"
)

func main() {
    var recip big.Rat
    max := int64(1 << 19)
    for candidate := int64(2); candidate < max; candidate++ {
        sum := big.NewRat(1, candidate)
        max2 := int64(math.Sqrt(float64(candidate)))
        for factor := int64(2); factor <= max2; factor++ {
            if candidate%factor == 0 {
                sum.Add(sum, recip.SetFrac64(1, factor))
                if f2 := candidate / factor; f2 != factor {
                    sum.Add(sum, recip.SetFrac64(1, f2))
                }
            }
        }
        if sum.Denom().Int64() == 1 {
            perfectstring := ""
            if sum.Num().Int64() == 1 {
                perfectstring = "perfect!"
            }
            fmt.Printf("Sum of recipr. factors of %d = %d exactly %s\n",
                candidate, sum.Num().Int64(), perfectstring)
        }
    }
}


include ..\Utilitys.pmt

1.0e-15 var tolerance

def test
    over over - abs tolerance >
enddef

def agm /# n1 n2 -- n3 #/
    test while
        over over + 2 / rot rot * sqrt
    test endwhile
enddef

1 1 2 sqrt / agm tostr ?


define('PRECISION', 13);

function agm($a0, $g0, $tolerance = 1e-10)
{
    // the bc extension deals in strings and cannot convert
    // floats in scientific notation by itself - hence
    // this manual conversion to a string
    $limit = number_format($tolerance, PRECISION, '.', '');
    $an    = $a0;
    $gn    = $g0;
    do {
        list($an, $gn) = array(
            bcdiv(bcadd($an, $gn), 2),
            bcsqrt(bcmul($an, $gn)),
        );
    } while (bccomp(bcsub($an, $gn), $limit) > 0);

    return $an;
}

bcscale(PRECISION);
echo agm(1, 1 / bcsqrt(2));


a=1
b=2
cycles=40
step=0.001
x=0
y=0

function love.load()
     x = love.graphics.getWidth()/2
     y = love.graphics.getHeight()/2
end

function love.draw()
     love.graphics.print("a="..a,16,16)
     love.graphics.print("b="..b,16,32)

     for i=0,cycles*math.pi,step do
          love.graphics.points(x+(a + b*i)*math.cos(i),y+(a + b*i)*math.sin(i))
     end
end


module Archimedean_spiral {
	smooth on ' enable GDI+
	def r(θ)=5+3*θ
	cls #002222,0
	pen #FFFF00
	refresh 5000
	every 1000 {
		\\ redifine window (console width and height) and place it to center (symbol ;)
		Window 12, random(10, 18)*1000, random(8, 12)*1000;
		move scale.x/2, scale.y/2
		let N=2, k1=pi/120, k=k1, op=5, op1=1
		for i=1 to int(1200*min.data(scale.x, scale.y)/18000)
			pen op
			swap op, op1
			Width 3 {draw angle k, r(k)*n}
			k+=k1
		next
		refresh 5000
		\\ press space to exit loop
		if  keypress(32) then exit
	}
	pen 14
	cls 5
	refresh 50
}
Archimedean_spiral


plots[polarplot](1+2*theta, theta = 0 .. 6*Pi)


With[{a = 5, b = 4}, PolarPlot[a + b t, {t, 0, 10 Pi}]]


a = 5^4^3^2
as = "$a"     // Coerce to string
println["Length=" + length[as] + ", " + left[as,20] + "..." + right[as,20]]


package main

import (
	"fmt"
	"math/big"
)

func main() {
	x := big.NewInt(2)
	x = x.Exp(big.NewInt(3), x, nil)
	x = x.Exp(big.NewInt(4), x, nil)
	x = x.Exp(big.NewInt(5), x, nil)
	str := x.String()
	fmt.Printf("5^(4^(3^2)) has %d digits: %s ... %s\n",
		len(str),
		str[:20],
		str[len(str)-20:],
	)
}


class Rational extends Number implements Comparable {
    final BigInteger num, denom

    static final Rational ONE = new Rational(1)
    static final Rational ZERO = new Rational(0)

    Rational(BigDecimal decimal) {
        this(
        decimal.scale() < 0 ? decimal.unscaledValue() * 10 ** -decimal.scale() : decimal.unscaledValue(),
        decimal.scale() < 0 ? 1                                                : 10 ** decimal.scale()
        )
    }

    Rational(BigInteger n, BigInteger d = 1) {
        if (!d || n == null) { n/d }
        (num, denom) = reduce(n, d)
    }

    private List reduce(BigInteger n, BigInteger d) {
        BigInteger sign = ((n < 0) ^ (d < 0)) ? -1 : 1
        (n, d) = [n.abs(), d.abs()]
        BigInteger commonFactor = gcd(n, d)

        [n.intdiv(commonFactor) * sign, d.intdiv(commonFactor)]
    }

    Rational toLeastTerms() { reduce(num, denom) as Rational }

    private BigInteger gcd(BigInteger n, BigInteger m) {
        n == 0 ? m : { while(m%n != 0) { (n, m) = [m%n, n] }; n }()
    }

    Rational plus(Rational r) { [num*r.denom + r.num*denom, denom*r.denom] }
    Rational plus(BigInteger n) { [num + n*denom, denom] }
    Rational plus(Number n) { this + ([n] as Rational) }

    Rational next() { [num + denom, denom] }

    Rational minus(Rational r) { [num*r.denom - r.num*denom, denom*r.denom] }
    Rational minus(BigInteger n) { [num - n*denom, denom] }
    Rational minus(Number n) { this - ([n] as Rational) }

    Rational previous() { [num - denom, denom] }

    Rational multiply(Rational r) { [num*r.num, denom*r.denom] }
    Rational multiply(BigInteger n) { [num*n, denom] }
    Rational multiply(Number n) { this * ([n] as Rational) }

    Rational div(Rational r) { new Rational(num*r.denom, denom*r.num) }
    Rational div(BigInteger n) { new Rational(num, denom*n) }
    Rational div(Number n) { this / ([n] as Rational) }

    BigInteger intdiv(BigInteger n) { num.intdiv(denom*n) }

    Rational negative() { [-num, denom] }

    Rational abs() { [num.abs(), denom] }

    Rational reciprocal() { new Rational(denom, num) }

    Rational power(BigInteger n) {
        def (nu, de) = (n < 0 ? [denom, num] : [num, denom])*.power(n.abs())
        new Rational (nu, de)
    }

    boolean asBoolean() { num != 0 }

    BigDecimal toBigDecimal() { (num as BigDecimal)/(denom as BigDecimal) }

    BigInteger toBigInteger() { num.intdiv(denom) }

    Double toDouble() { toBigDecimal().toDouble() }
    double doubleValue() { toDouble() as double }

    Float toFloat() { toBigDecimal().toFloat() }
    float floatValue() { toFloat() as float }

    Integer toInteger() { toBigInteger().toInteger() }
    int intValue() { toInteger() as int }

    Long toLong() { toBigInteger().toLong() }
    long longValue() { toLong() as long }

    Object asType(Class type) {
        switch (type) {
            case this.class:              return this
            case [Boolean, Boolean.TYPE]: return asBoolean()
            case BigDecimal:              return toBigDecimal()
            case BigInteger:              return toBigInteger()
            case [Double, Double.TYPE]:   return toDouble()
            case [Float, Float.TYPE]:     return toFloat()
            case [Integer, Integer.TYPE]: return toInteger()
            case [Long, Long.TYPE]:       return toLong()
            case String:                  return toString()
            default: throw new ClassCastException("Cannot convert from type Rational to type " + type)
        }
    }

    boolean equals(o) { compareTo(o) == 0 }

    int compareTo(o) {
        o instanceof Rational
            ? compareTo(o as Rational)
            : o instanceof Number
                ? compareTo(o as Number)
                : (Double.NaN as int)
    }
    int compareTo(Rational r) { num*r.denom <=> denom*r.num }
    int compareTo(Number n) { num <=> denom*(n as BigInteger) }

    int hashCode() { [num, denom].hashCode() }

    String toString() {
        "${num}//${denom}"
    }
}


arithmetic_geometric_mean:           /* 31 August 2012 */
   procedure options (main);
   declare (a, g, t) float (18);

   a = 1; g = 1/sqrt(2.0q0);
   put skip list ('The arithmetic-geometric mean of ' || a || ' and ' || g || ':');
   do until (abs(a-g) < 1e-15*a);
      t = (a + g)/2; g = sqrt(a*g);
      a = t;
      put skip data (a, g);
   end;
   put skip list ('The result is:', a);
end arithmetic_geometric_mean;


sqrt = (x) :
   xi = 1
   7 times :
      xi = (xi + x / xi) / 2
   .
   xi
.

agm = (x, y) :
   7 times :
      a = (x + y) / 2
      g = sqrt(x * y)
      x = a
      y = g
   .
   x
.


function agm ([Double]$a, [Double]$g) {
    [Double]$eps = 1E-15
    [Double]$a1 = [Double]$g1 = 0
    while([Math]::Abs($a - $g) -gt $eps) {
        $a1, $g1 = $a, $g
        $a = ($a1 + $g1)/2
        $g = [Math]::Sqrt($a1*$g1)
    }
    [pscustomobject]@{
        a = "$a"
        g = "$g"
    }
}
agm 1 (1/[Math]::Sqrt(2))


a = 1;
b = 1;
turns = 2;
theta = 0:0.1:2*turns*pi;
polarplot(theta, a + b*theta);


import math

import gintro/[glib, gobject, gtk, gio, cairo]

const

  Width = 601
  Height = 601

  Limit = 12 * math.PI

  Origin = (x: float(Width div 2), y: float(Height div 2))
  B = floor((Width div 2) / Limit)

#---------------------------------------------------------------------------------------------------

proc draw(area: DrawingArea; context: Context) =
  ## Draw the spiral.

  var theta = 0.0
  var delta = 0.01
  var (prevx, prevy) = Origin

  # Clear the region.
  context.moveTo(0, 0)
  context.setSource(0.0, 0.0, 0.0)
  context.paint()

  # Draw the spiral.
  context.setSource(1.0, 1.0, 0.0)
  context.moveTo(Origin.x, Origin.y)
  while theta < Limit:
    let r = B * theta
    let x = Origin.x + r * cos(theta)   # X-coordinate on drawing area.
    let y = Origin.y + r * sin(theta)   # Y-coordinate on drawing area.
    context.lineTo(x, y)
    context.stroke()
    # Set data for next round.
    context.moveTo(x, y)
    prevx = x
    prevy = y
    theta += delta

#---------------------------------------------------------------------------------------------------

proc onDraw(area: DrawingArea; context: Context; data: pointer): bool =
  ## Callback to draw/redraw the drawing area contents.

  area.draw(context)
  result = true

#---------------------------------------------------------------------------------------------------

proc activate(app: Application) =
  ## Activate the application.

  let window = app.newApplicationWindow()
  window.setSizeRequest(Width, Height)
  window.setTitle("Archimedean spiral")

  # Create the drawing area.
  let area = newDrawingArea()
  window.add(area)

  # Connect the "draw" event to the callback to draw the spiral.
  discard area.connect("draw", ondraw, pointer(nil))

  window.showAll()

#———————————————————————————————————————————————————————————————————————————————————————————————————

let app = newApplication(Application, "Rosetta.spiral")
discard app.connect("activate", activate)
discard app.run()


\\ The Archimedean spiral
\\ ArchiSpiral() - Where: lps is a number of loops, c is a direction 0/1
\\ (counter-clockwise/clockwise). 6/6/16 aev
\\ Note: cartes2() can be found here on
\\ http://rosettacode.org/wiki/Polyspiral#PARI.2FGP page.
ArchiSpiral(size,lps,c=0)={
my(a=.0,ai=.1,r=.0,ri=.1,as=lps*2*Pi,n=as/ai,x,y,vc,vx=List(.0),vy=vx);
if(c<0||c>1, c=0); if(c, ai*=-1);
print(" *** The Archimedean spiral: size=",size," loops=",lps," c=",c);
for(i=1, n, vc=cartes2(r,a); x=vc[1]; y=vc[2];
    listput(vx,x); listput(vy,y);
    r+=ri; a+=ai;
);\\fend i
plothraw(Vec(vx),Vec(vy));
}
{\\ Executing:
ArchiSpiral(640,5);   \\ArchiSpiral1.png
ArchiSpiral(640,5,1); \\ArchiSpiral2.png
}


5 4 3 2???  # Calculate 5^(4^(3^2))
`..         # Convert to string and make two copies
20<p        # Print the first 20 digits
-20>p       # Print the last 20 digits
,p          # Print the length


main :: IO ()
main = do
  let y = show (5 ^ 4 ^ 3 ^ 2)
  let l = length y
  putStrLn
    ("5**4**3**2 = " ++
     take 20 y ++ "..." ++ drop (l - 20) y ++ " and has " ++ show l ++ " digits")


=+  big=(pow 5 (pow 4 (pow 3 2)))
=+  digits=(lent (skip <big> |=(a/* ?:(=(a '.') & |))))
[digits (div big (pow 10 (sub digits 20))) (mod big (pow 10 20))]


import Data.Ratio ((%))

-- Prints the first N perfect numbers.
main = do
  let n = 4
  mapM_ print $
    take
      n
      [ candidate
      | candidate <- [2 .. 2 ^ 19]
      , getSum candidate == 1 ]
  where
    getSum candidate =
      1 % candidate +
      sum
        [ 1 % factor + 1 % (candidate `div` factor)
        | factor <- [2 .. floor (sqrt (fromIntegral candidate))]
        , candidate `mod` factor == 0 ]


procedure main()
   limit := 2^19

   write("Perfect numbers up to ",limit," (using rational arithmetic):")
   every write(is_perfect(c := 2 to limit))
   write("End of perfect numbers")

   # verify the rest of the implementation

   zero := makerat(0)          # from integer
   half := makerat(0.5)        # from real
   qtr  := makerat("1/4")      # from strings ...
   one  := makerat("1")
   mone := makerat("-1")

   verifyrat("eqrat",zero,zero)
   verifyrat("ltrat",zero,half)
   verifyrat("ltrat",half,zero)
   verifyrat("gtrat",zero,half)
   verifyrat("gtrat",half,zero)
   verifyrat("nerat",zero,half)
   verifyrat("nerat",zero,zero)
   verifyrat("absrat",mone,)

end

procedure is_perfect(c)       #: test for perfect numbers using rational arithmetic
   rsum := rational(1, c, 1)
   every f := 2 to sqrt(c) do
      if 0 = c % f then
         rsum := addrat(rsum,addrat(rational(1,f,1),rational(1,integer(c/f),1)))
   if rsum.numer = rsum.denom = 1 then
      return c
end


Procedure.d AGM(a.d, g.d, ErrLim.d=1e-15)
  Protected.d ta=a+1, tg
  While ta <> a
    ta=a: tg=g
    a=(ta+tg)*0.5
    g=Sqr(ta*tg)
  Wend
  ProcedureReturn a
EndProcedure

If OpenConsole()
  PrintN(StrD(AGM(1, 1/Sqr(2)), 16))
  Input()
  CloseConsole()
EndIf


use Imager;
use constant PI => 3.14159265;

my ($w, $h) = (400, 400);
my $img = Imager->new(xsize => $w, ysize => $h);

for ($theta = 0; $theta < 52*PI; $theta += 0.025) {
    $x = $w/2 + $theta * cos($theta/PI);
    $y = $h/2 + $theta * sin($theta/PI);
    $img->setpixel(x => $x, y => $y, color => '#FF00FF');
}

$img->write(file => 'Archimedean-spiral.png');


--
-- demo\rosetta\Archimedean_spiral.exw
-- ===================================
--
with javascript_semantics
include pGUI.e

Ihandle dlg, canvas
cdCanvas cddbuffer, cdcanvas

function redraw_cb(Ihandle /*ih*/)
    integer {w, h} = IupGetIntInt(canvas, "DRAWSIZE"),
            a = 0, b = 5, cx = floor(w/2), cy = floor(h/2)
    cdCanvasActivate(cddbuffer)
    for deg=0 to 360*7 do
        atom rad = deg*PI/180,
             r = rad*b + a
        integer x = cx + floor(r*cos(rad)),
                y = cy + floor(r*sin(rad))
        cdCanvasPixel(cddbuffer, x, y, #00FF00)
    end for
    cdCanvasFlush(cddbuffer)
    return IUP_DEFAULT
end function

function map_cb(Ihandle ih)
    cdcanvas = cdCreateCanvas(CD_IUP, ih)
    cddbuffer = cdCreateCanvas(CD_DBUFFER, cdcanvas)
    cdCanvasSetBackground(cddbuffer, CD_WHITE)
    cdCanvasSetForeground(cddbuffer, CD_RED)
    return IUP_DEFAULT
end function

procedure main()
    IupOpen()
    canvas = IupCanvas("RASTERSIZE=500x500") -- initial size
    IupSetCallbacks(canvas, {"MAP_CB", Icallback("map_cb"),
                             "ACTION", Icallback("redraw_cb")})
    dlg = IupDialog(canvas,`TITLE="Archimedean spiral"`)
    IupShow(dlg)
    IupSetAttribute(canvas, "RASTERSIZE", NULL) -- release the minimum limitation
    if platform()!=JS then
        IupMainLoop()
        IupClose()
    end if
end procedure

main()


procedure main()
    x := 5^4^3^2
    write("done with computation")
    x := string(x)
    write("5 ^ 4 ^ 3 ^ 2 has ",*x," digits")
    write("The first twenty digits are ",x[1+:20])
    write("The last twenty digits are  ",x[0-:20])
end


import java.math.BigInteger;

class IntegerPower {
    public static void main(String[] args) {
        BigInteger power = BigInteger.valueOf(5).pow(BigInteger.valueOf(4).pow(BigInteger.valueOf(3).pow(2).intValueExact()).intValueExact());
        String str = power.toString();
        int len = str.length();
        System.out.printf("5**4**3**2 = %s...%s and has %d digits%n",
                str.substring(0, 20), str.substring(len - 20), len);
    }
}


public class BigRationalFindPerfectNumbers {
    public static void main(String[] args) {
        int MAX_NUM = 1 << 19;
        System.out.println("Searching for perfect numbers in the range [1, " + (MAX_NUM - 1) + "]");

        BigRational TWO = BigRational.valueOf(2);
        for (int i = 1; i < MAX_NUM; i++) {
            BigRational reciprocalSum = BigRational.ONE;
            if (i > 1)
                reciprocalSum = reciprocalSum.add(BigRational.valueOf(i).reciprocal());
            int maxDivisor = (int) Math.sqrt(i);
            if (maxDivisor >= i)
                maxDivisor--;

            for (int divisor = 2; divisor <= maxDivisor; divisor++) {
                if (i % divisor == 0) {
                    reciprocalSum = reciprocalSum.add(BigRational.valueOf(divisor).reciprocal());
                    int dividend = i / divisor;
                    if (divisor != dividend)
                        reciprocalSum = reciprocalSum.add(BigRational.valueOf(dividend).reciprocal());
                }
            }
            if (reciprocalSum.equals(TWO))
                System.out.println(String.valueOf(i) + " is a perfect number");
        }
    }
}


from math import sqrt

def agm(a0, g0, tolerance=1e-10):
    """
    Calculating the arithmetic-geometric mean of two numbers a0, g0.

    tolerance     the tolerance for the converged
                  value of the arithmetic-geometric mean
                  (default value = 1e-10)
    """
    an, gn = (a0 + g0) / 2.0, sqrt(a0 * g0)
    while abs(an - gn) > tolerance:
        an, gn = (an + gn) / 2.0, sqrt(an * gn)
    return an

print agm(1, 1 / sqrt(2))


  [ $ "bigrat.qky" loadfile ] now!

  [ temp put
    [ 2over 2over temp share approx=
      iff 2drop done
      2over 2over v*
      temp share vsqrt drop
      dip [ dip [ v+ 2 n->v v/ ] ]
      again ]
    base share temp take ** round ]  is agm ( n/d n/d n --> n/d )

  1 n->v
  2 n->v 125 vsqrt drop 1/v
  125 agm
  2dup
  125 point$ echo$ cr cr
  swap say "Num: " echo cr
  say      "Den: " echo


arithmeticMean <- function(a, b) { (a + b)/2 }
geometricMean <- function(a, b) { sqrt(a * b) }

arithmeticGeometricMean <- function(a, b) {
  rel_error <- abs(a - b) / pmax(a, b)
  if (all(rel_error < .Machine$double.eps, na.rm=TRUE)) {
    agm <- a
    return(data.frame(agm, rel_error));
  }
  Recall(arithmeticMean(a, b), geometricMean(a, b))
}

agm <- arithmeticGeometricMean(1, 1/sqrt(2))
print(format(agm, digits=16))


#lang racket
(define (agm a g [ε 1e-15])
  (if (<= (- a g) ε)
      a
      (agm (/ (+ a g) 2) (sqrt (* a g)) ε)))

(agm 1 (/ 1 (sqrt 2)))


float x, y;
float theta;
float rotation;

void setup() {
  size(300, 300);
  theta = 0;
  rotation = 0.1;
  background(255);
}

void draw() {
  translate(width/2.0, height/2.0);
  x = theta*cos(theta/PI);
  y = theta*sin(theta/PI);
  point(x, y);
  theta = theta + rotation;
  // check restart
  if (x>width/2.0) frameCount=-1;
}


#MAXLOOP  = 7*360
#XCENTER  = 640/2
#YCENTER  = 480/2
#SCALAR   = 200

If OpenWindow(0, 100, 200, 640, 480, "Archimedean spiral")
  If CreateImage(0, 640, 480,24,RGB(255,255,255))
    If StartDrawing(ImageOutput(0))
      i.f=0.0
      While i<=#MAXLOOP
        x.f=#XCENTER+Cos(Radian(i))*#SCALAR*i/#MAXLOOP
        y.f=#YCENTER+Sin(Radian(i))*#SCALAR*i/#MAXLOOP
        Plot(x,y,RGB(50,50,50))
        i+0.05
      Wend
      StopDrawing()
    EndIf
  EndIf
  ImageGadget(0, 0, 0, 0, 0, ImageID(0))
  Repeat : Event = WaitWindowEvent() : Until Event = #PB_Event_CloseWindow
EndIf
End


from turtle import *
from math import *
color("blue")
down()
for i in range(200):
    t = i / 20 * pi
    x = (1 + 5 * t) * cos(t)
    y = (1 + 5 * t) * sin(t)
    goto(x, y)
up()
done()


  [ $ "turtleduck.qky" loadfile ] now!
  turtle
  0 n->v
  900 times
    [ 2dup walk
      1 20 v+
      1 36 turn ]
  2drop


def power($b): . as $in | reduce range(0;$b) as $i (1; . * $in);

5|power(4|power(3|power(2))) | tostring
| .[:20], .[-20:], length


import java.math.BigInteger

fun main(args: Array<String>) {
    val x = BigInteger.valueOf(5).pow(Math.pow(4.0, 3.0 * 3.0).toInt())
    val y = x.toString()
    val len = y.length
    println("5^4^3^2 = ${y.substring(0, 20)}...${y.substring(len - 20)} and has $len digits")
}


// the constructor
function Rational(numerator, denominator) {
    if (denominator === undefined)
        denominator = 1;
    else if (denominator == 0)
        throw "divide by zero";

    this.numer = numerator;
    if (this.numer == 0)
        this.denom = 1;
    else
        this.denom = denominator;

    this.normalize();
}

// getter methods
Rational.prototype.numerator   = function() {return this.numer};
Rational.prototype.denominator = function() {return this.denom};

// clone a rational
Rational.prototype.dup = function() {
    return new Rational(this.numerator(), this.denominator());
};

// conversion methods
Rational.prototype.toString = function() {
    if (this.denominator() == 1) {
        return this.numerator().toString();
    } else {
        // implicit conversion of numbers to strings
        return this.numerator() + '/' + this.denominator()
    }
};
Rational.prototype.toFloat  = function() {return eval(this.toString())}
Rational.prototype.toInt    = function() {return Math.floor(this.toFloat())};

// reduce
Rational.prototype.normalize = function() {
    // greatest common divisor
    var a=Math.abs(this.numerator()), b=Math.abs(this.denominator())
    while (b != 0) {
        var tmp = a;
        a = b;
        b = tmp % b;
    }
    // a is the gcd

    this.numer /= a;
    this.denom /= a;
    if (this.denom < 0) {
        this.numer *= -1;
        this.denom *= -1;
    }
    return this;
}

// absolute value
// returns a new rational
Rational.prototype.abs = function() {
    return new Rational(Math.abs(this.numerator()), this.denominator());
};

// inverse
// returns a new rational
Rational.prototype.inv = function() {
    return new Rational(this.denominator(), this.numerator());
};

//
// arithmetic methods

// variadic, modifies receiver
Rational.prototype.add = function() {
    for (var i = 0; i < arguments.length; i++) {
        this.numer = this.numer * arguments[i].denominator() + this.denom * arguments[i].numerator();
        this.denom = this.denom * arguments[i].denominator();
    }
    return this.normalize();
};

// variadic, modifies receiver
Rational.prototype.subtract = function() {
    for (var i = 0; i < arguments.length; i++) {
        this.numer = this.numer * arguments[i].denominator() - this.denom * arguments[i].numerator();
        this.denom = this.denom * arguments[i].denominator();
    }
    return this.normalize();
};

// unary "-" operator
// returns a new rational
Rational.prototype.neg = function() {
    return (new Rational(0)).subtract(this);
};

// variadic, modifies receiver
Rational.prototype.multiply = function() {
    for (var i = 0; i < arguments.length; i++) {
        this.numer *= arguments[i].numerator();
        this.denom *= arguments[i].denominator();
    }
    return this.normalize();
};

// modifies receiver
Rational.prototype.divide = function(rat) {
    return this.multiply(rat.inv());
}

// increment
// modifies receiver
Rational.prototype.inc = function() {
    this.numer += this.denominator();
    return this.normalize();
}

// decrement
// modifies receiver
Rational.prototype.dec = function() {
    this.numer -= this.denominator();
    return this.normalize();
}

//
// comparison methods

Rational.prototype.isZero = function() {
    return (this.numerator() == 0);
}
Rational.prototype.isPositive = function() {
    return (this.numerator() > 0);
}
Rational.prototype.isNegative = function() {
    return (this.numerator() < 0);
}

Rational.prototype.eq = function(rat) {
    return this.dup().subtract(rat).isZero();
}
Rational.prototype.ne = function(rat) {
    return !(this.eq(rat));
}
Rational.prototype.lt = function(rat) {
    return this.dup().subtract(rat).isNegative();
}
Rational.prototype.gt = function(rat) {
    return this.dup().subtract(rat).isPositive();
}
Rational.prototype.le = function(rat) {
    return !(this.gt(rat));
}
Rational.prototype.ge = function(rat) {
    return !(this.lt(rat));
}


sub agm( $a is copy, $g is copy ) {
    ($a, $g) = ($a + $g)/2, sqrt $a * $g until $a ≅ $g;
    return $a;
}

say agm 1, 1/sqrt 2;


define agm  use  $a, $g, $errlim
    # $errlim $g $a "%d %g %d\n" print
    $a 1.0  +   as $t
    repeat $a 1.0 * $g - abs -15 exp10 $a *  >   while
        $a $g + 2 /   as $t
        $a $g * sqrt  as $g
        $t as $a
        $g $a $t  "t: %g a: %g g: %g\n" print
    $a

16   1 2 sqrt /   1   agm   "agm: %.15g\n" print


function agm(x,y)
set a = x
set g = y
while abs(a - g) > 0.00000000001
set an = (a + g)/2
set gn = sqrt(a * g)
set a = an
set g = gn
set i = i + 1
end while
set result = g
end function

set x = 1
set y = 1/sqrt(2)
echo (x + y)/2
echo sqrt(x+y)
echo agm(x,y)


with(list(s=seq(0, 10 * pi, length.out=500)),
     plot((1 + s) * exp(1i * s), type="l"))


#lang racket/base
(require plot
         racket/math)

;; x and y bounds set to centralise the circle
(define (archemedian-spiral-renderer2d a b θ/τ-max
                                       #:samples (samples (line-samples)))
  (define (f θ) (+ a (* b θ)))
  (define max-dim (+ a (* θ/τ-max 2 pi b)))
  (polar f
      0 (* θ/τ-max 2 pi)
      #:x-min (- max-dim)
      #:x-max max-dim
      #:y-min (- max-dim)
      #:y-max  max-dim
      #:samples samples))

(plot (list (archemedian-spiral-renderer2d 0.0 24  4)))

;; writes to a file so hopefully, I can post it to RC...
(plot-file (list (archemedian-spiral-renderer2d 0.0 24  4))
           "images/archemidian-spiral-racket.png")


use Image::PNG::Portable;

my ($w, $h) = (400, 400);

my $png = Image::PNG::Portable.new: :width($w), :height($h);

(0, .025 ... 52*π).race.map: -> \Θ {
    $png.set: |((cis( Θ / π ) * Θ).reals »+« ($w/2, $h/2))».Int, 255, 0, 255;
}

$png.write: 'Archimedean-spiral-perl6.png';


/*REXX pgm plots several cycles (half a spiral) of the  Archimedean spiral (ASCII plot).*/
parse arg cy a b inc chr .                       /*obtain optional arguments from the CL*/
if  cy=='' |  cy==","   then  cy= 3              /*Not specified?  Then use the default.*/
if   a=='' |   a==","   then   a= 1              /* "      "         "   "   "     "    */
if   b=='' |   b==","   then   b= 9              /* "      "         "   "   "     "    */
if inc=='' | inc==","   then inc= 0.02           /* "      "         "   "   "     "    */
if chr=='' | chr==","   then chr= '∙'            /* "      "         "   "   "     "    */
if length(chr)==3  then chr= d2c(chr)            /*plot character coded in     decimal? */
if length(chr)==2  then chr= x2c(chr)            /*  "      "       "    " hexadecimal? */
cy= max(2, cy);         LOx= .                   /*set the  LOx  variable (a semaphore).*/
parse value scrsize()   with   sd  sw  .         /*get the size of the terminal screen. */
w= sw - 1        ;      mw= w * (cy-1) * 4       /*set useable width; max width for calc*/
h= sd - 1 + cy*10;      mh= h * (cy-1)           /* "     "    depth;  "  depth  "   "  */
@.=                                              /*initialize the line based plot field.*/
         do t=1  to pi()*cy  by inc              /*calc all the coördinates for spiral. */
         r= a +  b*    t                         /*  "   "   "       R       "    "     */
         x= w +  r*cos(t);     xx= x % 2         /*  "   "   "       X       "    "     */
         y= h +  r*sin(t);     yy= y % 2         /*  "   "   "       Y       "    "     */
         if x<0 | y<0 | x>mw | y>mh then iterate /*Is X or Y  out of bounds?  Then skip.*/
         if LOx==.  then do;   LOx= xx;      HIx= xx;      LOy= yy;       HIy= yy
                         end                     /* [↑]  find the minimums and maximums.*/
         LOx= min(LOx, xx);    HIx= max(HIx, xx) /*determine the   X   MIN  and  MAX.   */
         LOy= min(LOy, yy);    HIy= max(HIy, yy) /*    "      "    Y    "    "    "     */
         @.yy= overlay(chr, @.yy, xx+1)          /*assign the plot character (glyph).   */
         end   /*t*/
call plot                                        /*invoke plotting subroutine (to term).*/
exit                                             /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
pi:   pi=3.1415926535897932384626433832795028841971693993751058209749445923078; return pi
plot:      do row=HIy  to LOy  by -1;   say substr(@.row, LOx+1);   end;        return
r2r:  return arg(1)  //  (pi() * 2)             /*normalize radians ───► a unit circle.*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
cos:  procedure; parse arg x;  x= r2r(x);  _= 1;  a= abs(x);    hpi= pi * .5
      numeric fuzz  min(6, digits() - 3);         if a=pi       then return -1
      if a=hpi | a=hpi*3  then return  0          if a=pi / 3   then return .5
      if a=pi * 2 / 3     then return -.5;        q= x*x;       z= 1
        do k=2  by 2  until p=z;   p= z;   _= -_ *q/(k*k-k);    z= z+_;   end;    return z
/*──────────────────────────────────────────────────────────────────────────────────────*/
sin:  procedure; parse arg x;  x= r2r(x);  _= x;  numeric fuzz min(5, max(1, digits() -3))
      if x=pi * .5         then return 1;         if x==pi*1.5  then return -1
      if abs(x)=pi | x=0   then return 0;         q= x*x;       z= x
        do k=2  by 2  until p=z;   p= z;   _= -_ *q/(k*k+k);    z= z+_;   end;    return z


define integer->pow(factor::integer) => {
    #factor <= 0
        ? return 0

    local(retVal) = 1

    loop(#factor) => { #retVal *= self }

    return #retVal
}

local(bigint) = string(5->pow(4->pow(3->pow(2))))
#bigint->sub(1,20) + ` ... ` + #bigint->sub(#bigint->size - 19)
"\n"
`Number of digits: ` + #bigint->size


bc = require("bc")
-- since 5$=5^4$, and IEEE754 can handle 4$, this would be sufficient:
-- n = bc.pow(bc.new(5), bc.new(4^3^2))
-- but for this task:
n = bc.pow(bc.new(5), bc.pow(bc.new(4), bc.pow(bc.new(3), bc.new(2))))
s = n:tostring()
print(string.format("%s...%s (%d digits)", s:sub(1,20), s:sub(-20,-1), #s))


# a and b are assumed to be non-zero integers
def gcd(a; b):
  # subfunction expects [a,b] as input
  # i.e. a ~ .[0] and b ~ .[1]
  def rgcd: if .[1] == 0 then .[0]
         else [.[1], .[0] % .[1]] | rgcd
         end;
  [a,b] | rgcd;

# To take advantage of gojq's support for accurate integer division:
def idivide($j):
  . as $i
  | ($i % $j) as $mod
  | ($i - $mod) / $j ;

# To take advantage of gojq's arbitrary-precision integer arithmetic:
def power($b): . as $in | reduce range(0;$b) as $i (1; . * $in);

# $p should be an integer or a rational
# $q should be a non-zero integer or a rational
# Output:  a Rational: $p // $q
def r($p;$q):
  def r: if type == "number" then {n: ., d: 1} else . end;
  # The remaining subfunctions assume all args are Rational
  def n: if .d < 0 then {n: -.n, d: -.d} else . end;
  def rdiv($a;$b):
    ($a.d * $b.n) as $denom
    | if $denom==0 then "r: division by 0" | error
    else r($a.n * $b.d; $denom)
    end;
  if $q == 1 and ($p|type) == "number" then {n: $p, d: 1}
  elif $q == 0 then "r: denominator cannot be 0" | error
  else if ($p|type == "number") and ($q|type == "number")
       then gcd($p;$q) as $g
       | {n: ($p/$g), d: ($q/$g)} | n
       else rdiv($p|r; $q|r)
       end
  end;

# Polymorphic (integers and rationals in general)
def requal($a; $b):
  if $a | type == "number" and $b | type == "number" then $a == $b
  else r($a;1) == r($b;1)
  end;

# Input: a Rational
# Output: a Rational with a denominator that has no more than $digits digits
# and such that |rBefore - rAfter| < 1/(10|power($digits)
# where $digits should be a positive integer.
def rround($digits):
  if .d | length > $digits
  then (10|power($digits)) as $p
  | .d as $d
  | r($p * .n | idivide($d); $p)
  else . end;

# Polymorphic; see also radd/0
def radd($a; $b):
  def r: if type == "number" then {n: ., d: 1} else . end;
    ($a|r) as {n: $na, d: $da}
  | ($b|r) as {n: $nb, d: $db}
  | r( ($na * $db) + ($nb * $da); $da * $db );

# Polymorphic; see also rmult/0
def rmult($a; $b):
  def r: if type == "number" then {n: ., d: 1} else . end;
    ($a|r) as {n: $na, d: $da}
  | ($b|r) as {n: $nb, d: $db}
  | r( $na * $nb; $da * $db ) ;

# Input: an array of rationals (integers and/or Rationals)
# Output: a Rational computed using left-associativity
def rmult:
  if length == 0 then r(1;1)
  elif length == 1 then r(.[0]; 1)  # ensure the result is Rational
  else .[0] as $first
  | reduce .[1:][] as $x ($first; rmult(.; $x))
  end;

# Input: an array of rationals (integers and/or Rationals)
# Output: a Rational computed using left-associativity
def radd:
  if length == 0 then r(0;1)
  elif length == 1 then r(.[0]; 1) # ensure the result is Rational
  else .[0] as $first
  | reduce .[1:][] as $x ($first; radd(. ; $x))
  end;

def rabs: r(.;1) | r(.n|length; .d|length);

def rminus: r(-1 * .n; .d);

def rminus($a; $b): radd($a; rmult(-1; $b));

# Note that rinv does not check for division by 0
def rinv: r(1; .);

def rdiv($a; $b): r($a; $b);

# Input: an integer or a Rational, $p
# Output: $p < $q
def rlessthan($q):
  # lt($b) assumes . and $b have the same sign
  def lt($b):
    . as $a
    | ($a.n * $b.d) < ($b.n * $a.d);

  if $q|type == "number" then rlessthan(r($q;1))
  else if type == "number" then r(.;1) else . end
  | if .n < 0
    then if ($q.n >= 0) then true
         else . as $p | ($q|rminus | rlessthan($p|rminus))
         end
    else lt($q)
    end
  end;

def rgreaterthan($q):
  . as $p | $q | rlessthan($p);

def rlessthanOrEqual($q): requal(.;$q) or rlessthan($q);
def rgreaterthanOrEqual($q): requal(.;$q) or rgreaterthan($q);

# Input: non-negative integer or Rational
def rsqrt(precision):
  r(.;1) as $n
  | (precision + 1) as $digits
  | def update: rmult( r(1;2); radd(.x; rdiv($n; .x))) | rround($digits);

  | def update: rmult( r(1;2); radd(.x; rdiv($n; .x)));

  r(1; 10|power(precision)) as $p
  | { x: .}
  | .root = update
  | until( rminus(.root; .x) | rabs | rlessthan($p);
      .x = .root
      | .root = update )
  | .root ;

# Use native floats
# q.v. r_to_decimal(precision)
def r_to_decimal: .n / .d;

# Input: a Rational, or {n, d} in general, or an integer.
# Output: a string representation of the input as a decimal number.
# If the input is a number, it is simply converted to a string.
# Otherwise, $precision determines the number of digits after the decimal point,
# obtained by truncating, but trailing 0s are omitted.
# Examples assuming $digits is 5:
#  -0//1 => "0"
#   2//1 => "2"
#   1//2 => "0.5"
#   1//3 => "0.33333"
#   7//9 => "0.77777"
#   1//100 => "0.01"
#  -1//10 => "-0.1"
#   1//1000000 => "0."
def r_to_decimal($digits):
  if .n == 0 # captures the annoying case of -0
  then "0"
  elif type == "number" then tostring
  elif .d < 0 then {n: -.n, d: -.d}|r_to_decimal($digits)
  elif .n < 0
  then "-" + ((.n = -.n) | r_to_decimal($digits))
  else (10|power($digits)) as $p
  | .d as $d
  | if $d == 1 then .n|tostring
    else ($p * .n | idivide($d) | tostring) as $n
    | ($n|length) as $nlength
    | (if $nlength > $digits then $n[0:$nlength-$digits] + "." + $n[$nlength-$digits:]
       else "0." + ("0"*($digits - $nlength) + $n)
       end) | sub("0+$";"")
    end
  end;

# pretty print ala Julia
def rpp: "\(.n) // \(.d)";


using Primes
divisors(n) = foldl((a, (p, e)) -> vcat((a * [p^i for i in 0:e]')...), factor(n), init=[1])

isperfect(n) = sum(1 // d for d in divisors(n)) == 2

lo, hi = 2, 2^19
println("Perfect numbers between ", lo, " and ", hi, ": ", collect(filter(isperfect, lo:hi)))


/*REXX program calculates the  AGM  (arithmetic─geometric mean)  of two (real) numbers. */
parse arg a b digs .                             /*obtain optional numbers from the C.L.*/
if digs=='' | digs==","  then digs= 120          /*No DIGS specified?  Then use default.*/
numeric digits digs                              /*REXX will use lots of decimal digits.*/
if    a=='' |    a==","  then a= 1               /*No A specified?  Then use the default*/
if    b=='' |    b==","  then b= 1 / sqrt(2)     /* " B     "         "   "   "     "   */
call AGM a,b                                     /*invoke the  AGM  function.           */
say  '1st # ='      a                            /*display the   A   value.             */
say  '2nd # ='      b                            /*   "     "    B     "                */
say  '  AGM ='  agm(a, b)                        /*   "     "   AGM    "                */
exit 0                                           /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
agm:  procedure: parse arg x,y;  if x=y  then return x       /*is this an equality case?*/
                                 if y=0  then return 0       /*is   Y   equal to zero ? */
                                 if x=0  then return y/2     /* "   X     "    "   "    */
      d= digits()                                /*obtain the  current  decimal digits. */
      numeric digits d + 5                       /*add 5 more digs to ensure convergence*/
      tiny= '1e-'  ||  (digits() - 1)            /*construct a pretty tiny REXX number. */
      ox= x + 1                                  /*ensure that   the old X  ¬=  new X.  */
                do  while ox\=x  &  abs(ox)>tiny /*compute until the old X   ≡  new X.  */
                ox= x;    oy= y                  /*save    the  old  value of  X and Y. */
                x=     (ox + oy)  *  .5          /*compute  "   new    "    "  X.       */
                y= sqrt(ox * oy)                 /*   "     "    "     "    "  Y.       */
                end   /*while*/

      numeric digits d                           /*restore the original decimal digits. */
      return x / 1                               /*normalize  X  to new    "       "    */
/*──────────────────────────────────────────────────────────────────────────────────────*/
sqrt: procedure; parse arg x; if x=0  then return 0; d=digits(); m.=9; numeric form; h=d+6
      numeric digits; parse value format(x,2,1,,0) 'E0'  with  g 'E' _ .;  g=g *.5'e'_ % 2
        do j=0  while h>9;      m.j=h;               h=h % 2  + 1;  end /*j*/
        do k=j+5  to 0  by -1;  numeric digits m.k;  g=(g+x/g)*.5;  end /*k*/;    return g


decimals(9)
see agm(1, 1/sqrt(2)) + nl
see agm(1,1/pow(2,0.5)) + nl

func agm agm,g
       while agm
             an  = (agm + g)/2
             gn  = sqrt(agm*g)
             if fabs(agm-g) <= fabs(an-gn) exit ok
             agm = an
             g   = gn
       end
       return gn


/*
 +---------------------------------------------------------------------------------------------------------
 +     Program Name : Archimedean spiral
 +---------------------------------------------------------------------------------------------------------
*/
Load "guilib.ring"

horzSize  = 400
vertSize  = 400

counter     = 0  ### cycle thru colors
colorRed    = new qcolor() { setrgb(255,000,000,255) }
colorGreen  = new qcolor() { setrgb(000,255,000,255) }
colorBlue   = new qcolor() { setrgb(000,000,255,255) }
colorYellow = new qcolor() { setrgb(255,255,000,255) }

penUseR = new qpen() { setcolor(colorRed)    setwidth(1) }
penUseG = new qpen() { setcolor(colorGreen)  setwidth(1) }
penUseB = new qpen() { setcolor(colorBlue)   setwidth(1) }
penUseY = new qpen() { setcolor(colorYellow) setwidth(1) }

        deg2rad    = atan(1) * 4 / 180
        screensize = 600
        turns      = 5
        halfscrn   = screensize / 2
        sf         = (turns * (screensize - 100)) / halfscrn
        x = 1
        y = 1
        r = 0
        inc = 0.50   ### control increment speed of r

New qapp
{
   win1 =  new qwidget()
    {
        setwindowtitle("Draw Spiral")
        setgeometry(100,100,600,600)

       label1 = new qlabel(win1)
       {
           setgeometry(10,10,600,600)
           settext("")
       }

       Canvas = new qlabel(win1)
       {
            MonaLisa = new qPixMap2( 600,600)
            color    = new qcolor(){ setrgb(255,0,0,255) }

            daVinci  = new qpainter()
            {
               begin(MonaLisa)
               penUse = new qpen() { setcolor(colorRed) setwidth(1) }
               setpen(penUseR)
               #endpaint()      ### This will Stop the Painting
            }

            setpixmap(MonaLisa)
       }

        oTimer = new qTimer(win1)
        {
            setinterval(1)    ### 1 millisecond
            settimeoutevent("DrawCounter()")
            start()
        }

       show()   ### Will show Painting ONLY after exec
    }
   exec()
}

###====================================================

Func DrawCounter()

    x  = cos(r * deg2rad) * r / sf
    y  = sin(r * deg2rad) * r / sf
    r += inc   ###  0.20 fast, 0.90 slow

        if r >= turns * 360
            r = inc
            x = 1
            y = 1
            counter++
            whichColor = counter % 4
            See  "whichColor: "+ whichColor +nl

                if whichColor = 0 daVinci.setpen(penUseR)  ok
                if whichColor = 1 daVinci.setpen(penUseG)  ok
                if whichColor = 2 daVinci.setpen(penUseB)  ok
                if whichColor = 3 daVinci.setpen(penUseY)  ok
 ok

    hpoint = halfscrn + x
    ypoint = halfscrn - y

    daVinci.drawpoint(hpoint, ypoint)
    Canvas.setpixmap(MonaLisa)          ### Need this setpixmap to display imageLabel
    win1.show()                         ### Need this show to display imageLabel

return


INCR = 0.1
attr_reader :x, :theta

def setup
  sketch_title 'Archimedian Spiral'
  @theta = 0
  @x = 0
  background(255)
  translate(width / 2.0, height / 2.0)
  begin_shape
  (0..50*PI).step(INCR) do |theta|
    @x = theta * cos(theta / PI)
    curve_vertex(x, theta * sin(theta / PI))
  end
  end_shape
end

def settings
  size(300, 300)
end


#[macro_use(px)]
extern crate bmp;

use bmp::{Image, Pixel};
use std::f64;

fn main() {
    let width = 600u32;
    let half_width = (width / 2) as i32;
    let mut img = Image::new(width, width);
    let draw_color = px!(255, 128, 128);

    // Constants defining the spiral size.
    let a = 1.0_f64;
    let b = 9.0_f64;

    // max_angle = number of spirals * 2pi.
    let max_angle = 5.0_f64 * 2.0_f64 * f64::consts::PI;

    let mut theta = 0.0_f64;
    while theta < max_angle {
        theta = theta + 0.002_f64;

        let r = a + b * theta;
        let x = (r * theta.cos()) as i32 + half_width;
        let y = (r * theta.sin()) as i32 + half_width;
        img.set_pixel(x as u32, y as u32, draw_color);
    }

    // Save the image
    let _ = img.save("archimedean_spiral.bmp").unwrap_or_else(|e| panic!("Failed to save: {}", e));
}


data xy;
h=constant('pi')/40;
do i=0 to 400;
    t=i*h;
    x=(1+t)*cos(t);
    y=(1+t)*sin(t);
    output;
end;
keep x y;
run;

proc sgplot;
series x=x y=y;
run;


object ArchimedeanSpiral extends App {

  SwingUtilities.invokeLater(() =>
    new JFrame("Archimedean Spiral") {

      class ArchimedeanSpiral extends JPanel {
        setPreferredSize(new Dimension(640, 640))
        setBackground(Color.white)

        private def drawGrid(g: Graphics2D): Unit = {
          val (angle, margin, numRings) = (toRadians(45), 10, 8)
          val w = getWidth
          val (center, spacing) = (w / 2, (w - 2 * margin) / (numRings * 2))

          g.setColor(new Color(0xEEEEEE))
          for (i <- 0 until numRings) {
            val pos = margin + i * spacing
            val size = w - (2 * margin + i * 2 * spacing)
            g.drawOval(pos, pos, size, size)
            val ia = i * angle
            val x2 = center + (cos(ia) * (w - 2 * margin) / 2).toInt
            val y2 = center - (sin(ia) * (w - 2 * margin) / 2).toInt
            g.drawLine(center, center, x2, y2)
          }
        }

        private def drawSpiral(g: Graphics2D): Unit = {
          val (degrees: Double, center) = (toRadians(0.1), getWidth / 2)
          val (a, b, c, end) = (0, 20, 1, 360 * 2 * 10 * degrees)

          def plot(g: Graphics2D, x: Int, y: Int): Unit = g.drawOval(x, y, 1, 1)

          def iter(theta: Double): Double = {
            if (theta < end) {
              val r = a + b * pow(theta, 1 / c)
              val x = r * cos(theta)
              val y = r * sin(theta)
              plot(g, (center + x).toInt, (center - y).toInt)
              iter(theta + degrees)
            } else theta
          }

          g.setStroke(new BasicStroke(2))
          g.setColor(Color.orange)
          iter(0)
        }

        override def paintComponent(gg: Graphics): Unit = {
          super.paintComponent(gg)
          val g = gg.asInstanceOf[Graphics2D]
          g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)
          drawGrid(g)
          drawSpiral(g)
        }
      }

      add(new ArchimedeanSpiral, BorderLayout.CENTER)
      pack()
      setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE)
      setLocationRelativeTo(null)
      setResizable(false)
      setVisible(true)
    }
  )

}


s:=ToString[5^4^3^2];
Print[StringTake[s,20]<>"..."<>StringTake[s,-20]<>" ("<>[email protected]@s<>" digits)"];


>> answer = vpi(5)^(vpi(4)^(vpi(3)^vpi(2)));
>> numDigits = order(answer) + 1

numDigits =

      183231

>> [sprintf('%d',leadingdigit(answer,20)) '...' sprintf('%d',trailingdigit(answer,20))]
%First and Last 20 Digits

ans =

62060698786608744707...92256259918212890625


value = str(5^(4^(3^2)))

first20 = value.substring(0,20)
last20 = value.substring(len(value) - 20)

println "The first twenty digits are " + first20
println "The last twenty digits are " + last20

if (first20 = "62060698786608744707") && (last20 = "92256259918212890625")
	println "\nThese digits are correct.\n"
end

println "The result is " + len(str(value)) + " digits long"


// version 1.1.2

fun gcd(a: Long, b: Long): Long = if (b == 0L) a else gcd(b, a % b)

infix fun Long.ldiv(denom: Long) = Frac(this, denom)

infix fun Int.idiv(denom: Int) = Frac(this.toLong(), denom.toLong())

fun Long.toFrac() = Frac(this, 1)

fun Int.toFrac() = Frac(this.toLong(), 1)

class Frac : Comparable<Frac> {
    val num: Long
    val denom: Long

    companion object {
        val ZERO = Frac(0, 1)
        val ONE  = Frac(1, 1)
    }

    constructor(n: Long, d: Long) {
        require(d != 0L)
        var nn = n
        var dd = d
        if (nn == 0L) {
            dd = 1
        }
        else if (dd < 0) {
            nn = -nn
            dd = -dd
        }
        val g = Math.abs(gcd(nn, dd))
        if (g > 1) {
            nn /= g
            dd /= g
        }
        num = nn
        denom = dd
    }

    constructor(n: Int, d: Int) : this(n.toLong(), d.toLong())

    operator fun plus(other: Frac) =
        Frac(num * other.denom + denom * other.num, other.denom * denom)

    operator fun unaryPlus() = this

    operator fun unaryMinus() = Frac(-num, denom)

    operator fun minus(other: Frac) = this + (-other)

    operator fun times(other: Frac) = Frac(this.num * other.num, this.denom * other.denom)

    operator fun rem(other: Frac) = this - Frac((this / other).toLong(), 1) * other

    operator fun inc() = this + ONE
    operator fun dec() = this - ONE

    fun inverse(): Frac {
        require(num != 0L)
        return Frac(denom, num)
    }

    operator fun div(other: Frac) = this * other.inverse()

    fun abs() = if (num >= 0) this else -this

    override fun compareTo(other: Frac): Int {
        val diff = this.toDouble() - other.toDouble()
        return when {
            diff < 0.0  -> -1
            diff > 0.0  -> +1
            else        ->  0
        }
    }

    override fun equals(other: Any?): Boolean {
       if (other == null || other !is Frac) return false
       return this.compareTo(other) == 0
    }

    override fun hashCode() = num.hashCode() xor denom.hashCode()

    override fun toString() = if (denom == 1L) "$num" else "$num/$denom"

    fun toDouble() = num.toDouble() / denom

    fun toLong() = num / denom
}

fun isPerfect(n: Long): Boolean {
    var sum = Frac(1, n)
    val limit = Math.sqrt(n.toDouble()).toLong()
    for (i in 2L..limit) {
        if (n % i == 0L) sum += Frac(1, i) + Frac(1, n / i)
    }
    return sum == Frac.ONE
}

fun main(args: Array<String>) {
    var frac1 = Frac(12, 3)
    println ("frac1 = $frac1")
    var frac2 = 15 idiv 2
    println("frac2 = $frac2")
    println("frac1 <= frac2 is ${frac1 <= frac2}")
    println("frac1 >= frac2 is ${frac1 >= frac2}")
    println("frac1 == frac2 is ${frac1 == frac2}")
    println("frac1 != frac2 is ${frac1 != frac2}")
    println("frac1 + frac2 = ${frac1 + frac2}")
    println("frac1 - frac2 = ${frac1 - frac2}")
    println("frac1 * frac2 = ${frac1 * frac2}")
    println("frac1 / frac2 = ${frac1 / frac2}")
    println("frac1 % frac2 = ${frac1 % frac2}")
    println("inv(frac1)    = ${frac1.inverse()}")
    println("abs(-frac1)   = ${-frac1.abs()}")
    println("inc(frac2)    = ${++frac2}")
    println("dec(frac2)    = ${--frac2}")
    println("dbl(frac2)    = ${frac2.toDouble()}")
    println("lng(frac2)    = ${frac2.toLong()}")
    println("\nThe Perfect numbers less than 2^19 are:")
    // We can skip odd numbers as no known perfect numbers are odd
    for (i in 2 until (1 shl 19) step 2) {
        if (isPerfect(i.toLong())) print("  $i")
    }
    println()
}


# The flt package (http://flt.rubyforge.org/) is useful for high-precision floating-point math.
# It lets us control 'context' of numbers, individually or collectively -- including precision
# (which adjusts the context's value of epsilon accordingly).

require 'flt'
include Flt

BinNum.Context.precision = 512  # default 53 (bits)

def agm(a,g)
  new_a = BinNum a
  new_g = BinNum g
  while new_a - new_g > new_a.class.Context.epsilon do
    old_g = new_g
    new_g = (new_a * new_g).sqrt
    new_a = (old_g + new_a) * 0.5
  end
  new_g
end

puts agm(1, 1 / BinNum(2).sqrt)


print agm(1, 1/sqr(2))
print agm(1,1/2^.5)
print using("#.############################",agm(1, 1/sqr(2)))

function agm(agm,g)
 while agm
   an  = (agm + g)/2
   gn  = sqr(agm*g)
   if abs(agm-g) <= abs(an-gn) then exit while
   agm = an
   g   = gn
 wend
end function


// Accepts two command line arguments
// cargo run --name agm arg1 arg2

fn main () {
    let mut args = std::env::args();

    let x = args.nth(1).expect("First argument not specified.").parse::<f32>().unwrap();
    let y = args.next().expect("Second argument not specified.").parse::<f32>().unwrap();

    let result = agm(x,y);
    println!("The arithmetic-geometric mean is {}", result);
}

fn agm (x: f32, y: f32) -> f32 {
    let e: f32 = 0.000001;
    let mut a = x;
    let mut g = y;
    let mut a1: f32;
    let mut g1: f32;

    if a * g < 0f32 { panic!("The arithmetric-geometric mean is undefined for numbers less than zero!"); }
    else {
        loop {
            a1 = (a + g) / 2.;
            g1 = (a * g).sqrt();
            a = a1;
            g = g1;
            if (a - g).abs() < e {  return a; }
        }
    }
}


  def agm(a: Double, g: Double, eps: Double): Double = {
    if (math.abs(a - g) < eps) (a + g) / 2
    else agm((a + g) / 2, math.sqrt(a * g), eps)
  }

  agm(1, math.sqrt(2)/2, 1e-15)


(import (scheme base)
        (scheme complex)
        (rebottled pstk))

; settings for spiral
(define *resolution* 0.01)
(define *count* 2000)
(define *a* 10)
(define *b* 10)
(define *center*
  (let ((size 200)) ; change this to alter size of display
    (* size 1+i)))

(define (draw-spiral canvas)
  (define (coords theta)
    (let ((r (+ *a* (* *b* theta))))
      (make-polar r theta)))
  ;
  (do ((i 0 (+ i 1))) ; loop to draw spiral
    ((= i *count*) )
    (let ((c (+ (coords (* i *resolution*)) *center*)))
      (canvas 'create 'line
              (real-part c) (imag-part c)
              (+ 1 (real-part c)) (imag-part c)))))

(let ((tk (tk-start)))
  (tk/wm 'title tk "Archimedean Spiral")
  (let ((canvas (tk 'create-widget 'canvas)))
    (tk/pack canvas)
    (canvas 'configure
            'height: (* 2 (real-part *center*))
            'width: (* 2 (imag-part *center*)))
    (draw-spiral canvas))
  (tk-event-loop tk))


a = 3;
b = 2;

theta = linspace(0,10*%pi,1000);
r = a + b .* theta;

//1. Plot using polar coordinates
scf(1);
polarplot(theta,r);

//2. Plot using rectangular coordinates
//2.1 Convert coordinates using Euler's formula
z = r .* exp(%i .* theta);
x = real(z);
y = imag(z);

scf(2);
plot2d(x,y);


$ include "seed7_05.s7i";
  include "draw.s7i";
  include "keybd.s7i";

const proc: main is func
  local
    const float: xCenter is 117.0;
    const float: yCenter is 139.0;
    const float: maxTheta is 10.0 * PI;
    const float: delta is 0.01;
    const float: a is 1.0;
    const float: b is 7.0;
    var float: theta is 0.0;
    var float: radius is 0.0;
  begin
    screen(256, 256);
    clear(curr_win, black);
    KEYBOARD := GRAPH_KEYBOARD;
    while theta <= maxTheta do
      radius := a + b * theta;
      point(round(xCenter + radius * cos(theta)),
            round(yCenter - radius * sin(theta)), white);
      theta +:= delta;
    end while;
    DRAW_FLUSH;
    ignore(getc(KEYBOARD));
  end func;


using System.Console;
using System.Numerics;
using System.Numerics.BigInteger;

module BigInt
{
    Main() : void
    {
        def n = Pow(5, Pow(4, Pow(3, 2) :> int) :> int).ToString();
        def len = n.Length;
        def first20 = n.Substring(0, 20);
        def last20 = n.Substring(len - 20, 20);

        assert (first20 == "62060698786608744707", "High order digits are incorrect");
        assert (last20 == "92256259918212890625", "Low order digits are incorrect");
        assert (len == 183231, "Result contains wrong number of digits");

        WriteLine("Result: {0} ... {1}", first20, last20);
        WriteLine($"Length of result: $len digits");
    }
}


;;;	No built-in big integer exponentiation
(define (exp-big x n)
	(setq x (bigint x))
	(let (y 1L)
		(if (= n 0)
			1L
			(while (> n 1)
				(if (odd? n)
					(setq y (* x y)))
				(setq x (* x x) n (/ n 2)))
		(* x y))))
;
;;; task
(define (test)
	(local (res)
		;	drop the "L" at the end
		(setq res (0 (- (length res) 1) (string (exp-big 5 (exp-big 4 (exp-big 3 2))))))
		(println "The result has:  " (length res) " digits")
		(println "First 20 digits: " (0 20 res))
		(println "Last 20 digits:  " (-20 20 res))))


/* NetRexx */

options replace format comments java crossref savelog symbols

import java.math.BigInteger

numeric digits 30 -- needed to report the run-time

nanoFactor = 10 ** 9

t1 = System.nanoTime
x = BigInteger.valueOf(5)
x = x.pow(BigInteger.valueOf(4).pow(BigInteger.valueOf(3).pow(2).intValue()).intValue())
n = Rexx(x.toString)
t2 = System.nanoTime
td = t2 - t1
say "Run time in seconds:" td / nanoFactor
say

check = "62060698786608744707...92256259918212890625"
sample = n.left(20)"..."n.right(20)

say "Expected result:" check
say "  Actual result:" sample
say "         digits:" n.length
say

if check = sample
then
  say "Result confirmed"
else
  say "Result does not satisfy test"

return


n=2^19
for testNumber=1 to n
    sum$=castToFraction$(0)
    for factorTest=1 to sqr(testNumber)
        if GCD(factorTest,testNumber)=factorTest then sum$=add$(sum$,add$(reciprocal$(castToFraction$(factorTest)),reciprocal$(castToFraction$(testNumber/factorTest))))
    next factorTest
    if equal(sum$,castToFraction$(2))=1 then print testNumber
next testNumber
end

function abs$(a$)
    aNumerator=val(word$(a$,1,"/"))
    aDenominator=val(word$(a$,2,"/"))
    bNumerator=abs(aNumerator)
    bDenominator=abs(aDenominator)
    b$=str$(bNumerator)+"/"+str$(bDenominator)
    abs$=simplify$(b$)
end function

function negate$(a$)
    aNumerator=val(word$(a$,1,"/"))
    aDenominator=val(word$(a$,2,"/"))
    bNumerator=-1*aNumerator
    bDenominator=aDenominator
    b$=str$(bNumerator)+"/"+str$(bDenominator)
    negate$=simplify$(b$)
end function

function add$(a$,b$)
    aNumerator=val(word$(a$,1,"/"))
    aDenominator=val(word$(a$,2,"/"))
    bNumerator=val(word$(b$,1,"/"))
    bDenominator=val(word$(b$,2,"/"))
    cNumerator=(aNumerator*bDenominator+bNumerator*aDenominator)
    cDenominator=aDenominator*bDenominator
    c$=str$(cNumerator)+"/"+str$(cDenominator)
    add$=simplify$(c$)
end function

function subtract$(a$,b$)
    aNumerator=val(word$(a$,1,"/"))
    aDenominator=val(word$(a$,2,"/"))
    bNumerator=val(word$(b$,1,"/"))
    bDenominator=val(word$(b$,2,"/"))
    cNumerator=(aNumerator*bDenominator-bNumerator*aDenominator)
    cDenominator=aDenominator*bDenominator
    c$=str$(cNumerator)+"/"+str$(cDenominator)
    subtract$=simplify$(c$)
end function

function multiply$(a$,b$)
    aNumerator=val(word$(a$,1,"/"))
    aDenominator=val(word$(a$,2,"/"))
    bNumerator=val(word$(b$,1,"/"))
    bDenominator=val(word$(b$,2,"/"))
    cNumerator=aNumerator*bNumerator
    cDenominator=aDenominator*bDenominator
    c$=str$(cNumerator)+"/"+str$(cDenominator)
    multiply$=simplify$(c$)
end function

function divide$(a$,b$)
    divide$=multiply$(a$,reciprocal$(b$))
end function

function simplify$(a$)
    aNumerator=val(word$(a$,1,"/"))
    aDenominator=val(word$(a$,2,"/"))
    gcd=GCD(aNumerator,aDenominator)
    if aNumerator<0 and aDenominator<0 then gcd=-1*gcd
    bNumerator=aNumerator/gcd
    bDenominator=aDenominator/gcd
    b$=str$(bNumerator)+"/"+str$(bDenominator)
    simplify$=b$
end function

function reciprocal$(a$)
    aNumerator=val(word$(a$,1,"/"))
    aDenominator=val(word$(a$,2,"/"))
    reciprocal$=str$(aDenominator)+"/"+str$(aNumerator)
end function

function equal(a$,b$)
    if simplify$(a$)=simplify$(b$) then equal=1:else equal=0
end function

function castToFraction$(a)
    do
        exp=exp+1
        a=a*10
    loop until a=int(a)
    castToFraction$=simplify$(str$(a)+"/"+str$(10^exp))
end function

function castToReal(a$)
    aNumerator=val(word$(a$,1,"/"))
    aDenominator=val(word$(a$,2,"/"))
    castToReal=aNumerator/aDenominator
end function

function castToInt(a$)
    castToInt=int(castToReal(a$))
end function

function GCD(a,b)
    if a=0 then
        GCD=1
    else
        if a>=b then
            while b
                c = a
                a = b
                b = c mod b
                GCD = abs(a)
            wend
        else
            GCD=GCD(b,a)
        end if
    end if
end function


(define agm
  (case-lambda
    ((a0 g0) ; call again with default value for tolerance
     (agm a0 g0 1e-8))
    ((a0 g0 tolerance) ; called with three arguments
     (do ((a a0 (* (+ a g) 1/2))
          (g g0 (sqrt (* a g))))
       ((< (abs (- a g)) tolerance) a)))))

(display (agm 1 (/ 1 (sqrt 2)))) (newline)


$ include "seed7_05.s7i";
  include "float.s7i";
  include "math.s7i";

const func float: agm (in var float: a, in var float: g) is func
  result
    var float: agm is 0.0;
  local
    const float: iota is 1.0E-7;
    var float: a1 is 0.0;
    var float: g1 is 0.0;
  begin
    if a * g < 0.0 then
      raise RANGE_ERROR;
    else
      while abs(a - g) > iota do
        a1 := (a + g) / 2.0;
        g1 := sqrt(a * g);
        a := a1;
        g := g1;
      end while;
      agm := a;
    end if;
  end func;

const proc: main is func
  begin
    writeln(agm(1.0, 2.0) digits 6);
    writeln(agm(1.0, 1.0 / sqrt(2.0)) digits 6);
  end func;


import <Utilities/Math.sl>;

agm(a, g) :=
    let
        iota := 1.0e-15;
        arithmeticMean := 0.5 * (a + g);
        geometricMean := sqrt(a * g);
    in
        a when abs(a-g) < iota
    else
        agm(arithmeticMean, geometricMean);

main := agm(1.0, 1.0 / sqrt(2));


require('Imager')
define π = Num.pi

var (w, h) = (400, 400)
var img = %O<Imager>.new(xsize => w, ysize => h)

for Θ in (0 .. 52*π -> by(0.025)) {
    img.setpixel(
        x => floor(cos(Θ / π)*Θ + w/2),
        y => floor(sin(Θ / π)*Θ + h/2),
        color => [255, 0, 0]
    )
}

img.write(file => 'Archimedean_spiral.png')


clear all
scalar h=_pi/40
set obs 400
gen t=_n*h
gen x=(1+t)*cos(t)
gen y=(1+t)*sin(t)
line y x


package require Tk

# create widgets
canvas .canvas
frame .controls

ttk::label .legend -text " r = a + b θ "
ttk::label .label_a -text "a ="
ttk::entry .entry_a -textvariable a
ttk::label .label_b -text "a ="
ttk::entry .entry_b -textvariable b
button .button -text "Redraw" -command draw

# layout
grid .canvas .controls -sticky nsew
grid .legend - -sticky ns -in .controls
grid .label_a .entry_a -sticky nsew -in .controls
grid .label_b .entry_b -sticky nsew -in .controls
grid .button - -sticky ns -in .controls

# make the canvas resize with the window
grid columnconfigure . 0 -weight 1
grid rowconfigure . 0 -weight 1

# spiral parameters:
set a .2
set b .05

proc draw {} {
    variable a
    variable b

    # make sure inputs are valid:
    if {![string is double $a] || ![string is double $b]} return
    if {$a == 0 || $b == 0} return

    set w [winfo width .canvas]
    set h [winfo height .canvas]
    set r 0
    set pi [expr {4*atan(1)}]
    set step [expr {$pi / $w}]
    for {set t 0} {$r < 2} {set t [expr {$t + $step}]} {
        set r [expr {$a + $b * $t}]
        set y [expr {sin($t) * $r}]
        set x [expr {cos($t) * $r}]

        # transform to canvas co-ordinates
        set y [expr {entier((1+$y)*$h/2)}]
        set x [expr {entier((1+$x)*$w/2)}]
        lappend coords $x $y
    }
    .canvas delete all
    set id [.canvas create line $coords -fill red]
}

# draw whenever parameters are changed
# ";#" so extra trace arguments are ignored
trace add variable a write {draw;#}
trace add variable b write {draw;#}

wm protocol . WM_DELETE_WINDOW exit ;# exit when window is closed

update  ;# lay out widgets before trying to draw
draw
vwait forever ;# go into event loop until window is closed


import bigints

var x = 5.pow 4.pow 3.pow 2
var s = $x

echo s[0..19]
echo s[s.high - 19 .. s.high]
echo s.len


open Num
open Str
open String

let () =
  let answer = (Int 5) **/ (Int 4) **/ (Int 3) **/ (Int 2) in
  let answer_string = string_of_num answer in
  Printf.printf "has %d digits: %s ... %s\n"
                (length answer_string)
                (first_chars answer_string 20)
                (last_chars answer_string 20)


import: mapping

5 4 3 2 pow pow pow >string dup left( 20 ) . dup right( 20 ) . size .


(define x (expt 5 (expt 4 (expt 3 2))))
(print
   (div x (expt 10 (- (log 10 x) 20)))
   "..."
   (mod x (expt 10 20)))
(print "totally digits: " (log 10 x))


-- parent script "Frac"
property num
property denom

----------------------------------------
-- @constructor
-- @param {integer} numerator
-- @param {integer} [denominator=1]
----------------------------------------
on new (me, numerator, denominator)
  if voidP(denominator) then denominator = 1
  if denominator=0 then return VOID -- rule out division by zero
  g = me._gcd(numerator, denominator)
  if g<>0 then
    numerator = numerator/g
    denominator = denominator/g
  else
    numerator = 0
    denominator = 1
  end if
  if denominator<0 then
    numerator = -numerator
    denominator = -denominator
  end if
  me.num = numerator
  me.denom = denominator
  return me
end

----------------------------------------
-- Returns string representation "<num>/<denom>"
-- @return {string}
----------------------------------------
on toString (me)
  return me.num&"/"&me.denom
end

----------------------------------------
--
----------------------------------------
on _gcd (me, a, b)
  if a = 0 then return b
  if b = 0 then return a
  if a > b then return me._gcd(b, a mod b)
  return me._gcd(a, b mod a)
end


function gcd(a,b) return a == 0 and b or gcd(b % a, a) end

do
  local function coerce(a, b)
    if type(a) == "number" then return rational(a, 1), b end
    if type(b) == "number" then return a, rational(b, 1) end
    return a, b
  end
  rational = setmetatable({
  __add = function(a, b)
      local a, b = coerce(a, b)
      return rational(a.num * b.den + a.den * b.num, a.den * b.den)
    end,
  __sub = function(a, b)
      local a, b = coerce(a, b)
      return rational(a.num * b.den - a.den * b.num, a.den * b.den)
    end,
  __mul = function(a, b)
      local a, b = coerce(a, b)
      return rational(a.num * b.num, a.den * b.den)
    end,
  __div = function(a, b)
      local a, b = coerce(a, b)
      return rational(a.num * b.den, a.den * b.num)
    end,
  __pow = function(a, b)
      if type(a) == "number" then return a ^ (b.num / b.den) end
      return rational(a.num ^ b, a.den ^ b) --runs into a problem if these aren't integers
    end,
  __concat = function(a, b)
      if getmetatable(a) == rational then return a.num .. "/" .. a.den .. b end
      return a .. b.num .. "/" .. b.den
    end,
  __unm = function(a) return rational(-a.num, -a.den) end}, {
  __call = function(z, a, b) return setmetatable({num = a / gcd(a, b),den = b / gcd(a, b)}, z) end} )
end

print(rational(2, 3) + rational(3, 5) - rational(1, 10) .. "") --> 7/6
print((rational(4, 5) * rational(5, 9)) ^ rational(1, 2) .. "") --> 2/3
print(rational(45, 60) / rational(5, 2) .. "") --> 3/10
print(5 + rational(1, 3) .. "") --> 16/3

function findperfs(n)
  local ret = {}
  for i = 1, n do
    sum = rational(1, i)
    for fac = 2, i^.5 do
      if i % fac == 0 then
        sum = sum + rational(1, fac) + rational(fac, i)
      end
    end
    if sum.den == sum.num then
      ret[#ret + 1] = i
    end
  end
  return table.concat(ret, '\n')
end
print(findperfs(2^19))


 10 LET A=1
 20 LET G=1/SQR 2
 30 GOSUB 100
 40 PRINT AGM
 50 STOP
100 LET A0=A
110 LET A=(A+G)/2
120 LET G=SQR (A0*G)
130 IF ABS(A-G)>.00000001 THEN GOTO 100
140 LET AGM=A
150 RETURN


agm:y
    "return the arithmetic-geometric mean agm(x, y)
     of the receiver (x) and the argument, y.
     See https://en.wikipedia.org/wiki/Arithmetic-geometric_mean"

    |ai an gi gn epsilon delta|

    ai := (self + y) / 2.
    gi := (self * y) sqrt.
    epsilon := self ulp.

    [
        an := (ai + gi) / 2.
        gn := (ai * gi) sqrt.
        delta := (an - ai) abs.
        ai := an.
        gi := gn.
    ] doUntil:[ delta < epsilon ].
    ^ ai


WITH
  rec (rn, a, g, diff) AS (
    SELECT  1, 1, 1/SQRT(2), 1 - 1/SQRT(2)
      FROM  dual
    UNION ALL
    SELECT  rn + 1, (a + g)/2, SQRT(a * g), (a + g)/2 - SQRT(a * g)
      FROM  rec
      WHERE diff > 1e-38
  )
SELECT *
FROM   rec
WHERE  diff <= 1e-38
;


Private Sub plot_coordinate_pairs(x As Variant, y As Variant)
    Dim chrt As Chart
    Set chrt = ActiveSheet.Shapes.AddChart.Chart
    With chrt
        .ChartType = xlXYScatter
        .HasLegend = False
        .SeriesCollection.NewSeries
        .SeriesCollection.Item(1).XValues = x
        .SeriesCollection.Item(1).Values = y
    End With
End Sub
Public Sub main()
    Dim x(1000) As Single, y(1000) As Single
    a = 1
    b = 9
    For i = 0 To 1000
        theta = i * WorksheetFunction.Pi() / 60
        r = a + b * theta
        x(i) = r * Cos(theta)
        y(i) = r * Sin(theta)
    Next i
    plot_coordinate_pairs x, y
End Sub


import "graphics" for Canvas, Color
import "dome" for Window

class Game {
    static init() {
        Window.title = "Archimedean Spiral"
        __width = 400
        __height = 400
        Canvas.resize(__width, __height)
        Window.resize(__width, __height)
        var col = Color.red
        spiral(col)
    }

    static spiral(col) {
        var theta = 0
        while (theta < 52 * Num.pi) {
            var x = ((theta/Num.pi).cos * theta + __width/2).truncate
            var y = ((theta/Num.pi).sin * theta + __height/2).truncate
            Canvas.pset(x, y, col)
            theta = theta + 0.025
        }
    }

    static update() {}

    static draw(dt) {}
}


real A, B, R, T, X, Y;
[SetVid($12);           \set 640x480 graphics
A:= 0.0;  B:= 3.0;  T:= 0.0;
Move(320, 240);         \start at center of screen
repeat  R:= A + B*T;
        X:= R*Cos(T);  Y:= R*Sin(T);
        Line(fix(X)+320, 240-fix(Y), 4\red\);
        T:= T + 0.03;   \increase angle (Theta)
until   T >= 314.159;   \50 revs
]


--REXX program to show arbitrary precision integers.
numeric digits 200000
check = '62060698786608744707...92256259918212890625'

start = .datetime~new
n = 5 ** (4 ** (3**2))
time = .datetime~new - start
say 'elapsed time for the calculation:' time
say
sampl = left(n, 20)"..."right(n, 20)

say ' check:' check
say 'Sample:' sampl
say 'digits:' length(n)
say

if check=sampl then say 'passed!'
               else say 'failed!'


declare
  Pow5432 = {Pow 5 {Pow 4 {Pow 3 2}}}
  S = {Int.toString Pow5432}
  Len = {Length S}
in
  {System.showInfo
   {List.take S 20}#"..."#
   {List.drop S Len-20}#" ("#Len#" Digits)"}


num_first_last_digits(a=5,b=4^3^2,n=20)={ my(L = b*log(a)/log(10), m=Mod(a,10^n)^b);
	[L\1+1, 10^frac(L)\10^(1-n), lift(m)] \\ where x\y = floor(x/y) but more efficient
}
print("Length, first and last 20 digits of 5^4^3^2: ", num_first_last_digits()) \\ uses default values a=5, b=4^3^2, n=20


Class Rational {
      \\ this is a compact version for this task
      numerator as decimal, denominator as decimal
      gcd=lambda->0
      lcm=lambda->0
      operator "+" {
           Read l
           denom=.lcm(l.denominator, .denominator)
           .numerator<=denom/l.denominator*l.numerator+denom/.denominator*.numerator
           if .numerator==0 then denom=1
           .denominator<=denom
      }
      Group Real {
            value {
                  link parent numerator, denominator to n, d
                  =n/d
            }
      }
      Group ToString$ {
           value {
                  link parent numerator, denominator to n, d
                  =Str$(n)+"/"+Str$(d,"")
            }
      }
      class:
      Module Rational (.numerator, .denominator) {
            if .denominator<=0 then Error "Positive only denominator"
            gcd1=lambda (a as decimal, b as decimal) -> {
                  if a<b then swap a,b
                  g=a mod b
                  while g {
                        a=b:b=g: g=a mod b
                  }
                        =abs(b)
            }
            .gcd<=gcd1
            .lcm<=lambda gcd=gcd1 (a as decimal, b as decimal) -> {
                  =a/gcd(a,b)*b
            }
      }
}
sum=rational(1, 1)
onediv=rational(1,1)
divcand=rational(1,1)
Profiler
For sum.denominator= 2 to 2**15 {
      divcand.denominator=sum.denominator
      For onediv.denominator=2 to sqrt(sum.denominator) {
            if sum.denominator mod onediv.denominator = 0 then {
                  divcand.numerator=onediv.denominator
                  sum=sum+onediv+divcand
            }
      }
      if sum.real=1 then Print sum.denominator;" is perfect"
      sum.numerator=1
}
Print timecount


fun agm(a, g) = let
  fun agm'(a, g, eps) =
    if Real.abs(a-g) < eps then
      a
    else
      agm'((a+g)/2.0, Math.sqrt(a*g), eps)
  in agm'(a, g, 1e~15)
  end;


mata

real scalar agm(real scalar a, real scalar b) {
	real scalar c
	do {
		c=0.5*(a+b)
		b=sqrt(a*b)
		a=c
	} while (a-b>1e-15*a)
	return(0.5*(a+b))
}

agm(1,1/sqrt(2))
end


import Darwin

enum AGRError : Error {
	case undefined
}

func agm(_ a: Double, _ g: Double, _ iota: Double = 1e-8) throws -> Double {
	var a = a
	var g = g
	var a1: Double = 0
	var g1: Double = 0

	guard a * g >= 0 else {
		throw AGRError.undefined
	}

	while abs(a - g) > iota {
		a1 = (a + g) / 2
		g1 = sqrt(a * g)
		a = a1
		g = g1
	}

	return a
}

do {
	try print(agm(1, 1 / sqrt(2)))
} catch {
	print("agr is undefined when a * g < 0")
}


proc agm {a b} {
    set old_b [expr {$b<0?inf:-inf}]
    while {$a != $b && $b != $old_b} {
	set old_b $b
	lassign [list [expr {0.5*($a+$b)}] [expr {sqrt($a*$b)}]] a b
    }
    return $a
}

puts [agm 1 [expr 1/sqrt(2)]]


5 OPEN WINDOW 320, 200 : WINDOW ORIGIN "CC"
10 LET A=1.5
20 LET B=0.7
30 FOR T=0 TO 30*PI STEP 0.05
40 LET R=A+B*T
50 LINE TO R*COS(T),R*SIN(T)
60 NEXT T


fcn archimedeanSpiral(a,b,circles){
   w,h:=640,640; centerX,centerY:=w/2,h/2;
   bitmap:=PPM(w+1,h+1,0xFF|FF|FF);  // White background

   foreach deg in ([0.0 .. 360*circles]){
      rad:=deg.toRad();
      r:=rad*b + a;
      x,y:=r.toRectangular(rad);
      bitmap[centerX + x, centerY + y] = 0x00|FF|00;  // Green dot
   }
   bitmap.writeJPGFile("archimedeanSpiral.jpg");
}(0,5,7);


program GMP_Demo;

uses
  math, gmp;

var
  a:   mpz_t;
  out: pchar;
  len: longint;
  i:   longint;

begin
  mpz_init_set_ui(a, 5);
  mpz_pow_ui(a, a, 4 ** (3 ** 2));
  len := mpz_sizeinbase(a, 10);
  writeln('GMP says size is: ', len);
  out := mpz_get_str(NIL, 10, a);
  writeln('Actual size is:   ', length(out));
  write('Digits: ');
  for i := 0 to 19 do
    write(out[i]);
  write ('...');
  for i := len - 20 to len do
    write(out[i]);
  writeln;
end.


use Math::BigInt;
my $x = Math::BigInt->new('5') ** Math::BigInt->new('4') ** Math::BigInt->new('3') ** Math::BigInt->new('2');
my $y = "$x";
printf("5**4**3**2 = %s...%s and has %i digits\n", substr($y,0,20), substr($y,-20), length($y));


with javascript_semantics
include mpfr.e
atom t0 = time()
mpz res = mpz_init()
mpz_ui_pow_ui(res,5,power(4,power(3,2)))
string s = mpz_get_short_str(res),
       e = elapsed(time()-t0)
printf(1,"5^4^3^2 = %s (%s)\n", {s,e})


1→A:1/sqrt(2)→G
While abs(A-G)>e-15
(A+G)/2→B
sqrt(AG)→G:B→A
End
A


function agm {
    float a=$1 g=$2 eps=${3:-1e-11} tmp
    while (( abs(a-g) > eps )); do
        print "debug: a=$a\tg=$g"
        tmp=$(( (a+g)/2.0 ))
        g=$(( sqrt(a*g) ))
        a=$tmp
    done
    echo $a
}

agm $((1/sqrt(2))) 1


Private Function agm(a As Double, g As Double, Optional tolerance As Double = 0.000000000000001) As Double
    Do While Abs(a - g) > tolerance
        tmp = a
        a = (a + g) / 2
        g = Sqr(tmp * g)
        Debug.Print a
    Loop
    agm = a
End Function
Public Sub main()
    Debug.Print agm(1, 1 / Sqr(2))
End Sub


Function agm(a,g)
	Do Until a = tmp_a
		tmp_a = a
		a = (a + g)/2
		g = Sqr(tmp_a * g)
	Loop
	agm = a
End Function

WScript.Echo agm(1,1/Sqr(2))


#  Perform calculation
$BigNumber = [BigInt]::Pow( 5, [BigInt]::Pow( 4, [BigInt]::Pow( 3, 2 ) ) )

#  Display first and last 20 digits
$BigNumberString = [string]$BigNumber
$BigNumberString.Substring( 0, 20 ) + "..." + $BigNumberString.Substring( $BigNumberString.Length - 20, 20 )

#  Display number of digits
$BigNumberString.Length


DEFINITION MODULE Rational;
    TYPE RAT =  RECORD
                    numerator : INTEGER;
                    denominator : INTEGER;
                END;

    PROCEDURE IGCD( i : INTEGER; j : INTEGER ) : INTEGER;
    PROCEDURE ILCM( i : INTEGER; j : INTEGER ) : INTEGER;
    PROCEDURE IABS( i : INTEGER ) : INTEGER;

    PROCEDURE RNormalize( i : RAT ) : RAT;
    PROCEDURE RCreate( num : INTEGER; dem : INTEGER ) : RAT;
    PROCEDURE RAdd( i : RAT; j : RAT ) : RAT;
    PROCEDURE RSubtract( i : RAT; j : RAT ) : RAT;
    PROCEDURE RMultiply( i : RAT; j : RAT ) : RAT;
    PROCEDURE RDivide( i : RAT; j : RAT ) : RAT;
    PROCEDURE RAbs( i : RAT ) : RAT;
    PROCEDURE RInv( i : RAT ) : RAT;
    PROCEDURE RNeg( i : RAT ) : RAT;

    PROCEDURE RInc( i : RAT ) : RAT;
    PROCEDURE RDec( i : RAT ) : RAT;

    PROCEDURE REQ( i : RAT; j : RAT ) : BOOLEAN;
    PROCEDURE RNE( i : RAT; j : RAT ) : BOOLEAN;
    PROCEDURE RLT( i : RAT; j : RAT ) : BOOLEAN;
    PROCEDURE RLE( i : RAT; j : RAT ) : BOOLEAN;
    PROCEDURE RGT( i : RAT; j : RAT ) : BOOLEAN;
    PROCEDURE RGE( i : RAT; j : RAT ) : BOOLEAN;

    PROCEDURE RIsZero( i : RAT ) : BOOLEAN;
    PROCEDURE RIsNegative( i : RAT ) : BOOLEAN;
    PROCEDURE RIsPositive( i : RAT ) : BOOLEAN;

    PROCEDURE RToString( i : RAT; VAR S : ARRAY OF CHAR );
    PROCEDURE RToRational( s : ARRAY OF CHAR ) : RAT;

    PROCEDURE WriteRational( i : RAT );

END Rational.


Imports System.Math
Imports System.Console

Module Module1

    Function CalcAGM(ByVal a As Double, ByVal b As Double) As Double
        Dim c As Double, d As Double = 0, ld As Double = 1
        While ld <> d : c = a : a = (a + b) / 2 : b = Sqrt(c * b)
            ld = d : d = a - b : End While : Return b
    End Function

    Function DecSqRoot(ByVal v As Decimal) As Decimal
        Dim r As Decimal = CDec(Sqrt(CDbl(v))), t As Decimal = 0, d As Decimal = 0, ld As Decimal = 1
        While ld <> d : t = v / r : r = (r + t) / 2
            ld = d : d = t - r : End While : Return t
    End Function

    Function CalcAGM(ByVal a As Decimal, ByVal b As Decimal) As Decimal
        Dim c As Decimal, d As Decimal = 0, ld As Decimal = 1
        While ld <> d : c = a : a = (a + b) / 2 : b = DecSqRoot(c * b)
            ld = d : d = a - b : End While : Return b
    End Function

    Sub Main(ByVal args As String())
        WriteLine("Double  result: {0}", CalcAGM(1.0, DecSqRoot(0.5)))
        WriteLine("Decimal result: {0}", CalcAGM(1D, DecSqRoot(0.5D)))
        If System.Diagnostics.Debugger.IsAttached Then ReadKey()
    End Sub

End Module


import math

const ep = 1e-14

fn agm(aa f64, gg f64) f64 {
    mut a, mut g := aa, gg
    for math.abs(a-g) > math.abs(a)*ep {
        t := a
        a, g = (a+g)*.5, math.sqrt(t*g)
    }
    return a
}

fn main() {
    println(agm(1.0, 1.0/math.sqrt2))
}


IncludeFile "Decimal.pbi"

;- Declare the variables that will be used
Define.Decimal *a
Define n, L$, R$, out$, digits.s

;- 4^3^2 is withing 32 bit range, so normal procedures can be used
n=Pow(4,Pow(3,2))

;- 5^n is larger then 31^2, so the same library call as in the "Long multiplication" task is used
*a=PowerDecimal(IntegerToDecimal(5),IntegerToDecimal(n))

;- Convert the large number into a string & present the results
out$=DecimalToString(*a)
L$ = Left(out$,20)
R$ = Right(out$,20)
digits=Str(Len(out$))
out$="First 20 & last 20 chars of 5^4^3^2 are;"+#CRLF$+L$+#CRLF$+R$+#CRLF$
out$+"and the result is "+digits+" digits long."

MessageRequester("Arbitrary-precision integers, PureBasic",out$)


 > quackery

Welcome to Quackery.

Enter "leave" to leave the shell.

/O> 5 4 3 2 ** ** **
... number$ dup 20 split swap echo$
... say "..." -20 split echo$ drop cr
... size echo say " digits" cr
...
62060698786608744707...92256259918212890625
183231 digits

Stack empty.

/O>


INTERFACE Frac;

EXCEPTION ZeroDenominator;

TYPE

  T <: Public;
  Public = OBJECT
  METHODS
    (* initialization and conversion *)
    init(a, b: INTEGER): T RAISES { ZeroDenominator };
    fromInt(a: INTEGER): T;
    (* unary operators *)
    abs(): T;
    opposite(): T;
    (* binary operators *)
    plus(other: T): T;
    minus(other: T): T;
    times(other: T): T;
    dividedBy(other: T): T RAISES { ZeroDenominator };
    integerDivision(other: INTEGER): T RAISES { ZeroDenominator };
    (* relations *)
    equals(other: T): BOOLEAN;
    notEqualTo(other: T): BOOLEAN;
    lessThan(other: T): BOOLEAN;
    lessEqual(other: T): BOOLEAN;
    greaterEqual(other: T): BOOLEAN;
    greater(other: T): BOOLEAN;
    (* other easily-checked properties *)
    isInt(): BOOLEAN;
    (* inc/decrement *)
    inc(step: CARDINAL := 1);
    dec(step: CARDINAL := 1);
  END;

  PROCEDURE One():  T;
  PROCEDURE Zero(): T;

  (* I/O *)
  PROCEDURE PutRat(a: T);

END Frac.


var eps = 1e-14

var agm = Fn.new { |a, g|
    while ((a-g).abs > a.abs * eps) {
        var t = a
        a = (a+g)/2
        g = (t*g).sqrt
    }
    return a
}

System.print(agm.call(1, 1/2.sqrt))


include c:\cxpl\codesi;
real A, A1, G;
[Format(0, 16);
A:= 1.0;  G:= 1.0/sqrt(2.0);
repeat	A1:= (A+G)/2.0;
	G:= sqrt(A*G);
	A:= A1;
	RlOut(0, A);  RlOut(0, G);  RlOut(0, A-G);  CrLf(0);
until	A=G;
]


10 LET a=1: LET g=1/SQR 2
20 LET ta=a
30 LET a=(a+g)/2
40 LET g=SQR (ta*g)
50 IF a<ta THEN GO TO 20
60 PRINT a


library(gmp)
large <- pow.bigz(5, pow.bigz(4, pow.bigz(3, 2)))
largestr <- as.character(large)
cat("first 20 digits:", substr(largestr, 1, 20), "\n",
    "last 20 digits:", substr(largestr, nchar(largestr) - 19, nchar(largestr)), "\n",
    "number of digits: ", nchar(largestr), "\n")


#lang racket

(define answer (number->string (foldr expt 1 '(5 4 3 2))))
(define len (string-length answer))

(printf "Got ~a digits~n" len)
(printf "~a ... ~a~n"
        (substring answer 0 20)
        (substring answer (- len 20) len))


/*REXX program calculates and demonstrates  arbitrary precision numbers (using powers). */
numeric digits 200000                            /*two hundred thousand decimal digits. */

    # = 5 ** (4 ** (3 ** 2) )                    /*calculate multiple exponentiations.  */

true=62060698786608744707...92256259918212890625 /*what answer is supposed to look like.*/
rexx= left(#, 20)'...'right(#, 20)               /*the left and right 20 decimal digits.*/

say  '  true:'    true                           /*show what the  "true"  answer is.    */
say  '  REXX:'    rexx                           /*  "    "   "    REXX      "    "     */
say  'digits:'    length(#)                      /*  "    "   "   length  of answer is. */
say
if true == rexx   then say 'passed!'             /*either it passed,  ···               */
                  else say 'failed!'             /*    or it didn't.                    */
                                                 /*stick a fork in it,  we're all done. */