Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 86 additions & 0 deletions std/bigint.d
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,92 @@ public:
opAssign(x);
}

/// Construct `BigInt` from `Int128`
import std.int128 : Int128;
Comment on lines +191 to +192
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Construct `BigInt` from `Int128`
import std.int128 : Int128;
import std.int128 : Int128;
/// Construct `BigInt` from `Int128`

Not sure if this is needed, but I think the doc comment should be after the import.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Putting this import here means that it will be affected by the public: attribute specifier on line 53, turning it into a public import. This means that the symbol Int128 will be visible as BigInt.Int128 from outside the std.bigint module.

To fix this, move the import to the top of the module, outside the declaration of struct BigInt.

this(Int128 x) pure nothrow @safe {
data = data.init;
opAssign(x);
}

/// Assignment from `Int128`.
BigInt opAssign(T : Int128)(T x) @safe
{
sign = false;

ulong lo = x.data.lo;
long hi = x.data.hi;

// Determine sign and get absolute value
if (hi < 0)
{
sign = true;

// Two's complement negate
lo = ~lo + 1;
hi = ~hi + (lo == 0);
}

// Now (hi, lo) is the positive magnitude
if (hi != 0)
{
ulong[2] mag = [cast(ulong) hi, lo];
data.fromMagnitude(mag[]);
}
else
{
data = lo;
}

if (data.isZero)
sign = false;

return this;
}

///
@safe unittest
{
import std.int128;
Int128 x;
BigInt b;
BigInt re;

x = Int128(0L);
b = x;
re = BigInt(0L);
assert(b == re);

x = Int128(42L);
b = x;
re = BigInt(42L);
assert(b == re);

x = Int128(-42L);
b = x;
re = BigInt(-42L);
assert(b == re);

x = Int128(-1L);
b = x;
re = BigInt(-1L);
assert(b == re);

x = (Int128(1L) << 100) + Int128(12345L);
b = x;
re = (BigInt(1L) << 100) + BigInt(12345L);
assert(b == re);

x = -((Int128(1L) << 100) + Int128(12345L));
b = x;
re = -((BigInt(1L) << 100) + BigInt(12345L));
assert(b == re);

x = Int128.min;
b = x;
re = -(BigInt(1L) << 127);
assert(b == re);
}

///
@safe unittest
{
Expand Down