mirror of
https://github.com/status-im/nim-stew.git
synced 2025-01-23 10:29:44 +00:00
fix, tests: saturated on unsigned
This commit is contained in:
parent
0f5abee01d
commit
b78fe3e61a
@ -59,19 +59,13 @@ func addOverflow*(x, y: SomeUnsignedInt, carry: bool):
|
||||
|
||||
func addSaturated*(x, y: SomeUnsignedInt): SomeUnsignedInt =
|
||||
## Add the two integers using saturating arithmetic.
|
||||
let r = x + y
|
||||
if r > max(SomeUnsignedInt):
|
||||
max(SomeUnsignedInt)
|
||||
let
|
||||
(p, r) = addOverflow(x, y)
|
||||
if r:
|
||||
SomeUnsignedInt.high
|
||||
else:
|
||||
r
|
||||
p
|
||||
|
||||
func subSaturated*(x, y: SomeUnsignedInt): SomeUnsignedInt =
|
||||
## Subtract y from x using saturating arithmetic.
|
||||
let r = x - y
|
||||
if r < min(SomeUnsignedInt):
|
||||
min(SomeUnsignedInt)
|
||||
else:
|
||||
r
|
||||
|
||||
func subOverflow*(x, y: SomeUnsignedInt):
|
||||
tuple[result: SomeUnsignedInt, overflow: bool] =
|
||||
@ -94,6 +88,15 @@ func subOverflow*(x, y: SomeUnsignedInt, borrow: bool):
|
||||
(c, d) = subOverflow(a, typeof(a)(borrow))
|
||||
(c, b or d)
|
||||
|
||||
func subSaturated*(x, y: SomeUnsignedInt): SomeUnsignedInt =
|
||||
## Subtract y from x using saturating arithmetic.
|
||||
let
|
||||
(p, r) = subOverflow(x, y)
|
||||
if r:
|
||||
SomeUnsignedInt.low
|
||||
else:
|
||||
p
|
||||
|
||||
func mulWiden*(x, y: uint64): tuple[lo, hi: uint64] =
|
||||
let
|
||||
x0 = x and uint32.high
|
||||
@ -153,6 +156,6 @@ func mulSaturated*(x, y: SomeUnsignedInt): SomeUnsignedInt =
|
||||
let
|
||||
(a, b) = mulOverflow(x, y)
|
||||
if b:
|
||||
max(SomeUnsignedInt)
|
||||
SomeUnsignedInt.high
|
||||
else:
|
||||
a
|
||||
|
@ -23,6 +23,14 @@ template testSubOverflow[T: SomeUnsignedInt]() =
|
||||
doAssert subOverflow(T.high, T.high, false) == (T(0), false)
|
||||
doAssert subOverflow(T.high, T.high, true) == (T.high, true)
|
||||
|
||||
template testAddSaturated[T: SomeUnsignedInt]() =
|
||||
doAssert addSaturated(T(100), T(1)) == T(101)
|
||||
doAssert addSaturated(T.high, T(127)) == T.high
|
||||
|
||||
template testSubSaturated[T: SomeUnsignedInt] =
|
||||
doAssert subSaturated(T(100), T(27)) == T(73)
|
||||
doAssert subSaturated(T(13), T(127)) == T.low
|
||||
|
||||
template testAddOverflow() =
|
||||
testAddOverflow[uint8]()
|
||||
testAddOverflow[uint16]()
|
||||
@ -37,6 +45,20 @@ template testSubOverflow() =
|
||||
testSubOverflow[uint64]()
|
||||
testSubOverflow[uint]()
|
||||
|
||||
template testAddSaturated() =
|
||||
testAddSaturated[uint8]()
|
||||
testAddSaturated[uint16]()
|
||||
testAddSaturated[uint32]()
|
||||
testAddSaturated[uint64]()
|
||||
testAddSaturated[uint]()
|
||||
|
||||
template testSubSaturated() =
|
||||
testSubSaturated[uint8]()
|
||||
testSubSaturated[uint16]()
|
||||
testSubSaturated[uint32]()
|
||||
testSubSaturated[uint64]()
|
||||
testSubSaturated[uint]()
|
||||
|
||||
template testMulWiden[T: SomeUnsignedInt]() =
|
||||
doAssert mulWiden(T.low, T.low) == (T.low, T.low)
|
||||
doAssert mulWiden(T(2), T(2)) == (T(4), T(0))
|
||||
@ -47,7 +69,17 @@ template testMulWiden[T: SomeUnsignedInt]() =
|
||||
doAssert mulWiden(T.high, T.high, T(0)) == (T(1), T.high - 1)
|
||||
doAssert mulWiden(T.high, T.high, T.high) == (T(0), T.high)
|
||||
|
||||
# TODO testMulOverflow
|
||||
template testMulSaturated[T: SomeUnsignedInt]() =
|
||||
doAssert mulSaturated(T(100), T(2)) == T(200)
|
||||
doAssert mulSaturated(T.high, T(10)) == T.high
|
||||
|
||||
template testMulSaturated() =
|
||||
testMulSaturated[uint8]()
|
||||
testMulSaturated[uint16]()
|
||||
testMulSaturated[uint32]()
|
||||
testMulSaturated[uint64]()
|
||||
testMulSaturated[uint]()
|
||||
|
||||
|
||||
template testMulWiden() =
|
||||
testMulWiden[uint8]()
|
||||
@ -59,7 +91,10 @@ template testMulWiden() =
|
||||
template test() =
|
||||
testAddOverflow()
|
||||
testSubOverflow()
|
||||
testAddSaturated()
|
||||
testSubSaturated()
|
||||
testMulWiden()
|
||||
testMulSaturated
|
||||
|
||||
static: test()
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user