All Downloads are FREE. Search and download functionalities are using the official Maven repository.

src.org.python.core.PyInteger Maven / Gradle / Ivy

Go to download

Jython is an implementation of the high-level, dynamic, object-oriented language Python written in 100% Pure Java, and seamlessly integrated with the Java platform. It thus allows you to run Python on any Java platform.

There is a newer version: 2.7.4
Show newest version
// Copyright (c) Corporation for National Research Initiatives
// Copyright (c) Jython Developers
package org.python.core;

import java.io.Serializable;
import java.math.BigInteger;

import org.python.core.stringlib.FloatFormatter;
import org.python.core.stringlib.IntegerFormatter;
import org.python.core.stringlib.InternalFormat;
import org.python.core.stringlib.InternalFormat.Formatter;
import org.python.core.stringlib.InternalFormat.Spec;
import org.python.expose.ExposedGet;
import org.python.expose.ExposedMethod;
import org.python.expose.ExposedNew;
import org.python.expose.ExposedType;
import org.python.expose.MethodType;

/**
 * A builtin python int.
 */
@Untraversable
@ExposedType(name = "int", doc = BuiltinDocs.int_doc)
public class PyInteger extends PyObject {

    public static final PyType TYPE = PyType.fromClass(PyInteger.class);

    /** The minimum value of an int represented by a BigInteger */
    public static final BigInteger MIN_INT = BigInteger.valueOf(Integer.MIN_VALUE);

    /** The maximum value of an int represented by a BigInteger */
    public static final BigInteger MAX_INT = BigInteger.valueOf(Integer.MAX_VALUE);

    /** @deprecated Use MIN_INT instead. */
    @Deprecated
    public static final BigInteger minInt = MIN_INT;
    /** @deprecated Use MAX_INT instead. */
    @Deprecated
    public static final BigInteger maxInt = MAX_INT;

    private static final String LOOKUP = "0123456789abcdef";

    private final int value;

    public PyInteger(PyType subType, int v) {
        super(subType);
        value = v;
    }

    public PyInteger(int v) {
        this(TYPE, v);
    }

    @ExposedNew
    public static PyObject int_new(PyNewWrapper new_, boolean init, PyType subtype,
            PyObject[] args, String[] keywords) {

        ArgParser ap = new ArgParser("int", args, keywords, new String[] {"x", "base"}, 0);
        PyObject x = ap.getPyObject(0, null);
        int base = ap.getInt(1, -909);

        if (new_.for_type == subtype) { // A substantive PyInteger is required as the return value

            if (x == null) {
                return Py.Zero;

            } else if (base == -909) {
                if (x instanceof PyBoolean) {
                    return (coerce(x) == 0) ? Py.Zero : Py.One;
                } else if (x instanceof PyByteArray) {
                    // Make use of the string to int conversion in PyString
                    PyString xs = new PyString(x.asString());
                    return asPyInteger(xs);
                } else {
                    return asPyInteger(x);
                }
            } else if (!(x instanceof PyString)) {
                throw Py.TypeError("int: can't convert non-string with explicit base");
            }

            try {
                return Py.newInteger(((PyString)x).atoi(base));
            } catch (PyException pye) {
                if (pye.match(Py.OverflowError)) {
                    return ((PyString)x).atol(base);
                }
                throw pye;
            }

        } else { // A PyIntegerDerived(subtype, ... ) is required as the return value

            if (x == null) {
                return new PyIntegerDerived(subtype, 0);
            } else if (base == -909) {
                PyObject intOrLong = asPyInteger(x);

                if (intOrLong instanceof PyInteger) {
                    return new PyIntegerDerived(subtype, ((PyInteger)intOrLong).getValue());
                } else {
                    throw Py.OverflowError("long int too large to convert to int");
                }

            } else if (!(x instanceof PyString)) {
                throw Py.TypeError("int: can't convert non-string with explicit base");
            }

            return new PyIntegerDerived(subtype, ((PyString)x).atoi(base));
        }
    } // xxx

