mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-18 13:30:33 +00:00
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>
This commit is contained in:
@@ -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`.
|
||||
##
|
||||
|
||||
Reference in New Issue
Block a user