From 6c832faeaa12861673f5913eb30ad5001e716e4d Mon Sep 17 00:00:00 2001 From: mratsim Date: Thu, 8 Feb 2018 22:02:56 +0100 Subject: [PATCH] Add uint256 support --- examples/example_uint.nim | 35 ++++++++++++++++ src/ttmath.nim | 3 ++ src/ttmathuint.nim | 86 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 124 insertions(+) create mode 100644 examples/example_uint.nim create mode 100644 src/ttmathuint.nim diff --git a/examples/example_uint.nim b/examples/example_uint.nim new file mode 100644 index 0000000..eb3fdc8 --- /dev/null +++ b/examples/example_uint.nim @@ -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 diff --git a/src/ttmath.nim b/src/ttmath.nim index 16ca540..1e76fe5 100644 --- a/src/ttmath.nim +++ b/src/ttmath.nim @@ -1,3 +1,6 @@ +import ttmathuint +export ttmathuint + const TTMATH_HEADER = "headers/ttmath.h" type diff --git a/src/ttmathuint.nim b/src/ttmathuint.nim new file mode 100644 index 0000000..0ca62a9 --- /dev/null +++ b/src/ttmathuint.nim @@ -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: "".} = 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: "".} + +proc c_str(s: stdString): cstring {.importcpp: "#.c_str()", header: "".} + +#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;".}