The OpenD Programming Language

BigUIntView

Arbitrary length unsigned integer view.

struct BigUIntView (
W
) if (
__traits(isUnsigned, W)
) {}

Alias This

lightConst

ditto

Members

Functions

bitwiseNotInPlace
void bitwiseNotInPlace()
bt
bool bt(size_t position)
ctlz
size_t ctlz()
cttz
size_t cttz()
fromBinaryStringImpl
bool fromBinaryStringImpl(const(C)[] str)
fromHexStringImpl
bool fromHexStringImpl(const(C)[] str)
fromStringImpl
bool fromStringImpl(const(C)[] str)
get
bool get(U value)
length
size_t length()

Retrurns: signed integer view using the same data payload

lightConst
BigUIntView!(const W) lightConst()
mostSignificantFirst
auto mostSignificantFirst()
mostSignificantFirst
auto mostSignificantFirst()
normalized
BigUIntView normalized()
BigUIntView!(const W) normalized()

Strips most significant zero coefficients.

opCast
T opCast()
opCast
T opCast()
opCast
T opCast()
opCast
BigUIntView!V opCast()
opCmp
sizediff_t opCmp(BigUIntView!(const W) rhs)
opEquals
bool opEquals(BigUIntView!(const W) rhs)
opEquals
bool opEquals(ulong rhs)
opOpAssign
bool opOpAssign(BigUIntView!(const W) rhs, bool overflow)
bool opOpAssign(BigIntView!(const W) rhs, bool overflow)

Performs bool overflow = big +(-)= big operatrion.

opOpAssign
bool opOpAssign(T rhs)

Performs bool Overflow = big +(-)= scalar operatrion. Precondition: non-empty coefficients

opOpAssign
W opOpAssign(W rhs, W overflow)

Performs W overflow = (big += overflow) *= scalar operatrion. Precondition: non-empty coefficients

opOpAssign
uint opOpAssign(uint rhs, uint overflow)

Performs uint remainder = (overflow$big) /= scalar operatrion, where $ denotes big-endian concatenation. Precondition: non-empty coefficients, overflow < rhs

opOpAssign
UInt!size opOpAssign(UInt!size rhs, UInt!size overflow)

Performs W overflow = (big += overflow) *= scalar operatrion. Precondition: non-empty coefficients

opUnary
BigIntView!W opUnary()
popLeastSignificant
void popLeastSignificant()
popMostSignificant
void popMostSignificant()
signed
BigIntView!W signed(bool sign)

Retrurns: signed integer view using the same data payload

smallLeftShiftInPlace
void smallLeftShiftInPlace(uint shift)

Shifts left using at most size_t.sizeof * 8 - 1 bits

smallRightShiftInPlace
void smallRightShiftInPlace(uint shift)

Shifts right using at most size_t.sizeof * 8 - 1 bits

toStringImpl
size_t toStringImpl(C[] str)
topLeastSignificantPart
BigUIntView topLeastSignificantPart(size_t length)
topMostSignificantPart
BigUIntView topMostSignificantPart(size_t length)
twoComplementInPlace
bool twoComplementInPlace()

Performs number=-number operatrion. Precondition: non-empty coefficients

withSign
BigIntView!W withSign(bool sign)

Static functions

fromBinaryString
BigUIntView fromBinaryString(const(C)[] str)
fromHexString
BigUIntView fromHexString(const(C)[] str)

Variables

coefficients
W[] coefficients;

A group of coefficients for a radix W.max + 1.

Examples

import mir.bignum.integer;

