•math.GCD and •math.LCM for u64 arguments

This commit is contained in:
Marshall Lochbaum 2022-11-22 16:47:53 -05:00
parent 49636bae79
commit 51840bc853
4 changed files with 42 additions and 4 deletions

View File

@ -17,7 +17,7 @@
/*internal.c*/M(itype,"•internal.Type") M(elType,"•internal.ElType") M(refc,"•internal.Refc") M(isPure,"•internal.IsPure") A(info,"•internal.Info") M(heapDump,"•internal.HeapDump") \
/*internal.c*/M(squeeze,"•internal.Squeeze") M(deepSqueeze,"•internal.DeepSqueeze") D(eequal,"•internal.EEqual") A(internalTemp,"•internal.Temp") \
/*internal.c*/D(variation,"•internal.Variation") A(listVariations,"•internal.ListVariations") M(clearRefs,"•internal.ClearRefs") M(unshare,"•internal.Unshare") \
/* arithm.c*/M(sin,"•math.Sin") M(cos,"•math.Cos") M(tan,"•math.Tan") M(asin,"•math.Asin") M(acos,"•math.Acos") M(atan,"•math.Atan") D(atan2,"•math.Atan2")
/* arithm.c*/M(sin,"•math.Sin") M(cos,"•math.Cos") M(tan,"•math.Tan") M(asin,"•math.Asin") M(acos,"•math.Acos") M(atan,"•math.Atan") D(atan2,"•math.Atan2") D(gcd,"•math.GCD") D(lcm,"•math.LCM")
#define FOR_PM1(A,M,D) \
/*md1.c*/A(tbl,"") A(each,"¨") A(fold,"´") A(scan,"`") A(const,"˙") A(swap,"˜") A(cell,"˘") A(insert,"˝") \

View File

@ -366,4 +366,42 @@ B atan2_c2(B t, B w, B x) {
thrM("•math.Atan2: Unexpected argument types");
}
static u64 gcd_u64(u64 a, u64 b) {
if (a == 0) return b;
if (b == 0) return a;
u8 az = CTZ(a);
u8 bz = CTZ(b);
u8 sh = az<bz? az : bz;
b >>= bz;
while (a > 0) {
a >>= az;
u64 d = b - a;
az = CTZ(d);
b = b<a? b : a;
a = b<a? -d : d;
}
return b << sh;
}
static u64 lcm_u64(u64 a, u64 b) {
if (a==0 | b==0) return 0;
return (a / gcd_u64(a, b)) * b;
}
B gcd_c2(B t, B w, B x) {
if (isNum(w) && isNum(x)) {
if (!q_u64(w) || !q_u64(x)) thrM("•math.GCD: Inputs other than natural numbers not yet supported");
return m_f64(gcd_u64(o2u64G(w), o2u64G(x)));
}
P2(gcd)
thrM("•math.GCD: Unexpected argument types");
}
B lcm_c2(B t, B w, B x) {
if (isNum(w) && isNum(x)) {
if (!q_u64(w) || !q_u64(x)) thrM("•math.LCM: Inputs other than natural numbers not yet supported");
return m_f64(lcm_u64(o2u64G(w), o2u64G(x)));
}
P2(gcd)
thrM("•math.GCD: Unexpected argument types");
}
#undef P2

View File

@ -109,8 +109,8 @@ static B mathNS;
B getMathNS() {
if (mathNS.u == 0) {
#define F(X) inc(bi_##X),
Body* d = m_nnsDesc("sin","cos","tan","asin","acos","atan","atan2");
mathNS = m_nns(d, F(sin)F(cos)F(tan)F(asin)F(acos)F(atan)F(atan2));
Body* d = m_nnsDesc("sin","cos","tan","asin","acos","atan","atan2","gcd","lcm");
mathNS = m_nns(d, F(sin)F(cos)F(tan)F(asin)F(acos)F(atan)F(atan2)F(gcd)F(lcm));
#undef F
gc_add(mathNS);
}

View File

@ -1551,7 +1551,7 @@ u32* dsv_text[] = {
U"•file.MapBytes",U"•file.Modified",U"•file.Name",U"•file.Parent",U"•file.Remove",U"•file.Rename",U"•file.Size",U"•file.Type",
U"•internal.ClearRefs",U"•internal.DeepSqueeze",U"•internal.EEqual",U"•internal.ElType",U"•internal.HeapDump",U"•internal.Info",U"•internal.IsPure",U"•internal.ListVariations",U"•internal.Refc",U"•internal.Squeeze",U"•internal.Temp",U"•internal.Type",U"•internal.Unshare",U"•internal.Variation",
U"•math.Acos",U"•math.Asin",U"•math.Atan",U"•math.Atan2",U"•math.Cos",U"•math.Sin",U"•math.Tan",
U"•math.Acos",U"•math.Asin",U"•math.Atan",U"•math.Atan2",U"•math.Cos",U"•math.GCD",U"•math.LCM",U"•math.Sin",U"•math.Tan",
U"•rand.Deal",U"•rand.Range",U"•rand.Subset",
U"•term.CharB",U"•term.CharN",U"•term.ErrRaw",U"•term.Flush",U"•term.OutRaw",U"•term.RawMode",
NULL