leftShift для BigInteger в Groovy - PullRequest
1 голос
/ 21 июня 2020

Как выполнить операцию leftShift для BigInteger in Groovy?

Метод leftShift определено в расширении JDK Groovy

Однако приведенный ниже код вызывает исключение UnsupportedOperationException :

Integer i = new Integer(3)
println(i << 2)

BigInteger b = new BigInteger("3")
println(b << 2)

Результат:

12   <-- working for Integer
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)

Полагаю, я мог бы использовать метод BigInteger.shiftLeft () (обратите внимание, что это не leftShift , а shiftLeft ...), но, в конце концов, я хотел бы использовать оператор << в Number , который может быть либо Integer , либо BigInteger .

Ошибка Groovy? (Я использую 3.0.4)

Ответы [ 2 ]

3 голосов
/ 21 июня 2020

По какой-то причине базовый BigIntegerMath не отменяет метод leftShiftImpl () , что приводит к UnsopportedOperationException.

Может стоить сообщить о проблеме.

На данный момент вам нужно прибегнуть к обходным путям, например

assert 12 == new BigInteger(3).intValue() << 2
//or
assert 12 == new BigInteger(3).shiftLeft( 2 )
1 голос
/ 21 июня 2020

Итак, похоже, что это ошибка в Groovy, на что указывает наш @ injecteer

Хорошая новость в том, что Groovy легко «исправить» с помощью класса «mixin»:

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

Все еще немного раздражает ...

...