Implement comparison
This commit is contained in:
parent
de87739635
commit
36cc2b2e02
|
@ -16,7 +16,7 @@ when sizeof(int) == 8 and not defined(Stint32):
|
||||||
else:
|
else:
|
||||||
type Word* = uint32
|
type Word* = uint32
|
||||||
|
|
||||||
type Word* = uint32
|
const WordBitWidth = sizeof(Word) * 8
|
||||||
|
|
||||||
func wordsRequired*(bits: int): int {.compileTime.} =
|
func wordsRequired*(bits: int): int {.compileTime.} =
|
||||||
## Compute the number of limbs required
|
## Compute the number of limbs required
|
||||||
|
@ -24,7 +24,7 @@ func wordsRequired*(bits: int): int {.compileTime.} =
|
||||||
(bits + WordBitWidth - 1) div WordBitWidth
|
(bits + WordBitWidth - 1) div WordBitWidth
|
||||||
|
|
||||||
type
|
type
|
||||||
Limbs*[N: static int] = array[N, BaseUint]
|
Limbs*[N: static int] = array[N, Word]
|
||||||
|
|
||||||
StUint*[bits: static[int]] = object
|
StUint*[bits: static[int]] = object
|
||||||
## Stack-based integer
|
## Stack-based integer
|
||||||
|
@ -60,3 +60,39 @@ func mostSignificantWord*(limbs: Limbs): auto {.inline.} =
|
||||||
limbs[^1]
|
limbs[^1]
|
||||||
else:
|
else:
|
||||||
limbs[0]
|
limbs[0]
|
||||||
|
|
||||||
|
iterator leastToMostSig*(limbs: Limbs): Word =
|
||||||
|
## Iterate from least to most significant word
|
||||||
|
when cpuEndian == littleEndian:
|
||||||
|
for i in 0 ..< limbs.len:
|
||||||
|
yield limbs[i]
|
||||||
|
else:
|
||||||
|
for i in countdown(limbs.len-1, 0):
|
||||||
|
yield limbs[i]
|
||||||
|
|
||||||
|
iterator leastToMostSig*(limbs: var Limbs): var Word =
|
||||||
|
## Iterate from least to most significant word
|
||||||
|
when cpuEndian == littleEndian:
|
||||||
|
for i in 0 ..< limbs.len:
|
||||||
|
yield limbs[i]
|
||||||
|
else:
|
||||||
|
for i in countdown(limbs.len-1, 0):
|
||||||
|
yield limbs[i]
|
||||||
|
|
||||||
|
iterator leastToMostSig*(aLimbs, bLimbs: Limbs): (Word, Word) =
|
||||||
|
## Iterate from least to most significant word
|
||||||
|
when cpuEndian == littleEndian:
|
||||||
|
for i in 0 ..< limbs.len:
|
||||||
|
yield (aLimbs[i], bLimbs[i])
|
||||||
|
else:
|
||||||
|
for i in countdown(limbs.len-1, 0):
|
||||||
|
yield (aLimbs[i], bLimbs[i])
|
||||||
|
|
||||||
|
iterator leastToMostSig*(aLimbs: var Limbs, bLimbs: Limbs): (var Word, Word) =
|
||||||
|
## Iterate from least to most significant word
|
||||||
|
when cpuEndian == littleEndian:
|
||||||
|
for i in 0 ..< limbs.len:
|
||||||
|
yield (aLimbs[i], bLimbs[i])
|
||||||
|
else:
|
||||||
|
for i in countdown(limbs.len-1, 0):
|
||||||
|
yield (aLimbs[i], bLimbs[i])
|
||||||
|
|
|
@ -7,36 +7,46 @@
|
||||||
#
|
#
|
||||||
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
||||||
|
|
||||||
import ./datatypes
|
import
|
||||||
|
./datatypes,
|
||||||
|
./primitives/addcarry_subborrow
|
||||||
|
|
||||||
func isZero*(n: SomeUnsignedInt): bool {.inline.} =
|
func isZero*(n: SomeUnsignedInt): bool {.inline.} =
|
||||||
n == 0
|
n == 0
|
||||||
|
|
||||||
func isZero*(n: UintImpl): bool {.inline.} =
|
func isZero*(limbs: Limbs): bool {.inline.} =
|
||||||
n.hi.isZero and n.lo.isZero
|
for word in limbs:
|
||||||
|
if not word.isZero():
|
||||||
|
return false
|
||||||
|
return true
|
||||||
|
|
||||||
func `<`*(x, y: UintImpl): bool {.inline.}=
|
func `<`*(x, y: Limbs): bool {.inline.}=
|
||||||
# Lower comparison for multi-precision integers
|
# Lower comparison for multi-precision integers
|
||||||
x.hi < y.hi or
|
var diff: Word
|
||||||
(x.hi == y.hi and x.lo < y.lo)
|
var borrow: Borrow
|
||||||
|
for wx, wy in leastToMostSig(x, y):
|
||||||
|
subB(borrow, diff, wx, wy, borrow)
|
||||||
|
return bool(borrow)
|
||||||
|
|
||||||
func `==`*(x, y: UintImpl): bool {.inline.}=
|
func `==`*(x, y: Limbs): bool {.inline.}=
|
||||||
# Equal comparison for multi-precision integers
|
# Equal comparison for multi-precision integers
|
||||||
x.hi == y.hi and x.lo == y.lo
|
for wx, wy in leastToMostSig(x, y):
|
||||||
|
if wx != wy:
|
||||||
|
return false
|
||||||
|
return true
|
||||||
|
|
||||||
func `<=`*(x, y: UintImpl): bool {.inline.}=
|
func `<=`*(x, y: Limbs): bool {.inline.}=
|
||||||
# Lower or equal comparison for multi-precision integers
|
# Lower or equal comparison for multi-precision integers
|
||||||
x.hi < y.hi or
|
not(y < x)
|
||||||
(x.hi == y.hi and x.lo <= y.lo)
|
|
||||||
|
|
||||||
func isEven*(x: SomeUnsignedInt): bool {.inline.} =
|
func isEven*(x: SomeUnsignedInt): bool {.inline.} =
|
||||||
(x and 1) == 0
|
(x and 1) == 0
|
||||||
|
|
||||||
func isEven*(x: UintImpl): bool {.inline.}=
|
func isEven*(x: Limbs): bool {.inline.}=
|
||||||
x.lo.isEven
|
x.leastSignificantWord.isEven
|
||||||
|
|
||||||
func isOdd*(x: SomeUnsignedInt): bool {.inline.} =
|
func isOdd*(x: SomeUnsignedInt): bool {.inline.} =
|
||||||
not x.isEven
|
not x.isEven
|
||||||
|
|
||||||
func isOdd*(x: UintImpl): bool {.inline.}=
|
func isOdd*(x: Limbs): bool {.inline.}=
|
||||||
not x.isEven
|
not x.isEven
|
||||||
|
|
Loading…
Reference in New Issue