打包数值的数学运算

Jam*_*uth 5 c# bit-shift

给出以下代码将四个byte值打包成a uint.

private static void Pack(byte x, byte y, byte z, byte w)
{
    this.PackedValue = (uint)x |
                       ((uint)y << 8) |
                       ((uint)z << 16) |
                       ((uint)w << 24);
}
Run Code Online (Sandbox Code Playgroud)

是否有可能*, +, / and -将数值运算符应用于值,以便可以将其解压缩为正确的byte等价物?

编辑.

澄清一下,如果我试图将该值乘以另一个打包值

uint result  = this.PackedValue * other.PackedValue 
Run Code Online (Sandbox Code Playgroud)

然后使用以下内容解压...

public byte[] ToBytes()
{
    return new[]
    {
        (byte)(this.PackedValue & 0xFF),
        (byte)((this.PackedValue >> 8) & 0xFF),
        (byte)((this.PackedValue >> 16) & 0xFF),
        (byte)((this.PackedValue >> 24) & 0xFF)
    };
}
Run Code Online (Sandbox Code Playgroud)

我得到了错误的结果.

这是一个完整的代码示例,显示了预期和实际结果.

void Main()
{
    uint x = PackUint(128, 128, 128, 128);
    uint y = (uint)(x * 1.5f);

    byte[] b1 = ToBytes(x);
    x.Dump(); // 2155905152
    b1.Dump(); // 128, 255, 128, 255 RIGHT!
    byte[] b2 = ToBytes(y);
    b2.Dump(); // 0, 192, 192, 192 WRONG! Should be 192, 192, 192, 192

}

// Define other methods and classes here
private static uint PackUint(byte x, byte y, byte z, byte w)
{
    return ((uint)x) |
           ((uint)y << 8) |
           ((uint)z << 16) |
           ((uint)w << 24);
}

public static byte[] ToBytes(uint packed)
{
    return new[]
    {
        (byte)(packed & 0xFF),
        (byte)((packed >> 8) & 0xFF),
        (byte)((packed >> 16) & 0xFF),
        (byte)((packed >> 24) & 0xFF)
    };
}
Run Code Online (Sandbox Code Playgroud)

Rom*_*kov 5

它不起作用的唯一原因1.5f是因为浮子不够精确.尝试1.5d(for double),您的示例将起作用.然而,这种方法仅限于"好"的情况,即那些保证每个字节的结果是整数的情况.一个特例是当你乘以一个整数时,只要四个结果都没有溢出,它就会一直有效.

如果没有单个字节溢出,也可以对加法和减法执行此操作.显然任何溢出都会弄乱附近的字节.如果您希望对负字节(-128 ... 127)使用2的补码,则这尤其成问题,因为将3添加到-2也是"溢出"并且会使下一个字节陷入混乱.