public void LogGammaApproxTest()
        {
            Assert.AreEqual(Math.Log(1), Approx.LogGamma(1), 1e-10);
            Assert.AreEqual(Math.Log(1), Approx.LogGamma(2), 1e-10);
            Assert.AreEqual(Math.Log(2), Approx.LogGamma(3), 1e-10);
            Assert.AreEqual(Math.Log(6), Approx.LogGamma(4), 1e-10);
            Assert.AreEqual(Math.Log(24), Approx.LogGamma(5), 1e-10);

            Assert.AreEqual(Math.Log(Math.Sqrt(Math.PI)), Approx.LogGamma(0.5), 1e-10);
            Assert.AreEqual(Math.Log(Math.Sqrt(Math.PI) / 2), Approx.LogGamma(1.5), 1e-10);
            Assert.AreEqual(Math.Log(Math.Sqrt(Math.PI) * 3 / 4), Approx.LogGamma(2.5), 1e-10);
            Assert.AreEqual(Math.Log(Math.Sqrt(Math.PI) * 15 / 8), Approx.LogGamma(3.5), 1e-10);
        }
        public void LogGammaApproxBorderTest()
        {
            {
                List <MultiPrecision <Pow2.N4> > ys = new();

                foreach (MultiPrecision <Pow2.N4> x in TestTool.EnumerateNeighbor((MultiPrecision <Pow2.N4>) 16, 4))
                {
                    MultiPrecision <Pow2.N4> y = MultiPrecision <Pow2.N4> .LogGamma(x);

                    Console.WriteLine(x);
                    Console.WriteLine(x.ToHexcode());
                    Console.WriteLine(y);
                    Console.WriteLine(y.ToHexcode());
                    Console.Write("\n");

                    TestTool.Tolerance(Approx.LogGamma((double)x), y, ignore_sign: true);

                    ys.Add(y);
                }

                TestTool.NearlyNeighbors(ys, 4);
                TestTool.SmoothnessSatisfied(ys, 1);
                TestTool.MonotonicitySatisfied(ys);
            }

            {
                List <MultiPrecision <Pow2.N8> > ys = new();

                foreach (MultiPrecision <Pow2.N8> x in TestTool.EnumerateNeighbor((MultiPrecision <Pow2.N8>) 32, 4))
                {
                    MultiPrecision <Pow2.N8> y = MultiPrecision <Pow2.N8> .LogGamma(x);

                    Console.WriteLine(x);
                    Console.WriteLine(x.ToHexcode());
                    Console.WriteLine(y);
                    Console.WriteLine(y.ToHexcode());
                    Console.Write("\n");

                    TestTool.Tolerance(Approx.LogGamma((double)x), y, ignore_sign: true);

                    ys.Add(y);
                }

                TestTool.NearlyNeighbors(ys, 4);
                TestTool.SmoothnessSatisfied(ys, 1);
                TestTool.MonotonicitySatisfied(ys);
            }

            {
                List <MultiPrecision <Pow2.N16> > ys = new();

                foreach (MultiPrecision <Pow2.N16> x in TestTool.EnumerateNeighbor((MultiPrecision <Pow2.N16>) 60, 4))
                {
                    MultiPrecision <Pow2.N16> y = MultiPrecision <Pow2.N16> .LogGamma(x);

                    Console.WriteLine(x);
                    Console.WriteLine(x.ToHexcode());
                    Console.WriteLine(y);
                    Console.WriteLine(y.ToHexcode());
                    Console.Write("\n");

                    TestTool.Tolerance(Approx.LogGamma((double)x), y, ignore_sign: true);

                    ys.Add(y);
                }

                TestTool.NearlyNeighbors(ys, 4);
                TestTool.SmoothnessSatisfied(ys, 1);
                TestTool.MonotonicitySatisfied(ys);
            }

            {
                List <MultiPrecision <Pow2.N32> > ys = new();

                foreach (MultiPrecision <Pow2.N32> x in TestTool.EnumerateNeighbor((MultiPrecision <Pow2.N32>) 116, 4))
                {
                    MultiPrecision <Pow2.N32> y = MultiPrecision <Pow2.N32> .LogGamma(x);

                    Console.WriteLine(x);
                    Console.WriteLine(x.ToHexcode());
                    Console.WriteLine(y);
                    Console.WriteLine(y.ToHexcode());
                    Console.Write("\n");

                    TestTool.Tolerance(Approx.LogGamma((double)x), y, ignore_sign: true);

                    ys.Add(y);
                }

                TestTool.NearlyNeighbors(ys, 4);
                TestTool.SmoothnessSatisfied(ys, 1);
                TestTool.MonotonicitySatisfied(ys);
            }

            {
                List <MultiPrecision <Pow2.N64> > ys = new();

                foreach (MultiPrecision <Pow2.N64> x in TestTool.EnumerateNeighbor((MultiPrecision <Pow2.N64>) 228, 4))
                {
                    MultiPrecision <Pow2.N64> y = MultiPrecision <Pow2.N64> .LogGamma(x);

                    Console.WriteLine(x);
                    Console.WriteLine(x.ToHexcode());
                    Console.WriteLine(y);
                    Console.WriteLine(y.ToHexcode());
                    Console.Write("\n");

                    TestTool.Tolerance(Approx.LogGamma((double)x), y, ignore_sign: true);

                    ys.Add(y);
                }

                TestTool.NearlyNeighbors(ys, 4);
                TestTool.SmoothnessSatisfied(ys, 1);
                TestTool.MonotonicitySatisfied(ys);
            }

            {
                List <MultiPrecision <Pow2.N128> > ys = new();

                foreach (MultiPrecision <Pow2.N128> x in TestTool.EnumerateNeighbor((MultiPrecision <Pow2.N128>) 456, 4))
                {
                    MultiPrecision <Pow2.N128> y = MultiPrecision <Pow2.N128> .LogGamma(x);

                    Console.WriteLine(x);
                    Console.WriteLine(x.ToHexcode());
                    Console.WriteLine(y);
                    Console.WriteLine(y.ToHexcode());
                    Console.Write("\n");

                    TestTool.Tolerance(Approx.LogGamma((double)x), y, ignore_sign: true);

                    ys.Add(y);
                }

                TestTool.NearlyNeighbors(ys, 4);
                TestTool.SmoothnessSatisfied(ys, 1);
                TestTool.MonotonicitySatisfied(ys);
            }

            {
                List <MultiPrecision <Pow2.N256> > ys = new();

                foreach (MultiPrecision <Pow2.N256> x in TestTool.EnumerateNeighbor((MultiPrecision <Pow2.N256>) 908, 4))
                {
                    MultiPrecision <Pow2.N256> y = MultiPrecision <Pow2.N256> .LogGamma(x);

                    Console.WriteLine(x);
                    Console.WriteLine(x.ToHexcode());
                    Console.WriteLine(y);
                    Console.WriteLine(y.ToHexcode());
                    Console.Write("\n");

                    TestTool.Tolerance(Approx.LogGamma((double)x), y, ignore_sign: true);

                    ys.Add(y);
                }

                TestTool.NearlyNeighbors(ys, 4);
                TestTool.SmoothnessSatisfied(ys, 1);
                TestTool.MonotonicitySatisfied(ys);
            }
        }
        public void LogGammaTest()
        {
            for (int i = 1; i < 200; i++)
            {
                MultiPrecision <Pow2.N8> x = MultiPrecision <Pow2.N8> .Ldexp(MultiPrecision <Pow2.N8> .One, -2) * i;

                MultiPrecision <Pow2.N8> y = MultiPrecision <Pow2.N8> .LogGamma(x);

                Console.WriteLine(x);
                Console.WriteLine(y);

                TestTool.Tolerance(Approx.LogGamma((double)x), y, rateerr: 1e-10, ignore_sign: true);
            }

            Assert.IsTrue(0 == MultiPrecision <Pow2.N8> .LogGamma(1));
            Assert.IsTrue(0 == MultiPrecision <Pow2.N8> .LogGamma(2));

            Assert.IsTrue(
                MultiPrecision <Pow2.N8> .NearlyEqualBits(
                    MultiPrecision <Pow2.N8> .Log(2),
                    MultiPrecision <Pow2.N8> .LogGamma(3),
                    1
                    ));

            Assert.IsTrue(
                MultiPrecision <Pow2.N8> .NearlyEqualBits(
                    MultiPrecision <Pow2.N8> .Log(6),
                    MultiPrecision <Pow2.N8> .LogGamma(4),
                    1
                    ));

            Assert.IsTrue(
                MultiPrecision <Pow2.N8> .NearlyEqualBits(
                    MultiPrecision <Pow2.N8> .Log(24),
                    MultiPrecision <Pow2.N8> .LogGamma(5),
                    1
                    ));

            Assert.IsTrue(
                MultiPrecision <Pow2.N8> .NearlyEqualBits(
                    MultiPrecision <Plus1 <Pow2.N8> > .Log(MultiPrecision <Plus1 <Pow2.N8> > .Sqrt(MultiPrecision <Plus1 <Pow2.N8> > .PI)).Convert <Pow2.N8>(),
                    MultiPrecision <Pow2.N8> .LogGamma(0.5),
                    1
                    ));

            Assert.IsTrue(
                MultiPrecision <Pow2.N8> .NearlyEqualBits(
                    MultiPrecision <Plus1 <Pow2.N8> > .Log(MultiPrecision <Plus1 <Pow2.N8> > .Sqrt(MultiPrecision <Plus1 <Pow2.N8> > .PI) / 2).Convert <Pow2.N8>(),
                    MultiPrecision <Pow2.N8> .LogGamma(1.5),
                    1
                    ));

            Assert.IsTrue(
                MultiPrecision <Pow2.N8> .NearlyEqualBits(
                    MultiPrecision <Plus1 <Pow2.N8> > .Log(MultiPrecision <Plus1 <Pow2.N8> > .Sqrt(MultiPrecision <Plus1 <Pow2.N8> > .PI) * 3 / 4).Convert <Pow2.N8>(),
                    MultiPrecision <Pow2.N8> .LogGamma(2.5),
                    1
                    ));

            Assert.IsTrue(
                MultiPrecision <Pow2.N8> .NearlyEqualBits(
                    MultiPrecision <Plus1 <Pow2.N8> > .Log(MultiPrecision <Plus1 <Pow2.N8> > .Sqrt(MultiPrecision <Plus1 <Pow2.N8> > .PI) * 15 / 8).Convert <Pow2.N8>(),
                    MultiPrecision <Pow2.N8> .LogGamma(3.5),
                    1
                    ));
        }