Report a bug
If you spot a problem with this page, click here to create a GitHub issue.
Improve this page
Quickly fork, edit online, and submit a pull request for this page. Requires a signed-in GitHub account. This works well for small changes. If you'd like to make larger changes you may want to consider using a local clone.

mir.bignum.fixed

Note The module doesn't provide full arithmetic API for now.

struct UInt(size_t size) if (size % (size_t.sizeof * 8) == 0 && (size >= size_t.sizeof * 8));
Fixed-length unsigned integer.
Parameters:
size size in bits
size_t[size / (size_t.sizeof * 8)] data;
Payload. The data is located in the target endianness.
this(size_t N)(auto ref const size_t[N] data)
if (N <= this.data.length);
this(size_t argSize)(auto ref const UInt!argSize arg)
if (argSize <= size);
this()(auto ref const ulong[data.length / 2] data);
this(ulong data);
this(uint data);
pure @nogc @safe this(C)(scope const(C)[] str)
if (isSomeChar!C);
Examples:
import mir.math.constant: PI;
UInt!256 integer = "34010447314490204552169750449563978034784726557588085989975288830070948234680"; // constructor
assert(integer == UInt!256.fromHexString("4b313b23aa560e1b0985f89cbe6df5460860e39a64ba92b4abdd3ee77e4e05b8"));
pure nothrow @nogc scope @trusted bool fromStringImpl(C)(scope const(C)[] str)
if (isSomeChar!C);
Returns:
false in case of overflow or incorrect string.

Precondition non-empty coefficients.

const pure nothrow @safe immutable(C)[] toString(C = char)()
if (isSomeChar!C && isMutable!C);
Examples:
auto str = "34010447314490204552169750449563978034784726557588085989975288830070948234680";
auto integer = UInt!256(str);
assert(integer.toString == str);

integer = UInt!256.init;
assert(integer.toString == "0");
const void toString(C = char, W)(ref scope W w)
if (isSomeChar!C && isMutable!C);
Examples:
Check @nogc toString impl
import mir.format: stringBuf;
auto str = "34010447314490204552169750449563978034784726557588085989975288830070948234680";
auto integer = UInt!256(str);
stringBuf buffer;
buffer << integer;
assert(buffer.data == str, buffer.data);
enum UInt!size max;
enum UInt!size min;
pure nothrow @nogc @property scope @safe BigUIntView!size_t view()();
const pure nothrow @nogc @property scope @safe BigUIntView!(const(size_t)) view()();
UInt!size fromHexString(bool allowUnderscores = false)(scope const(char)[] str);
pure nothrow @nogc @safe bool fromHexStringImpl(C, bool allowUnderscores = false)(scope const(C)[] str)
if (isSomeChar!C);
UInt!size fromBinaryString(bool allowUnderscores = false)(scope const(char)[] str);
pure nothrow @nogc @safe bool fromBinaryStringImpl(C, bool allowUnderscores = false)(scope const(C)[] str)
if (isSomeChar!C);
const auto opEquals(size_t rhsSize)(auto ref const UInt!rhsSize rhs);

const auto opEquals(ulong rhs);
const auto opCmp(UInt!size rhs);

const scope auto opCmp(ulong rhs);
pure nothrow @nogc ref scope @safe UInt!size opAssign(ulong rhs) return;
pure nothrow @nogc scope @safe bool opOpAssign(string op)(UInt!size rhs, bool overflow = false)
if (op == "+" || op == "-");

pure nothrow @nogc scope @safe bool opOpAssign(string op)(size_t rhs)
if (op == "+" || op == "-");

pure nothrow @nogc scope @safe bool opOpAssign(string op)(ulong rhs)
if (op == "+" || op == "-");

pure nothrow @nogc scope @safe bool opOpAssign(string op, size_t rsize)(UInt!rsize rhs, bool overflow = false)
if ((op == "+" || op == "-") && (rsize < size));
bool overflow = a += b and bool overflow = a -= b operations.
pure nothrow @nogc scope @safe size_t opOpAssign(string op : "*")(size_t rhs, size_t carry = 0);

