【发布时间】:2015-01-25 21:51:12
【问题描述】:
我必须使用位操作找到两个数字中的较大者。这些是相同的规则:
/*
* isGreater - if x > y then return 1, else return 0
* Example: isGreater(4,5) = 0, isGreater(5,4) = 1
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 24
*/
这是我为此编写的代码:
int isGreater(int x, int y) {
/* to find greater, subtract y from x using 2's complement method.
* then find 2's complement of the answer and shift right by 31 to give MSB
* which is 1 if x>y and 0 if x<y */
int ydash=(~y)+0x01;
int diff=x+ydash;
int a=(~diff)+0x01;
int b=a>>31;
int c=b&0x01;
return c;
}
为此我收到此错误:
错误:测试 isGreater(-2147483648[0x80000000],2147483647[0x7fffffff]) 失败... ...给出 1[0x1]。应该是 0[0x0]
我可以使用 unsigned int,但不能使用其他数据类型。我不确定这有什么帮助。我该如何解决这个问题?
【问题讨论】:
-
是否允许否定?
-
那么,输入值是有符号整数还是无符号整数?你也可以使用普通的
int吗? (看起来答案是“是”,但不妨检查一下。)鉴于错误消息,输入似乎已签名。另外,我们处理的是 32 位值,而不是 64 位值?这是一种虐待狂的家庭作业问题,让那些不在大学里的人发疯。当您被允许使用比较运算符时,答案是微不足道的,而当您不允许使用比较运算符时,答案会非常困难——因为您不是。值得称赞的是,您已经清楚地说明了前面的限制——谢谢。 -
由于您在代码中使用签名的
int,因此每次溢出都是未定义的行为。这是否真的会影响您的答案尚不清楚,但理论上,您应该在类型签名时避免溢出。 -
在 C 中不是右移负值 UB 吗?
-
显然否定是允许的。有一个测试工具可以检查每个函数的所有可能输入值。这个函数弹出这个错误。这是作业,这是我在通过测试工具运行之前得到的代码。问题是,我已经尝试了所有我能想到的东西,理论上它在我尝试时适用于数学,但这个错误符合我的编程,因为作为无符号数,负数大于另一个。是的,32 位值;它也驱使那些在大学里疯了的人:)
标签: c comparison max bit-manipulation