要吐出的值范围超过64的块数

问题描述 投票:0回答:2

我有以下代码:

long[] blocks = new long[(someClass.getMemberArray().length - 1) / 64 + 1];  

基本上someClass.getMemberArray()可以返回一个可能比64大得多的数组,并且代码尝试确定需要多少len 64的块来进行后续处理。我对逻辑及其工作方式感到困惑。在我看来,只是在做:

 long[] blocks = new long[(int) Math.ceil(someClass.getMemberArray().length / 64.0)];  

应该工作也看起来更简单。有人可以帮助我理解原始摘要中的-1+1推理,其工作原理以及ceil在某些情况下是否会失败?

java arrays math integer integer-division
2个回答
0
投票

我不知道为什么需要-1,但是+1可能会纠正除法结果四舍五入到最接近的非十进制值的情况(嗯,应该是情况除外,除非结果没有小数位)


0
投票

正如您正确评论的那样,需要-1 / + 1才能获得正确数量的块,包括仅部分填充的块。有效地四舍五入。

(但是它有一些可能被认为是一个错误:如果数组的长度为0,需要0个块,它将返回1。这是因为整数除法通常在大多数系统上都被截断,即对负数进行四舍五入,因此(0-1)/ 64产生0。但是,由于某些原因不允许零块,这可能是一个功能。尽管如此,它肯定需要注释。)

第一行原始行的原因是,它仅使用整数算术,在大多数计算机上,这仅应转换为一些基本且快速的机器指令。

第二种解决方案涉及强制转换浮点算法和强制转换。传统上,大多数处理器上的浮点运算速度要慢得多,这可能是第一个解决方案的原因。但是,在具有集成浮点支持的现代CPU上,性能更多地取决于其他因素,例如高速缓存行和流水线。

就个人而言,我不太喜欢这两种解决方案,因为它们的作用并不十分明显。因此,我建议以下解决方案:

int arrayLength = someClass.getMemberArray().length;
int blockCount = ceilDiv(arrayLength, 64);
long[] blocks = new long[blockCount];

//...

/**
 * Integer division, rounding up.
 * @return the quotient a/b, rounded up.
 */
static int ceilDiv(int a, int b) {
    assert b >= 0 : b; // Doesn't work for negative divisor.

    // Divide.
    int quotient = a / b;

    // If a is not a multiple of b, round up.
    if (a % b != 0) {
        quotient++;
    }

    return quotient;
}

这是罗word的,但至少很清楚应该发生什么,并且它提供了适用于所有整数(负除数除外)的通用解决方案。不幸的是,大多数语言都没有提供优雅的“舍入整数除法”解决方案。

© www.soinside.com 2019 - 2024. All rights reserved.