Come ottenere una rappresentazione binaria con riempimento 0 di un numero intero in java?


120

ad esempio, per 1, 2, 128, 256l'uscita può essere (16 cifre):

0000000000000001
0000000000000010
0000000010000000
0000000100000000

Provai

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

mette spazi per il riempimento a sinistra:

`               1'

Come mettere 0s per imbottitura. Non sono riuscito a trovarlo in Formatter . C'è un altro modo per farlo?

PS questo post descrive come formattare interi con 0-padding sinistro, ma non è per la rappresentazione binaria.


Hai provato a usare %016s?
Deniz Dogan

1
@Deniz sì, fallisce conException in thread "main" java.util.FormatFlagsConversionMismatchException: Conversion = s, Flags = 0
khachik

dare un'occhiata a questo: stackoverflow.com/a/15124135/1316649
fstang

Risposte:


198

Penso che questa sia una soluzione non ottimale, ma potresti farlo

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

1
Sì, lo faccio ora, ma credo che dovrebbe esserci un altro modo :) Grazie.
Khachik

in realtà dopo aver fatto qualche ricerca, sembra che tu non possa farlo usando solo la sintassi printf .. Quindi forse non è poi così male, dopo tutto.
Samuel Parsonage

@Daniel Il numero negativo non conterrà spazi, quindi funziona anche.
Eric Wang

@Daniel Integer :: toBinaryString doc:Returns a string representation of the integer argument as an unsigned integer in base 2.
Alan

17

Non esiste una conversione binaria incorporata in java.util.Formatter, ti consiglio di utilizzare String.replace per sostituire il carattere spazio con zeri, come in:

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

Oppure implementa la tua logica per convertire gli interi in una rappresentazione binaria con l'aggiunta di un riempimento a sinistra da qualche parte lungo le linee fornite in questo modo. Oppure, se hai davvero bisogno di passare i numeri al formato, puoi convertire la tua rappresentazione binaria in BigInteger e quindi formattarla con zeri iniziali, ma questo è molto costoso in fase di esecuzione, come in:

String.format("%016d", new BigInteger(Integer.toBinaryString(1)))

Grazie, questa è migliore, poiché evita l'overflow sui grandi numeri (es. 2 ^ 30).
khachik

1
Sì, ma davvero non lo farei, userei il metodo di sostituzione o il mio metodo di riempimento: un modo sarebbe usare di nuovo String.format per formattare la lunghezza di riempimento necessaria con l'argomento zero o nel codice: String.format ( "% 0" + (32 - binary.length ()) + "d"% s ", 0, binary) ovviamente dovrai controllare i risultati negativi di 32 - binary.length () ...
Zoran Regvart

12

Puoi usare Apache Commons StringUtils . Offre metodi per riempire le stringhe:

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

9

Stavo provando tutti i tipi di chiamate di metodo che non avevo mai usato prima per farlo funzionare, hanno funzionato con moderato successo, finché non ho pensato a qualcosa di così semplice che potrebbe funzionare, e lo ha fatto!

Sono sicuro che è stato pensato prima, non sono sicuro che sia buono per lunghe stringhe di codici binari, ma funziona bene per stringhe a 16 bit. Spero che sia d'aiuto!! (Nota che la seconda parte di codice è migliorata)

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

Grazie a Will per aver contribuito a migliorare questa risposta per farla funzionare senza un ciclo. Questo potrebbe essere un po 'goffo ma funziona, per favore migliora e commenta se puoi ....

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;

Questa è una soluzione semplice e piacevole. Potrebbe essere migliorato utilizzando la differenza tra binString.length()e 16 per creare una stringa e quindi aggiungendo quella stringa a binString invece di eseguire il ciclo anche se con qualcosa di simile a questa risposta: stackoverflow.com/a/2804866/1353098
Will

1
Will - sei brillante, metterlo nel mio codice adesso! Neanche a me è piaciuto il loop, grazie !!!
Tom Spencer

7

Ecco una nuova risposta per un vecchio post.

Per riempire un valore binario con zeri iniziali a una lunghezza specifica, prova questo:

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

Se len = 4e val = 1,

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

restituisce la stringa "10001", quindi

"10001".substring( 1 )

scarta il primo carattere. Quindi otteniamo quello che vogliamo:

"0001"

Se valè probabile che sia negativo, prova piuttosto:

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

5

Una versione più semplice dell'idea di user3608934 "Questo è un vecchio trucco, crea una stringa con 16 0 quindi aggiungi la stringa binaria tagliata che hai":

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

4

Non conosco la soluzione "giusta" ma posso suggerirti una patch veloce.

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

L'ho appena provato e ho visto che funziona bene.


perché il formattatore è largo solo 16 caratteri? perchè no %32s?
portatore dell'anello

3

provare...

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

Non penso che questo sia il modo "corretto" per farlo ... ma funziona :)


1
Questo è certamente un buon sistema per farlo, perché funziona solo fino ad una piccola frazione di valori di input .... La più grande potenza che può con successo produzione è 0000001111111111per il valore di ingresso 1023Qualsiasi valore maggiore di quello produrrà l'uscita dal toBinaryString(1024)di 10000000000che è troppo grande per parseInt(...)Così, l'input funziona solo per 1K di 64K possibili valori di input
rolfl

1

Una soluzione ingenua che funzionerebbe

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

Un altro metodo sarebbe

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

Questo produrrà una stringa a 16 bit dell'intero 5


1

A partire da Java 11, puoi utilizzare il metodo repeat (...) :

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

Oppure, se è necessaria la rappresentazione a 32 bit di qualsiasi numero intero:

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

0

Questo è un vecchio trucco, crea una stringa con 16 0 quindi aggiungi la stringa binaria tagliata che hai ottenuto da String.format ("% s", Integer.toBinaryString (1)) e usa i 16 caratteri più a destra, eliminando qualsiasi iniziale 0 di. Meglio ancora, crea una funzione che ti consenta di specificare la lunghezza di una stringa binaria che desideri. Ovviamente ci sono probabilmente un miliardo di altri modi per ottenere questo risultato, incluse le librerie, ma aggiungo questo post per aiutare un amico :)

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

0

Vorrei scrivere la mia classe util con il metodo come di seguito

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

}

Produzione:

5
101
0000000000000000000000000000000000000000000000000000000000000101

Lo stesso approccio potrebbe essere applicato a qualsiasi tipo integrale. Presta attenzione al tipo di maschera

long mask = 1L << i;


0

Questo metodo converte un int in una stringa, length = bits. O riempito con 0 o con i bit più significativi troncati.

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

0

Puoi usare lib https://github.com/kssource/BitSequence . Accetta un numero e restituisce una stringa numerica, riempita e / o raggruppata.

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

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()è la lunghezza del numero diciamo 2 in binario è 01 che è la lunghezza 2 cambia 4 alla lunghezza massima desiderata del numero. Questo può essere ottimizzato su O (n). utilizzando continue.


0

// Di seguito gestirà le dimensioni corrette

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

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

1
numBe numsono uguali e non diversi in alcun modo
igorepst
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.