代码之家  ›  专栏  ›  技术社区  ›  Roman Starkov

C中使用位求反运算符写入“byte”类型常量的最短方法?

c#
  •  2
  • Roman Starkov  · 技术社区  · 14 年前

    这是一个“软问题”,但基本上,我尝试采用隐式转换为字节的模式:

    byte x = 0;
    x |= 2;       // implicit conversion of "x | 2" to byte here
    

    并使用它 去除 位:

    x &= ~2;      // compile error
    

    我能想到的最短的是:

    x &= unchecked((byte) ~2);
    

    (在这一点上,我开始认真考虑写作 x &= 253; // ~2 相反…或者只是一个优秀的老演员: x = (byte) (x & ~2); )

    我错过了一条较短的路吗?

    4 回复  |  直到 14 年前
        1
  •  4
  •   Matt Brunell    14 年前

    这个怎么样?

    {
       byte x = 0;
       x |= 2;
       x &= 0xFF & ~2;
    }
    

    说明:这里有两个问题。首先,一元运算符“~”:

    根据C规范4.1.5:

    整型一元和二元运算符总是用有符号运算。 32位精度,无符号32位 精度,有符号64位精度,或 无符号64位精度:

    对于一元+和~运算符,操作数转换为类型t, 其中t是int的第一个,uint, 长,和乌龙,可以完全 表示 操作数。然后操作 使用类型的精度执行 t,结果的类型是t。

    一旦应用了一元运算符,结果总是最小的一个“int”类型。从这里,您希望隐式转换为字节。

    其次, Implicit conversions :

    int类型的常量表达式不能 转换为sbyte、byte、short, ushort、uint或ulong提供了 常量表达式的值为 在目的地范围内 类型。

    因此,~2始终是一个int。它不能隐式转换为byte,因为它超出了范围。如果将其约束在范围内,则可以隐式转换。

        2
  •  3
  •   user720594    14 年前

    您可以这样命名常量:

    [Flags]
    enum SomeType : byte {
      Value = 2,
    }
    
    public void Method () {
      SomeType t = 0;
      t |= SomeType.Value;
      t &= ~SomeType.Value;
    }
    
        3
  •  0
  •   John Alexiou    14 年前

    使用自定义类型

        public struct Bits
        {
            byte x;
            public Bits(int x) { this.x = (byte)x; }
            public Bits(byte x) { this.x = x; }            
            public Bits(Bits x) { this.x = x.x; }
    
            public static implicit operator byte(Bits x) { return x.x; }
            public static implicit operator Bits(byte x) { return new Bits(x); }
            public static implicit operator Bits(int x) { return new Bits(x); }
        }
    
        static void Main(string[] args)
        {
            Bits x = 0;
            x |= 2;
            x &= ~2;
        }
    

    此外,还可以为字节编写扩展方法来设置位。

        public static byte Set(this byte x, byte v)
        {
            return (byte)(x | v);
        }
        public static byte Unset(this byte x, byte v)
        {
            return (byte)(x & ~v);
        }
        static void Main(string[] args)
        {
            byte x = 0;
            x = x.Set(2);
            x = x.Unset(2);
        }
    
        4
  •  -1
  •   Jonathan    14 年前
    byte x = 6;
    Console.WriteLine(x & ~(byte)2);
    

    这对我有效,印刷品4