Skip to content

Commit 5b6dd2b

Browse files
committed
add test and fix inverse modulus
1 parent 1b275a2 commit 5b6dd2b

File tree

4 files changed

+22
-14
lines changed

4 files changed

+22
-14
lines changed

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,3 +117,12 @@ def mypow_rev(a, b, c):
117117
assert mypow_rev(*args[:-1]) == args[-1], "%r -> %r == %r" % (args, mypow(*args[:-1]), args[-1])
118118

119119
assert 2**1.0 == 2.0
120+
121+
try:
122+
pow(12,-2,100)
123+
except ValueError as e:
124+
assert "base is not invertible for the given modulus" in str(e)
125+
else:
126+
assert False
127+
128+
assert pow(1234567, -2, 100) == 9

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ def test_pow():
299299
# (0xffffffffffffffff >> 63) is used to produce a non-narrowed int
300300
assert 2**(0xffffffffffffffff >> 63) == 2
301301

302-
if sys.implementation.name == "graalpython":
302+
if sys.version_info.minor >= 8:
303303
# for some reason this hangs CPython on the CI even if it's just parsed
304304
from pow_tests import test_pow
305305
test_pow()

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

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -802,26 +802,24 @@ private Object objectOp(Object left, Object right, Object mod) {
802802
BigInteger bigMod = integerToBigInteger(mod);
803803
if (bigMod.signum() == 0) {
804804
throw raise(ValueError, ErrorMessages.POW_THIRD_ARG_CANNOT_BE_ZERO);
805-
} else if (bigRight.signum() >= 0 && bigMod.signum() > 0) {
806-
return bigLeft.modPow(bigRight, bigMod);
807-
} else if (bigMod.signum() < 0) {
808-
BigInteger bigModPos = bigMod.abs();
805+
} else {
806+
BigInteger bigModPos;
807+
if (bigMod.signum() < 0) {
808+
bigModPos = bigMod.abs();
809+
} else {
810+
bigModPos = bigMod;
811+
}
809812
try {
810813
BigInteger pow = bigLeft.modPow(bigRight, bigModPos);
811-
if (!BigInteger.ZERO.equals(pow)) {
814+
if (bigModPos != bigMod && !BigInteger.ZERO.equals(pow)) {
812815
return pow.subtract(bigModPos);
813816
} else {
814817
return pow;
815818
}
816819
} catch (ArithmeticException e) {
817-
// bigModPos was used, so this exception must mean the exponent was negative
818-
return Math.pow(bigLeft.doubleValue(), bigRight.doubleValue()) % bigMod.doubleValue();
819-
}
820-
} else {
821-
try {
822-
return bigLeft.modPow(bigRight, bigMod);
823-
} catch (ArithmeticException e) {
824-
return Math.pow(bigLeft.doubleValue(), bigRight.doubleValue()) % bigMod.doubleValue();
820+
// a positive mod was used, so this exception must mean the exponent was
821+
// negative and the base is not relatively prime to the exponent
822+
throw raise(ValueError, ErrorMessages.POW_BASE_NOT_INVERTIBLE);
825823
}
826824
}
827825
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/ErrorMessages.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,5 +489,6 @@ public abstract class ErrorMessages {
489489
public static final String ZIPIMPORT_CANT_READ_DATA = "zipimport: can't read data";
490490
public static final String ZIPIMPORT_WRONG_CACHED_FILE_POS = "zipimport: wrong cached file position";
491491
public static final String ACCESS_TO_INTERNAL_LANG_NOT_PERMITTED = "access to internal language %s is not permitted";
492+
public static final String POW_BASE_NOT_INVERTIBLE = "base is not invertible for the given modulus";
492493
public static final String POW_THIRD_ARG_CANNOT_BE_ZERO = "pow() 3rd argument cannot be 0";
493494
}

0 commit comments

Comments
 (0)