Comparison of NSNumber literals
Asked Answered
D

4

6

I really like the new literals in Objective-C. I am wondering if with the new additions there's a better way to compare numbers.

For example, if I want to compare a and b:

a = @1;
b = @2;

Is the only way to compare them like this:

[a intValue] > [b intValue]

Or are there better, more elegant, solutions?

Drawee answered 11/9, 2012 at 1:55 Comment(4)
If you want, you could write a category adding methods like [a greaterThan: b] and [a equalTo: b]Dita
It's possible that compiler rewriting of operators will eventually emerge as an extension of this number literal syntax. @1 already becomes [NSNumber numberWithInt:1] -- there's no reason that @1 > @2 couldn't be allowed and rewritten as [@1 isGreaterThan:@2] (well, no reason aside from possible confusion: "Why can't I do if( 1 > @2 )?").Snot
yea you're right, it would take away low level pointer comparisons...but they could always do something like @1 @>= @2 and then implement greaterThanOrEqualTo in NSNumber, so it would be translated as [@1 greaterThanOrEqualTo:@2]...this way you can keep your pointer arithmetic as well as logical comparisonsDrawee
Or they could ditch the whole silly idea of boxing raw types and just go back to using int :-)Toper
T
13

For equality checks, you can use isEqualToNumber which checks if either the id or content is equal (with the latter using compare):

if ([a isEqualToNumber:b])                  // if a == b

Not sure why they also didn't implement isGreaterThanNumber and isLessThanNumber convenience methods (and possibly >= and <= as well), since the compare method below seems a little clunky.

For inequality checks, just use compare directly (you can also do this for equality as can be seen from the first one below):

if ([a compare:b] == NSOrderedSame)         // if (a == b)
if ([a compare:b] == NSOrderedAscending)    // if (a <  b)
if ([a compare:b] == NSOrderedDescending)   // if (a >  b)

if ([a compare:b] != NSOrderedSame)         // if (a != b)
if ([a compare:b] != NSOrderedAscending)    // if (a >= b)
if ([a compare:b] != NSOrderedSescending)   // if (a <= b)

Details can be found on the NSNumber class documentation page.


Keep in mind there's nothing preventing you from creating your own helper function which would, for example, allow code like:

if (nsnComp1 (a, ">=", b)) ... // returns true/false (yes/no)

or:

if (nsnComp2 (a, b) >= 0)  ... // returns -1/0/+1

even though it's less Objective-C and more C :-) It depends on whether your definition of "elegant" is bound mostly by efficiency or readability. Whether that's preferable to your intValue option is a decision you'll need to make yourself.

Toper answered 11/9, 2012 at 1:59 Comment(4)
Well, the probably only added isEqualToNumber: because the isEqualTo... methods are used in many other places [like isEqualToString:]. Just IMHO.Brackett
Thanks...didn't know about the compare, but still you don't know >= or<= ....would be more awesome if they did @1 == @2...but i understand why not.Drawee
@0xSina, if you mean I haven't specified an easy way to do >= and <= with compare, see the update. Those two, along with !=, can be done with the != comparison operator.Toper
Ah well played. I feel dumb right now, didn't think of that :)Drawee
A
7

NSNumber implements -compare: (as do a number of other classes). So you can say

switch ([a compare:b]) {
    case NSOrderedAscending: // a < b
        // blah blah
        break;
    case NSOrderedSame: // a == b
        // blah blah
        break;
    case NSOrderedDescending: // a > b
        // blah blah
        break;
}
Actinomycosis answered 11/9, 2012 at 1:57 Comment(0)
S
0

NSNumber also has an isEqualToNumber:

Schifra answered 11/9, 2012 at 2:0 Comment(0)
S
0

Here is the code snippet to check which works good:

NSLog(@"%d", number1 == number2);
NSLog(@"%d", [number1 isEqual:number2]);
NSLog(@"%d", [number1 isEqualToNumber:number2]);

The output:

1
1
1

Conclusion:

To understand comparison, you need to understand instance allocation. NSNumber internally implements a cache of objects assigned, and maps existing objects to any newly created objects using values. If an existing NSNumber object is found holding value 1, no new NSNumber instance is created.

Socio answered 8/7, 2016 at 10:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.