From f1091f4cd6dd55e2317ee4a7e0cd6a605edd98b2 Mon Sep 17 00:00:00 2001 From: Marius Gerbershagen Date: Fri, 12 Dec 2025 22:37:12 +0100 Subject: [PATCH] expt: fix floating point contagion Examples of the bug (expt -1.4d0 #C(1 2)) -> #C(-0.0020444484 -0.0016295447) (expt #C(1.0 3.0) 0.0d0) -> #C(1.0 0.0) These return a (complex single-float), should be (complex double-float). The code incorrectly assumed that the numbers associated to the types tx and ty were ordered such that long floats and complex long floats have higher numbers than double floats and complex double floats. --- src/c/numbers/expt.d | 20 +++++++++++--------- src/tests/normal-tests/complex.lsp | 6 ++++++ 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/c/numbers/expt.d b/src/c/numbers/expt.d index 66b16276e..ea387faf3 100644 --- a/src/c/numbers/expt.d +++ b/src/c/numbers/expt.d @@ -80,8 +80,14 @@ expt_zero(cl_object x, cl_object y) return ecl_make_complex(z, ecl_make_fixnum(0)); #ifdef ECL_COMPLEX_FLOAT case t_csfloat: + if (tx == t_longfloat || ty == t_longfloat) + return clfloat_one; + if (tx == t_doublefloat || ty == t_doublefloat) + return cdfloat_one; return csfloat_one; case t_cdfloat: + if (tx == t_longfloat || ty == t_longfloat) + return clfloat_one; return cdfloat_one; case t_clfloat: return clfloat_one; @@ -149,21 +155,17 @@ ecl_expt_complex_float(cl_object x, cl_object y) { cl_object ret; ECL_MATHERR_CLEAR; - switch ((ty > tx)? ty : tx) { - case t_clfloat: - case t_longfloat: + if (tx == t_clfloat || tx == t_longfloat || + ty == t_clfloat || ty == t_longfloat) { ret = ecl_make_clfloat (cpowl(ecl_to_clfloat(x), ecl_to_clfloat(y))); - break; - case t_cdfloat: - case t_doublefloat: + } else if (tx == t_cdfloat || tx == t_doublefloat || + ty == t_cdfloat || ty == t_doublefloat) { ret = ecl_make_cdfloat (cpow (ecl_to_cdfloat(x), ecl_to_cdfloat(y))); - break; - default: + } else { ret = ecl_make_csfloat (cpowf(ecl_to_csfloat(x), ecl_to_csfloat(y))); - break; } ECL_MATHERR_TEST; return ret; diff --git a/src/tests/normal-tests/complex.lsp b/src/tests/normal-tests/complex.lsp index d2276acbc..2fd66b56e 100644 --- a/src/tests/normal-tests/complex.lsp +++ b/src/tests/normal-tests/complex.lsp @@ -304,3 +304,9 @@ ;; (test csfloat.0010.issue-547 (finishes (expt #c(1.0 0.0) 2)))) + +(test complex.0011.expt-float-contagion + (is (typep (expt -1.4d0 #C(1 2)) '(complex double-float))) + (is (typep (expt -1.4l0 #C(1 2)) '(complex long-float))) + (is (typep (expt #C(1.0 3.0) 0.0d0) '(complex double-float))) + (is (typep (expt #C(1.0 3.0) 0.0l0) '(complex long-float))))