java如何将32位int移位32(再次)
好的,所以我知道通常的左移位和右移位只针对值0..31
定义得很好。我在考虑如何最好地将其扩展到32,从而简化一些算法。我想到了:
int32 << n & (n-32) >> 5
这似乎有效。问题是,它是否保证在任何体系结构(C,C++,java)上工作,并且能更有效地工作吗?p>
你可以在下面搜索框中键入要查询的问题!
好的,所以我知道通常的左移位和右移位只针对值0..31
定义得很好。我在考虑如何最好地将其扩展到32,从而简化一些算法。我想到了:
int32 << n & (n-32) >> 5
这似乎有效。问题是,它是否保证在任何体系结构(C,C++,java)上工作,并且能更有效地工作吗?p>
# 1 楼答案
在Java中,如果这些变量的类型为
int
,那么它就可以保证工作,因为Java中的>>
会进行算术右移,并且移位超过31也有定义的行为。但要注意运算符优先级这将适用于班次计数最多32次。但它可以修改为包含移位计数大于31的任何int值返回0
<>但是,在C和C++中,^ {< CD1>}的大小和^ {< CD2>}的行为是implementation defined。不过,大多数(如果不是全部的话)现代实现都将其作为有符号类型的算术移位来实现。此外,移动超过可变宽度的行为是undefined。更糟糕的是,有符号溢出调用UB,所以即使左移31也会调用UB(until C++14)。因此,要获得定义良好的输出,您需要uint32_t
这样的无符号固定宽度类型(因此x << 31
不是UB)>>
发出算术右移指令的编译器,对n
使用有符号类型,或者自己实现算术右移int32_t
的移位量限制为5位结果就是
如果体系结构支持conditional instructions如x86或ARM,那么下面的方法可能会更快
在64位平台上,您可以通过在64位类型中进行移位,然后进行掩码操作,使这一过程变得更加简单。一些32位平台,比如ARM,确实支持32位移位,所以这种方法也很有效
您可以看到输出程序集here。我看不出还有什么可以改进的