尽管传统智慧,使用+代替|将字节组合成int始终有效吗?

时间:2013-05-16 08:13:12

标签: c# bit-manipulation

传统观点认为,当您将bytes组合在一起制作int时,您应该使用|运算符而不是+运算符,否则您可以标志位有问题。

但在C#中似乎并非如此。看起来您可以愉快地使用+运算符,它甚至可以用于否定结果。

我的问题:

  • 这是真的吗?
  • 如果是这样,为什么会这样? (为什么很多人认为不应该 - 包括我!;)

这是一个测试程序,我相信使用+运算符和|运算符测试四个字节的每个可能组合,并验证两种方法都会产生相同的结果。

这是测试代码:

using System;
using System.Diagnostics;

namespace Demo
{
    class Program
    {
        int Convert1(byte b1, byte b2, byte b3, byte b4)
        {
            return b1 + (b2 << 8) + (b3 << 16) + (b4 << 24);
        }

        int Convert2(byte b1, byte b2, byte b3, byte b4)
        {
            return b1 | (b2 << 8) | (b3 << 16) | (b4 << 24);
        }

        void Run()
        {
            byte b = 0xff;

            Trace.Assert(Convert1(b, b, b, b) == -1); // Sanity check.
            Trace.Assert(Convert2(b, b, b, b) == -1);

            for (int i = 0; i < 256; ++i)
            {
                Console.WriteLine(i);
                byte b1 = (byte) i;

                for (int j = 0; j < 256; ++j)
                {
                    byte b2 = (byte) j;

                    for (int k = 0; k < 256; ++k)
                    {
                        byte b3 = (byte) k;

                        for (int l = 0; l < 256; ++l)
                        {
                            byte b4 = (byte) l;
                            Trace.Assert(Convert1(b1, b2, b3, b4) == Convert2(b1, b2, b3, b4));
                        }
                    }
                }
            }

            Console.WriteLine("Done.");
        }

        static void Main()
        {
            new Program().Run();
        }
    }
}

[编辑]

要了解其工作原理,请考虑以下事项:

byte b = 0xff;

int i1 = b;
int i2 = (b << 8);
int i3 = (b << 16);
int i4 = (b << 24);

Console.WriteLine(i1);
Console.WriteLine(i2);
Console.WriteLine(i3);
Console.WriteLine(i4);

int total = i1 + i2 + i3 + i4;

Console.WriteLine(total);

打印:

255
65280
16711680
-16777216
-1

啊哈!

1 个答案:

答案 0 :(得分:2)

的差异:

  1. 当位重叠时,|+会产生不同的结果:

    2 | 3 = 3
    2 + 3 = 5
    
  2. 实际使用有符号字节时,结果会有所不同:

    -2 | -3   = -1
    -2 + (-3) = -5