Uploaded image for project: 'Groovy'
  1. Groovy
  2. GROOVY-9605

leftShift operator does not work on BigInteger (throws UnsupportedOperationException)

    XMLWordPrintableJSON

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 3.0.4
    • Fix Version/s: 4.0.0-alpha-1, 3.0.5, 2.5.13
    • Component/s: groovy-jdk
    • Labels:
      None
    • Environment:
      Groovy 3.0.4 Windows and Linux

      Description

      Problem

      The leftShift operator (<<) does not work on BigInteger (see StackOverflow question).

      The leftShift() method is however described in Groovy's JDK enhancements.

      The below code fails with Groovy 3.0.4:

      Integer i = new Integer(3)
      assert 12 == i << 2
      
      Number b = new BigInteger("3")
      assert 12 == b << 2
      

      It throws an exception:

      Caught: java.lang.UnsupportedOperationException: Cannot use leftShift() on this number type: java.math.BigInteger with value: 3
      java.lang.UnsupportedOperationException: Cannot use leftShift() on this number type: java.math.BigInteger with value: 3
              at test.run(test.groovy:5)
      

      Consequence: you cannot use the << operator on a Number if this number is a BigInteger.

      Understanding of the problem

      (I'm not familiar with the code)
      The BigIntegerMath class does not implement the leftShift() method.

      Also, please note that JDK's BigInteger method for this operation is not leftShift() but shiftLeft()!

      Workaround

      Using mixins, the below code works:

      class EnhancedNumber {
      
      	static def originalLeftShift = org.codehaus.groovy.runtime.DefaultGroovyMethods.&leftShift
      	static Number leftShift(Number self, Number operand) {
      		self.class == BigInteger ? self.shiftLeft(operand) : originalLeftShift(self, operand)
      	}
      }
      
      Number.mixin(EnhancedNumber)
      
      Integer i = new Integer(3)
      assert 12 == i << 2
      
      Number b = new BigInteger("3")
      assert 12 == b << 2
      

        Attachments

          Activity

            People

            • Assignee:
              paulk Paul King
              Reporter:
              bertrandmartin Bertrand Martin
            • Votes:
              0 Vote for this issue
              Watchers:
              2 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 - 0.5h
                0.5h