HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaMinor

Base-changing numbers in Java

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
changingnumbersjavabase

Problem

On a whim, I came up with this program to act as a helper class for base changing, if I require it in the future. It was made to support fixed-point and negative inputs, but they are basically a hack. I used conventional mathematics for the algorithm, and I welcome any appreciation or criticism that may come my way.

Note:

Forgive the snake_case naming of some local variables, I know it's not the standard for Java code, but it hurts my eyes less than camelCase.

Algorithmic and code improvements are welcome. This code is tested to work (I tested it against WolframAlpha). You might want to try out 12345 decimal to base 236. It should give 52 73 if the boolean parameter substituteNumerics is false. changeBase(String,int,int,boolean) is the correct entry point. I used the BlueJ IDE to get away without a main method, but you might need one.

Disclaimer:

Look ma, no comments! Please forgive me. I was in a bit of a rush, so there aren't comments, but I hope the code is pretty self-documenting. I might add some documentation comments later, so no need to worry about that.

``
public class BaseConverter{
protected static final String negativeBaseErrorMessage="Negative or zero base values are illegal - supplied bases were %d & %d.",

invalidInputNumberErrorMessage="The supplied number(%s) for base conversion is invalid.";

private static String lookup="0123456789ABCDEFGHIJKLMNOPQRSTWXYZabcdefghijklmnopqrstwxyz+/=,?!;:\"'^
~|\\@#$%&*_<>(){}";

private static void updateLookup(int to_base){
if(to_base>lookup.length()){
while(lookup.length()0){
tmp_number/=to_base;
++num_digits;
}
digits=new int[num_digits];
num_digits=0;
while(number>0){
digits[num_digits++]=(int)number%to_base;
number/=to_base;
}
return digits;
}

public static String changeBase(String inputNumber,int from_base,int to_base){
return changeBase(inputNum

Solution

Bugs

You've got a few bugs;

System.out.println(BaseConverter.changeBase(""+0x7FFF_FFFF_FFFF_FFFFL, 10, 16, true));


Will give IndexOutOfBoundsException: String index out of range: -1.

System.out.println(BaseConverter.changeBase(""+100000, 10, 70000, true));


Will give an infinite loop.

System.out.println(BaseConverter.changeBase("0", 10, 16, true));


Gives back empty string, (should be "0")

System.out.println(BaseConverter.changeBase("-0", 10, 16, true));


or

System.out.println(BaseConverter.changeBase("--1", 10, 16, true));


Gives back "-". ("-1") works normally. The "-0" case could return 0, or minus zero (that's a thing) if you felt like it. "--1" is obviously parse error.

System.out.println(BaseConverter.changeBase("1-1", 10, 16, false));


Gives back "5 11", which... I have no idea what it means. I guess you're treating this as "91", which ... well, I think this too is parse error.

I think that if you're in a rush, you should make use of automated helpers as much as possible. I get that if you don't have a lot of time, you can write code with 1 pass only, and that's it. It's not a sustainable practice, but if you need something done TODAY, so you can ship it, and then improve the code whilst the release is being "tested" by customers, well, that could be a viable business practice.

However, that (in my opinion) does not excuse you from using something like an auto-formatter and whitespace. Whitespace is free - provided you place all the braces, you can insert spaces and newlines where you like.

So lets haul it through a formatter.

public class BaseConverter {
    protected static final String negativeBaseErrorMessage = "Negative or zero base values are illegal - supplied bases were %d & %d.",

    invalidInputNumberErrorMessage="The supplied number(%s) for base conversion is invalid.";

    private static String lookup = "0123456789ABCDEFGHIJKLMNOPQRSTWXYZabcdefghijklmnopqrstwxyz+/=,?!;:\"'^`~|\\@#$%&*_<>(){}";

    private static void updateLookup(int to_base) {
        if (to_base > lookup.length()) {
            while (lookup.length()  0) {
            tmp_number /= to_base;
            ++num_digits;
        }
        digits = new int[num_digits];
        num_digits = 0;
        while (number > 0) {
            digits[num_digits++] = (int) number % to_base;
            number /= to_base;
        }
        return digits;
    }

    public static String changeBase(String inputNumber,int from_base,int to_base){
        return changeBase(inputNumber,from_base,to_base,true);
    }

    private static boolean isInvalidInputNumber(String inputNumber){
        return inputNumber.startsWith(".") ||
               inputNumber.endsWith(".") ||
               inputNumber.endsWith("-");
    }

    public static String changeBase(String inputNumber, int from_base, int to_base, boolean substituteNumerics) {
        boolean isNegative = false;
        if (inputNumber.startsWith("-")) {
            inputNumber = inputNumber.substring(1, inputNumber.length());
            isNegative = true;
        }
        if (isInvalidInputNumber(inputNumber)) {
            throw new IllegalArgumentException(String.format(invalidInputNumberErrorMessage, inputNumber));
        }
        if (from_base = 0; --i) {
                new_number += lookup.charAt(digits[i]);
            }
        } else {
            for (int i = digits.length - 1; i >= 0; --i) {
                new_number += digits[i] + " ";
            }
        }
        return (isNegative) ? "-" + new_number.trim() : new_number.trim();
    }
}


To me, it reads quite a lot better; and that's just by pressing auto-format button on the IDE.

Next, since we're assuming you have no time, just insert whitespace. Whenever you start doing a different thing, add a new blank line.

``
public class BaseConverter {
protected static final String negativeBaseErrorMessage = "Negative or zero base values are illegal - supplied bases were %d & %d.",

invalidInputNumberErrorMessage="The supplied number(%s) for base conversion is invalid.";

private static String lookup = "0123456789ABCDEFGHIJKLMNOPQRSTWXYZabcdefghijklmnopqrstwxyz+/=,?!;:\"'^
~|\\@#$%&*_<>(){}";

private static void updateLookup(int to_base) {
if (to_base > lookup.length()) {
while (lookup.length() 0) {
tmp_number /= to_base;
++num_digits;
}
digits = new int[num_digits];

num_digits = 0;
while (number > 0) {
digits[num_digits++] = (int) number % to_base;
number /= to_base;
}
return digits;
}

public static String changeBase(String inputNumber,int from_base,int to_base){
return changeBase(inputNumber,from_base,to_base,true);
}

private static boolean isInvalidInputNumber(String inputNumber){
return inputNumber.startsWith(".") ||
inputNumber.endsWith(".") ||
inpu

Code Snippets

System.out.println(BaseConverter.changeBase(""+0x7FFF_FFFF_FFFF_FFFFL, 10, 16, true));
System.out.println(BaseConverter.changeBase(""+100000, 10, 70000, true));
System.out.println(BaseConverter.changeBase("0", 10, 16, true));
System.out.println(BaseConverter.changeBase("-0", 10, 16, true));
System.out.println(BaseConverter.changeBase("--1", 10, 16, true));

Context

StackExchange Code Review Q#123080, answer score: 5

Revisions (0)

No revisions yet.