简体   繁体   English

无法将64位二进制数解析为long

[英]Unable to parse 64 bit binary numbers to long

Given binary number in a string "0", I converted it to long to find its Bitwise Not/Complement. 给定字符串“0”中的二进制数,我将其转换为long以找到其按位不/补。

long number = Long.parseLong("0",2);
number = ~number;
System.out.println(Long.toBinaryString(number));

which prints 打印

1111111111111111111111111111111111111111111111111111111111111111 1111111111111111111111111111111111111111111111111111111111111111

ie, 64 1's. 即64 1。 But I'm unable to find complement of this. 但我无法找到这个的补充。

Long.parseLong("111111111111111111111111111111111111111111111111111111111111111",2); //fails

I get java.lang.NumberFormatException. 我得到java.lang.NumberFormatException。 What am I to do? 我是什么做的?

When you invert zero 当你反转零

number = ~number

you get negative one. 你得到消极的。 The Long.parseLong(String, int) method expects negative numbers to be represented with a minus prefix . Long.parseLong(String, int)方法期望负数用减去前缀表示 When you pass 64 1-s to the method, it thinks it's an overflow, and returns an error. 当您将64个1-s传递给该方法时,它认为它是溢出的,并返回错误。

One way to fix this is to check that the length is less than 64 before you parse the value. 解决此问题的一种方法是在解析值之前检查长度是否小于64。 If the length is exactly 64, chop off the first digit, and parse the rest of the number. 如果长度恰好是64,请切掉第一个数字,然后解析数字的其余部分。 Then check the initial digit. 然后检查初始数字。 If it is zero, leave the parsed number as is; 如果为零,则保留解析后的数字; otherwise, use binary OR to set the most significant bit: 否则,使用二进制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);
    }
}

The complement of 0 is 64 1's, which is equivalent to -1, since Java uses two's complement . 0的补码是64 1,相当于-1,因为Java使用了两个补码

Long.parseLong(String, int) 

expects a signed long (aka if the number is negative, it expects a leading - ), but you are passing it 64 1's, which are supposed to represent -1, but do not in this form. 期望一个有符号长(也就是说,如果数字是负数,它期望一个前导- ),但是你传递的是64 1,它应该代表-1,但不是这种形式。

Given that for negatives, it expects the a negative sign, passing it 64 1's causes the it to believe that the number is too large. 鉴于对于负数,它预期为负号,将其传递给64 1会导致它认为数字太大。

EDIT (explanation of dasblinkenlight's fix: couldn't properly format in comment): 编辑(对dasblinkenlight修复的解释:无法在评论中正确格式化):
So if String s = 所以如果String s =

"1111111111111111111111111111111111111111111111111111111111111111";

, and we have: ,我们有:

long res = Long.parseLong(s.substring(1), 2);

The binary form of res is: res的二进制形式是:

0111111111111111111111111111111111111111111111111111111111111111

Now, if we know that the first char of s is '1' , then we do the following: 现在,如果我们知道s的第一个char'1' ,那么我们执行以下操作:

 res |= (1L << 63);

(1L << 63) produces: (1L << 63)产生:

1000000000000000000000000000000000000000000000000000000000000000

So, the bitwise-or assignment to res yields 64 1's, which in two's complement is -1, as desired. 因此,对于res的按位或赋值将产生64 1,其中二进制补码为-1,如期望的那样。

This is because Long.parseLong (as well as Integer.parseInt etc) cannot parse two's complements and for it "111111111111111111111111111111111111111111111111111111111111111" is a positive number that exceeds Long.MAX_VALUE. 这是因为Long.parseLong(以及Integer.parseInt等)无法解析两个补码,因此“111111111111111111111111111111111111111111111111111111111111111”是一个超过Long.MAX_VALUE的正数。 But we can use BigInteger 但我们可以使用BigInteger

long l = new BigInteger("1111111111111111111111111111111111111111111111111111111111111111", 2).longValue()

this produces expected result = -1 这会产生预期结果= -1

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM