110,535
社区成员
发帖
与我相关
我的任务
分享
public BigInteger(Byte[] value)
{
if (value == null)
throw new ArgumentNullException("value");
Contract.EndContractBlock();
int byteCount = value.Length;
bool isNegative = byteCount > 0 && ((value[byteCount - 1] & 0x80) == 0x80);
// Try to conserve space as much as possible by checking for wasted leading byte[] entries
while (byteCount > 0 && value[byteCount-1] == 0) byteCount--;
if (byteCount == 0)
{
// BigInteger.Zero
_sign = 0;
_bits = null;
AssertValid();
return;
}
if (byteCount <= 4)
{
if (isNegative)
_sign = unchecked((int)0xffffffff);
else
_sign = 0;
for (int i = byteCount - 1; i >= 0; i--)
{
_sign <<= 8;
_sign |= value[i];
}
_bits = null;
if (_sign < 0 && !isNegative)
{
// int32 overflow
// example: Int64 value 2362232011 (0xCB, 0xCC, 0xCC, 0x8C, 0x0)
// can be naively packed into 4 bytes (due to the leading 0x0)
// it overflows into the int32 sign bit
_bits = new uint[1];
_bits[0] = (uint)_sign;
_sign = +1;
}
if (_sign == Int32.MinValue)
this = s_bnMinInt;
}
else
{
int unalignedBytes = byteCount % 4;
int dwordCount = byteCount / 4 + (unalignedBytes == 0 ? 0 : 1);
bool isZero = true;
uint[] val = new uint[dwordCount];
// Copy all dwords, except but don't do the last one if it's not a full four bytes
int curDword, curByte, byteInDword;
curByte = 3;
for (curDword = 0; curDword < dwordCount - (unalignedBytes == 0 ? 0 : 1); curDword++) {
byteInDword = 0;
while (byteInDword < 4) {
if (value[curByte] != 0x00) isZero = false;
val[curDword] <<= 8;
val[curDword] |= value[curByte];
curByte--;
byteInDword++;
}
curByte += 8;
}
// Copy the last dword specially if it's not aligned
if (unalignedBytes != 0) {
if (isNegative) val[dwordCount - 1] = 0xffffffff;
for (curByte = byteCount - 1; curByte >= byteCount - unalignedBytes; curByte--) {
if (value[curByte] != 0x00) isZero = false;
val[curDword] <<= 8;
val[curDword] |= value[curByte];
}
}
if (isZero) {
this = s_bnZeroInt;
}
else if (isNegative) {
NumericsHelpers.DangerousMakeTwosComplement(val); // mutates val
// pack _bits to remove any wasted space after the twos complement
int len = val.Length;
while (len > 0 && val[len - 1] == 0)
len--;
if (len == 1 && ((int)(val[0])) > 0) {
if (val[0] == 1 /* abs(-1) */) {
this = s_bnMinusOneInt;
}
else if (val[0] == kuMaskHighBit /* abs(Int32.MinValue) */) {
this = s_bnMinInt;
}
else {
_sign = (-1) * ((int)val[0]);
_bits = null;
}
}
else if (len != val.Length) {
_sign = -1;
_bits = new uint[len];
Array.Copy(val, _bits, len);
}
else {
_sign = -1;
_bits = val;
}
}
else
{
_sign = +1;
_bits = val;
}
}
AssertValid();
}