Java 要在64以上的值范围内吐出的块数
我有以下代码:Java 要在64以上的值范围内吐出的块数,java,arrays,math,integer,integer-division,Java,Arrays,Math,Integer,Integer Division,我有以下代码: long[] blocks = new long[(someClass.getMemberArray().length - 1) / 64 + 1]; 基本上,someClass.getMemberArray()可以返回一个比64大得多的数组,代码尝试确定后续处理需要多少个len 64块。 我对逻辑和它是如何工作的感到困惑。在我看来,只是做: long[] blocks = new long[(int) Math.ceil(someClass.getMemberArray
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
是否会失败吗?我不明白为什么需要-1,但是+1可能会纠正除法结果向下舍入到最接近的非十进制值的情况(除结果没有小数的情况外,其他情况都应该如此)正如您正确评论的那样,需要-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;
}
这很冗长,但至少清楚应该发生什么,并且它提供了一个适用于所有整数(负除数除外)的通用解决方案。不幸的是,大多数语言都不提供优雅的“整数除法取整”解决方案。如果
someClass.getMemberArray().length
为64,则如果不使用减法,结果将是2而不是1。因此,计算是正确的。我对这背后的直觉有点困惑,我更喜欢你的解决方案,而不是你发布这篇文章。我也想了解第一个的原始想法。我的意思是-1/+1背后的直觉是什么?我不明白。