二进制补码转换

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

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

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

EXTRA EDIT Alrighty,假设我们有以下字节流0,255,254,1,127。 在二进制补码格式中,它表示0,-1,-2,1,127。这需要钳位到0到25​​5范围。 欲了解更多信息,请查看这篇难以找到的文章: 两个补充

从您的样本输入您只需要:

 sbyte something = -128; byte foo = (byte)( something + 128); 
 new = old + 128; 

答对了 :-)

尝试

 sbyte signed = (sbyte)input; 

要么

 int signed = input | 0xFFFFFF00; 
  public static byte MakeHexSigned(byte value) { if (value > 255 / 2) { value = -1 * (255 + 1) + value; } return value; } 
 int8_t indata; /* -128,-127,...-1,0,1,...127 */ uint8_t byte = indata ^ 0x80; 

xor MSB,就是这样

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

脚步:

  1. 通过在变量前放置’〜’将#转换为compliment。 (即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; } 

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

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

要明确的是,当你使用一个带符号的类型(比如ubyte )时,框架在场景后面使用了Two's complement ,所以只需要转换为正确的类型,你将使用二进制补码。

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

对于from 128 to 255 (或从-128到-1)的值from 128 to 255下面给出的函数将返回0 ,对于from 0 to 127from 0 to 127将返回the same value

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

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

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

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

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

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

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

要添加偏差,只需添加整数:

 newValue = signedValue+128;