mp.Integer: add two's complement constructor

This commit is contained in:
Eugen Wissner 2017-05-10 19:27:25 +02:00
parent e4091669f8
commit 8afb552d59

View File

@ -160,6 +160,45 @@ struct Integer
assert(integer == 7383520307673030126); assert(integer == 7383520307673030126);
} }
/**
* Constructs the integer from a two's complement representation.
*
* Params:
* R = Range type.
* value = Range.
* allocator = Allocator.
*
* Precondition: $(D_INLINECODE allocator !is null)
*/
this(R)(R value,
shared Allocator allocator = defaultAllocator)
if (isBidirectionalRange!R && hasLength!R
&& is(Unqual!(ElementType!R) == ubyte))
{
this(Sign.positive, value, allocator);
if (!value.empty && ((value.front & 0x80) != 0))
{
// Negative number.
opOpAssign!"-"(exp2(countBits()));
}
}
///
nothrow @safe @nogc unittest
{
{
ubyte[8] range = [ 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xdd, 0xee ];
auto integer = Integer(range[]);
assert(integer == 7383520307673030126);
}
{
ubyte[8] range = [ 0xe6, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xdd, 0xee ];
auto integer = Integer(range[]);
assert(integer == -1839851729181745682);
}
}
/** /**
* Copies the integer. * Copies the integer.
*/ */
@ -219,10 +258,10 @@ struct Integer
{ {
if (this.sign) if (this.sign)
{ {
const bitCount = countBits(); const bc = countBits();
auto length = bitCount + (8 - (bitCount & 0x07)); auto length = bc + (8 - (bc & 0x07));
if (((countLSBs() + 1) == bitCount) && ((bitCount & 0x07) == 0)) if (((countLSBs() + 1) == bc) && ((bc & 0x07) == 0))
{ {
--length; --length;
} }
@ -1418,10 +1457,10 @@ struct Integer
{ {
return vector; return vector;
} }
const bitCount = countBits(); const bc = countBits();
const remainingBits = bitCount & 0x07; const remainingBits = bc & 0x07;
vector.reserve(bitCount / 8); vector.reserve(bc / 8);
if (remainingBits == 0) if (remainingBits == 0)
{ {
vector.insertBack(ubyte.init); vector.insertBack(ubyte.init);
@ -1431,9 +1470,9 @@ struct Integer
Integer tmp; Integer tmp;
if (this.sign) if (this.sign)
{ {
auto length = bitCount + (8 - remainingBits); auto length = bc + (8 - remainingBits);
if (((countLSBs() + 1) == bitCount) && (remainingBits == 0)) if (((countLSBs() + 1) == bc) && (remainingBits == 0))
{ {
length -= 8; length -= 8;
} }