pure nothrow @nogc scope @safe auto opOpAssign(string op : "*")(ulong rhs);
Returns:
overflow value of multiplication
pure nothrow @nogc scope @safe void opOpAssign(string op : "*", size_t rhsSize)(UInt!rhsSize rhs)
if (rhsSize <= size);
Returns:
overflow value of multiplication
pure nothrow @nogc scope @safe uint opOpAssign(string op : "/")(uint rhs, uint overflow = 0);
Performs uint remainder = (overflow$big) /= scalar operatrion, where $ denotes big-endian concatenation.

Precondition overflow < rhs

Parameters:
uint rhs unsigned value to devide by
uint overflow initial unsigned overflow
Returns:
unsigned remainder value (evaluated overflow)
nothrow ref UInt!size opOpAssign(string op)(UInt!size rhs) return
if (op == "^" || op == "|" || op == "&");
Examples:
auto a = UInt!128.fromHexString("dfbbfae3cd0aff2714a1de7022b0029d");
auto b = UInt!128.fromHexString("e3251bacb112c88b71ad3f85a970a314");
assert((a.opBinary!"|"(b)) == UInt!128.fromHexString("ffbffbeffd1affaf75adfff5abf0a39d"));
nothrow ref scope UInt!size opOpAssign(string op)(size_t rhs) return
if (op == "^" || op == "|" || op == "&");

pure nothrow @nogc ref scope @safe auto opOpAssign(string op)(ulong rhs) return
if (op == "^" || op == "|" || op == "&");
pure nothrow @nogc ref @safe UInt!size opOpAssign(string op)(size_t shift) return
if (op == "<<" || op == ">>");
const pure nothrow @nogc @safe UInt!size opBinary(string op)(size_t rhs)
if (op == "<<" || op == ">>>" || op == ">>");
auto c = a << b operation.
Examples:
auto a = UInt!128.fromHexString("afbbfae3cd0aff2714a1de7022b0029d");
assert(a << 0 == a);
assert(a << 4 == UInt!128.fromHexString("fbbfae3cd0aff2714a1de7022b0029d0"));
assert(a << 68 == UInt!128.fromHexString("4a1de7022b0029d00000000000000000"));
assert(a << 127 == UInt!128.fromHexString("80000000000000000000000000000000"));
assert(a >> 0 == a);
assert(a >> 4 == UInt!128.fromHexString("afbbfae3cd0aff2714a1de7022b0029"));
assert(a >> 68 == UInt!128.fromHexString("afbbfae3cd0aff2"));
assert(a >> 127 == UInt!128(1));
template opBinary(string op) if (op == "^" || op == "|" || op == "&" || op == "+" || op == "-" || op == "*")

template opBinaryRight(string op) if (op == "^" || op == "|" || op == "&" || op == "+" || op == "*")
Binary operations
const pure nothrow @nogc @safe UInt!size opBinary(size_t rsize)(UInt!rsize rhs)
if (rsize <= size);

const pure nothrow @nogc @safe UInt!size opBinary(ulong rhs);
const UInt!size smallLeftShift()(uint shift);
Shifts left using at most size_t.sizeof * 8 - 1 bits
Examples:
auto a = UInt!128.fromHexString("afbbfae3cd0aff2714a1de7022b0029d");
assert(a.smallLeftShift(4) == UInt!128.fromHexString("fbbfae3cd0aff2714a1de7022b0029d0"));
const UInt!size smallRightShift()(uint shift);
Shifts right using at most size_t.sizeof * 8 - 1 bits
Examples:
auto a = UInt!128.fromHexString("afbbfae3cd0aff2714a1de7022b0029d");
assert(a.smallRightShift(4) == UInt!128.fromHexString("afbbfae3cd0aff2714a1de7022b0029"));
const T opCast(T)()
if (is(Unqual!T == bool));
const T opCast(T)()
if (is(Unqual!T == ulong));
const T opCast(T)()
if (is(Unqual!T == uint));
const pure nothrow @nogc @safe UInt!newSize toSize(size_t newSize, bool lowerBits = true)();
Returns:
the number with shrinked or extended size.
const pure nothrow @nogc @safe UInt!(size + additionalRightBits) rightExtend(size_t additionalRightBits)()
if (additionalRightBits);
const pure nothrow @nogc @safe bool bt()(size_t position);
Examples:
auto a = UInt!128.fromHexString("afbbfae3cd0aff2714a1de7022b0029d");
assert(a.bt(127) == 1);
assert(a.bt(126) == 0);
assert(a.bt(125) == 1);
assert(a.bt(124) == 0);
assert(a.bt(0) == 1);
assert(a.bt(1) == 0);
assert(a.bt(2) == 1);
assert(a.bt(3) == 1);
const pure nothrow @nogc @property @safe size_t ctlz()();
Examples:
auto a = UInt!128.fromHexString("dfbbfae3cd0aff2714a1de7022b0029d");
assert (a.ctlz == 0);
a = UInt!128.init;
assert (a.ctlz == 128);
a = UInt!128.fromHexString("3");
assert (a.ctlz == 126);
const pure nothrow @nogc @property @safe size_t cttz()();
Examples:
auto a = UInt!128.fromHexString("d");
assert (a.cttz == 0);
a = UInt!128.init;
assert (a.cttz == 128);
a = UInt!128.fromHexString("300000000000000000");
assert (a.cttz == 68);
const @property bool signBit()();

