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)