计算一个非常大的数字

时间:2016-11-07 17:55:05

标签: c#

我有一个计算阶乘和组合的函数如下。

    int faktorial(int n)
    {
        if( (n == 0)||(n == 1))
        {
            return (1);
        }
        else
        {
            return (n * faktorial(n-1));
        }
    }

    int Kombinasi(int x, int y)
    {
        int n = faktorial(x);
        int k = (faktorial(x - y)) * (faktorial(y));
        int hasil = n / k;
        return (hasil);
    }

但是在计算阶乘时存在问题。 假设我想计算x = 1000和y = 4的组合。现有的呼叫因子函数组合的功能。但是阶乘函数无法计算它们。如何解决这个问题呢 ?。抱歉,我的英语很不好。感谢。

4 个答案:

答案 0 :(得分:2)

BigInteger可以正常工作,并且速度很快!。

BigInteger faktorial(BigInteger n)
{
    if ((n == 0) || (n == 1))
    {
        return (1);
    }
    else
    {
        return (n * faktorial(n - 1));
    }
}

BigInteger Kombinasi(BigInteger x, BigInteger y)
{
    BigInteger n = faktorial(x);
    BigInteger k = (faktorial(x - y)) * (faktorial(y));
    BigInteger hasil = n / k;
    return (hasil);
}

答案:

  

4023872600770937735437024339230039857193748642107146325437999104299385123986290205920442084869694048004799886101971960586316668729948085589013238296699445909974245040870737599188236277271887325197795059509952761208749754624970436014182780946464962910563938874378864873371191810458257836478499770124766328898359557354325131853239584630755574091142624174743493475534286465766116677973966688202912073791438537195882498081268678383745597317461360853795345242215865932019280908782973084313928444032812315586110369768013573042161687476096758713483120254785893207671691324484262361314125087802080002616831510273418279777047846358681701643650241536913982812648102130927612448963599287051149649754199093422215668325720808213331861168115536​​158365469840467089756029009505376164758477284218896796462449451607653534081989013854424879849599533191017233555566021394503997362807501378376153071277619268490343526252000158885351473316117021039681759215109077880193931781141945452572238655414610628921879602238389714 7608850627686296714667469756291123408243920816015378088989396451826324367161676217916890977991190375403127462228998800519544441428201218736174599264295658174662830295557029902432415318161721046583203678690611726015878352075151628422554026517048330422614397428693306169089796848259012545832716822645806652676995865268227280707578139185817888965220816434834482599326604336766017699961283186078838615027946595513115655203609398818061213855860030143569452722420634463179746059468257310379008402443243846565724501440282188525247093519062092902313649327349756551395872055965422874977401141334696271542284586237738753823048386568897646192738381490014076731044664025989949022222176590433990188601856652648506179970235619389701786004081188972991831102117122984590164192106888438712185564612496079872290851929681937238864261483965738229112312502418664935314397013742853192664987533721894069428143411852015801412334482801505139969429015348307764456909907315243327828826986460278986432113908350621709500259738986 3554277196742822248757586765752344220207573630569498825087968928162753848863396909959826280956121450994871701244516461260379029309120889086942028510640182154399457156805941872748998094254742173582401063677404595741785160829230135358081840096996372524230560855903700624271243416909004153690105933983835777939410970027753472000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

注意,但它似乎在8889左右溢出堆栈!。

答案 1 :(得分:1)

首先,要回答您的问题 - 如果您使用

,您可以处理更大的值(最多2 ^ 64 - 1)
ulong c;

第二,一点帮助 - 这对你的锻炼没有帮助。即使是unsigned long也无法处理如此大的值。但是,请注意,要获得(n选择k),您可以简单地计算(n *(n - 1)* .... *(n - k + 1))/ k !,它处理更小的值

答案 2 :(得分:1)

由于看起来你真正想做的是计算二项式系数,使用BigInteger的另一种方法是利用因子的一些数值属性。因此,不是直接计算阶乘(可能很大),而是可以这样做:

long Kombinasi(long x, long y)
{
    if( y == 0 ) return 1;
    return ( x * Kombinasi( x - 1, y - 1 ) ) / y;
}

如果您需要更大的值,也可以将此算法与BigInteger结合使用:

BigInteger Binomial( BigInteger n, BigInteger k )
{
    if( k <= 0 ) return 1;
    return ( n * Binomial( n - 1, k - 1 ) ) / k;
}

这比计算阶乘和除法更有效,因为它利用了大多数阶乘项抵消的事实。它也会执行较少的乘法运算,尤其是k很小的情况。

答案 3 :(得分:0)

正如其他成员所建议的,我们可以使用BitInteger来表示大数字。 我不知道它是否有用,但我想在这里解释一点。

所以我们假设我们有一个带有大值(int.Max)的signed int,如果你试图添加一些正整数值(10),它就不会给你System.OverflowException。它只是给你负值。所以如果你想在这种情况下引发异常。您可以使用checked关键字。如果表达式生成的值超出目标类型的范围。如果表达式包含一个或多个非常量值,则编译器不会检测溢出。可以使用checked关键字启用溢出检查。因此,当您尝试上面提到的内容时,它会抛出异常,您可以相应地处理它。

checked in C#