Task: Pi


C++: #include <iostream>
#include <boost/multiprecision/cpp_int.hpp>

using namespace boost::multiprecision;

class Gospers
{
    cpp_int q, r, t, i, n;

public:    

    
    Gospers() : q{1}, r{0}, t{1}, i{1}
    {
        ++*this; 
    }

    
    Gospers& operator++()
    {
        n = (q*(27*i-12)+5*r) / (5*t);

        while(n != (q*(675*i-216)+125*r)/(125*t))
        {
            r = 3*(3*i+1)*(3*i+2)*((5*i-2)*q+r);
            q = i*(2*i-1)*q;
            t = 3*(3*i+1)*(3*i+2)*t;
            i++;

            n = (q*(27*i-12)+5*r) / (5*t);
        }

        q = 10*q;
        r = 10*r-10*n*t;

        return *this;
    }

    
    int operator*()
    {
        return (int)n;
    }
};

int main()
{
    Gospers g;

    std::cout << *g << ".";  

    for(;;) 
    {
        std::cout << *++g;  
    }
}










Ada: with Ada.Command_Line;
with Ada.Text_IO;
with GNU_Multiple_Precision.Big_Integers;
with GNU_Multiple_Precision.Big_Rationals;
use GNU_Multiple_Precision;

procedure Pi_Digits is
   type Int is mod 2 ** 64;
   package Int_To_Big is new Big_Integers.Modular_Conversions (Int);

   
   Zero : constant Big_Integer := Int_To_Big.To_Big_Integer (0);
   One : constant Big_Integer := Int_To_Big.To_Big_Integer (1);
   Two : constant Big_Integer := Int_To_Big.To_Big_Integer (2);
   Three : constant Big_Integer := Int_To_Big.To_Big_Integer (3);
   Four : constant Big_Integer := Int_To_Big.To_Big_Integer (4);
   Ten : constant Big_Integer := Int_To_Big.To_Big_Integer (10);

   
   type LFT is record
      Q, R, S, T : Big_Integer;
   end record;

   
   function Extr (T : LFT; X : Big_Integer) return Big_Rational is
      use Big_Integers;
      Result : Big_Rational;
   begin
      
      
      Big_Rationals.Set_Numerator (Item         => Result,
                                   New_Value    => T.Q * X + T.R,
                                   Canonicalize => False);
      Big_Rationals.Set_Denominator (Item      => Result,
                                     New_Value => T.S * X + T.T);
      return Result;
   end Extr;

   
   function Unit return LFT is
   begin
      
      return LFT'(Q => One, R => Zero, S => Zero, T => One);
   end Unit;

   
   function Comp (T1, T2 : LFT) return LFT is
      use Big_Integers;
   begin
      
      return LFT'(Q => T1.Q * T2.Q + T1.R * T2.S,
                  R => T1.Q * T2.R + T1.R * T2.T,
                  S => T1.S * T2.Q + T1.T * T2.S,
                  T => T1.S * T2.R + T1.T * T2.T);
   end Comp;

   
   K : Big_Integer := Zero;
   function LFTS return LFT is
      use Big_Integers;
   begin
      K := K + One;
      return LFT'(Q => K,
                  R => Four * K + Two,
                  S => Zero,
                  T => Two * K + One);
   end LFTS;

   
   function Next (T : LFT) return Big_Integer is
   begin
      return Big_Rationals.To_Big_Integer (Extr (T, Three));
   end Next;

   
   function Safe (T : LFT; N : Big_Integer) return Boolean is
   begin
      return N = Big_Rationals.To_Big_Integer (Extr (T, Four));
   end Safe;

   
   function Prod (T : LFT; N : Big_Integer) return LFT is
      use Big_Integers;
   begin
      return Comp (LFT'(Q => Ten, R => -Ten * N, S => Zero, T => One), T);
   end Prod;

   procedure Print_Pi (Digit_Count : Positive) is
      Z : LFT := Unit;
      Y : Big_Integer;
      Count : Natural := 0;
   begin
      loop
         Y := Next (Z);
         if Safe (Z, Y) then
            Count := Count + 1;
            Ada.Text_IO.Put (Big_Integers.Image (Y));
            exit when Count >= Digit_Count;
            Z := Prod (Z, Y);
         else
            Z := Comp (Z, LFTS);
         end if;
      end loop;
   end Print_Pi;

   N : Positive := 250;
begin
   if Ada.Command_Line.Argument_Count = 1 then
      N := Positive'Value (Ada.Command_Line.Argument (1));
   end if;
   Print_Pi (N);
end Pi_Digits;