如何使用库调用计算C#中的阶乘?

如何使用库调用计算C#中的阶乘?,c#,factorial,C#,Factorial,我需要计算100左右的数字的阶乘!为了确定一系列抛硬币样式的数据是否是随机的,正如您在那里看到的,必要的公式包括3个阶乘计算(但有趣的是,其中两个阶乘计算是沿着第三个阶乘计算的) 我看到了,但我认为整数会很快被吹出来。我还可以制作一个关于阶乘计算更智能的函数(即,如果我有11!/(7!3!),根据wiki的例子,我可以转到(11*10*9*8)/3!),但这对我来说有点过早优化的味道,从某种意义上说,我希望它能工作,但我不在乎速度(现在) 那么,我可以调用什么样的C#库来计算阶乘以获得概率呢?我

我需要计算100左右的数字的阶乘!为了确定一系列抛硬币样式的数据是否是随机的,正如您在那里看到的,必要的公式包括3个阶乘计算(但有趣的是,其中两个阶乘计算是沿着第三个阶乘计算的)

我看到了,但我认为整数会很快被吹出来。我还可以制作一个关于阶乘计算更智能的函数(即,如果我有11!/(7!3!),根据wiki的例子,我可以转到(11*10*9*8)/3!),但这对我来说有点过早优化的味道,从某种意义上说,我希望它能工作,但我不在乎速度(现在)


那么,我可以调用什么样的C#库来计算阶乘以获得概率呢?我对阶乘计算中的所有惊人之处不感兴趣,我只想以一种我可以操纵它的方式得到结果。数学名称空间中似乎没有阶乘函数,因此出现了这个问题。

在类似的主题上也有过类似的讨论。那里有人链接了这个网站,其中包括一些关于高效算法甚至C#源代码的解释。

你可以试试——我没有用过这个库,但它们确实列出了阶乘和对数阶乘。

你想计算阶乘还是二项式系数

听起来你想计算二项式系数-尤其是当你提到11/(7!3!)

可能有一个库可以为您做到这一点,但作为(大概)访问堆栈溢出的程序员,没有理由不自己编写一个。不太复杂

为了避免内存溢出,在删除所有公共因素之前不要计算结果

此算法仍需改进,但您在这里有一个好算法的基础。分母值需要分解为它们的主要因子,以获得最佳结果。目前,这将很快运行n=50

float CalculateBinomial(int n, int k)
{
    var numerator = new List<int>();
    var denominator = new List<int>();
    var denominatorOld = new List<int>();

    // again ignore the k! common terms
    for (int i = k + 1; i <= n; i++)
        numerator.Add(i);

    for (int i = 1; i <= (n - k); i++)
    {
        denominator.AddRange(SplitIntoPrimeFactors(i));
    }

    // remove all common factors
    int remainder;                
    for (int i = 0; i < numerator.Count(); i++)
    {
        for (int j = 0; j < denominator.Count() 
            && numerator[i] >= denominator[j]; j++)
        {
            if (denominator[j] > 1)
            {
                int result = Math.DivRem(numerator[i], denominator[j], out remainder);
                if (remainder == 0)
                {
                    numerator[i] = result;
                    denominator[j] = 1;
                }
            }
        }
    }

    float denominatorResult = 1;
    float numeratorResult = 1;

    denominator.RemoveAll(x => x == 1);
    numerator.RemoveAll(x => x == 1);

    denominator.ForEach(d => denominatorResult = denominatorResult * d);
    numerator.ForEach(num => numeratorResult = numeratorResult * num);

    return numeratorResult / denominatorResult;
}

static List<int> Primes = new List<int>() { 2, 3, 5, 7, 11, 13, 17, 19, 
    23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97 };

