将 int 转换为 unsigned 的计算复杂度与比较值的复杂度

Computational complexity for casting int to unsigned vs complexity for comparing values

我只是想知道 C/C++ 中哪个操作更快,以及类型转换的计算复杂度是多少。

将 x 类型转换为无符号整数,如下所示:

(unsigned int) x

正在对 x 和常量进行比较:

x<0

编辑:计算复杂性,因为为了成功执行指令,哪个过程需要在硬件的低级方面进行最少的位操作。

编辑 #2: 所以为了提供一些背景信息,我特别想做的是看看是否减少

if( x < 0)

进入

if((((unsigned int)x)>>(((sizeof(int))<<3)-1)))

如果超过 100,000,000 次,x 的数量很大,above/below (+/-)50,000,000

是否会更有效率

(unsigned int) x 是 - 对于 near-universal 2 的补码 - 编译时操作:你告诉编译器将 x 的内容视为 unsigned 值,它本身不需要任何运行时 machine-code 指令,但可能会更改它发出的机器代码指令以支持对 unsigned 值的使用,甚至导致 dead-code 消除优化,例如以下可以在转换后完全消除:

if ((unsigned int)my_unsigned_int >= 0)

相关的 C++ 标准引用(我的粗体):

If the destination type is unsigned, the resulting value is the least unsigned integer congruent to the source integer (modulo 2n where n is the number of bits used to represent the unsigned type). [ Note: In a two’s complement representation, this conversion is conceptual and there is no change in the bit pattern (if there is no truncation). —end note ]

可能存在实际的按位更改,需要使用 1 的补码或 sign/magnitude 表示对某些奇怪的硬件进行操作。 (感谢 Yuushi 在评论中强调这一点)。

这与 x < 0 形成对比,后者 - 对于编译器没有特殊知识的带符号 x,确实需要 CPU/machine-code 指令来评估(如果使用结果) 和相应的运行时。该比较指令在更早的 CPU 上往往需要 1 "cycle",但请记住,现代 CPU 管道可以在单个周期内并行执行许多此类指令。

if( x < 0) vs if((((unsigned int)x)>>(((sizeof(int))<<3)-1))) - faster?

第一个总是至少和第二个一样快。与零的比较是 CPU 的 bread-and-butter 操作,并且 C++ 编译器肯定会为其使用高效的操作码(机器代码指令):您正在浪费时间来改进它。

要回答您实际编辑的问题,它不太可能更快。在最好的情况下,如果 x 在编译时已知,编译器将能够在这两种情况下完全优化分支。

如果 x 是一个 run-time 值,那么第一个将产生一个测试指令。第二个可能会产生一个 shift-right 立即数,然后是一个测试指令。

怪物 if((((unsigned int)x)>>(((sizeof(int))<<3)-1))) 会比直接的慢 if(x < 0): 两个版本都需要将一个值与零进行比较,但是你的怪物在比较之前添加了一个移位。