mirror of
https://github.com/status-im/nim-stint.git
synced 2025-02-21 03:18:13 +00:00
Add basic data structure, initialization and endianess test
This commit is contained in:
parent
364e11cf28
commit
6f77899709
15
mpint.nimble
15
mpint.nimble
@ -7,4 +7,17 @@ srcDir = "src"
|
|||||||
|
|
||||||
### Dependencies
|
### Dependencies
|
||||||
|
|
||||||
requires "nim >= 0.17.2"
|
requires "nim >= 0.17.2"
|
||||||
|
|
||||||
|
proc test(name: string, lang: string = "cpp") =
|
||||||
|
if not dirExists "build":
|
||||||
|
mkDir "build"
|
||||||
|
if not dirExists "nimcache":
|
||||||
|
mkDir "nimcache"
|
||||||
|
--run
|
||||||
|
--nimcache: "nimcache"
|
||||||
|
switch("out", ("./build/" & name))
|
||||||
|
setCommand lang, "tests/" & name & ".nim"
|
||||||
|
|
||||||
|
task test, "Run all tests":
|
||||||
|
test "all_tests"
|
8
src/mpint.nim
Normal file
8
src/mpint.nim
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# Copyright (c) 2018 Status Research & Development GmbH
|
||||||
|
# Distributed under the MIT License (license terms are at http://opensource.org/licenses/MIT).
|
||||||
|
|
||||||
|
import ./uint_type,
|
||||||
|
./uint_init
|
||||||
|
|
||||||
|
export uint_type,
|
||||||
|
uint_init
|
24
src/private/utils.nim
Normal file
24
src/private/utils.nim
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
# Copyright (c) 2018 Status Research & Development GmbH
|
||||||
|
# Distributed under the MIT License (license terms are at http://opensource.org/licenses/MIT).
|
||||||
|
|
||||||
|
import ../uint_type
|
||||||
|
|
||||||
|
proc bit_length*[T: BaseUint](n: T): int {.noSideEffect.}=
|
||||||
|
## Calculates how many bits are necessary to represent the number
|
||||||
|
result = 1
|
||||||
|
var y: T = n shr 1
|
||||||
|
while y > 0.T:
|
||||||
|
y = y shr 1
|
||||||
|
inc(result)
|
||||||
|
|
||||||
|
|
||||||
|
proc bit_length*[T: Natural](n: T): int {.noSideEffect.}=
|
||||||
|
## Calculates how many bits are necessary to represent the number
|
||||||
|
#
|
||||||
|
# For some reason using "BaseUint or Natural" directly makes Nim compiler
|
||||||
|
# throw a type mismatch
|
||||||
|
result = 1
|
||||||
|
var y: T = n shr 1
|
||||||
|
while y > 0.T:
|
||||||
|
y = y shr 1
|
||||||
|
inc(result)
|
29
src/uint_init.nim
Normal file
29
src/uint_init.nim
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
# Copyright (c) 2018 Status Research & Development GmbH
|
||||||
|
# Distributed under the MIT License (license terms are at http://opensource.org/licenses/MIT).
|
||||||
|
|
||||||
|
import typetraits
|
||||||
|
|
||||||
|
import private/utils,
|
||||||
|
uint_type
|
||||||
|
|
||||||
|
proc initMpUint*[T: BaseUint; U: BaseUInt](n: T, base_type: typedesc[U]): MpUint[U] {.noSideEffect.} =
|
||||||
|
let len = n.bit_length
|
||||||
|
const sizeU_bits = sizeof(U) * 8
|
||||||
|
|
||||||
|
when not (T is type result):
|
||||||
|
if len >= 2 * sizeU_bits:
|
||||||
|
# Todo print n
|
||||||
|
raise newException(ValueError, "Input cannot be stored in a multi-precision integer of base " & $T.name &
|
||||||
|
"\nIt requires at least " & $len & " bits of precision")
|
||||||
|
elif len < sizeU_bits:
|
||||||
|
result.lo = n.U # TODO: converter for MpInts
|
||||||
|
else:
|
||||||
|
raise newException(ValueError, "Unsupported at the moment: are you trying to build MpUint[uint32] from an uint64?")
|
||||||
|
else:
|
||||||
|
n
|
||||||
|
|
||||||
|
proc u128*[T: BaseUInt](n: T): UInt128 {.noSideEffect, inline.}=
|
||||||
|
initMpUint(n, uint64)
|
||||||
|
|
||||||
|
proc u256*[T: BaseUInt](n: T): UInt256 {.noSideEffect, inline.}=
|
||||||
|
initMpUint(n, UInt256)
|
16
src/uint_type.nim
Normal file
16
src/uint_type.nim
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
# Copyright (c) 2018 Status Research & Development GmbH
|
||||||
|
# Distributed under the MIT License (license terms are at http://opensource.org/licenses/MIT).
|
||||||
|
|
||||||
|
|
||||||
|
type
|
||||||
|
MpUint*{.packed.}[BaseUint] = object
|
||||||
|
when system.cpuEndian == littleEndian:
|
||||||
|
lo*, hi*: BaseUint
|
||||||
|
else:
|
||||||
|
hi*, lo*: BaseUint
|
||||||
|
|
||||||
|
BaseUint* = SomeUnsignedInt or MpUint
|
||||||
|
|
||||||
|
|
||||||
|
UInt128* = MpUint[uint64]
|
||||||
|
UInt256* = MpUint[UInt128]
|
4
tests/all_tests.nim
Normal file
4
tests/all_tests.nim
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
# Copyright (c) 2018 Status Research & Development GmbH
|
||||||
|
# Distributed under the MIT License (license terms are at http://opensource.org/licenses/MIT).$
|
||||||
|
|
||||||
|
import test_endianness
|
14
tests/test_endianness.nim
Normal file
14
tests/test_endianness.nim
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
# Copyright (c) 2018 Status Research & Development GmbH
|
||||||
|
# Distributed under the MIT License (license terms are at http://opensource.org/licenses/MIT).
|
||||||
|
|
||||||
|
import ../src/mpint, unittest
|
||||||
|
|
||||||
|
suite "Testing byte representation":
|
||||||
|
test "Byte representation conforms to the platform endianness":
|
||||||
|
let a = initMpUint(20182018, uint32)
|
||||||
|
let b = 20182018'u64
|
||||||
|
|
||||||
|
type AsBytes = array[8, byte]
|
||||||
|
|
||||||
|
check cast[AsBytes](a) == cast[AsBytes](b)
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user