diff options
author | quimt <126020181+quimt@users.noreply.github.com> | 2024-07-09 06:59:10 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-07-09 12:59:10 +0200 |
commit | 96c165304d53fbca83f89c73df38b63e3c0ab85e (patch) | |
tree | 2e6152de170548f27f114624f4e2bb9807efe47b /lib/pure/math.nim | |
parent | 732f7752a954bb33a92e839304006ba5d865400a (diff) | |
download | Nim-96c165304d53fbca83f89c73df38b63e3c0ab85e.tar.gz |
conditional compilation of gcd(SomeInteger,SomeInteger) in std/math (#23773)
The most specific version of `gcd(int,int)` in `std/math` uses bitwise comparisons from C compilers, which can't be borrowed on the js platform in the web browser. Conditional compilation here should fix the issue for this and downstream libraries such as `std/rationals` when compiling to browser js as the backend. --------- Co-authored-by: Andreas Rumpf <rumpf_a@web.de>
Diffstat (limited to 'lib/pure/math.nim')
-rw-r--r-- | lib/pure/math.nim | 71 |
1 files changed, 37 insertions, 34 deletions
diff --git a/lib/pure/math.nim b/lib/pure/math.nim index 73a60e974..c9b2162e9 100644 --- a/lib/pure/math.nim +++ b/lib/pure/math.nim @@ -58,6 +58,7 @@ import std/private/since # of the standard library! import std/[bitops, fenv] +import system/countbits_impl when defined(nimPreviewSlimSystem): import std/assertions @@ -1229,40 +1230,42 @@ func gcd*[T](x, y: T): T = swap x, y abs x -func gcd*(x, y: SomeInteger): SomeInteger = - ## Computes the greatest common (positive) divisor of `x` and `y`, - ## using the binary GCD (aka Stein's) algorithm. - ## - ## **See also:** - ## * `gcd func <#gcd,T,T>`_ for a float version - ## * `lcm func <#lcm,T,T>`_ - runnableExamples: - doAssert gcd(12, 8) == 4 - doAssert gcd(17, 63) == 1 - - 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 - +when useBuiltins: + ## this func uses bitwise comparisons from C compilers, which are not always available. + func gcd*(x, y: SomeInteger): SomeInteger = + ## Computes the greatest common (positive) divisor of `x` and `y`, + ## using the binary GCD (aka Stein's) algorithm. + ## + ## **See also:** + ## * `gcd func <#gcd,T,T>`_ for a float version + ## * `lcm func <#lcm,T,T>`_ + runnableExamples: + doAssert gcd(12, 8) == 4 + doAssert gcd(17, 63) == 1 + + 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 + func gcd*[T](x: openArray[T]): T {.since: (1, 1).} = ## Computes the greatest common (positive) divisor of the elements of `x`. ## |