public class BinaryInteger {
    private final int N;      // number of bits
    private final String s;   // bit string

    // create a binary integer from a string of 0s and 1s
    public BinaryInteger(String s) {
        if (!s.matches("[01]*")) {
            throw new RuntimeException("Illegal argument to BinaryInteger()");
        }
        this.s = s;
        this.N = s.length();
    }

    // length of this binary integer
    public int length() {
        return N;
    }

    // number of leading zeros in this binary integer
    public int leadingZeros() {
        int count = 0;
        for (int i = N-1; i >= 0; i--) {
            if (!ith(i)) count++;
            else break;
        }
        return count;
    }

    // is this binary integer strictly greater than that binary integer?
    public boolean isGreaterThan(BinaryInteger that) {
        int n1 = this.length() - this.leadingZeros();
        int n2 = that.length() - that.leadingZeros();
        if (n1 > n2) return true;
        if (n1 < n2) return false;
        for (int i = n1 - 1; i >= 0; i--) {
            if (this.ith(i) && !that.ith(i)) return true;
            if (that.ith(i) && !this.ith(i)) return false;
        }
        return false;   // equal
    }

    // return the ith least significant bit as a boolean
    private boolean ith(int i) {
        if      (s.charAt(N - i - 1) == '0') return false;
        else if (s.charAt(N - i - 1) == '1') return true;
        else throw new RuntimeException("Inconsisent state");
    }

    // return the bitwise xor of this binary integer and that binary integer
    public BinaryInteger xor(BinaryInteger that) {
        if (this.N != that.N) throw new RuntimeException("Size mismatch");
        String answer = "";
        for (int i = 0; i < N; i++) {
            if (this.ith(i) ^ that.ith(i)) answer = "1" + answer;
            else                           answer = "0" + answer;
        }
        return new BinaryInteger(answer);
    }

    // return the bitwise not of this binary integer
    public BinaryInteger not() {
        String answer = "";
        for (int i = 0; i < N; i++) {
            if (this.ith(i)) answer = "0" + answer;
            else             answer = "1" + answer;
        }
        return new BinaryInteger(answer);
    }

    // return string representation of this binary integer
    public String toString() {
        return s;
    }

    // test client
    public static void main(String[] args) {
        BinaryInteger a = new BinaryInteger("00011110");
        BinaryInteger b = new BinaryInteger("01010000");
        System.out.println("a                  = " + a);
        System.out.println("b                  = " + b);
        System.out.println("a.length()         = " + a.length());
        System.out.println("a.not()            = " + a.not());
        System.out.println("a.xor(b)           = " + a.xor(b));
        System.out.println("a.leadingZeros()   = " + a.leadingZeros());
        System.out.println("a.isGreaterThan(b) = " + a.isGreaterThan(b));
    }
}