为什么计算1 /(n * log(n)-n)会损坏计算机?

时间:2018-11-05 21:21:30

标签: php math sum inverse

最近我偶然发现了问题Wolfram says sum diverges, but Mathematica gives a numerical value。它说1/(n * log(n) - n)是不可求和的(或在数学上没有收敛为正确的)。有趣的一点是,尽管事实是“不可求和的”,我们仍然可以尝试以数字方式计算总和。 Mathematica给出〜6.1作为数字答案。

好。我认为,让我们尝试在该系列求和的PHP脚本中重现该数字(或类似内容)。我的代码是:

$formula = function ($n) {return 1/($n * log($n) - $n);};
$n=2;
$sum=0;

while(true) {
    $term_n = $formula($n);
    $sum += $term_n;
    if ($n++ % 100000 == 0) {
        if ($sum > 5.8)
            usleep(1000);
        echo "n=".number_format($n-1)."; sum={$sum}; error={$term_n}\n";
    }
}

我的算法一直计算答案,直到5.866,然后发生两件事之一:

  1. Ubuntu都崩溃/冻结
  2. 或者Linux杀死了我的计算脚本进程

这发生在大约3400万次迭代之后。

后来,我检查了与计算更多系列项相关的CPU负载如何变化。

现在,有趣的部分: 在大约2千2百万次迭代中,内核之间很难切换任务: enter image description here

后来,在大约3,300万次迭代中,内核达到了无可挽回的地步-他们根本拒绝工作: enter image description here

问题是-总和5.866有什么特别之处,以至于它使计算机崩溃?-考虑到迭代次数N既不是非常大(仅为3400万),也不是第N个词非常小(仅为1.7E-9),因此没有任何奇异的原因。

2 个答案:

答案 0 :(得分:2)

只是个猜测,但听起来计算机内存不足。您的脚本没有显式分配任何内存,但是也许您的PHP版本存在错误并以某种方式泄漏了内存。

如果可用内存耗尽,则确实可能导致正在运行的OS崩溃,或提示它杀死脚本以保护自己。

如果系统开始大量使用交换空间来进行补偿,那将使您的脚本暂时停止运行,从而导致您观察到的CPU图形出现波动。

答案 1 :(得分:0)

我将问题的根源缩小了-在脚本中执行的函数调用越多-内存泄漏越多。而且,调用哪个函数都没有关系-用户定义的,sin(),log()或min(,)或其他任何函数。因此,我怀疑这是PHP内核中的错误,它会在某些特定条件/操作系统内核下发生。

测试代码:

define('AMOUNT', 2000000);

if ($argc == 1)
    for ($i=AMOUNT; $i <= 3*AMOUNT; $i+=AMOUNT) 
        shell_exec('php ' . __FILE__ . " {$i}");
else 
    for ($i=0; $i < $argv[1]; $i++)
        sin(1);
    /*
    Change line above into something without a function call to stop memory leak :
    $x++; // for example
    */

产生这样的内存泄漏图:

enter image description here