Add substraction implementation
This commit is contained in:
parent
fc6483d42e
commit
4d7d5897cd
|
@ -4,16 +4,33 @@
|
||||||
import uint_type
|
import uint_type
|
||||||
|
|
||||||
proc `+=`*[T: MpUint](a: var T, b: T) {.noSideEffect.}=
|
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
|
type Base = type a.lo
|
||||||
let tmp = a.lo
|
let tmp = a.lo
|
||||||
|
|
||||||
a.lo += b.lo
|
a.lo += b.lo
|
||||||
a.hi += (a.lo < tmp).Base + b.hi
|
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 = 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
|
|
@ -2,4 +2,4 @@
|
||||||
# Distributed under the MIT License (license terms are at http://opensource.org/licenses/MIT).$
|
# Distributed under the MIT License (license terms are at http://opensource.org/licenses/MIT).$
|
||||||
|
|
||||||
import test_endianness,
|
import test_endianness,
|
||||||
test_addition
|
test_addsub
|
|
@ -44,3 +44,27 @@ suite "Testing addition implementation":
|
||||||
|
|
||||||
z += a
|
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)
|
Loading…
Reference in New Issue