trying to adjust addition function to a subtraction function

52 views Asked by At

I have this function:

        static int[] AddArrays(int[] a, int[] b)
        {
            Array.Reverse(a);
            Array.Reverse(b);

            int[] result = new int[Math.Max(a.Length, b.Length) + 1];

            int carry = 0;
            int value = 0;

            for (int i = 0; i < Math.Max(a.Length, b.Length); ++i)
            {
                value = (i < a.Length ? a[i] : 0) + (i < b.Length ? b[i] : 0) + carry;

                result[i] = value % 10;
                carry = value / 10;
            }

            if (carry > 0)
                result[result.Length - 1] = carry;
            else
                Array.Resize(ref result, result.Length - 1);

            // Let's restore a and b
            Array.Reverse(a);
            Array.Reverse(b);

            Array.Reverse(result);

            return result;
        }

the function takes 2 arrays of digits these arrays represent a big number which is outside of the integer limits. the function adds together the elements and returns the result. my question is how can i adjust this function to subtract the numbers, for example:

input:

int[] a = 5,475,982,475,984,574,238,975,248,522,952,789,229,899,999,999,9

int[] b = 5,475,982,475,984,574,238,975,248,522,952,789,229,899,999,999,8

(as digit lists meaning each index in the arr is one digit)

expected output: 1 (since 5,475,982,475,984,574,238,975,248,522,952,789,229,899,999,999,9 - 5,475,982,475,984,574,238,975,248,522,952,789,229,899,999,999,8 = 1)

2

There are 2 answers

0
JonasH On

The easiest and most reliable methods should be to use the built in types, i.e. BigInteger, for arbitrary precision math.

static int[] SubtractArrays(int[] a, int[] b)
{
    var bigA = new BigInteger(MemoryMarshal.Cast<int, byte>(a).ToArray());
    var bigB = new BigInteger(MemoryMarshal.Cast<int, byte>(a).ToArray());
    var bigC = bigA - bigB;

    return MemoryMarshal.Cast<byte, int>(bigC.ToByteArray()).ToArray();
}
0
Dmitry Bychenko On

If you can guarantee that result is not negative (otherwise you should think over how to represent it as an array) you can modify the code into (same school algorithm but for subtraction now):

static int[] SubtractArrays(int[] a, int[] b) {
  Array.Reverse(a);
  Array.Reverse(b);

  int[] result = new int[Math.Max(a.Length, b.Length)];
  int carry = 0;

  for (int i = 0; i < Math.Max(a.Length, b.Length); ++i) {
    int value = (i < a.Length ? a[i] : 0) - (i < b.Length ? b[i] : 0) - carry;

    if (value < 0) {
      value += 10;
      carry = 1;
    }
    else
      carry = 0;

    result[i] = value;
  }

  int size = result.Length;

  for (int i = result.Length - 1; i >= 1; --i)
    if (result[i] != 0)
      break;
    else
      size -= 1;

  Array.Resize(ref result, size);

  // Let's restore a and b
  Array.Reverse(a);
  Array.Reverse(b);
  Array.Reverse(result);

  return result;
}

Demo:

using System.Linq;

...

int[] a = "5,475,982,475,984,574,238,975,248,522,952,789,229,899,999,999,9"
  .Where(c => c >= '0' && c <= '9')
  .Select(c => c - '0')
  .ToArray();

int[] b = "5,475,982,475,984,574,238,975,248,522,952,789,229,899,999,999,8"
  .Where(c => c >= '0' && c <= '9')
  .Select(c => c - '0')
  .ToArray();

int[] c = SubtractArrays(a, b);

Console.Write(string.Concat(c));

Output:

1

Fiddle