二进制补码转换
我需要将二进制补码格式的字节转换为正整数字节。 范围-128到127映射到0到255。
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到255范围。 欲了解更多信息,请查看这篇难以找到的文章: 两个补充
从您的样本输入您只需要:
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位值。 注意:您必须检查第一位,看它是否为负数。
脚步:
-
通过在变量前放置’〜’将#转换为compliment。 (即y = ~y)
-
将#s转换为二进制字符串
-
将二进制字符串分成字符数组
-
从最右边的值开始,添加1,跟踪进位。 将结果存储在字符数组中。
-
将字符数组转换回字符串。
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 127
值from 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;