简体   繁体   English

用算术/按位运算符实现关系运算符

[英]Implement relational operator with arithmetic/bitwise operators

Assuming: 假设:

  • 32-bit signed integers in two's complement form 二进制补码形式的32位有符号整数
  • true and false are integers with values 1 and 0 truefalse是值为10整数
  • java operators Java运算符

Can you implement relational operators like < and == using only arithmetic and bitwise operators? 可以仅使用算术和按位运算符来实现像<==这样的关系运算符吗?

Here's a quick attempt. 这是一个快速尝试。 Signed less-than is messy but possible in 32-bit arithmetic if needed. 小于号是比较麻烦的,但是如果需要,可以在32位算术中使用。

int32_t cmp_lt(int32_t lhs, int32_t rhs) {
    int64_t tmp = lhs;
    tmp -= rhs;
    tmp >>= 63;
    return tmp & 1;
}

int32_t cmp_eq(int32_t lhs, int32_t rhs) {
    return (cmp_lt(lhs, rhs) | cmp_lt(rhs, lhs)) ^ 1;
}

// 32-bit only version
int32_t cmp_lt32(int32_t lhs, int32_t rhs) {
    int32_t tmp = lhs - rhs;
    // -lhs < +rhs is always true
    tmp |= ~rhs & lhs;
    // +lhs < -rhs is always false
    tmp &= ~rhs | lhs;
    tmp >>= 31;
    return tmp & 1;
}

edit: I see that Java was asked for. 编辑:我看到要求Java。 Not my native language but I believe the regular integer and long types could be substituted for int32_t and int64_t here. 不是我的母语,但我相信这里可以用int32_t和int64_t替换常规整数和long类型。

I think the less than/greater than can be implemented by subtracting one from the other, casting to an unsigned int and then use a bitwise AND with the sign bit, then shift it to the least significant bit. 我认为小于/大于可通过以下方式实现:将另一个相减,转换为无符号int,然后对符号位使用按位与,然后将其移至最低有效位。

Equality could be done with a binary NOT on the result of subtracting the two numbers. 可以通过对两个数字相减的结果使用二进制NOT来实现相等。 Haven't tested these, but used something similar in OpenCL years ago to prevent branching on the GPU. 尚未测试这些,但是几年前在OpenCL中使用了类似的方法来防止在GPU上分支。

Example for greater than: 大于的示例:

#include <stdio.h>

int main(int argc, char** argv) {
  int x = 6;
  int y = 4;
  int diff;
  unsigned int* udiff;
  unsigned int gr;
  unsigned int one = 1;

  diff = x - y;
  udiff = (unsigned int*)&diff;
  gr = (*udiff & (one << 31)) >> 31;

  printf("%d", gr);


}

(codepad) (键盘)

Less than can be done analogously. 少于类似地可以做的事情。 Equality: 平等:

#include <stdio.h>

int main(int argc, char** argv) {
  int x = 4;
  int y = 4;

  int diff;
  unsigned int* udiff;
  unsigned int eq;

  diff = x - y;
  udiff = (unsigned int*)&diff;

  eq = !(*udiff);

  printf("%d", eq);

}  

(codepad) (键盘)

Not sure how you can do this in Java, this relies on the fact that you can reinterpret a signed integral value as an unsigned int in C using pointer casting. 不确定如何在Java中执行此操作,这取决于您可以使用指针转换将带符号的整数值重新解释为C中的无符号int。

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

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