Javascript Euler#1项目:不同方法不一致结果背后的原因

Javascript Euler#1项目:不同方法不一致结果背后的原因,javascript,Javascript,我编写了两种方法来解决这个问题。一种是使用for循环,另一种是使用AP系列公式 function usingAP (limit) { var sum3 = sumAP(3, 3, Math.floor((limit - 1) / 3)), sum5 = sumAP(5, 5, Math.floor((limit - 1) / 5)), sum15 = sumAP(15, 15, Math.floor((limit -1 ) / 15)); retu

我编写了两种方法来解决这个问题。一种是使用for循环,另一种是使用AP系列公式

function usingAP (limit) {
    var sum3 = sumAP(3, 3, Math.floor((limit - 1) / 3)),
        sum5 = sumAP(5, 5, Math.floor((limit - 1) / 5)),
        sum15 = sumAP(15, 15, Math.floor((limit -1 ) / 15));
    return sum5 - sum15 + sum3;
}

//function usingFor (limit) {
//    var sum = 0;
//    for (; limit--; ) {
//        if (limit % 3 === 0 || limit % 5 === 0) {
//            sum += limit;
//        }
//    }
//    return sum;
//}

function usingFor (limit) {
    var sum = 0,
        sum1 = 0,
        conflictThreshold = 196474635,
        useComparisonSeriesToDebugGlitch = limit > conflictThreshold,
        isFirstTerm = true,
        diff = NaN;
    for (; limit--; ) {
        if (limit % 3 === 0 || limit % 5 === 0) {
            sum += limit;
        }
        if (useComparisonSeriesToDebugGlitch) {
            if (!isFirstTerm) {
                if (limit % 3 === 0 || limit % 5 === 0) {
                    sum1 += limit;
                }
            } else {
                isFirstTerm = false;
            }
            if (sum - sum1 - conflictThreshold !== diff) {
                diff = sum - sum1 - conflictThreshold;
                console.log(limit, '|', sum, '|', sum1, '|', diff);
            }
        }
    }
    return sum;
}
在达到某个限制(conflictThreshold)之前,这两个方法对相同的参数给出相同的结果。对于任何大于该值的极限,我都会得到不一致的结果

======196474635======
using AP: 9007199081385435
using for loop: 9007199081385435
我已经设置了一些日志,以查找此故障背后的原因

下面是一致结果的输出外观

======196474635======
using AP: 9007199081385435
using for loop: 9007199081385435
下面是不一致结果的情况:

======limit: 196474636======
using AP: 9007199277860070
196474635 '|' 196474635 '|' 0 '|' 0
9951 '|' 9007199254757828 '|' 9007199058283192 '|' 1
9945 '|' 9007199254787672 '|' 9007199058313035 '|' 2
9939 '|' 9007199254817492 '|' 9007199058342856 '|' 1
9935 '|' 9007199254837364 '|' 9007199058362727 '|' 2
...
2545 '|' 9007199276348940 '|' 9007199079874552 '|' -247
2541 '|' 9007199276354024 '|' 9007199079879637 '|' -248
2535 '|' 9007199276361636 '|' 9007199079887250 '|' -249
2529 '|' 9007199276369228 '|' 9007199079894841 '|' -248
2525 '|' 9007199276374280 '|' 9007199079899892 '|' -247
...
9 '|' 9007199277859724 '|' 9007199081385421 '|' -332
5 '|' 9007199277859736 '|' 9007199081385432 '|' -331
3 '|' 9007199277859740 '|' 9007199081385435 '|' -330
using for loop: 9007199277859740

我正试着去想一想。非常感谢您的帮助。

我不知道您是否愿意只使用Javascript,但以下是我提出的解决方案:

<html>
<body>
    <p id="demo"></p>
    <script text="javascript">
        var x = 0
        var y = 0

        while (x<1000){
            if ((x%3==0)||(x%5==0)){
            y=y+x;
            }
            x+=1;
        }
        document.getElementById("demo").innerHTML = y;
    </script>
</body>
</html>

变量x=0 变量y=0
而(x您使用的数字大于
Number.MAX_SAFE_INTEGER
。双精度浮点数字不能表示
9007199254740991
之外的连续整数集;存在“漏洞”除此之外,在数字行中。因此,您将得到不准确的结果。

我不知道您在问什么。请检查并更新您的问题,使其成为一个具体的可回答问题,而不是代码转储和一些注释。这个问题可以用一个简单的公式解决,无需循环。请阅读卡尔·弗里德里希·高斯:)我重新措辞了我的问题。我想了解这些方法无法提供正确答案的原因。我也实现了这个解决方案。事实证明,它的速度很慢,限制很大,因此还有其他解决方案。本文中提到了类似的事情:“例如,Number.MAX\u SAFE\u INTEGER+1===Number.MAX\u SAFE\u INTEGER+2将计算为true,这在数学上是不正确的。”