二进制补码转换

时间:2010-09-28 12:10:37

标签: c# twos-complement

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

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

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

EXTRA EDIT 好的,我们假设我们有以下字节流0,255,254,1,127。在二进制补码格式中,它表示0,-1,-2,1,127。这需要钳位到0到25​​5范围。有关详细信息,请查看这篇难以找到的文章:Two's complement

10 个答案:

答案 0 :(得分:7)

您想要的样本输入:

sbyte something = -128;

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

答案 1 :(得分:7)

new = old + 128;
宾果: - )

答案 2 :(得分:3)

尝试

sbyte signed = (sbyte)input;

int signed = input | 0xFFFFFF00;

答案 3 :(得分:2)

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

        return value;
    }

答案 4 :(得分:1)

如果我不正确,您的问题是如何转换输入,这实际上是signed-bytesbyte),但该输入存储在unsigned integer中,然后也是通过将负值转换为零来避免负值。

要明确的是,当您使用签名类型(如ubyte)时,框架在场景后面使用Two's complement,因此只需转换为正确的类型,您将使用两个补码。 / p>

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

下面显示的函数将返回值0的{​​{1}}(或从-128到-1),以及值from 128 to 255的{​​{1}}。

所以,如果你必须使用无符号整数作为输入和输出,你可以使用这样的东西:

the same value

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

from 0 to 127

答案 5 :(得分:1)

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

xor MSB,这都是

答案 6 :(得分: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;
    
    }
    

答案 7 :(得分:0)

您可能正在描述一些简单的事情,例如在您的号码中添加偏见(在这种情况下,为已签名的号码添加128)。

答案 8 :(得分:0)

我相信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);
    }
}

答案 9 :(得分:0)

所以问题是OP的问题实际上不是二进制补码转换。他正在向一组值中添加一个 bias ,以将范围从-128..127调整为0..255。

要实际执行二进制补码转换,只需将有符号值转换为无符号值,就像这样:

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

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

要添加偏差,您只需执行整数加法运算即可:

newValue = signedValue+128;