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 0
s 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);