📄 biginteger.cs
字号:
data = new uint[maxLength];
for(int i = 0; i < result.dataLength; i++)
data[i] = result.data[i];
dataLength = result.dataLength;
}
//***********************************************************************
// Constructor (Default value provided by an array of bytes)
//
// The lowest index of the input byte array (i.e [0]) should contain the
// most significant byte of the number, and the highest index should
// contain the least significant byte.
//
// E.g.
// To initialize "a" with the default value of 0x1D4F in base 16
// byte[] temp = { 0x1D, 0x4F };
// BigInteger a = new BigInteger(temp)
//
// Note that this method of initialization does not allow the
// sign to be specified.
//
//***********************************************************************
public BigInteger(byte[] inData)
{
dataLength = inData.Length >> 2;
int leftOver = inData.Length & 0x3;
if(leftOver != 0) // length not multiples of 4
dataLength++;
if(dataLength > maxLength)
throw(new ArithmeticException("Byte overflow in constructor."));
data = new uint[maxLength];
for(int i = inData.Length - 1, j = 0; i >= 3; i -= 4, j++)
{
data[j] = (uint)((inData[i-3] << 24) + (inData[i-2] << 16) +
(inData[i-1] << 8) + inData[i]);
}
if(leftOver == 1)
data[dataLength-1] = (uint)inData[0];
else if(leftOver == 2)
data[dataLength-1] = (uint)((inData[0] << 8) + inData[1]);
else if(leftOver == 3)
data[dataLength-1] = (uint)((inData[0] << 16) + (inData[1] << 8) + inData[2]);
while(dataLength > 1 && data[dataLength-1] == 0)
dataLength--;
//Console.WriteLine("Len = " + dataLength);
}
//***********************************************************************
// Constructor (Default value provided by an array of bytes of the
// specified length.)
//***********************************************************************
public BigInteger(byte[] inData, int inLen)
{
dataLength = inLen >> 2;
int leftOver = inLen & 0x3;
if(leftOver != 0) // length not multiples of 4
dataLength++;
if(dataLength > maxLength || inLen > inData.Length)
throw(new ArithmeticException("Byte overflow in constructor."));
data = new uint[maxLength];
for(int i = inLen - 1, j = 0; i >= 3; i -= 4, j++)
{
data[j] = (uint)((inData[i-3] << 24) + (inData[i-2] << 16) +
(inData[i-1] << 8) + inData[i]);
}
if(leftOver == 1)
data[dataLength-1] = (uint)inData[0];
else if(leftOver == 2)
data[dataLength-1] = (uint)((inData[0] << 8) + inData[1]);
else if(leftOver == 3)
data[dataLength-1] = (uint)((inData[0] << 16) + (inData[1] << 8) + inData[2]);
if(dataLength == 0)
dataLength = 1;
while(dataLength > 1 && data[dataLength-1] == 0)
dataLength--;
//Console.WriteLine("Len = " + dataLength);
}
//***********************************************************************
// Constructor (Default value provided by an array of unsigned integers)
//*********************************************************************
public BigInteger(uint[] inData)
{
dataLength = inData.Length;
if(dataLength > maxLength)
throw(new ArithmeticException("Byte overflow in constructor."));
data = new uint[maxLength];
for(int i = dataLength - 1, j = 0; i >= 0; i--, j++)
data[j] = inData[i];
while(dataLength > 1 && data[dataLength-1] == 0)
dataLength--;
//Console.WriteLine("Len = " + dataLength);
}
//***********************************************************************
// Overloading of the typecast operator.
// For BigInteger bi = 10;
//***********************************************************************
public static implicit operator BigInteger(long value)
{
return (new BigInteger(value));
}
public static implicit operator BigInteger(ulong value)
{
return (new BigInteger(value));
}
public static implicit operator BigInteger(int value)
{
return (new BigInteger((long)value));
}
public static implicit operator BigInteger(uint value)
{
return (new BigInteger((ulong)value));
}
//***********************************************************************
// Overloading of addition operator
//***********************************************************************
public static BigInteger operator +(BigInteger bi1, BigInteger bi2)
{
BigInteger result = new BigInteger();
result.dataLength = (bi1.dataLength > bi2.dataLength) ? bi1.dataLength : bi2.dataLength;
long carry = 0;
for(int i = 0; i < result.dataLength; i++)
{
long sum = (long)bi1.data[i] + (long)bi2.data[i] + carry;
carry = sum >> 32;
result.data[i] = (uint)(sum & 0xFFFFFFFF);
}
if(carry != 0 && result.dataLength < maxLength)
{
result.data[result.dataLength] = (uint)(carry);
result.dataLength++;
}
while(result.dataLength > 1 && result.data[result.dataLength-1] == 0)
result.dataLength--;
// overflow check
int lastPos = maxLength - 1;
if((bi1.data[lastPos] & 0x80000000) == (bi2.data[lastPos] & 0x80000000) &&
(result.data[lastPos] & 0x80000000) != (bi1.data[lastPos] & 0x80000000))
{
throw (new ArithmeticException());
}
return result;
}
//***********************************************************************
// Overloading of the unary ++ operator
//***********************************************************************
public static BigInteger operator ++(BigInteger bi1)
{
BigInteger result = new BigInteger(bi1);
long val, carry = 1;
int index = 0;
while(carry != 0 && index < maxLength)
{
val = (long)(result.data[index]);
val++;
result.data[index] = (uint)(val & 0xFFFFFFFF);
carry = val >> 32;
index++;
}
if(index > result.dataLength)
result.dataLength = index;
else
{
while(result.dataLength > 1 && result.data[result.dataLength-1] == 0)
result.dataLength--;
}
// overflow check
int lastPos = maxLength - 1;
// overflow if initial value was +ve but ++ caused a sign
// change to negative.
if((bi1.data[lastPos] & 0x80000000) == 0 &&
(result.data[lastPos] & 0x80000000) != (bi1.data[lastPos] & 0x80000000))
{
throw (new ArithmeticException("Overflow in ++."));
}
return result;
}
//***********************************************************************
// Overloading of subtraction operator
//***********************************************************************
public static BigInteger operator -(BigInteger bi1, BigInteger bi2)
{
BigInteger result = new BigInteger();
result.dataLength = (bi1.dataLength > bi2.dataLength) ? bi1.dataLength : bi2.dataLength;
long carryIn = 0;
for(int i = 0; i < result.dataLength; i++)
{
long diff;
diff = (long)bi1.data[i] - (long)bi2.data[i] - carryIn;
result.data[i] = (uint)(diff & 0xFFFFFFFF);
if(diff < 0)
carryIn = 1;
else
carryIn = 0;
}
// roll over to negative
if(carryIn != 0)
{
for(int i = result.dataLength; i < maxLength; i++)
result.data[i] = 0xFFFFFFFF;
result.dataLength = maxLength;
}
// fixed in v1.03 to give correct datalength for a - (-b)
while(result.dataLength > 1 && result.data[result.dataLength-1] == 0)
result.dataLength--;
// overflow check
int lastPos = maxLength - 1;
if((bi1.data[lastPos] & 0x80000000) != (bi2.data[lastPos] & 0x80000000) &&
(result.data[lastPos] & 0x80000000) != (bi1.data[lastPos] & 0x80000000))
{
throw (new ArithmeticException());
}
return result;
}
//***********************************************************************
// Overloading of the unary -- operator
//***********************************************************************
public static BigInteger operator --(BigInteger bi1)
{
BigInteger result = new BigInteger(bi1);
long val;
bool carryIn = true;
int index = 0;
while(carryIn && index < maxLength)
{
val = (long)(result.data[index]);
val--;
result.data[index] = (uint)(val & 0xFFFFFFFF);
if(val >= 0)
carryIn = false;
index++;
}
if(index > result.dataLength)
result.dataLength = index;
while(result.dataLength > 1 && result.data[result.dataLength-1] == 0)
result.dataLength--;
// overflow check
int lastPos = maxLength - 1;
// overflow if initial value was -ve but -- caused a sign
// change to positive.
if((bi1.data[lastPos] & 0x80000000) != 0 &&
(result.data[lastPos] & 0x80000000) != (bi1.data[lastPos] & 0x80000000))
{
throw (new ArithmeticException("Underflow in --."));
}
return result;
}
//***********************************************************************
// Overloading of multiplication operator
//***********************************************************************
public static BigInteger operator *(BigInteger bi1, BigInteger bi2)
{
int lastPos = maxLength-1;
bool bi1Neg = false, bi2Neg = false;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -