mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
math: add gcd and lcm
Add gcd and lcm functions to calculate the greatest common divisor (gcd) and the least common multiple (lcm) to the math module. This will also work for BigInts that implements its own gcd/lcm.
This commit is contained in:
committed by
Christoffer Lerno
parent
061c02306f
commit
62dca4f1c5
@@ -328,7 +328,7 @@ fn BigInt BigInt.unary_minus(&self)
|
||||
}
|
||||
|
||||
|
||||
macro void BigInt.div(self, BigInt other)
|
||||
macro BigInt BigInt.div(self, BigInt other)
|
||||
{
|
||||
self.div_this(other);
|
||||
return self;
|
||||
@@ -831,6 +831,14 @@ fn BigInt BigInt.gcd(&self, BigInt other)
|
||||
return g;
|
||||
}
|
||||
|
||||
fn BigInt BigInt.lcm(&self, BigInt other)
|
||||
{
|
||||
BigInt x = self.abs();
|
||||
BigInt y = other.abs();
|
||||
BigInt g = y.mult(x);
|
||||
return g.div(x.gcd(y));
|
||||
}
|
||||
|
||||
<*
|
||||
@require bits >> 5 < MAX_LEN "Required bits > maxlength"
|
||||
*>
|
||||
|
||||
@@ -1183,4 +1183,62 @@ macro long[<*>] long[<*>].muldiv(self, mul, div) => mul_div_helper(self, mul, di
|
||||
@require @is_same_vector_or_scalar(self, mul) `mul must be a vector of the same type as self, or be an integer scalar`
|
||||
@require @is_same_vector_or_scalar(self, div) `div must be a vector of the same type as self, or be an integer scalar`
|
||||
*>
|
||||
macro ulong[<*>] ulong[<*>].muldiv(self, mul, div) => mul_div_helper(self, mul, div);
|
||||
macro ulong[<*>] ulong[<*>].muldiv(self, mul, div) => mul_div_helper(self, mul, div);
|
||||
|
||||
<*
|
||||
@require types::is_int($typeof(a)) `The input must be an integer`
|
||||
@require types::is_int($typeof(b)) `The input must be an integer`
|
||||
*>
|
||||
macro _gcd(a, b) @private
|
||||
{
|
||||
if (a == 0) return b;
|
||||
if (b == 0) return a;
|
||||
|
||||
var $Type = $typeof(a);
|
||||
$Type r, aa, ab;
|
||||
aa = abs(a);
|
||||
ab = abs(b);
|
||||
while (ab != 0)
|
||||
{
|
||||
r = aa % ab;
|
||||
aa = ab;
|
||||
ab = r;
|
||||
}
|
||||
return aa;
|
||||
}
|
||||
|
||||
<*
|
||||
Calculate the least common multiple for the provided arguments.
|
||||
|
||||
@require $vacount >= 2 `At least two arguments are required.`
|
||||
*>
|
||||
macro lcm(...)
|
||||
{
|
||||
$typeof($vaarg[0]) result = $vaarg[0];
|
||||
$for (var $i = 1; $i < $vacount; $i++)
|
||||
$if $defined(result.lcm):
|
||||
result = result.lcm($vaarg[$i]);
|
||||
$else
|
||||
result = (abs($vaarg[$i]) * abs(result)) / (_gcd($vaarg[$i], result));
|
||||
$endif
|
||||
$endfor
|
||||
return result;
|
||||
}
|
||||
|
||||
<*
|
||||
Calculate the greatest common divisor for the provided arguments.
|
||||
|
||||
@require $vacount >= 2 `At least two arguments are required.`
|
||||
*>
|
||||
macro gcd(...)
|
||||
{
|
||||
$typeof($vaarg[0]) result = $vaarg[0];
|
||||
$for (var $i = 1; $i < $vacount; $i++)
|
||||
$if $defined(result.gcd):
|
||||
result = result.gcd($vaarg[$i]);
|
||||
$else
|
||||
result = _gcd($vaarg[$i], result);
|
||||
$endif
|
||||
$endfor
|
||||
return result;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user