2012-07-08 12 views
6

Quiero realizar aritmética simple en NSNumbers y conservar el tipo. es posible?NSNumber arithmetic

Por ejemplo:

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

¿Es mi definición del método, y FirstNumber y secondNumber son números enteros entonces me gustaría devolver un número entero que es el complemento entero de los dos. Igualmente, si ambos son dobles, entonces el resultado se devuelve como un doble.

Parece que puedo obtener el tipo (excepto booleano) usando [NSNumber objCType] como se encuentra en esta pregunta: get type of NSNumber pero parece que no puedo extraer esos tipos y hacer el cálculo sin muchos códigos para extraer los valores. cálculo y devolver el resultado para cada tipo posible.

¿Hay una forma breve y concisa de hacer esto?

+0

¿Qué piensas hacer si tienen diferentes tipos? –

+0

Feliz de lanzar un error, o use el tipo firstNumber como la plantilla. Ambos funcionarían para lo que necesito. –

+0

No hay una forma concisa de hacerlo. – sosborn

Respuesta

10

Si desea realizar aritmética, la mejor opción sería usar un NSDecimalNumber.

NSDecimalNumber tener métodos para realizar operaciones aritméticas como:

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

Y puesto que extiende NSDecimalNumber NSNumber también tienen todos los métodos de una NSNumber, así que creo que se podría utilizar en su caso sin ningún problema.

+0

¡He estado trabajando con Cocoa Touch durante más de un año y nunca había escuchado sobre esta clase! ¡¡Loca!! +1! – borrrden

3

Para casi todas las aplicaciones estará bien convertir a double y volver usando -doubleValue y –initWithDouble:. Esto le permitirá usar los símbolos C estándar (+, -, ...) y funciones (exp(), sin()). La única forma en que se encontraría en problemas es si estaba usando una precisión cercana a los valores enteros de 64 bits.

Si quiere seguir con las operaciones de la clase Objective-C, puede usar NSDecimalNumber.

Consulte también: How to add two NSNumber objects?

2

¿Qué hay de calcular el valor de la expresión como un doble (con todas las entradas como valores dobles), y luego comprobar si el resultado es un entero? Luego solo usa NSNumber numberWithInt: o NSNumber numberWithDouble: para devolver el resultado.

Cuando comprueba si el valor del resultado es un número entero, asegúrese de tener en cuenta el error de redondeo (por ejemplo, cuando 1 se expresa como 0,99999999, etc.).

EDITAR: Sólo notado en la documentación para NSNumber esta frase:

en cuenta que los objetos numéricos no necesariamente preservar el tipo que son creados con .

Creo que esto significa que no puede hacer de manera confiable lo que está tratando de hacer.

+0

Ni siquiera necesita ir tan lejos. El objetivo de NSNumber es abstraer eso. Es perfectamente feliz usando solo dobles.Como devuelve un NSNumber, puede retirar cualquier representación que desee, independientemente de lo que haya ingresado. Vea este fragmento que hice: http://ideone.com/HwIOa – borrrden

+0

¡Lo escucho! Personalmente dudo que alguna vez tenga que hacer algo de esto :) Estaba tratando de resolver el problema del OP. Si esto tiene sentido en el gran esquema de las cosas, es una pregunta diferente, y no tengo suficiente contexto para decir eso. – Macondo2Seattle