我只是想将我在C / C ++中编写的以下方法转换为Java。简而言之,代码提供了一种非常有效的方法来计算设置为1的数字的最左侧和最右侧位的索引。这两种方法基于Knuth的计算机编程艺术,第4卷中的代码。
// Returns index of the left-most bit of x that is one in the binary
// expansion of x. Assumes x > 0 since otherwise lambda(x) is undefined.
// Can be used to calculate floor(log(x, 2)), the number of binary digits
// of x, minus one.
int lambda(unsigned long x) {
double y = (double) x;
// Excuse the monstrocity below. I need to have a long that has the raw
// bits of x in data. Simply (long)y would yield x back since C would cast
// the double to a long. So we need to cast it to a (void *) so that C
// "forgets" what kind of data we are dealing with, and then cast it to
// long.
unsigned long xx = *((long *)((void*)&y));
// The first 52 bits are the the significant. The rest are the sign and
// exponent. Since the number is assumed to be positive, we don't have to
// worry about the sign bit being 1 and can simply extract the exponent by
// shifting right 52 bits. The exponent is in "excess-1023" format so we
// must subtract 1023 after.
return (int)(xx >> 52) - 1023;
}
// Returns the index of the right-most one bit in the binary expansion of x
int rho(unsigned long x) {
return lambda(x & -x);
}
正如你所看到的,我需要有一个具有相同位的double,但没有void*
强制转换,我不知道如何在Java中执行此操作。有什么想法吗?它甚至可能吗?
答案 0 :(得分:2)
有一个静态函数doubleToLongBits()
来执行类型转换。
long xx = Double.doubleToLongBits(y);
return (int) (xx >>> 52) - 1023;
注意>>>
在向右移动时将long视为无符号值。
阅读评论,但听起来你想要的是number of leading zeros.
的简单功能return 63 - Long.numberOfLeadingZeros(x);
我猜这在大多数现有架构上都更有效,但您必须对其进行分析才能确定。有一个类似的“尾随零”方法来计算你的rho()
函数。