A arbitrary-precision big integer, with a fixed set of mutable limbs.
Fields
limbs: []Limb,
Raw digits. These are:
- Little-endian ordered
- limbs.len >= 1
- Zero is represented as limbs.len == 1 with limbs[0] == 0.
Accessing limbs directly should be avoided. These are allocated limbs; the len
field tells the valid range.
len: usize,
positive: bool,
Functions
fn add(r: *Mutable, a: Const, b: Const) void
r = a + b r, a and b may be aliases.
r = a + b r, a and b may be aliases.
Asserts the result fits in
r
. An upper bound on the number of limbs needed by r is@max(a.limbs.len, b.limbs.len) + 1
.fn addSat(r: *Mutable, a: Const, b: Const, signedness: Signedness, bit_count: usize) void
r = a + b with 2s-complement saturating semantics. r, a and b may be aliases.
r = a + b with 2s-complement saturating semantics. r, a and b may be aliases.
Assets the result fits in
r
. Upper bound on the number of limbs needed by r iscalcTwosCompLimbCount(bit_count)
.fn addScalar(r: *Mutable, a: Const, scalar: anytype) void
r = a + scalar
r = a + scalar
r and a may be aliases. scalar is a primitive integer type.
Asserts the result fits in
r
. An upper bound on the number of limbs needed by r is@max(a.limbs.len, calcLimbLen(scalar)) + 1
.fn addWrap(r: *Mutable, a: Const, b: Const, signedness: Signedness, bit_count: usize) bool
r = a + b with 2s-complement wrapping semantics. Returns whether overflow occurr…
r = a + b with 2s-complement wrapping semantics. Returns whether overflow occurred. r, a and b may be aliases
Asserts the result fits in
r
. An upper bound on the number of limbs needed by r iscalcTwosCompLimbCount(bit_count)
.fn bitAnd(r: *Mutable, a: Const, b: Const) void
r = a & b under 2s complement semantics. r may alias with a or b.
r = a & b under 2s complement semantics. r may alias with a or b.
Asserts that r has enough limbs to store the result. If a or b is positive, the upper bound is
@min(a.limbs.len, b.limbs.len)
. If a and b are negative, the upper bound is@max(a.limbs.len, b.limbs.len) + 1
.fn bitNotWrap(r: *Mutable, a: Const, signedness: Signedness, bit_count: usize) void
r = ~a under 2s complement wrapping semantics. r may alias with a.
r = ~a under 2s complement wrapping semantics. r may alias with a.
Assets that r has enough limbs to store the result. The upper bound Limb count is r is
calcTwosCompLimbCount(bit_count)
.fn bitOr(r: *Mutable, a: Const, b: Const) void
r = a | b under 2s complement semantics. r may alias with a or b.
r = a | b under 2s complement semantics. r may alias with a or b.
a and b are zero-extended to the longer of a or b.
Asserts that r has enough limbs to store the result. Upper bound is
@max(a.limbs.len, b.limbs.len)
.fn bitReverse(r: *Mutable, a: Const, signedness: Signedness, bit_count: usize) void
r = @bitReverse(a) with 2s-complement semantics. r and a may be aliases.
r = @bitReverse(a) with 2s-complement semantics. r and a may be aliases.
Asserts the result fits in
r
. Upper bound on the number of limbs needed by r iscalcTwosCompLimbCount(bit_count)
.fn bitXor(r: *Mutable, a: Const, b: Const) void
r = a ^ b under 2s complement semantics. r may alias with a or b.
r = a ^ b under 2s complement semantics. r may alias with a or b.
Asserts that r has enough limbs to store the result. If a and b share the same signedness, the upper bound is
@max(a.limbs.len, b.limbs.len)
. Otherwise, if either a or b is negative but not both, the upper bound is@max(a.limbs.len, b.limbs.len) + 1
.fn byteSwap(r: *Mutable, a: Const, signedness: Signedness, byte_count: usize) void
r = @byteSwap(a) with 2s-complement semantics. r and a may be aliases.
r = @byteSwap(a) with 2s-complement semantics. r and a may be aliases.
Asserts the result fits in
r
. Upper bound on the number of limbs needed by r iscalcTwosCompLimbCount(8*byte_count)
.fn clone(other: Mutable, limbs: []Limb) Mutable
Clones an Mutable and returns a new Mutable with the same value. The new Mutable…
Clones an Mutable and returns a new Mutable with the same value. The new Mutable is a deep copy and can be modified separately from the original. Asserts that limbs is big enough to store the value.
fn convertToTwosComplement(r: *Mutable, a: Const, signedness: Signedness, bit_count: usize) void
If a is positive, this passes through to truncate. If a is negative, then r is …
If a is positive, this passes through to truncate. If a is negative, then r is set to positive with the bit pattern ~(a - 1). r may alias a.
Asserts
r
has enough storage to store the result. The upper bound iscalcTwosCompLimbCount(a.len)
.fn copy(self: *Mutable, other: Const) void
Copies the value of a Const to an existing Mutable so that they both have the sa…
Copies the value of a Const to an existing Mutable so that they both have the same value. Asserts the value fits in the limbs buffer.
fn divFloor(q: *Mutable, r: *Mutable, a: Const, b: Const, limbs_buffer: []Limb) void
q = a / b (rem r)
q = a / b (rem r)
a / b are floored (rounded towards 0). q may alias with a or b.
Asserts there is enough memory to store q and r. The upper bound for r limb count is
b.limbs.len
. The upper bound for q limb count is given bya.limbs
.limbs_buffer
is used for temporary storage. The amount required is given bycalcDivLimbsBufferLen
.fn divTrunc(q: *Mutable, r: *Mutable, a: Const, b: Const, limbs_buffer: []Limb) void
q = a / b (rem r)
q = a / b (rem r)
a / b are truncated (rounded towards -inf). q may alias with a or b.
Asserts there is enough memory to store q and r. The upper bound for r limb count is
b.limbs.len
. The upper bound for q limb count is given bya.limbs.len
.limbs_buffer
is used for temporary storage. The amount required is given bycalcDivLimbsBufferLen
.fn gcd(rma: *Mutable, x: Const, y: Const, limbs_buffer: *field_call) !void
rma may alias x or y. x and y may alias each other. Asserts that
rma
has eno…rma may alias x or y. x and y may alias each other. Asserts that
rma
has enough limbs to store the result. Upper bound is@min(x.limbs.len, y.limbs.len)
.limbs_buffer
is used for temporary storage during the operation. When this function returns, it will have the same length as it had when the function was called.fn gcdNoAlias(rma: *Mutable, x: Const, y: Const, limbs_buffer: *field_call) !void
rma may not alias x or y. x and y may alias each other. Asserts that
rma
has…rma may not alias x or y. x and y may alias each other. Asserts that
rma
has enough limbs to store the result. Upper bound is given bycalcGcdNoAliasLimbLen
.limbs_buffer
is used for temporary storage during the operation.fn init(limbs_buffer: []Limb, value: anytype) Mutable
value
is a primitive integer type. Asserts the value fits within the provided…value
is a primitive integer type. Asserts the value fits within the providedlimbs_buffer
. Note:calcLimbLen
can be used to figure out how big an array to allocate forlimbs_buffer
.fn mul(rma: *Mutable, a: Const, b: Const, limbs_buffer: []Limb, allocator: ?Allocator) void
rma = a * b
rma = a * b
rma
may alias witha
orb
.a
andb
may alias with each other.Asserts the result fits in
rma
. An upper bound on the number of limbs needed by rma is given bya.limbs.len + b.limbs.len
.limbs_buffer
is used for temporary storage. The amount required is given bycalcMulLimbsBufferLen
.fn mulNoAlias(rma: *Mutable, a: Const, b: Const, allocator: ?Allocator) void
rma = a * b
rma = a * b
rma
may not alias witha
orb
.a
andb
may alias with each other.Asserts the result fits in
rma
. An upper bound on the number of limbs needed by rma is given bya.limbs.len + b.limbs.len
.If
allocator
is provided, it will be used for temporary storage to improve multiplication performance.error.OutOfMemory
is handled with a fallback algorithm.fn mulWrap(rma: *Mutable, a: Const, b: Const, signedness: Signedness, bit_count: usize, limbs_buffer: []Limb, allocator: ?Allocator) void
rma = a * b with 2s-complement wrapping semantics.
rma = a * b with 2s-complement wrapping semantics.
rma
may alias witha
orb
.a
andb
may alias with each other.Asserts the result fits in
rma
. An upper bound on the number of limbs needed by rma is given bya.limbs.len + b.limbs.len
.limbs_buffer
is used for temporary storage. The amount required is given bycalcMulWrapLimbsBufferLen
.fn mulWrapNoAlias(rma: *Mutable, a: Const, b: Const, signedness: Signedness, bit_count: usize, allocator: ?Allocator) void
rma = a * b with 2s-complement wrapping semantics.
rma = a * b with 2s-complement wrapping semantics.
rma
may not alias witha
orb
.a
andb
may alias with each other.Asserts the result fits in
rma
. An upper bound on the number of limbs needed by rma is given bya.limbs.len + b.limbs.len
.If
allocator
is provided, it will be used for temporary storage to improve multiplication performance.error.OutOfMemory
is handled with a fallback algorithm.fn normalize(r: *Mutable, length: usize) void
Normalize a possible sequence of leading zeros.
Normalize a possible sequence of leading zeros.
[1, 2, 3, 4, 0] -> [1, 2, 3, 4] [1, 2, 0, 0, 0] -> [1, 2] [0, 0, 0, 0, 0] -> [0]
fn popCount(r: *Mutable, a: Const, bit_count: usize) void
r = @popCount(a) with 2s-complement semantics. r and a may be aliases.
r = @popCount(a) with 2s-complement semantics. r and a may be aliases.
Assets the result fits in
r
. Upper bound on the number of limbs needed by r iscalcTwosCompLimbCount(bit_count)
.fn pow(r: *Mutable, a: Const, b: u32, limbs_buffer: []Limb) !void
q = a ^ b
q = a ^ b
r may not alias a.
Asserts that
r
has enough limbs to store the result. Upper bound iscalcPowLimbsBufferLen(a.bitCountAbs(), b)
.limbs_buffer
is used for temporary storage. The amount required is given bycalcPowLimbsBufferLen
.fn readPackedTwosComplement(x: *Mutable, buffer: []const u8, bit_offset: usize, bit_count: usize, endian: Endian, signedness: Signedness) void
Read the value of
x
from a packed memorybuffer
. Asserts thatbuffer
is l…Read the value of
x
from a packed memorybuffer
. Asserts thatbuffer
is large enough to contain a value of bit-sizebit_count
at offsetbit_offset
.This is equivalent to loading the value of an integer with
bit_count
bits as if it were a field in packed memory at the provided bit offset.fn readTwosComplement(x: *Mutable, buffer: []const u8, bit_count: usize, endian: Endian, signedness: Signedness) void
Read the value of
x
frombuffer
Asserts thatbuffer
is large enough to co…Read the value of
x
frombuffer
Asserts thatbuffer
is large enough to contain a value of bit-sizebit_count
.The contents of
buffer
are interpreted as if they were the contents of @ptrCast(*[buffer.len]const u8, &x). Byte ordering is determined byendian
and any required padding bits are expected on the MSB end.fn saturate(r: *Mutable, a: Const, signedness: Signedness, bit_count: usize) void
Saturate an integer to a number of bits, following 2s-complement semantics. r m…
Saturate an integer to a number of bits, following 2s-complement semantics. r may alias a.
Asserts
r
has enough storage to store the result. The upper bound iscalcTwosCompLimbCount(a.len)
.fn set(self: *Mutable, value: anytype) void
Sets the Mutable to value. Value must be an primitive integer type. Asserts the…
Sets the Mutable to value. Value must be an primitive integer type. Asserts the value fits within the limbs buffer. Note:
calcLimbLen
can be used to figure out how big the limbs buffer needs to be to store a specific value.fn setString(self: *Mutable, base: u8, value: []const u8, limbs_buffer: []Limb, allocator: ?Allocator) error{InvalidCharacter}!void
Set self from the string representation
value
.Set self from the string representation
value
.value
must contain only digits <=base
and is case insensitive. Base prefixes are not allowed (e.g. 0x43 should simply be 43). Underscores in the input string are ignored and can be used as digit separators.Asserts there is enough memory for the value in
self.limbs
. An upper bound on number of limbs can be determined withcalcSetStringLimbCount
. Asserts the base is in the range [2, 16].Returns an error if the value has invalid digits for the requested base.
limbs_buffer
is used for temporary storage. The size required can be found withcalcSetStringLimbsBufferLen
.If
allocator
is provided, it will be used for temporary storage to improve multiplication performance.error.OutOfMemory
is handled with a fallback algorithm.fn setTwosCompIntLimit(r: *Mutable, limit: TwosCompIntLimit, signedness: Signedness, bit_count: usize) void
Set self to either bound of a 2s-complement integer. Note: The result is still …
Set self to either bound of a 2s-complement integer. Note: The result is still sign-magnitude, not twos complement! In order to convert the result to twos complement, it is sufficient to take the absolute value.
Asserts the result fits in
r
. An upper bound on the number of limbs needed by r iscalcTwosCompLimbCount(bit_count)
.fn shiftLeft(r: *Mutable, a: Const, shift: usize) void
r = a << shift, in other words, r = a * 2^shift
r = a << shift, in other words, r = a * 2^shift
r and a may alias.
Asserts there is enough memory to fit the result. The upper bound Limb count is
a.limbs.len + (shift / (@sizeOf(Limb) * 8))
.fn shiftLeftSat(r: *Mutable, a: Const, shift: usize, signedness: Signedness, bit_count: usize) void
r = a <<| shift with 2s-complement saturating semantics.
r = a <<| shift with 2s-complement saturating semantics.
r and a may alias.
Asserts there is enough memory to fit the result. The upper bound Limb count is r is
calcTwosCompLimbCount(bit_count)
.fn shiftRight(r: *Mutable, a: Const, shift: usize) void
r = a >> shift r and a may alias.
r = a >> shift r and a may alias.
Asserts there is enough memory to fit the result. The upper bound Limb count is
a.limbs.len - (shift / (@sizeOf(Limb) * 8))
.fn sqrNoAlias(rma: *Mutable, a: Const, opt_allocator: ?Allocator) void
rma = a * a
rma = a * a
rma
may not alias witha
.Asserts the result fits in
rma
. An upper bound on the number of limbs needed by rma is given by2 * a.limbs.len + 1
.If
allocator
is provided, it will be used for temporary storage to improve multiplication performance.error.OutOfMemory
is handled with a fallback algorithm.fn sqrt(r: *Mutable, a: Const, limbs_buffer: []Limb) void
r = ⌊√a⌋
r = ⌊√a⌋
r may alias a.
Asserts that
r
has enough limbs to store the result. Upper bound is(a.limbs.len - 1) / 2 + 1
.limbs_buffer
is used for temporary storage. The amount required is given bycalcSqrtLimbsBufferLen
.fn sub(r: *Mutable, a: Const, b: Const) void
r = a - b
r = a - b
r, a and b may be aliases.
Asserts the result fits in
r
. An upper bound on the number of limbs needed by r is@max(a.limbs.len, b.limbs.len) + 1
. The +1 is not needed if both operands are positive.fn subSat(r: *Mutable, a: Const, b: Const, signedness: Signedness, bit_count: usize) void
r = a - b with 2s-complement saturating semantics. r, a and b may be aliases.
r = a - b with 2s-complement saturating semantics. r, a and b may be aliases.
Assets the result fits in
r
. Upper bound on the number of limbs needed by r iscalcTwosCompLimbCount(bit_count)
.fn subWrap(r: *Mutable, a: Const, b: Const, signedness: Signedness, bit_count: usize) bool
r = a - b with 2s-complement wrapping semantics. Returns whether any overflow oc…
r = a - b with 2s-complement wrapping semantics. Returns whether any overflow occurred.
r, a and b may be aliases Asserts the result fits in
r
. An upper bound on the number of limbs needed by r iscalcTwosCompLimbCount(bit_count)
.fn swap(self: *Mutable, other: *Mutable) void
Efficiently swap an Mutable with another. This swaps the limb pointers and a ful…
Efficiently swap an Mutable with another. This swaps the limb pointers and a full copy is not performed. The address of the limbs field will not be the same after this function.
fn toManaged(self: Mutable, allocator: Allocator) Managed
Asserts that the allocator owns the limbs memory. If this is not the case, use …
Asserts that the allocator owns the limbs memory. If this is not the case, use
toConst().toManaged()
.fn truncate(r: *Mutable, a: Const, signedness: Signedness, bit_count: usize) void
Truncate an integer to a number of bits, following 2s-complement semantics. r m…
Truncate an integer to a number of bits, following 2s-complement semantics. r may alias a.
Asserts
r
has enough storage to store the result. The upper bound iscalcTwosCompLimbCount(a.len)
.