Как получить двоичное представление целого числа с нулями в java?

120

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

0000000000000001
0000000000000010
0000000010000000
0000000100000000

Я попытался

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

он помещает пробелы для заполнения слева:

`               1'

Как поставить 0s для заполнения. Я не смог найти его в Formatter . Есть другой способ сделать это?

PS этот пост описывает, как форматировать целые числа с левым заполнением 0, но это не для двоичного представления.

Хачик
источник
Вы пробовали использовать %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 ... Так что, возможно, это не так уж и плохо.
Samuel Parsonage
@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
Да, но я бы действительно не стал этого делать, я бы использовал либо метод replace, либо свой собственный метод заполнения: один из способов - снова использовать String.format для форматирования необходимой длины заполнения с нулевым аргументом или в коде: String.format ( "% 0" + (32 - binary.length ()) + "d"% s ", 0, binary), конечно, вам нужно будет следить за отрицательными результатами 32 - binary.length () ...
Зоран Regvart
12

Вы можете использовать Apache Commons StringUtils . Он предлагает методы для заполнения строк:

StringUtils.leftPad(Integer.toBinaryString(1), 16, '0');
Bunarro
источник
9

Я пробовал использовать всевозможные вызовы методов, которые раньше не использовал для этой работы, они работали с умеренным успехом, пока я не подумал о чем-то настолько простом, что он мог бы работать, и это сработало!

Я уверен, что об этом думали раньше, не уверен, что это хорошо для длинной строки двоичных кодов, но отлично работает для 16-битных строк. Надеюсь, поможет!! (Обратите внимание, что второй фрагмент кода улучшен)

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 )
Cr4paud
источник
5

Более простая версия идеи user3608934 «Это старый трюк, создайте строку с 16 нулями, а затем добавьте обрезанную двоичную строку, которую вы получили»:

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

Я только что попробовал и убедился, что все работает нормально.

AlexR
источник
почему форматер имеет ширину всего 16 символов? почему бы и нет %32s?
кольцо предъявитель
3

пытаться...

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

Я не думаю, что это "правильный" способ сделать это ... но он работает :)

Павел
источник
1
Это, конечно, плохой способ сделать это , потому что он работает только до небольшой части входных значений .... Самого большого выхода может успешно продукция 0000001111111111для входного значения 1023Любого значения больше , чем будет производить выход из toBinaryString(1024)из 10000000000которых является слишком велик для parseInt(...)Таким образом, вход работает только для 1К из 64К возможных входных значений
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

proeng
источник
1

Начиная с Java 11, вы можете использовать метод repeat (...) :

"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 );
    }
}
user3608934
источник
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
0000000000000000000000000000000000000000000000000000000000000101

Тот же подход можно применить к любым целым типам. Обратите внимание на тип маски

long mask = 1L << i;

Арсений Ковальчук
источник
0

Этот метод преобразует int в String, length = bits. Либо с дополнением нулями, либо с усечением наиболее значимых битов.

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
источник
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
Nikmass
источник
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). используя continue.

Джасмит Чхабра
источник
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равны и ничем не отличаются
игорепст