Initial commit
This commit is contained in:
commit
b5bde65670
|
@ -0,0 +1,2 @@
|
|||
# Auto detect text files and perform LF normalization
|
||||
* text=auto
|
|
@ -0,0 +1 @@
|
|||
nimcache/
|
|
@ -0,0 +1,11 @@
|
|||
// Place your settings in this file to overwrite default and user settings.
|
||||
{
|
||||
"editor.tabSize": 2,
|
||||
"indentRainbow.includedLanguages": [
|
||||
"nim"
|
||||
],
|
||||
"files.autoSave": "afterDelay",
|
||||
"workbench.editor.enablePreview": false,
|
||||
"nim.buildOnSave": false,
|
||||
"editor.formatOnPaste": true
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
||||
// for the documentation about the tasks.json format
|
||||
"version": "0.1.0",
|
||||
"command": "nim",
|
||||
"isShellCommand": true,
|
||||
"args": ["cpp", "-r", "${file}"],
|
||||
"showOutput": "always"
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2018 Coffepots
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
|
@ -0,0 +1,2 @@
|
|||
import src/integer256s
|
||||
export integer256s
|
|
@ -0,0 +1,94 @@
|
|||
import strutils
|
||||
|
||||
const
|
||||
bitSize = 256
|
||||
byteSize = bitSize div 8
|
||||
type
|
||||
Base256 = array[byteSize, uint8]
|
||||
Int256* = distinct Base256
|
||||
|
||||
# not exposed
|
||||
proc `[]`(v: Int256, i: int): uint8 = Base256(v)[i]
|
||||
# not exposed
|
||||
proc `[]=`(v: var Int256, i: int, val: uint8) =
|
||||
Base256(v)[i] = val
|
||||
# not exposed
|
||||
proc len(v: Int256): int = Base256(v).len
|
||||
# not exposed
|
||||
iterator pairs(v: Int256): (int, uint8) =
|
||||
for i in 0..< v.len:
|
||||
yield (i, v[i])
|
||||
|
||||
proc toNum(c: char): uint8 =
|
||||
assert c in {'0'..'9'} or c in {'A'..'F'} or c in {'a'..'f'}
|
||||
var base = 0
|
||||
case c
|
||||
of {'0'..'9'}: base = ord('0')
|
||||
of {'A'..'F'}: base = ord('A') - 10
|
||||
of {'a'..'f'}: base = ord('a') - 10
|
||||
else:
|
||||
raiseAssert "ERROR non-hex input to Int256"
|
||||
result = uint8(c.ord - base)
|
||||
|
||||
proc i256*(v: string): Int256 =
|
||||
## Hex
|
||||
assert v.len mod 2 == 0
|
||||
let startByte = v.len div 2
|
||||
for i in 0..< startByte:
|
||||
let
|
||||
p = i * 2
|
||||
c1 = v[p].toNum
|
||||
c2 = v[p + 1].toNum
|
||||
byteVal = c1 shl 4 or c2
|
||||
result[startByte - i - 1] = byteVal
|
||||
|
||||
proc i256*(v: int): Int256 =
|
||||
cast[ptr int](unsafeAddr(result))[] = v
|
||||
|
||||
proc `$`*(v: Int256): string =
|
||||
result = newString(byteSize * 2 + 2)
|
||||
result[0..1] = "0x"
|
||||
for i in countDown(byteSize - 1, 0):
|
||||
let p = i * 2 + 2
|
||||
result[p..p + 1] = v[byteSize - i - 1].toHex
|
||||
|
||||
proc `not`*(v: Int256): Int256 =
|
||||
for i, b in v:
|
||||
result[i] = 255'u8 - b
|
||||
|
||||
proc `+`*(v1, v2: Int256): Int256 =
|
||||
var
|
||||
intermediate: int
|
||||
carry = 0
|
||||
for i in 0..< byteSize:
|
||||
intermediate = int(v1[i]) + int(v2[i]) + carry
|
||||
carry = 0
|
||||
if intermediate > 255:
|
||||
result[i] = uint8(intermediate and 0xff)
|
||||
carry = intermediate shr 8
|
||||
else:
|
||||
result[i] = uint8(intermediate)
|
||||
#assert carry == 0 # can't use this assert when subtracting!
|
||||
|
||||
proc `-`*(v: Int256): Int256 =
|
||||
result = v.not + i256(1)
|
||||
|
||||
proc `-`*(v1, v2: Int256): Int256 =
|
||||
var negV2 = -v2
|
||||
result = v1 + negV2
|
||||
|
||||
proc `==`*(v1, v2: Int256): bool =
|
||||
for i in 0..<byteSize:
|
||||
if v1[i] != v2[i]: return false
|
||||
return true
|
||||
|
||||
proc isPositive*(v: Int256): bool = (v[byteSize - 1] and 0xff).int > 0
|
||||
|
||||
proc `>`*(v1, v2: Int256): bool =
|
||||
let x = v2 - v1
|
||||
return x.isPositive
|
||||
|
||||
proc `<`*(v1, v2: Int256): bool =
|
||||
let x = v1 - v2
|
||||
return x.isPositive
|
||||
|
Binary file not shown.
|
@ -0,0 +1,44 @@
|
|||
import ../integer256
|
||||
|
||||
import unittest
|
||||
suite "Int256":
|
||||
test "String input":
|
||||
var x = i256"123456"
|
||||
check $x == "0x0000000000000000000000000000000000000000000000000000000000123456"
|
||||
test "Numeric input":
|
||||
var x = i256(0x123456)
|
||||
check $x == "0x0000000000000000000000000000000000000000000000000000000000123456"
|
||||
test "Addition":
|
||||
var
|
||||
x = i256"123456"
|
||||
y = i256"123456"
|
||||
a = i256("13AC19ED413CCE5D402129")
|
||||
b = i256("667C9CFA7440B879181A96")
|
||||
c = i256("0AD99F7AF99413AC19293950ED413CCE5D402129")
|
||||
d = i256("0F0A884AA482759927667C9CFA7440B879181A96")
|
||||
check $(x + y) == "0x00000000000000000000000000000000000000000000000000000000002468AC"
|
||||
check $(a + b) == "0x0000000000000000000000000000000000000000007A28B6E7B57D86D6583BBF"
|
||||
check $(c + d) == "0x00000000000000000000000019E427C59E168945408FB5EDE7B57D86D6583BBF"
|
||||
test "Subtraction":
|
||||
var
|
||||
x = i256"123456"
|
||||
y = i256"123456"
|
||||
z = i256"0456"
|
||||
check $(x - y) == "0x0000000000000000000000000000000000000000000000000000000000000000"
|
||||
check $(x - z) == "0x0000000000000000000000000000000000000000000000000000000000123000"
|
||||
|
||||
test "Inversion":
|
||||
var x = i256"abcdef"
|
||||
check $(-x) == "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF543211"
|
||||
check $(x.not) == "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF543210"
|
||||
test "Equality":
|
||||
var
|
||||
x = i256"abcdef"
|
||||
y = i256"abcdef"
|
||||
check x == y
|
||||
test "Comparison":
|
||||
var
|
||||
x = i256"abcd"
|
||||
y = i256"ab"
|
||||
check x > y == true
|
||||
check x < y == false
|
Loading…
Reference in New Issue