📄 pylong.java
字号:
// Copyright (c) Corporation for National Research Initiativespackage org.python.core;import java.math.BigInteger;import java.io.Serializable;/** * A builtin python long. This is implemented as a * java.math.BigInteger. */public class PyLong extends PyObject{ private static final BigInteger minLong = BigInteger.valueOf(Long.MIN_VALUE); private static final BigInteger maxLong = BigInteger.valueOf(Long.MAX_VALUE); private static final BigInteger minDouble = new java.math.BigDecimal(Double.MIN_VALUE).toBigInteger(); private static final BigInteger maxDouble = new java.math.BigDecimal(Double.MAX_VALUE).toBigInteger(); private java.math.BigInteger value; public PyLong(java.math.BigInteger v) { value = v; } public PyLong(double v) { this(new java.math.BigDecimal(v).toBigInteger()); } public PyLong(long v) { this(java.math.BigInteger.valueOf(v)); } public PyLong(String s) { this(new java.math.BigInteger(s)); } public String toString() { return value.toString()+"L"; } public int hashCode() { // Probably won't work well for some classes of keys... return value.intValue(); } public boolean __nonzero__() { return !value.equals(java.math.BigInteger.valueOf(0)); } public double doubleValue() { double v = value.doubleValue(); if (v == Double.NEGATIVE_INFINITY || v == Double.POSITIVE_INFINITY) { throw Py.OverflowError("long int too long to convert"); } return v; } private static final double scaledDoubleValue(BigInteger val, int[] exp){ double x = 0; int signum = val.signum(); byte[] digits; if (signum >= 0) { digits = val.toByteArray(); } else { digits = val.negate().toByteArray(); } int count = 8; int i = 0; if (digits[0] == 0) { i++; count++; } count = count <= digits.length?count:digits.length; while (i < count) { x = x * 256 + (digits[i] & 0xff); i++; } exp[0] = digits.length - i; return signum*x; } public double scaledDoubleValue(int[] exp){ return scaledDoubleValue(value,exp); } private long getLong(long min, long max) { if (value.compareTo(maxLong) <= 0 && value.compareTo(minLong) >= 0) { long v = value.longValue(); if (v >= min && v <= max) return v; } throw Py.OverflowError("long int too long to convert"); } public Object __tojava__(Class c) { try { if (c == Byte.TYPE || c == Byte.class) { return new Byte((byte)getLong(Byte.MIN_VALUE, Byte.MAX_VALUE)); } if (c == Short.TYPE || c == Short.class) { return new Short((short)getLong(Short.MIN_VALUE, Short.MAX_VALUE)); } if (c == Integer.TYPE || c == Integer.class) { return new Integer((int)getLong(Integer.MIN_VALUE, Integer.MAX_VALUE)); } if (c == Long.TYPE || c == Long.class) { return new Long(getLong(Long.MIN_VALUE, Long.MAX_VALUE)); } if (c == Float.TYPE || c == Double.TYPE || c == Float.class || c == Double.class) { return __float__().__tojava__(c); } if (c == BigInteger.class || c == Number.class || c == Object.class || c == Serializable.class) { return value; } } catch (PyException e) { return Py.NoConversion; } return super.__tojava__(c); } public int __cmp__(PyObject other) { return value.compareTo(((PyLong)other).value); } public Object __coerce_ex__(PyObject other) { if (other instanceof PyLong) return other; else if (other instanceof PyInteger) { return new PyLong(((PyInteger)other).getValue()); } else { return Py.None; } } private static final boolean canCoerce(PyObject other) { return other instanceof PyLong || other instanceof PyInteger; } private static final BigInteger coerce(PyObject other) { if (other instanceof PyLong) return ((PyLong) other).value; else if (other instanceof PyInteger) return java.math.BigInteger.valueOf( ((PyInteger) other).getValue()); else throw Py.TypeError("xxx"); } public PyObject __add__(PyObject right) { if (!canCoerce(right)) return null; return new PyLong(value.add(coerce(right))); } public PyObject __radd__(PyObject left) { return __add__(left); } public PyObject __sub__(PyObject right) { if (!canCoerce(right)) return null; return new PyLong(value.subtract(coerce(right))); } public PyObject __rsub__(PyObject left) { return new PyLong(coerce(left).subtract(value)); } public PyObject __mul__(PyObject right) { if (right instanceof PySequence) return ((PySequence) right).repeat(coerceInt(this)); if (!canCoerce(right)) return null; return new PyLong(value.multiply(coerce(right))); } public PyObject __rmul__(PyObject left) { if (left instanceof PySequence) return ((PySequence) left).repeat(coerceInt(this)); if (!canCoerce(left)) return null; return new PyLong(coerce(left).multiply(value)); } // Getting signs correct for integer division // This convention makes sense when you consider it in tandem with modulo private BigInteger divide(BigInteger x, BigInteger y) { BigInteger zero = java.math.BigInteger.valueOf(0); if (y.equals(zero)) throw Py.ZeroDivisionError("long division or modulo"); if (y.compareTo(zero) < 0) { if (x.compareTo(zero) > 0) return (x.subtract(y).subtract( BigInteger.valueOf(1))).divide(y); } else { if (x.compareTo(zero) < 0) return (x.subtract(y).add(BigInteger.valueOf(1))).divide(y); } return x.divide(y); } public PyObject __div__(PyObject right) { if (!canCoerce(right)) return null; if (Options.divisionWarning > 0) Py.warning(Py.DeprecationWarning, "classic long division"); return new PyLong(divide(value, coerce(right))); } public PyObject __rdiv__(PyObject left) { if (!canCoerce(left)) return null; if (Options.divisionWarning > 0) Py.warning(Py.DeprecationWarning, "classic long division"); return new PyLong(divide(coerce(left), value)); } public PyObject __floordiv__(PyObject right) { if (!canCoerce(right)) return null; return new PyLong(divide(value, coerce(right))); } public PyObject __rfloordiv__(PyObject left) { if (!canCoerce(left)) return null; return new PyLong(divide(coerce(left), value)); } private static final PyFloat true_divide(BigInteger a,BigInteger b) { int[] ae = new int[1]; int[] be = new int[1]; double ad,bd; ad = scaledDoubleValue(a,ae); bd = scaledDoubleValue(b,be); if (bd == 0 ) throw Py.ZeroDivisionError("long division or modulo");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -