是否有可能在内存中获得双倍的原始位?

时间:2014-03-12 05:21:50

标签: java

我只是想将我在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中执行此操作。有什么想法吗?它甚至可能吗?

1 个答案:

答案 0 :(得分:2)

有一个静态函数doubleToLongBits()来执行类型转换。

long xx = Double.doubleToLongBits(y);
return (int) (xx >>> 52) - 1023;

注意>>>在向右移动时将long视为无符号值。

阅读评论,但听起来你想要的是number of leading zeros.

的简单功能
return 63 - Long.numberOfLeadingZeros(x);

我猜这在大多数现有架构上都更有效,但您必须对其进行分析才能确定。有一个类似的“尾随零”方法来计算你的rho()函数。