C#天文级别大数的运算

对于通常数值而言,我们只需要用int、long、float等即可存储,但对于无限长度的天文级别数据而言,就不能使用直接运算了。这时候需要转换下运算方式,即通过字符串的形式进行运算:

 #region 大数操作
    /// <summary>
    /// 大数比较
    /// </summary>
    /// <param name="_var1">参数1</param>
    /// <param name="_var2">参数2</param>
    /// <returns></returns>
    public static bool BigDateCompare(string _s1, string _s2)
    {
        if (_s1.Length > _s2.Length) return true;
        if (_s1.Length == _s2.Length)
        {
            char[] _char1 = _s1.ToCharArray();
            char[] _char2 = _s2.ToCharArray();
            for (int _i = _char1.Length - 1; _i >= 0; _i--)
            {
                var _num1 = int.Parse(_char1[_i].ToString());
                var _num2 = int.Parse(_char2[_i].ToString());

                if (_num1 > _num2) return true;
                else if (_num1 < _num2) return false;

                if (_i == 0 && _num1 == _num2) return true;
            }
        }
        return false;
    }

    /// <summary>
    /// 大数相加
    /// </summary> 
    public static string BigDataPlus(string _s1, string _s2)
    {
        //将数字转换成char类型的数组,然后每一位进行运算
        char[] _char1;
        char[] _char2;
        //计算前区分,令char1 为长的那个字符创转换成的数组.+
        if (_s1.Length > _s2.Length)
        {
            _char1 = _s1.ToCharArray();
            _char2 = _s2.ToCharArray();
        }
        else
        {
            _char1 = _s2.ToCharArray();
            _char2 = _s1.ToCharArray();
        }
        //flag 进位标识,末位相加进位的话前面一位需要加上进位
        int _flag = 0;
        //创建一个list接收两个数组相加的结果
        List<int> _resultList = new List<int>();
        //遍历相加
        for (int _i = _char1.Length - 1; _i >= 0; _i--)
        {
            //字母与数字之间的类型转换
            int a = int.Parse(_char1[_i].ToString());
            //初始化,数组char2 短一些
            int b = 0;
            //末尾
            var _fine = _i - (_char1.Length - _char2.Length);
            //计算,使得char1与char2 末位相加
            if (_fine >= 0)
            {
                b = int.Parse((_char2[_fine]).ToString());
            }
            //两个数字相加,同时加上进位,
            //注意:flag 的设置一定要放在相加后面,因为相加要使用当前的flag,如果提前设置,flag的作用就没有起到。
            var _theNum = a + b + _flag;
            _resultList.Add(_theNum % 10);
            _flag = _theNum / 10;
        }
        //最后进位处理
        if (_flag != 0)
        {
            _resultList.Add(_flag);
        }
        string _buffer = "";
        //逆向遍历,因为加的时候是从末位开始加的,首位的在后面。
        for (int i = _resultList.Count - 1; i >= 0; i--)
        {
            _buffer += _resultList[i];
        }
        //相加结果字符串返回。
        return _buffer;
    }

    /// <summary>
    /// 大数相减
    /// 该函数只支持_s1>_s2
    /// </summary> 
    public static string BigDataSUB(string _s1, string _s2)
    {
        //将数字转换成char类型的数组,然后每一位进行运算
        char[] _char1 = _s1.ToCharArray();
        char[] _char2 = _s2.ToCharArray();
        //flag 降位标识,末位相减借位的话前面一位需要加降位
        int _flag = 0;
        //创建一个list接收两个数组相减的结果
        List<int> _resultList = new List<int>();
        //遍历相减
        for (int _i = _char1.Length - 1; _i >= 0; _i--)
        {
            //字母与数字之间的类型转换
            int a = int.Parse(_char1[_i].ToString());
            //初始化,数组char2短一些
            int b = 0;
            //末尾
            var _fine = _i - (_char1.Length - _char2.Length);
            //计算,使得char1与char2 末位相加
            if (_fine >= 0)
            {
                b = int.Parse((_char2[_fine]).ToString());
            }
            //两个数字相减,同时减去借位,
            //注意:flag 的设置一定要放在相减后面,因为相加要使用当前的flag,如果提前设置,flag的作用就没有起到。
            var _theNum = a - _flag - b;
            if (_theNum > 0)
            {
                _resultList.Add(_theNum);
                _flag = 0;
            }
            else
            {
                _resultList.Add(10 + _theNum);
                _flag = 1;
            }
        }
        string _buffer = "";
        //逆向遍历,因为加的时候是从末位开始加的,首位的在后面。
        for (int i = _resultList.Count - 1; i >= 0; i--)
        {
            _buffer += _resultList[i];
        }
        //相加结果字符串返回。
        return _buffer;
    }

    /// <summary>
    /// 计算某位与一个数字相乘
    /// s1:某位的数字,s2:相乘的数字,offset:就是后面要补几个零
    /// </summary>
    private static string BigdateMulit(string _s1, string _s2, int _offset)
    {
        //s1与s2都必须是一位,否则直接返回空
        if (_s1.Length != 1 || _s2.Length != 1)
        {
            return null;
        }
        int _num = int.Parse(_s1) * int.Parse(_s2);
        string _buffer = _num.ToString();
        if (_offset >= 1)
        {
            for (int _i = 1; _i <= _offset; _i++)
            {
                _buffer += "0";
            }
        }
        return _buffer;
    }

    /// <summary>
    /// 一个数组与一个数字相乘
    /// </summary>
    private static string BigDateNumMulit(char[] _chars, string _s, int _offset)
    {
        if (_s.Length != 1)
        {
            return null;
        }
        string _result = "0";
        for (int i = _chars.Length - 1; i >= 0; i--)
        {
            string _temp = BigdateMulit(_chars[i].ToString(), _s, _chars.Length - i - 1);
            _result = BigDataPlus(_temp, _result);
        }
        string _buffer = _result;
        if (_offset >= 1)
        {
            for (int i = 1; i <= _offset; i++)
            {
                _buffer += "0";
            }
        }
        return _buffer;
    }

    /// <summary>
    /// 两个大数相乘
    /// </summary>
    public static string BigDatenumMulitfy(string _s1, string _s2)
    {
        char[] _chars1 = _s1.ToCharArray();
        char[] _chars2 = _s2.ToCharArray();
        string _result = "0";
        for (int i = _chars1.Length - 1; i >= 0; i--)
        {
            string _temp = BigDateNumMulit(_chars2, _chars1[i].ToString(), _chars1.Length - i - 1);
            _result = BigDataPlus(_result, _temp);
        }
        return _result.ToString();
    }

    /// <summary>
    /// 大数与float相乘,得出一个大数
    /// </summary>
    public static string BigDatenumMulitfy(string _s1, float _f2)
    {
        string _str = _f2.ToStrin
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值