在c#中用字节数组表示的Int32求和

时间:2016-12-18 19:56:17

标签: c# .net arrays

我有一个音频数据数组,这是由字节数组表示的很多Int32数字(每个4字节元素代表一个Int32),我想对数据进行一些操作(例如,每个数据加10) INT32)。

我将字节转换为Int32,进行操作并将其转换回字节,如下例所示:

//byte[] buffer;
for (int i=0; i<buffer.Length; i+=4)
{
    Int32 temp0 = BitConverter.ToInt32(buffer, i);
    temp0 += 10;
    byte[] temp1 = BitConverter.GetBytes(temp0);
    for (int j=0;j<4;j++)
    {
        buffer[i + j] = temp1[j];
    }
}

但我想知道是否有更好的方法来进行此类操作。

2 个答案:

答案 0 :(得分:1)

以下方法如何:

struct My
{
    public int Int;
}
var bytes = Enumerable.Range(0, 20).Select(n => (byte)(n + 240)).ToArray();
foreach (var b in bytes) Console.Write("{0,-4}", b);

// Pin the managed memory
GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);

for (int i = 0; i < bytes.Length; i += 4)
{
    // Copy the data
    My my = (My)Marshal.PtrToStructure<My>(handle.AddrOfPinnedObject() + i);

    my.Int += 10;

    // Copy back
    Marshal.StructureToPtr(my, handle.AddrOfPinnedObject() + i, true);
}
// Unpin
handle.Free();

foreach (var b in bytes) Console.Write("{0,-4}", b);

我只是为了好玩而做到了。

不确定那不那么难看。

我不知道,它会更快吗?测试一下。

答案 1 :(得分:1)

您可以查看.NET Reference Source有关如何从/转换为大端的指针(笑)。

class intFromBigEndianByteArray {
    public byte[] b;
    public int this[int i] {
        get {
            i <<= 2; // i *= 4; // optional
            return (int)b[i] << 24 | (int)b[i + 1] << 16 | (int)b[i + 2] << 8 | b[i + 3];
        }
        set {
            i <<= 2; // i *= 4; // optional
            b[i    ] = (byte)(value >> 24);
            b[i + 1] = (byte)(value >> 16);
            b[i + 2] = (byte)(value >>  8);
            b[i + 3] = (byte)value;
        }
    }
}

和样品使用:

byte[] buffer = { 127, 255, 255, 255, 255, 255, 255, 255 };//big endian { int.MaxValue, -1 }

//bool check = BitConverter.IsLittleEndian;     // true
//int test = BitConverter.ToInt32(buffer, 0);   // -129 (incorrect because little endian)

var fakeIntBuffer = new intFromBigEndianByteArray() { b = buffer };

fakeIntBuffer[0] += 2;    // { 128, 0, 0, 1 } = big endian int.MinValue - 1
fakeIntBuffer[1] += 2;    // {   0, 0, 0, 1 } = big endian 1

Debug.Print(string.Join(", ", buffer)); // "128, 0, 0, 0, 1, 0, 0, 1" 

为了获得更好的性能,您可以查看并行处理和SIMD指令 - Using SSE in C# 为了获得更好的性能,您可以查看Utilizing the GPU with c#