I was working on some code today where I had to compare two NSDecimalNumbers. This was my first attempt at comparing them:
NSDecimalNumber *number1 = [NSDecimalNumber one];
NSDecimalNumber *zero = [NSDecimalNumber zero];
if (number1 > zero) {
//1 is always greater than 0 right?
}
This code will compile without errors or even warnings, but it doesn't work. It works, but it doesn't do what you expect. Turns out you aren't comparing the values of the two NSDecimalNumbers, your comparing pointer addresses.
Even more shocking, Objective-C does not have operator overloading! I've been developing in Objective-C for 3+ years now and I had no idea, it just never came up in iTimeZone. Assuming that Objective-C had operator overloads that did the expected evaluation on the value cost me about 4 hours today, especially since the compiler was no help.
I switched over to this implementation and thought I was done:
NSDecimalNumber *number1 = [NSDecimalNumber one];
NSDecimalNumber *zero = [NSDecimalNumber zero];
if ([number1 floatValue] > [zero floatValue]) {
//1 is always greater than 0 right?
}
Looks good right? Wrong! While this works for short fractional numbers, numbers that have more precisions will lose them with that syntax. I could have also used:
...
if ([number1 doubleValue] > [zero doubleValue]) {
//1 is always greater than 0 right?
}
That increases the precision from 6 digits to 15, quite a leap, but some digits could still get cutoff.
The absolutely correct way?
...
if ([number1 compare:zero] == NSOrderedDescending) {
//Hey number1 is greater after all
}
I don't think I am going out on a limb here saying that isn't the easiest to understand syntax. A comment surely would have to go above the if statement to rewrite that in plain english, or even using an operator. While I have only written a few operator overload methods in C++ and none in .NET, I sure did use them in .NET all the time. I hope Objectice-C gets them in a future release.