auto a = BigInt!2("123456789098765432123456789098765432100");
char[ceilLog10Exp2(a.data.length * (size_t.sizeof * 8))] buffer;
auto len = a.view.unsigned.toStringImpl(buffer);
assert(buffer[$ - len .. $] == "123456789098765432123456789098765432100");
import mir.test;
auto view = BigUIntView!size_t.fromHexString!(char, true)("abcd_efab_cdef");
(cast(ulong)view).should == 0xabcd_efab_cdef;
auto a = BigUIntView!size_t.fromHexString("afbbfae3cd0aff2714a1de7022b0029d");
a.smallLeftShiftInPlace(4);
assert(a == BigUIntView!size_t.fromHexString("fbbfae3cd0aff2714a1de7022b0029d0"));
a.smallLeftShiftInPlace(0);
assert(a == BigUIntView!size_t.fromHexString("fbbfae3cd0aff2714a1de7022b0029d0"));
auto a = BigUIntView!size_t.fromHexString("afbbfae3cd0aff2714a1de7022b0029d");
a.smallRightShiftInPlace(4);
assert(a == BigUIntView!size_t.fromHexString("afbbfae3cd0aff2714a1de7022b0029"));
// Check that invalid underscores in hex literals throw an error.
void expectThrow(const(char)[] input) {
    bool caught = false;
    try { 
        auto view = BigUIntView!size_t.fromHexString!(char, true)(input);
    } catch (Exception e) {
        caught = true;
    }

    assert(caught);
}

expectThrow("abcd_efab_cef_");
expectThrow("abcd__efab__cef");
expectThrow("_abcd_efab_cdef");
expectThrow("_abcd_efab_cdef_");
expectThrow("_abcd_efab_cdef__");
expectThrow("__abcd_efab_cdef");
expectThrow("__abcd_efab_cdef_");
expectThrow("__abcd_efab_cdef__");
expectThrow("__abcd__efab_cdef__");
expectThrow("__abcd__efab__cdef__");
auto view = BigUIntView!size_t.fromBinaryString!(char, true)("1111_0000_0101");
assert(cast(ulong)view == 0b1111_0000_0101);
// Check that invalid underscores in hex literals throw an error.
void expectThrow(const(char)[] input) {
    bool caught = false;
    try { 
        auto view = BigUIntView!size_t.fromBinaryString!(char, true)(input);
    } catch (Exception e) {
        caught = true;
    }

    assert(caught);
}

expectThrow("abcd");
expectThrow("0101__1011__0111");
expectThrow("_0101_1011_0111");
expectThrow("_0101_1011_0111_");
expectThrow("_0101_1011_0111__");
expectThrow("__0101_1011_0111_");
expectThrow("__0101_1011_0111__");
expectThrow("__0101__1011_0111__");
expectThrow("__1011__0111__1011__");
auto a = cast(double) BigUIntView!size_t.fromHexString("afbbfae3cd0aff2714a1de7022b0029d");
assert(a == 0xa.fbbfae3cd0bp+124);
assert(cast(double) BigUIntView!size_t.init == 0);
assert(cast(double) BigUIntView!size_t([0]) == 0);
import mir.bignum.fp: Fp;
import mir.bignum.fixed: UInt;

auto fp = cast(Fp!128) BigUIntView!ulong.fromHexString("afbbfae3cd0aff2714a1de7022b0029d");
assert(fp.exponent == 0);
assert(fp.coefficient == UInt!128.fromHexString("afbbfae3cd0aff2714a1de7022b0029d"));

fp = cast(Fp!128) BigUIntView!size_t.fromHexString("ae3cd0aff2714a1de7022b0029d");
assert(fp.exponent == -20);
assert(fp.coefficient == UInt!128.fromHexString("ae3cd0aff2714a1de7022b0029d00000"));

fp = cast(Fp!128) BigUIntView!size_t.fromHexString("e7022b0029d");
assert(fp.exponent == -84);
assert(fp.coefficient == UInt!128.fromHexString("e7022b0029d000000000000000000000"));

fp = cast(Fp!128) BigUIntView!size_t.fromHexString("e7022b0029d");
assert(fp.exponent == -84);
assert(fp.coefficient == UInt!128.fromHexString("e7022b0029d000000000000000000000"));

fp = cast(Fp!128) BigUIntView!size_t.fromHexString("e7022b0029d");
assert(fp.exponent == -84);
assert(fp.coefficient == UInt!128.fromHexString("e7022b0029d000000000000000000000"));

