Як отримати 0-padded бінарне представлення цілого числа в java?


120

наприклад, для 1, 2, 128, 256виходу може бути (16 цифр):

0000000000000001
0000000000000010
0000000010000000
0000000100000000

я намагався

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

він ставить пробіли для лівої підкладки:

`               1'

Як укласти 0s для підкладки. Я не зміг його знайти у форматі . Чи є інший спосіб це зробити?

У цій публікації PS описано, як форматувати цілі числа з лівим 0-padding, але це не для двійкового представлення.


Ви спробували використовувати %016s?
Деніз Доган

1
@Deniz так, це не вдаєтьсяException in thread "main" java.util.FormatFlagsConversionMismatchException: Conversion = s, Flags = 0
хачик

подивіться на це: stackoverflow.com/a/15124135/1316649
fstang

Відповіді:


198

Я думаю, що це неоптимальне рішення, але ви могли б зробити

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

1
Так, я це роблю зараз, але я вважаю, що має бути інший шлях :) Дякую.
хачик

насправді після деяких досліджень, схоже, що ви не можете це зробити, просто використовуючи синтаксис printf .. Тож, можливо, це все не так вже й погано.
Самуель Парсонаж

@Daniel Негативний номер не міститиме місця, тому він також працює.
Ерік Ван

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

17

Не існує вбудованого бінарного перетворення в java.util.Formatter, я б радив вам використовувати String.replace для заміни символу пробілу нулями, як у:

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

Або застосуйте власну логіку для перетворення цілих чисел у двійкове представлення з додаванням лівої підкладки десь уздовж рядків, наведених у цьому . Або якщо вам дійсно потрібно передати номери у формат, ви можете перетворити своє бінарне представлення в BigInteger, а потім відформатувати це за допомогою ведучих нулів, але це дуже дорого під час виконання, як у:

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

Дякую, це краще, оскільки це дозволяє уникнути переповнення великої кількості (наприклад, 2 ^ 30).
хачик

1
Так, але я б дійсно цього не робив, я б застосував або метод заміни, або власний метод заміщення: один із способів - знову використовувати String.format для форматування необхідної довжини прокладки з нульовим аргументом або в коді: String.format ( "% 0" + (32 - binary.length ()) + "d"% s ", 0, binary), звичайно, вам потрібно буде стежити за негативними результатами 32 - binary.length () ...
Zoran Regvart

12

Ви можете використовувати Apache Commons StringUtils . Він пропонує методи набивання струн:

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

9

Я пробував всілякі виклики методів, які я раніше не використовував, щоб зробити цю роботу, вони працювали з помірним успіхом, поки я не подумав про те, що таке просте, що просто може спрацювати, і це було!

Я впевнений, що про це думали раніше, не впевнений, чи корисний це довгий рядок двійкових кодів, але він добре працює для рядків 16Bit. Сподіваюся, це допомагає !! (Зверніть увагу, другий фрагмент коду вдосконалений)

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

Завдяки Волі, що допомогла вдосконалити цю відповідь, щоб вона працювала з циклом. Це, можливо, трохи незграбно, але це працює, будь ласка, вдосконаліть і прокоментуйте, якщо зможете….

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;

Це приємне і просте рішення. Це можна було б покращити, використовуючи різницю між binString.length()16 та створити рядок, а потім додати цю рядок до binString, а не циклічно, хоча з подібною відповіддю: stackoverflow.com/a/2804866/1353098
Буде

1
Будеш - ти геніальний, погано вклав це в мій код прямо зараз! Мені також не сподобалася петля, дякую !!!
Том Спенсер

7

Ось нова відповідь на старий пост.

Щоб встановити бінарне значення з провідними нулями на певну довжину, спробуйте це:

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

Якщо len = 4і val = 1,

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

повертає рядок "10001", значить

"10001".substring( 1 )

відкидає найпершого персонажа. Таким чином ми отримуємо те, що хочемо:

"0001"

Якщо valце, швидше за все, негативно, спробуйте:

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

5

Простіша версія ідеї user3608934 "Це стара хитрість. Створіть рядок з 16 0, а потім додайте обрізаний бінарний рядок, який ви отримали":

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

4

Я не знаю "правильного" рішення, але я можу запропонувати вам швидкий виправлення.

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

Я щойно спробував це і побачив, що він прекрасно працює.


чому формат формату становить лише 16 символів? чому ні %32s?
носія кільця

3

спробуйте ...

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

Я не думаю, що це "правильний" спосіб зробити це ... але це працює :)


1
Це, звичайно, поганий спосіб зробити це , тому що він працює тільки до невеликої частини вхідних значень .... Найбільшого виходу може успішно продукція 0000001111111111для вхідного значення 1023Будь-якого значення більше , ніж буде виробляти вихід з toBinaryString(1024)з 10000000000яких є Занадто великий для parseInt(...)Таким чином, вхід працює лише для 1K 64K можливих вхідних значень
rolfl

1

Наївне рішення, яке було б справою

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

Ще один метод був би

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

Це створить 16-бітний рядок цілого числа 5


1

Починаючи з Java 11, ви можете використовувати метод повторення (...) :

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

Або якщо вам потрібно 32-бітове представлення будь-якого цілого числа:

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

0

Це стара хитрість, створіть рядок з 16 0, а потім додайте обрізаний бінарний рядок, який ви отримали від String.format ("% s", Integer.toBinaryString (1)), і використовуйте найправильніші 16 символів, відключаючи будь-які ведучі 0. А ще краще, зробіть функцію, яка дозволяє вам вказати, яку довжину бінарного рядка ви хочете. Звичайно, мабуть, є мільярд інших способів досягти цього, включаючи бібліотеки, але я додаю цю посаду, щоб допомогти другові :)

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

Я б написав власний клас утиліти методом, як показано нижче

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

}

Вихід:

5
101
00000000000000000000000000000000000000000000000000000000000000000101

Цей же підхід може бути застосований до будь-яких цілісних типів. Зверніть увагу на тип маски

long mask = 1L << i;


0

Цей метод перетворює int в String, length = біти. Або із заниженими знаками 0, або з усіма найбільш значущими бітами.

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

Ви можете використовувати lib https://github.com/kssource/BitSequence . Він приймає число і повертає банальний рядок, прокладений та / або згрупований.

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()- довжина числа, скажімо, 2 у двійковій формі - 01, а довжина 2 - зміна 4 на бажану максимальну довжину числа. Це можна оптимізувати до O (n). використовуючи продовжити.


0

// Нижче буде оброблено належні розміри

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
numBі numрівні і нічим не відрізняються
igorepst
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.