Como converter uma string binária em um inteiro de base 10 em Java

108

Eu tenho uma matriz de Strings que representam números binários (sem zeros à esquerda) que desejo converter em seus números de base 10 correspondentes. Considerar:

binary 1011 becomes integer 11
binary 1001 becomes integer 9
binary   11 becomes integer 3   etc. 

Qual é a melhor maneira de proceder? Tenho explorado java.lang.number. * Sem encontrar um método de conversão direta. Integer.parseInt(b)retorna um inteiro IGUAL à String ... por exemplo, 1001 se torna 1.001 em vez de 9 ... e não parece incluir um parâmetro para uma base de saída. toBinaryStringfaz a conversão na direção errada. Suspeito que precisarei fazer uma conversão em várias etapas, mas não consigo encontrar a combinação certa de métodos ou subclasses. Também não tenho certeza de até que ponto os zeros à esquerda ou a falta deles serão um problema. Alguém tem boas instruções para me apontar?

dwwilson66
fonte

Respostas:

263

Você precisa especificar a raiz . Há uma sobrecarga de Integer#parseInt()que permite.

int foo = Integer.parseInt("1001", 2);
Matt Ball
fonte
1
Perfeição. Eu perdi completamente a segunda linha na documentação do parseInt que permite o radix. Funciona como um sonho.
dwwilson66,
1
Isso funciona com zeros à esquerda também? Só confirmando, embora não veja razão para não.
Siddhartha
@NagabhushanBaddi example? Você está passando uma representação de complemento de dois?
Matt Ball
18

Isso pode funcionar:

public int binaryToInteger(String binary) {
    char[] numbers = binary.toCharArray();
    int result = 0;
    for(int i=numbers.length - 1; i>=0; i--)
        if(numbers[i]=='1')
            result += Math.pow(2, (numbers.length-i - 1));
    return result;
}
Hassan
fonte
Suponho que seja meio desnecessário. É o que acontece quando você tem um tempinho entre as aulas.
Hassan
6
este é útil para mim porque eu tenho que fazer um projeto escolar com conversões sem usar as que o java já tem
bucksnort2
Alguém testou isso antes? aqui number.length menos o índice mais 1 é multiplicado por 2, se não me engano em bynary você começa com 1 e multiplica esse valor por 2, então pegue o resultado e multiplique esse um por 2 que será sua 3 casa e assim em
Christopher Cabezudo Rodriguez
(CAIXA DE COMENTÁRIOS NÃO É BOM PARA SNIPPETS) Aqui o Código que estou usando base no seu (eu estava perdido e uso o seu como modelo) public static int binaryToInteger (String binary) {char [] numbers = binary.ToCharArray (); resultado int = 0; int posValue = 1; para (int i = números.Comprimento - 1; i> = 0; i--) {if (números [i] == '1') {resultado + = posValor; } posValue * = 2; } resultado de retorno; }
Christopher Cabezudo Rodriguez
1
Este snippet de código não está funcionando. forloop e cálculo da nova resultvariável não está correto.
trilimites
8
int foo = Integer.parseInt("1001", 2);

funciona bem se você estiver lidando com números positivos, mas se você precisa lidar com números com sinais, você pode precisar assinar, estender sua string e então converter para um Int

public class bit_fun {
    public static void main(String[] args) {
        int x= (int)Long.parseLong("FFFFFFFF", 16);
        System.out.println("x =" +x);       

        System.out.println(signExtend("1"));
        x= (int)Long.parseLong(signExtend("1"), 2);
        System.out.println("x =" +x);

        System.out.println(signExtend("0"));
        x= (int)Long.parseLong(signExtend("0"), 2);
        System.out.println("x =" +x);

        System.out.println(signExtend("1000"));
        x= (int)Long.parseLong(signExtend("1000"), 2);
        System.out.println("x =" +x);

        System.out.println(signExtend("01000"));
        x= (int)Long.parseLong(signExtend("01000"), 2);
        System.out.println("x =" +x);
    }

    private static String signExtend(String str){
        //TODO add bounds checking
        int n=32-str.length();
        char[] sign_ext = new char[n];
        Arrays.fill(sign_ext, str.charAt(0));

        return new String(sign_ext)+str;
    }
}

