Jak uzyskać binarną reprezentację liczby całkowitej z zerami w języku Java?


120

na przykład dla 1, 2, 128, 256wyjścia może być (16 cyfr):

0000000000000001
0000000000000010
0000000010000000
0000000100000000

próbowałem

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

umieszcza spacje na dopełnienie z lewej strony:

`               1'

Jak założyć 0wyściółkę. Nie mogłem go znaleźć w programie Formatter . Czy jest inny sposób, aby to zrobić?

PS Ten post opisuje, jak formatować liczby całkowite z lewym dopełnieniem 0, ale nie jest to reprezentacja binarna.


Czy próbowałeś użyć %016s?
Deniz Dogan

1
@Deniz tak, nie udaje się zException in thread "main" java.util.FormatFlagsConversionMismatchException: Conversion = s, Flags = 0
khachik

Odpowiedzi:


198

Myślę, że to nieoptymalne rozwiązanie, ale możesz to zrobić

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

1
Tak, robię to teraz, ale uważam, że powinien być inny sposób :) Dziękuję.
chaczik

właściwie po zrobieniu pewnych badań wygląda na to, że nie da się tego zrobić po prostu używając składni printf .. Więc może wcale nie jest tak źle.
Samuel Parsonage,

@Daniel Liczba ujemna nie zawiera spacji, więc też działa.
Eric Wang

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

17

Nie ma wbudowanej konwersji binarnej w java.util.Formatter, radziłbym użyć String.replace do zastąpienia znaku spacji zerami, jak w:

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

Lub zaimplementuj własną logikę do konwersji liczb całkowitych na reprezentację binarną z dodanym lewym dopełnieniem gdzieś wzdłuż linii podanych w tym przykładzie . Lub jeśli naprawdę potrzebujesz przekazać liczby do formatu, możesz przekonwertować swoją reprezentację binarną na BigInteger, a następnie sformatować ją z zerami wiodącymi, ale jest to bardzo kosztowne w czasie wykonywania, jak w:

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

Dzięki, ten jest lepszy, ponieważ pozwala uniknąć przepełnienia dużych liczb (np. 2 ^ 30).
chaczik

1
Tak, ale naprawdę bym tego nie zrobił, użyłbym metody replace lub własnej metody dopełniania: jednym ze sposobów byłoby ponowne użycie String.format do sformatowania wymaganej długości dopełnienia z argumentem zero lub w kodzie: String.format ( "% 0" + (32 - binary.length ()) + "d"% s ", 0, binary) oczywiście musisz uważać na ujemne wyniki 32 - binary.length () ...
Zoran Regvart

12

Możesz użyć Apache Commons StringUtils . Oferuje metody wypełniania strun:

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

9

Próbowałem różnych wywołań metod, których wcześniej nie używałem, aby to działało, działały z umiarkowanym sukcesem, dopóki nie pomyślałem o czymś, co jest tak proste, że może po prostu zadziałać, i zadziałało!

Jestem pewien, że pomyślano o tym wcześniej, nie jestem pewien, czy jest to dobre dla długiego ciągu kodów binarnych, ale działa dobrze w przypadku ciągów 16-bitowych. Mam nadzieję, że to pomoże!! (Uwaga: drugi fragment kodu został ulepszony)

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

Dzięki Willowi za pomoc w ulepszeniu tej odpowiedzi, aby działała bez pętli. To może trochę niezdarne, ale działa, popraw i skomentuj, jeśli możesz ....

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;

To ładne i proste rozwiązanie. Można to poprawić, używając różnicy między binString.length()a 16 do utworzenia ciągu, a następnie dołączając ten ciąg do binString zamiast zapętlania, chociaż za pomocą czegoś takiego jak ta odpowiedź: stackoverflow.com/a/2804866/1353098
Will

1
Will - jesteś genialny, w tej chwili włożyłem to do mojego kodu! Pętla też mi się nie podobała, dziękuję !!!
Tom Spencer,

7

Tutaj nowa odpowiedź na stary post.

Aby dopełnić wartość binarną wiodącymi zerami do określonej długości, spróbuj tego:

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

Jeśli len = 4i val = 1,

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

zwraca "10001"następnie ciąg

"10001".substring( 1 )

odrzuca pierwszy znak. Otrzymujemy więc to, czego chcemy:

"0001"

Jeśli valmoże być negatywne, spróbuj:

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

5

Prostsza wersja pomysłu użytkownika3608934 „To stara sztuczka, utwórz ciąg z 16 zerami, a następnie dołącz przycięty ciąg binarny, który otrzymałeś”:

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

4

Nie znam "właściwego" rozwiązania, ale mogę zaproponować szybką łatkę.

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

Właśnie go wypróbowałem i zobaczyłem, że działa dobrze.


dlaczego formatyzator ma tylko 16 znaków szerokości? dlaczego nie %32s?
okaziciel pierścienia

3

próbować...

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

Nie sądzę, żeby to był „właściwy” sposób na zrobienie tego ... ale działa :)


1
Jest to z pewnością słaba sposób to zrobić, ponieważ działa tylko do niewielkiego ułamka wartości wejściowych .... Największy wyjście to może z powodzeniem produkować jest 0000001111111111dla wartości wejściowej 1023Każda wartość większa niż przyniesie wyjście z toBinaryString(1024)od 10000000000którego jest zbyt duży dla parseInt(...)W ten sposób wejście działa tylko dla 1K z 64K możliwych wartości wejściowych
rolfl

1

To naiwne rozwiązanie

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

Mogłaby być inna metoda

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

Spowoduje to utworzenie 16-bitowego ciągu liczby całkowitej 5


1

Począwszy od Java 11, możesz użyć metody repeat (...) :

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

Lub, jeśli potrzebujesz 32-bitowej reprezentacji dowolnej liczby całkowitej:

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

0

To jest stara sztuczka, utwórz ciąg z 16 zerami, a następnie dołącz przycięty ciąg binarny otrzymany z String.format ("% s", Integer.toBinaryString (1)) i użyj 16 skrajnych prawostronnych znaków, odcinając wszelkie początkowe 0's. Jeszcze lepiej, stwórz funkcję, która pozwoli ci określić, jak długi ciąg binarny chcesz. Oczywiście istnieje prawdopodobnie miliard innych sposobów na osiągnięcie tego, w tym biblioteki, ale dodaję ten post, aby pomóc przyjacielowi :)

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

Napisałbym własną klasę util z metodą jak poniżej

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

}

Wynik:

5
101
00000000000000000000000000000000000000000000000000000000000101

To samo podejście można zastosować do dowolnych typów całkowitych. Zwróć uwagę na rodzaj maski

long mask = 1L << i;


0

Ta metoda konwertuje int na String, length = bits. Albo uzupełnione zerami, albo obcięte najbardziej znaczące bity.

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

Możesz użyć lib https://github.com/kssource/BitSequence . Akceptuje liczbę i zwraca bajnarny łańcuch, dopełniony i / lub zgrupowany.

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()to długość liczby, powiedzmy, że 2 w systemie dwójkowym to 01, czyli długość 2, zmień 4 na żądaną maksymalną długość liczby. Można to zoptymalizować do O (n). używając Continue.


0

// Poniżej znajdziesz odpowiednie rozmiary

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
numBi numsą równi i nie różnią się w żaden sposób
igorepst
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.