Làm cách nào để lấy biểu diễn nhị phân có đệm 0 của một số nguyên trong java?


120

ví dụ, đối 1, 2, 128, 256với đầu ra có thể là (16 chữ số):

0000000000000001
0000000000000010
0000000010000000
0000000100000000

Tôi đã thử

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

nó đặt khoảng trống cho phần đệm bên trái:

`               1'

Cách đặt 0s cho phần đệm. Tôi không thể tìm thấy nó trong Formatter . Có cách nào khác để làm điều đó không?

Tái bút bài đăng này mô tả cách định dạng số nguyên với phần đệm 0 bên trái, nhưng nó không dành cho biểu diễn nhị phân.


Bạn đã thử sử dụng %016schưa?
Deniz Dogan

1
@Deniz có, nó không thành công vớiException in thread "main" java.util.FormatFlagsConversionMismatchException: Conversion = s, Flags = 0
Khachik

Câu trả lời:


198

Tôi nghĩ đây là một giải pháp không tối ưu, nhưng bạn có thể làm

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

1
Vâng, tôi làm điều đó ngay bây giờ, nhưng tôi tin rằng nên có một cách khác :) Cảm ơn bạn.
khachik

thực sự sau khi thực hiện một số nghiên cứu, có vẻ như bạn không thể làm điều đó nếu chỉ sử dụng cú pháp printf .. Vì vậy, có lẽ nó không quá tệ.
Samuel Parsonage

@Daniel Số âm sẽ không chứa bất kỳ khoảng trắng nào, vì vậy nó cũng hoạt động.
Eric Wang,

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

17

Không có chuyển đổi nhị phân nào được tích hợp trong java.util.Formatter, tôi khuyên bạn nên sử dụng String.replace để thay thế ký tự khoảng trắng bằng số không, như trong:

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

Hoặc thực hiện logic của riêng bạn để chuyển đổi số nguyên sang biểu diễn nhị phân với phần đệm bên trái được thêm vào đâu đó dọc theo các dòng được đưa ra trong điều này . Hoặc nếu bạn thực sự cần chuyển các số sang định dạng, bạn có thể chuyển đổi biểu diễn nhị phân của mình thành BigInteger và sau đó định dạng bằng các số 0 ở đầu, nhưng điều này rất tốn kém trong thời gian chạy, như trong:

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

Cảm ơn, cái này tốt hơn, vì nó tránh bị tràn trên các số lớn (ví dụ: 2 ^ 30).
khachik

1
Có, nhưng tôi thực sự sẽ không làm điều đó, tôi sẽ sử dụng phương thức thay thế hoặc phương thức đệm của riêng mình: một cách là sử dụng lại String.format để định dạng độ dài đệm cần thiết với đối số bằng không hoặc trong mã: String.format ( "% 0" + (32 - binary.length ()) + "d"% s ", 0, binary) tất nhiên bạn sẽ cần phải theo dõi kết quả tiêu cực của 32 - binary.length () ...
Zoran Khởi hành lại

12

Bạn có thể sử dụng Apache Commons StringUtils . Nó cung cấp các phương pháp cho chuỗi đệm:

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

9

Tôi đã thử tất cả các loại lệnh gọi phương thức mà tôi chưa thực sự sử dụng trước đây để thực hiện công việc này, chúng hoạt động với thành công vừa phải, cho đến khi tôi nghĩ ra một thứ đơn giản đến mức có thể hoạt động, và nó đã thành công!

Tôi chắc rằng nó đã được nghĩ đến trước đây, không chắc liệu nó có tốt cho chuỗi mã nhị phân dài hay không nhưng nó hoạt động tốt với chuỗi 16Bit. Hy vọng nó giúp!! (Lưu ý đoạn mã thứ hai được cải thiện)

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

Cảm ơn Will đã giúp cải thiện câu trả lời này để làm cho nó hoạt động mà không có vòng lặp. Điều này có thể hơi vụng về nhưng nó hoạt động, hãy cải thiện và nhận xét lại nếu bạn có thể ....

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;

Đây là một giải pháp tốt và đơn giản. Nó có thể được cải thiện bằng cách sử dụng sự khác biệt giữa binString.length()và 16 để tạo một chuỗi và sau đó nối chuỗi đó vào binString thay vì lặp lại mặc dù với câu trả lời như sau: stackoverflow.com/a/2804866/1353098
Sẽ

1
Will - bạn thật tuyệt vời, hãy đưa nó vào mã của tôi ngay bây giờ! Tôi cũng không thích vòng lặp, thankyou !!!
Tom Spencer

7

Đây là một câu trả lời mới cho một bài viết cũ.

Để chèn một giá trị nhị phân với các số 0 ở đầu vào một độ dài cụ thể, hãy thử cách này:

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

Nếu len = 4val = 1,

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

trả về chuỗi "10001", sau đó

"10001".substring( 1 )

loại bỏ ký tự đầu tiên. Vì vậy, chúng tôi đạt được những gì chúng tôi muốn:

"0001"

Nếu valcó khả năng là tiêu cực, thay vì thử:

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

5

Một phiên bản đơn giản hơn của ý tưởng của user3608934 "Đây là một thủ thuật cũ, hãy tạo một chuỗi có 16 số 0 sau đó nối chuỗi nhị phân đã được cắt bớt mà bạn có":

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

4

Tôi không biết giải pháp "đúng" nhưng tôi có thể đề xuất cho bạn một bản vá nhanh.

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

Tôi vừa dùng thử và thấy nó hoạt động tốt.


tại sao định dạng chỉ rộng 16 ký tự? tại sao không %32s?
người mang nhẫn

3

thử...

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

Tôi không nghĩ đây là cách "chính xác" để làm điều này ... nhưng nó hoạt động :)


1
Điều này chắc chắn là một cách nghèo để làm điều đó bởi vì nó chỉ có tác dụng lên đến một phần nhỏ của giá trị đầu vào .... Sản lượng lớn nhất nó có thể thành công sản phẩm được 0000001111111111cho giá trị đầu vào 1023Bất kỳ giá trị lớn hơn sẽ cho kết quả từ toBinaryString(1024)các 10000000000đó là quá lớn đối với parseInt(...)Như vậy, đầu vào chỉ hoạt động cho 1K của 64K giá trị đầu vào có thể
rolfl

1

Một giải pháp ngây thơ mà hiệu quả sẽ là

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

Một phương pháp khác sẽ là

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

Điều này sẽ tạo ra một chuỗi 16 bit của số nguyên 5


1

Bắt đầu với Java 11, bạn có thể sử dụng phương thức repeat (...) :

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

Hoặc, nếu bạn cần biểu diễn 32 bit của bất kỳ số nguyên nào:

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

0

Đây là một thủ thuật cũ, tạo một chuỗi có 16 số 0 sau đó nối chuỗi nhị phân đã cắt bớt mà bạn nhận được từ String.format ("% s", Integer.toBinaryString (1)) và sử dụng 16 ký tự ngoài cùng bên phải, loại bỏ bất kỳ ký tự đầu nào 0 của. Tốt hơn, hãy tạo một hàm cho phép bạn chỉ định độ dài của một chuỗi nhị phân mà bạn muốn. Tất nhiên, có lẽ có hàng triệu cách khác để thực hiện điều này bao gồm cả thư viện, nhưng tôi thêm bài đăng này để giúp đỡ một người bạn :)

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

Tôi sẽ viết lớp sử dụng của riêng mình với phương thức như dưới đây

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

}

Đầu ra:

5
101
000000000000000000000000000000000000000000000000000000000000000101

Cách tiếp cận tương tự có thể được áp dụng cho bất kỳ loại tích phân nào. Chú ý đến loại mặt nạ

long mask = 1L << i;


0

Phương thức này chuyển đổi một int thành một chuỗi, độ dài = bit. Được đệm bằng số 0 hoặc bị cắt bớt các bit quan trọng nhất.

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

Bạn có thể sử dụng lib https://github.com/kssource/BitSequence . Nó chấp nhận một số và trả về chuỗi byte, được đệm và / hoặc được nhóm lại.

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()là độ dài của số, ví dụ 2 trong hệ nhị phân là 01 là độ dài 2 thay đổi 4 thành độ dài tối đa mong muốn của số. Điều này có thể được tối ưu hóa thành O (n). bằng cách sử dụng tiếp tục.


0

// Bên dưới sẽ xử lý các kích thước phù hợp

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
numBnumđều bình đẳng và không khác dưới mọi hình thức
igorepst
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.