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

时间:2013-12-12 19:24:20

标签: java operators

假设:

  • 以二进制补码形式的32位有符号整数
  • truefalse是值为10
  • 的整数
  • java运算符

您是否可以仅使用算术运算符和按位运算符来实现<==之类的关系运算符?

2 个答案:

答案 0 :(得分:1)

这是一个快速尝试。签名小于凌乱,但如果需要,可以在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;
}

编辑:我看到Java被要求了。不是我的母语,但我相信常规整数和长类型可以替换为int32_t和int64_t。

答案 1 :(得分:0)

我认为小于/大于可以通过从另一个中减去一个来实现,转换为无符号整数然后使用符号位的符号AND,然后将其移到最低有效位。

在减去两个数字的结果上,可以用二进制NOT来完成等式。 尚未对这些进行测试,但在OpenCL多年前使用类似的东西来阻止GPU上的分支。

大于的示例:

#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)

少于可以类似地完成。 平等:

#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)

不确定如何在Java中执行此操作,这取决于您可以使用指针转换将已签名的整数值重新解释为C中的unsigned int。