2010-09-28 209 views
9

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

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

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

EXTRA EDIT Alrighty,可以说我们有以下字节流0,255,254,1,127。在二进制补码格式中,这代表0,-1,-2,1,127.这个我需要钳位到0到25​​5的范围。欲了解更多信息请查看这个很难找到文章:Two's complement

+2

'byte'没有签名,你想干什么? – leppie 2010-09-28 12:12:01

+0

我仍然不完全确定在这里尝试了什么。要么是所有答案给你的方式,要么你错误地理解2的补码表示。 – leppie 2010-09-28 12:29:33

回答

7

从你的样品输入您只是想:

sbyte something = -128; 

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

请参阅我的编辑。现在希望它更清楚。 – Yehonatan 2010-09-30 06:32:01

+3

@Yehonatan:但是您想如何在0到255范围内表示-1? – leppie 2010-09-30 07:04:56

0

你可以描述为增加偏置到你的电话号码一样简单的东西(在这种情况下,将128添加到签名号码)。

+0

如果只是这么简单。 – Yehonatan 2010-09-30 06:32:32

6
new = old + 128; 

宾果:-)

+9

因为我找不到'bingo'关键字,所以我编辑了你的答案以便阅读:-) – paxdiablo 2010-09-28 12:33:47

+0

'旧'是原始字节值还是它的转换?如果它的原始字节值,那么这给出了错误的答案。如果它是后者,那么这就是我要求的过程。 – Yehonatan 2010-09-30 06:30:56

0

如果我正确undestood,你的问题是如何输入,这实在是一个signed-bytesbyte)转换,但输入存储在unsigned integer,然后还通过将它们转换为零来避免负值。

需要明确的是,当你使用一个符号的类型(如ubyte)的框架是用Two's complement幕后,所以才铸造了你将要使用补正确的类型。

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

下面提出将返回0为值from 128 to 255(或从-128至-1)the same value为值from 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而字节):

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

尝试

sbyte signed = (sbyte)input; 

int signed = input | 0xFFFFFF00; 
1
public static byte MakeHexSigned(byte value) 
    { 
     if (value > 255/2) 
     { 
      value = -1 * (255 + 1) + value; 
     } 

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

XOR MSB,这是所有

+2

对我来说,这看起来不像C# – reggaeguitar 2015-04-01 19:27:47

0

我相信,二进制补码的字节将与下文中最好的做法。也许不优雅或短暂,但清晰明显。我会把它作为我的一个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); 
    } 
} 
1

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

步骤:

  1. 转换#由变量之前放置 '〜' 赞扬。 (即,Y =〜Y)

  2. 转换#分别为二进制串

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