output:
x =-1
11111111111111111111111111111111
x =-1
00000000000000000000000000000000
x =0
11111111111111111111111111111000
x =-8
00000000000000000000000000001000
x =8 

Espero que ajude!

txcotrader
fonte
1
Eu precisava de -1 convertido de binário para decimal, fiz isso. System.out.println ((int) Long.parseLong ("1111111111111111111111111111111111", 2));
Zeus
5
static int binaryToInt (String binary){
    char []cA = binary.toCharArray();
    int result = 0;
    for (int i = cA.length-1;i>=0;i--){
        //111 , length = 3, i = 2, 2^(3-3) + 2^(3-2)
        //                    0           1  
        if(cA[i]=='1') result+=Math.pow(2, cA.length-i-1);
    }
    return result;
}
Rudy Duran
fonte
2
public Integer binaryToInteger(String binary){
    char[] numbers = binary.toCharArray();
    Integer result = 0;
    int count = 0;
    for(int i=numbers.length-1;i>=0;i--){
         if(numbers[i]=='1')result+=(int)Math.pow(2, count);
         count++;
    }
    return result;
}

Acho que estou ainda mais entediado! Resposta de Hassan modificada para funcionar corretamente.

ModernIncantations
fonte
1

Para mim, obtive NumberFormatException ao tentar lidar com os números negativos. Usei o seguinte para os números negativos e positivos.

System.out.println(Integer.parseUnsignedInt("11111111111111111111111111110111", 2));      

Output : -9
Zeus
fonte
0

Versão corrigida de Integer.parseInt (texto) de java para trabalhar com números negativos:

public static int parseInt(String binary) {
    if (binary.length() < Integer.SIZE) return Integer.parseInt(binary, 2);

    int result = 0;
    byte[] bytes = binary.getBytes();

    for (int i = 0; i < bytes.length; i++) {
        if (bytes[i] == 49) {
            result = result | (1 << (bytes.length - 1 - i));
        }
    }

    return result;
}
skyrosbit
fonte
0

Eu amo loops! Yay!

String myString = "1001001"; //73

While loop com acumulador, da esquerda para a direita ( lnão muda):

int n = 0,
    j = -1,
    l = myString.length();
while (++j < l) n = (n << 1) + (myString.charAt(j) == '0' ? 0 : 1);
return n;

Da direita para a esquerda com 2 vars de loop, inspirados em Convert boolean to int em Java (absolutamente horrível):

int n = 0,
    j = myString.length,
    i = 1;
while (j-- != 0) n -= (i = i << 1) * new Boolean(myString.charAt(j) == '0').compareTo(true);
return n >> 1;

Uma implementação um pouco mais razoável:

int n = 0,
    j = myString.length(),
    i = 1;
while (j-- != 0) n += (i = i << 1) * (myString.charAt(j) == '0' ? 0 : 1);
return n >> 1;

Uma versão legível: p

int n = 0;
for (int j = 0; j < myString.length(); j++) {
    n *= 2;
    n += myString.charAt(j) == '0' ? 0 : 1;
}
return n;
bjb568
fonte
0

Se você está preocupado com o desempenho Integer.parseInt()e Math.pow()são muito caros. Você pode usar a manipulação de bits para fazer a mesma coisa duas vezes mais rápido (com base na minha experiência):

final int num = 87;
String biStr = Integer.toBinaryString(num);

System.out.println(" Input Number: " + num + " toBinary "+ biStr);
int dec = binaryStringToDecimal(biStr);
System.out.println("Output Number: " + dec + " toBinary "+Integer.toBinaryString(dec));

Onde

int binaryStringToDecimal(String biString){
  int n = biString.length();      
  int decimal = 0;
  for (int d = 0; d < n; d++){
    // append a bit=0 (i.e. shift left) 
    decimal = decimal << 1;

    // if biStr[d] is 1, flip last added bit=0 to 1 
    if (biString.charAt(d) == '1'){
      decimal = decimal | 1; // e.g. dec = 110 | (00)1 = 111
    }
  }
  return decimal;
}

Resultado:

 Input Number: 87 toBinary 1010111
Output Number: 87 toBinary 1010111
anask
fonte