From: Samuele P. <ped...@us...> - 2003-08-05 11:21:58
|
Update of /cvsroot/jython/jython/org/python/core In directory sc8-pr-cvs1:/tmp/cvs-serv20219/org/python/core Modified Files: PyLong.java Log Message: implemented coversion to double+scale, reimplemented true division for longs using it (like CPython) same for math.log/10 . test_long now passes, test_long_future also partially ( only partially because of buggy unrelated future flags inheritance - to fix). Index: PyLong.java =================================================================== RCS file: /cvsroot/jython/jython/org/python/core/PyLong.java,v retrieving revision 2.17 retrieving revision 2.18 diff -C2 -d -r2.17 -r2.18 *** PyLong.java 24 Dec 2002 16:52:16 -0000 2.17 --- PyLong.java 5 Aug 2003 11:21:52 -0000 2.18 *************** *** 57,61 **** return v; } ! private long getLong(long min, long max) { if (value.compareTo(maxLong) <= 0 && value.compareTo(minLong) >= 0) { --- 57,96 ---- 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) { *************** *** 214,221 **** } public PyObject __truediv__(PyObject right) { if (!canCoerce(right)) return null; ! return new PyFloat(doubleValue() / coerce(right).doubleValue()); } --- 249,284 ---- } + 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"); + + ad /= bd; + int aexp = ae[0]-be[0]; + + if (aexp > Integer.MAX_VALUE/8) { + throw Py.OverflowError("long/long too large for a float"); + } else if ( aexp < -(Integer.MAX_VALUE/8)) { + return new PyFloat(0.0); + } + + ad = ad * Math.pow(2.0, aexp*8); + + if (Double.isInfinite(ad)) { + throw Py.OverflowError("long/long too large for a float"); + } + + return new PyFloat(ad); + } + public PyObject __truediv__(PyObject right) { if (!canCoerce(right)) return null; ! return true_divide(this.value,coerce(right)); } *************** *** 223,227 **** if (!canCoerce(left)) return null; ! return new PyFloat(coerce(left).doubleValue() / doubleValue()); } --- 286,290 ---- if (!canCoerce(left)) return null; ! return true_divide(coerce(left),this.value); } |