test against intx library

This commit is contained in:
jangko 2023-07-07 08:59:38 +07:00
parent ea02d7db68
commit d198ec031e
No known key found for this signature in database
GPG Key ID: 31702AE10541E6B9
9 changed files with 2398 additions and 371 deletions

View File

@ -30,11 +30,11 @@ jobs:
shell: bash
- target:
os: macos
builder: macos-11
builder: macos-12
shell: bash
- target:
os: windows
builder: windows-2019
builder: windows-latest
shell: msys2 {0}
defaults:
@ -47,22 +47,29 @@ jobs:
- name: Checkout
uses: actions/checkout@v3
- name: Set GCC 10 as default compiler (Linux)
if: runner.os == 'Linux' && matrix.target.cpu != 'i386'
run: |
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 100 \
--slave /usr/bin/g++ g++ /usr/bin/g++-10 \
--slave /usr/bin/gcov gcov /usr/bin/gcov-10
- name: Install build dependencies (Linux i386)
if: runner.os == 'Linux' && matrix.target.cpu == 'i386'
run: |
sudo dpkg --add-architecture i386
sudo apt-fast update -qq
sudo DEBIAN_FRONTEND='noninteractive' apt-fast install \
--no-install-recommends -yq gcc-multilib g++-multilib \
libssl-dev:i386
--no-install-recommends -yq gcc-10-multilib g++-10-multilib \
libssl-dev:i386 linux-libc-dev:i386
mkdir -p external/bin
cat << EOF > external/bin/gcc
#!/bin/bash
exec $(which gcc) -m32 "\$@"
exec $(which gcc-10) -m32 "\$@"
EOF
cat << EOF > external/bin/g++
#!/bin/bash
exec $(which g++) -m32 "\$@"
exec $(which g++-10) -m32 "\$@"
EOF
chmod 755 external/bin/gcc external/bin/g++
echo '${{ github.workspace }}/external/bin' >> $GITHUB_PATH
@ -155,6 +162,6 @@ jobs:
nim --version
nimble --version
nimble install -y --depsOnly
#nimble install -y https://github.com/alehander42/nim-quicktest ttmath
env TEST_LANG="c" nimble test
#env TEST_LANG="cpp" nimble test
# run test against intx
env TEST_LANG="cpp" nimble test

View File

@ -28,12 +28,6 @@ task test_internal, "Run tests for internal procs":
task test_public_api, "Run all tests - prod implementation (StUint[64] = uint64":
test "", "tests/all_tests"
task test_uint256_ttmath, "Run random tests Uint256 vs TTMath":
requires "https://github.com/alehander42/nim-quicktest >= 0.18.0", "https://github.com/status-im/nim-ttmath"
putEnv("TEST_LANG", "cpp")
switch("define", "release")
test "", "tests/test_uint256_ttmath"
task test, "Run all tests":
exec "nimble test_internal"
exec "nimble test_public_api"

View File

@ -37,4 +37,7 @@ import
t_randomized_divmod,
test_bugfix,
test_features
when defined(cpp):
import
test_vs_intx

2043
tests/intx/intx.hpp Normal file

File diff suppressed because it is too large Load Diff

163
tests/intx/intx.nim Normal file
View File

