Skip to content

Commit 53b04bd

Browse files
committed
FEAT: new lcm native for resolving the least common multiple of two integers
1 parent 12794b3 commit 53b04bd

File tree

3 files changed

+55
-14
lines changed

3 files changed

+55
-14
lines changed

src/core/n-math.c

+17-8
Original file line numberDiff line numberDiff line change
@@ -933,19 +933,28 @@ enum {SINE, COSINE, TANGENT};
933933
*/ REBNATIVE(gcd)
934934
/*
935935
// gcd: native [
936-
// {Returns greatest common divisor}
936+
// {Returns the greatest common divisor}
937937
// a [integer!]
938938
// b [integer!]
939939
// ]
940940
***********************************************************************/
941941
{
942-
REBINT a = VAL_INT64(D_ARG(1));
943-
REBINT b = VAL_INT64(D_ARG(2));
942+
SET_INTEGER(D_RET, Gcd(VAL_INT64(D_ARG(1)), VAL_INT64(D_ARG(2))));
943+
return R_RET;
944+
}
944945

945-
// Euclid's algorithm
946-
if (a < 0) a = -a;
947-
if (b < 0) b = -b;
948-
if (b) while ((a %= b) && (b %= a));
949-
SET_INTEGER(D_RET, a + b);
946+
/***********************************************************************
947+
**
948+
*/ REBNATIVE(lcm)
949+
/*
950+
// lcm: native [
951+
// {Returns the least common multiple}
952+
// a [integer!]
953+
// b [integer!]
954+
// ]
955+
***********************************************************************/
956+
{
957+
SET_INTEGER(D_RET, Lcm(VAL_INT64(D_ARG(1)), VAL_INT64(D_ARG(2))));
950958
return R_RET;
951959
}
960+

src/core/t-integer.c

+25
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,31 @@
4343
return (VAL_INT64(a) > VAL_INT64(b));
4444
}
4545

46+
/***********************************************************************
47+
**
48+
*/ REBINT Gcd(REBINT a, REBINT b)
49+
/*
50+
** Greatest common divisor (Euclid's algorithm)
51+
**
52+
***********************************************************************/
53+
{
54+
if (a < 0) a = -a;
55+
if (b < 0) b = -b;
56+
if (b) while ((a %= b) && (b %= a));
57+
return a + b;
58+
}
59+
60+
/***********************************************************************
61+
**
62+
*/ REBINT Lcm(REBINT a, REBINT b)
63+
/*
64+
** Least common multiple
65+
***********************************************************************/
66+
{
67+
if (a == 0 && b == 0) return 0;
68+
return a / Gcd(a, b) * b;
69+
}
70+
4671

4772
/***********************************************************************
4873
**

src/tests/units/integer-test.r3

+13-6
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,20 @@ Rebol [
6161
===end-group===
6262

6363

64-
===start-group=== "gcd"
64+
===start-group=== "gcd/lcm"
6565
--test-- "gcd"
66-
--assert 6 = gcd 54 24
67-
--assert 6 = gcd 24 54
68-
--assert 3 = gcd 0 3
69-
--assert 3 = gcd 3 0
70-
--assert 3 = gcd 21 -48
66+
--assert 6 = gcd 54 24
67+
--assert 6 = gcd 24 54
68+
--assert 3 = gcd 0 3
69+
--assert 3 = gcd 3 0
70+
--assert 3 = gcd 21 -48
71+
--test-- "lcm"
72+
--assert 36 = lcm 12 18
73+
--assert 36 = lcm 18 12
74+
--assert 0 = lcm 0 1
75+
--assert 0 = lcm 1 0
76+
--assert 0 = lcm 0 0
77+
7178
===end-group===
7279

7380

0 commit comments

Comments
 (0)