在C#中从恒定位宽扩展的符号

时间:2010-10-20 18:34:13

标签: c# c binary bit-manipulation signed

我有一个长度为5位的值。 4位确定数字,第5位确定符号,通过保持-16和+15之间的任何值。如何在C#中实现从恒定位宽扩展的符号?我知道在C中,我可以使用类似下面的内容来完成此任务:

int x; // convert this from using 5 bits to a full int
int r; // resulting sign extended number goes here
struct {signed int x:5;} s;
r = s.x = x;

如何在C#中执行类似的操作?

5 个答案:

答案 0 :(得分:2)

你的意思并不是很清楚,但可能就像这样简单:

int fiveBits = normal & 0x1f;

反之亦然:

int normal =  fiveBits < 16 ? fiveBits : fiveBits | -32;

如果您可以建议一些原始输入和所需输出,那将有所帮助。

答案 1 :(得分:2)

我知道这是一个老问题,但对于未来的搜索者,我有更多的信息。

C#不支持自定义位宽,但它支持二进制操作和getter / setter,这使得添加兼容层变得相对容易。例如,如果要将原始数据存储在字节_num中,但希望能够使用标准C#sbyte与其进行交互,则可以使用以下命令:

byte _num;
sbyte num {
    get
    {
        return (sbyte)(((_num & 0x10) << 3) | (_num & 0x0F));
    }
    set
    {
        _num = (byte)((value & 0x0F) | ((value & 0x80) >> 3));
    }
}

这种shell在与低级固件或嵌入式项目交互时特别有用。

答案 2 :(得分:1)

执行左移,然后是算术右移,将符号位移动到高位然后再移回。算术右移将为您执行符号扩展。

当然这取决于是否有一个有效的算术移位操作。抽象的C语言没有(它的实现定义是否有效),但大多数实现都有。我不确定C#,但我猜它有一个。

答案 3 :(得分:1)

我只是编写一个C函数(因为我真的不知道C#),它会使用我知道在C#中可用的操作来完成这项工作。

int five_bit_to_signed(int five_bit) {
     int sh = (sizeof(int)*8)-5;
     int x = five_bit << sh; // puts your sign bit in the highest bit.
     return x >> sh;  // since x is signed this is an arithmatic signed shift
}

答案 4 :(得分:0)

从您的问题来看,您似乎希望拥有一个可以轻松转换为int类型的结构:

struct FiveBit
{
  public int bits;

  public static implicit operator int(FiveBit f)
  {
    return (f.bits & 0x10) == 0 ? f.bits : f.bits | -32;
  }

  public static implicit operator FiveBit(int r)
  {
    return new FiveBit() { bits = r & 0x1f };
  }
}

以下是一个使用示例:

class FiveBitTest
{
  static void Main(string[] args)
  {
    FiveBit f = new FiveBit();
    int r; // resulting sign extended number goes here

    f.bits = 0;
    r = f;
    Console.WriteLine("r = {0}, f.bits = 0x{1:X}", r, f.bits);

    f.bits = 0x1f;
    r = f;
    Console.WriteLine("r = {0}, f.bits = 0x{1:X}", r, f.bits);

    r = -2;
    f = r;
    Console.WriteLine("r = {0}, f.bits = 0x{1:X}", r, f.bits);
}

以上的输出是:

r = 0, f.bits = 0x0
r = -1, f.bits = 0x1F
r = -2, f.bits = 0x1E