@property void signBit()(bool value);
Examples:
auto a = UInt!128.fromHexString("dfbbfae3cd0aff2714a1de7022b0029d");
assert(a.signBit);
a.signBit = false;
assert(a == UInt!128.fromHexString("5fbbfae3cd0aff2714a1de7022b0029d"));
assert(!a.signBit);
a.signBit = true;
assert(a == UInt!128.fromHexString("dfbbfae3cd0aff2714a1de7022b0029d"));
UInt!sizeB extendedMulHigh(size_t sizeA, size_t sizeB)(UInt!sizeA a, UInt!sizeB b);
@safe UInt!(sizeA + sizeB) extendedMul(size_t sizeA, size_t sizeB)(UInt!sizeA a, UInt!sizeB b);

@safe UInt!(size + size_t.sizeof * 8) extendedMul(size_t size)(UInt!size a, size_t b);

UInt!128 extendedMul()(ulong a, ulong b);

UInt!64 extendedMul()(uint a, uint b);
Examples:
auto a = UInt!128.max;
auto b = UInt!256.max;
auto c = UInt!384.max;
assert(extendedMul(a, a) == UInt!256.max - UInt!128.max - UInt!128.max);
assert(extendedMul(a, b) == UInt!384.max - UInt!128.max - UInt!256.max);
assert(extendedMul(b, a) == UInt!384.max - UInt!128.max - UInt!256.max);

a = UInt!128.fromHexString("dfbbfae3cd0aff2714a1de7022b0029d");
b = UInt!256.fromHexString("3fe48f2dc8aad570d037bc9b323fc0cfa312fcc2f63cb521bd8a4ca6157ef619");
c = UInt!384.fromHexString("37d7034b86e8d58a9fc564463fcedef9e2ad1126dd2c0f803e61c72852a9917ef74fa749e7936a9e4e224aeeaff91f55");
assert(extendedMul(a, b) == c);
assert(extendedMul(b, a) == c);

a = UInt!128.fromHexString("23edf5ff44ee3a4feafc652607aa1eb9");
b = UInt!256.fromHexString("d3d79144b8941fb50c9102e3251bacb112c88b71ad3f85a970a31458ce24297b");
c = UInt!384.fromHexString("1dbb62fe6ca5fed101068eda7222d6a9857633ecdfed37a2d156ff6309065ecc633f31465727677a93a7acbd1dac63e3");
assert(extendedMul(a, b) == c);
assert(extendedMul(b, a) == c);
Examples:
ulong
ulong a = 0xdfbbfae3cd0aff27;
ulong b = 0x14a1de7022b0029d;
auto c = UInt!128.fromHexString("120827399968ea2a2db185d16e8cc8eb");
assert(extendedMul(a, b) == c);
assert(extendedMul(b, a) == c);
Examples:
uint
uint a = 0xdfbbfae3;
uint b = 0xcd0aff27;
auto c = UInt!64.fromHexString("b333243de8695595");
assert(extendedMul(a, b) == c);
assert(extendedMul(b, a) == c);
UInt!(size + size_t.sizeof * 8) extendedMulAdd(size_t size)(UInt!size a, size_t b, UInt!size c);