DoxigAlpha

writePackedTwosComplement

Write the value of x to a packed memory buffer. Asserts that buffer is large enough to contain a value of bit-size bit_count at offset bit_offset.

This is equivalent to storing the value of an integer with bit_count bits as if it were a field in packed memory at the provided bit offset.

Function parameters

Parameters

#
buffer:[]u8
bit_offset:usize
bit_count:usize

Used to indicate either limit of a 2s-complement integer.

Types

#
TwosCompIntLimit
Used to indicate either limit of a 2s-complement integer.
Mutable
A arbitrary-precision big integer, with a fixed set of mutable limbs.
Const
A arbitrary-precision big integer, with a fixed set of immutable limbs.
Managed
An arbitrary-precision big integer along with an allocator which manages the memory.

Returns the number of limbs needed to store `scalar`, which must be a

Functions

#
calcLimbLen
Returns the number of limbs needed to store `scalar`, which must be a
calcSetStringLimbCount
Assumes `string_len` doesn't account for minus signs if the number is negative.
calcNonZeroTwosCompLimbCount
Compute the number of limbs required to store a 2s-complement number of `bit_count` bits.
calcTwosCompLimbCount
Compute the number of limbs required to store a 2s-complement number of `bit_count` bits.
addMulLimbWithCarry
a + b * c + *carry, sets carry to the overflow bits
llcmp
Returns -1, 0, 1 if |a| < |b|, |a| == |b| or |a| > |b| respectively for limbs.

Source

Implementation

#
pub fn writePackedTwosComplement(x: Const, buffer: []u8, bit_offset: usize, bit_count: usize, endian: Endian) void {
    assert(x.fitsInTwosComp(if (x.positive) .unsigned else .signed, bit_count));

    // Copy all complete limbs
    var carry: u1 = 1;
    var limb_index: usize = 0;
    var bit_index: usize = 0;
    while (limb_index < bit_count / @bitSizeOf(Limb)) : (limb_index += 1) {
        var limb: Limb = if (limb_index < x.limbs.len) x.limbs[limb_index] else 0;

        // 2's complement (bitwise not, then add carry bit)
        if (!x.positive) {
            const ov = @addWithOverflow(~limb, carry);
            limb = ov[0];
            carry = ov[1];
        }

        // Write one Limb of bits
        mem.writePackedInt(Limb, buffer, bit_index + bit_offset, limb, endian);
        bit_index += @bitSizeOf(Limb);
    }

    // Copy the remaining bits
    if (bit_count != bit_index) {
        var limb: Limb = if (limb_index < x.limbs.len) x.limbs[limb_index] else 0;

        // 2's complement (bitwise not, then add carry bit)
        if (!x.positive) limb = ~limb +% carry;

        // Write all remaining bits
        mem.writeVarPackedInt(buffer, bit_index + bit_offset, bit_count - bit_index, limb, endian);
    }
}