diff --git a/src/private/utils.nim b/src/private/utils.nim index 0bfab1a..377f9ff 100644 --- a/src/private/utils.nim +++ b/src/private/utils.nim @@ -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 diff --git a/src/uint_logical_ops.nim b/src/uint_logical_ops.nim new file mode 100644 index 0000000..1d186c2 --- /dev/null +++ b/src/uint_logical_ops.nim @@ -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 \ No newline at end of file