1
\$\begingroup\$

I have written a program for a user-defined binary data type in JAVA. It has

static methods for purposeful usage

methods for binary arithmetic

methods for bitwise operations

It's working as intended, but I feel the code is a bit too verbose. Any suggestions on how to shorten it? Also, can I make it faster? Beyond that, were any noob errors of exception cases meant. P.S. You will see that I defined my own methods for bitwise operations instead of the standard JAVA bitwise operators. I did it just to get the hang of programming.

import java.lang.*;
import java.util.*;
class Binary
{
    public final int binary;
    public final int decimal;
    public static int fromBintoDec(int b)
    {
        int fv, d = 0, p2 = 1;
        while
        (b != 0)
        {
            fv = (b % 10);
            d += (fv * p2);
            b /= 10;
            p2 *= 2;
        }
        return d;
    }
    public static int fromDectoBin(int d)
    {
        String bs = "", sd; int mv;
        while
        (d != 0)
        {
            mv = (d % 2);
            sd = Integer.toString(mv);
            bs = (sd + bs);
            d /= 2;
        }
        int b = Integer.parseInt(bs);
        return b;
    }
    public static int howManyDigits(int x)
    {
       int nd = 0;
       while
       (x != 0)
       {
           x /= 10;
           nd += 1;
       }
       return nd;
    }
    public static String[] readyBitwise(int x, int y)
    {
        int ndg = howManyDigits(Math.max(x, y));
        int ndl = howManyDigits(Math.min(x, y));
        int nzd = ndg - ndl;
        String zd = "";
        String xs = Integer.toString(x);
        String ys = Integer.toString(y);
        for
        (int i = 1; i <= nzd; i++) 
        {
            zd += '0';
        }
        if 
        (x > y)
        {
            ys = zd + ys;
        }
        else
        {
            xs = zd + xs;
        }
        String[] fa = new String[2];
        fa[0] = xs;
        fa[1] = ys;
        return fa;
    }
    public static int[] toBitArray(String x)
    {
        int l = x.length();
        int[] xba = new int[l];
        for 
        (int i = 0; i < l; i++)
        {
            xba[i] = (Integer.parseInt((Character.toString(x.charAt(i)))));
        }
        return xba;
    }
    public static int toBinary(int[] xa)
    {
        int s = xa.length;
        String xsb = ""; int xb;
        for 
        (int i = 0; i < s; i++)
        {
            String d = Integer.toString(xa[i]);
            xsb += d;
        }
        xb = Integer.parseInt(xsb);
        return xb;
    }
    public Binary(int bi)
    {
        binary = bi;
        decimal = (fromBintoDec(bi));
    }
    public String toString()
    {
        String bsv = Integer.toString(binary);
        return bsv;
    }
    public int toDecimal()
    {
        Binary x = this;
        return (x.decimal);
    }
    public Binary plus(Binary y)
    {
        Binary x = this;
        int ds = x.decimal + y.decimal;
        int bs = fromDectoBin(ds);
        Binary s = new Binary(bs);
        return s;
    }
    public Binary minus(Binary y)
    {
        Binary x = this;
        int dd = Math.abs((x.decimal - y.decimal));
        int bd = fromDectoBin(dd);
        Binary d = new Binary(bd);
        return d;
    }
    public Binary times(Binary y)
    {
        Binary x = this;
        int dp = x.decimal * y.decimal;
        int bp = fromDectoBin(dp);
        Binary p = new Binary(bp);
        return p;
    }
    public Binary by(Binary y)
    {
        Binary x = this;
        int dq = x.decimal / y.decimal;
        int bq = fromDectoBin(dq);
        Binary q = new Binary(bq);
        return q;
    }
    public Binary mod(Binary y)
    {
        Binary x = this;
        int dq = x.decimal % y.decimal;
        int bq = fromDectoBin(dq);
        Binary q = new Binary(bq);
        return q;
    }
    public Binary or(Binary y)
    {
        Binary x = this;
        int xb = x.binary;
        int yb = y.binary;
        String xsb = (readyBitwise(xb, yb))[0];
        String ysb = (readyBitwise(xb, yb))[1];
        int[] xba = toBitArray(xsb);
        int[] yba = toBitArray(ysb);
        int s = xba.length;
        int[] fa = new int[s];
        int xd, yd;
        for 
        (int i = 0; i < s; i++)
        {
            xd = xba[i];
            yd = yba[i];
            if
            ((xd == 0) && (yd == 0))
            {
                fa[i] = 0;
            }
            else if
            ((xd == 1) && (yd == 0))
            {
                fa[i] = 1;
            }
            else if
            ((xd == 0) && (yd == 1))
            {
                fa[i] = 1;
            }
            else if
            ((xd == 1) && (yd == 1))
            {
                fa[i] = 1;
            }
            else
            {
                i += 0;
            }
        }
        int ob = toBinary(fa);
        return (new Binary(ob));
    }
    public Binary and(Binary y)
    {
        Binary x = this;
        int xb = x.binary;
        int yb = y.binary;
        String xsb = (readyBitwise(xb, yb))[0];
        String ysb = (readyBitwise(xb, yb))[1];
        int[] xba = toBitArray(xsb);
        int[] yba = toBitArray(ysb);
        int s = xba.length;
        int[] fa = new int[s];
        int xd, yd;
        for 
        (int i = 0; i < s; i++)
        {
            xd = xba[i];
            yd = yba[i];
            if
            ((xd == 0) && (yd == 0))
            {
                fa[i] = 0;
            }
            else if
            ((xd == 1) && (yd == 0))
            {
                fa[i] = 0;
            }
            else if
            ((xd == 0) && (yd == 1))
            {
                fa[i] = 0;
            }
            else if
            ((xd == 1) && (yd == 1))
            {
                fa[i] = 1;
            }
            else
            {
                i += 0;
            }
        }
        int ab = toBinary(fa);
        return (new Binary(ab));
    }
    public Binary xor(Binary y)
    {
        Binary x = this;
        int xb = x.binary;
        int yb = y.binary;
        String xsb = (readyBitwise(xb, yb))[0];
        String ysb = (readyBitwise(xb, yb))[1];
        int[] xba = toBitArray(xsb);
        int[] yba = toBitArray(ysb);
        int s = xba.length;
        int[] fa = new int[s];
        int xd, yd;
        for 
        (int i = 0; i < s; i++)
        {
            xd = xba[i];
            yd = yba[i];
            if
            ((xd == 0) && (yd == 0))
            {
                fa[i] = 0;
            }
            else if
            ((xd == 1) && (yd == 0))
            {
                fa[i] = 1;
            }
            else if
            ((xd == 0) && (yd == 1))
            {
                fa[i] = 1;
            }
            else if
            ((xd == 1) && (yd == 1))
            {
                fa[i] = 0;
            }
            else
            {
                i += 0;
            }
        }
        xb = toBinary(fa);
        return (new Binary(xb));
    }
    public Binary not()
    {
        Binary x = this;
        String xb = Integer.toString(x.binary);
        int[] xba = toBitArray(xb);
        int s = xba.length;
        int[] fa = new int[s];
        int xd;
        for 
        (int i = 0; i < s; i++)
        {
            xd = xba[i];
            if
            ((xd == 0))
            {
                fa[i] = 1;
            }
            else if
            ((xd == 1))
            {
                fa[i] = 0;
            }
            else
            {
                i += 0;
            }
        }
        int xbi = toBinary(fa);
        return (new Binary(xbi));
    }
    public static void Test()
    {
        Binary a = new Binary(1100);
        Binary b = new Binary(101);
        System.out.println(a.plus(b));
        System.out.println(a.minus(b));
        System.out.println(a.times(b));
        System.out.println(a.by(b));
        System.out.println(a.or(b));
        System.out.println(a.and(b));
        System.out.println(a.xor(b));
        System.out.println(b.not());
    }
}
\$\endgroup\$
3
  • 1
    \$\begingroup\$ I'm confused why the binary conversion static methods map from int to int. That's very much not what I'd expect... \$\endgroup\$
    – Vogel612
    Dec 17 '19 at 8:02
  • \$\begingroup\$ @Vogel612 the public static int fromBintoDec(int b) I have used for an internal operation (conversion of the binary value entered to decimal for usage in arithmetic operations. I am defining a new data type so I cannot return a Binary and work with it without defining my work methods. \$\endgroup\$ Dec 17 '19 at 15:12
  • \$\begingroup\$ @RileyJones Int as a datatype for both decimal and binary is odd. An int is already binary in the internal representation. It becomes decimal only when printed out to human readable form. The printout could also be hexadecimal or octal. Thus we'd be expecting to see strings as output data types for the conversions. \$\endgroup\$ Dec 19 '19 at 8:32
1
\$\begingroup\$

Naming

Finding good names is the hardest part in programming. So always take your time to think carefully of your identifier names. Single letter and abbreviated names

Avoid single letter and abbreviated names.

As mentionned by @tinstaafl you don't gain anything by using one or two character names. Although this abbreviation makes sense to you (now) anyone reading your code being not familiar with the problem has a hard time finding out what this means.

If you do this to save typing work: remember that you way more often read your code than actually typing something. Also for Java you have good IDE support with code completion so that you most likely type a long identifier only once and later on select it from the IDEs code completion proposals.

Don't surprise your readers

A name of a method should clearly state what the method does. A bad example in your code is howManyDigits(). It counts the digits og the decimal representation which is somewhat surprising in a class that is called Binary.

The name of the class itself is also misleading. It claims to be a class being a binary representation of a number but is is a collection of service methods for binary numbers.

Naming Conventions

Please read (and follow) the Java Naming Conventions.

Your use of the CamelCase naming scheme is not consequent. The methods fromBintoDec() and its companion fromDectoBin() should better be named fromBinToDec() and fromDecToBin()

But the naming conventions do not only apply to the casing of the identifiers. It also applies to how names are "constructed". E.g. method names should start with a verb. the worst example in your code is howManyDigits(). It should better be countDigits() and along with the previous point countDecimalDigits().

Similar is true for fromBintoDec() and its companion fromDectoBin(). If the class Binary was really a Number type this method names might be OK since we have similar named methods in other Number implementations. But since this is just a collection of service methods the methods should have more explicit names like convertDecimalToBinary() and convertBinaryToDecimal().

static is evil

Last but not least: it is an urban legend that utility classes must have only static methods. In the absesnce of a better name we accidently called such static only classes "utility class" to distinguish them from "normal classes". In java there is no real benefit for such static only classes except that you save to type the new key word and a pair of braces. static access increases coupling for no real reason and effectively prevents polymorphism.

\$\endgroup\$
2
  • \$\begingroup\$ in my howManyDigits() method, I counted the digits with the decimal representation because I am storing the binary number as an integer. \$\endgroup\$ Dec 19 '19 at 15:19
  • \$\begingroup\$ Thanks for the huge help. I will change the code so that the binary representation is stored as a string. \$\endgroup\$ Dec 19 '19 at 15:20
3
\$\begingroup\$

A few things to start with:

If your methods are only meant to be used internally then they should be private not public.

For your methods where the names don't really match what the methods are doing, some comments should be used. You may remember what they are doing now but will you a year from now

The same goes for your variable names. You don't gain anything by using one or two character names.

I don't see anywhere that you're storing the binary representation of the integer used in the constructor. Even the ToString method only returns the integer not the binary representation of the integer. To me this is not what one would expect from a class called Binary.

* EDIT *

After looking at your code further, it looks like you're using an integer with only the digits 0 and 1 to store the binary. This is very anti-intuitive, especially since there aren't any comments to mention this, or any code to recognize malformed input.

\$\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.