二进制补码转换

发布于 2024-09-25 02:24:35 字数 497 浏览 11 评论 0原文

我需要将二进制补码格式的字节转换为正整数字节。 范围 -128 到 127 映射到 0 到 255。

Examples: -128 (10000000) -> 0 , 127 (01111111) -> 255, etc.

编辑为了消除混淆,输入字节(当然)是 0 到 255 范围内的无符号整数。但它表示有符号整数使用二进制补码格式,范围为 -128 到 127。例如,输入字节值128(二进制10000000)实际上代表-128。

额外编辑 好吧,假设我们有以下字节流 0,255,254,1,127。在二进制补码格式中,这代表 0、-1、-2、1、127。我需要将其限制在 0 到 255 范围内。有关更多信息,请查看这篇很难找到的文章:二进制补码

I need to convert bytes in two's complement format to positive integer bytes.
The range -128 to 127 mapped to 0 to 255.

Examples: -128 (10000000) -> 0 , 127 (01111111) -> 255, etc.

EDIT To clear up the confusion, the input byte is (of course) an unsigned integer in the range 0 to 255. BUT it represents a signed integer in the range -128 to 127 using two's complement format. For example, the input byte value of 128 (binary 10000000) actually represents -128.

EXTRA EDIT Alrighty, lets say we have the following byte stream 0,255,254,1,127. In two's complement format this represents 0, -1, -2, 1, 127. This I need clamping to the 0 to 255 range. For more info check out this hard to find article: Two's complement

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

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

发布评论

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

评论(10

℉絮湮 2024-10-02 02:24:35

从您的示例输入中,您只需要:

sbyte something = -128;

byte foo = (byte)( something + 128);

From you sample input you simply want:

sbyte something = -128;

byte foo = (byte)( something + 128);
绝對不後悔。 2024-10-02 02:24:35
new = old + 128;

宾果游戏:-)

new = old + 128;

bingo :-)

池予 2024-10-02 02:24:35

尝试

sbyte signed = (sbyte)input;

int signed = input | 0xFFFFFF00;

Try

sbyte signed = (sbyte)input;

or

int signed = input | 0xFFFFFF00;
茶底世界 2024-10-02 02:24:35
    public static byte MakeHexSigned(byte value)
    {
        if (value > 255 / 2)
        {
            value = -1 * (255 + 1) + value;
        }

        return value;
    }
    public static byte MakeHexSigned(byte value)
    {
        if (value > 255 / 2)
        {
            value = -1 * (255 + 1) + value;
        }

        return value;
    }
季末如歌 2024-10-02 02:24:35

我相信 2s 补码字节最好用以下方法完成。也许不优雅或简短,但清晰可见。我会将其作为静态方法放在我的 util 类之一中。

public static sbyte ConvertTo2Complement(byte b)
{
    if(b < 128)
    {
        return Convert.ToSByte(b);
    }
    else
    {
        int x = Convert.ToInt32(b);
        return Convert.ToSByte(x - 256);
    }
}

I believe that 2s complement bytes would be best done with the following. Maybe not elegant or short but clear and obvious. I would put it as a static method in one of my util classes.

public static sbyte ConvertTo2Complement(byte b)
{
    if(b < 128)
    {
        return Convert.ToSByte(b);
    }
    else
    {
        int x = Convert.ToInt32(b);
        return Convert.ToSByte(x - 256);
    }
}
饭团 2024-10-02 02:24:35

您可以描述一些简单的事情,例如向您的数字添加偏差(在本例中,向带符号的数字添加 128)。

You could be describing something as simple as adding a bias to your number ( in this case, adding 128 to the signed number ).

寄意 2024-10-02 02:24:35

如果我理解正确,您的问题是如何转换输入,这实际上是一个 signed-bytesbyte),但该输入存储在无符号整数中,然后还可以通过将其转换为来避免负值零。

需要明确的是,当您使用有符号类型(例如 ubyte)时,框架会在幕后使用 Two 的补码,因此只需转换为您将使用的正确类型二进制补码。

然后,完成转换后,您可以使用简单的 if 或条件三元运算符 (?:)。

对于 从 128 到 255(或从 -128 到 -1)的值,下面提供的函数将返回 0,对于值相同的值 从 0 到 127

因此,如果您必须使用无符号整数作为输入和输出,您可以使用如下所示的内容:

private static uint ConvertSByteToByte(uint input)
{
    sbyte properDataType = (sbyte)input; //128..255 will be taken as -128..-1
    if (properDataType < 0) { return 0; } //when negative just return 0
    if (input > 255) { return 0; } //just in case as uint can be greater than 255
    return input;
}

或者,恕我直言,您可以将输入和输出更改为最适合您的输入和输出的数据类型(sbyte和字节):

private static byte ConvertSByteToByte(sbyte input)
{
    return input < 0 ? (byte)0 : (byte)input;
}

If I undestood correctly, your problem is how to convert the input, which is really a signed-byte (sbyte), but that input is stored in a unsigned integer, and then also avoid negative values by converting them to zero.

To be clear, when you use a signed type (like ubyte) the framework is using Two's complement behind the scene, so just by casting to the right type you will be using two's complement.

Then, once you have that conversion done, you could clamp the negative values with a simple if or a conditional ternary operator (?:).

