mirror of
https://github.com/lcn2/calc.git
synced 2025-08-16 01:03:29 +03:00
Converted all ASCII tabs to ASCII spaces using a 8 character tab stop, for all files, except for all Makefiles (plus rpm.mk). The `git diff -w` reports no changes.
162 lines
4.6 KiB
C
162 lines
4.6 KiB
C
/*
|
|
* poly - polynomial functions
|
|
*
|
|
* Copyright (C) 1999,2021,2023 Ernest Bowen and Landon Curt Noll
|
|
*
|
|
* Primary author: Ernest Bowen
|
|
*
|
|
* Calc is open software; you can redistribute it and/or modify it under
|
|
* the terms of the version 2.1 of the GNU Lesser General Public License
|
|
* as published by the Free Software Foundation.
|
|
*
|
|
* Calc is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
|
|
* Public License for more details.
|
|
*
|
|
* A copy of version 2.1 of the GNU Lesser General Public License is
|
|
* distributed with calc under the filename COPYING-LGPL. You should have
|
|
* received a copy with calc; if not, write to Free Software Foundation, Inc.
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*
|
|
* Under source code control: 1995/12/02 03:10:28
|
|
* File existed as early as: 1995
|
|
*
|
|
* chongo <was here> /\oo/\ http://www.isthe.com/chongo/
|
|
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
|
|
*/
|
|
|
|
|
|
#include "value.h"
|
|
|
|
|
|
#include "banned.h" /* include after system header <> includes */
|
|
|
|
|
|
bool
|
|
evp(LISTELEM *cp, LISTELEM *x, VALUE *vres)
|
|
{
|
|
VALUE v, tmp1, tmp2;
|
|
bool s;
|
|
|
|
s = false;
|
|
while (cp) {
|
|
if (s) {
|
|
mulvalue(vres, &x->e_value, &tmp1);
|
|
freevalue(vres);
|
|
*vres = tmp1;
|
|
}
|
|
v = cp->e_value;
|
|
if (v.v_type == V_LIST) {
|
|
if (evalpoly(v.v_list, x->e_next, &tmp1)) {
|
|
if (s) {
|
|
addvalue(&tmp1, vres, &tmp2);
|
|
freevalue(&tmp1);
|
|
freevalue(vres);
|
|
*vres = tmp2;
|
|
} else {
|
|
s = true;
|
|
*vres = tmp1;
|
|
}
|
|
}
|
|
} else {
|
|
if (s) {
|
|
addvalue(&v, vres, &tmp1);
|
|
freevalue(vres);
|
|
*vres = tmp1;
|
|
} else {
|
|
s = true;
|
|
copyvalue(&v, vres);
|
|
}
|
|
}
|
|
cp = cp->e_prev;
|
|
}
|
|
return s;
|
|
}
|
|
|
|
|
|
bool
|
|
evalpoly(LIST *clist, LISTELEM *x, VALUE *vres)
|
|
{
|
|
LISTELEM *cp;
|
|
VALUE v;
|
|
|
|
cp = clist->l_first;
|
|
if (cp == NULL)
|
|
return false;
|
|
if (x == NULL) {
|
|
v = cp->e_value;
|
|
if (v.v_type == V_LIST)
|
|
return evalpoly(v.v_list, x->e_next, vres);
|
|
copyvalue(&v, vres);
|
|
return true;
|
|
}
|
|
return evp(clist->l_last, x, vres);
|
|
}
|
|
|
|
void
|
|
insertitems(LIST *lp1, LIST *lp2)
|
|
{
|
|
LISTELEM *ep;
|
|
|
|
for (ep = lp2->l_first; ep; ep = ep->e_next) {
|
|
if (ep->e_value.v_type == V_LIST)
|
|
insertitems(lp1, ep->e_value.v_list);
|
|
else
|
|
insertlistlast(lp1, &ep->e_value);
|
|
}
|
|
}
|
|
|
|
|
|
long
|
|
countlistitems(LIST *lp)
|
|
{
|
|
LISTELEM *ep;
|
|
|
|
long n = 0;
|
|
for (ep = lp->l_first; ep; ep = ep->e_next) {
|
|
if (ep->e_value.v_type == V_LIST)
|
|
n += countlistitems(ep->e_value.v_list);
|
|
else
|
|
n++;
|
|
}
|
|
return n;
|
|
}
|
|
|
|
|
|
void
|
|
addlistitems(LIST *lp, VALUE *vres)
|
|
{
|
|
LISTELEM *ep;
|
|
VALUE tmp;
|
|
|
|
for (ep = lp->l_first; ep; ep = ep->e_next) {
|
|
addvalue(vres, &ep->e_value, &tmp);
|
|
freevalue(vres);
|
|
*vres = tmp;
|
|
if (vres->v_type < 0)
|
|
return;
|
|
}
|
|
}
|
|
|
|
void
|
|
addlistinv(LIST *lp, VALUE *vres)
|
|
{
|
|
LISTELEM *ep;
|
|
VALUE tmp1, tmp2;
|
|
|
|
for (ep = lp->l_first; ep; ep = ep->e_next) {
|
|
if (ep->e_value.v_type == V_LIST) {
|
|
addlistinv(ep->e_value.v_list, vres);
|
|
} else {
|
|
invertvalue(&ep->e_value, &tmp1);
|
|
addvalue(vres, &tmp1, &tmp2);
|
|
freevalue(&tmp1);
|
|
freevalue(vres);
|
|
*vres = tmp2;
|
|
}
|
|
if (vres->v_type < 0)
|
|
return;
|
|
}
|
|
}
|