我有這樣的代碼:無法理解的Java二進制補
package com.company;
import java.net.InetAddress;
import java.net.UnknownHostException;
public class Main {
private final static int broadcast = 0xffffffff; //4294967295, or 255.255.255.255
private final static int firstClassE = 0xf0000000; //4026531840, or 240.0.0.0
public static int GetIntInetAddress(InetAddress toConvert)
{
final byte[] addr = toConvert.getAddress();
final int ipAddr =
((addr[0] & 0xFF) << (3 * 8)) +
((addr[1] & 0xFF) << (2 * 8)) +
((addr[2] & 0xFF) << (1 * 8)) +
(addr[3] & 0xFF);
return ipAddr;
}
public static Boolean IsClassEAddress(InetAddress address)
{
int curAddr = GetIntInetAddress(address);
Boolean test1 = curAddr >= firstClassE;
Boolean test2 = curAddr < broadcast;
System.out.println(String.format("\ncurAddr: %s, firstClassE: 240.0.0.0, broadcast: 255.255.255.255", address.getHostAddress()));
System.out.println(String.format("curAddr: %d, firstClassE: %d, broadcast: %d, curAddr >= firstClassE: %s, curAddr < broadcast: %s",
curAddr, firstClassE, broadcast, test1 ? "true" : "false", test2 ? "true" : "false"));
return (test1 && test2) ? true : false;
}
public static void main(String[] args) throws UnknownHostException
{
if (IsClassEAddress(InetAddress.getByName("1.0.0.0")))
{
// Raise a flag
System.out.println("Class E IP address detected.");
}
if (IsClassEAddress(InetAddress.getByName("250.0.0.0")))
{
// Raise a flag
System.out.println("Class E IP address detected.");
}
if (IsClassEAddress(InetAddress.getByName("239.255.255.255")))
{
// Raise a flag
System.out.println("Class E IP address detected.");
}
if (IsClassEAddress(InetAddress.getByName("240.0.0.0")))
{
// Raise a flag
System.out.println("Class E IP address detected.");
}
if (IsClassEAddress(InetAddress.getByName("240.0.0.1")))
{
// Raise a flag
System.out.println("Class E IP address detected.");
}
if (IsClassEAddress(InetAddress.getByName("255.255.255.255")))
{
// Raise a flag
System.out.println("Class E IP address detected.");
}
}
}
將會產生以下的輸出:
curAddr: 1.0.0.0, firstClassE: 240.0.0.0, broadcast: 255.255.255.255
curAddr: 16777216, firstClassE: -268435456, broadcast: -1, curAddr >= firstClassE: true, curAddr < broadcast: false
curAddr: 250.0.0.0, firstClassE: 240.0.0.0, broadcast: 255.255.255.255
curAddr: -100663296, firstClassE: -268435456, broadcast: -1, curAddr >= firstClassE: true, curAddr < broadcast: true
Class E IP address detected.
curAddr: 239.255.255.255, firstClassE: 240.0.0.0, broadcast: 255.255.255.255
curAddr: -268435457, firstClassE: -268435456, broadcast: -1, curAddr >= firstClassE: false, curAddr < broadcast: true
curAddr: 240.0.0.0, firstClassE: 240.0.0.0, broadcast: 255.255.255.255
curAddr: -268435456, firstClassE: -268435456, broadcast: -1, curAddr >= firstClassE: true, curAddr < broadcast: true
Class E IP address detected.
curAddr: 240.0.0.1, firstClassE: 240.0.0.0, broadcast: 255.255.255.255
curAddr: -268435455, firstClassE: -268435456, broadcast: -1, curAddr >= firstClassE: true, curAddr < broadcast: true
Class E IP address detected.
curAddr: 255.255.255.255, firstClassE: 240.0.0.0, broadcast: 255.255.255.255
curAddr: -1, firstClassE: -268435456, broadcast: -1, curAddr >= firstClassE: true, curAddr < broadcast: false
什麼我不理解就是爲什麼數字和比較是不是我所期望他們是,但代碼產生我想要的結果。我認爲這是整個兩個補充的東西,我只是因爲某些原因不「得到」。從機制上講,我知道它(二進制補碼)是翻轉位和加1,但我沒有得到的是,爲什麼我的比較正常工作,如果一些數字倒置?
例如,在第一次檢查IP 1.0.0.0時,檢查int值16777216以查看它是否小於255.255.255.255的int值,即-1。結果是錯誤的,但廣播IP在轉換爲int時顯然比IP爲1.0.0.0的IP更大,而不是更小。同樣,當我們知道顯然不是這種情況時,對於1.0.0.0至少或高於240.0.0.0的檢查返回true。
我檢查了邊界情況,一切正常......我只是不明白它爲什麼(我寫了代碼,所以去圖!)。如果有一個更明確的方法來確定一個IP是否在一個範圍內失敗,我想探討一下,儘管我的工作方式一定沒有道理(或者是否這樣做)?
在IntelliJ中,還有一種奇怪的這種行爲的例子。當我檢查地址時,檢查員顯示正確的值和負值,正如我在下面的圖片中用紅色箭頭突出顯示的那樣。使用Windows calc,我放入-84並轉換爲十六進制並收到FFF ... FAC。當我輸入172時,我只收到AC ...爲什麼我會得到相同的十六進制數字,前面是最高位置處的1?
UPDATE:
感謝所有的患者討論和偉大的答案!我認爲我掌握了這個東西的機制,但仍然在處理使用的微妙之處。 :)乾杯!
這是一個很大的代碼和輸出。你能不能提供一個小小的片段來證明你對補碼的誤解? –
_「當轉換爲int時,廣播IP顯然比IP爲1.0.0.0更大,而不是更小 - 」這一點根本不「顯而易見」。二進制中的「1.0.0.0」是「0x01000000」,「255.255.255.255」是「0xFFFFFFFF」。第一個值表示「16777216」,第二個值表示「-1」。你不能通過說你不「得到」兩個補碼來改變這一點。它只是。 –
如果你想比較工作正確,最簡單的方法是使用'long'而不是'int',然後一切都將是正面的。 – ajb