diff --git a/changelog/std-bigint-getDigit.dd b/changelog/std-bigint-getDigit.dd new file mode 100644 index 000000000..62eb29c03 --- /dev/null +++ b/changelog/std-bigint-getDigit.dd @@ -0,0 +1,15 @@ +`getDigit` Was Added To `std.bigint` + +$(REF getDigit, std, algorithm, BigInt) gives the `ulongs` or `uints` +that make up the underlying representation of the `BigInt`. + +----- +import std.bigint; + +auto a = BigInt("1000"); +assert(a.getDigit(0) == 1000); + +auto b = BigInt("2_000_000_000_000_000_000_000_000_000"); +assert(b.getDigit(0) == 4584946418820579328); +assert(b.getDigit(1) == 108420217); +----- diff --git a/std/bigint.d b/std/bigint.d index 786663e89..1bb893935 100644 --- a/std/bigint.d +++ b/std/bigint.d @@ -1025,6 +1025,53 @@ public: assert(aa[BigInt(456)] == "def"); } + /** + * Gets the nth number in the underlying representation that makes up the whole + * `BigInt`. + * + * Params: + * T = the type to view the underlying representation as + * n = The nth number to retrieve. Must be less than $(LREF ulongLength) or + * $(LREF uintLength) with respect to `T`. + * Returns: + * The nth `ulong` in the representation of this `BigInt`. + */ + T getDigit(T = ulong)(size_t n) const + if (is(T == ulong) || is(T == uint)) + { + static if (is(T == ulong)) + { + assert(n < ulongLength(), "getDigit index out of bounds"); + return data.peekUlong(n); + } + else + { + assert(n < uintLength(), "getDigit index out of bounds"); + return data.peekUint(n); + } + } + + /// + @system pure unittest + { + auto a = BigInt("1000"); + assert(a.ulongLength() == 1); + assert(a.getDigit(0) == 1000); + + assert(a.uintLength() == 1); + assert(a.getDigit!uint(0) == 1000); + + auto b = BigInt("2_000_000_000_000_000_000_000_000_000"); + assert(b.ulongLength() == 2); + assert(b.getDigit(0) == 4584946418820579328); + assert(b.getDigit(1) == 108420217); + + assert(b.uintLength() == 3); + assert(b.getDigit!uint(0) == 3489660928); + assert(b.getDigit!uint(1) == 1067516025); + assert(b.getDigit!uint(2) == 108420217); + } + private: void negate() @safe pure nothrow @nogc { diff --git a/std/internal/math/biguintcore.d b/std/internal/math/biguintcore.d index ebe5c30f0..76dda571b 100644 --- a/std/internal/math/biguintcore.d +++ b/std/internal/math/biguintcore.d @@ -284,7 +284,7 @@ public: } // The value at (cast(ulong[]) data)[n] - ulong peekUlong(int n) pure nothrow const @safe @nogc + ulong peekUlong(size_t n) pure nothrow const @safe @nogc { static if (BigDigit.sizeof == int.sizeof) { @@ -296,7 +296,8 @@ public: return data[n]; } } - uint peekUint(int n) pure nothrow const @safe @nogc + + uint peekUint(size_t n) pure nothrow const @safe @nogc { static if (BigDigit.sizeof == int.sizeof) { @@ -308,7 +309,7 @@ public: return (n & 1) ? cast(uint)(x >> 32) : cast(uint) x; } } -public: + /// void opAssign(Tulong)(Tulong u) pure nothrow @safe if (is (Tulong == ulong)) {