madbean

Code idiom: using logical ^ to change your mind

26 Mar 2003

This idiom is a cool little trick, but I've seen coders scratching their head trying to work out what it does; so a detailed explanation is in order.

The ^ bitwise exclusive-or operator (or "XOR") is standard computer science fare. An XOR is often used to flip bits in a byte/word. In Java, the ^ bitwise operator works on all the integer types (int, byte, short, char, and long) and performs an XOR between each corresponding bit in the arguments.

But, if the operands to ^ are both boolean, then a logical exclusive-or (LXOR) is performed (as opposed to a bitwise XOR). The result of LXOR is "true if the operands are different; otherwise false if they are the same". The truth table for x ^ y looks like this:

xy falsetrue
falsefalsetrue
truetruefalse


The idiom: using ^ to change your mind

Can you work out what the following code does?

public static boolean isTuesday(boolean invert) {
    GregorianCalendar now = new GregorianCalendar();
    boolean isTue = now.get(Calendar.DAY_OF_WEEK) == Calendar.TUESDAY;
    return isTue ^ invert;
}

System.out.println("is Tuesday? " + isTuesday(false));
System.out.println("is not Tuesday? " + isTuesday(true));

The trick utilises this:

  • (x ^ false) is always just x
  • (x ^ true) negates x, it is !x

So, if you have some code that conditionally needs to do the opposite of what it normally would do (that is, it needs to "change its mind"), just pass an "invert" argument, and LXOR with that argument when making decisions. (You could call this argument "invert", "reverse", "negate", etc. depending on the particular semantics.)

Applied example: AbstractConditionalTag

Here is the code for a useful AbstractConditionalTag JSP Taglib and an example "is Tuesday" tag.

public abstract class AbstractConditionalTag extends TagSupport {
    private boolean invertTest = false;

    public void setInvert(String invert) {
        invertTest = "true".equalsIgnoreCase(invert);
    }

    public int doStartTag() throws JspTagException {
        try {
            boolean result = evaluateCondition() ^ invertTest;
            return result ? EVAL_BODY_INCLUDE : SKIP_BODY;
        }
        catch (RuntimeException e) {
            Logger.log(this, e);
            return SKIP_BODY;
        }
    }

    protected abstract boolean evaluateCondition()
        throws JspTagException;
}

public class IsTuesdayTag extends AbstractConditionalTag {
    public static boolean evaluateCondition() {
        GregorianCalendar now = new GregorianCalendar();
        return now.get(Calendar.DAY_OF_WEEK) == Calendar.TUESDAY;
    }
}

And you would use it in a JSP page like this:

<tag:isTuesday>
  It's Tuesday; rubbish day!
</tag:isTuesday>
<tag:isTuesday invert="true">
  Don't put the rubbish out today.
</tag:isTuesday>
  • Home
  • Blog