@ -0,0 +1,163 @@
import strutils
from os import DirSep
const intxPath = currentSourcePath.rsplit(DirSep, 1)[0]
{.passc: "-I" & intxPath.}
{.passc: "-std=c++20".}
const INTX_HEADER = intxPath & "/intx.hpp"
static:
debugEcho INTX_HEADER
type
UInt*[NumBits: static[int]] {.importcpp: "intx::uint<'0>", header: INTX_HEADER.} = object
TTInt = UInt
stdString {.importc: "std::string", header: "<string.h>".} = object
proc `+`*(a, b: TTInt): TTInt {.importcpp: "(# + #)".}
proc `-`*(a, b: TTInt): TTInt {.importcpp: "(# - #)".}
proc `*`*(a, b: TTInt): TTInt {.importcpp: "(# * #)".}
proc `/`*(a, b: TTInt): TTInt {.importcpp: "(# / #)".}
proc `div`*(a, b: TTInt): TTInt {.importcpp: "(# / #)".}
proc `mod`*(a, b: TTInt): TTInt {.importcpp: "(# % #)".}
proc `==`*(a, b: TTInt): bool {.importcpp: "(# == #)".}
proc `<`*(a, b: TTInt): bool {.importcpp: "(# < #)".}
proc `<=`*(a, b: TTInt): bool {.importcpp: "(# <= #)".}
proc `+=`*(a: var TTInt, b: TTInt) {.importcpp: "# += #".}
proc `-=`*(a: var TTInt, b: TTInt) {.importcpp: "# -= #".}
proc `*=`*(a: var TTInt, b: TTInt) {.importcpp: "# *= #".}
proc `/=`*(a: var TTInt, b: TTInt) {.importcpp: "# /= #".}
proc `and`*(a, b: TTInt): TTInt {.importcpp: "(# & #)".}
proc `or`*(a, b: TTInt): TTInt {.importcpp: "(# | #)".}
proc `xor`*(a, b: TTInt): TTInt {.importcpp: "(# ^ #)".}
proc `|=`*(a: var TTInt, b: TTInt) {.importcpp: "(# |= #)".}
proc `&=`*(a: var TTInt, b: TTInt) {.importcpp: "(# &= #)".}
proc `^=`*(a: var TTInt, b: TTInt) {.importcpp: "(# ^= #)".}
proc `shl`*(a: UInt, b: uint64): UInt {.importcpp: "(# << #)".}
proc `shr`*(a: UInt, b: uint64): UInt {.importcpp: "(# >> #)".}
proc pow*(a, b: TTInt): TTInt {.importcpp: "exp(#,#)".}
proc ToString(a: TTInt, base: cint): stdString {.importcpp: "to_string", header: INTX_HEADER.}
proc toString*(a: TTInt, base: int = 10): string =
let tmp = a.ToString(cint(base))
var tmps: cstring
{.emit: """
`tmps` = const_cast<char*>(`tmp`.c_str());
""".}
result = $tmps
proc `$`*(a: TTInt): string {.inline.} = a.toString()
proc initUInt[T](a: uint64): T {.importcpp: "'0{#}".}
proc pow*(a: UInt, b: uint64): UInt =
pow(a, initUInt[UInt](b))
#[
proc FromString(a: var TTInt, s: cstring, base: uint) {.importcpp, header: INTX_HEADER.}
proc fromString*(a: var TTInt, s: cstring, base: int = 10) = a.FromString(s, uint(base))
proc fromHex*(a: var TTInt, s: string) {.inline.} = a.fromString(s, 16)
proc initInt[T](a: int64): T {.importcpp: "'0((int)#)".}
proc initInt[T](a: cstring): T {.importcpp: "'0(#)".}
template defineIntConstructor(typ: typedesc, name: untyped{nkIdent}) =
template name*(a: int64): typ = initInt[typ](a)
template name*(a: cstring): typ = initInt[typ](a)
template `+`*(a: typ, b: int): typ = a + initInt[typ](b)
template `+`*(a: int, b: typ): typ = initInt[typ](a) + b
template `-`*(a: typ, b: int): typ = a - initInt[typ](b)
template `-`*(a: int, b: typ): typ = initInt[typ](a) - b
template `+=`*(a: var typ, b: int) = a += initInt[typ](b)
template `-=`*(a: var typ, b: int) = a -= initInt[typ](b)
defineIntConstructor(Int256, i256)
defineIntConstructor(Int512, i512)
defineIntConstructor(Int1024, i1024)
defineIntConstructor(Int2048, i2048)
template defineUIntConstructor(typ: typedesc, name: untyped{nkIdent}) =
template name*(a: uint64): typ = initUInt[typ](a)
template name*(a: cstring): typ = initInt[typ](a)
template `+`*(a: typ, b: int): typ = a + initUInt[typ](b)
template `+`*(a: int, b: typ): typ = initUInt[typ](a) + b
template `-`*(a: typ, b: int): typ = a - initUInt[typ](b)
template `-`*(a: int, b: typ): typ = initUInt[typ](a) - b
template `+=`*(a: var typ, b: uint) = a += initUInt[typ](b)
template `-=`*(a: var typ, b: uint) = a -= initUInt[typ](b)
defineUIntConstructor(UInt256, u256)
defineUIntConstructor(UInt512, u512)
defineUIntConstructor(UInt1024, u1024)
defineUIntConstructor(UInt2048, u2048)
proc `-`*(a: Int): Int {.importcpp: "(- #)".}
proc pow*(a: Int, b: int): Int =
var tmp = a
tmp.inplacePow(initInt[Int](b))
result = tmp
proc pow*(a: UInt, b: uint64): UInt =
var tmp = a
tmp.inplacePow(initUInt[UInt](b))
result = tmp
proc `shl`*(a: Int, b: int): Int {.importcpp: "(# << #)".}
proc `shr`*(a: Int, b: int): Int {.importcpp: "(# >> #)".}
proc getInt*(a: Int): int {.importcpp: "ToInt", header: INTX_HEADER.}
proc getUInt*(a: UInt): uint64 {.importcpp: "ToUInt", header: INTX_HEADER.}
proc setZero*(a: var TTInt) {.importcpp: "SetZero", header: INTX_HEADER.}
proc setOne*(a: var TTInt) {.importcpp: "SetOne", header: INTX_HEADER.}
proc setMin*(a: var TTInt) {.importcpp: "SetMin", header: INTX_HEADER.}
proc setMax*(a: var TTInt) {.importcpp: "SetMax", header: INTX_HEADER.}
proc clearFirstBits*(a: var TTInt, n: uint) {.importcpp: "ClearFirstBits", header: INTX_HEADER.}
template max*[T: TTInt]: TTInt =
var r = initInt[T](0)
r.setMax()
r
proc hexToUInt*[N](hexStr: string): UInt[N] {.inline.} = result.fromHex(hexStr)
proc toHex*(a: TTInt): string {.inline.} = a.toString(16)
proc toByteArrayBE*[N](num: UInt[N]): array[N div 8, byte] {.noSideEffect, noinit, inline.} =
## Convert a TTInt (in native host endianness) to a big-endian byte array
const N = result.len
for i in 0 ..< N:
{.unroll: 4.}
result[i] = byte getUInt(num shr uint((N-1-i) * 8))
proc readUIntBE*[N](ba: openArray[byte]): UInt[N] {.noSideEffect, inline.} =
## Convert a big-endian array of Bytes to an UInt256 (in native host endianness)
const sz = N div 8
assert(ba.len >= sz)
for i in 0 ..< sz:
{.unroll: 4.}
result = result shl 8 or initUInt[UInt[N]](ba[i])
proc inc*(a: var TTInt, n = 1) {.inline.} =
when a is Int:
a += initInt[type a](n)
else:
a += initUInt[type a](n.uint)
proc dec*(a: var TTInt, n = 1) {.inline.} =
when a is Int:
a -= initInt[type a](n)
else:
a -= initUInt[type a](n.uint)
]#

