亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

按位運算符究竟如何在Java中工作?

按位運算符究竟如何在Java中工作?

夢里花落0921 2022-09-28 14:49:57
我目前正在嘗試在Java中圍繞位和位移運算符。雖然它們在簡化的玩具示例(基本上是正整數)中對我來說是有意義的,但是一旦涉及負數,我的理解就會崩潰,在其他一些情況下也是如此。我嘗試用兩個搜索引擎在互聯網上搜索,我甚至檢查了Java規范。我找不到任何正確描述按位和位移運算符在Java中如何工作的來源。Java標準庫中特別讓我感到困惑的一個函數是 。來自 OpenJdk 的源代碼如下所示(LGPLv2 具有類路徑異常),并在爪哇文檔中摘錄:java.lang.Integer.toUnsignedLong(int)/** * Converts the argument to a {@code long} by an unsigned * conversion.  In an unsigned conversion to a {@code long}, the * high-order 32 bits of the {@code long} are zero and the * low-order 32 bits are equal to the bits of the integer * argument.    */public static long toUnsignedLong(int x) {    return ((long) x) & 0xffffffffL;}根據上面復制的官方文檔,“長整型的高位32位為零,低階32位等于整數參數的位。但是,我不明白這如何從方法體內部的代碼中得出。在閱讀該方法時,以下是我對正x的思路:當整數轉換為 long 時,其符號位/最高有效位為零。因此,長整型符號位/最高有效位為零,低位等于整數的位。由于 long 具有所有最低階 4 字節,并且由于只有這些字節中包含數據,因此此掩碼不起作用,并且返回正確的結果。0xffffffff然而,當在負面的背景下閱讀它時,我的理解就崩潰了:x當整數為 cst 到 long 時,其符號位/最高有效位為 1。因此,長號的符號位/最有效位是一,低階位等于整數的位,除了第四個最低有效字節的最有效位是零,當它在整數中為1時。由于 long 在最低順序為 4 個字節中具有所有 1,在最高順序的 4 個字節中具有零,因此它具有更改長整型上的符號位的唯一效果,并使四個最低有效位中的錯誤整數保持不變。因此,它從此方法返回錯誤的答案,其中整數的符號位在移動到長整型時會更改。0xffffffff但是,當我測試此方法時,我得到的結果與Javadoc一致。我懷疑我誤解了Java中按位運算符或其兩個補碼整數表示的一個或多個基本點,我希望這個問題可以澄清這些要點。
查看完整描述

1 回答

?
至尊寶的傳說

TA貢獻1789條經驗 獲得超10個贊

按位運算符的工作方式完全符合您的預期。它們是嚴格的位運算符,根本不考慮位的語義。


有時,使用斷點運行代碼最為簡單。對于您的具體示例,我將操作的步驟轉換為原子語句,并使用 打印結果。Long.toString


int x = -57;


// step 1:

long xCast = (long) x;

System.out.println(Long.toString(xCast, 2)); // -1110011 - this is not the bitwise representation however.


long mask = 0xffffffffL;

System.out.println(Long.toString(mask, 2)); // 11111111111111111111111111111111


// step 2:

long result = ((long) x) & mask;

System.out.println(Long.toString(result, 2)); // 11111111111111111111111111000111

步驟 1 是操作外觀的主要原因。在 Java 中,所有(嚴格數字)值都是有符號的(字符是無符號的)。這意味著,正如您正確指出的那樣,所有最高位都是符號位。然而,有趣的部分是,如果一個數字是負數,那么其余位會做什么。以下主題已經涵蓋了“二的補碼”的基礎知識:什么是“2的補碼”?這個維基百科頁面也是如此:https://en.wikipedia.org/wiki/Two%27s_complement


為了縮短它,在java中,對于整數:


int zero = 0; // == 0b00000000_00000000_00000000_00000000


int maxPositive = Integer.MAX_VALUE; // == 0b01111111_11111111_11111111_11111111


int minus1 = -1; // == 0b11111111_11111111_11111111_11111111


int minNegative = Integer.MIN_VALUE; // == 0b10000000_00000000_00000000_00000000

因此,一切正常的原因是,如果整數為負數,則在強制轉換時,整個上部 32 位將轉換為 1,否則數字的表示值將發生變化。有效:


int x = 0b11111111_11111111_11111111_11000111;

轉換為:


long xCast = 0b11111111_11111111_11111111_11111111_11111111_11111111_11111111_11000111;

由于您作為開發人員希望該方法僅返回初始設置的位,因此您必須從結果中屏蔽上位。這是在步驟 2 中完成的。


因此,您的示例的答案:Java中非浮動值的表示是二的補碼,因此,當智能地將值從int轉換為long時,對于負數,上面的位被1填充。因此,它們必須被刪除。


查看完整回答
反對 回復 2022-09-28
  • 1 回答
  • 0 關注
  • 103 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號