使用按位运算符确定 Int 是否适合 C 中的 Short

Determining if an Int Fits into a Short in C using Bitwise Operators

我的任务是制作一个函数,return判断 int x 是否适合 C 中的 short(return 如果适合则为 1,否则为 0)。这通常是一个相当简单的解决方案,但我只能使用以下按位运算符:! ~ & ^ | + << >>.

这里还有一些规则:

我了解这些算子的基本功能,但对实现逻辑感到困惑。有什么想法吗?

假设2的补码,算术右移,舍弃溢出位的左移,32位int,则:

x<<16>>16 ^ x
当且仅当 x 适合 16 位 short.

时,

为零

由于我们被要求 return 零表示不适合,一表示适合,我们可以 return:

! (x<<16>>16 ^ x)

证明:

如果x适合short,那么x•216适合int,所以x<<16 产生没有溢出的结果,并且 x<<16>>16 恢复 x (因为只删除零的算术右移实际上是一个没有余数的除法),之后 x ^ x 为零。

如果 x 超过了一个短路,那么 x<<16 就会溢出(我们假设这会导致丢弃高位)。此外,它的值是 y<<16 为某些 y 生成的值之一,这是一个空头。那么 x<<16>>16 必须产生与 y<<16>>16 相同的值,即 y,与 x 不同,因此 x<<16>>16 ^ x 不能为零。

假设有 2 个补码,您最初的想法是测试所有前导位但 15 位全为 0 或全为 1 确实可行。

11111111 11111111 1xxxxxxx xxxxxxxx /* for negative 16 bits int */
00000000 00000000 0xxxxxxx xxxxxxxx /* for positive 16 bits int */

假设算术右移,你可以右移15来消除未知位,然后只剩下1或0(如果它适合15位)

因此 x>>15 应该是 0 或 -1。
如果为 0,则 !(x>>15) 为真。
如果是-1,则!(~(x>>15))为真。
因此,您可以测试 !(x>>15) | !(~(x>>15))
或者你也可以这样写:!(x>>15) | !(~x>>15)

请注意,上面的表达式不假定 32 位 x,并且还可以用于测试 int64 是否适合 int16...

还有很多其他方法...
由于您也可以使用 +,因此 (x>>15)+1 为 0 或 1。
然后你可以清除最后一位:((x>>15)+1)>>1.
如果上面的表达式全为 0(假),x 确实适合 16 位 int,因此您需要:

! (((x>>15)+1)>>1)

由你来寻找更多的表达...