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

发布于 2024-09-28 08:13:38 字数 330 浏览 8 评论 0原文

我有一个长度为 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;

How can I do things like this in C#?

I have a value thats 5 bits in length. 4 bits determine the number and the 5th bit determines the sign, there by holding any value between -16 and +15. How can I accomplish sign extending from a constant bit width in C#? I know in C, I can use something like the follow to accomplish this:

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;

How can I do something similar to this in C#?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

淑女气质 2024-10-05 08:13:38

我只是编写一个 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
}

I'm just writing a C function (because I don't really know C#) that will do this using operations that I know are available in 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
}
心的憧憬 2024-10-05 08:13:38

目前尚不清楚您的意思,但它可能简单如下:

int fiveBits = normal & 0x1f;

反之亦然:

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

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

It's not really clear what you mean, but it could be as simple as:

int fiveBits = normal & 0x1f;

and for the reverse:

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

If you could suggest some original input and desired output, that would help.

兲鉂ぱ嘚淚 2024-10-05 08:13:38

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

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

Perform a left shift followed by an arithmetic right shift to move the sign bit into the high position and then back. The arithmetic right shift will perform the sign extension for you.

Of course this depends on having a working arithmetic shift operation. The abstract C language does not (it's implementation-defined whether it works or not), but most implementations do. I'm not sure about C# but I would guess it has one.

坏尐絯℡ 2024-10-05 08:13:38

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

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

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

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

I know this is an old question, but for future searchers I have more info.

C# does not support custom bit widths, but it does support binary operations and getters/setters, which makes it relatively easy to add a compatibility layer. For instance, if you want to store the raw data in a byte _num, but want to be able to interact with it using a standard C# sbyte, you can use the following:

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

This kind of shell is especially useful when interacting with low level firmware or embedded projects.

要走就滚别墨迹 2024-10-05 08:13:38

从您的问题来看,您似乎希望有一个可以轻松地与 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

From your question, it appears you wish to have a structure that can readily be converted to and from an int type:

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 };
  }
}

And here's an example of usage:

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);
}

The output of the above is:

r = 0, f.bits = 0x0
r = -1, f.bits = 0x1F
r = -2, f.bits = 0x1E
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文