Division/modulo 2x faster by removing shift in MpUint bit_length
This commit is contained in:
parent
1c5da77a29
commit
43cb3441bc
|
@ -11,10 +11,10 @@ macro getSubType*(T: typedesc): untyped =
|
||||||
|
|
||||||
proc bit_length*[T: SomeUnsignedInt](n: T): int {.noSideEffect.}=
|
proc bit_length*[T: SomeUnsignedInt](n: T): int {.noSideEffect.}=
|
||||||
## Calculates how many bits are necessary to represent the number
|
## Calculates how many bits are necessary to represent the number
|
||||||
result = 1
|
|
||||||
var y: T = n shr 1
|
var n = n
|
||||||
while y != 0.T:
|
while n != 0.T:
|
||||||
y = y shr 1
|
n = n shr 1
|
||||||
inc(result)
|
inc(result)
|
||||||
|
|
||||||
proc bit_length*[T: Natural](n: T): int {.noSideEffect.}=
|
proc bit_length*[T: Natural](n: T): int {.noSideEffect.}=
|
||||||
|
@ -22,20 +22,21 @@ proc bit_length*[T: Natural](n: T): int {.noSideEffect.}=
|
||||||
#
|
#
|
||||||
# For some reason using "SomeUnsignedInt or Natural" directly makes Nim compiler
|
# For some reason using "SomeUnsignedInt or Natural" directly makes Nim compiler
|
||||||
# throw a type mismatch
|
# throw a type mismatch
|
||||||
result = 1
|
|
||||||
var y: T = n shr 1
|
var n = n
|
||||||
while y != 0.T:
|
while n != 0.T:
|
||||||
y = y shr 1
|
n = n shr 1
|
||||||
inc(result)
|
inc(result)
|
||||||
|
|
||||||
proc bit_length*[T: MpUint](n: T): int {.noSideEffect.}=
|
proc bit_length*[T: MpUint](n: T): int {.noSideEffect.}=
|
||||||
## Calculates how many bits are necessary to represent the number
|
## Calculates how many bits are necessary to represent the number
|
||||||
const zero = T()
|
|
||||||
result = 1
|
const maxHalfRepr = n.lo.type.sizeof * 8 - 1
|
||||||
var y: T = n shr 1
|
|
||||||
while y != zero:
|
if n.hi.bit_length == 0:
|
||||||
y = y shr 1 # TODO: shr is slow!
|
n.lo.bit_length
|
||||||
inc(result)
|
else:
|
||||||
|
n.hi.bit_length + maxHalfRepr
|
||||||
|
|
||||||
proc asUint*[T: MpUInt](n: T): auto {.noSideEffect, inline.}=
|
proc asUint*[T: MpUInt](n: T): auto {.noSideEffect, inline.}=
|
||||||
## Casts a multiprecision integer to an uint of the same size
|
## Casts a multiprecision integer to an uint of the same size
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
# Copyright (c) 2018 Status Research & Development GmbH
|
||||||
|
# Distributed under the MIT License (license terms are at http://opensource.org/licenses/MIT).
|
||||||
|
|
||||||
|
import uint_type
|
||||||
|
|
||||||
|
proc `not`*(x: MpUint): MpUint {.noInit, noSideEffect, inline.}=
|
||||||
|
## Bitwise complement of unsigned integer x
|
||||||
|
result.lo = not x.lo
|
||||||
|
result.hi = not x.hi
|
||||||
|
|
||||||
|
proc `or`*(x, y: MpUint): MpUint {.noInit, noSideEffect, inline.}=
|
||||||
|
## `Bitwise or` of numbers x and y
|
||||||
|
result.lo = x.lo or y.lo
|
||||||
|
result.hi = x.hi or y.hi
|
||||||
|
|
||||||
|
proc `and`*(x, y: MpUint): MpUint {.noInit, noSideEffect, inline.}=
|
||||||
|
## `Bitwise and` of numbers x and y
|
||||||
|
result.lo = x.lo and y.lo
|
||||||
|
result.hi = x.hi and y.hi
|
||||||
|
|
||||||
|
proc `xor`*(x, y: MpUint): MpUint {.noInit, noSideEffect, inline.}=
|
||||||
|
## `Bitwise xor` of numbers x and y
|
||||||
|
result.lo = x.lo xor y.lo
|
||||||
|
result.hi = x.hi xor y.hi
|
Loading…
Reference in New Issue