Machines make mistakes too, especially when humans are operating them.
- Dr. Phyllis Gardner, The Dropout
Is the title a clickbait? Well, Yes and No. Hear me out! Consider the following code.
#include<stdio.h>
int main(){
unsigned int a;
int b;
a = 5;
b = -5;
if( b > a){
printf("\n%d is greater than %d\n", b, a);
}
}
Now, some of you might have gotten an idea or even found out the dirt. Yes, unsigned is the keyword here. But why does the computer not catch it? C is one of the languages that let you write device/system level code. Is it a good or bad thing? If you know what you are doing, it is the former and latter if otherwise.
Now, why do we get the result that we do? It is because, C will resort to general comparison if the operators are not overridden for a datatype. And, in our case, both the unsigned int and int has a size of 4 bytes. So, the compiler happily compiles the code and sends the data through a comparator(may vary depending on the CPU architecture) during runtime.
To understand this better, we have to perceive these numbers like a computer does.
a is an unsigned integer. So the 5 is stored in the register as a binary value of 32 bits.
00000000 00000000 00000000 00000101
b is a signed integer. So, -5 is stored as 2's complement.
binary value of 5 is 00000000 00000000 00000000 00000101
Inverse of the same is 11111111 11111111 11111111 11111010
Finally, add 1 to it. 11111111 11111111 11111111 11111011
So, -5 is stored as 11111111 11111111 11111111 11111011
So, when I ask the computer if 11111111 11111111 11111111 11111011 is greater than 00000000 00000000 00000000 00000101? It is like, meh, yeah!