วิธีรับ 0-padded binary แทนจำนวนเต็มใน java?


120

ตัวอย่างเช่นสำหรับ1, 2, 128, 256ผลลัพธ์สามารถเป็น (16 หลัก):

0000000000000001
0000000000000010
0000000010000000
0000000100000000

ฉันเหนื่อย

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

ทำให้มีช่องว่างสำหรับช่องว่างด้านซ้าย:

`               1'

วิธีใส่0s สำหรับ padding. ไม่พบในฟอร์แมตเตอร์ มีวิธีอื่นที่จะทำได้หรือไม่?

ป.ล. โพสต์นี้อธิบายถึงวิธีการจัดรูปแบบจำนวนเต็มด้วย 0-padding ด้านซ้าย แต่ไม่ใช่สำหรับการแทนค่าไบนารี


คุณลองใช้แล้ว%016sหรือยัง?
Deniz Dogan

1
@ เดนิซใช่มันล้มเหลวด้วยException in thread "main" java.util.FormatFlagsConversionMismatchException: Conversion = s, Flags = 0
khachik

ดูสิ่งนี้: stackoverflow.com/a/15124135/1316649
fstang

คำตอบ:


198

ฉันคิดว่านี่เป็นวิธีแก้ปัญหาที่ไม่เหมาะสม แต่คุณสามารถทำได้

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

1
ใช่ฉันทำตอนนี้ แต่ฉันเชื่อว่าควรมีวิธีอื่น :) ขอบคุณ
khachik

หลังจากทำการค้นคว้าแล้วดูเหมือนว่าคุณจะไม่สามารถทำได้เพียงแค่ใช้ printf syntax .. ดังนั้นบางทีมันอาจจะไม่เลวร้ายนัก
Samuel Parsonage

@Daniel Negative number จะไม่มีช่องว่างดังนั้นจึงใช้ได้เช่นกัน
Eric Wang

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

17

ไม่มีการแปลงไบนารีใน java.util.Formatter ฉันขอแนะนำให้คุณใช้ String.replace เพื่อแทนที่อักขระช่องว่างด้วยศูนย์เช่นใน:

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

หรือใช้ตรรกะของคุณเองเพื่อแปลงจำนวนเต็มเพื่อแทน binary กับเพิ่มที่ไหนสักแห่ง padding ซ้ายไปตามเส้นที่กำหนดไว้ในนี้เพื่อให้ หรือถ้าคุณต้องการส่งตัวเลขไปจัดรูปแบบจริงๆคุณสามารถแปลงการแสดงไบนารีของคุณเป็น BigInteger จากนั้นจัดรูปแบบด้วยเลขศูนย์นำหน้า แต่สิ่งนี้มีค่าใช้จ่ายสูงมากที่รันไทม์เช่นใน:

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

ขอบคุณอันนี้ดีกว่าเนื่องจากหลีกเลี่ยงการล้นของตัวเลขจำนวนมาก (เช่น 2 ^ 30)
khachik

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

ขอขอบคุณ Will ที่ช่วยปรับปรุงคำตอบนี้เพื่อให้ทำงานได้โดยไม่ต้องวนซ้ำ อาจจะดูเงอะงะเล็กน้อย แต่ใช้ได้ผลโปรดปรับปรุงและแสดงความคิดเห็นกลับมาหากทำได้ ....

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
จะ - คุณยอดเยี่ยมไม่ดีใส่รหัสของฉันตอนนี้! ฉันไม่ชอบลูปเช่นกันขอบคุณ !!!
Tom Spencer

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 คุณสามารถใช้เมธอด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 );
    }
}

0

ฉันจะเขียนคลาส util ของตัวเองด้วยวิธีการดังต่อไปนี้

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 เบาะด้วย 0s หรือบิตที่สำคัญที่สุดถูกตัดทอน

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 ยอมรับตัวเลขและส่งคืนสตริง bynary เบาะและ / หรือจัดกลุ่ม

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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.