Skip to content

Conversation

@jpellegrini
Copy link
Contributor

@jpellegrini jpellegrini commented Nov 30, 2025

The algorithm used in GCD is Euclid's. Since R5RS requires it for several arguments, and Sigscheme implements other variable-length procedures as folds, this implementation follows that. Basically,

(gcd a1 a2 a3 ...)

is implemented as

(fold 0 %gcd2 '(a1 a2 a3 ...))

Here, "fold" does not exist - it's written in C, in a similar fashion to other functions (+, /, * etc), and "%gcd2" is a static C function.

LCM is implemented as usual using the GCD.

src/number.c Outdated
Comment on lines 436 to 437
/* BEGIN code for computing gcd of two numbers
result = GCD(result, right); */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need this comment?

This is only the main computation part. So I feel that this is redundant.

src/number.c Outdated
Comment on lines 439 to 450
n1 = result;
n2 = SCM_INT_VALUE(right);

if (n1 < 0) n1 = - n1;
if (n2 < 0) n2 = - n2;

while (n1 != 0) {
tmp = n1;
n1 = n2 % n1;
n2 = tmp;
}
result = n2;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you use spaces instead of tab for indent?

(assert-equal? (tn) 1 (gcd 20 1))
(assert-equal? (tn) 4 (gcd 8 20 32))
(tn "lcm")
(assert-equal? (tn) 288 (gcd 32 -36))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
(assert-equal? (tn) 288 (gcd 32 -36))
(assert-equal? (tn) 288 (lcm 32 -36))

src/number.c Outdated
Comment on lines 442 to 443
if (n1 < 0) n1 = - n1;
if (n2 < 0) n2 = - n2;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (n1 < 0) n1 = - n1;
if (n2 < 0) n2 = - n2;
if (n1 < 0) n1 = -n1;
if (n2 < 0) n2 = -n2;

src/number.c Outdated
Comment on lines 485 to 486
if (n1 < 0) n1 = - n1;
if (n2 < 0) n2 = - n2;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (n1 < 0) n1 = - n1;
if (n2 < 0) n2 = - n2;
if (n1 < 0) n1 = -n1;
if (n2 < 0) n2 = -n2;

src/number.c Outdated
Comment on lines 485 to 495
if (n1 < 0) n1 = - n1;
if (n2 < 0) n2 = - n2;

big = n1 > n2 ? n1 : n2;
small = n1 < n2 ? n1 : n2;
n1 = big;

while (n1 % small != 0)
n1 += big;

result = n1;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about defining static scm_int_t gcd(scm_int_t x, scm_int_t y) and using it in scm_p_gcd() and scm_p_lcm()?

@jpellegrini
Copy link
Contributor Author

I believe all issues are dealt with. Please tell me if there is anything else to be changed.

src/number.c Outdated
SCM_EXPORT ScmObj
scm_p_lcm(ScmObj left, ScmObj right, enum ScmReductionState *state)
{
scm_int_t result, big, small, n1, n2;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to update this.

Could you enable GitHub Actions on your fork so that you can check CI results on your fork?

src/number.c Outdated
case SCM_REDUCE_1:
ENSURE_INT(right);
result *= SCM_INT_VALUE(right) / gcd(result, SCM_INT_VALUE(right));
/* Fall through. */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you use spaces not tab?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Copy link
Member

@kou kou left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you update the PR description before we merge this?

We'll use the PR description as commit message.

src/number.c Outdated
default:
SCM_NOTREACHED;
}
if (result < 0) result = -result;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we move this abs() to gcd()?

I think that, in general, GCD algorithm assumes that both of inputs are non-neagtive.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes but then, for each binary gcd() called, abs will be done (instead of just once after the n-ary GCD). Also, the abs is still necessary at the end of LCM, since the variable right can be negative in each iteration. Anyway, I will do that.

x = y % x;
y = tmp;
}
return (y >= 0) ? y : -y;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm. Could you add a comment why we use this approach if we want to use this instead of the following? Because the following is the standard implementation and this implementation isn't the standard implementation.

static scm_int_t gcd(scm_int_t x, scm_int_t y)
{
    scm_int_t tmp;
    if (x < 0)
        x = -x;
    if (y < 0)
        y = -y;
    while (x != 0) {
        tmp = x;
        x = y % x;
        y = tmp;
    }
    return y;
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure - done!

@kou
Copy link
Member

kou commented Dec 1, 2025

Could you rebase on master and resolve conflict?

The algorithm used in GCD is Euclid's. Since R5RS requires it for
several arguments, and Sigscheme implements other variable-length
procedures as folds, this implementation follows that. Basically,

(gcd a1 a2 a3 ...)

is implemented as

(fold 0 %gcd2 '(a1 a2 a3 ...))

Here, "fold" does not exist - it's written in C, in a similar
fashion to other functions (+, /, * etc), and "%gcd2" is a
static C function.

LCM is implemented as usual using the GCD.
@jpellegrini
Copy link
Contributor Author

Could you rebase on master and resolve conflict?

Done!

@kou kou merged commit 46f1de4 into uim:main Dec 1, 2025
4 checks passed
@kou
Copy link
Member

kou commented Dec 1, 2025

Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants