如何在 C# 中在没有 bigint 的情况下添加或减去非常大的数字

本文关键字:非常 数字 添加 情况下 bigint | 更新日期: 2023-09-27 18:32:24

所以让我首先说我是一个新手,对 C# 知之甚少。

进入主题:我需要制作一个能够加/减非常大的整数的程序。最初,使用 BigInt 只是为了发现它是不允许的。应该有一个合乎逻辑的解决方法吗?我有一个想法,即使用"小学方法",从右到左添加每个数字。

做了一个字符串,我把它分成字符数组,并从右到左添加每个数字(GetUpperBound-i)。但它似乎不起作用。

我的代码:

string s, s2;
char[] c_arr, c_arr2;
int i, erg;
s = "1234";
s2 = "5678";
c_arr = s.ToCharArray();
c_arr2 = s2.ToCharArray();
for (i = 0; i <= c_arr.GetUpperBound(0); i++)
{
    erg = c_arr[c_arr.GetUpperBound(0)-i]+c_arr2[c_arr2.GetUpperBound(0)-i];
    Console.Write(erg);
}
Console.ReadKey();

如何在 C# 中在没有 bigint 的情况下添加或减去非常大的数字

您的"小学方法"代码存在一些错误。您不考虑进位,您将 ascii 值而不是 0-9 之间的实际值相加,并且您以错误的顺序输出结果。

下面的代码虽然不是很优雅,但确实产生了正确的结果:

var s1 = "12345";
var s2 = "5678";
var carry = false;
var result = String.Empty;
if(s1.Length != s2.Length)
{
    var diff = Math.Abs(s1.Length - s2.Length);
    if(s1.Length < s2.Length)
    {
        s1 = String.Join("", Enumerable.Repeat("0", diff)) + s1;
    }
    else
    {
        s2 = String.Join("", Enumerable.Repeat("0", diff)) + s2;
    }
}

for(int i = s1.Length-1;i >= 0; i--)
{
    var augend = Convert.ToInt32(s1.Substring(i,1));
    var addend = Convert.ToInt32(s2.Substring(i,1));
    var sum = augend + addend;
    sum += (carry ? 1 : 0);
    carry = false;
    if(sum > 9)
    {
        carry = true;
        sum -= 10;
    }
    result = sum.ToString() + result;
}
if(carry)
{
    result = "1" + result;
}
Console.WriteLine(result);

下面的程序可以用来加两个大数,我已经用字符串生成器来存储结果了。您可以添加最多包含"2,147,483,647"的数字。

