[英]Unable to parse 64 bit binary numbers to long
給定字符串“0”中的二進制數,我將其轉換為long以找到其按位不/補。
long number = Long.parseLong("0",2);
number = ~number;
System.out.println(Long.toBinaryString(number));
打印
1111111111111111111111111111111111111111111111111111111111111111
即64 1。 但我無法找到這個的補充。
Long.parseLong("111111111111111111111111111111111111111111111111111111111111111",2); //fails
我得到java.lang.NumberFormatException。 我是什么做的?
當你反轉零
number = ~number
你得到消極的。 Long.parseLong(String, int)
方法期望負數用減去前綴表示 。 當您將64個1-s傳遞給該方法時,它認為它是溢出的,並返回錯誤。
解決此問題的一種方法是在解析值之前檢查長度是否小於64。 如果長度恰好是64,請切掉第一個數字,然后解析數字的其余部分。 然后檢查初始數字。 如果為零,則保留解析后的數字; 否則,使用二進制OR
設置最高有效位:
String s = "1111111111111111111111111111111111111111111111111111111111111111";
long res;
if (s.length() < 64) {
res = Long.parseLong(s, 2);
} else {
res = Long.parseLong(s.substring(1), 2);
if (s.charAt(0) == '1') {
res |= (1L << 63);
}
}
0的補碼是64 1,相當於-1,因為Java使用了兩個補碼 。
Long.parseLong(String, int)
期望一個有符號長(也就是說,如果數字是負數,它期望一個前導-
),但是你傳遞的是64 1,它應該代表-1,但不是這種形式。
鑒於對於負數,它預期為負號,將其傳遞給64 1會導致它認為數字太大。
編輯(對dasblinkenlight修復的解釋:無法在評論中正確格式化):
所以如果String s =
"1111111111111111111111111111111111111111111111111111111111111111";
,我們有:
long res = Long.parseLong(s.substring(1), 2);
res
的二進制形式是:
0111111111111111111111111111111111111111111111111111111111111111
現在,如果我們知道s
的第一個char
是'1'
,那么我們執行以下操作:
res |= (1L << 63);
(1L << 63)
產生:
1000000000000000000000000000000000000000000000000000000000000000
因此,對於res
的按位或賦值將產生64 1,其中二進制補碼為-1,如期望的那樣。
這是因為Long.parseLong(以及Integer.parseInt等)無法解析兩個補碼,因此“111111111111111111111111111111111111111111111111111111111111111”是一個超過Long.MAX_VALUE的正數。 但我們可以使用BigInteger
long l = new BigInteger("1111111111111111111111111111111111111111111111111111111111111111", 2).longValue()
這會產生預期結果= -1
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.