I did research about binary counting, and wanted to make an application in Java that converts a string to binary code:

 /**
 * This class converts strings by looping through the characters, gets the
 * decimal code for each, then divides the number by 2 untill the quotient is 0
 * 
 * @author Mr Pro Pop
 *
 */
public class Binary {

    /**
     * This function takes a string as a parameter and converts it to binary code
     * 
     * @param string The string to be converted to binary code
     * @return The binary code of the input string
     */

    public String getBinaryCode(String string) {

        if (string.length() == 0)
            return null;

        char[] characters = string.toCharArray();
        StringBuilder result = new StringBuilder();
        int number = 0;

        for (int i = 0; i < characters.length; i++) {
            number = getDecimal(characters[i]);
            for (int j = 0; j < 8; j++) {
                if (number % 2 == 0) {
                    result.insert(0, 0);
                } else {
                    result.insert(0, 1);
                }
                number = (int) (number / 2);
            }
            result.append(" ");
        }
        return result.toString();
    }

    /**
     * This function gets the decimal number of a character
     * 
     * @param character The character that we want the decimal value of
     * @return The decimal of the character from the ascii table
     */
    public int getDecimal(char character) {
        for (int i = 0; i <= 255; i++) {
            if (character == (char) i) {
                return i;
            }
        }
        return -1;
    }

    public static void main(String[] args) {
        String string = "a";
        Binary b = new Binary();
        System.out.println("Binary code for" + string + " is " + b.getBinaryCode(string));
    }

}

Output:

Binary code for a is 01100001

Here it works well, however, spacing doesn't work. I do acknowledge that I could simply code this in a different easier method by Integer.toBinaryString(character[i]) but tried doing it my way to learn and especially with this method.

Any improvements I could do or anything to pay attention for?

  • 1
    Please do not update the code in your question to incorporate feedback from answers, doing so goes against the Question + Answer style of Code Review. This is not a forum where you should keep the most updated version in your question. Please see what you may and may not do after receiving answers. In this case I would recommend that you add a self-answer with the updated code and the list of changes you made. You can find your previous changes in the edit history – Simon Forsberg Sep 23 at 21:39
  • @SimonForsberg Thanks I guess, but just wanted my final code to be re-viewed back to be sure it is correct, and that is why I kept the most updated version of the code. – Mr Pro Pop Sep 23 at 21:47
  • 2
    @MrProPop, it is more than okay to post another question with your new working code. – Malachi Sep 24 at 3:33
up vote 6 down vote accepted

I would change

public int getDecimal(char character)
{
    for (int i = 0; i <= 255; i++)
    {
         if (character == (char) i)
         {
              return i;
          }
     }
     return -1;
}

To just

public int getDecimal(char character)
{
     if(character<0||character>255)
          return -1;
     return character;
}

, As char is a number, too.

Also try using >> operator to get nth binary digit, which means division by 2.

number = (int) (number / 2);

To

number = number >>1;

I don't know if it would be faster in java, but it works faster in old computer's assembly program(Division was expensive than just shifting)

If you use assembly you can access carry flags and optimize it.

For more information about it, refer here.

Provided that al holds the target number and bx holds the target string address, and cx holds 8,

L1:                  ; This is the loop
mov dl, '0'      ; Ascii character zero
shl al, 1          ; Upper bit now in carry flag
adc dl, 0        ; Adds carry flag - 0 or 1
mov [bx], dl   ; Save digit to current position
inc bx             ; Next position
loop L1          ; Counts down cx
mov [bx], 0    ; Zero terminate (might need to use register)
  • Oh thanks!!! Changed the getDecimal method. One thing I didn't quite get is the >> operator, what do you mean? And also one more question please, why is my append(" ") putting space after the result? So say I pass "sup" it would give the binary code of each character not separated and at the end put 3 spaces. – Mr Pro Pop Sep 23 at 1:17
  • @MrProPop Maybe because of the insert method? – KYHSGeekCode Sep 23 at 1:20
  • Aha, thanks for the tip. Btw, yes your right, the problem is because of insert, but if I don't use insert, then I would get the binary code the other way round, like flipped. Do I run a for loop to order them back? Just thought of it would consume more resources considering a large string looping through each character. – Mr Pro Pop Sep 23 at 1:26
  • 1
    @MrProPop Maybe you can do that. Or if you use assembly language you can access carry flag which is set when it is shifted in certain conditions like the ooerand is even or its highst bit is 1, etc. Then you can naturally find bits from its highest bits. – KYHSGeekCode Sep 23 at 1:35
  • Thanks for everything! I have updated my question with the working code, and why I changed something to another and attached debugging. – Mr Pro Pop Sep 23 at 15:24

Here is my final working code

for (int i = 0; i < characters.length; i++) {
    int number = getDecimal(characters[i]);
    for (int j = 0; j < 8; j++) {
        result.insert(i * 9, (number % 2 == 0) ? 0 : 1);
        number = (int) (number >> 1);
    }
    // put a space if it isn't the last string
    if (i < characters.length - 1)
        result.insert(8 * (i + 1) + i, " ");
}

public int getDecimal(char character) {
    return character;
}

What I did?

  • I initialized the integer variable number inside the loop. I dunno why, just wanted to do it, think it is more organized now.
  • I used conditional operator known as Ternary Operator instead of the if/else. Reason is because it is shorter and looks more neat.
  • Made it put the bit at the beginning (first index) and after the loop runs, it puts a space at the end (after the last character).
  • Used the shifting operator instead of the division as recommended below, may be faster.
  • Why i*9 for the first loop? Cause i will start of with 0, so it is always going to put the character in the index 0. Then when i increments and becomes 1, it is going to be 9. Here if you realize, the 8 bits take the positions 0,7 then space at 8 and the new word binary sequence starts at 9. Therefore, the printing is (8 * (i+1)) for a loop for 3, will give 8, 17, 26 which is where we need the spaces.
  • Changed the get decimal number from ASCII character function and made it shorter by just returning the decimal of the character. No need for the if statements or for loops.

I made a simple debug for those of you who are confused or don't get it after the insert method add this

System.out.println("j:" + j + " Current number? " + number + " remainder is " + number % 2);

Output:

i:0

j:0 Current number? 97 remainder is 1

j:1 Current number? 48 remainder is 0

j:2 Current number? 24 remainder is 0

j:3 Current number? 12 remainder is 0

j:4 Current number? 6 remainder is 0

j:5 Current number? 3 remainder is 1

j:6 Current number? 1 remainder is 1

j:7 Current number? 0 remainder is 0

Binary code for a is 01100001

If there are further improvements or notes, please let me know, and ask if you have questions. Thanks everyone!

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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