我的用例是这个
我希望通过移97173329791011L
来将down
这样的极长数减少为较小的整数,并通过移{{可以从较小的整数中取回长数97173329791011L
1}}。我实现了一个名为up
的函数,如下所示实现
reduceLong
但是,由于产生的结果不正确,因此我觉得我的功能存在某种错误。这是尝试将private int reduceLong(long reduceable) {
return (int) (reduceable >> 32);
}
缩小为较小整数时控制台输出的结果
97173329791011L
非常感谢您的帮助。非常感谢。
答案 0 :(得分:2)
int
数据类型可以容纳[-2 ^ 31,+ 2 ^ 31-1](含)范围内的所有整数值。以十进制表示,即[-2147483648、2147483647]。总范围涵盖2 ^ 32个不同的数字,这是有道理的,因为int是内存中的32位。就像您不能在火柴盒中存储大象一样,您也不能在32位数据中存储无限量的数据。您最多可以存储32位数据。
3706111600L长; (略微)在int的范围之外。二进制形式是:
11011100111001101100011001110000
您如何建议将这64位存储为仅32位?这里没有通用的策略,从数学上讲不可能有这样的策略:您可以长时间存储2 ^ 64个不同的数字,而唯一的值比2 ^ 32多,因此无论您建议使用哪种“压缩”算法,都无法使用除了最多2 ^ 32个唯一的长值,这只是其中的一小部分。
与此分开,运行您的代码段:首先,您执行11011100111001101100011001110000 >> 32,它将除去所有位。 (那里恰好有32位),因此为什么要得到0。
也许您想要这种“压缩”算法:我们认为在此方案中可表示的2 ^ 32长为:
从0到2 ^ 31-1的所有long,方法是将它们映射到相同的整数值,然后再将另一批2 ^ 31 long映射到位之后,通过按位映射将它们紧随其后,尽管在Java中所有数字都有符号,然后将它们映射为负整数。所有其他long值(因此,所有高于2 ^ 32-1的值和所有负的long值)都无法映射(或者,如果尝试,它们将取消映射到错误的值)。
如果需要的话,您需要做的所有事情:
int longToInt = (int) theLong;
long backToLong = 0xFFFFFFFFL & theLong;
通常,如果将int强制转换为长整数,则它会“符号扩展”,用1填充前32位,以表示int为负数。按位&运算将前32位全部清除为0,您又回到了原始... IF 原始long在顶部具有32个零位(3706111600L这样做)。
答案 1 :(得分:1)
您的测试编号太小。 3706111600L
转换为十六进制0x00000000DCE6C670
。
如果将此数字向右移32位,将丢失最后8个半字节;否则,将丢失最后8个半字节。您得出的数字是0x00000000L。强制转换为int,此值仍为0。