Bertrand Martin created GROOVY-9605:
---------------------------------------

             Summary: leftShift operator does not work on BigInteger (throws 
UnsupportedOperationException)
                 Key: GROOVY-9605
                 URL: https://issues.apache.org/jira/browse/GROOVY-9605
             Project: Groovy
          Issue Type: Bug
          Components: groovy-jdk
    Affects Versions: 3.0.4
         Environment: Groovy 3.0.4 Windows and Linux
            Reporter: Bertrand Martin


h1. Problem
The _leftShift_ operator ({{<<}}) does not work on *BigInteger* (see 
[StackOverflow 
question|https://stackoverflow.com/questions/62496971/leftshift-method-on-biginteger-in-groovy]).

The *leftShift()* method is however described in [Groovy's JDK 
enhancements|http://docs.groovy-lang.org/latest/html/api/org/codehaus/groovy/runtime/DefaultGroovyMethods.html#leftShift(java.lang.Number,java.lang.Number)].

The below code fails with Groovy 3.0.4:
{code:groovy}
Integer i = new Integer(3)
assert 12 == i << 2

Number b = new BigInteger("3")
assert 12 == b << 2
{code}

It throws an exception:
{noformat}
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)
{noformat}

Consequence: you cannot use the {{<<}} operator on a _Number_ if this number is 
a _BigInteger_.

h1. Understanding of the problem
(I'm not familiar with the code)
The 
[BigIntegerMath|https://github.com/groovy/groovy-core/blob/master/src/main/org/codehaus/groovy/runtime/typehandling/BigIntegerMath.java]
 class does not implement the _leftShift()_ method.

Also, please note that JDK's 
[BigInteger|https://docs.oracle.com/javase/8/docs/api/java/math/BigInteger.html#shiftLeft-int-]
 method for this operation is *not* _leftShift()_ but _shiftLeft()_!

h1. Workaround
Using mixins, the below code works:
{code:groovy}
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
{code}



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to