    /**
     * Convert all sorts of object types to either PyInteger or PyLong,
     * using their {@link PyObject#__int__()} method, whether exposed or not, or if that raises an
     * exception (as the base PyObject one does), using any __trunc__()
     * the type may have exposed. If all this fails, this method raises an exception. Equivalent to
     * CPython PyNumber_Int().
     *
     * @param x to convert to an int
     * @return int or long result.
     * @throws PyException {@code TypeError} if no method of conversion can be found
     * @throws PyException {@code AttributeError} if neither __int__ nor __trunc__ found (?)
     */
    private static PyObject asPyInteger(PyObject x) throws PyException {
        // XXX: Not sure that this perfectly matches CPython semantics.
        try {
            // Try the object itself (raises AttributeError if not overridden from PyObject)
            return x.__int__();

        } catch (PyException pye) {
            if (!pye.match(Py.AttributeError)) {
                // x had an __int__ method, but something else went wrong: pass it on
                throw pye;

            } else {
                // x did not have an __int__ method, but maybe __trunc__ will work
                try {
                    PyObject integral = x.invoke("__trunc__");
                    return convertIntegralToInt(integral);

                } catch (PyException pye2) {
                    if (!pye2.match(Py.AttributeError)) {
                        throw pye2;
                    }
                    String fmt = "int() argument must be a string or a number, not '%.200s'";
                    throw Py.TypeError(String.format(fmt, x));
                }
            }
        }
    }

    /**
     * Helper called on whatever exposed method __trunc__ returned: it may be
     * int, long or something with an exposed __int__.
     *
     * @return convert to an int.
     * @throws TypeError and AttributeError.
     */
    private static PyObject convertIntegralToInt(PyObject integral) {
        if (!(integral instanceof PyInteger) && !(integral instanceof PyLong)) {
            PyObject i = integral.invoke("__int__");
            if (!(i instanceof PyInteger) && !(i instanceof PyLong)) {
                throw Py.TypeError(String.format("__trunc__ returned non-Integral (type %.200s)",
                        integral.getType().fastGetName()));
            }
            return i;
        }
        return integral;
    }

    @ExposedGet(name = "real", doc = BuiltinDocs.int_real_doc)
    public PyObject getReal() {
        return int___int__();
    }

    @ExposedGet(name = "imag", doc = BuiltinDocs.int_imag_doc)
    public PyObject getImag() {
        return Py.newInteger(0);
    }

    @ExposedGet(name = "numerator", doc = BuiltinDocs.int_numerator_doc)
    public PyObject getNumerator() {
        return int___int__();
    }

    @ExposedGet(name = "denominator", doc = BuiltinDocs.int_denominator_doc)
    public PyObject getDenominator() {
        return Py.newInteger(1);
    }

    public int getValue() {
        return value;
    }

    @Override
    public String toString() {
        return int_toString();
    }

    // XXX: need separate __doc__ for __repr__
    @ExposedMethod(names = {"__str__", "__repr__"}, doc = BuiltinDocs.int___str___doc)
    final String int_toString() {
        return Integer.toString(getValue());
    }

    @Override
    public int hashCode() {
        return int_hashCode();
    }

    @ExposedMethod(names = "__hash__", doc = BuiltinDocs.int___hash___doc)
    final int int_hashCode() {
        return getValue();
    }

    @Override
    public boolean __nonzero__() {
        return int___nonzero__();
    }

    @ExposedMethod(doc = BuiltinDocs.int___nonzero___doc)
    final boolean int___nonzero__() {
        return getValue() != 0;
    }

