signed int addsub

This commit is contained in:
jangko 2023-06-14 07:38:23 +07:00
parent f2959e5135
commit 8ea95078f4
No known key found for this signature in database
GPG Key ID: 31702AE10541E6B9
4 changed files with 45 additions and 36 deletions

View File

@ -30,7 +30,7 @@ func sign*(a: StInt): int =
else: -1
func isNegative*(a: StInt): bool =
a.sign < 0
a.limbs[^1] >= signMask
func clearMSB(a: var StInt) =
a.limbs[^1] = a.limbs[^1] and clearSignMask
@ -107,14 +107,11 @@ func `==`*(a, b: StInt): bool =
func `<`*(a, b: StInt): bool =
## Unsigned `less than` comparison
let
aSign = a.sign
bSign = b.sign
aNeg = a.isNegative
bNeg = b.isNegative
if aSign >= 0:
if bSign < 0:
return false
elif bSign >= 0:
return true
if aNeg xor bNeg:
return aNeg
a.imp < b.imp
@ -174,40 +171,48 @@ func `shl`*(a: StInt, k: SomeInteger): StInt =
## Shift left by k bits
result.imp.shiftLeft(a.imp, k)
func setBit*(a: var StInt, k: Natural) =
a.imp.setBit(k)
func clearBit*(a: var StInt, k: Natural) =
a.imp.clearBit(k)
func getBit*(a: StInt, k: Natural): bool =
a.imp.getBit(k)
{.pop.}
# Addsub
# --------------------------------------------------------
{.push raises: [], inline, noinit, gcsafe.}
#[
func `+`*(a, b: StInt): StInt =
## Addition for multi-precision unsigned int
result.sum(a, b)
result.imp.sum(a.imp, b.imp)
func `+=`*(a: var StInt, b: StInt) =
## In-place addition for multi-precision unsigned int
a.sum(a, b)
a.imp.sum(a.imp, b.imp)
func `-`*(a, b: StInt): StInt =
## Substraction for multi-precision unsigned int
result.diff(a, b)
result.imp.diff(a.imp, b.imp)
func `-=`*(a: var StInt, b: StInt) =
## In-place substraction for multi-precision unsigned int
a.diff(a, b)
a.imp.diff(a.imp, b.imp)
func inc*(a: var StInt, w: Word = 1) =
a.imp.inc(w)
func `+`*(a: StInt, b: SomeUnsignedInt): StInt =
## Addition for multi-precision unsigned int
## with an unsigned integer
result.sum(a, Word(b))
result.imp.sum(a.imp, Word(b))
func `+=`*(a: var StInt, b: SomeUnsignedInt) =
## In-place addition for multi-precision unsigned int
## with an unsigned integer
a.inc(Word(b))
]#
a.imp.inc(Word(b))
{.pop.}

View File

@ -126,24 +126,29 @@ export
{.push raises: [], inline, gcsafe.}
func `shr`*(a: StUint, k: SomeInteger): StUint =
func `shr`*(a: StUint, k: Natural): StUint =
## Shift right by k bits
result.shiftRight(a, k)
func `shl`*(a: StUint, k: SomeInteger): StUint =
func `shl`*(a: StUint, k: Natural): StUint =
## Shift left by k bits
result.shiftLeft(a, k)
func setBit*(a: var StUint, k: SomeInteger) =
func setBit*(a: var StUint, k: Natural) =
let limbIndex = k div WordBitWidth
let bitIndex = k mod WordBitWidth
setBit(a.limbs[limbIndex], bitIndex)
func clearBit*(a: var StUint, k: SomeInteger) =
func clearBit*(a: var StUint, k: Natural) =
let limbIndex = k div WordBitWidth
let bitIndex = k mod WordBitWidth
clearBit(a.limbs[limbIndex], bitIndex)
func getBit*(a: StUint, k: Natural): bool =
let limbIndex = k div WordBitWidth
let bitIndex = k mod WordBitWidth
getBit(a.limbs[limbIndex], bitIndex)
{.pop.}
# Addsub

View File

@ -122,42 +122,42 @@ proc main() =
suite "Testing signed addition implementation":
test "In-place addition gives expected result":
var a = 20182018.stint(64)
let b = 20172017.stint(64)
var a = 20182018.stint(256)
let b = 20172017.stint(256)
a += b
check: cast[int64](a) == 20182018'i64 + 20172017'i64
check a == (20182018'i64 + 20172017'i64).i256
test "Addition gives expected result":
let a = 20182018.stint(64)
let b = 20172017.stint(64)
let a = 20182018.stint(256)
let b = 20172017.stint(256)
check: cast[int64](a+b) == 20182018'i64 + 20172017'i64
check a+b == (20182018'i64 + 20172017'i64).i256
test "When the low half overflows, it is properly carried":
# uint8 (low half) overflow at 255
let a = 100'i16.stint(16)
let b = 100'i16.stint(16)
let a = 100.stint(256)
let b = 100.stint(256)
check: cast[int16](a+b) == 200
check a+b == 200.i256
suite "Testing signed substraction implementation":
test "In-place substraction gives expected result":
var a = 20182018.stint(64)
let b = 20172017.stint(64)
var a = 20182018.stint(256)
let b = 20172017.stint(256)
a -= b
check: cast[int64](a) == 20182018'i64 - 20172017'i64
check a == (20182018'i64 - 20172017'i64).i256
test "Substraction gives expected result":
let a = 20182018.stint(64)
let b = 20172017.stint(64)
let a = 20182018.stint(256)
let b = 20172017.stint(256)
check: cast[int64](a-b) == 20182018'i64 - 20172017'i64
check: a-b == (20182018'i64 - 20172017'i64).i256
main()

View File

@ -274,7 +274,6 @@ proc main() =
suite "Wider signed int comparison coverage":
testComparison(check, test)
suite "Signed int - Testing comparison operators":
let
a = 10.i256