Uploaded image for project: 'Commons Lang'
  1. Commons Lang
  2. LANG-1627

BooleanUtils.xor not behaving as expected with any odd number of true's

Attach filesAttach ScreenshotVotersWatch issueWatchersCreate sub-taskLinkCloneUpdate Comment AuthorReplace String in CommentUpdate Comment VisibilityDelete Comments
    XMLWordPrintableJSON

Details

    • Bug
    • Status: Resolved
    • Major
    • Resolution: Fixed
    • 3.11
    • 3.13.0
    • None
    • None

    Description

      Hi,

      I was expecting a xor function that takes a variable number of arguments to return true if and only if exactly one among all of the arguments is true, regardless of the number of arguments.

      This holds true given three false's:

      @Test
      public void threeFalse() {
       boolean[] bools = new boolean[]{Boolean.FALSE, Boolean.FALSE, Boolean.FALSE};
       assertFalse(BooleanUtils.xor(bools));
      }

       
      It also holds true given 4 true's, as well as for any even number of trues.

          @Test
          public void fourTrue() {
              boolean[] bools = new boolean[]{Boolean.TRUE, Boolean.TRUE, Boolean.TRUE, Boolean.TRUE};
              assertFalse(BooleanUtils.xor(bools));
          }
      

      The above tests pass.

      But with any odd number of true's that doesn't hold anymore:

       

      @Test
      public void threeTrue() {
       boolean[] bools = new boolean[]{Boolean.TRUE, Boolean.TRUE, Boolean.TRUE};
       assertFalse(BooleanUtils.xor(bools));
      }
      

      This test fails.

      That was totally unexpected to me.
      But as it turns out, even

      true ^ true ^ true

      evaluates to true. That was unexpected too to me, at a first sight.

      The thing is that xor (I mean the original boolean operator) is a binary operator, so if you want to make it n-ary, one simple solution is to apply it in two by two: ((a ^ b) ^ c) ^ d
      And that's what is done in the implementation of the method BooleanUtils#xor.

      But that brings to BooleanUtils.xor(true, true, true) == true, and at the same time BooleanUtils.xor(true, true, true, true) == false, which just doesn't sound right to me.

      Whether or not you agree with me that that is a bug of the method, please at least update the Javadoc, because right now it is not providing the user enough information. Look:

      Performs an xor on a set of booleans.
               BooleanUtils.xor(true, true)   = false
               BooleanUtils.xor(false, false) = false
               BooleanUtils.xor(true, false)  = true
      

       

      Thanks.

      Cheers

      Attachments

        Activity

          This comment will be Viewable by All Users Viewable by All Users
          Cancel

          People

            Unassigned Unassigned
            alb-i986 Alberto Scotto
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Time Tracking

                Estimated:
                Original Estimate - Not Specified
                Not Specified
                Remaining:
                Remaining Estimate - 0h
                0h
                Logged:
                Time Spent - 1h 40m
                1h 40m

                Slack

                  Issue deployment