【问题标题】:C/C++ Check to see if bit 31 is set in an unsigned intC/C++ 检查是否在无符号整数中设置了位 31
【发布时间】:2013-05-21 06:35:14
【问题描述】:

我正在尝试检查是否在无符号整数中设置了位。我不确定我怎么能做到这一点,但我认为它会是这样的。我正在尝试用 C++ 制作 cdq 指令(但它是一个函数)

这就是我所拥有的

unsigned int cdq(unsigned int eax)
{
     unsigned int edx = 0;

     if( (eax >> 31) & 1 ) { edx = 0xFFFFFFFF; }
     return edx
}

当我使用具有以下值的函数时:

cdq(0x12345678) 位 31 设置为 (1) 所以它应该返回 (unsigned int)-1 cdq(0x01) 位 31 未设置 (0) 所以它应该返回 0

问题是它总是返回 0,我不知道为什么

【问题讨论】:

  • 0x12345678 中的第 31 位如何设置?最高位设置为第 28 位。
  • @juanchopanza "你需要eax>>30" -- 错误。
  • eax & 0x7FFFFFFF 如果“最后”位为 0,则为 0,否则为 != 0。假设 unsigned int 至少有 32 位。然后注意在 0x12345678 中第 31 位没有设置。
  • @JimBalter 我以某种方式阅读了“第 31 位”而不是“第 31 位”。我的错。
  • @JimBalter 你是对的,这真的很糟糕。我希望我能活到足够长的时间来弥补这个不可原谅的行为。同时,我已经删除了冒犯性的评论,希望这一行为能够在某种程度上消除这种失常。

标签: c++ c bits


【解决方案1】:

cdq(0x12345678) 位 31 已设置 (1)

不,不是……设置的最高位是第 28 位:

    1    2    3    4    5    6    7    8
 0001 0010 0011 0100 0101 0110 0111 1000
 ^  ^ 
 |  |
31  28

你的代码应该可以工作,但我会使用

if( eax & (1U << 31) ) edx = 0xFFFFFFFF;

因为它更直接一些,并且它移动一个常量而不是一个变量,所以在运行时所做的工作更少(尽管优化编译器应该为两者生成相同的代码)。

其实我会写类似的东西

int cdq(int eax)
{
    return eax < 0? -1 : 0;
}

顺便说一句,您的代码实际上并没有实现 cdq,因为您的 eax 和 edx 变量不是硬件 eax 和 edx 寄存器。无论如何,将 ASM 指令复制为 C 函数确实不是一个好主意...... C 有自己的特性来做这些事情,例如,

int32_t foo = -0x12345678;
int64_t bar = (int64_t)foo;

【讨论】:

  • 好点@caf,但也许你可以留下评论,因为我仍在完善这个答案......编辑它有点激进。
猜你喜欢
  • 2011-08-22
  • 1970-01-01
  • 2012-09-08
  • 2021-09-06
  • 1970-01-01
  • 2018-06-19
  • 2022-07-28
  • 2012-07-12
  • 1970-01-01
相关资源
最近更新 更多