Skip to content

Commit

Permalink
FEAT: new lcm native for resolving the least common multiple of two…
Browse files Browse the repository at this point in the history
… integers
  • Loading branch information
Oldes committed Dec 10, 2021
1 parent 12794b3 commit 53b04bd
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 14 deletions.
25 changes: 17 additions & 8 deletions src/core/n-math.c
Original file line number Diff line number Diff line change
Expand Up @@ -933,19 +933,28 @@ enum {SINE, COSINE, TANGENT};
*/ REBNATIVE(gcd)
/*
// gcd: native [
// {Returns greatest common divisor}
// {Returns the greatest common divisor}
// a [integer!]
// b [integer!]
// ]
***********************************************************************/
{
REBINT a = VAL_INT64(D_ARG(1));
REBINT b = VAL_INT64(D_ARG(2));
SET_INTEGER(D_RET, Gcd(VAL_INT64(D_ARG(1)), VAL_INT64(D_ARG(2))));
return R_RET;
}

// Euclid's algorithm
if (a < 0) a = -a;
if (b < 0) b = -b;
if (b) while ((a %= b) && (b %= a));
SET_INTEGER(D_RET, a + b);
/***********************************************************************
**
*/ REBNATIVE(lcm)
/*
// lcm: native [
// {Returns the least common multiple}
// a [integer!]
// b [integer!]
// ]
***********************************************************************/
{
SET_INTEGER(D_RET, Lcm(VAL_INT64(D_ARG(1)), VAL_INT64(D_ARG(2))));
return R_RET;
}

25 changes: 25 additions & 0 deletions src/core/t-integer.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,31 @@
return (VAL_INT64(a) > VAL_INT64(b));
}

/***********************************************************************
**
*/ REBINT Gcd(REBINT a, REBINT b)
/*
** Greatest common divisor (Euclid's algorithm)
**
***********************************************************************/
{
if (a < 0) a = -a;
if (b < 0) b = -b;
if (b) while ((a %= b) && (b %= a));
return a + b;
}

/***********************************************************************
**
*/ REBINT Lcm(REBINT a, REBINT b)
/*
** Least common multiple
***********************************************************************/
{
if (a == 0 && b == 0) return 0;
return a / Gcd(a, b) * b;
}


/***********************************************************************
**
Expand Down
19 changes: 13 additions & 6 deletions src/tests/units/integer-test.r3
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,20 @@ Rebol [
===end-group===


===start-group=== "gcd"
===start-group=== "gcd/lcm"
--test-- "gcd"
--assert 6 = gcd 54 24
--assert 6 = gcd 24 54
--assert 3 = gcd 0 3
--assert 3 = gcd 3 0
--assert 3 = gcd 21 -48
--assert 6 = gcd 54 24
--assert 6 = gcd 24 54
--assert 3 = gcd 0 3
--assert 3 = gcd 3 0
--assert 3 = gcd 21 -48
--test-- "lcm"
--assert 36 = lcm 12 18
--assert 36 = lcm 18 12
--assert 0 = lcm 0 1
--assert 0 = lcm 1 0
--assert 0 = lcm 0 0

===end-group===


Expand Down

0 comments on commit 53b04bd

Please sign in to comment.