我一直在尝试判断两个32位的数字相减时是否有溢出。给出的规则是:
Can only use: ! ~ & ^ | + << >>
* Max uses: 20
Example: subCheck(0x80000000,0x80000000) = 1,
* subCheck(0x80000000,0x70000000) = 0
No conditionals, loops, additional functions, or casting
字符串
到目前为止我已经
int dif = x - y; // dif is x - y
int sX = x >> 31; // get the sign of x
int sY = y >> 31; // get the sign of y
int sDif = dif >> 31; // get the sign of the difference
return (((!!sX) & (!!sY)) | (!sY)); // if the sign of x and the sign of y
// are the same, no overflow. If y is
// 0, no overflow.
型
我现在意识到我不能在实际的函数(-)中使用减法,所以我的整个函数无论如何都是无用的。我如何使用不同于减法的方法,并仅使用按位操作来确定是否存在溢出?
3条答案
按热度按时间a14dhokn1#
请购买和阅读黑客的喜悦为这些东西。这是一个非常好的书。
字符串
2ul0zpep2#
感谢大家的帮助!以下是我提出的解决问题的方法:
字符串
我尝试的每一个案例都成功了。我改变了@HackerBoss的建议,得到了y的符号而不是ny,然后在return语句中颠倒了两个检查。这样,如果符号相同,或者如果结果的符号和x的符号相同,它就返回true。
tf7tbtn23#
为了避免未定义的行为,我将假设整数以二进制补码表示,这是从
sX
、sY
和sDif
的计算中推断出来的。我还将假设sizeof(int)
为4。如果您只处理32位整数,那么使用int32_t
可能会更好,因为int
的大小会因平台而异。既然你可以使用加法,你可以把减法看作是一个数的负数的加法。一个存储在二进制补码中的数可以通过翻转所有的位并加一来求反。这给出了以下修改后的代码:
字符串