[armedbear-cvs] r12940 - trunk/abcl/src/org/armedbear/lisp
Erik Huelsmann
ehuelsmann at common-lisp.net
Sat Oct 2 21:39:53 UTC 2010
Author: ehuelsmann
Date: Sat Oct 2 17:39:52 2010
New Revision: 12940
Log:
Fix loss of precision in (expt <non-double> <complex-double>),
fixes last Maxima failure.
Modified:
trunk/abcl/src/org/armedbear/lisp/Complex.java
trunk/abcl/src/org/armedbear/lisp/MathFunctions.java
Modified: trunk/abcl/src/org/armedbear/lisp/Complex.java
==============================================================================
--- trunk/abcl/src/org/armedbear/lisp/Complex.java (original)
+++ trunk/abcl/src/org/armedbear/lisp/Complex.java Sat Oct 2 17:39:52 2010
@@ -80,6 +80,15 @@
return imagpart;
}
+ /** Coerces the complex parts into DoubleFloats
+ *
+ * @return a new complex with double-float real and imaginary parts
+ */
+ public LispObject coerceToDoubleFloat() {
+ return getInstance(DoubleFloat.coerceToFloat(realpart),
+ DoubleFloat.coerceToFloat(imagpart));
+ }
+
@Override
public LispObject typeOf()
{
Modified: trunk/abcl/src/org/armedbear/lisp/MathFunctions.java
==============================================================================
--- trunk/abcl/src/org/armedbear/lisp/MathFunctions.java (original)
+++ trunk/abcl/src/org/armedbear/lisp/MathFunctions.java Sat Oct 2 17:39:52 2010
@@ -623,6 +623,34 @@
}
// for anything not a rational or complex rational, use
// float approximation.
+ boolean wantDoubleFloat = false;
+ if (base instanceof DoubleFloat)
+ wantDoubleFloat = true;
+ else if (power instanceof DoubleFloat)
+ wantDoubleFloat = true;
+ else if (base instanceof Complex
+ && (((Complex)base).getRealPart() instanceof DoubleFloat
+ || ((Complex)base).getImaginaryPart() instanceof DoubleFloat))
+ wantDoubleFloat = true;
+ else if (power instanceof Complex
+ && (((Complex)power).getRealPart() instanceof DoubleFloat
+ || ((Complex)power).getImaginaryPart() instanceof DoubleFloat))
+ wantDoubleFloat = true;
+
+ if (wantDoubleFloat) {
+ if (power instanceof Complex)
+ power = ((Complex)power).coerceToDoubleFloat();
+ else
+ power = DoubleFloat.coerceToFloat(power);
+
+ if (base instanceof Complex)
+ base = ((Complex)base).coerceToDoubleFloat();
+ else
+ base = DoubleFloat.coerceToFloat(base);
+ }
+
+
+
if (base instanceof Complex || power instanceof Complex)
return exp(power.multiplyBy(log(base)));
final double x; // base
More information about the armedbear-cvs
mailing list