C
#include<stdio.h>
int main(int argc, char** argv) {
int a, b;
long long c;
double d;
printf("A: ");
scanf("%d", &a);
printf("B: ");
scanf("%d", &b);
c = (long long)a - (long long)b;
if (c == 0) {
puts("Integer A is equal to B.");
}
else {
d = *(double*)&c;
if (d == d) {
puts("Integer A is greater than B.");
}
else {
puts("Integer B is greater than A.");
}
}
return 0;
}
It was golfed but then I realized this wasn't a golf. So now it's not. ;)
To understand how this works, you have to understand how numbers are integers and floats are represented, bitwise, and how the CPU operates on them.
I'm starting out by getting two 32-bit signed integers. They are stored as ints to bound the input. I then cast them to long longs, basically converting them to 64-bit integers, and then subtract. This subtraction is important. If A is larger than B, the result will be positive. If they're equal, the result is 0, and if B is larger than A, the result is negative. The negative case is the key, here, because of how it's represented as an integer in memory. A negative integer is stored as a 2's complement, and since these are 64-bit integers, we'll have at least one DWord of 1s in the MSBs in memory. I then store that into a 64-bit double variable, turning it into a double value with the same bit encoding. If it is negative, this double value is a NaN. By IEEE floating point rules, comparing a NaN with itself will always result in false
, which indicates that A < B.
And of course, a simple zero check can add an equivalence check to the algorithm.
EDIT: This now works for very large and very small ints. It requires a 64-bit compiler, where long long
is defined as having a size of 8 bytes. Unfortunately, gcc in Cygwin didn't do the trick, so I had to use Visual Studio. But, it works. This, I found, does not work for very large and very small 32-bit integers. I will be investigating a solution.
return a!=b
could be argued to meet the spec (it determines whethera
is (greater than or less than)b
). \$\endgroup\$