View File

@ -0,0 +1,18 @@
import
../../stint,
./intx
export intx
template asSt*(val: UInt): auto =
type TargetType = StUint[val.NumBits]
cast[ptr TargetType](unsafeAddr val)[]
template asTT*[N: static[int]](arr: array[N, uint64]): auto =
type TargetType = UInt[N * 64]
cast[ptr TargetType](unsafeAddr arr[0])[]
template asTT*(x: StUint): auto =
type TargetType = UInt[x.bits]
var arr = x.toBytes(cpuEndian)
cast[ptr TargetType](addr arr[0])[]

View File

@ -1,337 +0,0 @@
# 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.
# Requires "https://github.com/status-im/nim-ttmath#master"
# Note that currently importing both Stint and TTMath will crash the compiler for unknown reason
import ../stint, unittest, quicktest, ttmath_compat
const itercount = 10_000
suite "Property-based testing (testing with random inputs) of Uint256":
when defined(release):
echo "Testing in release mode with " & $itercount & " random tests for each proc."
else:
echo "Testing in debug mode " & $itercount & " random tests for each proc. (StUint[64] = 2x uint32)"
let hi = 1'u shl (sizeof(uint64)*7)
quicktest "`or`", itercount do(x0: uint64(min=0, max=hi),
x1: uint64(min=0, max=hi),
x2: uint64(min=0, max=hi),
x3: uint64(min=0, max=hi),
y0: uint64(min=0, max=hi),
y1: uint64(min=0, max=hi),
y2: uint64(min=0, max=hi),
y3: uint64(min=0, max=hi)):
let
x = [x0, x1, x2, x3]
y = [y0, y1, y2, y3]
ttm_x = x.asTT
ttm_y = y.asTT
mp_x = cast[StUint[256]](x)
mp_y = cast[StUint[256]](y)
let
ttm_z = ttm_x or ttm_y
mp_z = mp_x or mp_y
check ttm_z.asSt == mp_z
quicktest "`and`", itercount do(x0: uint64(min=0, max=hi),
x1: uint64(min=0, max=hi),
x2: uint64(min=0, max=hi),
x3: uint64(min=0, max=hi),
y0: uint64(min=0, max=hi),
y1: uint64(min=0, max=hi),
y2: uint64(min=0, max=hi),
y3: uint64(min=0, max=hi)):
let
x = [x0, x1, x2, x3]
y = [y0, y1, y2, y3]
ttm_x = x.asTT
ttm_y = y.asTT
mp_x = cast[StUint[256]](x)
mp_y = cast[StUint[256]](y)
let
ttm_z = ttm_x and ttm_y
mp_z = mp_x and mp_y
check ttm_z.asSt == mp_z
quicktest "`xor`", itercount do(x0: uint64(min=0, max=hi),
x1: uint64(min=0, max=hi),
x2: uint64(min=0, max=hi),
x3: uint64(min=0, max=hi),
y0: uint64(min=0, max=hi),
y1: uint64(min=0, max=hi),
y2: uint64(min=0, max=hi),
y3: uint64(min=0, max=hi)):
let
x = [x0, x1, x2, x3]
y = [y0, y1, y2, y3]
ttm_x = x.asTT
ttm_y = y.asTT
mp_x = cast[StUint[256]](x)
mp_y = cast[StUint[256]](y)
let
ttm_z = ttm_x xor ttm_y
mp_z = mp_x xor mp_y
check ttm_z.asSt == mp_z
# Not defined for ttmath
# quicktest "`not`", itercount do(x0: uint64(min=0, max=hi),
# x1: uint64(min=0, max=hi),
# x2: uint64(min=0, max=hi),
# x3: uint64(min=0, max=hi):
# let
# x = [x0, x1, x2, x3]
# y = [y0, y1, y2, y3]
# ttm_x = cast[ttmath.UInt256](x)
# mp_x = cast[StUint[256]](x)
# let
# ttm_z = not ttm_x
# mp_z = not mp_x
# check(cast[array[4, uint64]](ttm_z) == cast[array[4, uint64]](mp_z))
quicktest "`<`", itercount do(x0: uint64(min=0, max=hi),
x1: uint64(min=0, max=hi),
x2: uint64(min=0, max=hi),
x3: uint64(min=0, max=hi),
y0: uint64(min=0, max=hi),
y1: uint64(min=0, max=hi),
y2: uint64(min=0, max=hi),
y3: uint64(min=0, max=hi)):
let
x = [x0, x1, x2, x3]
y = [y0, y1, y2, y3]
ttm_x = x.asTT
ttm_y = y.asTT
mp_x = cast[StUint[256]](x)
mp_y = cast[StUint[256]](y)
let
ttm_z = ttm_x < ttm_y
mp_z = mp_x < mp_y
check(ttm_z == mp_z)
quicktest "`<=`", itercount do(x0: uint64(min=0, max=hi),
x1: uint64(min=0, max=hi),
x2: uint64(min=0, max=hi),
x3: uint64(min=0, max=hi),
y0: uint64(min=0, max=hi),
y1: uint64(min=0, max=hi),
y2: uint64(min=0, max=hi),
y3: uint64(min=0, max=hi)):
let
x = [x0, x1, x2, x3]
y = [y0, y1, y2, y3]
ttm_x = x.asTT
ttm_y = y.asTT
mp_x = cast[StUint[256]](x)
mp_y = cast[StUint[256]](y)
let
ttm_z = ttm_x <= ttm_y
mp_z = mp_x <= mp_y
check(ttm_z == mp_z)
quicktest "`+`", itercount do(x0: uint64(min=0, max=hi),
x1: uint64(min=0, max=hi),
x2: uint64(min=0, max=hi),
x3: uint64(min=0, max=hi),
y0: uint64(min=0, max=hi),
y1: uint64(min=0, max=hi),
y2: uint64(min=0, max=hi),
y3: uint64(min=0, max=hi)):
let
x = [x0, x1, x2, x3]
y = [y0, y1, y2, y3]
ttm_x = x.asTT
ttm_y = y.asTT
mp_x = cast[StUint[256]](x)
mp_y = cast[StUint[256]](y)
let
ttm_z = ttm_x + ttm_y
mp_z = mp_x + mp_y
check ttm_z.asSt == mp_z
quicktest "`-`", itercount do(x0: uint64(min=0, max=hi),
x1: uint64(min=0, max=hi),
x2: uint64(min=0, max=hi),
x3: uint64(min=0, max=hi),
y0: uint64(min=0, max=hi),
y1: uint64(min=0, max=hi),
y2: uint64(min=0, max=hi),
y3: uint64(min=0, max=hi)):
let
x = [x0, x1, x2, x3]
y = [y0, y1, y2, y3]
ttm_x = x.asTT
ttm_y = y.asTT
mp_x = cast[StUint[256]](x)
mp_y = cast[StUint[256]](y)
let
ttm_z = ttm_x - ttm_y
mp_z = mp_x - mp_y
check ttm_z.asSt == mp_z
quicktest "`*`", itercount do(x0: uint64(min=0, max=hi),
x1: uint64(min=0, max=hi),
x2: uint64(min=0, max=hi),
x3: uint64(min=0, max=hi),
y0: uint64(min=0, max=hi),
y1: uint64(min=0, max=hi),
y2: uint64(min=0, max=hi),
y3: uint64(min=0, max=hi)):
let
x = [x0, x1, x2, x3]
y = [y0, y1, y2, y3]
ttm_x = x.asTT
ttm_y = y.asTT
mp_x = cast[StUint[256]](x)
mp_y = cast[StUint[256]](y)
let
ttm_z = ttm_x * ttm_y
mp_z = mp_x * mp_y
check ttm_z.asSt == mp_z
quicktest "`shl`", itercount do(x0: uint64(min=0, max=hi),
x1: uint64(min=0, max=hi),
x2: uint64(min=0, max=hi),
x3: uint64(min=0, max=hi),
y: int(min = 0, max=(255))):
let
x = [x0, x1, x2, x3]
ttm_x = x.asTT
mp_x = cast[StUint[256]](x)
let
ttm_z = ttm_x shl y.uint
mp_z = mp_x shl y
check ttm_z.asSt == mp_z
quicktest "`shr`", itercount do(x0: uint64(min=0, max=hi),
x1: uint64(min=0, max=hi),
x2: uint64(min=0, max=hi),
x3: uint64(min=0, max=hi),
y: int(min = 0, max=(255))):
let
x = [x0, x1, x2, x3]
ttm_x = x.asTT
mp_x = cast[StUint[256]](x)
let
ttm_z = ttm_x shr y.uint
mp_z = mp_x shr y
check ttm_z.asSt == mp_z
quicktest "`mod`", itercount do(x0: uint64(min=0, max=hi),
x1: uint64(min=0, max=hi),
x2: uint64(min=0, max=hi),
x3: uint64(min=0, max=hi),
y0: uint64(min=0, max=hi),
y1: uint64(min=0, max=hi),
y2: uint64(min=0, max=hi),
y3: uint64(min=0, max=hi)):
let
x = [x0, x1, x2, x3]
y = [y0, y1, y2, y3]
ttm_x = x.asTT
ttm_y = y.asTT
mp_x = cast[StUint[256]](x)
mp_y = cast[StUint[256]](y)
let
ttm_z = ttm_x mod ttm_y
mp_z = mp_x mod mp_y
check ttm_z.asSt == mp_z
quicktest "`div`", itercount do(x0: uint64(min=0, max=hi),
x1: uint64(min=0, max=hi),
x2: uint64(min=0, max=hi),
x3: uint64(min=0, max=hi),
y0: uint64(min=0, max=hi),
y1: uint64(min=0, max=hi),
y2: uint64(min=0, max=hi),
y3: uint64(min=0, max=hi)):
let
x = [x0, x1, x2, x3]
y = [y0, y1, y2, y3]
ttm_x = x.asTT
ttm_y = y.asTT
mp_x = cast[StUint[256]](x)
mp_y = cast[StUint[256]](y)
let
ttm_z = ttm_x div ttm_y
mp_z = mp_x div mp_y
check ttm_z.asSt == mp_z
quicktest "pow", itercount do(x0: uint64(min=0, max=hi),
x1: uint64(min=0, max=hi),
x2: uint64(min=0, max=hi),
x3: uint64(min=0, max=hi),
y : int(min=0, max=high(int))):
let
x = [x0, x1, x2, x3]
ttm_x = x.asTT
mp_x = cast[StUint[256]](x)
let
ttm_z = ttm_x.pow(y.uint)
mp_z = mp_x.pow y
check ttm_z.asSt == mp_z

