簡體   English   中英

無法將64位二進制數解析為long

[英]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.

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