    @Override
    public Object __tojava__(Class c) {
        if (c == Integer.TYPE || c == Number.class || c == Object.class || c == Integer.class
                || c == Serializable.class) {
            return Integer.valueOf(getValue());
        }

        if (c == Boolean.TYPE || c == Boolean.class) {
            return Boolean.valueOf(getValue() != 0);
        }
        if (c == Byte.TYPE || c == Byte.class) {
            return Byte.valueOf((byte)getValue());
        }
        if (c == Short.TYPE || c == Short.class) {
            return Short.valueOf((short)getValue());
        }

        if (c == Long.TYPE || c == Long.class) {
            return Long.valueOf(getValue());
        }
        if (c == Float.TYPE || c == Float.class) {
            return Float.valueOf(getValue());
        }
        if (c == Double.TYPE || c == Double.class) {
            return Double.valueOf(getValue());
        }
        return super.__tojava__(c);
    }

    @Override
    public int __cmp__(PyObject other) {
        return int___cmp__(other);
    }

    @ExposedMethod(type = MethodType.CMP, doc = BuiltinDocs.int___cmp___doc)
    final int int___cmp__(PyObject other) {
        if (!canCoerce(other)) {
            return -2;
        }
        int v = coerce(other);
        return getValue() < v ? -1 : getValue() > v ? 1 : 0;
    }

    @Override
    public Object __coerce_ex__(PyObject other) {
        return int___coerce_ex__(other);
    }

    @ExposedMethod(doc = BuiltinDocs.int___coerce___doc)
    final PyObject int___coerce__(PyObject other) {
        return adaptToCoerceTuple(int___coerce_ex__(other));
    }

    /**
     * Coercion logic for int. Implemented as a final method to avoid invocation of virtual methods
     * from the exposed coerced.
     */
    final Object int___coerce_ex__(PyObject other) {
        return other instanceof PyInteger ? other : Py.None;
    }

    private static final boolean canCoerce(PyObject other) {
        return other instanceof PyInteger;
    }

    private static final int coerce(PyObject other) {
        if (other instanceof PyInteger) {
            return ((PyInteger)other).getValue();
        }
        throw Py.TypeError("xxx");
    }

    @Override
    public PyObject __add__(PyObject right) {
        return int___add__(right);
    }