The functions presented below will return 0 for values from 128 to 255 (or from -128 to -1), and the same value for values from 0 to 127.

So, if you must use unsigned integers as input and output you could use something like this:

private static uint ConvertSByteToByte(uint input)
{
    sbyte properDataType = (sbyte)input; //128..255 will be taken as -128..-1
    if (properDataType < 0) { return 0; } //when negative just return 0
    if (input > 255) { return 0; } //just in case as uint can be greater than 255
    return input;
}

Or, IMHO, you could change your input and outputs to the data types best suited to your input and output (sbyte and byte):

private static byte ConvertSByteToByte(sbyte input)
{
    return input < 0 ? (byte)0 : (byte)input;
}
骄傲 2024-10-02 02:24:35
int8_t indata; /* -128,-127,...-1,0,1,...127 */
uint8_t byte = indata ^ 0x80;

异或 MSB,仅此而已

int8_t indata; /* -128,-127,...-1,0,1,...127 */
uint8_t byte = indata ^ 0x80;

xor MSB, that's all

心清如水 2024-10-02 02:24:35

这是我对这个问题的解决方案,适用于大于 8 位的数字。我的示例是 16 位值。注意:您必须检查第一位,看看它是否为负数。

步骤:

  1. 通过在变量前放置“~”将 # 转换为补语。 (即 y = ~y)

  2. 将 #s 转换为二进制字符串

  3. 将二进制字符串分解为字符数组

  4. 开始对于最右边的值,添加 1 ,跟踪进位。将结果存储在字符数组中。

  5. 将字符数组转换回字符串。

    私有字符串TwosComplimentMath(字符串值1,字符串值2)
    {
        char[] binary1 = value1.ToCharArray();
        char[] binary2 = value2.ToCharArray();
        布尔进位=假;
        char[] calcResult = new char[16];
    
        for (int i = 15; i >= 0; i--)
        {
            if (二进制1[i] == 二进制2[i])
            {
                if (binary1[i] == '1')
                {
                    如果(携带)
                    {
                        计算结果[i] = '1';
                        进位=真;
                    }
                    别的
                    {
                        计算结果[i] = '0';
                        进位=真;
                    }
                }
                别的
                {
                    如果(携带)
                    {
                        计算结果[i] = '1';
                        进位=假;
                    }
                    别的
                    {
                        计算结果[i] = '0';
                        进位=假;
                    }
                }
            }
            别的
            {
                如果(携带)
                {
                    计算结果[i] = '0';
                    进位=真;
                }
                别的
                {
                    计算结果[i] = '1';
                    进位=假;
                }
            }
    
        }
    
        字符串结果 = 新字符串(calcResult);
        返回结果;
    
    }
    

Here is my solution for this problem, for numbers bigger than 8-bits. My example is for a 16-bit value. Note: You will have to check the first bit, to see if it is a negative or not.

Steps:

  1. Convert # to compliment by placing '~' before variable. (ie. y = ~y)

  2. Convert #s to binary string

  3. Break binary strings into character array

  4. Starting with right most value, add 1 , keeping track of carries. Store result in character array.

  5. Convert character array back to string.

    private string TwosComplimentMath(string value1, string value2)
    {
        char[] binary1 = value1.ToCharArray();
        char[] binary2 = value2.ToCharArray();
        bool carry = false;
        char[] calcResult = new char[16];
    
        for (int i = 15; i >= 0; i--)
        {
            if (binary1[i] == binary2[i])
            {
                if (binary1[i] == '1')
                {
                    if (carry)
                    {
                        calcResult[i] = '1';
                        carry = true;
                    }
                    else
                    {
                        calcResult[i] = '0';
                        carry = true;
                    }
                }
                else
                {
                    if (carry)
                    {
                        calcResult[i] = '1';
                        carry = false;
                    }
                    else
                    {
                        calcResult[i] = '0';
                        carry = false;
                    }
                }
            }
            else
            {
                if (carry)
                {
                    calcResult[i] = '0';
                    carry = true;
                }
                else
                {
                    calcResult[i] = '1';
                    carry = false;
                }
            }
    
        }
    
        string result = new string(calcResult);
        return result;
    
    }
    
初见终念 2024-10-02 02:24:35

所以问题是OP的问题并不是真正的二进制补码转换。他向一组值添加偏差,以将范围从 -128..127 调整到 0..255。

要实际进行二进制补码转换,只需将有符号值转换为无符号值,如下所示:

sbyte test1 = -1;
byte test2 = (byte)test1;

-1 变为 255。-128 变为 128。但这听起来不像 OP 想要的。他只是想向上滑动一个数组,使最低的有符号值(-128)变成最低的无符号值(0)。

要添加偏差,只需进行整数加法:

newValue = signedValue+128;

So the problem is that the OP's problem isn't really two's complement conversion. He's adding a bias to a set of values, to adjust the range from -128..127 to 0..255.

To actually do a two's complement conversion, you just typecast the signed value to the unsigned value, like this:

sbyte test1 = -1;
byte test2 = (byte)test1;

-1 becomes 255. -128 becomes 128. This doesn't sound like what the OP wants, though. He just wants to slide an array up so that the lowest signed value (-128) becomes the lowest unsigned value (0).

To add a bias, you just do integer addition:

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