# SumLongOctal – CodeJava
Task The input data is in 64 bit decimal numbers Octal numbers has suffix "o" Class should be named SumLongOctal Solution We need to change our parseNumber method yet again. Let’s take a look at it from SumHex modification static long parseNumber(StringBuilder number) { if (!number.isEmpty()) { String numberString = number.toString(); if ( numberString.startsWith("0x") || numberString.startsWith("0X") ) { return Long.parseLong(numberString.substring(2), 16); } else { return Integer.parseInt(numberString); } } else { return 0; } } Let’s adapt our new logic on a concept level

`CTRL K`

# SumLongOctal

# Task

- The input data is in 64 bit decimal numbers
- Octal numbers has suffix `"o"`
- Class should be named `SumLongOctal`

## Solution

We need to change our `parseNumber` method yet again. Let’s take a look at it from `SumHex` modification

    static long parseNumber(StringBuilder number) {
        if (!number.isEmpty()) {
            String numberString = number.toString();
            if (
                numberString.startsWith("0x") || numberString.startsWith("0X")
            ) {
                return Long.parseLong(numberString.substring(2), 16);
            } else {
                return Integer.parseInt(numberString);
            }
        } else {
            return 0;
        }
    }

Let’s adapt our new logic on a concept level

    static long parseNumber(StringBuilder number) {
        if (!number.isEmpty()) {
            String numberString = number.toString();
            int numberStringLength = numberString.length();
            if (
                /* number is octal */
            ) {
                return Long.parseLong(numberString.substring(0, numberStringLength - 1), 8); // 16 -> 8
            } else {
                return Integer.parseInt(numberString);
            }
        } else {
            return 0;
        }
    }

As you can see is that we need to only change method of checking if the number is octal. It’s actually fairly easy. With hexadecimal numbers we checked if the number started with `"0x"` or `"0X"`. Now we need to check if the number ends with `"o"` or `"O"`. To do that we will use `String.endsWith(String suffix)` method that checks if the string ends with `prefix`.

And also we change `16` to `8` here

    return Long.parseLong(numberString.substring(0, numberStringLength - 1), 8);

Because we are converting from octal, not hexadecimal anymore.

Note

Note, that we alse changed how we crop out the last character of our `numberString`. First, we introduced new variable `numberStringLength`, that represents a length of `numberString` (or number of characters in the string). Then, we take a substring using `substring(0, numberStringLength - 1)`. We start at first index (`0`) and go all the way to the second from the end of the string. We use `- 1` and not `- 2` because last index is exclusive (meaning it doesn’t count).

So the code for `parseNumber` method will be

    static long parseNumber(StringBuilder number) {
        if (!number.isEmpty()) {
            String numberString = number.toString();
            int numberStringLength = numberString.length();
            if (
                numberString.endsWith("o") || numberString.endsWith("O")
            ) {
                return Long.parseLong(numberString.substring(0, numberStringLength - 1), 8); // 16 -> 8
            } else {
                return Integer.parseInt(numberString);
            }
        } else {
            return 0;
        }
    }

So the solution would be

    // SumLongOctal.java

    public class SumLongOctal {

        public static void main(String[] args) {
            int sum = 0;
            for (String argument : args) {
                StringBuilder number = new StringBuilder();
                for (char c : argument.toCharArray()) {
                    if (!Character.isWhitespace(c)) {
                        number.append(c);
                    } else {
                        sum += parseNumber(number);
                        number = new StringBuilder();
                    }
                }

                sum += parseNumber(number);
            }

            System.out.println(sum);
        }

        static long parseNumber(StringBuilder number) {
            if (!number.isEmpty()) {
                String numberString = number.toString();
                int numberStringLength = numberString.length();
                if (numberString.endsWith("o") || numberString.endsWith("O")) {
                    return Long.parseLong(numberString.substring(0, numberStringLength - ), 8);
                } else {
                    return Integer.parseInt(numberString);
                }
            } else {
                return 0;
            }
        }
    }

Let’s try to test it with test like this

    $ java SumLongOctal " +12345678901234567 "
    Exception in thread "main" java.lang.NumberFormatException: For input string: "+12345678901234567"
            at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:67)
            at java.base/java.lang.Integer.parseInt(Integer.java:662)
            at java.base/java.lang.Integer.parseInt(Integer.java:778)
            at sum.SumLongOctal.parseNumber(SumLongOctal.java:32)
            at sum.SumLongOctal.main(SumLongOctal.java:15)

As you can see we got a `NumberFormatException`. Here it’s not an octal number and it doesn’t fit into `int` data type, so let’s change `int` to `long` which is bigger.

    // SumLongOctal.java

    public class SumLongOctal {

        public static void main(String[] args) {
            long sum = 0; // int -> long
            for (String argument : args) {
                StringBuilder number = new StringBuilder();
                for (char c : argument.toCharArray()) {
                    if (!Character.isWhitespace(c)) {
                        number.append(c);
                    } else {
                        sum += parseNumber(number);
                        number = new StringBuilder();
                    }
                }

                sum += parseNumber(number);
            }

            System.out.println(sum);
        }

        static long parseNumber(StringBuilder number) {
            if (!number.isEmpty()) {
                String numberString = number.toString();
                int numberStringLength = numberString.length();
                if (numberString.endsWith("o") || numberString.endsWith("O")) {
                    return Long.parseLong(numberString.substring(0, numberStringLength - 1), 8);
                } else {
                    return Long.parseLong(numberString); // Integer.parseInt(...) -> Long.parseLong(...)
                }
            } else {
                return 0;
            }
        }
    }

Note

Notice we changed data type of `sum` to `long` in order to store 64 bit numbers.

Let’s test some more

    $ java SumLongOctal.java "1777777777777777777776o"
    Exception in thread "main" java.lang.NumberFormatException: For input string: "1777777777777777777776" under radix 8
    	at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:67)
    	at java.base/java.lang.Long.parseLong(Long.java:709)
    	at SumLongOctal.parseNumber(SumLongOctal.java:29)
    	at SumLongOctal.main(SumLongOctal.java:18)

We can see that this number doesn’t fit into `long` data type. So we need to use something called `BigInteger` and more specifically we will be using its `BigInteger.longValue()` method.

First we need to import it using

    import java.math.BigInteger;

and then we will replace

    return Long.parseLong(numberString.substring(0, numberStringLength - 1), 8);

with

    return new BigInteger(number.substring(0, numberStringLength - 1), 8).longValue();

So the final code would be

    // SumLongOctal.java

    import java.math.BigInteger;

    public class SumLongOctal {

        public static void main(String[] args) {
            long sum = 0;
            for (String argument : args) {
                StringBuilder number = new StringBuilder();
                for (char c : argument.toCharArray()) {
                    if (!Character.isWhitespace(c)) {
                        number.append(c);
                    } else {
                        sum += parseNumber(number);
                        number = new StringBuilder();
                    }
                }

                sum += parseNumber(number);
            }

            System.out.println(sum);
        }

        static long parseNumber(StringBuilder number) {
            if (!number.isEmpty()) {
                String numberString = number.toString();
                int numberStringLength = numberString.length();
                if (numberString.endsWith("o") || numberString.endsWith("O")) {
                    return new BigInteger(
                        number.substring(0, numberStringLength - 1),
                        8
                    ).longValue();
                } else {
                    return Long.parseLong(numberString);
                }
            } else {
                return 0;
            }
        }
    }