Files
codejava.tech/content/courses/prog-intro/homeworks/sum/SumLongOctal/_index.md
me 38158e5319
All checks were successful
Deploy / deploy (push) Successful in 14s
update
2026-04-14 15:26:42 +03:00

8.2 KiB

title, weight
title weight
SumLongOctal 6

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