Add substraction implementation

This commit is contained in:
mratsim 2018-02-15 23:28:31 +01:00
parent fc6483d42e
commit 4d7d5897cd
3 changed files with 49 additions and 8 deletions

View File

@ -4,16 +4,33 @@
import uint_type
proc `+=`*[T: MpUint](a: var T, b: T) {.noSideEffect.}=
# In-place addition for multi-precision unsigned int
#
# Optimized assembly should contain adc instruction (add with carry)
# Clang on MacOS does with the -d:release switch and MpUint[uint32] (uint64)
type Base = type a.lo
let tmp = a.lo
a.lo += b.lo
a.hi += (a.lo < tmp).Base + b.hi
# Optimized assembly should contain adc instruction (add with carry)
# Clang on MacOS does with the -d:release switch.
proc `+`*[T: MpUint](a: T, b: T): T {.noSideEffect, noInit.}=
proc `+`*[T: MpUint](a, b: T): T {.noSideEffect, noInit, inline.}=
# Addition for multi-precision unsigned int
result = a
result += b
result += b
proc `-=`*[T: MpUint](a: var T, b: T) {.noSideEffect.}=
# In-place substraction for multi-precision unsigned int
#
# Optimized assembly should contain sbc instruction (substract with carry)
# Clang on MacOS does with the -d:release switch and MpUint[uint32] (uint64)
type Base = type a.lo
let tmp = a.lo
a.lo -= b.lo
a.hi -= (a.lo > tmp).Base + b.hi
proc `-`*[T: MpUint](a, b: T): T {.noSideEffect, noInit, inline.}=
# Substraction for multi-precision unsigned int
result = a
result -= b

View File

@ -2,4 +2,4 @@
# Distributed under the MIT License (license terms are at http://opensource.org/licenses/MIT).$
import test_endianness,
test_addition
test_addsub

View File

@ -43,4 +43,28 @@ suite "Testing addition implementation":
check: cast[uint16](z) == 64
z += a
check: cast[uint16](z) == 164
check: cast[uint16](z) == 164
suite "Testing substraction implementation":
test "In-place substraction gives expected result":
var a = initMpUint(20182018, uint32)
let b = initMpUint(20172017, uint32)
a -= b
check: cast[uint64](a) == 20182018'u64 - 20172017'u64
test "Substraction gives expected result":
let a = initMpUint(20182018, uint32)
let b = initMpUint(20172017, uint32)
check: cast[uint64](a-b) == 20182018'u64 - 20172017'u64
test "Full overflow is handled like native unsigned types":
# uint16 overflows after 65535
let a = initMpUint(100, uint8)
let b = initMpUint(101, uint8)
check: cast[uint16](a-b) == high(uint16)