List<int> SplitIntoPrimeFactors(int x)
{
    var results = new List<int>();
    int remainder = 0;

    int i = 0;
    while (!Primes.Contains(x) && x != 1)
    {
        int result = Math.DivRem(x, Primes[i], out remainder);
        if (remainder == 0)
        {
            results.Add(Primes[i]);
            x = result;
            i = 0;
        }
        else
        {
            i++;
        }
    }
    results.Add(x);
    return results;
}
浮点计算项(int n,int k)
{
变量分子=新列表();
var分母=新列表();
var denominorold=新列表();
//再次忽略k!常用术语
对于(int i=k+1;i 1)
{
int result=Math.DivRem(分子[i],分母[j],余数);
如果(余数==0)
{
分子[i]=结果;
分母[j]=1;
}
}
}
}
浮动分母Result=1;
浮点数结果=1;
分母.RemoveAll(x=>x==1);
分子RemoveAll(x=>x==1);
分母ForEach(d=>DenominorResult=DenominorResult*d);
numerator.ForEach(num=>numeratorResult=numeratorResult*num);
返回数值结果/分母结果;
}
静态列表素数=新列表(){2,3,5,7,11,13,17,19,
23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97 };
列出拆分因子(整数x)
{
var results=新列表();
整数余数=0;
int i=0;
而(!Primes.Contains(x)&&x!=1)
{
int result=Math.DivRem(x,素数[i],余数);
如果(余数==0)
{
结果。添加(素数[i]);
x=结果;
i=0;
}
其他的
{
i++;
}
}
结果:添加(x);
返回结果;
}
我可以估计n=110,k=50(返回6x10^31),但无法使用系统运行n=120,k=50。

using System;
//calculating factorial with recursion
namespace ConsoleApplication2
{
    class Program
    {
        long fun(long a)
        {
            if (a <= 1)
            {
                return 1;}
            else
            {
                long c = a * fun(a - 1);
                return c;
            }}

