11
\$\begingroup\$

I'm a beginner in Java and I tried to create a program that will perform basic arithmetic operations on binary numbers.

BinaryOperations class:

package binaryoperations;

import java.io.IOException;
import static java.lang.System.in;
import java.util.Scanner;

public class BinaryOperations {
    public static void main(String[] args) throws IOException {
        try(Scanner in = new Scanner(System.in)) {
            Operations operation = new Operations();
            System.out.print("First Binary:  ");
                String binOne = in.next();
            System.out.print("Second Binary: ");
                String binTwo = in.next();
            System.out.println("Sum:        " + operation.GetBinarySum(binOne, binTwo));
            System.out.println("Difference: " + operation.GetBinaryDiff(binOne, binTwo));
            System.out.println("Product:    " + operation.GetBinaryProd(binOne, binTwo));
            System.out.println("Quotient:   " + operation.GetBinaryQuotient(binOne, binTwo));
        } catch(NumberFormatException e) {
            System.out.println("Looks like you entered a non Binary digit.");
        } finally {
                in.close();
            }
        }
    }

Operations class:

package binaryoperations;

public class Operations {

    public String GetBinarySum(String a, String b){
        int left = Integer.parseInt(a, 2);
        int right = Integer.parseInt(b, 2);
        int sum = left + right;
        return Integer.toBinaryString(sum);
    }

    public String GetBinaryDiff(String a, String b){
        int left = Integer.parseInt(a, 2);
        int right = Integer.parseInt(b, 2);
        int diff = left - right;
        return Integer.toBinaryString(diff);
    }

    public String GetBinaryProd(String a, String b){
        int left = Integer.parseInt(a, 2);
        int right = Integer.parseInt(b, 2);
        int prod = left * right;
        return Integer.toBinaryString(prod);
    }

    public String GetBinaryQuotient(String a, String b){
        int left = Integer.parseInt(a, 2);
        int right = Integer.parseInt(b, 2);
        int quotient = left / right;
        return Integer.toBinaryString(quotient);
    }
}

To get the result I used Integer.parseInt(String, radix 2) because it's binary.

Did I do something wrong? Is it okay to use radix then converting the result to Binary to get the answer? Or is it better to apply the large amount of code to get the answer? Any suggestions is appreciated.

\$\endgroup\$
  • \$\begingroup\$ @Mast read again, it's a BinaryOperations "Main" class, and a Operations "Calculator" class. \$\endgroup\$ – Pimgd Apr 24 '15 at 9:41
  • \$\begingroup\$ @Pimgd I must have misread. \$\endgroup\$ – Mast Apr 24 '15 at 9:44
13
\$\begingroup\$

Style

I'm sorry for making it personal here, camelCase, but the preferred styling for function names is that they're, well, camelCased. (Apologies for the bad pun). So not GetBinarySum, but getBinarySum.

Removing the Operations class

I think your approach for implementation of Operations is flawed.

You're taking two Strings, converting them to numbers, performing a simple operation and converting it to String again.

This by itself is not a problem, but...

        System.out.println("Sum:        " + operation.GetBinarySum(binOne, binTwo));
        System.out.println("Difference: " + operation.GetBinaryDiff(binOne, binTwo));
        System.out.println("Product:    " + operation.GetBinaryProd(binOne, binTwo));
        System.out.println("Quotient:   " + operation.GetBinaryQuotient(binOne, binTwo));

Here you're doing the following:

read two Strings
convert to ints
sum
convert to binary string
print
convert to ints
diff
convert to binary string
print
convert to ints
prod
convert to binary string
print
convert to ints
quotient
convert to binary string
print

If you instead converted the Strings directly after reading, you could do input validation per input ("hey, you entered a 2 for your second binary number!"), and you'd save on doing all this conversion. You'd convert once, do the math, convert back 4 times (4 different results), and done.

Something like this:

read two Strings
convert to ints
sum
convert to binary string
print
diff
convert to binary string
print
prod
convert to binary string
print
quotient
convert to binary string
print

Here's an implementation without error handling:

        int left = Integer.parseInt(binOne, 2);
        int right = Integer.parseInt(binTwo, 2);

        System.out.println("Sum:        " + Integer.toBinaryString(left + right));
        System.out.println("Difference: " + Integer.toBinaryString(left - right));
        System.out.println("Product:    " + Integer.toBinaryString(left * right));
        System.out.println("Quotient:   " + Integer.toBinaryString(left / right));

And poof! The entire Operations class is gone.

Why have an Operations class

Now, if this were some super advanced calculator which has to do more than just do basic math, it'd help to have the Operations class.

For example, "count all the positive bits in the number" or "detect if this binary number is a square". Then you'd be better served by an operations class that takes int(s) and returns int or boolean. You can later convert this to a String. If you write the implementations like that, your BinaryOperations (which needs a better name) class would be responsible for handling input and output (Like the screens and the buttons of a calculator) and the Operations class would be responsible for doing the actual calculating.

Consider why the Java creators made a java.lang.Math class that takes integers, not Strings and it should be easier to understand how to split responsibilities.

About use of Integer.parseInt with radix

Use built-ins when you can.

Built-ins apply to a larger populace than your custom code. Built-ins have been tested by the people who create the Java language. And above all, built-ins don't require you to implement them yourself.

When the resulting code is written faster, has a greater chance of being correct and uses components people are familiar with, why wouldn't you use built-in functions?

Oh, and in case you forgot what they do, they come with documentation too. So it's easy to remind yourself of how the built-ins work. Custom functions require you to re-read the code if you've forgotten and there's no documentation.

\$\endgroup\$
6
\$\begingroup\$

Pimgd provided a good point about your Operations class, but if you wanted to keep it I would suggest making these changes to it as it's a "utility class"

  • Make it a final class
  • Add a private constructor (this removes the default constructor)
  • Make all the methods static

Example:

public final class Operations {

    private Operations() {
        // Intentionally empty
    }

    public static String GetBinarySum(String a, String b){
        // Your code here...
    }

    // etc.
}

And then in your main method, remove this Operations operation = new Operations(); and call the methods straight from Operations like Operations.GetBinarySum(...);

But why?

It's simply a collection of methods, not really an object in the traditional sense. If you made two Operations objects they'd be exactly the same, there's no stored values in them. Because of this it is what people call a "utility class".

The conventions for these are to make all the methods static (As a side note, usually the indicator that your class is a utility class is if all methods/fields are static) and make the class final so nothing can extend it and add a private, no argument constructor to prevent the compiler from making the default one so nothing can instantiate it.


Relevant quote from the link on default constructors:

The compiler automatically provides a no-argument, default constructor for any class without constructors.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.