diff -r 23cdb1f98069 -r bbd6c6d64b52 src/org/python/core/PyInteger.java --- a/src/org/python/core/PyInteger.java Mon Mar 18 21:06:33 2013 -0700 +++ b/src/org/python/core/PyInteger.java Mon Mar 18 22:59:03 2013 -0700 @@ -38,6 +38,8 @@ @Deprecated public static final BigInteger maxInt = MAX_INT; + private static final char[] LOOKUP = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; + private final int value; public PyInteger(PyType subType, int v) { @@ -1090,7 +1092,23 @@ format.setGroupingUsed(true); strValue = format.format(value); } else if (value instanceof BigInteger) { - strValue = ((BigInteger) value).toString(radix); + switch (radix) { + /* + case 2: + strValue = toBinString((BigInteger) value); + break; + case 8: + strValue = toOctString((BigInteger) value); + break; + */ + case 16: + strValue = toHexString((BigInteger) value); + break; + default: + // TODO: emulate CPython's _PyLong_Format() for efficiency + strValue = ((BigInteger) value).toString(radix); + break; + } } else { strValue = Integer.toString((Integer) value, radix); } @@ -1123,6 +1141,28 @@ return spec.pad(strValue, '>', 0); } + static final String toHexString(BigInteger value) { + int signum = value.signum(); + + // obvious shortcut + if (signum == 0) + return "0"; + + // we want to work in absolute numeric value (negative sign is added afterward) + byte[] input = value.abs().toByteArray(); + char[] output = new char[input.length * 2]; + + for (int i = 0; i < input.length; i++) { + output[2*i] = LOOKUP[(input[i] >> 4) & 0x0F]; + output[2*i+1] = LOOKUP[input[i] & 0x0F]; + } + + // before returning the char array as string, remove leading zeroes, but not the last one + String result = new String(output).replaceFirst("^0+(?!$)", ""); + + return signum < 0 ? "-" + result : result; + } + @Override public boolean isIndex() { return true; diff -r 23cdb1f98069 -r bbd6c6d64b52 src/org/python/core/PyLong.java --- a/src/org/python/core/PyLong.java Mon Mar 18 21:06:33 2013 -0700 +++ b/src/org/python/core/PyLong.java Mon Mar 18 22:59:03 2013 -0700 @@ -994,12 +994,19 @@ @ExposedMethod(doc = BuiltinDocs.long___hex___doc) final PyString long___hex__() { - String s = getValue().toString(16); - if (s.startsWith("-")) { + /* + Issue 2013: + getValue() returns a BigInteger object reference, and BigInteger.toString(radix) is known to + take computationally expensive time to compute for large numbers. + */ + //String s = getValue().toString(16); + + BigInteger value = getValue(); + String s = PyInteger.toHexString(value); + if (s.startsWith("-")) return new PyString("-0x" + s.substring(1, s.length()) + "L"); - } else { + else return new PyString("0x" + s + "L"); - } } @ExposedMethod(doc = BuiltinDocs.long___str___doc)