简体   繁体   English

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

[英]Reducing a long to an integer in java via bit shifting

My use case is this, 我的用例是这样,

I wish to reduce an extremely long number like 97173329791011L to a smaller integer by shifting down and be able to get back the long number 97173329791011L from the smaller integer by shifting up .I have implemented a function called reduceLong to implement this as shown below 我希望通过down移位将极长的数字(如97173329791011L为较小的整数,并能够通过up移位的97173329791011L从较小的整数中获取较长的数字( 97173329791011L 。我实现了一个称为reduceLong的函数,如下所示

private int reduceLong(long reduceable) {
        return (int) (reduceable >> 32);
    }

However, I feel the function I have is in a way wrong as the result produced is incorrect. 但是,我感觉到我拥有的功能有问题,因为生成的结果不正确。 Here is the result from my console output when trying to reduce 97173329791011L to a smaller integer 这是尝试将97173329791011L减小为较小整数时控制台输出的结果

Trying to reduce 97173329791011L
Result= 0

Your help would be greatly appreciated. 您的帮助将不胜感激。 Thanks alot. 非常感谢。

The int datatype can hold all integral values in the range [-2^31, +2^31-1], inclusive. int数据类型可以保存[-2 ^ 31,+ 2 ^ 31-1](包括)范围内的所有整数值。 That's, in decimal, [-2147483648, 2147483647]. 以十进制表示,即[-2147483648、2147483647]。 The total range covers 2^32 different numbers, and that makes sense because ints are 32 bits in memory. 总范围涵盖2 ^ 32个不同的数字,这是有道理的,因为int是内存中的32位。 Just like you can't store an elephant in a matchbox, you can't store an infinite amount of data in 32 bits worth of data. 就像您不能在火柴盒中存储大象一样,您也不能在32位数据中存储无限量的数据。 You can store at most... 32 bits worth of data. 您最多可以存储32位数据。

3706111600L is a long; 3706111600L长; it is (slightly) outside of the range of the int. (略微)在int的范围之外。 In binary, it is: 用二进制表示:

11011100111001101100011001110000

How do you propose to store these 64 bits into a mere 32 bits? 您如何建议将这64位存储为仅32位? There is no general strategy here, and that is mathematically impossible to have: You can store exactly 2^64 different numbers in a long, and that's more unique values than 2^32, so whatever 'compression' algorithm you suggest, it cannot work except for at most 2^32 unique long values, which is only a very small number of them. 这里没有通用的策略,从数学上讲不可能有这样的策略:您可以长时间存储2 ^ 64个不同的数字,而唯一的值比2 ^ 32多,因此无论您建议使用哪种“压缩”算法,都无法使用除了最多2 ^ 32个唯一的long值之外,这只是其中的一小部分。

Separate from that, running your snippet: first, you do 11011100111001101100011001110000 >> 32, which gets rid of all of the bits. 与此不同的是,运行您的代码段:首先,执行11011100111001101100011001110000 >> 32,它将除去所有位。 (there are exactly 32 bits there), hence why you get 0. (那里恰好有32位),因此为什么要得到0。

Perhaps you want this 'compression' algorithm: The 2^32 longs we decree as representable in this scheme are: 也许您想要这种“压缩”算法:我们认为在该方案中可表示的2 ^ 32长为:

all the longs from 0 to 2^31-1, by mapping them to the same integer value, and then also another batch of 2^31 longs that immediately follow that, by mapping them bitwise, although, given that in java all numbers are signed, these then map to negative ints. 从0到2 ^ 31-1的所有long,方法是将它们映射到相同的整数值,然后再通过按位映射它们,紧接着跟在其后的另一批2 ^ 31 long,尽管在Java中所有数字都是签名,然后将它们映射为负整数。 All other long values (so all values above 2^32-1 and all negative longs) cannot be mapped (or if you try, they'd unmap to the wrong value). 所有其他长值(因此,所有高于2 ^ 32-1的值和所有负长值)都无法映射(或者,如果尝试这样做,它们将取消映射到错误的值)。

If you want that, all you need to do: 如果需要,您需要做的所有事情:

int longToInt = (int) theLong;
long backToLong = 0xFFFFFFFFL & theLong;

Normally if you cast an int to a long it 'sign extends', filling the top 32 bits with 1s to represent the fact that your int is negative. 通常,如果将int强制转换为long,则它会“符号扩展”,用1填充前32位,以表示int为负数。 The bitwise & operation clears the top 32 bits all back down to 0 and you're back to your original... IF the original long had 32 zero-bits at the top (which 3706111600L does). 按位&运算将前32位全部清除为0,然后返回到原始... 如果原始long在顶部具有32个零位(3706111600L这样做)。

Your test number is too small. 您的考试编号太小。 Converted into Hexadecimal, 3706111600L is 0x00000000DCE6C670 . 转换为十六进制的3706111600L0x00000000DCE6C670 If you shift this number 32 bits to the right, you will lose the last 8 nibbles; 如果将此数字向右移32位,将丢失最后8个半字节;否则,将丢失最后8个半字节。 your resulting number is 0x00000000L. 您得到的数字是0x00000000L。 Casted to int this value is still 0. 强制转换为int,此值仍为0。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM