javacalculatorchecksum8-bit

Java program to calculate 8-bit checksum


I have an assignment to calculate the checksum of a number of 8-bit binary numbers. I've come a long way but for some reason it's giving me the wrong result. For example if x is: 10101010 and y is: 01101111, the checksum would be 11100110. But my code gives the checksum 01101110 (inverted an all). Please note the invertion of the sum happens in a different, already made, method. Meaning my method is returning 10010001, but is supposed to return 00011001.

Where have I gone wrong?

The Octet-method was already made.

    int[] x = new int[8];

    Octet(String s){
        if (s.length() != 8) {
            System.out.println("Too few or too many characters");
            return;
        }
        for (int i = 0; i < 8; i++) {
            if (s.charAt(i) == '1') {
                x[7 - i] = 1;
            }
            else {
                x[7 - i] = 0;
            }
        }
    }
    
    Octet sum(Octet y) {
        Octet result = new Octet("00000000");
         
        int carry = 0;

        for(int i = 0; i < 8; i++) {
            result.x[i] = x[i] ^ y.x[i] + carry;
            carry = x[i] & y.x[i];
        }

        if(carry == 1) {
            for(int i = 0; i < 8 && carry == 0; i++) {
                result.x[i] = result.x[i] ^ carry;
                carry = result.x[i] & carry;
            }
        }
                        
        return result;
    } 


Solution

  • Your problem is primarily that you're incorrectly mixing up binary (XOR) and integer (+) operations on the same integer values. Since you're combining three values together, you should stick with addition.

    If all of this could be rewritten, I'd store the bits in a single integer, in which case you'd get the logic pretty much for free. But if this is an exercise where you can't change the definition of an Octet, then here's a sum function that does the right thing based on working on integers:

    Octet sum(Octet y) {
        Octet result = new Octet("00000000");
        int carry = 0;
        for(int i = 0; i < 8; i++) {
            int a = x[i] + y.x[i] + carry;
            result.x[i] = a & 1;
            carry = a >> 1;
        }
        return result;
    }
    

    The main point here is that you don't want to use XOR. Only integer arithmetic will allow you to combine three values together and get the right result in all cases. So you add the three values, and then extract the resulting two bits (result bit + carry bit).

    I don't know what your second loop was supposed to do in your sum function, but as written, it would never enter the loop and so would never do anything anyway.

    I added a toString method to your Octet class:

    public String toString() {
        StringBuilder r = new StringBuilder();
        for (int i = 0 ; i < 8 ; i++) {
            r.append(x[7-i] == 1? "1" : "0");
        }
        return r.toString();
    }
    

    such that this test code gives a correct, readable result:

    public static void main(String[] args) {
        Octet x = new Octet("10101010");
        Octet y = new Octet("01101111");
        Octet z = x.sum(y);
        System.out.println(z);
    }
    

    Result:

    00011001