2014-03-12 57 views
1

我只是试图将我在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); 
} 

正如你所看到的,我需要有一个长期具有双重的同位,但没有void*投,我不确定如何在Java中执行此操作。有什么想法吗?它甚至有可能吗?

+1

请注意,您开始使用的“C/C++”代码不起作用:它会打破严格的别名规则,即使中间转换为void *也是如此。只有大多数编译器根据程序员的意图生成代码。在C中,'memcpy()'或联合是访问表示的合适方式。 –

回答

2

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

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

注意>>>将右对齐时的无符号值视为long。

阅读评论,不过,这听起来像你想要的是的number of leading zeros.

return 63 - Long.numberOfLeadingZeros(x); 

我猜想,这是大多数目前的架构更有效率的一个简单的功能,但你不得不简介它为了确定。有一个类似的“尾随零”方法来计算你的rho()函数。

相关问题