small quality of life fix + auto conversion of booleans
This commit is contained in:
parent
834ff19a25
commit
a8f50c4dbe
|
@ -11,4 +11,4 @@ export uint_type,
|
|||
uint_init,
|
||||
uint_bitwise_ops,
|
||||
uint_binary_ops,
|
||||
uint_comparison
|
||||
uint_comparison
|
||||
|
|
|
@ -4,6 +4,11 @@
|
|||
import ../uint_type,
|
||||
macros
|
||||
|
||||
macro getSubType*(T: typedesc): untyped =
|
||||
## Returns the subtype of a generic type
|
||||
## MpUint[uint32] --> uint32
|
||||
getTypeInst(T)[1][1]
|
||||
|
||||
|
||||
proc bit_length*[T: BaseUint](n: T): int {.noSideEffect.}=
|
||||
## Calculates how many bits are necessary to represent the number
|
||||
|
@ -54,11 +59,6 @@ proc asDoubleUint*[T: BaseUint](n: T): auto {.noSideEffect, inline.} =
|
|||
|
||||
n.asUint.Double
|
||||
|
||||
macro getSubType*(T: typedesc): untyped =
|
||||
## Returns the subtype of a generic type
|
||||
## MpUint[uint32] --> uint32
|
||||
getTypeInst(T)[1][1]
|
||||
|
||||
|
||||
proc toMpUint*[T: SomeInteger](n: T): auto {.noSideEffect, inline.} =
|
||||
## Cast an integer to the corresponding size MpUint
|
||||
|
|
|
@ -10,11 +10,11 @@ proc `+=`*[T: MpUint](x: var T, y: T) {.noSideEffect.}=
|
|||
#
|
||||
# Optimized assembly should contain adc instruction (add with carry)
|
||||
# Clang on MacOS does with the -d:release switch and MpUint[uint32] (uint64)
|
||||
type Base = type x.lo
|
||||
type MpBase = type x.lo
|
||||
let tmp = x.lo
|
||||
|
||||
x.lo += y.lo
|
||||
x.hi += (x.lo < tmp).Base + y.hi
|
||||
x.hi += MpBase(x.lo < tmp) + y.hi
|
||||
|
||||
proc `+`*[T: MpUint](x, y: T): T {.noSideEffect, noInit, inline.}=
|
||||
# Addition for multi-precision unsigned int
|
||||
|
@ -26,11 +26,11 @@ proc `-=`*[T: MpUint](x: var T, y: T) {.noSideEffect.}=
|
|||
#
|
||||
# Optimized assembly should contain sbb instruction (substract with borrow)
|
||||
# Clang on MacOS does with the -d:release switch and MpUint[uint32] (uint64)
|
||||
type MPBase = type x.lo
|
||||
type MpBase = type x.lo
|
||||
let tmp = x.lo
|
||||
|
||||
x.lo -= y.lo
|
||||
x.hi -= (x.lo > tmp).MPBase + y.hi
|
||||
x.hi -= MpBase(x.lo > tmp) + y.hi
|
||||
|
||||
proc `-`*[T: MpUint](x, y: T): T {.noSideEffect, noInit, inline.}=
|
||||
# Substraction for multi-precision unsigned int
|
||||
|
@ -79,7 +79,7 @@ template naiveMulImpl[T: MpUint](x, y: T): MpUint[T] =
|
|||
# - More total operations means more register moves
|
||||
|
||||
let # cannot be const, compile-time sizeof only works for simple types
|
||||
size = (T.sizeof * 8)
|
||||
size = T.sizeof * 8
|
||||
halfSize = size div 2
|
||||
let
|
||||
z0 = naiveMul(x.lo, y.lo)
|
||||
|
@ -104,4 +104,5 @@ proc naiveMul[T: BaseUint](x, y: T): MpUint[T] {.noSideEffect, noInit, inline.}=
|
|||
naiveMulImpl(x.toMpUint, y.toMpUint)
|
||||
else:
|
||||
# Case: at least uint128 * uint128 --> uint256
|
||||
naiveMulImpl(x, y)
|
||||
naiveMulImpl(x, y)
|
||||
|
||||
|
|
|
@ -35,10 +35,10 @@ proc `shl`*[T: MpUint](x: T, y: SomeInteger): T {.noInit, noSideEffect.}=
|
|||
return x
|
||||
|
||||
let # cannot be const, compile-time sizeof only works for simple types
|
||||
size = (T.sizeof * 8)
|
||||
size = T.sizeof * 8
|
||||
halfSize = size div 2
|
||||
|
||||
type Sub = getSubType T
|
||||
type Sub = type x.lo
|
||||
|
||||
if y < halfSize:
|
||||
result.hi = (x.hi shl y) or (x.lo shr (halfSize - y))
|
||||
|
@ -54,10 +54,10 @@ proc `shr`*[T: MpUint](x: T, y: SomeInteger): T {.noInit, noSideEffect.}=
|
|||
return x
|
||||
|
||||
let # cannot be const, compile-time sizeof only works for simple types
|
||||
size = (T.sizeof * 8)
|
||||
size = T.sizeof * 8
|
||||
halfSize = size div 2
|
||||
|
||||
type Sub = getSubType T
|
||||
type Sub = type x.lo
|
||||
|
||||
if y < halfSize:
|
||||
result.lo = (x.lo shr y) or (x.hi shl (halfSize - y))
|
||||
|
@ -80,7 +80,7 @@ proc `shr`*[T: MpUint](x: T, y: SomeInteger): T {.noInit, noSideEffect.}=
|
|||
|
||||
# proc `shl`*[T: MpUint](x: T, y: SomeInteger): T {.noInit, noSideEffect.}=
|
||||
# ## Compute the `shift left` operation of x and y
|
||||
# type Sub = getSubType T
|
||||
# type Sub = type x.lo
|
||||
#
|
||||
# let # cannot be const, compile-time sizeof only works for simple types
|
||||
# size = Sub(T.sizeof * 8)
|
||||
|
@ -102,7 +102,7 @@ proc `shr`*[T: MpUint](x: T, y: SomeInteger): T {.noInit, noSideEffect.}=
|
|||
|
||||
# proc `shr`*[T: MpUint](x: T, y: SomeInteger): T {.noInit, noSideEffect.}=
|
||||
# ## Compute the `shift right` operation of x and y
|
||||
# type Sub = getSubType T
|
||||
# type Sub = type x.lo
|
||||
#
|
||||
# let # cannot be const, compile-time sizeof only works for simple types
|
||||
# size = Sub(T.sizeof * 8)
|
||||
|
|
|
@ -13,4 +13,14 @@ type
|
|||
|
||||
|
||||
UInt128* = MpUint[uint64]
|
||||
UInt256* = MpUint[UInt128]
|
||||
UInt256* = MpUint[UInt128]
|
||||
|
||||
|
||||
template convBool(typ: typedesc): untyped =
|
||||
converter boolMpUint*(b: bool): MpUint[typ] {.noSideEffect, inline.}=
|
||||
result.lo = b.typ
|
||||
|
||||
convBool(uint8)
|
||||
convBool(uint16)
|
||||
convBool(uint32)
|
||||
convBool(uint64)
|
Loading…
Reference in New Issue