Skip to content

Commit a901ca5

Browse files
committed
[GR-13915] Strength reduction on BigInteger multiplication
PullRequest: graalpython/441
2 parents ef596d3 + 357dc3a commit a901ca5

File tree

2 files changed

+23
-4
lines changed
  • graalpython
    • com.oracle.graal.python.test/src/tests
    • com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ints

2 files changed

+23
-4
lines changed

graalpython/com.oracle.graal.python.test/src/tests/test_int.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,11 @@ def test_boolean2int():
6767
assert int(False) == 0
6868

6969

70+
def test_bigint_mul():
71+
assert 99999937497465632974931 * 1223432423545234234123123 == 122343165886896325043539375228725106116626429513
72+
assert 99999937497465632974931 * (2**100) == 126764980791447734004805377032945185921379990352429056
73+
74+
7075
def test_int_from_custom():
7176
class CustomInt4():
7277
def __int__(self):

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ints/IntBuiltins.java

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -637,27 +637,41 @@ PInt doLLOvf(long x, long y) {
637637
if (((ax | ay) >>> 31 != 0)) {
638638
int leadingZeros = Long.numberOfLeadingZeros(ax) + Long.numberOfLeadingZeros(ay);
639639
if (leadingZeros < 66) {
640-
return factory().createInt(op(BigInteger.valueOf(x), BigInteger.valueOf(y)));
640+
return factory().createInt(mul(BigInteger.valueOf(x), BigInteger.valueOf(y)));
641641
}
642642
}
643643
return factory().createInt(r);
644644
}
645645

646646
@Specialization
647647
PInt doPIntLong(PInt left, long right) {
648-
return factory().createInt(op(left.getValue(), BigInteger.valueOf(right)));
648+
return factory().createInt(mul(left.getValue(), BigInteger.valueOf(right)));
649649
}
650650

651651
@Specialization
652652
PInt doPIntPInt(PInt left, PInt right) {
653-
return factory().createInt(op(left.getValue(), right.getValue()));
653+
return factory().createInt(mul(left.getValue(), right.getValue()));
654+
}
655+
656+
@TruffleBoundary
657+
BigInteger mul(BigInteger a, BigInteger b) {
658+
if (b.and(b.subtract(BigInteger.ONE)).equals(BigInteger.ZERO)) {
659+
return bigIntegerShift(a, b.getLowestSetBit());
660+
} else {
661+
return bigIntegerMul(a, b);
662+
}
654663
}
655664

656665
@TruffleBoundary
657-
BigInteger op(BigInteger a, BigInteger b) {
666+
BigInteger bigIntegerMul(BigInteger a, BigInteger b) {
658667
return a.multiply(b);
659668
}
660669

670+
@TruffleBoundary
671+
BigInteger bigIntegerShift(BigInteger a, int n) {
672+
return a.shiftLeft(n);
673+
}
674+
661675
@SuppressWarnings("unused")
662676
@Fallback
663677
PNotImplemented doGeneric(Object left, Object right) {

0 commit comments

Comments
 (0)