Как можно улучшить функцию суммирования двоичных чисел?

Я сделал функцию которая принимает два двоичных числа которые находиться в string и суммирует их. Правильно ли я сделал эту функцию с точки зрения переменных например или можно лучше сделать? P.s сама функция работает корректно

public string res = "";
    public void SumBit(string bite1,string bite2)
    {
        string res = "";
        char interBit = '0';
       for (int i=bite1.Length-1 ;i>=0; i--)
       {
            if (bite1[i] == '1' && bite2[i] == '1')
            {
                if (interBit == '1')
                {
                    res = '1' + res;
                }
                else
                {
                    res = '0' + res;
                    interBit = '1';
                }
            }
            else
            if (bite1[i] == '1' && bite2[i] == '0' || bite1[i] == '0' && bite2[i] == '1')
            {
                if (interBit == '1')
                {
                    res = '0' + res;
                }
                else
                {
                    res = '1' + res;
                }
            }
            else
            {
                if (interBit=='1')
                {
                    res = '1' + res;
                    interBit = '0';
                }
                else
                res = '0' + res;
            }
       }
    }

Я использовал тип string, потому что удобно работать ведь какое либо десятичное число легко перевести в двоичное следующим образом

  number = Convert.ToString(intput, 2);

Ответы (2 шт):

Автор решения: tym32167

Вообще такое делать имеет смысл только в учебных целях, в реальной задаче лучше строку перевести в число, сложить и обратно перевести в строку.

Но мне просто было интересно написать алгоритм, потому скидываю как ответ, чего добру пропадать то.

Я вместо кучи if-ов просто посчитал количество единичек на каждой из позиций.

public string SumBit(string bite1,string bite2)
{
    bool reminder = false;
    var ret = new Stack<char>();
    var len = Math.Max(bite1.Length, bite2.Length);
    
    for(int i=0; i<len; i++)
    {
        int cnt = reminder ? 1 : 0;     
        if (i < bite1.Length && bite1[bite1.Length - 1 - i] == '1') cnt++;
        if (i < bite2.Length && bite2[bite2.Length - 1 - i] == '1') cnt++;
        if (cnt % 2 != 0) ret.Push('1');
        else ret.Push('0');
        reminder = cnt  > 1;
    }
    
    if(reminder) ret.Push('1');
    
    var sb = new StringBuilder();
    while(ret.Count > 0) sb.Append(ret.Pop());      
    return sb.ToString();
}

Проверка

Console.WriteLine(SumBit("1010","0101"));
Console.WriteLine();
Console.WriteLine(SumBit("00","00"));
Console.WriteLine(SumBit("00","01"));
Console.WriteLine(SumBit("00","10"));
Console.WriteLine(SumBit("00","11"));
Console.WriteLine();
Console.WriteLine(SumBit("01", "00"));
Console.WriteLine(SumBit("01", "01"));
Console.WriteLine(SumBit("01", "10"));
Console.WriteLine(SumBit("01", "11"));
Console.WriteLine();
Console.WriteLine(SumBit("10", "00"));
Console.WriteLine(SumBit("10", "01"));
Console.WriteLine(SumBit("10", "10"));
Console.WriteLine(SumBit("10", "11"));
Console.WriteLine();
Console.WriteLine(SumBit("11", "00"));
Console.WriteLine(SumBit("11", "01"));
Console.WriteLine(SumBit("11", "10"));
Console.WriteLine(SumBit("11", "11"));

Результат

1111

00
01
10
11

01
10
11
100

10
11
100
101

11
100
101
110
→ Ссылка
Автор решения: A K

Тоже раньше писал такие же решения, как @tym32617:

public string AddBinary(string a, string b)
{
    var sb = new StringBuilder();

    var carry = 0;
    
    var iA = a.Length - 1;
    var iB = b.Length - 1;

    while (iA >= 0 || iB >= 0)
    {
        var bA = iA < 0 ? 0 : a[iA] - '0';
        var bB = iB < 0 ? 0 : b[iB] - '0';

        sb.Insert(0, (bA + bB + carry) % 2);
        
        carry = (bA + bB + carry) / 2;
        
        iA--;
        iB--;
    }

    if(carry == 0)
        return sb.ToString();
        
    sb.Insert(0, '1');
    return sb.ToString();
}

Но мне не нравится вот эта последняя проверка переноса, её можно упростить:

public string AddBinary(string a, string b)
{
    var sb = new StringBuilder();

    var carry = 0;
    
    var iA = a.Length - 1;
    var iB = b.Length - 1;

    while (iA >= 0 || iB >= 0 || carry > 0)
    {
        var bA = iA < 0 ? 0 : a[iA] - '0';
        var bB = iB < 0 ? 0 : b[iB] - '0';

        sb.Insert(0, (bA + bB + carry) % 2);
        
        carry = (bA + bB + carry) / 2;
        
        iA--;
        iB--;
    }

    return sb.ToString();
}

Задача взята с литкода: https://leetcode.com/problems/add-binary/

[Test]
[TestCase("11", "1", "100")]
[TestCase("1010", "1011", "10101")]
public void SolutionTests(string a, string b, string expected)
{
    var actual = new Solution().AddBinary(a, b);
    Assert.That(actual, Is.EqualTo(expected));
}

Для десятичных чисел алгоритм тот же, надо только % 2 и / 2 заменить на основание 10. И это проще в написании потому что универсальнее.

public string AddStrings(string num1, string num2)
{
    var res = new StringBuilder();

    int carry = 0;
    int p1 = num1.Length - 1;
    int p2 = num2.Length - 1;
    while (p1 >= 0 || p2 >= 0 || carry != 0)
    {
        int x1 = p1 >= 0 ? num1[p1] - '0' : 0;
        int x2 = p2 >= 0 ? num2[p2] - '0' : 0;
        int value = (x1 + x2 + carry) % 10;
        carry = (x1 + x2 + carry) / 10;
        res.Insert(0, value);
        p1--;
        p2--;
    }

    return res.ToString();
}
→ Ссылка