Task: Arithmetic-geometric mean


C++: 

#include "gmp.h"

void agm (const mpf_t in1, const mpf_t in2, mpf_t out1, mpf_t out2) {
	mpf_add (out1, in1, in2);
	mpf_div_ui (out1, out1, 2);
	mpf_mul (out2, in1, in2);
	mpf_sqrt (out2, out2);
}

int main (void) {
	mpf_set_default_prec (65568);
	mpf_t x0, y0, resA, resB;

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

	for(int i=0; i<7; i++){
		agm(x0, y0, resA, resB);
		agm(resA, resB, x0, y0);
	}
	gmp_printf ("%.20000Ff\n", x0);
	gmp_printf ("%.20000Ff\n\n", y0);

	return 0;
}


C#: namespace RosettaCode.ArithmeticGeometricMean
{
    using System;
    using System.Collections.Generic;
    using System.Globalization;

    internal static class Program
    {
        private static double ArithmeticGeometricMean(double number,
                                                      double otherNumber,
                                                      IEqualityComparer<double>
                                                          comparer)
        {
            return comparer.Equals(number, otherNumber)
                       ? number
                       : ArithmeticGeometricMean(
                           ArithmeticMean(number, otherNumber),
                           GeometricMean(number, otherNumber), comparer);
        }

        private static double ArithmeticMean(double number, double otherNumber)
        {
            return 0.5 * (number + otherNumber);
        }

        private static double GeometricMean(double number, double otherNumber)
        {
            return Math.Sqrt(number * otherNumber);
        }

        private static void Main()
        {
            Console.WriteLine(
                ArithmeticGeometricMean(1, 0.5 * Math.Sqrt(2),
                                        new RelativeDifferenceComparer(1e-5)).
                    ToString(CultureInfo.InvariantCulture));
        }

        private class RelativeDifferenceComparer : IEqualityComparer<double>
        {
            private readonly double _maximumRelativeDifference;

            internal RelativeDifferenceComparer(double maximumRelativeDifference)
            {
                _maximumRelativeDifference = maximumRelativeDifference;
            }

            public bool Equals(double number, double otherNumber)
            {
                return RelativeDifference(number, otherNumber) <=
                       _maximumRelativeDifference;
            }

            public int GetHashCode(double number)
            {
                return number.GetHashCode();
            }

            private static double RelativeDifference(double number,
                                                     double otherNumber)
            {
                return AbsoluteDifference(number, otherNumber) /
                       Norm(number, otherNumber);
            }

            private static double AbsoluteDifference(double number,
                                                     double otherNumber)
            {
                return Math.Abs(number - otherNumber);
            }

            private static double Norm(double number, double otherNumber)
            {
                return 0.5 * (Math.Abs(number) + Math.Abs(otherNumber));
            }
        }
    }
}