14

我需要将二进制补码格式的字节转换为正整数字节。范围 -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 的范围内。有关更多信息,请查看这篇很难找到的文章:补码

4

10 回答 10

8

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

sbyte something = -128;

byte foo = (byte)( something + 128);
于 2010-09-28T12:13:14.153 回答
7
new = old + 128;

答对了 :-)

于 2010-09-28T12:13:35.023 回答
3

尝试

sbyte signed = (sbyte)input;

或者

int signed = input | 0xFFFFFF00;
于 2010-10-12T20:20:20.923 回答
2

我相信 2s 补码字节最好用以下方法完成。也许不是优雅或简短,但清晰而明显。我会把它作为一个静态方法放在我的一个实用程序类中。

public static sbyte ConvertTo2Complement(byte b)
{
    if(b < 128)
    {
        return Convert.ToSByte(b);
    }
    else
    {
        int x = Convert.ToInt32(b);
        return Convert.ToSByte(x - 256);
    }
}
于 2013-02-03T12:08:59.697 回答
2
    public static byte MakeHexSigned(byte value)
    {
        if (value > 255 / 2)
        {
            value = -1 * (255 + 1) + value;
        }

        return value;
    }
于 2011-11-22T16:13:03.533 回答
1
int8_t indata; /* -128,-127,...-1,0,1,...127 */
uint8_t byte = indata ^ 0x80;

xor MSB,仅此而已

于 2012-09-25T13:34:19.053 回答
1

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

脚步:

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

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

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

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

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

    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;
    
    }
    
于 2013-07-10T13:27:53.437 回答
1

如果我没有正确理解,您的问题是如何转换输入,这实际上是 a signed-byte( sbyte ),但该输入存储在 aunsigned integer中,然后通过将它们转换为零来避免负值。

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

if然后,一旦完成转换,就可以使用简单或条件三元运算符 ( ? :) 来限制负值。

下面介绍的函数将返回0from 128 to 255(或从 -128 到 -1)和the same valuefrom 0 to 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 和 byte):

private static byte ConvertSByteToByte(sbyte input)
{
    return input < 0 ? (byte)0 : (byte)input;
}
于 2010-10-12T20:01:25.740 回答
1

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

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

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

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

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

newValue = signedValue+128;
于 2018-08-08T20:15:16.850 回答
0

您可以描述一些简单的事情,例如为您的号码添加偏差(在这种情况下,将 128 添加到签名号码)。

于 2010-09-28T12:13:16.833 回答