From 4d7d5897cdaef108380483b259d33378a0dd419f Mon Sep 17 00:00:00 2001 From: mratsim Date: Thu, 15 Feb 2018 23:28:31 +0100 Subject: [PATCH] Add substraction implementation --- src/uint_binary_ops.nim | 29 ++++++++++++++++---- tests/all_tests.nim | 2 +- tests/{test_addition.nim => test_addsub.nim} | 26 +++++++++++++++++- 3 files changed, 49 insertions(+), 8 deletions(-) rename tests/{test_addition.nim => test_addsub.nim} (63%) diff --git a/src/uint_binary_ops.nim b/src/uint_binary_ops.nim index d49866e..ac8d89d 100644 --- a/src/uint_binary_ops.nim +++ b/src/uint_binary_ops.nim @@ -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 \ No newline at end of file + 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 \ No newline at end of file diff --git a/tests/all_tests.nim b/tests/all_tests.nim index 88567f7..1d7fb63 100644 --- a/tests/all_tests.nim +++ b/tests/all_tests.nim @@ -2,4 +2,4 @@ # Distributed under the MIT License (license terms are at http://opensource.org/licenses/MIT).$ import test_endianness, - test_addition \ No newline at end of file + test_addsub \ No newline at end of file diff --git a/tests/test_addition.nim b/tests/test_addsub.nim similarity index 63% rename from tests/test_addition.nim rename to tests/test_addsub.nim index a053962..22006fe 100644 --- a/tests/test_addition.nim +++ b/tests/test_addsub.nim @@ -43,4 +43,28 @@ suite "Testing addition implementation": check: cast[uint16](z) == 64 z += a - check: cast[uint16](z) == 164 \ No newline at end of file + 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) \ No newline at end of file