繁体   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