相册地址:
http://hi.baidu.com/delaprelson/album/%B4%F3%CA%FD%BC%C6%CB%E3
乘除的两个重载先不拿出来SHOW人了
所谓大数,就是超出数据类型的数值,C#能存储的最大数据类型是decimal,如果一个数的大小超出它的
存储范围,就会溢出。
解决方法是用一个长度足够大的数组,按数组的每一个元素存储4个位长的数,这样就能用数组来表示已
个足够大的数。
如521412468811643779611167425,在C#中任何一种数据类型都无法存储,如果用数组,按每4位为一个数
组元素,就可以存储起来。但是在运行效率方面有点慢——毕竟用到了数组,内存开销肯定是大了一点的
。
用数组表示例如 short b[] = new short[100];
b[0]=7425;b[1]=1116;b[2]=7796;b[3]=1643;b[4]=6881;b[5]=4124;
//最后一个,按照任何数 假设把这个数设为x,那么有x%4<4,就是说,最后一个数的长度要么等于4,要么
就小于4且大于0,所以:
b[6]=521;
然后在最后一位设置校检位,用来表明该数是一个正数,或者是负数,假设,正数为-1,负数为-2
就有:
521412468811643779611167425,
b[7]=-1;
如果-521412468811643779611167425,
b[7]=-2;
如果有小数部分还要另外设置
用途: 可以用来实现RSA加密算法,当然了 用C#作算法,要考虑速度,本人只是偏爱C#编程
在这里用一个枚举来表示
/// <summary>
/// 校检正负数,并作为结束符
/// </summary>
internal enum NumberCheck : short {
/// <summary>
/// 如果是正数,在数组的最后一个元素加入该枚举值(-1表示)
/// </summary>
Positive = -1,
/// <summary>
/// 如果是负数,在数组的最后一个元素加入该枚举值(-2表示)
/// </summary>
Negative = -2,
/// <summary>
/// 小数点标记位,在数组的第一个元素加入该枚举值(-3表示)
/// </summary>
FloatingPointFlag = -3,
/// <summary>
/// 小数点标记位,意味着没有小数部分,或者截除小数部分,
/// 在数组的第一个元素加入该枚举值(-4表示)
/// </summary>
NonFloatingPointFlag = -4
};
}
如果用一个类或者结构将这样的“类型”封装起来,并实现运算符重载,就能对该类型实现+-/×等运算
;如果实现转换运算符,还可以同系统自带的数据类型一起进行运算,某种意义上,也成为了一种用于运
算的数据类型。
下面是源代码,将上述的类型封装成结构,名为BigNumber ,只提供+-,×/就不提供了
using System.Text;
using System.Runtime.InteropServices;
using System.Threading;
using System.IO;
using System.Diagnostics;
using System.EnterpriseServices;
/*
* written by Feng
* since 27-may-09 13:13:18
*/
namespace FengCreateCLRDll {
namespace BigNumberCount {
//入口
//1.用一个纯数字的string
//2.同上 char[]
//3一个short数组,格式 如:1,000,000,1 ->short [] a : a[0]=1,进四位,a[1]=1000
// a[2]=校检位:正数,负数,(正浮点数,负浮点数:在小数点的位置校检)
//计算精确位
//对于整数部分,不必限制位
//对于小数部分,精确到小数点后的多少位:无理数计算,如:11÷7
//7亿9千万 <= cout <8亿 个list元素的个数 说明至少有4*7亿9千万的数位(即 31.4亿个长
度)可以被储存在BigNumber结构中
//运算符重载
//转换 二 八 十六 进制 用short数组表示 ,转换成易读性的string
//运用
//RAS算法
//整数部分,校检位在最后一个元素中
//小数部分,校检位在第一个元素
/// <summary>
/// 用来表示“大数”的数据类型,这样的“大数”一般是超出内置数据类型的数字,可通过运
算符重载
/// 进行运算.(未完)
/// </summary>
[SerializableAttribute]
[ComVisibleAttribute(true)]
[Guid("c3454a74-9742-4408-89aa-7395e32855e6")]
public struct BigNumber {
//关于线程同步,由于这是一个结构,在运算符重载的操作数--参数,都是外部实参的副本
//,也就是值拷贝,而不是引用拷贝,因此在多线程里使用同一个对象,除非作为参数实参
的对象
//在外面的线程被修改,并且只有在调用重载之前修改,才有可能引起参数上的改变,从而
引起
//对象不同步,如果是在调用重载之后,才修改该值的,不会影响。
//字段
/// <summary>
/// 整数部分
/// </summary>
List<short> IntegerPart;//包含最后一个校检位
/// <summary>
/// 小数部分
/// </summary>
List<short> FractionPart;//第一位除以1*10^(4*1),第二个除以10^(4*2)
/// <summary>
/// 获取整数部分的值,用数组表示
/// </summary>
public short[] INTERGETpart {
get {
return this.IntegerPart.ToArray();
}
}
/// <summary>
/// 获取小数部分的值,用数组表示
/// </summary>
public short[] FRACTIONpart {
get {
return this.FractionPart.ToArray();
}
}
/// <summary>
/// 获取一个数的长度
/// </summary>
internal static short Length(short specValue) {
short count = 1;
short t = specValue;
while((t /= 10) > 0)
count++;
return count;
}
static BigNumber zero = new BigNumber("0");
/// <summary>
/// 返回一个零值的BigNumber对象
/// </summary>
public static BigNumber Zero {
get {
return zero;
}
}
/// <summary>
/// 将BigNumber结构储存的值转化为易于理解的十进制数,用string表示
/// </summary>
internal string ReadableBigNumber {
get {
string rv = "";
short[] ip = this.INTERGETpart;
short[] fp = this.FRACTIONpart;
#region 整数
int l = ip.Length;
if(ip[l - 1] == (short)NumberCheck.Negative) //获取标记位
rv += "-";
else
rv += "+";
rv += ip[l - 2].ToString();//最高位的值
if(ip.Length > 2) {
short regL = 0;
for(int maxi = l - 3; maxi >= 0; maxi--) {
//从第二个元素开始,如果只有3位,2位,1位,->在前面填充4-n个零
regL = Length(ip[maxi]);
switch(regL) {
case 1:
rv += "000" + ip[maxi].ToString();
break;
case 2:
rv += "00" + ip[maxi].ToString();
break;
case 3:
rv += "0" + ip[maxi].ToString();
break;
case 4:
rv += ip[maxi].ToString();
break;
}
}
}
#endregion 整数
#region 小数
if(fp[fp.Length - 1] == (short)NumberCheck.NonFloatingPointFlag)
return rv;
int fl = fp.Length;
rv += ".";
short fregL = 0;
for(int mini = 1; mini <= fl - 1; mini++) {
fregL = Length(fp[mini]);
switch(fregL) {
case 1:
rv += "000" + fp[mini].ToString();
break;
case 2:
rv += "00" + fp[mini].ToString();
break;
case 3:
rv += "0" + fp[mini].ToString();
break;
case 4:
rv += fp[mini].ToString();
break;
}
}
#endregion 小数
return rv;
}
}
//静态字段
int ReserveLength;
//静态属性
/// <summary>
/// 设置或者获取在计算后得到小数点后保留的位数,默认保留20位小数,前提是进行无理
数运算的情况下,采取的折衷措施,否则函数不会返回,将一直运算下去
/// </summary>
public int FloatingPointReserveLength {
get {
return ReserveLength;
}
set {
ReserveLength = value;
}
}
/* internal BigNumber() {
this.IntegerPart = new List<short>();
this.FractionPart = new List<short>();
this.ReserveLength = 10;
this.IntegerPart.Add(0);
this.IntegerPart.Add((short)NumberCheck.Positive);
this.FractionPart.Add((short)NumberCheck.NonFloatingPointFlag);
}
*/
/// <summary>
/// 用一个字符串表示某个超出数据类型范围的数值,存入一个数组中,通过数组间的元素
进行运算
/// </summary>
/// <param name="bignumber">格
式:"+4521412468811643779611167425.12454254643"</param>
/// <remarks>正负标记:+或- 必须放在字符串的起始处,也可不用正负标记,
如"45214124688"为正数</remarks>
public BigNumber(string bignumber) {
object lobj = new object();
lock(lobj) {
this.ReserveLength = 20;
// bignumber = BigNumber.OffInvalidZero(bignumber);
byte[] b = ASCIIEncoding.ASCII.GetBytes(bignumber);
//+ :43 ,- :45 ,0 :48 , .:46,9:57
//检索第一个字符 + - 0
int startLocation = 0;//数字串的起始位
bool folatingPoint = false;//检索小数点是否存在,默认不存在
int folatingPointLocation = 0;
bool flag = false;// + - 标记 默认为没有+ - 标记 bignumber的第一个元素0
if(bignumber == "-0" || bignumber == "+0" || bignumber == "0")
goto _forbidden_zone;
if(bignumber.Length == 1)
if(b[0] < 48 || b[0] > 57)
throw new ArgumentException("参数 bignumber 格式不正确");
else
goto _forbidden_zone;
if(
b[0] != 43 && b[0] != 45 &&
(b[0] < 48 || b[0] > 57)
)
throw new ArgumentException("参数 bignumber 格式不正确");
if(b[0] != 43 && b[0] != 45)
flag = false;
else
flag = true;
if(flag && b[1] == 48 && b[2] != 46)
throw new ArgumentException("参数 bignumber 格式不正确");
if(!flag && b[0] == 48 && b[1] != 46)
throw new ArgumentException("参数 bignumber 格式不正确");
//+- 0.开头
if(flag)
startLocation = 1;
if(flag && b[1] == 48)
startLocation = 3;
if(!flag && b[0] == 48)
startLocation = 2;
//非0开头的串,查找'.'是否存在以及位置
for(int i = 0; i < b.Length; i++)
if(b[i] == 46) {
folatingPoint = true;
folatingPointLocation = i;
break;//第一个并记录到变量
}
if(b[b.Length - 1] == 46)
throw new ArgumentException("参数 bignumber 格式不正确");
//从startLocation开始判断非0-9的值
if(folatingPoint)
for(int i = startLocation; i < b.Length; i++)
if(bignumber[i] > 57 || bignumber[i] < 48) {
if(i == folatingPointLocation)
continue;
throw new ArgumentException("参数 bignumber 格式不正确");
}
_forbidden_zone:
//每4个子串为一个storeBigNum元素,从字符串的高位,按每4位,填充到
storeBigNum的元素中
//值低位数放到storeBigNum低位元素中,按左开始,NumberCheck放在最后,便于计
算
//1234 5678 a[0]5678 a[1]1234
//从右到左
//某些位可能不足4位,例如原数:10040006->6,1004 :6->0006,如果10040006-
50006,后面相同的抵消,1004-5
//100040006-5-70006,后面抵消,0006 0004 1 : 4-7->14-7=7,向高位借1-
>9997,0000
this.IntegerPart = new List<short>();
this.FractionPart = new List<short>();
string decimal_fraction = "";//小数部分的值
string whole_number = "";//整数部分的值
if(folatingPoint)
decimal_fraction = bignumber.Substring(
folatingPointLocation + 1,
bignumber.Length - folatingPointLocation - 1);
else
decimal_fraction = "";
if(flag) {
if(folatingPoint)
whole_number = bignumber.Substring(
1, folatingPointLocation - 1);
else
whole_number = bignumber.Substring(
1, bignumber.Length - 1);
} else
if(!flag) {
if(folatingPoint)
whole_number = bignumber.Substring(
0, folatingPointLocation);
else
whole_number = bignumber;
}
//Console.WriteLine(whole_number);
#region 小数部分
//按最高位(0.1 十分位)对齐,当计算时,不足的位补0对齐
//小数的十分位在数组里的表现是四位数,如0.1在数组里是1000
if(folatingPoint) {
this.FractionPart.Add((short)NumberCheck.FloatingPointFlag);//小数点
符号位
int lastvalue = decimal_fraction.Length % 4;
//填充0,使每个数组元素都够4位数
switch(lastvalue) {
case 1:
decimal_fraction += "000"; break;
case 2: decimal_fraction += "00"; break;
case 3: decimal_fraction += "0"; break;
}
int count = decimal_fraction.Length / 4;
int start = 0;
string substr = "";
for(int i = 0; i < count; i++) {
substr = decimal_fraction.Substring(start, 4);
this.FractionPart.Add(
Convert.ToInt16(substr));
start += 4;
}
} else
this.FractionPart.Add((short)NumberCheck.NonFloatingPointFlag);
#endregion 小数部分
# region 整数部分
//按最低位(个位)对齐
if(whole_number.Length <= 4)
this.IntegerPart.Add(
Convert.ToInt16(whole_number)
);
if(whole_number.Length > 4) {
int count = whole_number.Length / 4;//循环的次数
int lastvalue = whole_number.Length % 4;//最后一次的字符个数
int start = whole_number.Length - 4;
string substr = "";
for(int i = 0; i < count; i++) {
substr = whole_number.Substring(start, 4);//串的最右边的子串,作
为storeBigNum的地位元素值
this.IntegerPart.Add(
Convert.ToInt16(substr)
);
start -= 4;
}
if(lastvalue != 0)
this.IntegerPart.Add(
Convert.ToInt16(whole_number.Substring(0, lastvalue)));
}
#endregion 整数部分
#region 正负校检位
if(flag && b[0] == 45)
this.IntegerPart.Add((short)NumberCheck.Negative);
else
this.IntegerPart.Add((short)NumberCheck.Positive);
#endregion 正负校检位
}
}
internal BigNumber(short[] integetpart, short[] fractionpart) {
object lobj = new object();
lock(lobj) {
this.IntegerPart = new List<short>(integetpart);
this.FractionPart = new List<short>(fractionpart);
this.ReserveLength = 20;
}
}
/// <summary>
/// 通过一个int类型的对象实例化一个BigNumber对象
/// </summary>
/// <param name="bignumber">一个int类型的对象</param>
/// <returns>返回一个BigNumber对象</returns>
public static BigNumber Instance(int bignumber) {
return new BigNumber(bignumber.ToString());
}
/// <summary>
/// 通过一个long类型的对象实例化一个BigNumber对象
/// </summary>
/// <param name="bignumber">一个long类型的对象</param>
/// <returns>返回一个BigNumber对象</returns>
public static BigNumber Instance(long bignumber) {
return new BigNumber(bignumber.ToString());
}
/// <summary>
/// 通过一个double类型的对象实例化一个BigNumber对象
/// </summary>
/// <param name="bignumber">一个double类型的对象</param>
/// <returns>返回一个BigNumber对象</returns>
public static BigNumber Instance(double bignumber) {
return new BigNumber(bignumber.ToString());
}
/// <summary>
/// 通过一个decimal类型的对象实例化一个BigNumber对象
/// </summary>
/// <param name="bignumber">一个decimal类型的对象</param>
/// <returns>返回一个BigNumber对象</returns>
public static BigNumber Instance(decimal bignumber) {
return new BigNumber(bignumber.ToString());
}
#region 摘要
//乘是连续相加的和
//除是连续相减的差
#endregion
public static BigNumber operator +(BigNumber leftValue, BigNumber rightValue) {
List<short> _fraction = new List<short>();//小数 ->从最后的元素累计相加 然后
反转该数组
List<short> _integer = new List<short>();//整数
short _c = 0;//进位的值
object lobj = new object();
lock(lobj) {
# region 正正 负负
if(
leftValue.INTERGETpart[leftValue.INTERGETpart.Length - 1] ==
rightValue.INTERGETpart[rightValue.INTERGETpart.Length - 1]) {
#region 小数部分
//同位部分相加,余出部分填充
//是否有小数部分
int _l = leftValue.FRACTIONpart.Length; //设置操作数小数部分的数组长
度
if(leftValue.FRACTIONpart[0] != (short)
NumberCheck.NonFloatingPointFlag
|| rightValue.FRACTIONpart[0] != (short)
NumberCheck.NonFloatingPointFlag) {
if(leftValue.FRACTIONpart.Length >
rightValue.FRACTIONpart.Length) {
for(int i = leftValue.FRACTIONpart.Length - 1; i >
rightValue.FRACTIONpart.Length - 1; i--)
_fraction.Add(leftValue.FRACTIONpart[i]);
_l = rightValue.FRACTIONpart.Length;
} else if(leftValue.FRACTIONpart.Length <
rightValue.FRACTIONpart.Length) {
for(int i = rightValue.FRACTIONpart.Length - 1; i >
leftValue.FRACTIONpart.Length - 1; i--) {
_fraction.Add(rightValue.FRACTIONpart[i]);
}
_l = leftValue.FRACTIONpart.Length;//获取较短的数组长度
}//a._l==1 b._l左右操作数的长度相等
//从最后的操作数相加
int _t = 0;
//ARRAY[0]为校检位,不必相加
for(int i = _l - 1; i >= 1; i--) {
_t = leftValue.FRACTIONpart[i] + rightValue.FRACTIONpart[i]
+ _c;
if(_t >= 10000) {
_fraction.Add((short)(_t % 10000));
_c = (short)(_t / 10000);
} else {
_fraction.Add((short)_t);
_c = 0;
}
}
_fraction.Add((short)NumberCheck.FloatingPointFlag);
//需反转
/*
List<short> tflist = new List<short>(_fraction);
int _midvalue = 0;
for(int i = 0; i < _fraction.Count; i++) {
_fraction[i]=tflist[tflist.count
}
*/
_fraction.Reverse();
} else
_fraction.Add((short)NumberCheck.NonFloatingPointFlag);
#endregion 小数部分
#region 整数部分
int _it = 0;
int _ic = 0;
if(leftValue.INTERGETpart.Length >= rightValue.INTERGETpart.Length)
_ic = rightValue.INTERGETpart.Length - 1;//校检位
else
if(leftValue.INTERGETpart.Length <
rightValue.INTERGETpart.Length)
_ic = leftValue.INTERGETpart.Length - 1;
// Console.WriteLine(rightValue.INTERGETpart
[rightValue.INTERGETpart.Length-1]);
for(int i = 0; i < _ic; i++) {
_it = leftValue.INTERGETpart[i] + rightValue.INTERGETpart[i] +
_c;
if(_it >= 10000) {
_integer.Add(
Convert.ToInt16(
_it % 10000)
);
_c = (short)(_it / 10000);
} else {
_integer.Add(
Convert.ToInt16(
_it));
_c = 0;
}
}
if(leftValue.INTERGETpart.Length > rightValue.INTERGETpart.Length)
for(int i = _ic; i < leftValue.INTERGETpart.Length - 1; i++) {
_it = leftValue.INTERGETpart[i] + _c;
if(_it >= 10000) {
_integer.Add((short)(_it % 10000));
_c = (short)(_it / 10000);
} else {
_integer.Add((short)_it);
_c = 0;
}
} else
if(leftValue.INTERGETpart.Length <
rightValue.INTERGETpart.Length)
for(int i = _ic; i < rightValue.INTERGETpart.Length - 1;
i++) {
_it = rightValue.INTERGETpart[i] + _c;
if(_it >= 10000) {
_integer.Add((short)(_it % 10000));
_c = (short)(_it / 1000);
} else {
_integer.Add((short)_it);
_c = 0;
}
}
if(leftValue.INTERGETpart[leftValue.INTERGETpart.Length - 1] ==
(short)NumberCheck.Positive)
_integer.Add((short)NumberCheck.Positive);
else
_integer.Add((short)NumberCheck.Negative);
return new BigNumber(_integer.ToArray(), _fraction.ToArray());
}
# endregion 整数部分
#endregion 正正 负负
#region 正负
BigNumber _ll = new BigNumber(leftValue.INTERGETpart,
leftValue.FRACTIONpart);
BigNumber _rr = new BigNumber(rightValue.INTERGETpart,
rightValue.FRACTIONpart);
_ll.IntegerPart[_ll.IntegerPart.Count - 1] = (short)
NumberCheck.Positive;
_rr.IntegerPart[_rr.IntegerPart.Count - 1] = (short)
NumberCheck.Positive;
BigNumber _rt = _ll - _rr;
if(_ll > _rr)
_rt.IntegerPart[_rt.IntegerPart.Count - 1] = leftValue.IntegerPart
[leftValue.IntegerPart.Count - 1];
else
if(_ll < _rr)
_rt.IntegerPart[_rt.IntegerPart.Count - 1] =
rightValue.IntegerPart
[rightValue.IntegerPart.Count - 1];
return _rt;
#endregion 正负
}
}
//operator-最终都是大数减去小数
public static BigNumber operator -(BigNumber leftValue, BigNumber rightValue) {
if(BigNumber.OffInvalidZero(leftValue) == BigNumber.OffInvalidZero
(rightValue))
return new BigNumber("0");
BigNumber _rt = BigNumber.zero;
BigNumber _l = new BigNumber(leftValue.INTERGETpart,
leftValue.FRACTIONpart);
BigNumber _r = new BigNumber(rightValue.INTERGETpart,
rightValue.FRACTIONpart)
;
// - -
if(leftValue.IntegerPart[leftValue.IntegerPart.Count - 1] == (short)
NumberCheck.Negative
&& rightValue.IntegerPart[rightValue.IntegerPart.Count - 1] == (short)
NumberCheck.Negative) {
_l.IntegerPart[_l.IntegerPart.Count - 1] = _r.IntegerPart
[_r.IntegerPart.Count - 1] = (short)NumberCheck.Positive;
_rt = subtract(_l, _r);
_rt.IntegerPart[_rt.IntegerPart.Count - 1] = (short)
NumberCheck.Negative;
return _rt;
}
// + +
if(leftValue.IntegerPart[leftValue.IntegerPart.Count - 1] == (short)
NumberCheck.Positive
&& rightValue.IntegerPart[rightValue.IntegerPart.Count - 1] == (short)
NumberCheck.Positive) {
_rt = subtract(_l, _r);
if(leftValue > rightValue)
_rt.IntegerPart[_rt.IntegerPart.Count - 1] = (short)
NumberCheck.Positive;
else
if(leftValue < rightValue)
_rt.IntegerPart[_rt.IntegerPart.Count - 1] = (short)
NumberCheck.Negative;
return _rt;
}
// +-
if(leftValue.IntegerPart[leftValue.IntegerPart.Count - 1] == (short)
NumberCheck.Positive
&& rightValue.IntegerPart[rightValue.IntegerPart.Count - 1] == (short)
NumberCheck.Negative) {
_l.IntegerPart[_l.IntegerPart.Count - 1] = (short)NumberCheck.Positive;
_r.IntegerPart[_r.IntegerPart.Count - 1] = (short)NumberCheck.Positive;
_rt = _l + _r;
return _rt;
}
// - +
if(leftValue.IntegerPart[leftValue.IntegerPart.Count - 1] == (short)
NumberCheck.Negative
&& rightValue.IntegerPart[rightValue.IntegerPart.Count - 1] == (short)
NumberCheck.Positive) {
_l.IntegerPart[_l.IntegerPart.Count - 1] = (short)NumberCheck.Positive;
_r.IntegerPart[_r.IntegerPart.Count - 1] = (short)NumberCheck.Positive;
_rt = _l + _r;
_rt.IntegerPart[_rt.IntegerPart.Count - 1] = (short)
NumberCheck.Negative;
}
return _rt;
}
//减
internal static BigNumber subtract(BigNumber theGreatNum, BigNumber theLessNum)
{
//防止被修改值
//校检两个数的大小
BigNumber temp = theLessNum;
if(theGreatNum < theLessNum) {
temp = theGreatNum;
theGreatNum = theLessNum;
theLessNum = temp;
}
List<short> _integer = new List<short>();//整数
List<short> _fraction = new List<short>();//小数
//从大数的高位借的值---小数部分的
// short _loan = 0;
int _f_location = theLessNum.FractionPart.Count - 1;//小数部分被借出的数的索
引的起始位置
int _loanStartl = -1;
short _NextLoan = 0;//向下一个数借1
#region 小数部分
//采用 FractionPart可修改参数值
if(theGreatNum.FractionPart[0] == (short)NumberCheck.FloatingPointFlag
|| theGreatNum.FractionPart[0] == (short)NumberCheck.FloatingPointFlag
) {
if(theGreatNum.FractionPart[0] == (short)
NumberCheck.NonFloatingPointFlag)
theGreatNum.FractionPart[0] = (short)NumberCheck.FloatingPointFlag;
//计算小数部分多出来的位
int _frc = Math.Abs(theGreatNum.FractionPart.Count -
theLessNum.FractionPart.Count);
//如果小于则添加10000(最后)9999。。。。。
//如果大于则用原来的大数的小数部分填充到_fraction 需反转
if(theGreatNum.FractionPart.Count < theLessNum.FractionPart.Count) {
_loanStartl = theGreatNum.FractionPart.Count - 1;//从这个位置减去1 <
标记>
while(_frc-- >= 2) {
theGreatNum.FractionPart.Add(9999);
// Console.WriteLine("ppp");
}
theGreatNum.FractionPart.Add(10000);
// _loan = 1;//借的数 需被减
} else
if(theGreatNum.FractionPart.Count > theLessNum.FractionPart.Count) {
int _l = theGreatNum.FractionPart.Count - 1;
while(_frc-- >= 1) {
_fraction.Add(theGreatNum.FractionPart[_l--]);//填充
}
}
//-------------------------------------------------------计算部分
//到索引[1]时停止,因为[0]是校检位
while(_f_location >= 1) {
if(_f_location == _loanStartl)
theGreatNum.FractionPart[_f_location] -= 1;
theGreatNum.FractionPart[_f_location] -= _NextLoan;
if(theGreatNum.FractionPart[_f_location]
< theLessNum.FractionPart[_f_location]
) {
theGreatNum.FractionPart[_f_location] += 10000;
_NextLoan = 1;
}
_fraction.Add(
Convert.ToInt16(
theGreatNum.FractionPart[_f_location] - theLessNum.FractionPart
[_f_location]
));
--_f_location;
}
_fraction.Add((short)NumberCheck.FloatingPointFlag);
_fraction.Reverse();//反转
} else
_fraction.Add((short)NumberCheck.NonFloatingPointFlag);
#endregion 小数部分
#region 整数部分
//从个位开始对齐
//大的数的整数长度不是跟小的数的整数长度相等就是比它大
//按小的数的整数的长度为基准
int _il = theLessNum.IntegerPart.Count - 1;//小的数的校检位
for(int i = 0; i < _il; i++) {
theLessNum.IntegerPart[i] += _NextLoan;
_NextLoan = 0;
if(theGreatNum.IntegerPart[i] < theLessNum.IntegerPart[i]) {
theGreatNum.IntegerPart[i] += 10000;
_NextLoan = 1;
}
_integer.Add(
Convert.ToInt16(
theGreatNum.IntegerPart[i] - theLessNum.IntegerPart[i]
)
);
}
int _superfluous = theGreatNum.IntegerPart.Count -
theLessNum.IntegerPart.Count;
int _LastLoan = _NextLoan;
if(_superfluous > 0) {
for(int i = theLessNum.IntegerPart.Count - 1; i <
theGreatNum.IntegerPart.Count - 1; i++) {
if(theGreatNum.IntegerPart[i] < _LastLoan) {
theGreatNum.IntegerPart[i] += 10000;
_NextLoan = 1;
} else
_NextLoan = 0;
_integer.Add(
Convert.ToInt16(
theGreatNum.IntegerPart[i] - _LastLoan)
);
_LastLoan = _NextLoan;
}
}
int index = _integer.Count - 1;
while(index > 0) {
if(_integer[index] != 0)
break;
else
if(_integer[index] == 0) {
_integer.RemoveAt(index);
index = _integer.Count - 1;
}
}
_integer.Add(-5);//未标记
/* for(int i = 1; i < _integer.Count - 1; i++) {
if(_integer[i] != 0)
break;
else
if(_integer[i] == 0)
_integer.RemoveAt(i);
}*/
#endregion 整数部分
return new BigNumber(_integer.ToArray(), _fraction.ToArray());
}
// < >如果碰到相等的 都返回false
public static bool operator >(BigNumber leftValue, BigNumber rightValue) {
#region 原有算法
/* leftValue = new BigNumber(BigNumber.OffInvalidZero(leftValue));
rightValue = new BigNumber(BigNumber.OffInvalidZero(rightValue));
// "123456.00000000">"123456"------???????????????????
short leftIntLastV = leftValue.INTERGETpart[leftValue.INTERGETpart.Length - 1];
short rightIntLastV = rightValue.INTERGETpart[rightValue.INTERGETpart.Length -
1];
//比较校检位,正负数比较
if(leftIntLastV > rightIntLastV)
return true;
else
if(leftIntLastV < rightIntLastV)
return false;
//同时是整数或负数
if(leftIntLastV == rightIntLastV) {
//都是正数
if(leftIntLastV == (short)NumberCheck.Positive) {
if(leftValue.INTERGETpart.Length > rightValue.INTERGETpart.Length)
return true;
else
if(leftValue.INTERGETpart.Length < rightValue.INTERGETpart.Length)
return false;
}
//都是负数
if(leftIntLastV == (short)NumberCheck.Negative) {
if(leftValue.INTERGETpart.Length > rightValue.INTERGETpart.Length)
return false;
else
if(leftValue.INTERGETpart.Length <
rightValue.INTERGETpart.Length)
return true;
}
int r = string.Compare(leftValue.ReadableBigNumber,
rightValue.ReadableBigNumber);
//正数
if(leftIntLastV == (short)NumberCheck.Positive) {
switch(r) {
case 1:
return true;
default:
return false;
}
}else
if(leftIntLastV == (short)NumberCheck.Negative) {
switch(r) {
case -1:
return true;
default:
return false;
}
}
}
return false;
*/
#endregion 原有算法
if(leftValue == rightValue)
return false;
return !(leftValue < rightValue);
}
public static bool operator <(BigNumber _leftValue, BigNumber _rightValue) {
BigNumber leftValue = new BigNumber(BigNumber.OffInvalidZero(_leftValue));
BigNumber rightValue = new BigNumber(BigNumber.OffInvalidZero(_rightValue));
short leftIntLastV = leftValue.INTERGETpart[leftValue.INTERGETpart.Length -
1];
short rightIntLastV = rightValue.INTERGETpart[rightValue.INTERGETpart.Length
- 1];
//比较校检位,正负数比较
if(leftIntLastV > rightIntLastV)
return false;
else
if(leftIntLastV < rightIntLastV)
return true;
//同时是整数或负数
if(leftIntLastV == rightIntLastV) {
//都是正数
if(leftIntLastV == (short)NumberCheck.Positive) {
if(leftValue.INTERGETpart.Length > rightValue.INTERGETpart.Length)
return false;
//else
if(leftValue.INTERGETpart.Length < rightValue.INTERGETpart.Length)
return true;
//整数部分比较
//条件是整数部分的数组长度相等
//leftValue.INTERGETpart.Length - 2最大的4位,0终止
for(int i = leftValue.INTERGETpart.Length - 2; i >= 0; i--) {
if(leftValue.INTERGETpart[i] < rightValue.INTERGETpart[i])
return true;
else
if(leftValue.INTERGETpart[i] > rightValue.INTERGETpart[i])
return false;
}
//小数部分比较 依据整数部分,如果整数部分都是相等的时候,比较小数部
分
}
//都是负数
if(leftIntLastV == (short)NumberCheck.Negative) {
if(leftValue.INTERGETpart.Length > rightValue.INTERGETpart.Length)
return true;
// else
if(leftValue.INTERGETpart.Length < rightValue.INTERGETpart.Length)
return false;
//跟正数相反的条件
for(int i = leftValue.INTERGETpart.Length - 2; i >= 0; i--) {
if(leftValue.INTERGETpart[i] < rightValue.INTERGETpart[i])
return false;
else
if(leftValue.INTERGETpart[i] > rightValue.INTERGETpart[i])
return true;
}
}
//问题所在
int r = string.Compare(leftValue.ReadableBigNumber,
rightValue.ReadableBigNumber);
//正数
if(leftIntLastV == (short)NumberCheck.Positive) {
switch(r) {
case -1:
return true;
default:
return false;
}
} else
if(leftIntLastV == (short)NumberCheck.Negative) {
switch(r) {
case 1:
return true;
default:
return false;
}
}
}
return false;
}
public static bool operator <=(BigNumber leftValue, BigNumber rightValue) {
bool ok = false;
if(leftValue == rightValue)
ok = true;
else
if(leftValue < rightValue)
ok = true;
return ok;
}
public static bool operator >=(BigNumber leftValue, BigNumber rightValue) {
bool ok = false;
if(leftValue == rightValue)
ok = true;
else
if(leftValue > rightValue)
ok = true;
return ok;
}
public static bool operator ==(BigNumber leftValue, BigNumber rightValue) {
leftValue = new BigNumber(BigNumber.OffInvalidZero(leftValue));
rightValue = new BigNumber(BigNumber.OffInvalidZero(rightValue));
if(leftValue.INTERGETpart[leftValue.INTERGETpart.Length - 1] !=
rightValue.INTERGETpart[rightValue.INTERGETpart.Length - 1])
return false;
int r = string.Compare(leftValue.ReadableBigNumber,
rightValue.ReadableBigNumber);
if(r == 0)
return true;
return false;
}
public static bool operator !=(BigNumber leftValue, BigNumber rightValue) {
leftValue = new BigNumber(BigNumber.OffInvalidZero(leftValue));
rightValue = new BigNumber(BigNumber.OffInvalidZero(rightValue));
if(leftValue.INTERGETpart[leftValue.INTERGETpart.Length - 1] !=
rightValue.INTERGETpart[rightValue.INTERGETpart.Length - 1])
return true;
int r = string.Compare(leftValue.ReadableBigNumber,
rightValue.ReadableBigNumber);
if(r != 0)
return true;
return false;
}
#region ICloneable 成员
/// <summary>
/// 克隆BigNumber对象
/// </summary>
/// <returns>返回当前实例的深层副本</returns>
public object Clone() {
return new BigNumber(
this.ReadableBigNumber);
}
#endregion
//转化运算符
/// <summary>
/// 将int类型隐式转换成BigNumber类型,这样一个BigNumber对象能直接与一个int对象进
行运算.
/// 如BigNumber a =new BigNumber("88");int b=56;BigNumber c= a%b;
/// 这说明,隐式转化好过显式转化,直接一点
/// </summary>
public static implicit operator BigNumber(int convertValue) {
return new BigNumber(convertValue.ToString());
}
//转化运算符
/// <summary>
/// 将long类型隐式转换成BigNumber类型
/// </summary>
public static implicit operator BigNumber(long convertValue) {
return new BigNumber
(convertValue.ToString());
}
//转化运算符
/// <summary>
/// 将double类型隐式转换成BigNumber类型
/// </summary>
public static implicit operator BigNumber(double convertValue) {
return new BigNumber(convertValue.ToString());
}
//转化运算符
/// <summary>
/// 将decimal类型隐式转换成BigNumber类型
/// </summary>
public static implicit operator BigNumber(decimal convertValue) {
return new BigNumber(convertValue.ToString());
}
};//BigNumber
}