Add uint256 support

This commit is contained in:
mratsim 2018-02-08 22:02:56 +01:00
parent 1dd3d37a9c
commit 6c832faeaa
3 changed files with 124 additions and 0 deletions

35
examples/example_uint.nim Normal file
View File

@ -0,0 +1,35 @@
import ttmath
var a = 2.u256
var b = 2.u256
echo a + b
echo a - b
echo a * b
echo a / b
echo a < b
echo a > b
echo 3.u256 > b
echo a < 3.u256
echo a <= b
echo a >= b
a += b
echo a
a *= b
echo a
a -= b
echo a
a /= b
echo a
echo a mod b
echo a div b
echo a and b
echo a or b
echo a xor b
echo pow(a, 2)
echo a shl 2
echo a shr 2
echo a.getUInt
echo -a
echo "02".u256

View File

@ -1,3 +1,6 @@
import ttmathuint
export ttmathuint
const TTMATH_HEADER = "headers/ttmath.h"
type

86
src/ttmathuint.nim Normal file
View File

@ -0,0 +1,86 @@
const TTMATH_HEADER = "headers/ttmathuint.h"
type
UInt256* {.importc: "ttmath::UInt<4>", header: TTMATH_HEADER.} = object
table: array[4, uint64]
stdString {.importc: "std::string", header: "<string.h>".} = object
proc `+`*(a: UInt256, b: UInt256): UInt256 {.importcpp: "(# + #)".}
proc `-`*(a: UInt256, b: UInt256): UInt256 {.importcpp: "(# - #)".}
proc `*`*(a: UInt256, b: UInt256): UInt256 {.importcpp: "(# * #)".}
proc `/`*(a: UInt256, b: UInt256): UInt256 {.importcpp: "(# / #)".}
proc `div`*(a: UInt256, b: UInt256): UInt256 {.importcpp: "(# / #)".}
proc `==`*(a: UInt256, b: UInt256): bool {.importcpp: "(# == #)".}
proc `<`*(a: UInt256, b: UInt256): bool {.importcpp: "(# < #)".}
proc `<=`*(a: UInt256, b: UInt256): bool {.importcpp: "(# <= #)".}
proc `+=`*(a: var UInt256, b: UInt256) {.importcpp: "# += #".}
proc `-=`*(a: var UInt256, b: UInt256) {.importcpp: "# -= #".}
proc `*=`*(a: var UInt256, b: UInt256) {.importcpp: "# *= #".}
proc `/=`*(a: var UInt256, b: UInt256) {.importcpp: "# /= #".}
template `-`*(a: UInt256): UInt256 =
0.u256 - a
proc `and`*(a: UInt256, b: UInt256): UInt256 {.importcpp: "(# & #)".}
proc `or`*(a: UInt256, b: UInt256): UInt256 {.importcpp: "(# | #)".}
proc `xor`*(a: UInt256, b: UInt256): UInt256 {.importcpp: "(# ^ #)".}
proc u256*(a: uint64): UInt256 {.importcpp: "ttmath::UInt<4>((uint)#)".}
proc u256*(a: cstring): UInt256 {.importcpp: "ttmath::UInt<4>(#)".}
proc u256*(a: string): UInt256 =
cstring(a).u256
proc inplacePow(a: var UInt256, b: UInt256) {.importcpp: "(#.Pow(#))".}
proc inplaceDiv(a: var UInt256, b: UInt256, c: var UInt256) {.importcpp: "(#.Div(#, #))".}
proc pow*(a: UInt256, b: uint64): UInt256 =
var tmp = a
tmp.inplacePow(b.u256)
result = tmp
proc `mod`*(a: UInt256, b: UInt256): UInt256 =
var tmp = a
tmp.inplaceDiv(b, result)
proc ToString(a: UInt256, s: stdString | cstring) {.importcpp: "#.ToString(#)", header: TTMATH_HEADER.}
proc strcpy(c: cstring, s: cstring) {.importc: "strcpy", header: "<cstring>".}
proc c_str(s: stdString): cstring {.importcpp: "#.c_str()", header: "<string.h>".}
#proc toCString*(a: UInt256): cstring =
proc `shl`*(a: UInt256, b: uint64): UInt256 {.importcpp: "(# << #)".}
proc `shr`*(a: UInt256, b: uint64): UInt256 {.importcpp: "(# >> #)".}
proc getUInt*(a: UInt256): uint64 =
a.table[0]
proc `$`*(a: UInt256): string =
var tmp: stdString
# TODO: something smarter
{.emit: "tmp = \" \";".}
var s: cstring
{.emit: "s = new char[256];".}
a.ToString(tmp)
strcpy(s, tmp.c_str())
result = $s
{.emit: "delete[] s;".}