簡體   English   中英

通過位移將Java中的long減少為整數

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

我的用例是這樣,

我希望通過down移位將極長的數字(如97173329791011L為較小的整數,並能夠通過up移位的97173329791011L從較小的整數中獲取較長的數字( 97173329791011L 。我實現了一個稱為reduceLong的函數,如下所示

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

但是,我感覺到我擁有的功能有問題,因為生成的結果不正確。 這是嘗試將97173329791011L減小為較小整數時控制台輸出的結果

Trying to reduce 97173329791011L
Result= 0

您的幫助將不勝感激。 非常感謝。

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個唯一的long值之外,這只是其中的一小部分。

與此不同的是,運行您的代碼段:首先,執行11011100111001101100011001110000 >> 32,它將除去所有位。 (那里恰好有32位),因此為什么要得到0。

也許您想要這種“壓縮”算法:我們認為在該方案中可表示的2 ^ 32長為:

從0到2 ^ 31-1的所有long,方法是將它們映射到相同的整數值,然后再通過按位映射它們,緊接着跟在其后的另一批2 ^ 31 long,盡管在Java中所有數字都是簽名,然后將它們映射為負整數。 所有其他長值(因此,所有高於2 ^ 32-1的值和所有負長值)都無法映射(或者,如果嘗試這樣做,它們將取消映射到錯誤的值)。

如果需要,您需要做的所有事情:

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

通常,如果將int強制轉換為long,則它會“符號擴展”,用1填充前32位,以表示int為負數。 按位&運算將前32位全部清除為0,然后返回到原始... 如果原始long在頂部具有32個零位(3706111600L這樣做)。

您的考試編號太小。 轉換為十六進制的3706111600L0x00000000DCE6C670 如果將此數字向右移32位,將丟失最后8個半字節;否則,將丟失最后8個半字節。 您得到的數字是0x00000000L。 強制轉換為int,此值仍為0。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM