Sefier Tang
Sefier Tang

Reputation: 790

How could I convert a 64-width binary string to long in Java?

I want to convert a 64-width binary string to long, there is a static method:

Long.parseLong(String s, int radix)

to do this, but it isn't suitable for my case.

The problem is my binary string is a machine-style long int.

For example:

1111111111111111111111111111111111111111111111111111111110000101 represents -123, but this method recognize it as a huge positive number, this troubles me, how could I solve this problem?

Must I write a function that does the complement?

Upvotes: 13

Views: 22469

Answers (5)

ValeriST
ValeriST

Reputation: 1

I think that the easiest way is to use Long.parseUnsignedLong for example:

String str = "1111111111111111111111111111111111111111111111111111111110000101";
System.out.println(Long.parseUnsignedLong(str, 2));

Will print:

-123

Upvotes: 0

Peter Lawrey
Peter Lawrey

Reputation: 533510

You can use BigInteger

public static void main(String... args) {
    String s = "1111111111111111111111111111111111111111111111111111111110000101";
    long l = parseLong(s, 2);
    System.out.println(s +" => " + l);

    String s2 = s.substring(1);
    long l2 = parseLong(s2, 2);
    System.out.println(s2 +" => " + l2);
}

private static long parseLong(String s, int base) {
    return new BigInteger(s, base).longValue();
}

prints

1111111111111111111111111111111111111111111111111111111110000101 => -123
111111111111111111111111111111111111111111111111111111110000101 => 9223372036854775685

Upvotes: 16

yshavit
yshavit

Reputation: 43391

You could just set the bits yourself...

assert string.length() == 64;
long result = 0;
for (int i = 0; i < 64; ++i) {
    char c = string.charAt(63-i);
    switch (c) {
        case '1': result |= (1L << i); break;
        case '0'; break;
        default: throw new WhateverException("bad char " + c);
    }
}

EDIT: I originally had 1 << i, which means the shifting is being done as an int. Fixed to make it being done as a long.

Upvotes: 2

Taymon
Taymon

Reputation: 25676

I don't think there's a library function to do what you want, but this should work:

long num = 0L;
for (int i = 0; i < 64; i++) {
    if (yourString.charAt(i) == '1') {
        num ^= 1L << (63 - i);
    }
}

Of course, you should check to make sure that the string is length 64 and contains only 0 and 1.

Upvotes: 0

Tim
Tim

Reputation: 60120

My incredibly hacked-together solution, tested only on your case:

public static long makeLong(String input) {
    if(input.substring(0,1).equals("1")) {
        return -1 * (Long.MAX_VALUE - Long.parseLong(input.substring(1), 2) + 1);
    } else {
        return Long.parseLong(input, 2);
    }
}

Basically, if the first bit is a one, the number is negative, so we parse the rest of the number as a positive, then do some two's complement magic by subtracting that result from Long.MAX_VALUE and adding one, then forcing the negative back onto the number returned. Otherwise, the normal conversion applies.

Upvotes: 2

Related Questions