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)
|
let optim_type = optimInt(x)
|
||||||
if optim_type.isInt:
|
if optim_type.isInt:
|
||||||
result = quote do:
|
result = quote do:
|
||||||
cast[`optim_type`](`x`)
|
(cast[ptr `optim_type`](`x`.unsafeAddr))[]
|
||||||
else:
|
else:
|
||||||
when system.cpuEndian == littleEndian:
|
when system.cpuEndian == littleEndian:
|
||||||
let size = getSize(x)
|
let size = getSize(x)
|
||||||
|
@ -51,7 +51,7 @@ macro most_significant_word*(x: IntImpl): untyped =
|
||||||
else:
|
else:
|
||||||
let msw_pos = 0
|
let msw_pos = 0
|
||||||
result = quote do:
|
result = quote do:
|
||||||
cast[`optim_type`](`x`)[`msw_pos`]
|
(cast[ptr `optim_type`](`x`)[`msw_pos`.unsafeAddr])[]
|
||||||
|
|
||||||
macro asSignedWordsZip*[T](
|
macro asSignedWordsZip*[T](
|
||||||
x, y: IntImpl[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.
|
# 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.}=
|
func `+`*(x, y: IntImpl): IntImpl {.noInit, 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.}=
|
|
||||||
# Addition for multi-precision signed int
|
# Addition for multi-precision signed int
|
||||||
result = x
|
type SubTy = type x.lo
|
||||||
result += y
|
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.}=
|
func `-`*[T: IntImpl](x: T): T {.noInit, inline.}=
|
||||||
result = not x
|
result = not x
|
||||||
result += one(T)
|
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