mirror of
https://gitlab.com/embeddable-common-lisp/ecl.git
synced 2026-01-24 21:41:29 -08:00
numbers: fix several bugs in the expt function
-expt of an integer and rational lead to a wrong type error in ecl_expt_float -type contagion of (expt 0 +y) did not work properly -there were several useless type checks in places where previous function calls already ensured that objects were numbers Fixes #526.
This commit is contained in:
parent
a08f26cc27
commit
6ade6d4491
1 changed files with 8 additions and 14 deletions
|
|
@ -128,12 +128,9 @@ ecl_expt_float(cl_object x, cl_object y) {
|
|||
case t_doublefloat:
|
||||
return ecl_make_double_float
|
||||
(pow(ecl_to_double(x), ecl_to_double(y)));
|
||||
case t_singlefloat:
|
||||
default:
|
||||
return ecl_make_single_float
|
||||
(powf(ecl_to_float(x), ecl_to_float(y)));
|
||||
default:
|
||||
if (ty > tx) FEwrong_type_nth_arg(@[expt], 1, x, @[number]);
|
||||
else FEwrong_type_nth_arg(@[expt], 2, y, @[number]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -163,18 +160,11 @@ cl_object
|
|||
ecl_expt(cl_object x, cl_object y)
|
||||
{
|
||||
cl_type ty, tx;
|
||||
cl_object z;
|
||||
/* 0 ^ 0 -> 1 */
|
||||
if (ecl_unlikely(ecl_zerop(y))) {
|
||||
return expt_zero(x, y);
|
||||
}
|
||||
ty = ecl_t_of(y);
|
||||
tx = ecl_t_of(x);
|
||||
/* ty is already ensured to be a number by ecl_zerop above */
|
||||
if (ecl_unlikely(!ECL_NUMBER_TYPE_P(tx))) {
|
||||
FEwrong_type_nth_arg(@[expt], 1, x, @[number]);
|
||||
}
|
||||
if (ecl_zerop(x)) {
|
||||
if (ecl_unlikely(ecl_zerop(x))) {
|
||||
/* 0 ^ -y = (1/0)^y */
|
||||
if (!ecl_plusp(cl_realpart(y))) {
|
||||
/* Normally we would have signalled FEdivision_by_zero, but fpe
|
||||
|
|
@ -182,7 +172,8 @@ ecl_expt(cl_object x, cl_object y)
|
|||
return ecl_divide(ecl_make_fixnum(1), x);
|
||||
}
|
||||
/* 0 ^ +y = 0 */
|
||||
return x;
|
||||
/* We call ecl_times to ensure the most contagious type.*/
|
||||
return ecl_times(x, y);
|
||||
}
|
||||
/* Here comes the order in which we handle cases: */
|
||||
/* -----------------------------------FIRST IF--- */
|
||||
|
|
@ -196,6 +187,9 @@ ecl_expt(cl_object x, cl_object y)
|
|||
/* ---------------------------------THIRD ELSE--- */
|
||||
/* positive ^ number -> float */
|
||||
/* ---------------------------------------------- */
|
||||
/* x and y are already ensured to be a number by ecl_zerop above */
|
||||
ty = ecl_t_of(y);
|
||||
tx = ecl_t_of(x);
|
||||
if (ty == t_fixnum || ty == t_bignum) {
|
||||
switch (tx) {
|
||||
case t_fixnum:
|
||||
|
|
@ -216,7 +210,7 @@ ecl_expt(cl_object x, cl_object y)
|
|||
return ecl_expt_complex_float(x, y);
|
||||
#else
|
||||
/* We call expt_zero to ensure the most contagious type.*/
|
||||
z = ecl_log1(ecl_times(x, expt_zero(x, y)));
|
||||
cl_object z = ecl_log1(ecl_times(x, expt_zero(x, y)));
|
||||
z = ecl_times(z, y);
|
||||
z = ecl_exp(z);
|
||||
return z;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue