diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2018-05-27 13:38:09 +0200 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2018-05-27 13:38:09 +0200 |
commit | 98498087202203e343c782ce24e294bd0b82becf (patch) | |
tree | 1bec5f2fa4f14b9925b10622288390f43673175c /lib/pure | |
parent | 669a5644926290e19a3fc32fd319c056183ff2d9 (diff) | |
parent | 7e8eadb6ba9c94ea429ee7178e8cc8fbcbf558ea (diff) | |
download | Nim-98498087202203e343c782ce24e294bd0b82becf.tar.gz |
Merge branch 'devel' into araq-big-refactoring
Diffstat (limited to 'lib/pure')
-rw-r--r-- | lib/pure/math.nim | 32 | ||||
-rw-r--r-- | lib/pure/parseutils.nim | 3 |
2 files changed, 33 insertions, 2 deletions
diff --git a/lib/pure/math.nim b/lib/pure/math.nim index 9e590debc..49d87f007 100644 --- a/lib/pure/math.nim +++ b/lib/pure/math.nim @@ -21,6 +21,8 @@ include "system/inclrtl" {.push debugger:off .} # the user does not want to trace a part # of the standard library! +import bitops + proc binom*(n, k: int): int {.noSideEffect.} = ## Computes the binomial coefficient if k <= 0: return 1 @@ -455,16 +457,42 @@ proc `^`*[T](x: T, y: Natural): T = x *= x proc gcd*[T](x, y: T): T = - ## Computes the greatest common divisor of ``x`` and ``y``. + ## Computes the greatest common (positive) divisor of ``x`` and ``y``. ## Note that for floats, the result cannot always be interpreted as ## "greatest decimal `z` such that ``z*N == x and z*M == y`` ## where N and M are positive integers." - var (x,y) = (x,y) + var (x, y) = (x, y) while y != 0: x = x mod y swap x, y abs x +proc gcd*(x, y: SomeInteger): SomeInteger = + ## Computes the greatest common (positive) divisor of ``x`` and ``y``. + ## Using binary GCD (aka Stein's) algorithm. + when x is SomeSignedInt: + var x = abs(x) + else: + var x = x + when y is SomeSignedInt: + var y = abs(y) + else: + var y = y + + if x == 0: + return y + if y == 0: + return x + + let shift = countTrailingZeroBits(x or y) + y = y shr countTrailingZeroBits(y) + while x != 0: + x = x shr countTrailingZeroBits(x) + if y > x: + swap y, x + x -= y + y shl shift + proc lcm*[T](x, y: T): T = ## Computes the least common multiple of ``x`` and ``y``. x div gcd(x, y) * y diff --git a/lib/pure/parseutils.nim b/lib/pure/parseutils.nim index d77790fe0..d54f1454b 100644 --- a/lib/pure/parseutils.nim +++ b/lib/pure/parseutils.nim @@ -197,6 +197,9 @@ proc parseUntil*(s: string, token: var string, until: string, ## parses a token and stores it in ``token``. Returns ## the number of the parsed characters or 0 in case of an error. A token ## consists of any character that comes before the `until` token. + if until.len == 0: + token.setLen(0) + return 0 var i = start while i < s.len: if s[i] == until[0]: |