views:

162

answers:

2

I am not sure if that would make any trouble. Normally, lets say, I sum up a few values. I would do it like this:

val1 = val1 + val2;
val1 = val1 + val3;
val1 = val1 + val4;

and so on... Could I do something similar with NSDecimal, or should I not provide the same NSDecimal "object" twice in the parameters? (btw, how's that called? not a "object", right?)

Apple says:

NSDecimalAdd
Adds two decimal values.

NSCalculationError NSDecimalAdd (
   NSDecimal *result,
   const NSDecimal *leftOperand,
   const NSDecimal *rightOperand,
   NSRoundingMode roundingMode
);

Discussion Adds leftOperand to rightOperand and stores the sum in result.

+2  A: 

I get tripped up by NSDecimal and NSDecimalNumber often. To me, this is one of the few great letdowns of the Framework...maybe I just haven't had that "ah ha!" moment like I have with so many other parts of Cocoa/Touch?!? As Aaron Hillegass says "Cocoa/Obj-C makes common things easy and difficult things possible." Well, here's a case where I think something common (use of a decimal value) is overly convoluted...and could/should be simplified. </diatribe>

Anyway, in this case, because NSDecimalAdd takes two pointers to a NSDecimal and returns a third pointer as a result you can reuse val1 to your hearts content. You're just changing the pointer with each statement to the new returned value.

Meltemi
I believe that NSDecimal and NSDecimalNumber are structured the way that they are for specific reasons. I agree that there could be better ways of interchanging data between NSDecimal and various formats, but I think the rest of the design is reasonable. For example, the above addition operator is optimized so that the structs aren't copied for the parameters and result, thus the pointers.
Brad Larson
I just opened another question to this parameter memory thing, before reading your comment. So my try to make a nice-to-use wrapper is failing ;) well, I'll still try to make a little wrapper to get at least rid of that ugly error thing I always have to handle. Want to handle that centralized.
HelloMoon
+1  A: 

The following code will do the addition you describe above:

NSCalculationError calculationError = NSDecimalAdd(&val1, &val1, &val2, NSRoundBankers);
calculationError = NSDecimalAdd(&val1, &val1, &val3, NSRoundBankers);
calculationError = NSDecimalAdd(&val1, &val1, &val4, NSRoundBankers);

assuming that you've set up val1, val2, and val3 as NSDecimals. In this case, I'm using the Banker's rounding behavior in the case of an overflow.

We use NSDecimal at the heart of the Core Plot framework, so we've created some helper functions that make doing this kind of math a little easier (if a little less efficient, due to the copying of structs during every function call). These can be found in the CPUtilities.m source file within the project.

Brad Larson
Perfect! I was also thinking about writing some helpers, but more like a utility class by using methods rather than functions. I've opened a question on how to get those pointer things right. Couldn't you use in CPUtilities the same technique like those NSDecimal... functions do? i.e. taking pointers to the structs rather than the structs itself, and feeding the function somehow "dereferenced"? Not sure... on the usage side that would not hurt too much. could provide all methods twice. once for pointers, once for "lazy use".
HelloMoon