簡體   English   中英

無法將很長的二進制字符串解析為數字類型

[英]Unable to parse very long binary string to numeric type

伙計們,我正在嘗試將一個極長的二進制字符串解析為其十進制等價物,但它會拋出NumberFormatException

String s = "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" +
        "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" +
        "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" +
        "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" +
        "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" +
        "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" +
        "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" +
        "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" +
        "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" +
        "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" +
        "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" +
        "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" +
        "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" +
        "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" +
        "111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" +
        "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" +
        "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" +
        "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" +
        "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" +
        "1111111111111111"; //String length is 1969

long n = Long.parseLong(s, 2); //line no. 25

System.out.println(n);

但它給出了下面提到的運行時錯誤:

線程“主”java.lang.NumberFormatException 中的異常:對於輸入字符串:“1111[...]111”在 java.lang.NumberFormatException.forInputString(NumberFormatException.java:65) 在 java.lang.Long.parseLong(Long .java:592) 在 Check2.main(Check2.java:25)

也嘗試過使用 BigInteger,valueOf() 方法,但所有的努力都是徒勞的。

如果有任何其他方法可以達到預期的效果,請告訴我。

java long 數據類型的最小值為-9,223,372,036,854,775,808 ,最大值為9,223,372,036,854,775,807 您擁有的數量遠遠大於允許的最大限制。

您可以改用 BigInteger 作為您的 String 。

BigInteger result = new BigInteger(inputString, 2);

intlong都有一個最大值(和最小值),相應地參見intlong的文檔。 二進制字符串的十進制表示超過了這些限制。

您可以改用BigDecimal來解析字符串。 它提供了一個構造函數,接受帶有數字和要使用的基數的字符串。 由於您的字符串是二進制格式,因此您應該傳遞基數值 2。

BigInteger myValue = new BigInteger(s, 2);

修改答案:

如果要使用BigInteger BigInteger所有操作。 在代碼片段中

    BigInteger n = new BigInteger(s, 2);
    int count = 0;
    while (n.intValue() != 0) {
        if (n.intValue() % 2 == 0) {
            n = BigInteger.valueOf(n.intValue() / 2);
            count++;    
        } else {
            n = BigInteger.valueOf(n.intValue() - 1);
            count++;
        }

    }
    System.out.println(count);

每次調用n.intValue()以及每次從int創建新的BigInteger時都會丟失重要信息(實際上是long ,公共BigInteger.valueOf()只接受long 。)

這是因為int只能存儲 32 位,但您開始的值卻有 1969 位。 n.intValue()提取最低 32 位,在BigInteger.valueOf(n.intValue() - 1) / BigInteger.valueOf(n.intValue() / 2) ,除了最后 32 位之外的所有內容都將丟失。

如果您將代碼替換為

    BigInteger n = new BigInteger(s, 2);
    int count = 0;
    while (!n.equals(BigInteger.ZERO)) {
        count++;
        if (!n.testBit(0)) {
            n = n.divide(BigInteger.TWO);
        } else {
            n = n.subtract(BigInteger.ONE);
        }
    }
    return count;

為什么你的代碼會導致死循環?

無限循環源於所有位設置的int值是 -1 的事實。

您的原始循環產生這些值:

  1. -1 是奇數,因此減去 1 得到 -2
  2. -2 是偶數,該值除以 2 得到 -1

您可以使用以下方法BigInteger()進行整數轉換:

BigInteger bi = new BigInteger(inputstring, 2);

或者您可以像這樣使用BigDecimal()

BigDecimal bd1 = new BigDecimal(inputstring.charAt(0)=='1'?1:0);
BigDecimal two = new BigDecimal(2);
for (int i = 1; i<inputstring.length(); i++) {
    bd1 = bd1.multiply(two);
    bd1 = bd1.add(new BigDecimal(inputstring.charAt(i)=='1'?1:0));
}
System.out.println("Big decimal number is"+ bd1);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM