Wie bekomme ich eine 0-aufgefüllte binäre Darstellung einer Ganzzahl in Java?

120

Zum Beispiel kann für 1, 2, 128, 256die Ausgabe (16 Stellen) sein:

0000000000000001
0000000000000010
0000000010000000
0000000100000000

Ich habe es versucht

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

Es werden Leerzeichen für die linke Polsterung eingefügt:

`               1'

Wie 0s zum Polstern setzen. Ich konnte es in Formatter nicht finden . Gibt es einen anderen Weg, es zu tun?

PS In diesem Beitrag wird beschrieben, wie Ganzzahlen mit linkem 0-Abstand formatiert werden, jedoch nicht für die binäre Darstellung.

Khachik
quelle
Haben Sie versucht, zu verwenden %016s?
Deniz Dogan
1
@ Deniz ja, es schlägt fehl mitException in thread "main" java.util.FormatFlagsConversionMismatchException: Conversion = s, Flags = 0
Khachik
Schauen Sie sich das an: stackoverflow.com/a/15124135/1316649
fstang

Antworten:

198

Ich denke, das ist eine suboptimale Lösung, aber Sie könnten es tun

String.format("%16s", Integer.toBinaryString(1)).replace(' ', '0')
Samuel Pfarrhaus
quelle
1
Ja, ich mache es jetzt, aber ich glaube, es sollte einen anderen Weg geben :) Danke.
Khachik
Nach einigen Recherchen sieht es so aus, als ob Sie es nicht einfach mit der printf-Syntax tun können. Vielleicht ist es also doch nicht so schlimm.
Samuel Parsonage
@ Daniel Negative Zahl enthält kein Leerzeichen, funktioniert also auch.
Eric Wang
@ Daniel Integer :: toBinaryString doc:Returns a string representation of the integer argument as an unsigned integer in base 2.
Alan
17

In java.util.Formatter ist keine binäre Konvertierung integriert. Ich würde Ihnen raten, entweder String.replace zu verwenden, um Leerzeichen durch Nullen zu ersetzen, wie in:

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

Oder Ihre eigene Logik zu konvertieren ganzen Zahlen in binärer Darstellung mit zusätzlichen links padding irgendwo entlang der in bestimmten Linien implementieren diese so. Wenn Sie zum Formatieren wirklich Zahlen übergeben müssen, können Sie Ihre Binärdarstellung in BigInteger konvertieren und diese dann mit führenden Nullen formatieren. Dies ist jedoch zur Laufzeit sehr kostspielig, wie in:

String.format("%016d", new BigInteger(Integer.toBinaryString(1)))
Zoran Regvart
quelle
Danke, dieser ist besser, da er den Überlauf bei großen Zahlen (zB 2 ^ 30) vermeidet.
Khachik
1
Ja, aber ich würde es wirklich nicht tun, ich würde entweder die Ersetzungsmethode oder meine eigene Auffüllmethode verwenden: Eine Möglichkeit wäre, String.format erneut zu verwenden, um die erforderliche Auffülllänge mit dem Argument Null zu formatieren, oder im Code: String.format ( "% 0" + (32 - binary.length ()) + "d"% s ", 0, binär) Natürlich müssen Sie auf negative Ergebnisse von 32 - binary.length () ...
Zoran
12

Sie können Apache Commons StringUtils verwenden . Es bietet Methoden zum Auffüllen von Zeichenfolgen:

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

Ich habe alle Arten von Methodenaufrufen ausprobiert, die ich vorher nicht wirklich verwendet habe, um diese Arbeit zu machen. Sie haben mit mäßigem Erfolg funktioniert, bis ich an etwas dachte, das so einfach ist, dass es vielleicht funktioniert, und es hat funktioniert!

Ich bin sicher, es wurde schon früher darüber nachgedacht, nicht sicher, ob es für lange Zeichenfolgen von Binärcodes gut ist, aber es funktioniert gut für 16-Bit-Zeichenfolgen. Ich hoffe es hilft!! (Beachten Sie, dass der zweite Code verbessert wurde.)

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

Vielen Dank an Will für die Verbesserung dieser Antwort, damit sie ohne Schleife funktioniert. Das ist vielleicht etwas ungeschickt, aber es funktioniert. Bitte verbessern Sie es und kommentieren Sie es zurück, wenn Sie können.

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
quelle
Dies ist eine schöne und einfache Lösung. Es könnte verbessert werden, indem der Unterschied zwischen binString.length()und 16 verwendet wird, um eine Zeichenfolge zu erstellen, und diese Zeichenfolge dann an binString angehängt wird, anstatt eine Schleife zu erstellen. Stackoverflow.com/a/2804866/1353098
Will
1
Will - du bist brillant, ich schreibe das jetzt in meinen Code! Ich mochte die Schleife auch nicht, danke !!!
Tom Spencer
7

Hier eine neue Antwort für einen alten Beitrag.

Versuchen Sie Folgendes, um einen Binärwert mit führenden Nullen auf eine bestimmte Länge aufzufüllen:

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

Wenn len = 4und val = 1,

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

die Zeichenfolge zurückgibt "10001", dann

"10001".substring( 1 )

verwirft das allererste Zeichen. So erhalten wir, was wir wollen:

"0001"

Wenn vales wahrscheinlich negativ ist, versuchen Sie lieber:

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

Eine einfachere Version der Idee von user3608934 "Dies ist ein alter Trick. Erstellen Sie eine Zeichenfolge mit 16 Nullen und fügen Sie dann die zugeschnittene Binärzeichenfolge hinzu, die Sie erhalten haben."

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

Ich kenne keine "richtige" Lösung, aber ich kann Ihnen einen schnellen Patch vorschlagen.

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

Ich habe es gerade versucht und gesehen, dass es gut funktioniert.

AlexR
quelle
Warum ist der Formatierer nur 16 Zeichen breit? warum nicht %32s?
Ringträger
3

Versuchen...

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

Ich denke nicht, dass dies der "richtige" Weg ist, dies zu tun ... aber es funktioniert :)

Paul
quelle
1
Dies ist sicherlich ein schlechter Weg, da dies nur bis zu einem kleinen Bruchteil der Eingabewerte funktioniert. Die größte Ausgabe, die erfolgreich erzeugt werden kann, ist 0000001111111111für den Eingabewert. 1023Jeder größere Wert erzeugt die Ausgabe, aus toBinaryString(1024)der er 10000000000stammt zu groß für die parseInt(...)Somit funktioniert die Eingabe nur für 1K von 64K möglichen Eingabewerten
rolfl
1

Eine naive Lösung, die funktionieren würde

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

Eine andere Methode wäre

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

Dies erzeugt eine 16-Bit-Zeichenfolge der Ganzzahl 5

proeng
quelle
1

Ab Java 11 können Sie die Wiederholungsmethode (...) verwenden:

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

Oder wenn Sie eine 32-Bit-Darstellung einer Ganzzahl benötigen:

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

Dies ist ein alter Trick. Erstellen Sie eine Zeichenfolge mit 16 Nullen und fügen Sie dann die zugeschnittene Binärzeichenfolge hinzu, die Sie aus String.format ("% s", Integer.toBinaryString (1)) erhalten haben, und verwenden Sie die 16 Zeichen ganz rechts, wobei Sie alle führenden Zeichen entfernen Nullen. Besser noch, machen Sie eine Funktion, mit der Sie angeben können, wie lange eine Binärzeichenfolge Sie möchten. Natürlich gibt es wahrscheinlich eine Unmenge anderer Möglichkeiten, dies zu erreichen, einschließlich Bibliotheken, aber ich füge diesen Beitrag hinzu, um einem Freund zu helfen :)

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
quelle
0

Ich würde meine eigene util-Klasse mit der folgenden Methode schreiben

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

}}

Ausgabe:

5
101
000000000000000000000000000000000000000000000000000000000000000101

Der gleiche Ansatz könnte auf alle integralen Typen angewendet werden. Achten Sie auf die Art der Maske

long mask = 1L << i;

Arseny Kovalchuk
quelle
0

Diese Methode konvertiert ein int in einen String, Länge = Bits. Entweder mit Nullen aufgefüllt oder mit den höchstwertigen Bits abgeschnitten.

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
quelle
0

Sie können lib https://github.com/kssource/BitSequence verwenden . Es akzeptiert eine Zahl und gibt eine beliebige Zeichenfolge zurück, aufgefüllt und / oder gruppiert.

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
quelle
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()ist die Länge der Zahl, sagen wir, 2 in binär ist 01, was die Länge 2 ist, ändern Sie 4 auf die gewünschte maximale Länge der Zahl. Dies kann auf O (n) optimiert werden. mit continue.

Jasmeet Chhabra
quelle
0

// Unten werden die richtigen Größen behandelt

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
quelle
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
quelle
1
numBund numsind gleich und in keiner Weise unterschiedlich
igorepst