【问题标题】:Converting from sign-magnitude to two's complement从符号幅度转换为二进制补码
【发布时间】:2011-09-23 20:05:00
【问题描述】:

对于这个赋值,我只能使用基本的按位运算符,没有控制结构,所以到目前为止我已经想出了这个代码来将符号大小转换为two's complement

int sm2tc(int x) {
    // Invert and add 1
    // Problem: sm has 2 zeros.. 1000...000 & 0000...000
    int tmin = 1 << 31;
    int mask = x >> 31;  // Determine sign of x
    int mask2 = ~tmin; // Negate tmin to get 0111111...
    int first = (x ^ mask) + (~mask + 1) ;
    int second = first & mask2; // Turns of MSB
    return second;
}

我哪里出错了?

【问题讨论】:

  • 你不应该依赖 int 是 32 位。使用 int32_t 确定 (stdint.h)。
  • 代码正在 32 位 linux 机器上运行以进行评分,并在我的机器上运行。如果我希望它是可移植的,我想我可以使用 (sizeof(int) * CHAR_BIT - 1) 来存储位值。
  • 如果练习的目的是定义明确的位操作并将您自己对符号的解释强加于位,那么您真的应该使用无符号类型。

标签: c bit-manipulation


【解决方案1】:

所以,你真正想要计算的是

result = (x & sign_bit) ? -(x & ~sign_bit) : x;

当然,您不允许使用控制结构。第一步是仅使用+^ 运算符重写-(x &amp; ~sign_bit)(-1 ^ (x &amp; ~sign_bit)) - -1。现在请注意,如果(x &amp; sign_bit) 为零,则(0 ^ (x &amp; ~sign_bit)) - 0 等于x。我们现在有

result = (x & sign_bit) ? (-1 ^ (x & ~sign_bit)) - -1 : (0 ^ (x & ~sign_bit)) - 0

然后您只需将-10 替换为根据符号位生成这些值的x 的函数,然后你会发现条件的两边都变成了相同的表达式,条件变为没必要。

【讨论】:

  • 您假设底层平台基于 2 的补码表示。你为什么要做出这样的假设?您为什么不假设该平台实际上是基于符号大小的?我想说针对这个特定问题的“干净”解决方案不应该依赖于平台的任何细节。例如,您的原始表达式在有符号量级平台上是无操作的。
  • 我们在 OP 的帖子中看到的是做出独立于平台的解决方案的明确尝试。所以,你所做的并不是 OP 所需要的。换句话说,你不能依赖 -x 产生 2 的补码表示,即禁止一元 -
  • 你的解释很好。我所要做的就是在实际转换之前切换我取消设置 MSB 的行
  • @AndreyT 你是对的,因为我使用 2 的补码机来解释,但我至少在第一步中消除了麻烦的一元减号,尽管我同意我应该使用 ~0而不是-1
  • @Neil 这个线程有点老了......我对 OP 有同样的问题,所以我在这里找到......我有一个答案的问题,为什么不直接写代码喜欢result = (x &amp; sign_bit) ? (~(x &amp; ~sign_bit))+1 : x?为什么需要添加 -00^ ?谢谢。
猜你喜欢
  • 1970-01-01
  • 2016-05-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-28
  • 1970-01-01
  • 1970-01-01
  • 2014-05-21
相关资源
最近更新 更多