Using System;
using System.Text;
using System.Linq;
public class Test
{
public static void Main()
{
    string term1="15245142151235123512352362362352351236";
    string term2="1522135123612646436143613461344";
    StringBuilder sum=new StringBuilder();
    int n1=term1.Length;
    int n2=term2.Length;
    int carry=0;
    int n=(n1>n2)?n1:n2;
    if(n1>n2)
    term2=term2.PadLeft(n1,'0');
    else
    term1=term1.PadLeft(n2,'0');
    for(int i=n-1;i>=0;i--)
    {
        int value=(carry+term1[i]-48+term2[i]-48)%10;
        sum.Append(value);
        carry=(carry+term1[i]-48+term2[i]-48)/10;
    }
    char[] c=sum.ToString().ToCharArray();
    Array.Reverse(c);
    Console.WriteLine(c);
}
}
string Add(string s1, string s2)
{
    bool carry = false;
    string result = string.Empty;
    if(s1[0] != '-' && s2[0] != '-')
    {
        if (s1.Length < s2.Length)
            s1 = s1.PadLeft(s2.Length, '0');
        if(s2.Length < s1.Length)
            s2 = s2.PadLeft(s1.Length, '0');
        for(int i = s1.Length-1; i >= 0; i--)
        {
            var augend = Convert.ToInt64(s1.Substring(i,1));
            var addend = Convert.ToInt64(s2.Substring(i,1));
            var sum = augend + addend;
            sum += (carry ? 1 : 0);
            carry = false;
            if(sum > 9)
            {
                carry = true;
                sum -= 10;
            }
            result = sum.ToString() + result;
        }
        if(carry)
        {
            result = "1" + result;
        }
    }
    else if(s1[0] == '-' || s2[0] == '-')
    {
        long sum = 0;
        if(s2[0] == '-')
        {
            //Removing negative sign
            char[] MyChar = {'-'};
            string NewString = s2.TrimStart(MyChar);
            s2 = NewString;
            if(s2.Length < s1.Length)
                s2 = s2.PadLeft(s1.Length, '0');
            for (int i = s1.Length - 1; i >= 0; i--)
            {
                var augend = Convert.ToInt64(s1.Substring(i,1));
                var addend = Convert.ToInt64(s2.Substring(i,1));
                if(augend >= addend)
                {
                    sum = augend - addend;
                }
                else 
                {
                    int temp = i - 1;
                    long numberNext = Convert.ToInt64(s1.Substring(temp,1));
                    //if number before is 0
                    while(numberNext == 0)
                    {
                        temp--;
                        numberNext = Convert.ToInt64(s1.Substring(temp,1));
                    }
                    //taking one from the neighbor number
                    int a = int.Parse(s1[temp].ToString());
                    a--;
                    StringBuilder tempString = new StringBuilder(s1);
                    string aString = a.ToString();
                    tempString[temp] = Convert.ToChar(aString);
                    s1 = tempString.ToString(); 
                    while(temp < i)
                    {
                        temp++;
                        StringBuilder copyS1 = new StringBuilder(s1);
                        string nine = "9"; 
                        tempString[temp] = Convert.ToChar(nine);
                        s1 = tempString.ToString();
                    }
                    augend += 10;
                    sum = augend - addend;
                }
                result = sum.ToString() + result;
            }
            //Removing the zero infront of the answer
            char[] zeroChar = {'0'};
            string tempResult = result.TrimStart(zeroChar);
            result = tempResult;
        }
    }
    return result;
}
string Multiply(string s1, string s2)
{
    string result = string.Empty;
    //For multipication
    bool Negative = false;
    if(s1[0] == '-' && s2[0] == '-')
        Negative = false;
    else if(s1[0] == '-' || s2[0] == '-')
        Negative = true;
    char[] minusChar = {'-'};
    string NewString;
    NewString = s2.TrimStart(minusChar);
    s2 = NewString;
    NewString = s1.TrimStart(minusChar);
    s1 = NewString;
    List<string> resultList = new List<string>();
    for(int i = s2.Length - 1; i >= 0; i--)
    {
        string multiplycation = string.Empty;
        for (int j = s1.Length - 1; j >= 0; j--)
        {
            var augend = Convert.ToInt64(s1.Substring(j,1));
            var addend = Convert.ToInt64(s2.Substring(i,1));
            long multiply = augend * addend;
            // print(multiply); 
            multiplycation = multiply.ToString() + multiplycation;
        }
        //Adding zero at the end of the multiplication
        for (int k =  s2.Length - 1 - i; k > 0; k--)
        {
            multiplycation += "0";
        }
        resultList.Add(multiplycation);
    }
    for (int i = 1; i < resultList.Count; i++)
    {
        resultList[0] = Add(resultList[0],resultList[i]);
    }
    //Finally assigning if negative negative sign in front of the number
    if(Negative)
        result = resultList[0].Insert(0,"-");
    else
        result = resultList[0];
    return result;
}
string Divide(string dividend, string divisor)
{
    string result = string.Empty;
    int remainder = 0;
    int intNumberstoGet = divisor.Length;
    int currentInt = 0;
    int dividing = int.Parse(dividend.Substring(currentInt,intNumberstoGet));
    int intDivisor = int.Parse(divisor);
    while(currentInt < dividend.Length)
    {
        if(dividing == 0)
        {
            currentInt++;
            result += "0";
        }
        else
        {
            while(dividing < intDivisor)
            {
                intNumberstoGet++;
                dividing = int.Parse(dividend.Substring(currentInt,intNumberstoGet));
            }
            if (dividing > 0)
            {   
                remainder = dividing % intDivisor;
                result += ((dividing - remainder) / intDivisor).ToString();
                intNumberstoGet = 1;
                if(currentInt < dividend.Length - 2)
                    currentInt += 2;
                else
                    currentInt++;
                if(currentInt != dividend.Length)
                {
                    dividing = int.Parse(dividend.Substring(currentInt,intNumberstoGet));
                    remainder *= 10;
                    dividing += remainder;
                }
            }
        }
    }
    return result;
}

你去吧。 另一个例子。 它比接受的答案快 10 到 30 倍。

    static string AddNumStr(string v1, string v2)
    {
        var v1Len = v1.Length;
        var v2Len = v2.Length;
        var count = Math.Max(v1Len, v2Len);
        var answ = new char[count + 1];
        while (count >= 0) answ[count--] = (char)((v1Len > 0 ? v1[--v1Len] & 0xF:0) + (v2Len>0 ? v2[--v2Len]&0xF : 0));
        for (var i = answ.Length - 1; i >= 0; i--)
        {
            if (answ[i] > 9)
            {
                answ[i - 1]++;
                answ[i] -= (char)10;
            }
            answ[i] = (char)(answ[i] | 48);
        }
        return new string(answ).TrimStart('0');
    }

下面SO问题有一些有趣的方法。虽然答案在Java中,但你一定会知道需要做什么。

如何在不使用java.math.BigInteger的情况下处理Java中的非常大的数字

    public static int[] addTwoNumbers(string s1, string s2)
    {
        char[] num1 = s1.ToCharArray();
        char[] num2 = s2.ToCharArray();
        int sum = 0;
        int carry = 0;
        int size = (s1.Length > s2.Length) ? s1.Length + 1 : s2.Length + 1;
        int[] result = new int[size];
        int index = size - 1;
        int num1index = num1.Length - 1;
        int num2index = num2.Length - 1;

        while (true)
        {
            if (num1index >= 0 && num2index >= 0)
            {
                sum = (num1[num1index]-'0') + (num2[num2index]-'0') + carry;
            }
            else if(num1index< 0 && num2index >= 0)
            {
                sum = (num2[num2index]-'0') + carry;
            }
            else if (num1index >= 0 && num2index < 0)
            {
                sum = (num1[num1index]-'0') + carry;
            }
            else { break; }

            carry = sum /10;
            result[index] = sum % 10;
            index--;
            num1index--;
            num2index--;
        } 
            if(carry>0)
            {
                result[index] = carry;
            }

        return result;
    }