Skip to content

Commit f3bcc9b

Browse files
committed
Fixed some expressions
1 parent 9e4efd6 commit f3bcc9b

File tree

1 file changed

+25
-19
lines changed

1 file changed

+25
-19
lines changed

src/bigints.nim

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -389,10 +389,6 @@ template `-=`*(a: var BigInt, b: BigInt) =
389389
assert a == 3.initBigInt
390390
a = a - b
391391

392-
func abs*(a: BigInt): BigInt =
393-
result = a
394-
result.isNegative = false
395-
396392
func unsignedMultiplication(a: var BigInt, b, c: BigInt) {.inline.} =
397393
# always called with bl >= cl
398394
let
@@ -450,6 +446,7 @@ func scalarMultiplication(a: var BigInt, b: uint32, c: BigInt) {.inline.} =
450446

451447
# forward declaration for use in `multiplication`
452448
func unsignedKaratsubaMultiplication(a: var BigInt, b, c: BigInt) {.inline.}
449+
func `shl`*(x: BigInt, y: Natural): BigInt
453450

454451
func multiplication(a: var BigInt, b, c: BigInt) =
455452
# a = b * c
@@ -472,20 +469,31 @@ func multiplication(a: var BigInt, b, c: BigInt) =
472469
unsignedMultiplication(a, b, c)
473470
a.isNegative = b.isNegative xor c.isNegative
474471

472+
func `shr`*(x: BigInt, y: Natural): BigInt
475473
func unsignedKaratsubaMultiplication(a: var BigInt, b, c: BigInt) {.inline.} =
476474
let
477475
bl = b.limbs.len
478476
cl = c.limbs.len
479477
let n = max(bl, cl)
480478
if bl == 1:
481479
# base case : multiply the only limb with each limb of second term
482-
var a: BigInt
483-
unsignedMultiplication(a, c, b)
480+
scalarMultiplication(a, b.limbs[0], c)
484481
return
485482
if cl == 1:
486-
var a: BigInt
487-
unsignedMultiplication(a, b, c)
488-
return
483+
scalarMultiplication(a, c.limbs[0], b)
484+
return
485+
if bl < karatsubaTreshold:
486+
if cl <= bl:
487+
unsignedMultiplication(a, b, c)
488+
else:
489+
unsignedMultiplication(a, c, b)
490+
return
491+
if cl < karatsubaTreshold:
492+
if bl <= cl:
493+
unsignedMultiplication(a, c, b)
494+
else:
495+
unsignedMultiplication(a, b, c)
496+
return
489497
let k = n shr 1 # should it be ceil(n/2) ?
490498
var
491499
low_b, high_b, low_c, high_c: BigInt
@@ -502,20 +510,18 @@ func unsignedKaratsubaMultiplication(a: var BigInt, b, c: BigInt) {.inline.} =
502510
unsignedKaratsubaMultiplication(lowProduct, low_b, low_c)
503511
unsignedKaratsubaMultiplication(highProduct, high_b, high_c)
504512
A3 = low_b - high_b # Additive variant of Karatsuba
505-
A4 = low_c - high_c # would add them
506-
let sign = A3.isNegative xor A4.isNegative
513+
A4 = high_c - low_c # would add them
507514
if A4.limbs.len >= A3.limbs.len:
508515
multiplication(A5, abs(A4), abs(A3))
509516
else:
510517
multiplication(A5, abs(A3), abs(A4))
511-
if sign:
512-
middleTerm = lowProduct + highProduct - A5
513-
else:
514-
middleTerm = lowProduct + highProduct + A5
515-
# result = lowProduct + middleTerm shr k + highProduct shr 2k
516-
a.limbs[0 .. k - 1] = lowProduct.limbs
517-
a.limbs[k .. 2*k-1] = middleTerm.limbs
518-
a.limbs[2*k .. 3*k-1] = highProduct.limbs
518+
middleTerm = lowProduct + highProduct + A5
519+
a = lowProduct + (middleTerm shr k) + (highProduct shr (2*k))
520+
# We could affect directly some of the bits of the result with slicing
521+
# a.limbs[0 .. k - 1] = lowProduct.limbs
522+
# But the following instructions would not be correct due to sign handling
523+
# a.limbs[k .. 2*k-1] = middleTerm.limbs
524+
# a.limbs[2*k .. 3*k-1] = highProduct.limbs
519525

520526

521527
func `*`*(a, b: BigInt): BigInt =

0 commit comments

Comments
 (0)