【问题标题】:Left shift operation with Ones' complement binary二进制补码的左移操作
【发布时间】:2019-09-06 11:26:55
【问题描述】:

我正在研究按位运算和有符号数表示。我已经认识到,如果我们在补码模式上进行左移。它没有正确地乘以原始数字。

例如(反码):

11100101 (-26) << 1 = 11001010 (-53)

11110100 (-11) << 2 = 11010000 (-47)

-26 左移 1 位给出 -53(不是 -52),-11 左移 2 位给出 -47(不是 -44)。这就是人们选择二进制补码进行精确数字运算的原因。我在谷歌上搜索过,但没有提到左移和补码的帖子。几乎提到了带补码的左移

【问题讨论】:

  • 在 C 和 C++ 中,这根本不重要。如果左移一个负数,则行为未定义。
  • 谢谢,所以在C或C++中,不支持左移负数,右移

标签: binary bitwise-operators bit-shift negative-number ones-complement


【解决方案1】:

在二进制补码中,负数 A 由正数 2 编码n-|A|并且可以通过 -2n-1 × an-1 + ∑0n-2 2i × ai 很容易证明,将这个值左移 k 位将得到 A×2k的代码>,只要没有溢出(即只有零或只有一个被移出)。

在一个补码中,负数 A 由(A 的 2 的补码)-1 编码。其值为 -2n-1 × an-1 + ∑0n-2 2i × ai-1。如果我们左移k,结果的数值是(2的补码2k*A)-2k*1(前提是没有溢出) .它与预期结果相差 2k-1,预期结果是(2k*A 的 2 的补码)-1

我们可以在您的示例中进行验证:

C1(-26)1-1))
C1(-11)2-1))

因此,要将 1 的补码中编码的负数乘以 2k,您需要将其左移 k 并添加到结果中 2k-1

一般来说,只有二进制补码提供简单的算术运算。其他代码(超 k、一个补码、符号绝对值)总是需要更正(这也是它们很少使用的原因)。

【讨论】:

  • 感谢您的有用解释,但据我所知,负数补码 A 由(A 的 2 的补码)编码 - 1(正如您所说的(2 的补码),这可能有点令人困惑A) + 1)。哪个是正确的
  • 你是对的。通常的负数 A 确实以两个补码形式编码为 C2(A)=~A+1。一个补码是~A,因此是 C2(A)-1。谢谢。我澄清了答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-11-23
  • 1970-01-01
  • 2015-04-12
  • 1970-01-01
  • 1970-01-01
  • 2014-09-20
  • 1970-01-01
相关资源
最近更新 更多