340 lines
9.6 KiB
Nim
340 lines
9.6 KiB
Nim
# Stint
|
|
# Copyright 2018 Status Research & Development GmbH
|
|
# Licensed under either of
|
|
#
|
|
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
|
|
# * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
|
|
#
|
|
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
|
|
|
import ../stint, unittest, test_helpers
|
|
|
|
template chkLT(chk: untyped, a, b: string, bits: int) =
|
|
chk fromHex(StInt[bits], a) < fromHex(StInt[bits], b)
|
|
|
|
template chkNotLT(chk: untyped, a, b: string, bits: int) =
|
|
chk (not(fromHex(StInt[bits], b) < fromHex(StInt[bits], a)))
|
|
|
|
template chkLTE(chk: untyped, a, b: string, bits: int) =
|
|
chk fromHex(StInt[bits], a) <= fromHex(StInt[bits], b)
|
|
|
|
template chkNotLTE(chk: untyped, a, b: string, bits: int) =
|
|
chk (not(fromHex(StInt[bits], b) <= fromHex(StInt[bits], a)))
|
|
|
|
template chkEQ(chk: untyped, a, b: string, bits: int) =
|
|
chk fromHex(StInt[bits], a) == fromHex(StInt[bits], b)
|
|
|
|
template chkNotEQ(chk: untyped, a, b: string, bits: int) =
|
|
chk (not(fromHex(StInt[bits], a) == fromHex(StInt[bits], b)))
|
|
|
|
template chkIsZero(chk: untyped, a: string, bits: int) =
|
|
chk fromHex(StInt[bits], a).isZero()
|
|
|
|
template chkNotIsZero(chk: untyped, a: string, bits: int) =
|
|
chk (not fromHex(StInt[bits], a).isZero())
|
|
|
|
template chkIsNegative(chk: untyped, a: string, bits: int) =
|
|
chk fromHex(StInt[bits], a).isNegative()
|
|
|
|
template chkNotIsNegative(chk: untyped, a: string, bits: int) =
|
|
chk (not fromHex(StInt[bits], a).isNegative())
|
|
|
|
template chkIsOdd(chk: untyped, a: string, bits: int) =
|
|
chk fromHex(StInt[bits], a).isOdd()
|
|
|
|
template chkNotIsOdd(chk: untyped, a: string, bits: int) =
|
|
chk (not fromHex(StInt[bits], a).isOdd())
|
|
|
|
template chkIsEven(chk: untyped, a: string, bits: int) =
|
|
chk fromHex(StInt[bits], a).isEven()
|
|
|
|
template chkNotIsEven(chk: untyped, a: string, bits: int) =
|
|
chk (not fromHex(StInt[bits], a).isEven())
|
|
|
|
template testComparison(chk, tst: untyped) =
|
|
tst "operator `LT`":
|
|
chk 0.i128 < 1.i128
|
|
chk -1.i128 < 1.i128
|
|
chk -1.i128 < 0.i128
|
|
chk Int128.low < Int128.high
|
|
chk -2.i128 < -1.i128
|
|
chk 1.i128 < 2.i128
|
|
chk 10000.i128 < Int128.high
|
|
chk Int128.low < 10000.i128
|
|
|
|
chk 0.i256 < 1.i256
|
|
chk -1.i256 < 1.i256
|
|
chk -1.i256 < 0.i256
|
|
chk Int256.low < Int256.high
|
|
chk -2.i256 < -1.i256
|
|
chk 1.i256 < 2.i256
|
|
|
|
chkLT(chk, "0", "F", 128)
|
|
chkLT(chk, "F", "FF", 128)
|
|
chkLT(chk, "FF", "FFF", 128)
|
|
chkLT(chk, "FFFF", "FFFFF", 128)
|
|
chkLT(chk, "FFFFF", "FFFFFFFF", 128)
|
|
chkLT(chk, "FFFFFFFFFFF", "FFFFFFFFFFFFFFFFFFFFFFFF", 128)
|
|
chkLT(chk, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", "FFFFFFFFFFFFFFFFFFFFFFFF", 128)
|
|
|
|
tst "operator `GT`":
|
|
chk 1.i128 > 0.i128
|
|
chk 1.i128 > -1.i128
|
|
chk 0.i128 > -1.i128
|
|
chk Int128.high > Int128.low
|
|
chk -1.i128 > -2.i128
|
|
chk 2.i128 > 1.i128
|
|
|
|
chk 1.i256 > 0.i256
|
|
chk 1.i256 > -1.i256
|
|
chk 0.i256 > -1.i256
|
|
chk Int256.high > Int256.low
|
|
chk -1.i256 > -2.i256
|
|
chk 2.i256 > 1.i256
|
|
|
|
chkNotLT(chk, "0", "F", 128)
|
|
chkNotLT(chk, "F", "FF", 128)
|
|
chkNotLT(chk, "FF", "FFF", 128)
|
|
chkNotLT(chk, "FFFF", "FFFFF", 128)
|
|
chkNotLT(chk, "FFFFF", "FFFFFFFF", 128)
|
|
chkNotLT(chk, "FFFFFFFFFFF", "FFFFFFFFFFFFFFFFFFFFFFFF", 128)
|
|
chkNotLT(chk, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", "FFFFFFFFFFFFFFFFFFFFFFFF", 128)
|
|
|
|
tst "operator `LTE`":
|
|
chk 0.i128 <= 1.i128
|
|
chk -1.i128 <= 1.i128
|
|
chk -1.i128 <= 0.i128
|
|
chk Int128.low <= Int128.high
|
|
chk -2.i128 <= -1.i128
|
|
chk 1.i128 <= 2.i128
|
|
chk 10000.i128 <= Int128.high
|
|
chk Int128.low <= 10000.i128
|
|
chk Int128.low <= Int128.low
|
|
chk Int128.high <= Int128.high
|
|
chk 10000.i128 <= 10000.i128
|
|
|
|
chk 0.i256 <= 1.i256
|
|
chk -1.i256 <= 1.i256
|
|
chk -1.i256 <= 0.i256
|
|
chk Int256.low <= Int256.high
|
|
chk -2.i256 <= -1.i256
|
|
chk 1.i256 <= 2.i256
|
|
chk 10000.i256 <= Int256.high
|
|
chk Int256.low <= 10000.i256
|
|
chk Int256.low <= Int256.low
|
|
chk Int256.high <= Int256.high
|
|
chk 10000.i256 <= 10000.i256
|
|
|
|
chkLTE(chk, "0", "F", 128)
|
|
chkLTE(chk, "F", "FF", 128)
|
|
chkLTE(chk, "FF", "FFF", 128)
|
|
chkLTE(chk, "FFFF", "FFFFF", 128)
|
|
chkLTE(chk, "FFFFF", "FFFFFFFF", 128)
|
|
chkLTE(chk, "FFFFFFFFFFF", "FFFFFFFFFFFFFFFFFFFFFFFF", 128)
|
|
chkLTE(chk, "FFFFFFFFFFFFFFFFFFFFFFFF", "FFFFFFFFFFFFFFFFFFFFFFFF", 128)
|
|
chkLTE(chk, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", "FFFFFFFFFFFFFFFFFFFFFFFF", 128)
|
|
|
|
tst "operator `GTE`":
|
|
chk 1.i128 >= 0.i128
|
|
chk 1.i128 >= -1.i128
|
|
chk 0.i128 >= -1.i128
|
|
chk Int128.high >= Int128.low
|
|
chk -1.i128 >= -2.i128
|
|
chk 2.i128 >= 1.i128
|
|
chk Int128.high >= 10000.i128
|
|
chk 10000.i128 >= Int128.low
|
|
chk Int128.low >= Int128.low
|
|
chk Int128.high >= Int128.high
|
|
chk 10000.i128 >= 10000.i128
|
|
|
|
chk 1.i256 >= 0.i256
|
|
chk 1.i256 >= -1.i256
|
|
chk 0.i256 >= -1.i256
|
|
chk Int256.high >= Int256.low
|
|
chk -1.i256 >= -2.i256
|
|
chk 2.i256 >= 1.i256
|
|
chk Int256.high >= 10000.i256
|
|
chk 10000.i256 >= Int256.low
|
|
chk Int256.low >= Int256.low
|
|
chk Int256.high >= Int256.high
|
|
chk 10000.i256 >= 10000.i256
|
|
|
|
chkNotLTE(chk, "0", "F", 128)
|
|
chkNotLTE(chk, "F", "FF", 128)
|
|
chkNotLTE(chk, "FF", "FFF", 128)
|
|
chkNotLTE(chk, "FFFF", "FFFFF", 128)
|
|
chkNotLTE(chk, "FFFFF", "FFFFFFFF", 128)
|
|
chkNotLTE(chk, "FFFFFFFFFFF", "FFFFFFFFFFFFFFFFFFFFFFFF", 128)
|
|
chkNotLTE(chk, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", "FFFFFFFFFFFFFFFFFFFFFFFF", 128)
|
|
|
|
tst "operator `EQ`":
|
|
chk 0.i128 == 0.i128
|
|
chk 1.i128 == 1.i128
|
|
chk -1.i128 == -1.i128
|
|
chk Int128.high == Int128.high
|
|
chk Int128.low == Int128.low
|
|
|
|
chk 0.i256 == 0.i256
|
|
chk 1.i256 == 1.i256
|
|
chk -1.i256 == -1.i256
|
|
chk Int256.high == Int256.high
|
|
chk Int256.low == Int256.low
|
|
|
|
chkEQ(chk, "0", "0", 128)
|
|
chkEQ(chk, "F", "F", 128)
|
|
chkEQ(chk, "FF", "FF", 128)
|
|
chkEQ(chk, "FFFF", "FFFF", 128)
|
|
chkEQ(chk, "FFFFF", "FFFFF", 128)
|
|
chkEQ(chk, "FFFFFFFFFFFFFFFFFFFFFFFF", "FFFFFFFFFFFFFFFFFFFFFFFF", 128)
|
|
|
|
tst "operator not `EQ`":
|
|
chk Int128.low != Int128.high
|
|
chk Int128.high != Int128.low
|
|
chk 0.i256 != 1.i256
|
|
chk 1.i256 != 0.i256
|
|
chk 1.i256 != -1.i256
|
|
chk -1.i256 != 1.i256
|
|
|
|
chkNotEQ(chk, "0", "F", 128)
|
|
chkNotEQ(chk, "F", "FF", 128)
|
|
chkNotEQ(chk, "FF", "FFF", 128)
|
|
chkNotEQ(chk, "FFFF", "FFFFF", 128)
|
|
chkNotEQ(chk, "FFFFF", "FFAFFFFF", 128)
|
|
chkNotEQ(chk, "FFFFFFFFFFF", "AFFFFFFFFFFFFFFFFFFFFFFF", 128)
|
|
|
|
tst "operator `isZero`":
|
|
chkIsZero(chk, "0", 128)
|
|
chkIsZero(chk, "0", 256)
|
|
|
|
tst "operator not `isZero`":
|
|
chkNotIsZero(chk, "5", 128)
|
|
chkNotIsZero(chk, "6", 256)
|
|
|
|
chkNotIsZero(chk, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 128)
|
|
chkNotIsZero(chk, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 256)
|
|
|
|
tst "operator `isNegative`":
|
|
chkIsNegative(chk, "F0000000000000000000000000000000", 128)
|
|
chkIsNegative(chk, "F000000000000000000000000000000000000000000000000000000000000000", 256)
|
|
|
|
chkIsNegative(chk, "A5000000000000000000000000000000", 128)
|
|
chkIsNegative(chk, "A600000000000000000000000000000000000000000000000000000000000000", 256)
|
|
|
|
tst "operator not `isNegative`":
|
|
chkNotIsNegative(chk, "0", 128)
|
|
chkNotIsNegative(chk, "0", 256)
|
|
|
|
chkNotIsNegative(chk, "5", 128)
|
|
chkNotIsNegative(chk, "6", 256)
|
|
|
|
chkNotIsNegative(chk, "75000000000000000000000000000000", 128)
|
|
chkNotIsNegative(chk, "7600000000000000000000000000000000000000000000000000000000000000", 256)
|
|
|
|
tst "operator `isOdd`":
|
|
chkIsOdd(chk, "1", 128)
|
|
chkIsOdd(chk, "1", 256)
|
|
|
|
chkIsOdd(chk, "FFFFFFFFFFFFFFF", 128)
|
|
chkIsOdd(chk, "FFFFFFFFFFFFFFFFFF", 256)
|
|
|
|
tst "operator not `isOdd`":
|
|
chkNotIsOdd(chk, "0", 128)
|
|
chkNotIsOdd(chk, "0", 256)
|
|
|
|
chkNotIsOdd(chk, "4", 128)
|
|
chkNotIsOdd(chk, "4", 256)
|
|
|
|
chkNotIsOdd(chk, "FFFFFFFFFFFFFFA", 128)
|
|
chkNotIsOdd(chk, "FFFFFFFFFFFFFFFFFA", 256)
|
|
|
|
tst "operator `isEven`":
|
|
chkIsEven(chk, "0", 128)
|
|
chkIsEven(chk, "0", 256)
|
|
|
|
chkIsEven(chk, "4", 128)
|
|
chkIsEven(chk, "4", 256)
|
|
|
|
chkIsEven(chk, "FFFFFFFFFFFFFFA", 128)
|
|
chkIsEven(chk, "FFFFFFFFFFFFFFFFFA", 256)
|
|
|
|
tst "operator not `isEven`":
|
|
chkNotIsEven(chk, "1", 128)
|
|
chkNotIsEven(chk, "1", 256)
|
|
|
|
chkNotIsEven(chk, "FFFFFFFFFFFFFFF", 128)
|
|
chkNotIsEven(chk, "FFFFFFFFFFFFFFFFFF", 256)
|
|
|
|
tst "isOne":
|
|
let x = 1.i128
|
|
chk x.isOne
|
|
|
|
let y = 1.i256
|
|
chk y.isOne
|
|
|
|
static:
|
|
testComparison(ctCheck, ctTest)
|
|
|
|
proc main() =
|
|
# Nim GC protests we are using too much global variables
|
|
# so put it in a proc
|
|
|
|
suite "Wider signed int comparison coverage":
|
|
testComparison(check, test)
|
|
|
|
suite "Signed int - Testing comparison operators":
|
|
let
|
|
a = 10.i256
|
|
b = 15.i256
|
|
c = 150.i256
|
|
|
|
test "< operator":
|
|
check:
|
|
a < b
|
|
not (a + b < b)
|
|
not (a + a + a < b + b)
|
|
-c < c
|
|
-c < a
|
|
-b < -a
|
|
not(-b < -b)
|
|
|
|
test "<= operator":
|
|
check:
|
|
a <= b
|
|
not (a + b <= b)
|
|
a + a + a <= b + b
|
|
-c <= c
|
|
-c <= a
|
|
-b <= -a
|
|
-b <= -b
|
|
|
|
test "> operator":
|
|
check:
|
|
b > a
|
|
not (b > a + b)
|
|
not (b + b > a + a + a)
|
|
c > -c
|
|
a > -c
|
|
b > -c
|
|
not(-b > -b)
|
|
|
|
test ">= operator":
|
|
check:
|
|
b >= a
|
|
not (b >= a + b)
|
|
b + b >= a + a + a
|
|
c >= -c
|
|
a >= -c
|
|
b >= -c
|
|
-b >= -b
|
|
|
|
test "isOdd/isEven":
|
|
check:
|
|
a.isEven
|
|
not a.isOdd
|
|
b.isOdd
|
|
not b.isEven
|
|
c.isEven
|
|
not c.isOdd
|
|
|
|
main()
|