通过位移将Java中的long减少为整数

时间:2019-02-22 13:59:40

标签: java

我的用例是这个

我希望通过移97173329791011L来将down这样的极长数减少为较小的整数,并通过移{{可以从较小的整数中取回长数97173329791011L 1}}。我实现了一个名为up的函数,如下所示实现

reduceLong

但是,由于产生的结果不正确,因此我觉得我的功能存在某种错误。这是尝试将private int reduceLong(long reduceable) { return (int) (reduceable >> 32); } 缩小为较小整数时控制台输出的结果

97173329791011L

非常感谢您的帮助。非常感谢。

2 个答案:

答案 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。