假设:
true
和false
是值为1
和0
您是否可以仅使用算术运算符和按位运算符来实现<
和==
之类的关系运算符?
答案 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);
}
少于可以类似地完成。 平等:
#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);
}
不确定如何在Java中执行此操作,这取决于您可以使用指针转换将已签名的整数值重新解释为C中的unsigned int。