Add sub, proper negate bound checking, high and low, most significant word mutation
This commit is contained in:
parent
8b412b879d
commit
0296b5eca9
|
@ -43,7 +43,7 @@ macro most_significant_word*(x: IntImpl): untyped =
|
|||
let optim_type = optimInt(x)
|
||||
if optim_type.isInt:
|
||||
result = quote do:
|
||||
cast[`optim_type`](`x`)
|
||||
(cast[ptr `optim_type`](`x`.unsafeAddr))[]
|
||||
else:
|
||||
when system.cpuEndian == littleEndian:
|
||||
let size = getSize(x)
|
||||
|
@ -51,7 +51,7 @@ macro most_significant_word*(x: IntImpl): untyped =
|
|||
else:
|
||||
let msw_pos = 0
|
||||
result = quote do:
|
||||
cast[`optim_type`](`x`)[`msw_pos`]
|
||||
(cast[ptr `optim_type`](`x`)[`msw_pos`.unsafeAddr])[]
|
||||
|
||||
macro asSignedWordsZip*[T](
|
||||
x, y: IntImpl[T],
|
||||
|
|
|
@ -7,20 +7,43 @@
|
|||
#
|
||||
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
||||
|
||||
import ./datatypes, ./int_bitwise_ops, ./initialization
|
||||
import ./datatypes, ./int_bitwise_ops,
|
||||
./initialization, ./as_signed_words, ./int_highlow
|
||||
|
||||
func `+=`*(x: var IntImpl, y: IntImpl) {.inline.}=
|
||||
## In-place addition for multi-precision signed int
|
||||
|
||||
type SubTy = type x.lo
|
||||
x.lo += y.lo
|
||||
x.hi += (x.lo < y.lo).toSubtype(SubTy) + y.hi
|
||||
|
||||
func `+`*(x, y: UintImpl): UintImpl {.noInit, inline.}=
|
||||
func `+`*(x, y: IntImpl): IntImpl {.noInit, inline.}=
|
||||
# Addition for multi-precision signed int
|
||||
result = x
|
||||
result += y
|
||||
type SubTy = type x.lo
|
||||
result.lo = x.lo + y.lo
|
||||
result.hi = (x.lo < y.lo).toSubtype(SubTy) + x.hi + y.hi
|
||||
|
||||
when compileOption("boundChecks"):
|
||||
if unlikely(
|
||||
(result.most_significant_word xor a.most_significant_word >= 0) or
|
||||
(result.most_significant_word xor b.most_significant_word >= 0)
|
||||
):
|
||||
raise newException(OverflowError, "Addition overflow")
|
||||
|
||||
func `-`*[T: IntImpl](x: T): T {.noInit, inline.}=
|
||||
result = not x
|
||||
result += one(T)
|
||||
when compileOption("boundChecks"):
|
||||
if unlikely(x == low(T)):
|
||||
raise newException(OverflowError, "The lowest negative number cannot be negated")
|
||||
|
||||
func `-`*(x, y: IntImpl): IntImpl {.noInit, inline.}=
|
||||
# Substraction for multi-precision signed int
|
||||
|
||||
type SubTy = type x.lo
|
||||
result.lo = x.lo - y.lo
|
||||
result.hi = x.hi - y.hi - (x.lo < y.lo).toSubtype(SubTy)
|
||||
|
||||
when compileOption("boundChecks"):
|
||||
if unlikely(
|
||||
(result.most_significant_word xor a.most_significant_word >= 0) or
|
||||
(result.most_significant_word xor (not b).most_significant_word >= 0)
|
||||
):
|
||||
raise newException(OverflowError, "Substraction underflow")
|
||||
|
||||
func `-=`*(x: var IntImpl, y: IntImpl) {.inline.}=
|
||||
## In-place substraction for multi-precision signed int
|
||||
x = x - y
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
# Mpint
|
||||
# Copyright 2018 Status Research & Development GmbH
|
||||
# Licensed under either of
|
||||
#
|
||||
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
|
||||
# * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
|
||||
#
|
||||
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
||||
|
||||
import ./datatypes, ./as_signed_words
|
||||
|
||||
func low*(T: typedesc[UintImpl]): T {.inline.}=
|
||||
|
||||
# The lowest signed int has representation
|
||||
# 0b1000_0000_0000_0000 ....
|
||||
# so we only have to set the most significant bit.
|
||||
type Msw = type result.most_significant_word
|
||||
when Msw is uint64:
|
||||
type U = int64
|
||||
else:
|
||||
type U = Msw
|
||||
|
||||
result.most_significant_word = low(U)
|
||||
|
||||
func high*(T: typedesc[UintImpl]): T {.inline, noInit.}=
|
||||
|
||||
# The lowest signed int has representation
|
||||
# 0b0111_1111_1111_1111 ....
|
||||
# so we only have to unset the most significant bit.
|
||||
not low(T)
|
|
@ -0,0 +1,16 @@
|
|||
# Mpint
|
||||
# Copyright 2018 Status Research & Development GmbH
|
||||
# Licensed under either of
|
||||
#
|
||||
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
|
||||
# * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
|
||||
#
|
||||
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
||||
|
||||
import ./datatypes, ./initialization
|
||||
|
||||
func low*(T: typedesc[UintImpl]): T {.inline, noInit.}=
|
||||
zero(T)
|
||||
|
||||
func high*(T: typedesc[UintImpl]): T {.inline, noInit.}=
|
||||
not zero(T)
|
Loading…
Reference in New Issue