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

View File

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

View File

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

View File

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