How do I add NSDecimalNumbers?
Asked Answered
L

5

22

OK this may be the dumb question of the day, but supposing I have a class with :

NSDecimalNumber *numOne   = [NSDecimalNumber numberWithFloat:1.0];
NSDecimalNumber *numTwo   = [NSDecimalNumber numberWithFloat:2.0];
NSDecimalNumber *numThree = [NSDecimalNumber numberWithFloat:3.0];

Why can't I have a function that adds those numbers:

- (NSDecimalNumber *)addThem {
    return (self.numOne + self.numTwo + self.numThree);
}

I apologize in advance for being an idiot, and thanks!

Lemming answered 15/3, 2010 at 18:16 Comment(1)
Don't degrade yourself. We all need help sometime.Vigesimal
L
22

You can't do what you want becuase neither C nor Objective C have operator overloading. Instead you have to write:

- (NSDecimalNumber *)addThem {
    return [self.numOne decimalNumberByAdding:
        [self.numTwo decimalNumberByAdding:self.numThree]];
}

If you're willing to play dirty with Objective-C++ (rename your source to .mm), then you could write:

NSDecimalNumber *operator + (NSDecimalNumber *a, NSDecimalNumber *b) {
    return [a decimalNumberByAdding:b];
}

Now you can write:

- (NSDecimalNumber *)addThem {
    return self.numOne + self.numTwo + self.numThree;
}

Go C++!

Leeannaleeanne answered 15/3, 2010 at 18:20 Comment(0)
C
10

NSDecimalNumber is an Objective C class which, when instantiated, produces an object which contains a number. You access the object (and objects in general) through methods only. Objective C doesn't have a way to directly express arithmetic against objects, so you need to make one of three calls:

  • -[NSDecimalNumber doubleValue], which extracts the numbers from your objects before adding the numbers. link
  • -[NSDecimalNumber decimalNumberByAdding], which creates an additional object, which may be more than you want. link
  • NSDecimalAdd, which, again, creates an additional object, which may be more than you want. link
Curtcurtail answered 15/3, 2010 at 18:23 Comment(3)
By the way, I'm surprised nobody has mentioned this, but... I think your first burst of sample code is broken. You appear to be calling the NSNumber class in order to instantiate NSDecimalNumber. I've never seen such a thing before and I'm suspicious of it. You might get away with it for a while due to the "late binding" nature of Objective C, but it seems like it will eventually cause bugs.Curtcurtail
"you can think of the later options as built atop the earlier ones" - This is not true in the first case. NSDecimalNumbers perform decimal math, not floating point, so extracting a double and adding that will eliminate the benefits of working with an NSDecimalNumber. Also, NSDecimalAdd() is a function that works on an NSDecimal struct, not an NSDecimalNumber object.Fluellen
Poor choice of words on my part. In fact, the entire chain of logic makes less sense to me now than when I wrote it, since NSDecimalAdd operates on NSDecimal rather than NSDecimalNumber. I've removed the statement. I was trying to show inter-releatedness but took it too far.Curtcurtail
U
6

See NSDecimalAdd function (as well as NSDecimalMultiply, NSDecimalDivide, NSDecimalSubtract).

Unreadable answered 15/3, 2010 at 18:21 Comment(2)
Note that these functions work on NSDecimal structs, not NSDecimalNumber objects, but you can easily extract an NSDecimal using NSDecimalNumber's -decimalValue method.Fluellen
That said, this is the approach I recommend. The NSDecimal functions are up to five times faster than the NSDecimalNumber equivalents, and you avoid creating autoreleased objects all over the place, yet you maintain the decimal arithmetic and precision of NSDecimalNumber. I use NSDecimal instead of NSDecimalNumber where I can in my applications.Fluellen
M
2
[[numOne decimalNumberByAdding:numTwo] decimalNumberByAdding:numThree]
Martinamartindale answered 15/3, 2010 at 18:19 Comment(0)
M
2

You can:

- (NSDecimalNumber *)addThem {
    return [[self.numOne decimalNumberByAdding:numTwo] decimalNumberByAdding:numThree];
}

The problem with your example is that what self.numOne really is at a bit level is a pointer to an object. So your function would return some random memory location, not the sum.

If Objective-C supported C++-style operator overloading, someone could define + when applied to two NSDecimalNumber objects as an alias to decimalNumberByAdding:. But it doesn't.

Mousy answered 15/3, 2010 at 18:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.