Merge pull request #5987 from JackStouffer/issue17249

Fix Issue 17249: Added BigInt.getDigit
This commit is contained in:
Andrei Alexandrescu 2018-01-25 16:59:51 -05:00 committed by GitHub
commit adee662094
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 66 additions and 3 deletions

View file

@ -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);
-----

View file

@ -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
{

View file

@ -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))
{