为什么此代码在一定限制后不回复nCr?

时间:2013-08-15 23:41:30

标签: c limit combinations long-integer combinatorics

这是从this similar question的解决方案复制的代码。梳理后(100,50),为什么会失败? 我相信它不应该超过长期的限制。如果确实如此,我不应该期望运行时错误而不是错误的答案。

  long long comb(long long n, long long r) {
        long long limit = r;
        if(r>(n-r))
            limit = n-r;
        long long sum = 1;
        long long i=0;
        while(i<limit){
            sum *= n-i;
            sum /= i+1;
            i++;        
        }
        return sum % 1000000007;
    }

我对100C50%1000000007的正确答案是538992043(使用pascal三角法计算)而不是354365244.

2 个答案:

答案 0 :(得分:1)

我认为您应该阅读您的尖锐答案,然后尝试模拟一些代码。 最有可能的问题是,如你的尖锐答案所示,整数溢出。

在阅读long long声明时,C只被强制分配它认为应该的空间;换句话说,根据平台,long long可以分配可变数量的字节,不会短于C约定设置的限制。

This帖子应该启发您关于该语言的这一特定方面的内容。

另一方面,假设您传递给C ++,您可以使用专用的Decimal类来存储数字的数字,然后删除long long int内存大小问题。

关于运行时错误,如果您正在尝试写入未分配的数据,则不需要C来提醒。假设您有一个unsigned int(根据定义,它至少可以存储0到65535之间的数字(参见this))。如果你试着写一个比那个更高的数字,比如70000,那么C会乐意写出来;但是你声明的int将存储一个荒谬的数字。发生了什么是写70000,C必须写一个比int更多的字节。它会写,但结果将是垃圾。 如果您尝试访问并写入&#34; protected&#34;它只会产生运行时错误。存储器中。

您也可以尝试使用unsigned long long int(对于遵循C99标准的编译器)保证至少保持0到18446744073709551615之间的数字。

答案 1 :(得分:0)

我可能错了,但对我而言,似乎你计算100!/(50!^ 2)大约是1 * 10 ^ 29而无符号long long int只能处理18,446,744,073,709,551,615。所以这将是溢出的情况。