1

Folks, I am trying to parse an extremely long binary String to its decimal equivalent, but its throwing the 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)

Tried using BigInteger,valueOf() methods too, but all efforts are going in vain.

Please do let me know if there's any other way to achieve the desired result.

6
  • 5
    new BigInteger(s, 2). Yields (see next comment). Commented Jun 5, 2022 at 7:19
  • 53464001755893906775528248454336169363107425257968492828199767359800928337144214373857690315530927382337207190645274835333559613715068219761640362263035643165525975239142905921064680045582374963643460995547234194717190909966075962384844676610299550914627032614388688844137186932202108041167335688122703079760153269853656415642415864769329344341966685140705203039900691169557165416067597126477057059908847603479119212425789693304525707922807514318982553404710298367103076439159769583102353828594382192359948728971055716056539111966002757898026740077828348230307702348019388863266429609508339711 Commented Jun 5, 2022 at 7:19
  • This WORKED!! One more final help if you could pls provide - I am trying to perform the below-mentioned operations but it's taking forever to compute it. Basically trying to compute the number of operations required to reduce that number n to 0, wherein the operations are :- Subract 1 if it's odd, divide by 2 if even, and finally return the count. That's it!! Please see the edited question for the complete code Commented Jun 5, 2022 at 7:43
  • 2
    To generalize my coment from before: n.bitLength() gives you the total number of bits from the first one bit. Subtract one to get the number of times you need to divide by 2. n.bitCount() gives you the number of one bits, so the number of times you need to subtract 1. So add those two numbers for a count of operations. Commented Jun 5, 2022 at 7:55
  • 1
    Sure, it was a pleasure, not least seeing that it actually helped. I regularly look through all of the methods of a class that i am using, no matter if I think I need one or not, but I tend to learn a lot from doing it. Documentation of BigInteger. Commented Jun 5, 2022 at 9:37

4 Answers 4

2

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. The number you have is much greater than the maximum limit allowed.

You can use BigInteger for your String instead.

BigInteger result = new BigInteger(inputString, 2);
Sign up to request clarification or add additional context in comments.

6 Comments

Absolutely right! But, is there STILL a way to perform the desired task and achieve the desired outcome?
what is the desired task? If you just add the string to new BigInteger, you can get the desired result
If somebody needs to work with floats, there is the BigDecimal ... same logic.
The author @AshishRamtri meantions that the string provided is in binary format (radix=2). The constructor of BigDecimal used in your answer uses decimal (radix=10) however, Thus my edit you rolled back ...
Oh, I realize my mistake now
|
2

Both int and long have a maximum (and miminum) value, see the documentation for int and long accordingly. The decimal representation of your binary string exceeds these limits.

You might use a BigDecimal instead to parse the String. 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.

BigInteger myValue = new BigInteger(s, 2);

4 Comments

This WORKED!! Thanks! One more final help if you could pls provide - I am trying to perform the below-mentioned operations but it's taking forever to compute it. Basically trying to compute the number of operations required to reduce that number n to 0, wherein the operations are :- Subract 1 if it's odd, divide by 2 if even, and finally return the count. That's it!! Please see the edited question for the complete code
I'm glad I could help. @AshishRamtri as this has nothing to do with your original problem (the parsing error) I would recommend asking a new question focussed on the new problem instead. And change this question back to the original core instead.
I'd have loved to change it back to the original core, but some others have already commented based on the latest post update. BUT, I'll definitely make sure that going forward I follow your advice on the same. Thanks again! : )
No worries. I still would consider adding this as a separate question so that others with the same or a similar problem might find a solution easier. Maybe notify Ole V. V. about it so that they may add their answer accordingly.
1

An answer to the amendment:

If you want to calculate with BigInteger you have to do all operations with 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.)

This is because an int can only store 32 bits, the value you start with however has 1969 bits. 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.

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.

Your original loop produces these values:

  1. -1 is odd, therefore it subtracts 1 which gives -2
  2. -2 is even, the value is divided by 2 which gives -1

2 Comments

I was able to run your counting in less than 0.01 seconds on my old computer. Which is a pretty vast difference from “forever”. (Not upvoting since the question no longer asks about this.)
Thanks for providing a detailed explanation as to why my code didn't work and went into an endless loop. Also, I was able to implement something along the lines of your solution, except for the BigInteger.TWO - which I guess is not supported in Java 8 but from Java 9 onwards, and I am currently on Java8. Nevertheless, appreciate your help on the same. - @Thomas Kläger
1

You can use this following method BigInteger() for integer conversion:

BigInteger bi = new BigInteger(inputstring, 2);

or you can use BigDecimal() like so:

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

2 Comments

Same answer already added for the question
Thanks but you can use BigDecimal(). Which I mention second example.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.