NSNumber arithmetic
Asked Answered
E

3

6

I want to perform some simple arithmetic on NSNumbers and preserve the type. Is this possible?

For example:

- (NSNumber *)add:(NSNumber *)firstNumber to:(NSNumber *)secondNumber;

Is my method definition, and firstNumber and secondNumber are integers then I would like to return an integer that is the integer addition of them both. Equally if both are doubles then to return the result as a double.

It looks like I can get the type (except for boolean) using [NSNumber objCType] as found in this question: get type of NSNumber but I can't seem to extract those types and do the calculation without lots of code to extract the values do the calculation and return the result for every possible type.

Is there a short and concise way of doing this?

Ettaettari answered 8/7, 2012 at 7:5 Comment(3)
What are you planning on doing if they have different types?Sweeping
Happy to throw an error, or use the firstNumber type as the template. Both would work for what I need.Ettaettari
There is no concise way to do it.Allocution
E
10

If you want to perform arithmetic the best bet would be using an NSDecimalNumber.

NSDecimalNumber have methods to perform arithmetic operations like :

– decimalNumberByAdding:
– decimalNumberBySubtracting:
– decimalNumberByMultiplyingBy:
– decimalNumberByDividingBy:
– decimalNumberByRaisingToPower:
– decimalNumberByMultiplyingByPowerOf10:
– decimalNumberByAdding:withBehavior:
– decimalNumberBySubtracting:withBehavior:
– decimalNumberByMultiplyingBy:withBehavior:
– decimalNumberByDividingBy:withBehavior:
– decimalNumberByRaisingToPower:withBehavior:
– decimalNumberByMultiplyingByPowerOf10:withBehavior:

And since NSDecimalNumber extends NSNumber it also have all methods of an NSNumber, so i think that you could use it in your case without any problem.

Expansion answered 8/7, 2012 at 8:31 Comment(1)
I've been working with Cocoa Touch for over a year and I've never heard of this class!! Crazy!! +1!Matelda
U
3

For nearly all applications it will be fine to convert to double and back using -doubleValue and –initWithDouble:. This will let you use the standard C symbols (+, -, ...) and functions (exp(), sin()). The only way you would run into trouble is if you were using close to the full precision for 64-bit integer values.

If you want to stick with Objective-C class operations you can use NSDecimalNumber instead.

See also: How to add two NSNumber objects?

Untinged answered 8/7, 2012 at 7:25 Comment(0)
A
2

How about calculating the expression value as a double (with all the inputs as double values), and then checking if the result is an integer? Then you just use NSNumber numberWithInt: or NSNumber numberWithDouble: to return the result.

When you check if the result value is an integer, be sure to account for the rounding error (e.g. when 1 is expressed as 0.99999999, etc).

EDIT: Just noticed in the docs for NSNumber this phrase:

Note that number objects do not necessarily preserve the type they are created with.

I think this means you can't reliably do what you're trying to do.

Abagail answered 8/7, 2012 at 7:28 Comment(2)
You don't even need to go that far. The point of NSNumber is to abstract that away. It's perfectly happy using only doubles. Since you return an NSNumber, you can pull any representation out that you want, regardless of what you put in. See this snippet that I made: ideone.com/HwIOaMatelda
I hear you! I personally doubt I'd ever need to do any of this :) I was just trying to solve the OP's problem. Whether this makes sense in the grand scheme of things, is a different question, and I don't have enough context to say that.Abagail

© 2022 - 2024 — McMap. All rights reserved.