[Jython-checkins] jython: as_integer_ratio implementation.

frank.wierzbicki jython-checkins at python.org
Thu Apr 5 03:36:07 CEST 2012


http://hg.python.org/jython/rev/ef7876da994f
changeset:   6534:ef7876da994f
user:        Frank Wierzbicki <fwierzbicki at gmail.com>
date:        Wed Apr 04 18:35:54 2012 -0700
summary:
  as_integer_ratio implementation.

files:
  src/org/python/core/PyFloat.java |  32 ++++++++++++++++++++
  1 files changed, 32 insertions(+), 0 deletions(-)


diff --git a/src/org/python/core/PyFloat.java b/src/org/python/core/PyFloat.java
--- a/src/org/python/core/PyFloat.java
+++ b/src/org/python/core/PyFloat.java
@@ -7,6 +7,7 @@
 import org.python.core.stringlib.Formatter;
 import org.python.core.stringlib.InternalFormatSpec;
 import org.python.core.stringlib.InternalFormatSpecParser;
+import org.python.modules.math;
 import java.io.Serializable;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
@@ -892,6 +893,37 @@
         return formatSpecStr.createInstance(result);
     }
 
+    @ExposedMethod(doc = BuiltinDocs.float_as_integer_ratio_doc)
+    public PyTuple as_integer_ratio() {
+        if (Double.isInfinite(value)) {
+            throw Py.OverflowError("Cannot pass infinity to float.as_integer_ratio.");
+        }
+        if (Double.isNaN(value)) {
+            throw Py.ValueError("Cannot pass NaN to float.as_integer_ratio.");
+        }
+        PyTuple frexp = math.frexp(value);
+        double float_part = ((Double)frexp.get(0)).doubleValue();
+        int exponent = ((Integer)frexp.get(1)).intValue();
+        for (int i=0; i<300 && float_part != Math.floor(float_part); i++) {
+            float_part *= 2.0;
+            exponent--;
+        }
+        /* self == float_part * 2**exponent exactly and float_part is integral.
+           If FLT_RADIX != 2, the 300 steps may leave a tiny fractional part
+           to be truncated by PyLong_FromDouble(). */
+        
+        PyLong numerator = new PyLong(float_part);
+        PyLong denominator = new PyLong(1);
+        PyLong py_exponent = new PyLong(Math.abs(exponent));
+        py_exponent = (PyLong)denominator.__lshift__(py_exponent);
+        if (exponent > 0) {
+            numerator = new PyLong(numerator.getValue().multiply(py_exponent.getValue()));
+        } else {
+            denominator = py_exponent;
+        }
+        return new PyTuple(numerator, denominator);
+    }
+
     @Override
     public double asDouble() {
         return getValue();

-- 
Repository URL: http://hg.python.org/jython


More information about the Jython-checkins mailing list