用c#编写的无限位数计算
2010-09-30 21:05:42 来源:WEB开发网加法和减法简单,就是用一个数组来保存每一位上的数字,然后从后往前一位一位的加减,加法记得前面会进一,减法则要把前面多余的“0”去掉;
乘法,你就在草稿纸上做下笔算吧,就是两个数组相应位数撒谎能够的数字相乘,分别在后面加上这两个数位后面的“0”,比如:
234*678=2*6*100*100+2*7*100*10+。。。。+4*8
是否看的明白?就是小学时老师怎么教你算你就怎么算,把电脑当成小学生就行了,这里要用到前面的加法;
除法:先拿被除数前面和除数相同位数的数和除数的倍数进行比较,这里的倍数计算就是前面的乘法,把最大倍数放进答案的最高位,以此类推,再把余下的数*10+后面一位,继续计算,直到最后一位;
下面是我写的代码,我先贴出最底层的无符号无浮点运算,计算参数均为StringBuilder类型,方便转换
(此代码仅供参考,不得参与商业活动)
static internal class Calculate
{
static private int[] operand1;
static private int[] operand2;
static private IList<int> result;
/// <summary>
/// 加法
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
static internal StringBuilder Addition(StringBuilder a, StringBuilder b)
{
SetOperand(a, b);
try
{
Reverse();
int count = (operand1.Length > operand2.Length) ? operand1.Length : operand2.Length;
int op1, op2, upNum = 0;
for (int i = 0; i < count; i++)
{
op1 = (i >= operand1.Length) ? 0 : operand1[i];
op2 = (i >= operand2.Length) ? 0 : operand2[i];
int temp = op1 + op2 + upNum;
if (temp < 10)
{
result.Insert(0, temp);
upNum = 0;
}
else
{
result.Insert(0, temp % 10);
upNum = temp / 10;
}
if ((i == (count - 1)) && upNum > 0) result.Insert(0, upNum);
}
}
catch { result = new List<int>() { 0,0,0}; }
return GetResult();
}
/// <summary>
/// 减法
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
static internal StringBuilder Subtraction(StringBuilder a, StringBuilder b)
{
SetOperand(a, b);
try
{
Reverse();
bool desc = isDesc(a, b);
int[] opList1 = desc ? operand2 : operand1;
int[] opList2 = desc ? operand1 : operand2;
int count = (opList1.Length > opList2.Length) ? opList1.Length : opList2.Length;
int op1, op2, upNum = 0;
for (int i = 0; i < count; i++)
{
op1 = (i >= opList1.Length) ? 0 : opList1[i];
op2 = (i >= opList2.Length) ? 0 : opList2[i];
int temp = op1 - op2 - upNum;
if (temp >= 0)
{
result.Insert(0, temp);
upNum = 0;
}
else
{
result.Insert(0, temp + 10);
upNum = 1;
}
}
for (int i = 0; i < count; i++)
{
if (result[0] == 0)
result.RemoveAt(0);
else
break;
}
}
catch { SetOperand(a, b); }
return GetResult();
}
/// <summary>
/// 乘法
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
static internal StringBuilder Multiplication(StringBuilder a, StringBuilder b)
{
SetOperand(a, b);
StringBuilder strResult = new StringBuilder("0");
try
{
int[] opList1 = operand1;
int[] opList2 = operand2;
for (int i = 0; i < opList1.Length; i++)
{
for (int j = 0; j < opList2.Length; j++)
{
string temp = (opList1[i] * opList2[j]).ToString();
Console.Write(temp);
for (int t = 0; t < (opList1.Length - i - 1) + (opList2.Length - j - 1); t++)
{
temp = temp + "0";
}
strResult = Addition(strResult, new StringBuilder(temp));
}
}
}
catch { SetOperand(a, b); }
return strResult;
//return GetResult();
}
/// <summary>
/// 除法
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
static internal StringBuilder Division(StringBuilder a, StringBuilder b)
{
SetOperand(a, b);
StringBuilder strResult = new StringBuilder();
try
{
StringBuilder opStr1 = clearSB(a);
StringBuilder opStr2 = clearSB(b);
if (isDesc(a, b))
{
strResult.Append("0");
}
else
{
StringBuilder upNum = new StringBuilder("0");
for (int i = 0; i <= (opStr1.Length - opStr2.Length); i++)
{
StringBuilder temp = new StringBuilder();
if (i == 0) temp.Append(opStr1.ToString().Substring(i, b.Length));
else temp.Append(opStr1.ToString().Substring(i + b.Length - 1, 1));
temp = Addition(clearSB(Multiplication(upNum, new StringBuilder("10"))), clearSB(temp));
for (int j = 9; j >= 0; j--)
{
StringBuilder tempSB = Multiplication(opStr2, new StringBuilder(j.ToString()));
if (!isDesc(clearSB(temp), clearSB(tempSB)))
{
strResult.Append(j.ToString());
upNum = clearSB(Subtraction(temp, clearSB(tempSB)));
break;
}
}
}
}
}
catch { SetOperand(a, b); }
return clearSB(strResult);
//return GetResult();
}
/// <summary>
/// 清除StringBuilder前面的0
/// </summary>
/// <param name="operand"></param>
/// <returns></returns>
static private StringBuilder clearSB(StringBuilder operand)
{
int count = operand.Length;
for (int i = 0; i < count; i++)
{
if (operand[0] == '0')
operand.Remove(0,1);
else
break;
}
return operand;
}
/// <summary>
/// 是否后者比前者大
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
static private bool isDesc(StringBuilder a, StringBuilder b)
{
int[] opList1 = PutListByString(a.ToString());
int[] opList2 = PutListByString(b.ToString());
bool desc = false;
if (opList2.Length > opList1.Length) desc = true;
if (opList2.Length == opList1.Length)
{
for (int i = 0; i < opList1.Length; i++)
{
if (opList1[i] > opList2[i])
{
desc = false;
i = opList1.Length;
}
else if (opList2[i] > opList1[i])
{
desc = true;
i = opList1.Length;
}
}
}
return desc;
}
/// <summary>
/// 倒序 被操作数组
/// </summary>
static private void Reverse()
{
int[] Result1 = new int[operand1.Length];
for (int i = 0; i < operand1.Length; i++)
{
Result1[i] = operand1[operand1.Length - i - 1];
}
operand1 = Result1;
int[] Result2 = new int[operand2.Length];
for (int i = 0; i < operand2.Length; i++)
{
Result2[i] = operand2[operand2.Length - i - 1];
}
operand2 = Result2;
}
/// <summary>
/// 得到答案 string
/// </summary>
/// <returns>string</returns>
static private StringBuilder GetResult()
{
StringBuilder strResult = new StringBuilder();
for (int i = 0; i < result.Count; i++)
{
strResult.Append(result[i]);
}
return strResult;
}
/// <summary>
/// 初始化
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
static private void SetOperand(StringBuilder a, StringBuilder b)
{
operand1 = PutListByString(a.ToString());
operand2 = PutListByString(b.ToString());
result = new List<int>();
}
/// <summary>
/// 转化字符串为数组
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
static private int[] PutListByString(string str)
{
int[] res = new int[str.Length];
try
{
for (int i = 0; i < str.Length; i++)
res[i] = int.Parse(str.Substring(i, 1));
}
catch { res = new int[] { 0 }; }
return res;
}
}
更多精彩
赞助商链接