¿Cómo obtener una representación binaria con 0 rellenos de un entero en Java?

120

por ejemplo, para 1, 2, 128, 256la salida puede ser (16 dígitos):

0000000000000001
0000000000000010
0000000010000000
0000000100000000

Lo intenté

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

pone espacios para el relleno izquierdo:

`               1'

Cómo poner 0s para relleno. No pude encontrarlo en Formatter . ¿Existe otra forma de hacerlo?

PD: esta publicación describe cómo formatear números enteros con relleno 0 izquierdo, pero no es para la representación binaria.

Khachik
fuente
¿Has probado a usar %016s?
Deniz Dogan
1
@Deniz sí, falla conException in thread "main" java.util.FormatFlagsConversionMismatchException: Conversion = s, Flags = 0
khachik
eche un vistazo a esto: stackoverflow.com/a/15124135/1316649
fstang

Respuestas:

198

Creo que esta es una solución subóptima, pero podrías hacer

String.format("%16s", Integer.toBinaryString(1)).replace(' ', '0')
Rectoría de Samuel
fuente
1
Sí, lo hago ahora, pero creo que debería haber otra forma :) Gracias.
Khachik
en realidad, después de investigar un poco, parece que no puedes hacerlo simplemente usando la sintaxis printf .. Así que quizás no sea tan malo después de todo.
Samuel Parsonage
@Daniel El número negativo no contendrá ningún espacio, por lo que también funciona.
Eric Wang
@Daniel Integer :: toBinaryString doc:Returns a string representation of the integer argument as an unsigned integer in base 2.
Alan
17

No hay una conversión binaria incorporada en java.util.Formatter, le aconsejaría que use String.replace para reemplazar el carácter de espacio con ceros, como en:

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

O implemente su propia lógica para convertir enteros en representación binaria con relleno izquierdo agregado en algún lugar a lo largo de las líneas dadas aquí . O si realmente necesita pasar números para formatear, puede convertir su representación binaria a BigInteger y luego formatearla con ceros a la izquierda, pero esto es muy costoso en tiempo de ejecución, como en:

String.format("%016d", new BigInteger(Integer.toBinaryString(1)))
Zoran Regvart
fuente
Gracias, este es mejor, ya que evita el desbordamiento en números grandes (por ejemplo, 2 ^ 30).
Khachik
1
Sí, pero realmente no lo haría, usaría el método de reemplazo o mi propio método de relleno: una forma sería usar String.format nuevamente para formatear la longitud de relleno necesaria con el argumento cero, o en el código: String.format ( "% 0" + (32 - binary.length ()) + "d"% s ", 0, binary) por supuesto, deberá estar atento a los resultados negativos de 32 - binary.length () ...
Zoran Regvart
12

Puede utilizar Apache Commons StringUtils . Ofrece métodos para rellenar cadenas:

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

Estaba probando todo tipo de llamadas a métodos que realmente no había usado antes para que esto funcionara, funcionaron con un éxito moderado, hasta que pensé en algo que es tan simple que podría funcionar, ¡y lo hizo!

Estoy seguro de que se ha pensado antes, no estoy seguro de si es bueno para cadenas largas de códigos binarios, pero funciona bien para cadenas de 16 bits. ¡¡Espero eso ayude!! (Tenga en cuenta que se ha mejorado la segunda parte del código)

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

Gracias a Will por ayudar a mejorar esta respuesta para que funcione sin problemas. Esto puede ser un poco torpe, pero funciona, por favor, mejore y comente si puede ...

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
fuente
Esta es una solución sencilla y agradable. Se podría mejorar usando la diferencia entre binString.length()y 16 para crear una cadena y luego agregar esa cadena a binString en lugar de hacer un bucle con algo como esta respuesta: stackoverflow.com/a/2804866/1353098
Will
1
Will, eres brillante, ¡lo pondré en mi código ahora mismo! Tampoco me gustó el bucle, ¡¡¡gracias !!!
Tom Spencer
7

Aquí una nueva respuesta para una publicación anterior.

Para rellenar un valor binario con ceros a la izquierda a una longitud específica, intente esto:

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

Si len = 4y val = 1,

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

devuelve la cadena "10001", luego

"10001".substring( 1 )

descarta el primer carácter. Entonces obtenemos lo que queremos:

"0001"

Si vales probable que sea negativo, intente:

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

Una versión más simple de la idea del usuario3608934 "Este es un truco antiguo, crea una cadena con 16 0 y luego agrega la cadena binaria recortada que obtuviste":

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

No conozco la solución "correcta", pero puedo sugerirle un parche rápido.

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

Lo acabo de probar y vi que funciona bien.

AlexR
fuente
¿Por qué el formateador tiene solo 16 caracteres de ancho? ¿por qué no %32s?
portador del anillo
3

tratar...

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

No creo que esta sea la forma "correcta" de hacer esto ... pero funciona :)

Pablo
fuente
1
Esta es ciertamente una mala manera de hacerlo porque solo funciona hasta una pequeña fracción de los valores de entrada ... La salida más grande que puede producir con éxito es 0000001111111111para el valor de entrada 1023Cualquier valor mayor que ese producirá la salida toBinaryString(1024)de la 10000000000cual es demasiado grande para el parseInt(...)Por lo tanto, la entrada solo funciona para 1K de 64K posibles valores de entrada
rolfl
1

Una solución ingenua que funcionaría

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

Otro método sería

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

Esto producirá una cadena de 16 bits del entero 5

proeng
fuente
1

A partir de Java 11, puede utilizar el método repeat (...) :

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

O, si necesita una representación de 32 bits de cualquier número entero:

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

Este es un viejo truco, cree una cadena con 16 0 y luego agregue la cadena binaria recortada que obtuvo de String.format ("% s", Integer.toBinaryString (1)) y use los 16 caracteres más a la derecha, cortando los primeros 0's. Mejor aún, cree una función que le permita especificar la longitud de una cadena binaria que desea. Por supuesto, probablemente hay un millón de otras formas de lograr esto, incluidas las bibliotecas, pero estoy agregando esta publicación para ayudar a un 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
fuente
0

Escribiría mi propia clase de utilidad con el método que se muestra a continuación

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));
}

}

Salida:

5
101
0000000000000000000000000000000000000000000000000000000000000101

El mismo enfoque podría aplicarse a cualquier tipo de integral. Presta atención al tipo de máscara

long mask = 1L << i;

Arseny Kovalchuk
fuente
0

Este método convierte un int en un String, length = bits. O bien rellenado con ceros o con los bits más 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
fuente
0

Puede usar lib https://github.com/kssource/BitSequence . Acepta un número y devuelve una cadena naria, rellenada y / o 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
fuente
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()es la longitud del número, digamos 2 en binario, es 01, que es la longitud 2, cambie 4 a la longitud máxima deseada del número. Esto se puede optimizar a O (n). utilizando continuar.

Jasmeet Chhabra
fuente
0

// A continuación se manejarán los tamaños adecuados

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
fuente
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
fuente
1
numBy numson iguales y no diferentes de ninguna manera
igorepst