简体   繁体   English

无法将很长的二进制字符串解析为数字类型

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

Folks, I am trying to parse an extremely long binary String to its decimal equivalent, but its throwing the NumberFormatException .伙计们,我正在尝试将一个极长的二进制字符串解析为其十进制等价物,但它会抛出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);

But it's giving the below-mentioned Runtime error:但它给出了下面提到的运行时错误:

Exception in thread "main" java.lang.NumberFormatException: For input string: "1111[...]111" at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65) at java.lang.Long.parseLong(Long.java:592) at Check2.main(Check2.java:25)线程“主”java.lang.NumberFormatException 中的异常:对于输入字符串:“1111[...]111”在 java.lang.NumberFormatException.forInputString(NumberFormatException.java:65) 在 java.lang.Long.parseLong(Long .java:592) 在 Check2.main(Check2.java:25)

Tried using BigInteger,valueOf() methods too, but all efforts are going in vain.也尝试过使用 BigInteger,valueOf() 方法,但所有的努力都是徒劳的。

Please do let me know if there's any other way to achieve the desired result.如果有任何其他方法可以达到预期的效果,请告诉我。

The java long data type has a minimum value of -9,223,372,036,854,775,808 and a maximum value of 9,223,372,036,854,775,807 . java long 数据类型的最小值为-9,223,372,036,854,775,808 ,最大值为9,223,372,036,854,775,807 The number you have is much greater than the maximum limit allowed.您拥有的数量远远大于允许的最大限制。

You can use BigInteger for your String instead.您可以改用 BigInteger 作为您的 String 。

BigInteger result = new BigInteger(inputString, 2);

Both int and long have a maximum (and miminum) value, see the documentation for int and long accordingly. intlong都有一个最大值(和最小值),相应地参见intlong的文档。 The decimal representation of your binary string exceeds these limits.二进制字符串的十进制表示超过了这些限制。

You might use a BigDecimal instead to parse the String.您可以改用BigDecimal来解析字符串。 It provides a constructor accepting a String with the number and the radix to use.它提供了一个构造函数,接受带有数字和要使用的基数的字符串。 As your string is in binary format, you should pass the radix value of 2.由于您的字符串是二进制格式,因此您应该传递基数值 2。

BigInteger myValue = new BigInteger(s, 2);

An answer to the amendment:修改答案:

If you want to calculate with BigInteger you have to do all operations with BigInteger .如果要使用BigInteger BigInteger所有操作。 In the code fragment在代码片段中

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

you loose important information every time you call n.intValue() and every time you create a new BigInteger from an int (actually a long , the public BigInteger.valueOf() only accepts a long .)每次调用n.intValue()以及每次从int创建新的BigInteger时都会丢失重要信息(实际上是long ,公共BigInteger.valueOf()只接受long 。)

This is because an int can only store 32 bits, the value you start with however has 1969 bits.这是因为int只能存储 32 位,但您开始的值却有 1969 位。 n.intValue() extracts the lowest 32 bits, and after BigInteger.valueOf(n.intValue() - 1) / BigInteger.valueOf(n.intValue() / 2) all but those last 32 bits are lost. n.intValue()提取最低 32 位,在BigInteger.valueOf(n.intValue() - 1) / BigInteger.valueOf(n.intValue() / 2) ,除了最后 32 位之外的所有内容都将丢失。

The code works if you replace it with如果您将代码替换为

    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;

Why does your code lead to an endless loop?为什么你的代码会导致死循环?

The endless loop arises from the fact that the int value that has all bits set is -1.无限循环源于所有位设置的int值是 -1 的事实。

Your original loop produces these values:您的原始循环产生这些值:

  1. -1 is odd, therefore it subtracts 1 which gives -2 -1 是奇数,因此减去 1 得到 -2
  2. -2 is even, the value is divided by 2 which gives -1 -2 是偶数,该值除以 2 得到 -1

You can use this following method BigInteger() for integer conversion:您可以使用以下方法BigInteger()进行整数转换:

BigInteger bi = new BigInteger(inputstring, 2);

or you can use BigDecimal() like so:或者您可以像这样使用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