155
tests/test_vs_intx.nim Normal file
View File

@ -0,0 +1,155 @@
# 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
std/[times, random],
unittest,
./intx/intx_compat,
../stint,
../helpers/prng_unsafe
const
itercount = 10_000
let seed = uint32(getTime().toUnix() and (1'i64 shl 32 - 1)) # unixTime mod 2^32
var rng: RngState
rng.seed(seed)
template testLoopImpl(bits: static int, name: string, gen: RandomGen, body: untyped) =
test name & " " & $gen & " " & $bits & " bits":
for _ in 0 ..< itercount:
let
mp_x {.inject.} = rng.random_elem(StUint[bits], gen)
mp_y {.inject.} = rng.random_elem(StUint[bits], gen)
ttm_x {.inject.} = asTT(mp_x)
ttm_y {.inject.} = asTT(mp_y)
body
template testLoop(bits: static int, name: string, body: untyped) =
testLoopImpl(bits, name, Long01Sequence, body)
testLoopImpl(bits, name, HighHammingWeight, body)
testLoopImpl(bits, name, Uniform, body)
template testYImpl(bits: static int, name: string, gen: RandomGen, maxY: uint64, body: untyped) =
test name & " " & $gen & " " & $bits & " bits":
var xrng = initRand()
for _ in 0 ..< itercount:
let
mp_x {.inject.} = rng.random_elem(StUint[bits], gen)
ttm_x {.inject.} = asTT(mp_x)
y {.inject.} = xrng.rand(maxY)
body
template testY(bits: static int, name: string, maxY: uint64, body: untyped) =
testYImpl(bits, name, Long01Sequence, maxY, body)
testYImpl(bits, name, HighHammingWeight, maxY, body)
testYImpl(bits, name, Uniform, maxY, body)
suite "Property-based testing (testing with random inputs) of UInt":
when defined(release):
echo "Testing in release mode with " & $itercount & " random tests for each proc."
else:
echo "Testing in debug mode " & $itercount & " random tests for each proc. (StUint[64] = 2x uint32)"
testLoop(256, "`or`"):
let
ttm_z = ttm_x or ttm_y
mp_z = mp_x or mp_y
check ttm_z.asSt == mp_z
testLoop(256, "`and`"):
let
ttm_z = ttm_x and ttm_y
mp_z = mp_x and mp_y
check ttm_z.asSt == mp_z
testLoop(256, "`xor`"):
let
ttm_z = ttm_x xor ttm_y
mp_z = mp_x xor mp_y
check ttm_z.asSt == mp_z
testLoop(256, "`<`"):
let
ttm_z = ttm_x < ttm_y
mp_z = mp_x < mp_y
check(ttm_z == mp_z)
testLoop(256, "`<=`"):
let
ttm_z = ttm_x <= ttm_y
mp_z = mp_x <= mp_y
check(ttm_z == mp_z)
testLoop(256, "`+`"):
let
ttm_z = ttm_x + ttm_y
mp_z = mp_x + mp_y
check ttm_z.asSt == mp_z
testLoop(256, "`-`"):
let
ttm_z = ttm_x - ttm_y
mp_z = mp_x - mp_y
check ttm_z.asSt == mp_z
testLoop(256, "`*`"):
let
ttm_z = ttm_x * ttm_y
mp_z = mp_x * mp_y
check ttm_z.asSt == mp_z
testLoop(256, "`div`"):
if not mp_y.isZero:
let
ttm_z = ttm_x div ttm_y
mp_z = mp_x div mp_y
check ttm_z.asSt == mp_z
testLoop(256, "`mod`"):
if not mp_y.isZero:
let
ttm_z = ttm_x mod ttm_y
mp_z = mp_x mod mp_y
check ttm_z.asSt == mp_z
testY(256, "`pow`", high(int).uint64):
let
ttm_z = ttm_x.pow y.uint64
mp_z = mp_x.pow y
check ttm_z.asSt == mp_z
testY(256, "`shl`", 255'u64):
let
ttm_z = ttm_x shl y.uint
mp_z = mp_x shl y
check ttm_z.asSt == mp_z
testY(256, "`shr`", 255'u64):
let
ttm_z = ttm_x shr y.uint
mp_z = mp_x shr y
check ttm_z.asSt == mp_z

View File

@ -1,19 +0,0 @@
import ../stint, ttmath/ttmath
export ttmath
template asSt*(val: UInt): auto =
type TargetType = StUint[val.NumBits]
cast[ptr TargetType](unsafeAddr val)[]
template asSt*(val: Int): auto =
type TargetType = StInt[val.NumBits]
cast[ptr TargetType](unsafeAddr val)[]
template asTT*[N: static[int]](arr: array[N, uint64]): auto =
type TargetType = UInt[N * 64]
cast[ptr TargetType](unsafeAddr arr[0])[]
template asTT*[N: static[int]](arr: array[N, int64]): auto =
type TargetType = Int[N * 64]
cast[ptr TargetType](unsafeAddr arr[0])[]