Como obter uma representação binária preenchida com 0 de um número inteiro em java?

120

por exemplo, para 1, 2, 128, 256a saída pode ser (16 dígitos):

0000000000000001
0000000000000010
0000000010000000
0000000100000000

eu tentei

String.format("%16s", Integer.toBinaryString(1));

coloca espaços para preenchimento esquerdo:

`               1'

Como colocar 0s para preenchimento. Não consegui encontrá-lo no Formatador . tem outro jeito de fazer isto?

PS, este post descreve como formatar números inteiros com preenchimento 0 esquerdo, mas não é para a representação binária.

khachik
fonte
Você já tentou usar %016s?
Deniz Dogan 12/12
1
@ Deniz sim, ele falha com #Exception in thread "main" java.util.FormatFlagsConversionMismatchException: Conversion = s, Flags = 0
khachik 12/12
dê uma olhada nisso: stackoverflow.com/a/15124135/1316649
fstang

Respostas:

198

Eu acho que essa é uma solução abaixo do ideal, mas você poderia fazer

String.format("%16s", Integer.toBinaryString(1)).replace(' ', '0')
Samuel Parsonage
fonte
1
Sim, faço agora, mas acredito que deve haver outro caminho :) Obrigado.
Khachik
na verdade, depois de fazer alguma pesquisa, parece que você não pode fazê-lo apenas usando a sintaxe printf. Portanto, talvez não seja tão ruim assim.
Samuel Parsonage
@Daniel O número negativo não terá espaço, portanto também funciona.
Eric Wang
@Daniel Inteiro :: toBinaryString doc:Returns a string representation of the integer argument as an unsigned integer in base 2.
Alan
17

Não há conversão binária incorporada no java.util.Formatter, aconselho que você use String.replace para substituir o caractere de espaço por zeros, como em:

String.format("%16s", Integer.toBinaryString(1)).replace(" ", "0")

Ou implemente sua própria lógica para converter números inteiros em representação binária com preenchimento esquerdo adicionado em algum lugar ao longo das linhas indicadas neste exemplo . Ou, se você realmente precisar passar números para o formato, poderá converter sua representação binária em BigInteger e formatá-la com zeros à esquerda, mas isso é muito caro no tempo de execução, como em:

String.format("%016d", new BigInteger(Integer.toBinaryString(1)))
Zoran Regvart
fonte
Obrigado, este é melhor, pois evita o excesso de números grandes (por exemplo, 2 ^ 30).
Khachik
1
Sim, mas eu realmente não faria isso, usaria o método de substituição ou o meu próprio método de preenchimento: uma maneira seria usar String.format novamente para formatar o comprimento de preenchimento necessário com o argumento zero ou no código: String.format ( "% 0" + (32 - binary.length ()) + "d"% s ", 0, binário) é claro que você precisará observar resultados negativos de 32 - binary.length () ...
Zoran Regvart
12

Você pode usar o Apache Commons StringUtils . Oferece métodos para preenchimento de strings:

StringUtils.leftPad(Integer.toBinaryString(1), 16, '0');
Bunarro
fonte
9

Eu estava tentando todos os tipos de chamadas de métodos que eu realmente não havia usado antes para fazer esse trabalho, elas funcionaram com sucesso moderado, até que pensei em algo tão simples que poderia funcionar, e funcionou!

Tenho certeza de que já foi pensado antes, não tenho certeza se é bom para uma longa sequência de códigos binários, mas funciona bem para cadeias de 16 bits. Espero que ajude!! (Observe que o segundo trecho de código foi aprimorado)

String binString = Integer.toBinaryString(256);
  while (binString.length() < 16) {    //pad with 16 0's
        binString = "0" + binString;
  }

Agradecemos a Will por ajudar a melhorar esta resposta para que ela funcione sem um loop. Talvez isso seja um pouco desajeitado, mas funciona. Por favor, melhore e comente novamente se puder ....

binString = Integer.toBinaryString(256);
int length = 16 - binString.length();
char[] padArray = new char[length];
Arrays.fill(padArray, '0');
String padString = new String(padArray);
binString = padString + binString;
Tom Spencer
fonte
Esta é uma solução simples e agradável. Poderia ser aprimorado usando a diferença entre binString.length()e 16 para criar uma sequência e, em seguida, anexando-a a binString, em vez de repetir, embora com algo como esta resposta: stackoverflow.com/a/2804866/1353098
Será
1
Will - você é brilhante, vou colocar isso no meu código agora mesmo! Eu também não gostei do loop, obrigado !!!
Tom Spencer
7

Aqui está uma nova resposta para um post antigo.

Para preencher um valor binário com zeros à esquerda para um comprimento específico, tente o seguinte:

Integer.toBinaryString( (1 << len) | val ).substring( 1 )

Se len = 4e val = 1,

Integer.toBinaryString( (1 << len) | val )

retorna a string "10001", então

"10001".substring( 1 )

descarta o primeiro caractere. Então, obtemos o que queremos:

"0001"

Se valé provável que seja negativo, tente:

Integer.toBinaryString( (1 << len) | (val & ((1 << len) - 1)) ).substring( 1 )
Cr4paud
fonte
5

Uma versão mais simples da idéia de user3608934 "Este é um truque antigo, crie uma sequência com 16 0 e, em seguida, acrescente a sequência binária aparada que você obteve":

private String toBinaryString32(int i) {
    String binaryWithOutLeading0 = Integer.toBinaryString(i);
    return "00000000000000000000000000000000"
            .substring(binaryWithOutLeading0.length())
            + binaryWithOutLeading0;
}
bento
fonte
4

Não sei a solução "certa", mas posso sugerir um patch rápido.

String.format("%16s", Integer.toBinaryString(1)).replace(" ", "0");

Eu apenas tentei e vi que funciona bem.

AlexR
fonte
por que o formatador tem apenas 16 caracteres? por que não %32s?
portador do anel 27/05
3

experimentar...

String.format("%016d\n", Integer.parseInt(Integer.toBinaryString(256)));

Eu não acho que esta é a maneira "correta" de fazer isso ... mas funciona :)

Paulo
fonte
1
Esta é certamente uma maneira ruim de fazê-lo, porque funciona apenas com uma pequena fração dos valores de entrada .... A maior saída que ela pode produzir com sucesso é 0000001111111111para o valor de entrada 1023Qualquer valor maior que isso produzirá a saída toBinaryString(1024)da 10000000000qual é muito grande para o parseInt(...)Assim, a entrada funciona apenas para 1K de 64K possíveis valores de entrada
rolfl
1

Uma solução ingênua que funcionaria seria

String temp = Integer.toBinaryString(5);
while (temp.length() < Integer.SIZE) temp = "0"+temp; //pad leading zeros
temp = temp.substring(Integer.SIZE - Short.SIZE); //remove excess

Um outro método seria

String temp = Integer.toBinaryString((m | 0x80000000));
temp = temp.substring(Integer.SIZE - Short.SIZE);

Isso produzirá uma sequência de 16 bits do número inteiro 5

proeng
fonte
1

A partir do Java 11, você pode usar o método repeat (...) :

"0".repeat(Integer.numberOfLeadingZeros(i) - 16) + Integer.toBinaryString(i)

Ou, se você precisar de uma representação de 32 bits de qualquer número inteiro:

"0".repeat(Integer.numberOfLeadingZeros(i != 0 ? i : 1)) + Integer.toBinaryString(i)
John McClane
fonte
0

Esse é um truque antigo, crie uma string com 16 0 e, em seguida, acrescente a string binária aparada que você obteve de String.format ("% s", Integer.toBinaryString (1)) e use os 16 caracteres mais à direita, cortando qualquer elemento inicial 0's. Melhor ainda, crie uma função que permita especificar por quanto tempo você deseja uma string binária. É claro que provavelmente existem outras maneiras de conseguir isso, incluindo bibliotecas, mas estou adicionando este post para ajudar um amigo :)

public class BinaryPrinter {

    public static void main(String[] args) {
        System.out.format("%d in binary is %s\n", 1, binaryString(1, 4));
        System.out.format("%d in binary is %s\n", 128, binaryString(128, 8));
        System.out.format("%d in binary is %s\n", 256, binaryString(256, 16));
    }

    public static String binaryString( final int number, final int binaryDigits ) {
        final String pattern = String.format( "%%0%dd", binaryDigits );
        final String padding = String.format( pattern, 0 );
        final String response = String.format( "%s%s", padding, Integer.toBinaryString(number) );

        System.out.format( "\npattern = '%s'\npadding = '%s'\nresponse = '%s'\n\n", pattern, padding, response );

        return response.substring( response.length() - binaryDigits );
    }
}
user3608934
fonte
0

Eu escreveria minha própria classe util com o método abaixo

public class NumberFormatUtils {

public static String longToBinString(long val) {
    char[] buffer = new char[64];
    Arrays.fill(buffer, '0');
    for (int i = 0; i < 64; ++i) {
        long mask = 1L << i;
        if ((val & mask) == mask) {
            buffer[63 - i] = '1';
        }
    }
    return new String(buffer);
}

public static void main(String... args) {
    long value = 0b0000000000000000000000000000000000000000000000000000000000000101L;
    System.out.println(value);
    System.out.println(Long.toBinaryString(value));
    System.out.println(NumberFormatUtils.longToBinString(value));
}

}

Resultado:

5
101
00000000000000000000000000000000000000000000000000000000000000000101

A mesma abordagem pode ser aplicada a qualquer tipo integral. Preste atenção ao tipo de máscara

long mask = 1L << i;

Arseny Kovalchuk
fonte
0

Este método converte um int em uma String, length = bits. Acolchoado com 0s ou com os bits mais significativos truncados.

static String toBitString( int x, int bits ){
    String bitString = Integer.toBinaryString(x);
    int size = bitString.length();
    StringBuilder sb = new StringBuilder( bits );
    if( bits > size ){
        for( int i=0; i<bits-size; i++ )
            sb.append('0');
        sb.append( bitString );
    }else
        sb = sb.append( bitString.substring(size-bits, size) );

    return sb.toString();
}
jenfax
fonte
0

Você pode usar a lib https://github.com/kssource/BitSequence . Aceita um número e retorna por sequência de caracteres, preenchida e / ou agrupada.

String s = new BitSequence(2, 16).toBynaryString(ALIGN.RIGHT, GROUP.CONTINOUSLY));  
return  
0000000000000010  

another examples:

[10, -20, 30]->00001010 11101100 00011110
i=-10->00000000000000000000000000001010
bi=10->1010
sh=10->00 0000 0000 1010
l=10->00000001 010
by=-10->1010
i=-10->bc->11111111 11111111 11111111 11110110
Nikmass
fonte
0
for(int i=0;i<n;i++)
{
  for(int j=str[i].length();j<4;j++)
  str[i]="0".concat(str[i]);
}

str[i].length()é comprimento do número, digamos 2 em binário, é 01, que é o comprimento 2, altera 4 para o comprimento máximo desejado do número. Isso pode ser otimizado para O (n). usando continue.

Jasmeet Chhabra
fonte
0

// Abaixo lidamos com tamanhos adequados

public static String binaryString(int i) {
    return String.format("%" + Integer.SIZE + "s", Integer.toBinaryString(i)).replace(' ', '0');
}

public static String binaryString(long i) {
    return String.format("%" + Long.SIZE + "s", Long.toBinaryString(i)).replace(' ', '0');
}
Paul Weiss
fonte
0
import java.util.Scanner;
public class Q3{
  public static void main(String[] args) {
    Scanner scn=new Scanner(System.in);
    System.out.println("Enter a number:");
    int num=scn.nextInt();
    int numB=Integer.parseInt(Integer.toBinaryString(num));
    String strB=String.format("%08d",numB);//makes a 8 character code
    if(num>=1 && num<=255){
     System.out.println(strB);
    }else{
        System.out.println("Number should be in range between 1 and 255");
    }
  }
}
Devesh Kumar
fonte
1
numBe numsão iguais e não diferente de qualquer forma
igorepst