SumDoubleHex

Task

  • Input data are 64-bit floating point numbers
  • There are decimal and hexadecimal numbers in the input
  • Hexadecimal numbers has 0x prefix, for example 0xa.bp2 equals (10 + 11/16)·4 = 42.75
  • Input is case-insensitive
  • Class should be named SumDoubleHex

Solution

Let’s change our SumHex parseNumber method modification code. Currently it looks like this

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 change it a little bit

static double parseNumber(StringBuilder number) { // long -> double
    if (!number.isEmpty()) {
        String numberString = number.toString();
        if (
            numberString.startsWith("0x") || numberString.startsWith("0X")
        ) {
            if (/* there is a dot (.) inside a number */) {
                return Double.parseDouble(numberString);
            }
            return Long.parseLong(numberString.substring(2), 16);
        } else {
            return Double.parseDouble(numberString); // Integer.parseInt(...) -> Double.parseDouble(...)
        }
    } else {
        return 0;
    }
}

Note

Notice, that we pass only one argument into Double.parseDouble() method, because parseDouble’s parser recognizes 0x pattern itself.

Aside of obvious analogical changes, we need to somehow understand if the number contains a dot (.). We can do so by using String.contains(CharSequence s). Which checks if the s is present in the string.

Note

In the defenition of the contains method there is CharSequence data type. String data type fits into CharSequence data type as it is declared in the documentation.

So our parseNumber method code will look like this

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

And after changing sum’s data type to double in main method we get

// SumDoubleHex.java

public class SumDoubleHex {

    public static void main(String[] args) {
        double 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 double parseNumber(StringBuilder number) {
        if (!number.isEmpty()) {
            String numberString = number.toString();
            if (
                numberString.startsWith("0x") || numberString.startsWith("0X")
            ) {
                if (numberString.contains(".")) {
                    return Double.parseDouble(numberString);
                }
                return Long.parseLong(numberString.substring(2), 16);
            } else {
                return Double.parseDouble(numberString);
            }
        } else {
            return 0;
        }
    }
}

This code will work and pass all the tests!