简体   繁体   English

C - 小于或等于按位运算符

[英]C - less than or equal to with bitwise operators

I'm trying to create a function to determine whether x is less than or equal to y.我正在尝试创建一个 function 来确定 x 是否小于或等于 y。 The legal operators are !合法经营者是! ~ & ^ | ~ & ^ | + << >> , and the function says "if x <= y then return 1, else return 0" + << >> ,并且 function 说“如果 x <= y 则返回 1,否则返回 0”

My thought process is to check whether xy is negative, and then right shift 31 bits and compare with 1. No matter what adjustments I do, it returns 0, when it's expecting 1.我的思考过程是检查xy是否为负,然后右移 31 位并与 1 进行比较。无论我做什么调整,它都返回 0,而它期望为 1。

This is what I have so far:这是我到目前为止所拥有的:

int isLessOrEqual(int x, int y) {
return (((x - y) >> 31) & 1) | (!(x^y));
}

Can anyone please help me see what I'm doing wrong?谁能帮我看看我做错了什么?

I also tried with all of these return statements:我还尝试了所有这些返回语句:

 return (!(x^y)) | (((x+(~y+1)) >> 31 ) & 1);
 return ~(((x+(~y+1)) >> 31 ) & 1) |  (!(x^y));
 return !(((x+(~y+1)) >> 31 ) & 1) |  (!(x^y));
 return (((x+(~y+1)) >> 31 ) & 1);

 return (((x+y+(~1)) >> 31 ) & 1) |  (!(x^y));
 return (((x+y+(~1) >> 31 ) & 1) |  (!(x^y));
 return (((x+(~y+1)) >> 31 ) & 0);

I am not going to do your assignment for you, but I will try to get you pointed in the right direction.我不会为你完成你的任务,但我会尽力让你指出正确的方向。

My thought process is to check whether xy is negative, and then right shift 31 bits and compare with 1.我的思路是检查xy是否为负数,然后右移31位与1比较。

I take you to mean that you want to test whether xy is negative by shifting the result and comparing with 1, and then to use that in determining the function's return value.我认为你的意思是你想通过移动结果并与1比较来测试xy是否为负,然后用它来确定函数的返回值。 That's more or less ok, but there is some room for concern about right shifting negative numbers, as the result is implementation defined.这或多或少没问题,但是对于右移负数有一些担忧,因为结果是实现定义的。 I do not think that's causing you trouble in practice, however.但是,我认为这不会在实践中给您带来麻烦。

No matter what adjustments I do, it returns 0, when it's expecting 1.无论我做什么调整,当它期待 1 时,它都会返回 0。

In some cases , yes.在某些情况下,是的。 But there are many other cases where that approach, correctly implemented, produces the desired result.但是在许多其他情况下,正确实施该方法会产生预期的结果。 About 75% of cases, in fact.事实上,大约 75% 的病例。 Specifically,具体来说,

  • it works (only) when xy does not overflow .它(仅)在xy不溢出时起作用

Additionally,此外,

  • since you're not allowed to use the - operator, you'll need to perform the two's complement conversion and use + instead.由于不允许使用-运算符,因此您需要执行二进制补码转换并改用+
  • you can avoid the shifting by ANDing with INT_MIN instead of with 1. This yields a nonzero result ( INT_MIN ) when and only when the other operand of the & has its sign bit set.您可以通过与INT_MIN而不是 1 进行与运算来避免移位。当且仅当&的另一个操作数设置了符号位时,这会产生非零结果 ( INT_MIN )。 If you like, you can convert non-zero to exactly 1 by logically negating twice ( !!x ).如果您愿意,您可以通过逻辑否定两次 ( !!x ) 将非零转换为 1。
  • You can slightly simplify the overall computation by using yx instead of xy .您可以使用yx而不是xy稍微简化整体计算。 Then you don't need special accommodation for the x == y case.那么对于x == y情况,您不需要特殊的住宿。

You know (or can know) that neither x - y nor y - x overflows when x and y have the same sign.您知道(或可以知道)当xy具有相同符号时, x - yy - x都不会溢出。 * In that case, you can use one or another variation on testing the arithmetic difference of the arguments. *在这种情况下,您可以使用一种或另一种变体来测试 arguments 的算术差异。 On the other hand, there is a simpler alternative when the two have differing signs (left as an exercise).另一方面,当两者具有不同的符号时,还有一个更简单的替代方案(留作练习)。

To combine those into a single expression, you can compute bitmasks that effect a selection between two alternatives.要将它们组合成一个表达式,您可以计算影响两个备选方案之间选择的位掩码。 Schematically:示意图:

return (WHEN_SIGNS_MATCH_MASK(x, y) & IS_DIFFERENCE_NON_NEGATIVE(y, x))
        | (WHEN_SIGNS_DIFFER_MASK(x, y) & ...);

The WHEN_SIGNS_MATCH_MASK should evaluate to 0 when the signs differ and to -1 (== all bits 1) or another appropriate value when the signs are the same.当符号不同时, WHEN_SIGNS_MATCH_MASK应评估为 0,当符号相同时,应评估为 -1(== 所有位 1)或另一个适当的值。 The WHEN_SIGNS_DIFFER_MASK implements the opposite sense of that sign comparison. WHEN_SIGNS_DIFFER_MASK实现了符号比较的相反意义。 The IS_DIFFERENCE_NON_NEGATIVE expands to your subtraction-based computation, and the ... is the alternative approach for the differing-sign case. IS_DIFFERENCE_NON_NEGATIVE扩展到基于减法的计算,而...是不同符号情况的替代方法。 (I've implied using macros. You don't need to use macros, but doing so will probably make your code clearer.) (我暗示使用宏。您不需要使用宏,但这样做可能会使您的代码更清晰。)


* A sufficient condition, but not a necessary one. *一个充分条件,但不是必要条件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM