Home > Mobile >  Calculations on byte array as on one huge number
Calculations on byte array as on one huge number

Time:10-18

Is there some algorithm with which I will be able to treat a byte[] array as one huge number on which I would be able to do mathematical calculations? Example:

What I have: byte[] tab = new byte[5] {5, 255, 0 ,1 ,62};

How I want to treat it as: 52550162 //whole number

What I want to do with it: tab = tab / 2

What would be the possible outcome: {26, 27, 50, 81}

The outcome can be randomized {26, 27, 50, 8, 1} {2, 62, 7, 50, 8, 1}, the only thing that I am carrying about is the possibility to do calculations on numbers represented as a byte array.

CodePudding user response:

You may convert the byte array into a string, and then use BigInteger.Parse() to convert it into a numeric value on which you can use arithmetic.

For example:

byte[] tab = new byte[5] {5, 255, 0 ,1 ,62};
var numericValue = BigInteger.Parse(string.Concat(tab));
numericValue /= 2;
Console.WriteLine(numericValue);  // 26275081

CodePudding user response:

I am not sure how fast this would be. If you could accept the answer as a Span<byte> you could speed this up by just using a large buffer instead of doing Array.Resize at the end.

Basically, I compute the answer array by dividing along the original source array, carrying any remainder to the right and splitting any values too large due to the carry. I also add in any skipped 0s from when the division results in too small a number. Once that is done, I resize the answer array.

var ans = new byte[tab.Length * 2];
int r = 0; // remainder to carry
int ansIdx = 0;
for (int j1 = 0; j1 < tab.Length;   j1) {
    var d = tab[j1] / 2;
    if (r == 0) { // no carry (remainder) from previous division
        if (tab[j1] >= 10) { // original byte was two or three digits
            if (d < 10 && j1 > 0) // new byte is one digit - skipped a zero (only add if past first byte)
                ans[ansIdx  ] = 0;
        }
        if (tab[j1] >= 100) { // original byte was three digits
            if (d < 100 && j1 > 0) // new byte is one or two digits - skipped a zero (only add if past first byte)
                ans[ansIdx  ] = 0;
        }
        ans[ansIdx  ] = (byte)d;
    }
    else { // have a carry (remainder) from previous byte
        if (tab[j1] < 10) // original byte was one digit
            ans[ansIdx  ] = (byte)(d 5);
        else if (tab[j1] < 100) // original byte was two digits
            ans[ansIdx  ] = (byte)(d   50);
        else { // original byte was three digits; new value must be split in two
            d  = 500;
            ans[ansIdx  ] = (byte)(d / 10);
            ans[ansIdx  ] = (byte)(d % 10);
        }
    }
    r = tab[j1] % 2; // check for carry (remainder)
}
Array.Resize(ref ans, ansIdx);
  • Related