Reputation: 14060
Assuming:
true
and false
are integers with values 1
and 0
Can you implement relational operators like <
and ==
using only arithmetic and bitwise operators?
Upvotes: 1
Views: 213
Reputation: 4455
Here's a quick attempt. Signed less-than is messy but possible in 32-bit arithmetic if needed.
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. Not my native language but I believe the regular integer and long types could be substituted for int32_t and int64_t here.
Upvotes: 1
Reputation: 5015
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.
Equality could be done with a binary NOT on the result of subtracting the two numbers. Haven't tested these, but used something similar in OpenCL years ago to prevent branching on the 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);
}
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);
}
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.
Upvotes: 0