klisp

an open source interpreter for the Kernel Programming Language.
git clone http://git.hanabi.in/repos/klisp.git
Log | Files | Refs | README

commit 0afe15922ebf0a87b04513f39bbc57b6ee5f7a17
parent 70e87112d3aa47380efff102729ce317139072c7
Author: Andres Navarro <canavarro82@gmail.com>
Date:   Wed,  6 Apr 2011 11:43:59 -0300

Bugfix: lcm with only 1 or more than 2 arguments was nonsense. It was computing the gcd of all numbers and dividing by that, instead of just doing lcm two at a time.

Diffstat:
Msrc/kgnumbers.c | 31++++++++-----------------------
1 file changed, 8 insertions(+), 23 deletions(-)

diff --git a/src/kgnumbers.c b/src/kgnumbers.c @@ -749,14 +749,13 @@ void klcm(klisp_State *K, TValue *xparams, TValue ptree, TValue denv) int32_t dummy; /* don't care about count of cycle pairs */ int32_t pairs = check_typed_list(K, "lcm", "number", knumberp, true, ptree, &dummy); - /* we will need to loop again after obtaining the gcd */ - int32_t saved_pairs = pairs; - - TValue res = i2tv(1); /* report: (lcm) = 1 */ + /* lcm is +infinite if there is any infinite number, must still loop to check for zero but returns #e+infinty */ bool seen_infinite = false; - int32_t finite_gcd = 0; + + /* report: this will cover the case of (lcm) = 1 */ + int32_t finite_lcm = 1; TValue tail = ptree; while(pairs--) { @@ -764,31 +763,17 @@ void klcm(klisp_State *K, TValue *xparams, TValue ptree, TValue denv) tail = kcdr(tail); if (ttiseinf(first)) { seen_infinite = true; - res = KEPINF; /* report */ } else if (kfast_zerop(first)) { klispE_throw(K, "lcm: result has no primary"); return; } else if (!seen_infinite) { - finite_gcd = (int32_t) kgcd32_64(finite_gcd, ivalue(first)); + finite_lcm = (int32_t) klcm32_64(finite_lcm, ivalue(first)); } } - if (!seen_infinite && saved_pairs) { - /* now collect the lcm proper, there are no zero and no infinities, - finite_gcd can't be zero because there are at least one finite, - non-zero number */ - tail = ptree; - pairs = saved_pairs; - int32_t lcm = 1; - while(pairs--) { - TValue first = kcar(tail); - tail = kcdr(tail); - int32_t first_i = ivalue(first); - /* no remainder */ - lcm *= (first_i < 0? -first_i : first_i) / finite_gcd; - } - res = i2tv(lcm); - } + /* according to the report, if there is any infinite res is #e+infinity */ + TValue res = seen_infinite? KEPINF : i2tv(finite_lcm); + kapply_cc(K, res); }