java – 长数组的精确和

前端之家收集整理的这篇文章主要介绍了java – 长数组的精确和前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
为了获得long []的确切总和,我正在使用以下代码段.
public static BigInteger sum(long[] a) {
    long low = 0;
    long high = 0;
    for (final long x : a) {
        low += (x & 0xFFFF_FFFFL);
        high += (x >> 32);
    }
    return BigInteger.valueOf(high).shiftLeft(32).add(BigInteger.valueOf(low));
}

通过处理分成两半的数字并最终组合部分和,它可以正常工作.令人惊讶的是,这种方法也有效:

public static BigInteger fastestSum(long[] a) {
    long low = 0;
    long high = 0;
    for (final long x : a) {
        low += x;
        high += (x >> 32);
    }
    // We know that low has the lowest 64 bits of the exact sum.
    // We also know that BigInteger.valueOf(high).shiftLeft(32) differs from the exact sum by less than 2**63.
    // So the upper half of high is off by at most one.
    high >>= 32;
    if (low < 0) ++high; // Surprisingly,this is enough to fix it.
    return BigInteger.valueOf(high).shiftLeft(64).add(BigInteger.valueOf(low));
}

我不相信最快的Sum应该按原样工作.我相信它可以奏效,但在最后一步还有更多工作要做.但是,它通过了我所有的测试(包括大型随机测试).所以我问:有人可以证明它有效或找到反例吗?

解决方法

fastestSum(new long[]{+1,-1})  => -18446744073709551616
原文链接:https://www.f2er.com/java/129947.html

猜你在找的Java相关文章