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.}=
|
||||
## Calculates how many bits are necessary to represent the number
|
||||
result = 1
|
||||
var y: T = n shr 1
|
||||
while y != 0.T:
|
||||
y = y shr 1
|
||||
|
||||
var n = n
|
||||
while n != 0.T:
|
||||
n = n shr 1
|
||||
inc(result)
|
||||
|
||||
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
|
||||
# throw a type mismatch
|
||||
result = 1
|
||||
var y: T = n shr 1
|
||||
while y != 0.T:
|
||||
y = y shr 1
|
||||
|
||||
var n = n
|
||||
while n != 0.T:
|
||||
n = n shr 1
|
||||
inc(result)
|
||||
|
||||
proc bit_length*[T: MpUint](n: T): int {.noSideEffect.}=
|
||||
## Calculates how many bits are necessary to represent the number
|
||||
const zero = T()
|
||||
result = 1
|
||||
var y: T = n shr 1
|
||||
while y != zero:
|
||||
y = y shr 1 # TODO: shr is slow!
|
||||
inc(result)
|
||||
|
||||
const maxHalfRepr = n.lo.type.sizeof * 8 - 1
|
||||
|
||||
if n.hi.bit_length == 0:
|
||||
n.lo.bit_length
|
||||
else:
|
||||
n.hi.bit_length + maxHalfRepr
|
||||
|
||||
proc asUint*[T: MpUInt](n: T): auto {.noSideEffect, inline.}=
|
||||
## 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