        static void Main(string[] args)
        {

            Console.WriteLine("enter the number");
            long num = Convert.ToInt64(Console.ReadLine());
            Console.WriteLine(new Program().fun(num));
            Console.ReadLine();
        }
    }
}
//用递归计算阶乘 命名空间控制台应用程序2 { 班级计划 { 长乐趣(长a) {
如果(a以下公式可以在1秒内计算出5000的阶乘

public class Number
{
    #region Fields
    private static long _valueDivision = 1000000000;
    private static int _valueDivisionDigitCount = 9;
    private static string _formatZeros = "000000000";
    List<long> _value;
    #endregion

    #region Properties
    public int ValueCount { get { return _value.Count; } }
    public long ValueAsLong
    {
        get
        {
            return long.Parse(ToString());
        }
        set { SetValue(value.ToString()); }
    }
    #endregion

    #region Constructors
    public Number()
    {
        _value = new List<long>();
    }
    public Number(long value)
        : this()
    {
        SetValue(value.ToString());
    }
    public Number(string value)
        : this()
    {
        SetValue(value);
    }
    private Number(List<long> list)
    {
        _value = list;
    }
    #endregion

    #region Public Methods
    public void SetValue(string value)
    {
        _value.Clear();
        bool finished = false;
        while (!finished)
        {
            if (value.Length > _valueDivisionDigitCount)
            {
                _value.Add(long.Parse(value.Substring(value.Length - _valueDivisionDigitCount)));
                value = value.Remove(value.Length - _valueDivisionDigitCount, _valueDivisionDigitCount);
            }
            else
            {
                _value.Add(long.Parse(value));
                finished = true;
            }
        }
    }
    #endregion

    #region Static Methods
    public static Number operator +(Number c1, Number c2)
    {
        return Add(c1, c2);
    }
    public static Number operator *(Number c1, Number c2)
    {
        return Mul(c1, c2);
    }
    private static Number Add(Number value1, Number value2)
    {
        Number result = new Number();
        int count = Math.Max(value1._value.Count, value2._value.Count);
        long reminder = 0;
        long firstValue, secondValue;
        for (int i = 0; i < count; i++)
        {
            firstValue = 0;
            secondValue = 0;
            if (value1._value.Count > i)
            {
                firstValue = value1._value[i];
            }
            if (value2._value.Count > i)
            {
                secondValue = value2._value[i];
            }
            reminder += firstValue + secondValue;
            result._value.Add(reminder % _valueDivision);
            reminder /= _valueDivision;
        }
        while (reminder > 0)
        {
            result._value.Add(reminder % _valueDivision);
            reminder /= _valueDivision;
        }
        return result;
    }
    private static Number Mul(Number value1, Number value2)
    {
        List<List<long>> values = new List<List<long>>();
        for (int i = 0; i < value2._value.Count; i++)
        {
            values.Add(new List<long>());
            long lastremain = 0;
            for (int j = 0; j < value1._value.Count; j++)
            {
                values[i].Add(((value1._value[j] * value2._value[i] + lastremain) % _valueDivision));
                lastremain = ((value1._value[j] * value2._value[i] + lastremain) / _valueDivision);
                //result.Add(();
            }
            while (lastremain > 0)
            {
                values[i].Add((lastremain % _valueDivision));
                lastremain /= _valueDivision;
            }
        }
        List<long> result = new List<long>();
        for (int i = 0; i < values.Count; i++)
        {
            for (int j = 0; j < i; j++)
            {
                values[i].Insert(0, 0);
            }
        }
        int count = values.Select(list => list.Count).Max();
        int index = 0;
        long lastRemain = 0;
        while (count > 0)
        {
            for (int i = 0; i < values.Count; i++)
            {
                if (values[i].Count > index)
                    lastRemain += values[i][index];
            }
            result.Add((lastRemain % _valueDivision));
            lastRemain /= _valueDivision;
            count -= 1;
            index += 1;
        }
        while (lastRemain > 0)
        {
            result.Add((lastRemain % _valueDivision));
            lastRemain /= _valueDivision;
        }
        return new Number(result);
    }
    #endregion

    #region Overriden Methods Of Object
    public override string ToString()
    {
        string result = string.Empty;
        for (int i = 0; i < _value.Count; i++)
        {
            result = _value[i].ToString(_formatZeros) + result;
        }
        return result.TrimStart('0');
    }
    #endregion
}

class Program
{
    static void Main(string[] args)
    {
        Number number1 = new Number(5000);
        DateTime dateTime = DateTime.Now;
        string s = Factorial(number1).ToString();
        TimeSpan timeSpan = DateTime.Now - dateTime;
        long sum = s.Select(c => (long) (c - '0')).Sum();
    }
    static Number Factorial(Number value)
    {
        if( value.ValueCount==1 && value.ValueAsLong==2)
        {
            return value;
        }
        return Factorial(new Number(value.ValueAsLong - 1)) * value;
    }
}
公共类编号
{
#区域字段
私有静态长期价值分割=100000000;
私有静态int_valueDivisionDigitCount=9;
私有静态字符串_formatZeros=“000000000”;
列表值;
#端区
#区域属性
public int ValueCount{get{return\u value.Count;}}
公共长期价值
{
得到
{
返回long.Parse(ToString());
}
set{SetValue(value.ToString());}
}
#端区
#区域构造函数
公众号码()
{
_值=新列表();
}
公共编号(长值)
:此()
{
SetValue(value.ToString());
}
公共编号(字符串值)
:此()
{
设置值(值);
}
私人号码(名单)
{
_值=列表;
}
#端区
#区域公共方法
公共void设置值(字符串值)
{
_value.Clear();
bool finished=false;
当(!完成)
{
如果(value.Length>\u valueDivisionDigitCount)
{
_value.Add(long.Parse(value.Substring(value.Length-_valueDivisionDigitCount));
value=value.Remove(value.Length-\u valuedivisionidigitcount,\u valuedivisionidigitcount);
}
其他的
{
_value.Add(long.Parse(value));
完成=正确;
}
}
}
#端区
#区域静态方法
公共静态编号运算符+(编号c1,编号c2)
{
返回Add(c1,c2);
}
公共静态编号运算符*(编号c1,编号c2)
{
返回Mul(c1,c2);
}
专用静态编号添加(编号值1、编号值2)
{
编号结果=新编号();
int count=Math.Max(value1.\u value.count,value2.\u value.count);
长提醒=0;
长第一值,第二值;
for(int i=0;ii)
{
firstValue=值1._值[i];
}
如果(瓦卢)
        int fac = 1;

        int[] facs = new int[array.Length+1];

        for (int i = 0; i < array.Length; i++)
        {
            for (int j = array[i]; j > 0; j--)
            {
                fac *= j;
            }
            facs[i] = fac;
            textBox1.Text += facs[i].ToString() + " ";
            fac = 1;
        }`