Comment obtenir une représentation binaire complétée par 0 d'un entier en Java?


120

par exemple, pour 1, 2, 128, 256la sortie peut être (16 chiffres):

0000000000000001
0000000000000010
0000000010000000
0000000100000000

j'ai essayé

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

il met des espaces pour le remplissage à gauche:

`               1'

Comment mettre des 0s pour le rembourrage. Je n'ai pas pu le trouver dans Formatter . Y a-t-il une autre façon de le faire?

PS ce post décrit comment formater des entiers avec un remplissage 0 à gauche, mais ce n'est pas pour la représentation binaire.


Avez-vous essayé d'utiliser %016s?
Deniz Dogan

1
@Deniz oui, ça échoue avecException in thread "main" java.util.FormatFlagsConversionMismatchException: Conversion = s, Flags = 0
khachik

Réponses:


198

Je pense que c'est une solution sous-optimale, mais vous pouvez faire

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

1
Oui, je le fais maintenant, mais je crois qu'il devrait y avoir un autre moyen :) Merci.
khachik

en fait, après avoir fait quelques recherches, on dirait que vous ne pouvez pas le faire simplement en utilisant la syntaxe printf .. Donc peut-être que ce n'est pas si mal après tout.
Samuel Parsonage

@Daniel Le nombre négatif ne contiendra aucun espace, donc cela fonctionne également.
Eric Wang

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

17

Il n'y a pas de conversion binaire intégrée dans java.util.Formatter, je vous conseillerais d'utiliser String.replace pour remplacer le caractère espace par des zéros, comme dans:

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

Ou implémentez votre propre logique pour convertir les nombres entiers en représentation binaire avec un remplissage à gauche ajouté quelque part le long des lignes données dans ceci . Ou si vous avez vraiment besoin de passer des nombres au format, vous pouvez convertir votre représentation binaire en BigInteger, puis la formater avec des zéros non significatifs, mais cela coûte très cher à l'exécution, comme dans:

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

Merci, celui-ci est meilleur, car il évite le débordement sur les gros nombres (par exemple 2 ^ 30).
khachik

1
Oui, mais je ne le ferais vraiment pas, j'utiliserais soit la méthode replace, soit ma propre méthode de remplissage: une façon serait d'utiliser à nouveau String.format pour formater la longueur de remplissage nécessaire avec l'argument zéro, ou dans le code: String.format ( "% 0" + (32 - binary.length ()) + "d"% s ", 0, binary) bien sûr, vous devrez surveiller les résultats négatifs de 32 - binary.length () ...
Zoran Regvart

12

Vous pouvez utiliser Apache Commons StringUtils . Il propose des méthodes de remplissage de chaînes:

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

9

J'essayais toutes sortes d'appels de méthode que je n'avais pas vraiment utilisés auparavant pour faire ce travail, ils ont fonctionné avec un succès modéré, jusqu'à ce que je pense à quelque chose qui est si simple que cela pourrait fonctionner, et ça l'a fait!

Je suis sûr que cela a déjà été pensé, je ne sais pas si c'est bon pour une longue chaîne de codes binaires, mais cela fonctionne bien pour les chaînes 16 bits. J'espère que ça aide!! (Notez que le deuxième morceau de code est amélioré)

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

Merci à Will d'avoir aidé à améliorer cette réponse pour qu'elle fonctionne sans boucle. C'est peut-être un peu maladroit mais cela fonctionne, veuillez améliorer et commenter si vous le pouvez ....

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;

C'est une solution simple et agréable. Il pourrait être amélioré en utilisant la différence entre binString.length()et 16 pour créer une chaîne, puis en ajoutant cette chaîne à binString plutôt qu'en boucle avec quelque chose comme cette réponse: stackoverflow.com/a/2804866/1353098
Will

1
Will - tu es génial, je vais mal mettre ça dans mon code maintenant! Je n'ai pas aimé la boucle non plus, merci !!!
Tom Spencer

7

Voici une nouvelle réponse pour un ancien post.

Pour compléter une valeur binaire avec des zéros non significatifs à une longueur spécifique, essayez ceci:

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

Si len = 4et val = 1,

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

renvoie la chaîne "10001", puis

"10001".substring( 1 )

supprime le tout premier caractère. Nous obtenons donc ce que nous voulons:

"0001"

Si cela valest susceptible d'être négatif, essayez plutôt:

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

5

Une version plus simple de l'idée de user3608934 "Ceci est une vieille astuce, créez une chaîne avec 16 0 puis ajoutez la chaîne binaire découpée que vous avez":

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

4

Je ne connais pas la "bonne" solution mais je peux vous proposer un patch rapide.

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

Je viens de l'essayer et j'ai vu que cela fonctionne bien.


pourquoi le formateur ne fait que 16 caractères de large? pourquoi pas %32s?
porteur de la bague

3

essayer...

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

Je ne pense pas que ce soit la "bonne" façon de faire ça ... mais ça marche :)


1
C'est certainement une mauvaise façon de le faire car cela ne fonctionne que jusqu'à une petite fraction des valeurs d'entrée .... La plus grande sortie qu'il peut produire avec succès est 0000001111111111pour la valeur d'entrée 1023Toute valeur plus grande que cela produira la sortie à partir toBinaryString(1024)de 10000000000laquelle est trop grand pour le parseInt(...)Ainsi, l'entrée ne fonctionne que pour 1K sur 64K valeurs d'entrée possibles
rolfl

1

Une solution naïve qui fonctionnerait serait

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

Une autre méthode serait

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

Cela produira une chaîne de 16 bits de l'entier 5


1

À partir de Java 11, vous pouvez utiliser la méthode repeat (...) :

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

Ou, si vous avez besoin d'une représentation 32 bits de n'importe quel entier:

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

0

C'est une vieille astuce, créez une chaîne avec 16 0 puis ajoutez la chaîne binaire découpée que vous avez obtenue de String.format ("% s", Integer.toBinaryString (1)) et utilisez les 16 caractères les plus à droite, en supprimant tout début 0. Mieux encore, créez une fonction qui vous permet de spécifier la longueur d'une chaîne binaire souhaitée. Bien sûr, il y a probablement un bazillion d'autres façons d'accomplir cela, y compris des bibliothèques, mais j'ajoute ce post pour aider un ami :)

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

J'écrirais ma propre classe util avec la méthode comme ci-dessous

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

}

Production:

5
101
000000000000000000000000000000000000000000000000000000000101

La même approche pourrait être appliquée à tous les types intégraux. Faites attention au type de masque

long mask = 1L << i;


0

Cette méthode convertit un int en une chaîne, longueur = bits. Soit complété avec des 0, soit avec les bits les plus significatifs tronqués.

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

Vous pouvez utiliser lib https://github.com/kssource/BitSequence . Il accepte un nombre et renvoie une chaîne annulaire, complétée et / ou groupée.

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()est la longueur du nombre, disons 2 en binaire, est 01 qui est la longueur 2 change 4 à la longueur maximale souhaitée du nombre. Cela peut être optimisé à O (n). en utilisant continuer.


0

// Ci-dessous traitera les tailles appropriées

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
numBet numsont égaux et pas différents en aucune façon
igorepst
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.