![将负十进制转换为二进制](https://linux22.com/image/1466756/%E5%B0%86%E8%B4%9F%E5%8D%81%E8%BF%9B%E5%88%B6%E8%BD%AC%E6%8D%A2%E4%B8%BA%E4%BA%8C%E8%BF%9B%E5%88%B6.png)
我一直在尝试将数字 -441 转换为二进制,但我真的不知道如何做到这一点。
我首先将 441 转换为二进制,即:110111001 然后我应该取这个数字的补数:001000110 然后我必须加一,结果是:001000111
练习说我必须给出 10 位和 16 位的二进制表示,所以我以为我可以在数字前面放一个零就可以了,但是经过大量搜索后我发现我应该在数字前面放一个 1,为什么会这样呢?
我该如何将 -441 转换为 16 位数字?
谢谢。
答案1
您之所以感到困惑,是因为您忘记了一定有某种东西可以区分正数和负数。
假设您想在 8 位上存储非负数。
00000000
为 0,00000001
为 1,00000010
为 2,00000011
为 3,00000100
为 4,- ...
11111111
是 255
因此,您可以在 8 位上存储 0-255 范围内的数字。255 = 2 8 - 1。(2 是二进制的基数,8 是位数,减去 1 是因为我们想要将 0 算进去)
现在,假设您也想存储负数。我们该如何实现呢?我们可以专门用一位来表示符号。如果此位是,0
则我们将其他 7 位解释为正数,否则解释为负数。最好使用最高有效位来表示符号,因为这样可以使某些操作更容易。
简单方法:直接读取一个数字即可:
00000001
== 1 和10000001
== -101000010
== 66 和11000010
== -6601111111
== 127 和11111111
== -127
一元数的补数:对于任何数字
x
,对其二进制表示取反将得到 的二进制表示-x
。这意味着:00000001
== 1 和11111110
== -101000010
== 66 和10111101
== -6601111111
== 127 和10000000
== -127
二进制补码:对于任何数字
x
,将其二进制表示取反并加 1 可得出 的二进制表示-x
。这意味着:00000001
== 1 和11111111
== -101000010
== 66 和10111110
== -6601111111
== 127 和1000001
== -12710000000
== -128
为什么二进制的补码是最好的?
- 因为它的范围最广:-128...127,而平凡方法和补码的范围为 -127...127
- 零的定义很明确:
- 二进制补码中只有
00000000
零 - 在平凡方法中,和
00000000
都10000000
为零 - 在反码中和
00000000
都11111111
为零
- 二进制补码中只有
- 加法和减法与无符号数相同,因此 CPU 不需要额外的指令来添加有符号数。
请注意,如果我们将最高有效位专用于符号位,那么我们就无法在不知道需要多少位的情况下将数字转换为二进制。例如,如果我们有 4 位,那么简单方法中的数字 -5 是1101
,在 7 位上它将是1000101
。0001101
(4 位 -5 用零填充至 7 位长度)实际上是 13(最高有效位是 0,因此它是正数)。
我不会为你做作业,但我可以给你一般性的建议:
要转换-x
为N
位长的二进制补码表示形式:
-x
使用二进制补码转换为二进制。- 在左侧用零填充,直到达到
N-1
长度。 - 在左边添加负号位。
我想您可以从这个答案中找出其余内容。如果您还有其他问题,请发表评论。
答案2
好吧,得到二进制补码后,你需要在二进制的最末端添加一个 0,这样它就变成了 10 位表示法。棘手的部分是你需要添加一个有符号位来表明二进制是负整数,即 (1) 0001000111