逻辑NOT(!)运算符不适用于按位语句
我试图确定是否可以计算两个32位整数的总和而不会溢出,同时仅使用某些按位和其他运算符。 因此,如果可以添加整数x和y而不溢出,则以下代码应该返回1,否则返回0。
(((((x >> 31) + (y >> 31)) & 2) >> 1))
但是,它应该是1时返回0,反之亦然。 当我使用逻辑NOT(!)运算符或与0x1按位异或(^)时,它不能解决问题。
!(((((x >> 31) + (y >> 31)) & 2) >> 1))
(((((x >> 31) + (y >> 31)) & 2) >> 1) ^ 0x1)
^这些不起作用。
提前致谢。
这有点干净:
~(x & y) >> 31
更新
克里斯的评论是正确的。 所有这些代码都会检查两个MSB是否都已设置。
我只是看着kriss的答案,而我想到,只用一个加法,加上按位运算符(假设为未签名的整数)也可以完成同样的事情。
((x & 0x7FFFFFFF) + (y & 0x7FFFFFFF)) & 0x80000000 & (x | y)
第一个括号中的部分将MSB设置为0,然后添加结果。 任何进位都将在结果的MSB中结束。 接下来的位掩码隔离。 最后一个术语检查x或y上的一组MSB,从而导致总体进位。 为了达到这个问题的规格,只要做到:
~(((x & 0x7FFFFFFF) + (y & 0x7FFFFFFF)) & 0x80000000 & (x | y)) >> 31
假设这两个数字都是无符号整数。 如果你使用带符号整数,那么有两种方法可以使溢出变得更加棘手,要么增加两个大的正数来增加两个大的负数。 无论如何检查最重要的位是不够的,因为除了传播进位,你必须考虑到它。
对于无符号整数,如果你不在乎作弊是一个简单的方法:
(x+y < x) || (x+y < y)
这会起作用,因为大多数编译器在溢出发生时不会做任何事情,只是让它发生。
你也可以说,为了溢出发生,至少有一个数字必须有最重要的位设置为1.因此类似的东西应该可以工作(小心,未经测试),但它比其他版本更加复杂。
/* both Most Significant bits are 1 */
(x&y&0x80000000)
/* x MSb is 1 and carry propagate */
||((x&0x80000000)&&(((x&0x7FFFFFFF)+y)&0x80000000))
/* y MSb is 1 and carry propagate */
||((y&0x80000000)&&(((y&0x7FFFFFFF)+x)&0x80000000))
链接地址: http://www.djcxy.com/p/9883.html
上一篇: Logical NOT (!) operator won't work with bitwise statement
下一篇: Where can I get a list of country names in native languages?