fp = cast(Fp!128) BigUIntView!size_t.fromHexString("ffffffffffffffffffffffffffffffff1000000000000000");
assert(fp.exponent == 64);
assert(fp.coefficient == UInt!128.fromHexString("ffffffffffffffffffffffffffffffff"));

fp = cast(Fp!128) BigUIntView!size_t.fromHexString("ffffffffffffffffffffffffffffffff8000000000000000");
assert(fp.exponent == 65);
assert(fp.coefficient == UInt!128.fromHexString("80000000000000000000000000000000"));

fp = cast(Fp!128) BigUIntView!size_t.fromHexString("fffffffffffffffffffffffffffffffe8000000000000000");
assert(fp.exponent == 64);
assert(fp.coefficient == UInt!128.fromHexString("fffffffffffffffffffffffffffffffe"));

fp = cast(Fp!128) BigUIntView!size_t.fromHexString("fffffffffffffffffffffffffffffffe8000000000000001");
assert(fp.exponent == 64);
assert(fp.coefficient == UInt!128.fromHexString("ffffffffffffffffffffffffffffffff"));
auto view = BigUIntView!ulong.fromHexString("afbbfae3cd0aff2714a1de7022b0029d");
assert(cast(ulong) view == 0x14a1de7022b0029d);
assert(cast(uint) view == 0x22b0029d);
assert(cast(ubyte) view == 0x9d);
import std.traits;
alias AliasSeq(T...) = T;

foreach (T; AliasSeq!(ubyte, ushort, uint, ulong))
{
    T[3] lhsData = [1, T.max-1, 0];
    T[3] rhsData = [T.max, T.max, 0];

    auto lhs = BigUIntView!T(lhsData).normalized;

    /// bool overflow = bigUInt op= scalar
    assert(lhs.coefficients == [1, T.max-1]);
    assert(lhs.mostSignificantFirst == [T.max-1, 1]);
    static if (T.sizeof >= 4)
    {
        assert((lhs += T.max) == false);
        assert(lhs.coefficients == [0, T.max]);
        assert((lhs += T.max) == false);
        assert((lhs += T.max) == true); // overflow bit
        assert(lhs.coefficients == [T.max-1, 0]);
        assert((lhs -= T(1)) == false);
        assert(lhs.coefficients == [T.max-2, 0]);
        assert((lhs -= T.max) == true); // underflow bit
        assert(lhs.coefficients == [T.max-1, T.max]);
        assert((lhs -= Signed!T(-4)) == true); // overflow bit
        assert(lhs.coefficients == [2, 0]);
        assert((lhs += Signed!T.max) == false); // overflow bit
        assert(lhs.coefficients == [Signed!T.max + 2, 0]);

        ///  bool overflow = bigUInt op= bigUInt/bigInt
        lhs = BigUIntView!T(lhsData);
        auto rhs = BigUIntView!T(rhsData).normalized;
        assert(lhs.coefficients == [Signed!T.max + 2, 0, 0]);
        assert(rhs.coefficients == [T.max, T.max]);
        assert((lhs += rhs) == false);
        assert(lhs.coefficients == [Signed!T.max + 1, 0, 1]);
        assert((lhs -= rhs) == false);
        assert(lhs.coefficients == [Signed!T.max + 2, 0, 0]);
        assert((lhs += -rhs) == true);
        assert(lhs.coefficients == [Signed!T.max + 3, 0, T.max]);
        assert((lhs += -(-rhs)) == true);
        assert(lhs.coefficients == [Signed!T.max + 2, 0, 0]);

        /// W overflow = bigUInt *= scalar
        assert((lhs *= T.max) == 0);
        assert((lhs += T(Signed!T.max + 2)) == false);
        assert(lhs.coefficients == [0, Signed!T.max + 2, 0]);
        lhs = lhs.normalized;
        lhs.coefficients[1] = T.max / 2 + 3;
        assert(lhs.coefficients == [0, T.max / 2 + 3]);
        assert((lhs *= 8u) == 4);
        assert(lhs.coefficients == [0, 16]);
    }
}

Meta