    @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.int___add___doc)
    final PyObject int___add__(PyObject right) {
        if (!canCoerce(right)) {
            return null;
        }
        int rightv = coerce(right);
        int a = getValue();
        int b = rightv;
        int x = a + b;
        if ((x ^ a) >= 0 || (x ^ b) >= 0) {
            return Py.newInteger(x);
        }
        return new PyLong((long)a + (long)b);
    }

    @Override
    public PyObject __radd__(PyObject left) {
        return int___radd__(left);
    }

    @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.int___radd___doc)
    final PyObject int___radd__(PyObject left) {
        return __add__(left);
    }

    private static PyObject _sub(int a, int b) {
        int x = a - b;
        if ((x ^ a) >= 0 || (x ^ ~b) >= 0) {
            return Py.newInteger(x);
        }
        return new PyLong((long)a - (long)b);
    }

    @Override
    public PyObject __sub__(PyObject right) {
        return int___sub__(right);
    }

    @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.int___sub___doc)
    final PyObject int___sub__(PyObject right) {
        if (!canCoerce(right)) {
            return null;
        }
        return _sub(getValue(), coerce(right));
    }

    @Override
    public PyObject __rsub__(PyObject left) {
        return int___rsub__(left);
    }

    @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.int___rsub___doc)
    final PyObject int___rsub__(PyObject left) {
        if (!canCoerce(left)) {
            return null;
        }
        return _sub(coerce(left), getValue());
    }

    @Override
    public PyObject __mul__(PyObject right) {
        return int___mul__(right);
    }

    @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.int___mul___doc)
    final PyObject int___mul__(PyObject right) {
        if (!canCoerce(right)) {
            return null;
        }
        int rightv = coerce(right);

        double x = getValue();
        x *= rightv;

        if (x <= Integer.MAX_VALUE && x >= Integer.MIN_VALUE) {
            return Py.newInteger((int)x);
        }
        return __long__().__mul__(right);
    }

    @Override
    public PyObject __rmul__(PyObject left) {
        return int___rmul__(left);
    }

    @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.int___rmul___doc)
    final PyObject int___rmul__(PyObject left) {
        return __mul__(left);
    }

    // Getting signs correct for integer division
    // This convention makes sense when you consider it in tandem with modulo
    private static long divide(long x, long y) {
        if (y == 0) {
            throw Py.ZeroDivisionError("integer division or modulo by zero");
        }
        long xdivy = x / y;
        long xmody = x - xdivy * y;

        // If the signs of x and y differ, and the remainder is non-0, C89 doesn't define
        // whether xdivy is now the floor or the ceiling of the infinitely precise
        // quotient. We want the floor, and we have it iff the remainder's sign matches
        // y's.
        if (xmody != 0 && ((y < 0 && xmody > 0) || (y > 0 && xmody < 0))) {
            xmody += y;
            --xdivy;
            // assert(xmody && ((y ^ xmody) >= 0));
        }
        return xdivy;
    }

    @Override
    public PyObject __div__(PyObject right) {
        return int___div__(right);
    }

    @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.int___div___doc)
    final PyObject int___div__(PyObject right) {
        if (!canCoerce(right)) {
            return null;
        }
        if (Options.division_warning > 0) {
            Py.warning(Py.DeprecationWarning, "classic int division");
        }
        return Py.newInteger(divide(getValue(), coerce(right)));
    }

    @Override
    public PyObject __rdiv__(PyObject left) {
        return int___rdiv__(left);
    }

    @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.int___rdiv___doc)
    final PyObject int___rdiv__(PyObject left) {
        if (!canCoerce(left)) {
            return null;
        }
        if (Options.division_warning > 0) {
            Py.warning(Py.DeprecationWarning, "classic int division");
        }
        return Py.newInteger(divide(coerce(left), getValue()));
    }

    @Override
    public PyObject __floordiv__(PyObject right) {
        return int___floordiv__(right);
    }

    @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.int___floordiv___doc)
    final PyObject int___floordiv__(PyObject right) {
        if (!canCoerce(right)) {
            return null;
        }
        return Py.newInteger(divide(getValue(), coerce(right)));
    }

    @Override
    public PyObject __rfloordiv__(PyObject left) {
        return int___rfloordiv__(left);
    }

    @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.int___rfloordiv___doc)
    final PyObject int___rfloordiv__(PyObject left) {
        if (!canCoerce(left)) {
            return null;
        }
        return Py.newInteger(divide(coerce(left), getValue()));
    }

    @Override
    public PyObject __truediv__(PyObject right) {
        return int___truediv__(right);
    }

    @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.int___truediv___doc)
    final PyObject int___truediv__(PyObject right) {
        if (right instanceof PyInteger) {
            return __float__().__truediv__(right);
        } else if (right instanceof PyLong) {
            return int___long__().__truediv__(right);
        } else {
            return null;
        }
    }

    @Override
    public PyObject __rtruediv__(PyObject left) {
        return int___rtruediv__(left);
    }

    @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.int___rtruediv___doc)
    final PyObject int___rtruediv__(PyObject left) {
        if (left instanceof PyInteger) {
            return left.__float__().__truediv__(this);
        } else if (left instanceof PyLong) {
            return left.__truediv__(int___long__());
        } else {
            return null;
        }
    }

    private static long modulo(long x, long y, long xdivy) {
        return x - xdivy * y;
    }

    @Override
    public PyObject __mod__(PyObject right) {
        return int___mod__(right);
    }

    @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.int___mod___doc)
    final PyObject int___mod__(PyObject right) {
        if (!canCoerce(right)) {
            return null;
        }
        int rightv = coerce(right);
        int v = getValue();
        return Py.newInteger(modulo(v, rightv, divide(v, rightv)));
    }

    @Override
    public PyObject __rmod__(PyObject left) {
        return int___rmod__(left);
    }

    @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.int___rmod___doc)
    final PyObject int___rmod__(PyObject left) {
        if (!canCoerce(left)) {
            return null;
        }
        int leftv = coerce(left);
        int v = getValue();
        return Py.newInteger(modulo(leftv, v, divide(leftv, v)));
    }

    @Override
    public PyObject __divmod__(PyObject right) {
        return int___divmod__(right);
    }

    @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.int___divmod___doc)
    final PyObject int___divmod__(PyObject right) {
        if (!canCoerce(right)) {
            return null;
        }
        int rightv = coerce(right);

        int v = getValue();
        long xdivy = divide(v, rightv);
        return new PyTuple(Py.newInteger(xdivy), Py.newInteger(modulo(v, rightv, xdivy)));
    }

    @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.int___rdivmod___doc)
    final PyObject int___rdivmod__(PyObject left) {
        if (!canCoerce(left)) {
            return null;
        }
        int leftv = coerce(left);

        int v = getValue();
        long xdivy = divide(leftv, v);
        return new PyTuple(Py.newInteger(xdivy), Py.newInteger(modulo(leftv, v, xdivy)));
    }

    @Override
    public PyObject __pow__(PyObject right, PyObject modulo) {
        return int___pow__(right, modulo);
    }

    @ExposedMethod(type = MethodType.BINARY, defaults = {"null"}, //
            doc = BuiltinDocs.int___pow___doc)
    final PyObject int___pow__(PyObject right, PyObject modulo) {
        if (!canCoerce(right)) {
            return null;
        }

        modulo = (modulo == Py.None) ? null : modulo;
        if (modulo != null && !canCoerce(modulo)) {
            return null;
        }

        return _pow(getValue(), coerce(right), modulo, this, right);
    }

    @Override
    public PyObject __rpow__(PyObject left) {
        if (!canCoerce(left)) {
            return null;
        }
        return _pow(coerce(left), getValue(), null, left, this);
    }

    @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.int___rpow___doc)
    final PyObject int___rpow__(PyObject left) {
        return __rpow__(left);
    }

    private static PyObject _pow(int value, int pow, PyObject modulo,//
            PyObject left, PyObject right) {
        int mod = 0;
        long tmp = value;
        boolean neg = false;
        if (tmp < 0) {
            tmp = -tmp;
            neg = (pow & 0x1) != 0;
        }
        long result = 1;

        if (pow < 0) {
            if (value != 0) {
                return left.__float__().__pow__(right, modulo);
            } else {
                throw Py.ZeroDivisionError("0.0 cannot be raised to a negative power");
            }
        }

        if (modulo != null) {
            mod = coerce(modulo);
            if (mod == 0) {
                throw Py.ValueError("pow(x, y, z) with z==0");
            }
        }

        // Standard O(ln(N)) exponentiation code
        while (pow > 0) {
            if ((pow & 0x1) != 0) {
                result *= tmp;
                if (mod != 0) {
                    result %= mod;
                }

                if (result > Integer.MAX_VALUE) {
                    return left.__long__().__pow__(right, modulo);
                }
            }
            pow >>= 1;
            if (pow == 0) {
                break;
            }
            tmp *= tmp;

            if (mod != 0) {
                tmp %= mod;
            }

            if (tmp > Integer.MAX_VALUE) {
                return left.__long__().__pow__(right, modulo);
            }
        }

        if (neg) {
            result = -result;
        }

        // Cleanup result of modulo
        if (mod != 0) {
            result = modulo(result, mod, divide(result, mod));
        }
        return Py.newInteger(result);
    }

    @Override
    public PyObject __lshift__(PyObject right) {
        return int___lshift__(right);
    }

    @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.int___lshift___doc)
    final PyObject int___lshift__(PyObject right) {
        int rightv;
        if (right instanceof PyInteger) {
            rightv = ((PyInteger)right).getValue();
        } else if (right instanceof PyLong) {
            return int___long__().__lshift__(right);
        } else {
            return null;
        }

        if (rightv >= Integer.SIZE) {
            return __long__().__lshift__(right);
        } else if (rightv < 0) {
            throw Py.ValueError("negative shift count");
        }
        int result = getValue() << rightv;
        if (getValue() != result >> rightv) {
            return __long__().__lshift__(right);
        }
        return Py.newInteger(result);
    }

    @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.int___rlshift___doc)
    final PyObject int___rlshift__(PyObject left) {
        int leftv;
        if (left instanceof PyInteger) {
            leftv = ((PyInteger)left).getValue();
        } else if (left instanceof PyLong) {
            return left.__rlshift__(int___long__());
        } else {
            return null;
        }

        if (getValue() >= Integer.SIZE) {
            return left.__long__().__lshift__(this);
        } else if (getValue() < 0) {
            throw Py.ValueError("negative shift count");
        }
        int result = leftv << getValue();
        if (leftv != result >> getValue()) {
            return left.__long__().__lshift__(this);
        }
        return Py.newInteger(result);
    }

    @Override
    public PyObject __rshift__(PyObject right) {
        return int___rshift__(right);
    }

    @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.int___rshift___doc)
    final PyObject int___rshift__(PyObject right) {
        int rightv;
        if (right instanceof PyInteger) {
            rightv = ((PyInteger)right).getValue();
        } else if (right instanceof PyLong) {
            return int___long__().__rshift__(right);
        } else {
            return null;
        }

        if (rightv < 0) {
            throw Py.ValueError("negative shift count");
        }

        if (rightv >= Integer.SIZE) {
            return Py.newInteger(getValue() < 0 ? -1 : 0);
        }

        return Py.newInteger(getValue() >> rightv);
    }

    @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.int___rrshift___doc)
    final PyObject int___rrshift__(PyObject left) {
        int leftv;
        if (left instanceof PyInteger) {
            leftv = ((PyInteger)left).getValue();
        } else if (left instanceof PyLong) {
            return left.__rshift__(int___long__());
        } else {
            return null;
        }

        if (getValue() < 0) {
            throw Py.ValueError("negative shift count");
        }

        if (getValue() >= Integer.SIZE) {
            return Py.newInteger(leftv < 0 ? -1 : 0);
        }

        return Py.newInteger(leftv >> getValue());
    }

    @Override
    public PyObject __and__(PyObject right) {
        return int___and__(right);
    }

    @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.int___and___doc)
    final PyObject int___and__(PyObject right) {
        int rightv;
        if (right instanceof PyInteger) {
            rightv = ((PyInteger)right).getValue();
        } else if (right instanceof PyLong) {
            return int___long__().__and__(right);
        } else {
            return null;
        }

        return Py.newInteger(getValue() & rightv);
    }

    @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.int___rand___doc)
    final PyObject int___rand__(PyObject left) {
        return int___and__(left);
    }

    @Override
    public PyObject __xor__(PyObject right) {
        return int___xor__(right);
    }

    @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.int___xor___doc)
    final PyObject int___xor__(PyObject right) {
        int rightv;
        if (right instanceof PyInteger) {
            rightv = ((PyInteger)right).getValue();
        } else if (right instanceof PyLong) {
            return int___long__().__xor__(right);
        } else {
            return null;
        }

        return Py.newInteger(getValue() ^ rightv);
    }

    @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.int___rxor___doc)
    final PyObject int___rxor__(PyObject left) {
        int leftv;
        if (left instanceof PyInteger) {
            leftv = ((PyInteger)left).getValue();
        } else if (left instanceof PyLong) {
            return left.__rxor__(int___long__());
        } else {
            return null;
        }

        return Py.newInteger(leftv ^ getValue());
    }

    @Override
    public PyObject __or__(PyObject right) {
        return int___or__(right);
    }

    @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.int___or___doc)
    final PyObject int___or__(PyObject right) {
        int rightv;
        if (right instanceof PyInteger) {
            rightv = ((PyInteger)right).getValue();
        } else if (right instanceof PyLong) {
            return int___long__().__or__(right);
        } else {
            return null;
        }

        return Py.newInteger(getValue() | rightv);
    }

    @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.int___ror___doc)
    final PyObject int___ror__(PyObject left) {
        return int___or__(left);
    }

    @Override
    public PyObject __neg__() {
        return int___neg__();
    }

    @ExposedMethod(doc = BuiltinDocs.int___neg___doc)
    final PyObject int___neg__() {
        long x = getValue();
        long result = -x;
        // check for overflow
        if (x < 0 && result == x) {
            return new PyLong(x).__neg__();
        }
        return Py.newInteger(result);
    }

    @Override
    public PyObject __pos__() {
        return int___pos__();
    }

    @ExposedMethod(doc = BuiltinDocs.int___pos___doc)
    final PyObject int___pos__() {
        return int___int__();
    }

    @Override
    public PyObject __abs__() {
        return int___abs__();
    }

    @ExposedMethod(doc = BuiltinDocs.int___abs___doc)
    final PyObject int___abs__() {
        if (getValue() < 0) {
            return int___neg__();
        }
        return int___int__();
    }

    @Override
    public PyObject __invert__() {
        return int___invert__();
    }

    @ExposedMethod(doc = BuiltinDocs.int___invert___doc)
    final PyObject int___invert__() {
        return Py.newInteger(~getValue());
    }

    @Override
    public PyObject __int__() {
        return int___int__();
    }

    @ExposedMethod(doc = BuiltinDocs.int___int___doc)
    final PyInteger int___int__() {
        return getType() == TYPE ? this : Py.newInteger(getValue());
    }

    @Override
    public PyObject __long__() {
        return int___long__();
    }

    @ExposedMethod(doc = BuiltinDocs.int___long___doc)
    final PyObject int___long__() {
        return new PyLong(getValue());
    }

    @Override
    public PyFloat __float__() {
        return int___float__();
    }

    @ExposedMethod(doc = BuiltinDocs.int___float___doc)
    final PyFloat int___float__() {
        return new PyFloat((double)getValue());
    }

    @Override
    public PyObject __trunc__() {
        return int___trunc__();
    }

    @ExposedMethod(doc = BuiltinDocs.int___trunc___doc)
    final PyObject int___trunc__() {
        return this;
    }

    @Override
    public PyObject conjugate() {
        return int_conjugate();
    }

    @ExposedMethod(doc = BuiltinDocs.int_conjugate_doc)
    final PyObject int_conjugate() {
        return this;
    }

    @Override
    public PyComplex __complex__() {
        return new PyComplex(getValue(), 0.);
    }

    @Override
    public PyString __oct__() {
        return int___oct__();
    }

    @ExposedMethod(doc = BuiltinDocs.int___oct___doc)
    final PyString int___oct__() {
        // Use the prepared format specifier for octal.
        return formatImpl(IntegerFormatter.OCT);
    }

    @Override
    public PyString __hex__() {
        return int___hex__();
    }

    @ExposedMethod(doc = BuiltinDocs.int___hex___doc)
    final PyString int___hex__() {
        // Use the prepared format specifier for hexadecimal.
        return formatImpl(IntegerFormatter.HEX);
    }

    /**
     * Common code used by the number-base conversion method __oct__ and __hex__.
     *
     * @param spec prepared format-specifier.
     * @return converted value of this object
     */
    private PyString formatImpl(Spec spec) {
        // Traditional formatter (%-format) because #o means "-0123" not "-0o123".
        IntegerFormatter f = new IntegerFormatter.Traditional(spec);
        f.format(value);
        return new PyString(f.getResult());
    }

    @ExposedMethod(doc = BuiltinDocs.int___getnewargs___doc)
    final PyTuple int___getnewargs__() {
        return new PyTuple(new PyObject[] {new PyInteger(this.getValue())});
    }

    @Override
    public PyTuple __getnewargs__() {
        return int___getnewargs__();
    }

    @Override
    public PyObject __index__() {
        return int___index__();
    }

    @ExposedMethod(doc = BuiltinDocs.int___index___doc)
    final PyObject int___index__() {
        return this;
    }

    @Override
    public int bit_length() {
        return int_bit_length();
    }

    @ExposedMethod(doc = BuiltinDocs.int_bit_length_doc)
    final int int_bit_length() {
        int v = value;
        if (v < 0) {
            v = -v;
        }
        return BigInteger.valueOf(v).bitLength();
    }

    @Override
    public PyObject __format__(PyObject formatSpec) {
        return int___format__(formatSpec);
    }

    @ExposedMethod(doc = BuiltinDocs.int___format___doc)
    final PyObject int___format__(PyObject formatSpec) {

        // Parse the specification
        Spec spec = InternalFormat.fromText(formatSpec, "__format__");
        InternalFormat.Formatter f;

        // Try to make an integer formatter from the specification
        IntegerFormatter fi = PyInteger.prepareFormatter(spec);
        if (fi != null) {
            // Bytes mode if formatSpec argument is not unicode.
            fi.setBytes(!(formatSpec instanceof PyUnicode));
            // Convert as per specification.
            fi.format(value);
            f = fi;

        } else {
            // Try to make a float formatter from the specification
            FloatFormatter ff = PyFloat.prepareFormatter(spec);
            if (ff != null) {
                // Bytes mode if formatSpec argument is not unicode.
                ff.setBytes(!(formatSpec instanceof PyUnicode));
                // Convert as per specification.
                ff.format(value);
                f = ff;

            } else {
                // The type code was not recognised in either prepareFormatter
                throw Formatter.unknownFormat(spec.type, "integer");
            }
        }

        // Return a result that has the same type (str or unicode) as the formatSpec argument.
        return f.pad().getPyResult();
    }

    /**
     * Common code for PyInteger     and PyLong to prepare an IntegerFormatter. This object has an
     * overloaded format method {@link IntegerFormatter#format(int)} and
     * {@link IntegerFormatter#format(BigInteger)} to support the two types.
     *
     * @param spec a parsed PEP-3101 format specification.
     * @return a formatter ready to use, or null if the type is not an integer format type.
     * @throws PyException {@code ValueError} if the specification is faulty.
     */
    @SuppressWarnings("fallthrough")
    static IntegerFormatter prepareFormatter(Spec spec) throws PyException {

        // Slight differences between format types
        switch (spec.type) {
            case 'c':
                // Character data: specific prohibitions.
                if (Spec.specified(spec.sign)) {
                    throw IntegerFormatter.signNotAllowed("integer", spec.type);
                } else if (spec.alternate) {
                    throw IntegerFormatter.alternateFormNotAllowed("integer", spec.type);
                }
                // Fall through

            case 'x':
            case 'X':
            case 'o':
            case 'b':
            case 'n':
                if (spec.grouping) {
                    throw IntegerFormatter.notAllowed("Grouping", "integer", spec.type);
                }
                // Fall through

            case Spec.NONE:
            case 'd':
                // Check for disallowed parts of the specification
                if (Spec.specified(spec.precision)) {
                    throw IntegerFormatter.precisionNotAllowed("integer");
                }
                // spec may be incomplete. The defaults are those commonly used for numeric formats.
                spec = spec.withDefaults(Spec.NUMERIC);
                // Get a formatter for the spec.
                return new IntegerFormatter(spec);

            default:
                return null;
        }
    }

    @Override
    public boolean isIndex() {
        return true;
    }

    @Override
    public int asIndex(PyObject err) {
        return getValue();
    }

    @Override
    public boolean isMappingType() {
        return false;
    }

    @Override
    public boolean isNumberType() {
        return true;
    }

    @Override
    public boolean isSequenceType() {
        return false;
    }

    @Override
    public long asLong(int index) {
        return getValue();
    }

    @Override
    public int asInt(int index) {
        return getValue();
    }

    @Override
    public int asInt() {
        return getValue();
    }

    @Override
    public long asLong() {
        return getValue();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy